From 944862566289b09eda83e34306f657f2a28c5525 Mon Sep 17 00:00:00 2001 From: "Sergio R. Caprile" Date: Fri, 3 Jul 2026 14:28:53 -0300 Subject: [PATCH] add real life testing for PPPoE and VLANs --- .github/workflows/nightly.yml | 26 ++++++- mongoose.c | 47 ++++++----- src/l2_ppp.c | 27 ++++--- src/net_builtin.c | 20 +++-- test/Makefile | 4 + test/ppp_test.c | 2 +- test/pppoe-server-options | 7 ++ test/pppoe_tap_test.c | 142 ++++++++++++++++++++++++++++++++++ test/setup_ga_network.sh | 26 +++++-- 9 files changed, 251 insertions(+), 50 deletions(-) create mode 100644 test/pppoe-server-options create mode 100644 test/pppoe_tap_test.c diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 0e068487..a204ed9a 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -152,6 +152,28 @@ jobs: - uses: actions/checkout@v5 with: { fetch-depth: 2 } - run: sudo apt -y update ; sudo apt -y install binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test ${{ matrix.target }} IPV6=${{ matrix.ipv6 }} + pppoe_vlan: # run tests, build tests performed by the l2 job may not catch runtime alignment and protocol issues, etc. + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + cc: [gcc, clang, g++, clang++] + ipv6: [0, 1] + name: PPPoE over VLAN CC=${{ matrix.cc }} IPV6=${{ matrix.ipv6 }} + steps: + - uses: actions/checkout@v5 + with: { fetch-depth: 2 } + - uses: webfactory/ssh-agent@v0.10.0 + with: + ssh-private-key: ${{ secrets.HEALTH_TESTS_SSH_KEY }} + - run: | + source ./test/setup_ga_network.sh + make -C test pppoe_tap_test CC=${{ matrix.cc }} IPV6=${{ matrix.ipv6 }} > log + - if: success() || failure() + run: | + cat log + test/health.awk < log > json + scp -o "StrictHostKeyChecking=no" json "root@176.9.217.245:/data/downloads/health/pppoe-vlan_${{ matrix.cc }}_${{ matrix.ipv6 }}_$(date +"%Y%m%d").json" atcmd: runs-on: ubuntu-latest @@ -219,12 +241,12 @@ jobs: make -C test/bsd shm_tap_bridge test/bsd/shm_tap_bridge & sleep 2 - make -C test/bsd + make -C test/bsd > log - if: success() || failure() run: | cat log test/health.awk < log > json - scp -o "StrictHostKeyChecking=no" json "root@176.9.217.245:/data/downloads/health/bsd_$(date +"%Y%m%d").json" + scp -o "StrictHostKeyChecking=no" json "root@176.9.217.245:/data/downloads/health/bsd_${{ matrix.cc }}_$(date +"%Y%m%d").json" s390: runs-on: ubuntu-latest diff --git a/mongoose.c b/mongoose.c index ed5b52ec..3a2594c9 100644 --- a/mongoose.c +++ b/mongoose.c @@ -5833,10 +5833,10 @@ static void ppp_handle_ipv6cp(struct mg_tcpip_if *ifp, uint8_t *ipv6cpp, find_opt( MG_PPP_IPV6CP_OPT_IFCID, 10, (const uint8_t *) (ipv6cp + 1), len - sizeof(*ipv6cp), - (uint8_t *) &((struct mg_l2addr *) (ifp->gwmac))->addr.ieee64)) { - if (((struct mg_l2addr *) (ifp->gwmac))->addr.ieee64 != 0) { + (uint8_t *) &((struct mg_l2addr *) (ifp->gw6mac))->addr.ieee64)) { + if (((struct mg_l2addr *) (ifp->gw6mac))->addr.ieee64 != 0) { MG_DEBUG(("IPV6CP cfg, GW IFCID: %M", mg_print_ieee64, - &((struct mg_l2addr *) (ifp->gwmac))->addr.ieee64)); + &((struct mg_l2addr *) (ifp->gw6mac))->addr.ieee64)); ipv6cp->code = MG_PPP_IPV6CP_CFG_ACK; ppp_tx_frame(ifp, MG_PPP_PROTO_IPV6CP, ipv6cpp, len); req[1] = id; @@ -5860,22 +5860,21 @@ static void ppp_handle_ipv6cp(struct mg_tcpip_if *ifp, uint8_t *ipv6cpp, // Our peer accepted our ifc id MG_VERBOSE(("got IPV6CP config ack")); break; - case MG_PPP_IPV6CP_CFG_NACK: + case MG_PPP_IPV6CP_CFG_NACK: { + struct mg_l2addr l2; MG_VERBOSE(("got IPV6CP config nack")); // NACK contains our "suggested" IFC id, use it if (len >= 10 && - find_opt( - MG_PPP_IPV6CP_OPT_IFCID, 10, (const uint8_t *) (ipv6cp + 1), - len - sizeof(*ipv6cp), - (uint8_t *) &((struct mg_l2addr *) (ifp->mac))->addr.ieee64)) { - MG_DEBUG(("IPV6CP cfg, IFCID: %M", mg_print_ieee64, - &((struct mg_l2addr *) (ifp->mac))->addr.ieee64)); + find_opt(MG_PPP_IPV6CP_OPT_IFCID, 10, (const uint8_t *) (ipv6cp + 1), + len - sizeof(*ipv6cp), (uint8_t *) &l2.addr.ieee64)) { + MG_DEBUG(("IPV6CP cfg, IFCID: %M", mg_print_ieee64, &l2.addr.ieee64)); + ifp->ip6ll[1] = l2.addr.ieee64; // RFC-5072 5, signal L3 we're ready ipv6cp->code = MG_PPP_IPV6CP_CFG_REQ; ppp_tx_frame(ifp, MG_PPP_PROTO_IPV6CP, ipv6cpp, len); } else { MG_ERROR(("Peer is not able to offer an interface id")); } - break; + } break; case MG_PPP_IPV6CP_CFG_REJECT: MG_ERROR(("Peer rejected our interface id")); break; @@ -6040,10 +6039,10 @@ bool mg_l2_pppoe_rx(struct mg_tcpip_if *ifp, enum mg_l2proto *proto, uint8_t *p = (uint8_t *) (pppoe + 1); uint16_t taglen; while (len >= 4) { // parse tags for a possible AC-Cookie - uint16_t curtag = *((uint16_t *) p); - taglen = mg_ntohs(*(((uint16_t *) p) + 1)); + uint16_t curtag = MG_LOAD_BE16(p); + taglen = MG_LOAD_BE16(p + 2); if (taglen > len - 4) return false; // truncated / malformed - if (curtag == mg_htons(0x0104)) { + if (curtag == 0x0104) { has_cookie = true; break; } @@ -9747,11 +9746,12 @@ static void mg_ip6_poll(struct mg_tcpip_if *ifp, bool s1) { static void mg_ip6_link(struct mg_tcpip_if *ifp, bool drv_up, bool l2_up) { bool cur_drv = (ifp->state6 != MG_TCPIP_STATE_DOWN); bool cur_l2 = (ifp->state6 >= MG_TCPIP_STATE_UP); + const uint8_t px[8] = {0xfe, 0x80, 0, 0, 0, 0, 0, 0}; // RFC-4291 2.5.6 if (drv_up != cur_drv || l2_up != cur_l2) { // link/L2 state has changed - if (l2_up && ifp->ip6ll[0] == 0 && ifp->ip6ll[1] == 0) { // gen ll address - uint8_t px[8] = {0xfe, 0x80, 0, 0, 0, 0, 0, 0}; // RFC-4291 2.5.6 + if (ifp->l2type == MG_TCPIP_L2_ETH && l2_up && ifp->ip6ll[0] == 0 && + ifp->ip6ll[1] == 0) { // gen ll address mg_l2_genip6(ifp->l2type, ifp->ip6ll, 64, ifp->mac); - memcpy(ifp->ip6ll, px, 8); // RFC-4291 2.5.4 + memcpy(ifp->ip6ll, px, 8); // RFC-2464 5 } // just got our link local address if we didn't have one. // If static configuration is used, global addresses, // prefix length, and gw are already filled at this point. @@ -9759,14 +9759,21 @@ static void mg_ip6_link(struct mg_tcpip_if *ifp, bool drv_up, bool l2_up) { if (!l2_up && ifp->enable_slaac) ifp->ip6[0] = ifp->ip6[1] = 0; ifp->state6 = !drv_up ? MG_TCPIP_STATE_DOWN : !l2_up ? MG_TCPIP_STATE_LINK_UP - : ifp->enable_slaac || ifp->ip6[0] == 0 ? MG_TCPIP_STATE_UP - : MG_TCPIP_STATE_IP; + : ifp->ip6ll[0] == 0 || ifp->enable_slaac || ifp->ip6[0] == 0 + ? MG_TCPIP_STATE_UP + : MG_TCPIP_STATE_IP; onstate6change(ifp); } else if (!ifp->enable_slaac && ifp->state6 == MG_TCPIP_STATE_UP && - ifp->ip6[0]) { + ifp->ip6ll[0] != 0 && ifp->ip6[0] != 0) { ifp->state6 = MG_TCPIP_STATE_IP; // ifp->fn has set an IP onstate6change(ifp); } + if ((ifp->l2type == MG_TCPIP_L2_PPP || ifp->l2type == MG_TCPIP_L2_PPPoE) && + ifp->state6 == MG_TCPIP_STATE_UP && ifp->ip6ll[0] == 0 && + ifp->ip6ll[1] != 0) { // IPV6CP has got an IFCID, gen ll address + memcpy(ifp->ip6ll, px, 8); // RFC-5072 5 + onstate6change(ifp); + } // just got our link local address if we didn't have one. } #else #define mg_ip6_poll(x, y) diff --git a/src/l2_ppp.c b/src/l2_ppp.c index a7ecf160..130d4f16 100644 --- a/src/l2_ppp.c +++ b/src/l2_ppp.c @@ -366,10 +366,10 @@ static void ppp_handle_ipv6cp(struct mg_tcpip_if *ifp, uint8_t *ipv6cpp, find_opt( MG_PPP_IPV6CP_OPT_IFCID, 10, (const uint8_t *) (ipv6cp + 1), len - sizeof(*ipv6cp), - (uint8_t *) &((struct mg_l2addr *) (ifp->gwmac))->addr.ieee64)) { - if (((struct mg_l2addr *) (ifp->gwmac))->addr.ieee64 != 0) { + (uint8_t *) &((struct mg_l2addr *) (ifp->gw6mac))->addr.ieee64)) { + if (((struct mg_l2addr *) (ifp->gw6mac))->addr.ieee64 != 0) { MG_DEBUG(("IPV6CP cfg, GW IFCID: %M", mg_print_ieee64, - &((struct mg_l2addr *) (ifp->gwmac))->addr.ieee64)); + &((struct mg_l2addr *) (ifp->gw6mac))->addr.ieee64)); ipv6cp->code = MG_PPP_IPV6CP_CFG_ACK; ppp_tx_frame(ifp, MG_PPP_PROTO_IPV6CP, ipv6cpp, len); req[1] = id; @@ -393,22 +393,21 @@ static void ppp_handle_ipv6cp(struct mg_tcpip_if *ifp, uint8_t *ipv6cpp, // Our peer accepted our ifc id MG_VERBOSE(("got IPV6CP config ack")); break; - case MG_PPP_IPV6CP_CFG_NACK: + case MG_PPP_IPV6CP_CFG_NACK: { + struct mg_l2addr l2; MG_VERBOSE(("got IPV6CP config nack")); // NACK contains our "suggested" IFC id, use it if (len >= 10 && - find_opt( - MG_PPP_IPV6CP_OPT_IFCID, 10, (const uint8_t *) (ipv6cp + 1), - len - sizeof(*ipv6cp), - (uint8_t *) &((struct mg_l2addr *) (ifp->mac))->addr.ieee64)) { - MG_DEBUG(("IPV6CP cfg, IFCID: %M", mg_print_ieee64, - &((struct mg_l2addr *) (ifp->mac))->addr.ieee64)); + find_opt(MG_PPP_IPV6CP_OPT_IFCID, 10, (const uint8_t *) (ipv6cp + 1), + len - sizeof(*ipv6cp), (uint8_t *) &l2.addr.ieee64)) { + MG_DEBUG(("IPV6CP cfg, IFCID: %M", mg_print_ieee64, &l2.addr.ieee64)); + ifp->ip6ll[1] = l2.addr.ieee64; // RFC-5072 5, signal L3 we're ready ipv6cp->code = MG_PPP_IPV6CP_CFG_REQ; ppp_tx_frame(ifp, MG_PPP_PROTO_IPV6CP, ipv6cpp, len); } else { MG_ERROR(("Peer is not able to offer an interface id")); } - break; + } break; case MG_PPP_IPV6CP_CFG_REJECT: MG_ERROR(("Peer rejected our interface id")); break; @@ -573,10 +572,10 @@ bool mg_l2_pppoe_rx(struct mg_tcpip_if *ifp, enum mg_l2proto *proto, uint8_t *p = (uint8_t *) (pppoe + 1); uint16_t taglen; while (len >= 4) { // parse tags for a possible AC-Cookie - uint16_t curtag = *((uint16_t *) p); - taglen = mg_ntohs(*(((uint16_t *) p) + 1)); + uint16_t curtag = MG_LOAD_BE16(p); + taglen = MG_LOAD_BE16(p + 2); if (taglen > len - 4) return false; // truncated / malformed - if (curtag == mg_htons(0x0104)) { + if (curtag == 0x0104) { has_cookie = true; break; } diff --git a/src/net_builtin.c b/src/net_builtin.c index 3dfb330c..414999e1 100644 --- a/src/net_builtin.c +++ b/src/net_builtin.c @@ -1922,11 +1922,12 @@ static void mg_ip6_poll(struct mg_tcpip_if *ifp, bool s1) { static void mg_ip6_link(struct mg_tcpip_if *ifp, bool drv_up, bool l2_up) { bool cur_drv = (ifp->state6 != MG_TCPIP_STATE_DOWN); bool cur_l2 = (ifp->state6 >= MG_TCPIP_STATE_UP); + const uint8_t px[8] = {0xfe, 0x80, 0, 0, 0, 0, 0, 0}; // RFC-4291 2.5.6 if (drv_up != cur_drv || l2_up != cur_l2) { // link/L2 state has changed - if (l2_up && ifp->ip6ll[0] == 0 && ifp->ip6ll[1] == 0) { // gen ll address - uint8_t px[8] = {0xfe, 0x80, 0, 0, 0, 0, 0, 0}; // RFC-4291 2.5.6 + if (ifp->l2type == MG_TCPIP_L2_ETH && l2_up && ifp->ip6ll[0] == 0 && + ifp->ip6ll[1] == 0) { // gen ll address mg_l2_genip6(ifp->l2type, ifp->ip6ll, 64, ifp->mac); - memcpy(ifp->ip6ll, px, 8); // RFC-4291 2.5.4 + memcpy(ifp->ip6ll, px, 8); // RFC-2464 5 } // just got our link local address if we didn't have one. // If static configuration is used, global addresses, // prefix length, and gw are already filled at this point. @@ -1934,14 +1935,21 @@ static void mg_ip6_link(struct mg_tcpip_if *ifp, bool drv_up, bool l2_up) { if (!l2_up && ifp->enable_slaac) ifp->ip6[0] = ifp->ip6[1] = 0; ifp->state6 = !drv_up ? MG_TCPIP_STATE_DOWN : !l2_up ? MG_TCPIP_STATE_LINK_UP - : ifp->enable_slaac || ifp->ip6[0] == 0 ? MG_TCPIP_STATE_UP - : MG_TCPIP_STATE_IP; + : ifp->ip6ll[0] == 0 || ifp->enable_slaac || ifp->ip6[0] == 0 + ? MG_TCPIP_STATE_UP + : MG_TCPIP_STATE_IP; onstate6change(ifp); } else if (!ifp->enable_slaac && ifp->state6 == MG_TCPIP_STATE_UP && - ifp->ip6[0]) { + ifp->ip6ll[0] != 0 && ifp->ip6[0] != 0) { ifp->state6 = MG_TCPIP_STATE_IP; // ifp->fn has set an IP onstate6change(ifp); } + if ((ifp->l2type == MG_TCPIP_L2_PPP || ifp->l2type == MG_TCPIP_L2_PPPoE) && + ifp->state6 == MG_TCPIP_STATE_UP && ifp->ip6ll[0] == 0 && + ifp->ip6ll[1] != 0) { // IPV6CP has got an IFCID, gen ll address + memcpy(ifp->ip6ll, px, 8); // RFC-5072 5 + onstate6change(ifp); + } // just got our link local address if we didn't have one. } #else #define mg_ip6_poll(x, y) diff --git a/test/Makefile b/test/Makefile index 3e93601c..e9f0f136 100644 --- a/test/Makefile +++ b/test/Makefile @@ -103,6 +103,10 @@ mip_tap_test: mip_x_test.c mip_tap_test.c mongoose.c mongoose.h packed_fs.c Make $(CC) mip_tap_test.c packed_fs.c $(CFLAGS) $(LDFLAGS) -o $@ ASAN_OPTIONS=$(ASAN_OPTIONS) $(RUN) ./$@ +pppoe_tap_test: pppoe_tap_test.c mongoose.c mongoose.h Makefile + $(CC) pppoe_tap_test.c $(CFLAGS) $(LDFLAGS) -o $@ + ASAN_OPTIONS=$(ASAN_OPTIONS) $(RUN) ./$@ + # bridge UDP port <--> TAP interface port_tap_bridge: port_tap_bridge.c cc port_tap_bridge.c -o $@ diff --git a/test/ppp_test.c b/test/ppp_test.c index fc40583b..e5cb638e 100644 --- a/test/ppp_test.c +++ b/test/ppp_test.c @@ -174,7 +174,7 @@ static void test_ipv6cp(void) { sizeof(ipv6cp))); proto = MG_TCPIP_L2PROTO_ARP; ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false); - ASSERT(memcmp(&((struct mg_l2addr *) ifp.gwmac)->addr.ieee64, ipv6cp + 6, + ASSERT(memcmp(&((struct mg_l2addr *) ifp.gw6mac)->addr.ieee64, ipv6cp + 6, 8) == 0); ASSERT(((struct ipv6cp *) ppp_payload(frame))->code == MG_PPP_IPV6CP_CFG_ACK); diff --git a/test/pppoe-server-options b/test/pppoe-server-options new file mode 100644 index 00000000..de0e8c64 --- /dev/null +++ b/test/pppoe-server-options @@ -0,0 +1,7 @@ +# PPP options for the PPPoE server +noauth +10.0.0.1:10.67.15.1 +lcp-echo-interval 1 +lcp-echo-failure 2 ++ipv6 +ipv6cp-use-ipaddr diff --git a/test/pppoe_tap_test.c b/test/pppoe_tap_test.c new file mode 100644 index 00000000..cabbbdde --- /dev/null +++ b/test/pppoe_tap_test.c @@ -0,0 +1,142 @@ +#define MG_ENABLE_TCPIP 1 +#define MG_ENABLE_TCPIP_DRIVER_INIT 0 + +#include +#ifndef __OpenBSD__ +#include +#include +#else +#include +#include +#include +#endif +#include + +#include "mongoose.c" + +#define WAIT_MS 5000 + +static size_t tap_rx(void *buf, size_t len, struct mg_tcpip_if *ifp) { + ssize_t received = read(*(int *) ifp->driver_data, buf, len); + usleep(1); + if (received < 0) return 0; + return (size_t) received; +} + +static size_t tap_tx(const void *buf, size_t len, struct mg_tcpip_if *ifp) { + ssize_t res = write(*(int *) ifp->driver_data, buf, len); + if (res < 0) { + MG_ERROR(("tap_tx failed: %d", errno)); + return 0; + } + return (size_t) res; +} + +static bool tap_poll(struct mg_tcpip_if *ifp, bool s1) { + return s1 && ifp->driver_data ? true : false; +} + +int main(int argc, char *argv[]) { + int res = EXIT_SUCCESS; + const char *iface = "tap0"; + const char *mac = "02:00:01:02:03:78"; +#ifndef __OpenBSD__ + const char *tuntap_device = "/dev/net/tun"; +#else + const char *tuntap_device = "/dev/tap0"; +#endif + uint16_t vlan_id = 3; + int fd, i; + struct ifreq ifr; + struct mg_mgr mgr; + struct mg_tcpip_driver driver; + struct mg_tcpip_if mif; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-i") == 0 && i + 1 < argc) { + iface = argv[++i]; + } else if (strcmp(argv[i], "-mac") == 0 && i + 1 < argc) { + mac = argv[++i]; + } else if (strcmp(argv[i], "-v") == 0 && i + 1 < argc) { + mg_log_set(atoi(argv[++i])); + } else if (strcmp(argv[i], "-vlan") == 0 && i + 1 < argc) { + vlan_id = (uint16_t) atoi(argv[++i]); + } else { + MG_ERROR(("unknown option %s", argv[i])); + return EXIT_FAILURE; + } + } + + fd = open(tuntap_device, O_RDWR); + if (fd < 0) { + MG_ERROR(("Failed to open TAP device: %d", errno)); + return EXIT_FAILURE; + } + + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, iface, IFNAMSIZ); +#ifndef __OpenBSD__ + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) { + MG_ERROR(("Failed to setup TAP interface: %s", ifr.ifr_name)); + close(fd); + return EXIT_FAILURE; + } +#else + ifr.ifr_flags = (short) (IFF_UP | IFF_BROADCAST | IFF_MULTICAST); + if (ioctl(fd, TUNSIFMODE, (void *) &ifr) < 0) { + MG_ERROR(("Failed to setup TAP interface: %s", ifr.ifr_name)); + close(fd); + return EXIT_FAILURE; + } +#endif + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); + + memset(&driver, 0, sizeof(driver)); + driver.tx = tap_tx; + driver.rx = tap_rx; + driver.poll = tap_poll; + + memset(&mif, 0, sizeof(mif)); + mif.driver = &driver; + mif.driver_data = &fd; +#if MG_ENABLE_IPV6 + mif.ip6[0] = mg_htonll(0x100000000000000); + mif.prefix[0] = 1; + mif.prefix_len = 64; + mif.gw6[0] = mg_htonll(0x100000000000000); + mif.gw6_ready = true; +#endif + mif.l2type = MG_TCPIP_L2_PPPoE; + mif.l2data.eth.vlan_id = vlan_id; + sscanf(mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &mif.mac[0], &mif.mac[1], + &mif.mac[2], &mif.mac[3], &mif.mac[4], &mif.mac[5]); + + mg_mgr_init(&mgr); + mg_tcpip_init(&mgr, &mif); + MG_INFO(("Opened TAP interface %s, VLAN %u", iface, vlan_id)); + + for (i = 0; i < WAIT_MS / 10 && (mif.state != MG_TCPIP_STATE_READY +#if MG_ENABLE_IPV6 + || mif.state6 != MG_TCPIP_STATE_READY +#endif + ); i++) { + mg_mgr_poll(&mgr, 10); + usleep(10000); + } + + if (mif.state != MG_TCPIP_STATE_READY) { + MG_ERROR(("IP FAILED %u", mif.state)); + res = EXIT_FAILURE; + } +#if MG_ENABLE_IPV6 + if (mif.state6 != MG_TCPIP_STATE_READY) { + MG_ERROR(("IPv6 FAILED %u", mif.state6)); + res = EXIT_FAILURE; + } +#endif + + mg_mgr_free(&mgr); + close(fd); + return res; +} diff --git a/test/setup_ga_network.sh b/test/setup_ga_network.sh index caac0363..8c56eb0d 100755 --- a/test/setup_ga_network.sh +++ b/test/setup_ga_network.sh @@ -23,18 +23,20 @@ echo # Package installation echo "Package installation" -sudo apt-get -y install isc-dhcp-server net-tools radvd -sudo systemctl stop radvd # just in case they think it is cool to start it +sudo apt-get -y install isc-dhcp-server net-tools radvd ppp pppoe +sudo systemctl stop radvd # they think it is cool to start it # sudo apt-get -y install build-essential sshpass echo echo "Network configuration script: Bridge" sudo ip link add $BRIDGE type bridge # Create brige -sudo ifconfig $BRIDGE $BRIDGE_IP netmask $BRIDGE_MASK up -sudo ifconfig $BRIDGE:1 $GATEWAY_IP netmask $BRIDGE_MASK up -sudo ifconfig $BRIDGE:2 $HOST_IP netmask $BRIDGE_MASK up -sudo ip -6 addr add $BRIDGE_IPV6/64 dev $BRIDGE -sudo ip -6 addr add $HOST_IPV6/64 dev $BRIDGE:1 +sudo ifconfig $BRIDGE $BRIDGE_IP netmask $BRIDGE_MASK up # its IP +sudo ifconfig $BRIDGE:1 $GATEWAY_IP netmask $BRIDGE_MASK up # IP announced by DHCP as gateway +sudo ifconfig $BRIDGE:2 $HOST_IP netmask $BRIDGE_MASK up # IP exported for LAN (dut) connections +sudo ip -6 addr add $BRIDGE_IPV6/64 dev $BRIDGE # its IPv6 +sudo ip -6 addr add $HOST_IPV6/64 dev $BRIDGE:1 # IPv6 exported for LAN (dut) connections +sudo ip link add link $BRIDGE name $BRIDGE.3 type vlan id 3 # Create VLAN for PPPoE+VLAN tests +sudo ifconfig $BRIDGE.3 up echo echo "Network configuration script: TAP" @@ -73,10 +75,20 @@ sudo cp test/dhcpd.conf /etc/dhcp/dhcpd.conf sudo chmod a+w /var/lib/dhcp/* sudo dhcpd mg_bridge0 & echo + +# Setup Router Advertising server echo "radvd listening at $BRIDGE_IPV6" sudo ip link set $BRIDGE up # there's no physical port, so we need to set link up for radvd to work sudo radvd -n -d 5 -C test/radvd.conf & echo + +# Setup PPPoE server +echo "pppoe-server listening at $BRIDGE.3" +printf "lock\n" | sudo tee /etc/ppp/options +sudo pppoe-server -F -D -O test/pppoe-server-options -I $BRIDGE.3 & +echo + +# Export generic server addresses so DUTs can connect to them echo "Host listening at $HOST_IP and $HOST_IPV6" export HOST_IP export HOST_IPV6