From mboxrd@z Thu Jan 1 00:00:00 1970 From: David Gibson To: passt-dev@passt.top Subject: [PATCH 7/7] Make substructures for IPv4 and IPv6 specific context information Date: Fri, 22 Jul 2022 15:31:18 +1000 Message-ID: <20220722053118.1067459-8-david@gibson.dropbear.id.au> In-Reply-To: <20220722053118.1067459-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============8016919413673228046==" --===============8016919413673228046== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The context structure contains a batch of fields specific to IPv4 and to IPv6 connectivity. Split those out into a sub-structure. This allows the conf_ip4() and conf_ip6() functions, which take the entire context but touch very little of it, to be given more specific parameters, making it clearer what it affects without stepping through the code. Signed-off-by: David Gibson --- arp.c | 2 +- conf.c | 184 ++++++++++++++++++++++++++++--------------------------- dhcp.c | 22 +++---- dhcpv6.c | 18 +++--- ndp.c | 16 ++--- passt.c | 2 +- passt.h | 68 ++++++++++++-------- pasta.c | 10 +-- tap.c | 22 +++---- tcp.c | 34 +++++----- udp.c | 62 +++++++++---------- util.c | 4 +- 12 files changed, 232 insertions(+), 212 deletions(-) diff --git a/arp.c b/arp.c index e8f21b5..0ad97af 100644 --- a/arp.c +++ b/arp.c @@ -66,7 +66,7 @@ int arp(const struct ctx *c, const struct pool *p) return 1; =20 /* Don't resolve our own address, either. */ - if (!memcmp(am->tip, &c->addr4, sizeof(am->tip))) + if (!memcmp(am->tip, &c->ip4.addr, sizeof(am->tip))) return 1; =20 ah->ar_op =3D htons(ARPOP_REPLY); diff --git a/conf.c b/conf.c index 2a4ef23..f46b195 100644 --- a/conf.c +++ b/conf.c @@ -404,9 +404,9 @@ overlap: static void get_dns(struct ctx *c) { int dns4_set, dns6_set, dnss_set, dns_set, fd; - struct in6_addr *dns6 =3D &c->dns6[0]; + struct in6_addr *dns6 =3D &c->ip6.dns[0]; struct fqdn *s =3D c->dns_search; - uint32_t *dns4 =3D &c->dns4[0]; + uint32_t *dns4 =3D &c->ip4.dns[0]; struct lineread resolvconf; int line_len; char *line, *p, *end; @@ -434,7 +434,7 @@ static void get_dns(struct ctx *c) *end =3D 0; =20 if (!dns4_set && - dns4 - &c->dns4[0] < ARRAY_SIZE(c->dns4) - 1 && + dns4 - &c->ip4.dns[0] < ARRAY_SIZE(c->ip4.dns) - 1 && inet_pton(AF_INET, p + 1, dns4)) { /* We can only access local addresses via the gw redirect */ if (ntohl(*dns4) >> IN_CLASSA_NSHIFT =3D=3D IN_LOOPBACKNET) { @@ -442,14 +442,14 @@ static void get_dns(struct ctx *c) *dns4 =3D 0; continue; } - *dns4 =3D c->gw4; + *dns4 =3D c->ip4.gw; } dns4++; *dns4 =3D 0; } =20 if (!dns6_set && - dns6 - &c->dns6[0] < ARRAY_SIZE(c->dns6) - 1 && + dns6 - &c->ip6.dns[0] < ARRAY_SIZE(c->ip6.dns) - 1 && inet_pton(AF_INET6, p + 1, dns6)) { /* We can only access local addresses via the gw redirect */ if (IN6_IS_ADDR_LOOPBACK(dns6)) { @@ -457,7 +457,7 @@ static void get_dns(struct ctx *c) memset(dns6, 0, sizeof(*dns6)); continue; } - memcpy(dns6, &c->gw6, sizeof(*dns6)); + memcpy(dns6, &c->ip6.gw, sizeof(*dns6)); } dns6++; memset(dns6, 0, sizeof(*dns6)); @@ -485,7 +485,7 @@ static void get_dns(struct ctx *c) close(fd); =20 out: - if (!dns_set && dns4 =3D=3D c->dns4 && dns6 =3D=3D c->dns6) + if (!dns_set && dns4 =3D=3D c->ip4.dns && dns6 =3D=3D c->ip6.dns) warn("Couldn't get any nameserver address"); } =20 @@ -612,12 +612,14 @@ static int conf_ns_opt(struct ctx *c, =20 /** * conf_ip4() - Verify or detect IPv4 support, get relevant addresses - * @c: Execution context * @ifi: Host interface to attempt (0 to determine one) + * @ip4: IPv4 context (will be written) + * @mac: MAC address to use (written if unset) * * Return: Interface index for IPv4, or 0 on failure. */ -static unsigned int conf_ip4(struct ctx *c, unsigned int ifi) +static unsigned int conf_ip4(unsigned int ifi, + struct ip4_ctx *ip4, unsigned char *mac) { if (!ifi) ifi =3D nl_get_ext_if(AF_INET); @@ -627,33 +629,33 @@ static unsigned int conf_ip4(struct ctx *c, unsigned in= t ifi) return 0; } =20 - if (!c->gw4) - nl_route(0, ifi, AF_INET, &c->gw4); + if (!ip4->gw) + nl_route(0, ifi, AF_INET, &ip4->gw); =20 - if (!c->addr4) { + if (!ip4->addr) { int mask_len =3D 0; =20 - nl_addr(0, ifi, AF_INET, &c->addr4, &mask_len, NULL); - c->mask4 =3D htonl(0xffffffff << (32 - mask_len)); + nl_addr(0, ifi, AF_INET, &ip4->addr, &mask_len, NULL); + ip4->mask =3D htonl(0xffffffff << (32 - mask_len)); } =20 - if (!c->mask4) { - if (IN_CLASSA(ntohl(c->addr4))) - c->mask4 =3D htonl(IN_CLASSA_NET); - else if (IN_CLASSB(ntohl(c->addr4))) - c->mask4 =3D htonl(IN_CLASSB_NET); - else if (IN_CLASSC(ntohl(c->addr4))) - c->mask4 =3D htonl(IN_CLASSC_NET); + if (!ip4->mask) { + if (IN_CLASSA(ntohl(ip4->addr))) + ip4->mask =3D htonl(IN_CLASSA_NET); + else if (IN_CLASSB(ntohl(ip4->addr))) + ip4->mask =3D htonl(IN_CLASSB_NET); + else if (IN_CLASSC(ntohl(ip4->addr))) + ip4->mask =3D htonl(IN_CLASSC_NET); else - c->mask4 =3D 0xffffffff; + ip4->mask =3D 0xffffffff; } =20 - memcpy(&c->addr4_seen, &c->addr4, sizeof(c->addr4_seen)); + memcpy(&ip4->addr_seen, &ip4->addr, sizeof(ip4->addr_seen)); =20 - if (MAC_IS_ZERO(c->mac)) - nl_link(0, ifi, c->mac, 0, 0); + if (MAC_IS_ZERO(mac)) + nl_link(0, ifi, mac, 0, 0); =20 - if (!c->gw4 || !c->addr4 || MAC_IS_ZERO(c->mac)) + if (!ip4->gw || !ip4->addr || MAC_IS_ZERO(mac)) return 0; =20 return ifi; @@ -661,12 +663,14 @@ static unsigned int conf_ip4(struct ctx *c, unsigned in= t ifi) =20 /** * conf_ip6() - Verify or detect IPv6 support, get relevant addresses - * @c: Execution context * @ifi: Host interface to attempt (0 to determine one) + * @ip6: IPv6 context (will be written) + * @mac: MAC address to use (written if unset) * * Return: Interface index for IPv6, or 0 on failure. */ -static unsigned int conf_ip6(struct ctx *c, unsigned int ifi) +static unsigned int conf_ip6(unsigned int ifi, + struct ip6_ctx *ip6, unsigned char *mac) { int prefix_len =3D 0; =20 @@ -678,23 +682,23 @@ static unsigned int conf_ip6(struct ctx *c, unsigned in= t ifi) return 0; } =20 - if (IN6_IS_ADDR_UNSPECIFIED(&c->gw6)) - nl_route(0, ifi, AF_INET6, &c->gw6); + if (IN6_IS_ADDR_UNSPECIFIED(&ip6->gw)) + nl_route(0, ifi, AF_INET6, &ip6->gw); =20 nl_addr(0, ifi, AF_INET6, - IN6_IS_ADDR_UNSPECIFIED(&c->addr6) ? &c->addr6 : NULL, - &prefix_len, &c->addr6_ll); + IN6_IS_ADDR_UNSPECIFIED(&ip6->addr) ? &ip6->addr : NULL, + &prefix_len, &ip6->addr_ll); =20 - memcpy(&c->addr6_seen, &c->addr6, sizeof(c->addr6)); - memcpy(&c->addr6_ll_seen, &c->addr6_ll, sizeof(c->addr6_ll)); + memcpy(&ip6->addr_seen, &ip6->addr, sizeof(ip6->addr)); + memcpy(&ip6->addr_ll_seen, &ip6->addr_ll, sizeof(ip6->addr_ll)); =20 - if (MAC_IS_ZERO(c->mac)) - nl_link(0, ifi, c->mac, 0, 0); + if (MAC_IS_ZERO(mac)) + nl_link(0, ifi, mac, 0, 0); =20 - if (IN6_IS_ADDR_UNSPECIFIED(&c->gw6) || - IN6_IS_ADDR_UNSPECIFIED(&c->addr6) || - IN6_IS_ADDR_UNSPECIFIED(&c->addr6_ll) || - MAC_IS_ZERO(c->mac)) + if (IN6_IS_ADDR_UNSPECIFIED(&ip6->gw) || + IN6_IS_ADDR_UNSPECIFIED(&ip6->addr) || + IN6_IS_ADDR_UNSPECIFIED(&ip6->addr_ll) || + MAC_IS_ZERO(mac)) return 0; =20 return ifi; @@ -899,17 +903,17 @@ static void conf_print(const struct ctx *c) if (!c->no_dhcp) { info("DHCP:"); info(" assign: %s", - inet_ntop(AF_INET, &c->addr4, buf4, sizeof(buf4))); + inet_ntop(AF_INET, &c->ip4.addr, buf4, sizeof(buf4))); info(" mask: %s", - inet_ntop(AF_INET, &c->mask4, buf4, sizeof(buf4))); + inet_ntop(AF_INET, &c->ip4.mask, buf4, sizeof(buf4))); info(" router: %s", - inet_ntop(AF_INET, &c->gw4, buf4, sizeof(buf4))); + inet_ntop(AF_INET, &c->ip4.gw, buf4, sizeof(buf4))); } =20 - for (i =3D 0; c->dns4[i]; i++) { + for (i =3D 0; c->ip4.dns[i]; i++) { if (!i) info("DNS:"); - inet_ntop(AF_INET, &c->dns4[i], buf4, sizeof(buf4)); + inet_ntop(AF_INET, &c->ip4.dns[i], buf4, sizeof(buf4)); info(" %s", buf4); } =20 @@ -933,17 +937,17 @@ static void conf_print(const struct ctx *c) goto dns6; =20 info(" assign: %s", - inet_ntop(AF_INET6, &c->addr6, buf6, sizeof(buf6))); + inet_ntop(AF_INET6, &c->ip6.addr, buf6, sizeof(buf6))); info(" router: %s", - inet_ntop(AF_INET6, &c->gw6, buf6, sizeof(buf6))); + inet_ntop(AF_INET6, &c->ip6.gw, buf6, sizeof(buf6))); info(" our link-local: %s", - inet_ntop(AF_INET6, &c->addr6_ll, buf6, sizeof(buf6))); + inet_ntop(AF_INET6, &c->ip6.addr_ll, buf6, sizeof(buf6))); =20 dns6: - for (i =3D 0; !IN6_IS_ADDR_UNSPECIFIED(&c->dns6[i]); i++) { + for (i =3D 0; !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns[i]); i++) { if (!i) info("DNS:"); - inet_ntop(AF_INET6, &c->dns6[i], buf6, sizeof(buf6)); + inet_ntop(AF_INET6, &c->ip6.dns[i], buf6, sizeof(buf6)); info(" %s", buf6); } =20 @@ -1065,9 +1069,9 @@ void conf(struct ctx *c, int argc, char **argv) enum conf_port_type tcp_tap =3D 0, tcp_init =3D 0; enum conf_port_type udp_tap =3D 0, udp_init =3D 0; struct fqdn *dnss =3D c->dns_search; - struct in6_addr *dns6 =3D c->dns6; + struct in6_addr *dns6 =3D c->ip6.dns; int name, ret, mask, b, i; - uint32_t *dns4 =3D c->dns4; + uint32_t *dns4 =3D c->ip4.dns; bool v4_only =3D false, v6_only =3D false; unsigned int ifi =3D 0; =20 @@ -1167,17 +1171,17 @@ void conf(struct ctx *c, int argc, char **argv) c->no_dhcp_dns_search =3D 1; break; case 9: - if (IN6_IS_ADDR_UNSPECIFIED(&c->dns6_fwd) && - inet_pton(AF_INET6, optarg, &c->dns6_fwd) && - !IN6_IS_ADDR_UNSPECIFIED(&c->dns6_fwd) && - !IN6_IS_ADDR_LOOPBACK(&c->dns6_fwd)) + if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_fwd) && + inet_pton(AF_INET6, optarg, &c->ip6.dns_fwd) && + !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_fwd) && + !IN6_IS_ADDR_LOOPBACK(&c->ip6.dns_fwd)) break; =20 - if (c->dns4_fwd =3D=3D INADDR_ANY && - inet_pton(AF_INET, optarg, &c->dns4_fwd) && - c->dns4_fwd !=3D INADDR_ANY && - c->dns4_fwd !=3D INADDR_BROADCAST && - c->dns4_fwd !=3D INADDR_LOOPBACK) + if (c->ip4.dns_fwd =3D=3D INADDR_ANY && + inet_pton(AF_INET, optarg, &c->ip4.dns_fwd) && + c->ip4.dns_fwd !=3D INADDR_ANY && + c->ip4.dns_fwd !=3D INADDR_BROADCAST && + c->ip4.dns_fwd !=3D INADDR_LOOPBACK) break; =20 err("Invalid DNS forwarding address: %s", optarg); @@ -1334,34 +1338,34 @@ void conf(struct ctx *c, int argc, char **argv) } break; case 'a': - if (IN6_IS_ADDR_UNSPECIFIED(&c->addr6) && - inet_pton(AF_INET6, optarg, &c->addr6) && - !IN6_IS_ADDR_UNSPECIFIED(&c->addr6) && - !IN6_IS_ADDR_LOOPBACK(&c->addr6) && - !IN6_IS_ADDR_V4MAPPED(&c->addr6) && - !IN6_IS_ADDR_V4COMPAT(&c->addr6) && - !IN6_IS_ADDR_MULTICAST(&c->addr6)) + if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.addr) && + inet_pton(AF_INET6, optarg, &c->ip6.addr) && + !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.addr) && + !IN6_IS_ADDR_LOOPBACK(&c->ip6.addr) && + !IN6_IS_ADDR_V4MAPPED(&c->ip6.addr) && + !IN6_IS_ADDR_V4COMPAT(&c->ip6.addr) && + !IN6_IS_ADDR_MULTICAST(&c->ip6.addr)) break; =20 - if (c->addr4 =3D=3D INADDR_ANY && - inet_pton(AF_INET, optarg, &c->addr4) && - c->addr4 !=3D INADDR_ANY && - c->addr4 !=3D INADDR_BROADCAST && - c->addr4 !=3D INADDR_LOOPBACK && - !IN_MULTICAST(c->addr4)) + if (c->ip4.addr =3D=3D INADDR_ANY && + inet_pton(AF_INET, optarg, &c->ip4.addr) && + c->ip4.addr !=3D INADDR_ANY && + c->ip4.addr !=3D INADDR_BROADCAST && + c->ip4.addr !=3D INADDR_LOOPBACK && + !IN_MULTICAST(c->ip4.addr)) break; =20 err("Invalid address: %s", optarg); usage(argv[0]); break; case 'n': - if (inet_pton(AF_INET, optarg, &c->mask4)) + if (inet_pton(AF_INET, optarg, &c->ip4.mask)) break; =20 errno =3D 0; mask =3D strtol(optarg, NULL, 0); if (mask > 0 && mask <=3D 32 && !errno) { - c->mask4 =3D htonl(0xffffffff << (32 - mask)); + c->ip4.mask =3D htonl(0xffffffff << (32 - mask)); break; } =20 @@ -1380,17 +1384,17 @@ void conf(struct ctx *c, int argc, char **argv) } break; case 'g': - if (IN6_IS_ADDR_UNSPECIFIED(&c->gw6) && - inet_pton(AF_INET6, optarg, &c->gw6) && - !IN6_IS_ADDR_UNSPECIFIED(&c->gw6) && - !IN6_IS_ADDR_LOOPBACK(&c->gw6)) + if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.gw) && + inet_pton(AF_INET6, optarg, &c->ip6.gw) && + !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.gw) && + !IN6_IS_ADDR_LOOPBACK(&c->ip6.gw)) break; =20 - if (c->gw4 =3D=3D INADDR_ANY && - inet_pton(AF_INET, optarg, &c->gw4) && - c->gw4 !=3D INADDR_ANY && - c->gw4 !=3D INADDR_BROADCAST && - c->gw4 !=3D INADDR_LOOPBACK) + if (c->ip4.gw =3D=3D INADDR_ANY && + inet_pton(AF_INET, optarg, &c->ip4.gw) && + c->ip4.gw !=3D INADDR_ANY && + c->ip4.gw !=3D INADDR_BROADCAST && + c->ip4.gw !=3D INADDR_LOOPBACK) break; =20 err("Invalid gateway address: %s", optarg); @@ -1410,7 +1414,7 @@ void conf(struct ctx *c, int argc, char **argv) break; case 'D': if (c->no_dns || - (!optarg && (dns4 - c->dns4 || dns6 - c->dns6))) { + (!optarg && (dns4 - c->ip4.dns || dns6 - c->ip6.dns))) { err("Empty and non-empty DNS options given"); usage(argv[0]); } @@ -1420,13 +1424,13 @@ void conf(struct ctx *c, int argc, char **argv) break; } =20 - if (dns4 - &c->dns4[0] < ARRAY_SIZE(c->dns4) && + if (dns4 - &c->ip4.dns[0] < ARRAY_SIZE(c->ip4.dns) && inet_pton(AF_INET, optarg, dns4)) { dns4++; break; } =20 - if (dns6 - &c->dns6[0] < ARRAY_SIZE(c->dns6) && + if (dns6 - &c->ip6.dns[0] < ARRAY_SIZE(c->ip6.dns) && inet_pton(AF_INET6, optarg, dns6)) { dns6++; break; @@ -1511,9 +1515,9 @@ void conf(struct ctx *c, int argc, char **argv) usage(argv[0]); } if (!v6_only) - c->ifi4 =3D conf_ip4(c, ifi); + c->ifi4 =3D conf_ip4(ifi, &c->ip4, c->mac); if (!v4_only) - c->ifi6 =3D conf_ip6(c, ifi); + c->ifi6 =3D conf_ip6(ifi, &c->ip6, c->mac); if (!c->ifi4 && !c->ifi6) { err("External interface not usable"); exit(EXIT_FAILURE); diff --git a/dhcp.c b/dhcp.c index 32dee56..7ad1319 100644 --- a/dhcp.c +++ b/dhcp.c @@ -332,20 +332,20 @@ int dhcp(const struct ctx *c, const struct pool *p) m->chaddr[0], m->chaddr[1], m->chaddr[2], m->chaddr[3], m->chaddr[4], m->chaddr[5]); =20 - m->yiaddr =3D c->addr4; - memcpy(opts[1].s, &c->mask4, sizeof(c->mask4)); - memcpy(opts[3].s, &c->gw4, sizeof(c->gw4)); - memcpy(opts[54].s, &c->gw4, sizeof(c->gw4)); + m->yiaddr =3D c->ip4.addr; + memcpy(opts[1].s, &c->ip4.mask, sizeof(c->ip4.mask)); + memcpy(opts[3].s, &c->ip4.gw, sizeof(c->ip4.gw)); + memcpy(opts[54].s, &c->ip4.gw, sizeof(c->ip4.gw)); =20 /* If the gateway is not on the assigned subnet, send an option 121 * (Classless Static Routing) adding a dummy route to it. */ - if ((c->addr4 & c->mask4) !=3D (c->gw4 & c->mask4)) { + if ((c->ip4.addr & c->ip4.mask) !=3D (c->ip4.gw & c->ip4.mask)) { /* a.b.c.d/32:0.0.0.0, 0:a.b.c.d */ opts[121].slen =3D 14; opts[121].s[0] =3D 32; - memcpy(opts[121].s + 1, &c->gw4, sizeof(c->gw4)); - memcpy(opts[121].s + 10, &c->gw4, sizeof(c->gw4)); + memcpy(opts[121].s + 1, &c->ip4.gw, sizeof(c->ip4.gw)); + memcpy(opts[121].s + 10, &c->ip4.gw, sizeof(c->ip4.gw)); } =20 if (c->mtu !=3D -1) { @@ -354,8 +354,8 @@ int dhcp(const struct ctx *c, const struct pool *p) opts[26].s[1] =3D c->mtu % 256; } =20 - for (i =3D 0, opts[6].slen =3D 0; !c->no_dhcp_dns && c->dns4[i]; i++) { - ((uint32_t *)opts[6].s)[i] =3D c->dns4[i]; + for (i =3D 0, opts[6].slen =3D 0; !c->no_dhcp_dns && c->ip4.dns[i]; i++) { + ((uint32_t *)opts[6].s)[i] =3D c->ip4.dns[i]; opts[6].slen +=3D sizeof(uint32_t); } =20 @@ -368,8 +368,8 @@ int dhcp(const struct ctx *c, const struct pool *p) uh->dest =3D htons(68); =20 iph->tot_len =3D htons(len +=3D sizeof(*iph)); - iph->daddr =3D c->addr4; - iph->saddr =3D c->gw4; + iph->daddr =3D c->ip4.addr; + iph->saddr =3D c->ip4.gw; iph->check =3D 0; iph->check =3D csum_unaligned(iph, (intptr_t)(iph->ihl * 4), 0); =20 diff --git a/dhcpv6.c b/dhcpv6.c index 4124a3e..fbae88d 100644 --- a/dhcpv6.c +++ b/dhcpv6.c @@ -390,7 +390,7 @@ static size_t dhcpv6_dns_fill(const struct ctx *c, char *= buf, int offset) if (c->no_dhcp_dns) goto search; =20 - for (i =3D 0; !IN6_IS_ADDR_UNSPECIFIED(&c->dns6[i]); i++) { + for (i =3D 0; !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns[i]); i++) { if (!i) { srv =3D (struct opt_dns_servers *)(buf + offset); offset +=3D sizeof(struct opt_hdr); @@ -398,7 +398,7 @@ static size_t dhcpv6_dns_fill(const struct ctx *c, char *= buf, int offset) srv->hdr.l =3D 0; } =20 - memcpy(&srv->addr[i], &c->dns6[i], sizeof(srv->addr[i])); + memcpy(&srv->addr[i], &c->ip6.dns[i], sizeof(srv->addr[i])); srv->hdr.l +=3D sizeof(srv->addr[i]); offset +=3D sizeof(srv->addr[i]); } @@ -473,12 +473,12 @@ int dhcpv6(struct ctx *c, const struct pool *p, if (mlen + sizeof(*uh) !=3D ntohs(uh->len) || mlen < sizeof(*mh)) return -1; =20 - c->addr6_ll_seen =3D *saddr; + c->ip6.addr_ll_seen =3D *saddr; =20 - if (IN6_IS_ADDR_LINKLOCAL(&c->gw6)) - src =3D &c->gw6; + if (IN6_IS_ADDR_LINKLOCAL(&c->ip6.gw)) + src =3D &c->ip6.gw; else - src =3D &c->addr6_ll; + src =3D &c->ip6.addr_ll; =20 mh =3D packet_get(p, 0, sizeof(*uh), sizeof(*mh), NULL); if (!mh) @@ -508,7 +508,7 @@ int dhcpv6(struct ctx *c, const struct pool *p, if (mh->type =3D=3D TYPE_CONFIRM && server_id) return -1; =20 - if ((bad_ia =3D dhcpv6_ia_notonlink(p, &c->addr6))) { + if ((bad_ia =3D dhcpv6_ia_notonlink(p, &c->ip6.addr))) { info("DHCPv6: received CONFIRM with inappropriate IA," " sending NotOnLink status in REPLY"); =20 @@ -580,7 +580,7 @@ int dhcpv6(struct ctx *c, const struct pool *p, resp.hdr.xid =3D mh->xid; =20 tap_ip_send(c, src, IPPROTO_UDP, (char *)&resp, n, mh->xid); - c->addr6_seen =3D c->addr6; + c->ip6.addr_seen =3D c->ip6.addr; =20 return 1; } @@ -602,5 +602,5 @@ void dhcpv6_init(const struct ctx *c) memcpy(resp.server_id.duid_lladdr, c->mac, sizeof(c->mac)); memcpy(resp_not_on_link.server_id.duid_lladdr, c->mac, sizeof(c->mac)); =20 - resp.ia_addr.addr =3D c->addr6; + resp.ia_addr.addr =3D c->ip6.addr; } diff --git a/ndp.c b/ndp.c index 4d13be3..29c4b14 100644 --- a/ndp.c +++ b/ndp.c @@ -107,7 +107,7 @@ int ndp(struct ctx *c, const struct icmp6hdr *ih, p +=3D 4; *(uint32_t *)p =3D htonl(3600); /* preferred lifetime */ p +=3D 8; - memcpy(p, &c->addr6, 8); /* prefix */ + memcpy(p, &c->ip6.addr, 8); /* prefix */ p +=3D 16; =20 if (c->mtu !=3D -1) { @@ -121,7 +121,7 @@ int ndp(struct ctx *c, const struct icmp6hdr *ih, if (c->no_dhcp_dns) goto dns_done; =20 - for (n =3D 0; !IN6_IS_ADDR_UNSPECIFIED(&c->dns6[n]); n++); + for (n =3D 0; !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns[n]); n++); if (n) { *p++ =3D 25; /* RDNSS */ *p++ =3D 1 + 2 * n; /* length */ @@ -130,7 +130,7 @@ int ndp(struct ctx *c, const struct icmp6hdr *ih, p +=3D 4; =20 for (i =3D 0; i < n; i++) { - memcpy(p, &c->dns6[i], 16); /* address */ + memcpy(p, &c->ip6.dns[i], 16); /* address */ p +=3D 16; } =20 @@ -177,15 +177,15 @@ dns_done: len =3D (uintptr_t)p - (uintptr_t)ihr - sizeof(*ihr); =20 if (IN6_IS_ADDR_LINKLOCAL(saddr)) - c->addr6_ll_seen =3D *saddr; + c->ip6.addr_ll_seen =3D *saddr; else - c->addr6_seen =3D *saddr; + c->ip6.addr_seen =3D *saddr; =20 ip6hr->daddr =3D *saddr; - if (IN6_IS_ADDR_LINKLOCAL(&c->gw6)) - ip6hr->saddr =3D c->gw6; + if (IN6_IS_ADDR_LINKLOCAL(&c->ip6.gw)) + ip6hr->saddr =3D c->ip6.gw; else - ip6hr->saddr =3D c->addr6_ll; + ip6hr->saddr =3D c->ip6.addr_ll; =20 ip6hr->payload_len =3D htons(sizeof(*ihr) + len); ip6hr->hop_limit =3D IPPROTO_ICMPV6; diff --git a/passt.c b/passt.c index 18c3512..686d483 100644 --- a/passt.c +++ b/passt.c @@ -363,7 +363,7 @@ int main(int argc, char **argv) if ((!c.no_udp && udp_init(&c)) || (!c.no_tcp && tcp_init(&c))) exit(EXIT_FAILURE); =20 - proto_update_l2_buf(c.mac_guest, c.mac, &c.addr4); + proto_update_l2_buf(c.mac_guest, c.mac, &c.ip4.addr); =20 if (c.ifi4 && !c.no_dhcp) dhcp_init(); diff --git a/passt.h b/passt.h index a8d5992..347e7c1 100644 --- a/passt.h +++ b/passt.h @@ -94,6 +94,44 @@ enum passt_modes { MODE_PASTA, }; =20 +/** + * struct ip4_ctx - IPv4 execution context + * @addr: IPv4 address for external, routable interface + * @addr_seen: Latest IPv4 address seen as source from tap + * @mask: IPv4 netmask, network order + * @gw: Default IPv4 gateway, network order + * @dns: IPv4 DNS addresses, zero-terminated, network order + * @dns_fwd: Address forwarded (UDP) to first IPv4 DNS, network order + */ +struct ip4_ctx { + uint32_t addr; + uint32_t addr_seen; + uint32_t mask; + uint32_t gw; + uint32_t dns[MAXNS + 1]; + uint32_t dns_fwd; +}; + +/** + * struct ip6_ctx - IPv6 execution context + * @addr: IPv6 address for external, routable interface + * @addr_ll: Link-local IPv6 address on external, routable interface + * @addr_seen: Latest IPv6 global/site address seen as source from tap + * @addr_ll_seen: Latest IPv6 link-local address seen as source from tap + * @gw: Default IPv6 gateway + * @dns: IPv6 DNS addresses, zero-terminated + * @dns_fwd: Address forwarded (UDP) to first IPv6 DNS, network order + */ +struct ip6_ctx { + struct in6_addr addr; + struct in6_addr addr_ll; + struct in6_addr addr_seen; + struct in6_addr addr_ll_seen; + struct in6_addr gw; + struct in6_addr dns[MAXNS + 1]; + struct in6_addr dns_fwd; +}; + /** * struct ctx - Execution context * @mode: Operation mode, qemu/UNIX domain socket or namespace/tap @@ -122,21 +160,10 @@ enum passt_modes { * @mac: Host MAC address * @mac_guest: MAC address of guest or namespace, seen or configured * @ifi4: Index of routable interface for IPv4, 0 if IPv4 disabled - * @addr4: IPv4 address for external, routable interface - * @addr4_seen: Latest IPv4 address seen as source from tap - * @mask4: IPv4 netmask, network order - * @gw4: Default IPv4 gateway, network order - * @dns4: IPv4 DNS addresses, zero-terminated, network order - * @dns4_fwd: Address forwarded (UDP) to first IPv4 DNS, network order + * @ip: IPv4 configuration * @dns_search: DNS search list * @ifi6: Index of routable interface for IPv6, 0 if IPv6 disabled - * @addr6: IPv6 address for external, routable interface - * @addr6_ll: Link-local IPv6 address on external, routable interface - * @addr6_seen: Latest IPv6 global/site address seen as source from tap - * @addr6_ll_seen: Latest IPv6 link-local address seen as source from tap - * @gw6: Default IPv6 gateway - * @dns6: IPv6 DNS addresses, zero-terminated - * @dns6_fwd: Address forwarded (UDP) to first IPv6 DNS, network order + * @ip6: IPv6 configuration * @pasta_ifn: Name of namespace interface for pasta * @pasta_ifn: Index of namespace interface for pasta * @pasta_conf_ns: Configure namespace interface after creating it @@ -192,23 +219,12 @@ struct ctx { unsigned char mac_guest[ETH_ALEN]; =20 unsigned int ifi4; - uint32_t addr4; - uint32_t addr4_seen; - uint32_t mask4; - uint32_t gw4; - uint32_t dns4[MAXNS + 1]; - uint32_t dns4_fwd; + struct ip4_ctx ip4; =20 struct fqdn dns_search[MAXDNSRCH]; =20 unsigned int ifi6; - struct in6_addr addr6; - struct in6_addr addr6_ll; - struct in6_addr addr6_seen; - struct in6_addr addr6_ll_seen; - struct in6_addr gw6; - struct in6_addr dns6[MAXNS + 1]; - struct in6_addr dns6_fwd; + struct ip6_ctx ip6; =20 char pasta_ifn[IF_NAMESIZE]; unsigned int pasta_ifi; diff --git a/pasta.c b/pasta.c index 2d7b5a1..5a78065 100644 --- a/pasta.c +++ b/pasta.c @@ -196,17 +196,17 @@ void pasta_ns_conf(struct ctx *c) nl_link(1, c->pasta_ifi, c->mac_guest, 1, c->mtu); =20 if (c->ifi4) { - prefix_len =3D __builtin_popcount(c->mask4); - nl_addr(1, c->pasta_ifi, AF_INET, &c->addr4, + prefix_len =3D __builtin_popcount(c->ip4.mask); + nl_addr(1, c->pasta_ifi, AF_INET, &c->ip4.addr, &prefix_len, NULL); - nl_route(1, c->pasta_ifi, AF_INET, &c->gw4); + nl_route(1, c->pasta_ifi, AF_INET, &c->ip4.gw); } =20 if (c->ifi6) { prefix_len =3D 64; - nl_addr(1, c->pasta_ifi, AF_INET6, &c->addr6, + nl_addr(1, c->pasta_ifi, AF_INET6, &c->ip6.addr, &prefix_len, NULL); - nl_route(1, c->pasta_ifi, AF_INET6, &c->gw6); + nl_route(1, c->pasta_ifi, AF_INET6, &c->ip6.gw); } } else { nl_link(1, c->pasta_ifi, c->mac_guest, 0, 0); diff --git a/tap.c b/tap.c index 8d552e9..3231da7 100644 --- a/tap.c +++ b/tap.c @@ -130,7 +130,7 @@ void tap_ip_send(const struct ctx *c, const struct in6_ad= dr *src, uint8_t proto, iph->frag_off =3D 0; iph->ttl =3D 255; iph->protocol =3D proto; - iph->daddr =3D c->addr4_seen; + iph->daddr =3D c->ip4.addr_seen; memcpy(&iph->saddr, &src->s6_addr[12], 4); =20 iph->check =3D 0; @@ -165,9 +165,9 @@ void tap_ip_send(const struct ctx *c, const struct in6_ad= dr *src, uint8_t proto, =20 ip6h->saddr =3D *src; if (IN6_IS_ADDR_LINKLOCAL(src)) - ip6h->daddr =3D c->addr6_ll_seen; + ip6h->daddr =3D c->ip6.addr_ll_seen; else - ip6h->daddr =3D c->addr6_seen; + ip6h->daddr =3D c->ip6.addr_seen; =20 memcpy(data, in, len); =20 @@ -354,9 +354,9 @@ resume: =20 l4_len =3D l3_len - hlen; =20 - if (iph->saddr && c->addr4_seen !=3D iph->saddr) { - c->addr4_seen =3D iph->saddr; - proto_update_l2_buf(NULL, NULL, &c->addr4_seen); + if (iph->saddr && c->ip4.addr_seen !=3D iph->saddr) { + c->ip4.addr_seen =3D iph->saddr; + proto_update_l2_buf(NULL, NULL, &c->ip4.addr_seen); } =20 l4h =3D packet_get(in, i, sizeof(*eh) + hlen, l4_len, NULL); @@ -504,13 +504,13 @@ resume: continue; =20 if (IN6_IS_ADDR_LINKLOCAL(saddr)) { - c->addr6_ll_seen =3D *saddr; + c->ip6.addr_ll_seen =3D *saddr; =20 - if (IN6_IS_ADDR_UNSPECIFIED(&c->addr6_seen)) { - c->addr6_seen =3D *saddr; + if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.addr_seen)) { + c->ip6.addr_seen =3D *saddr; } } else { - c->addr6_seen =3D *saddr; + c->ip6.addr_seen =3D *saddr; } =20 if (proto =3D=3D IPPROTO_ICMPV6) { @@ -545,7 +545,7 @@ resume: continue; } =20 - *saddr =3D c->addr6; + *saddr =3D c->ip6.addr; =20 if (proto !=3D IPPROTO_TCP && proto !=3D IPPROTO_UDP) { tap_packet_debug(NULL, ip6h, NULL, proto, NULL, 1); diff --git a/tcp.c b/tcp.c index 3382dfd..ec8c32e 100644 --- a/tcp.c +++ b/tcp.c @@ -1700,9 +1700,9 @@ do { \ b->ip6h.payload_len =3D htons(plen + sizeof(struct tcphdr)); b->ip6h.saddr =3D conn->a.a6; if (IN6_IS_ADDR_LINKLOCAL(&b->ip6h.saddr)) - b->ip6h.daddr =3D c->addr6_ll_seen; + b->ip6h.daddr =3D c->ip6.addr_ll_seen; else - b->ip6h.daddr =3D c->addr6_seen; + b->ip6h.daddr =3D c->ip6.addr_seen; =20 memset(b->ip6h.flow_lbl, 0, 3); =20 @@ -1723,7 +1723,7 @@ do { \ ip_len =3D plen + sizeof(struct iphdr) + sizeof(struct tcphdr); b->iph.tot_len =3D htons(ip_len); b->iph.saddr =3D conn->a.a4.a.s_addr; - b->iph.daddr =3D c->addr4_seen; + b->iph.daddr =3D c->ip4.addr_seen; =20 if (check) b->iph.check =3D *check; @@ -2069,7 +2069,7 @@ static uint32_t tcp_seq_init(const struct ctx *c, int a= f, const void *addr, } __attribute__((__packed__)) in =3D { .src =3D *(struct in_addr *)addr, .srcport =3D srcport, - .dst =3D { c->addr4 }, + .dst =3D { c->ip4.addr }, .dstport =3D dstport, }; =20 @@ -2083,7 +2083,7 @@ static uint32_t tcp_seq_init(const struct ctx *c, int a= f, const void *addr, } __attribute__((__packed__)) in =3D { .src =3D *(struct in6_addr *)addr, .srcport =3D srcport, - .dst =3D c->addr6, + .dst =3D c->ip6.addr, .dstport =3D dstport, }; =20 @@ -2197,16 +2197,16 @@ static void tcp_conn_from_tap(struct ctx *c, int af, = const void *addr, return; =20 if (!c->no_map_gw) { - if (af =3D=3D AF_INET && addr4.sin_addr.s_addr =3D=3D c->gw4) + if (af =3D=3D AF_INET && addr4.sin_addr.s_addr =3D=3D c->ip4.gw) addr4.sin_addr.s_addr =3D htonl(INADDR_LOOPBACK); - if (af =3D=3D AF_INET6 && IN6_ARE_ADDR_EQUAL(addr, &c->gw6)) + if (af =3D=3D AF_INET6 && IN6_ARE_ADDR_EQUAL(addr, &c->ip6.gw)) addr6.sin6_addr =3D in6addr_loopback; } =20 if (af =3D=3D AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr)) { struct sockaddr_in6 addr6_ll =3D { .sin6_family =3D AF_INET6, - .sin6_addr =3D c->addr6_ll, + .sin6_addr =3D c->ip6.addr_ll, .sin6_scope_id =3D c->ifi6, }; if (bind(s, (struct sockaddr *)&addr6_ll, sizeof(addr6_ll))) { @@ -2894,14 +2894,14 @@ static void tcp_conn_from_sock(struct ctx *c, union e= poll_ref ref, memcpy(&sa6, &sa, sizeof(sa6)); =20 if (IN6_IS_ADDR_LOOPBACK(&sa6.sin6_addr) || - IN6_ARE_ADDR_EQUAL(&sa6.sin6_addr, &c->addr6_seen) || - IN6_ARE_ADDR_EQUAL(&sa6.sin6_addr, &c->addr6)) { + IN6_ARE_ADDR_EQUAL(&sa6.sin6_addr, &c->ip6.addr_seen) || + IN6_ARE_ADDR_EQUAL(&sa6.sin6_addr, &c->ip6.addr)) { struct in6_addr *src; =20 - if (IN6_IS_ADDR_LINKLOCAL(&c->gw6)) - src =3D &c->gw6; + if (IN6_IS_ADDR_LINKLOCAL(&c->ip6.gw)) + src =3D &c->ip6.gw; else - src =3D &c->addr6_ll; + src =3D &c->ip6.addr_ll; =20 memcpy(&sa6.sin6_addr, src, sizeof(*src)); } @@ -2928,8 +2928,8 @@ static void tcp_conn_from_sock(struct ctx *c, union epo= ll_ref ref, memset(&conn->a.a4.one, 0xff, sizeof(conn->a.a4.one)); =20 if (s_addr >> IN_CLASSA_NSHIFT =3D=3D IN_LOOPBACKNET || - s_addr =3D=3D INADDR_ANY || htonl(s_addr) =3D=3D c->addr4_seen) - s_addr =3D ntohl(c->gw4); + s_addr =3D=3D INADDR_ANY || htonl(s_addr) =3D=3D c->ip4.addr_seen) + s_addr =3D ntohl(c->ip4.gw); =20 s_addr =3D htonl(s_addr); memcpy(&conn->a.a4.a, &s_addr, sizeof(conn->a.a4.a)); @@ -3118,7 +3118,7 @@ void tcp_sock_init(const struct ctx *c, int ns, sa_fami= ly_t af, =20 if (af =3D=3D AF_INET || af =3D=3D AF_UNSPEC) { if (!addr && c->mode =3D=3D MODE_PASTA) - bind_addr =3D &c->addr4; + bind_addr =3D &c->ip4.addr; else bind_addr =3D addr; =20 @@ -3159,7 +3159,7 @@ void tcp_sock_init(const struct ctx *c, int ns, sa_fami= ly_t af, =20 if (af =3D=3D AF_INET6 || af =3D=3D AF_UNSPEC) { if (!addr && c->mode =3D=3D MODE_PASTA) - bind_addr =3D &c->addr6; + bind_addr =3D &c->ip6.addr; else bind_addr =3D addr; =20 diff --git a/udp.c b/udp.c index 856429f..c4ebecc 100644 --- a/udp.c +++ b/udp.c @@ -690,20 +690,20 @@ static void udp_sock_fill_data_v4(const struct ctx *c, = int n, src_port =3D htons(b->s_in.sin_port); =20 if (src >> IN_CLASSA_NSHIFT =3D=3D IN_LOOPBACKNET || - src =3D=3D INADDR_ANY || src =3D=3D ntohl(c->addr4_seen)) { - b->iph.saddr =3D c->gw4; + src =3D=3D INADDR_ANY || src =3D=3D ntohl(c->ip4.addr_seen)) { + b->iph.saddr =3D c->ip4.gw; udp_tap_map[V4][src_port].ts =3D now->tv_sec; udp_tap_map[V4][src_port].flags |=3D PORT_LOCAL; =20 - if (b->s_in.sin_addr.s_addr =3D=3D c->addr4_seen) + if (b->s_in.sin_addr.s_addr =3D=3D c->ip4.addr_seen) udp_tap_map[V4][src_port].flags &=3D ~PORT_LOOPBACK; else udp_tap_map[V4][src_port].flags |=3D PORT_LOOPBACK; =20 bitmap_set(udp_act[V4][UDP_ACT_TAP], src_port); - } else if (c->dns4_fwd && - src =3D=3D ntohl(c->dns4[0]) && ntohs(src_port) =3D=3D 53) { - b->iph.saddr =3D c->dns4_fwd; + } else if (c->ip4.dns_fwd && + src =3D=3D ntohl(c->ip4.dns[0]) && ntohs(src_port) =3D=3D 53) { + b->iph.saddr =3D c->ip4.dns_fwd; } else { b->iph.saddr =3D b->s_in.sin_addr.s_addr; } @@ -768,17 +768,17 @@ static void udp_sock_fill_data_v6(const struct ctx *c, = int n, b->ip6h.payload_len =3D htons(udp6_l2_mh_sock[n].msg_len + sizeof(b->uh)); =20 if (IN6_IS_ADDR_LINKLOCAL(src)) { - b->ip6h.daddr =3D c->addr6_ll_seen; + b->ip6h.daddr =3D c->ip6.addr_ll_seen; b->ip6h.saddr =3D b->s_in6.sin6_addr; } else if (IN6_IS_ADDR_LOOPBACK(src) || - IN6_ARE_ADDR_EQUAL(src, &c->addr6_seen) || - IN6_ARE_ADDR_EQUAL(src, &c->addr6)) { - b->ip6h.daddr =3D c->addr6_ll_seen; + IN6_ARE_ADDR_EQUAL(src, &c->ip6.addr_seen) || + IN6_ARE_ADDR_EQUAL(src, &c->ip6.addr)) { + b->ip6h.daddr =3D c->ip6.addr_ll_seen; =20 - if (IN6_IS_ADDR_LINKLOCAL(&c->gw6)) - b->ip6h.saddr =3D c->gw6; + if (IN6_IS_ADDR_LINKLOCAL(&c->ip6.gw)) + b->ip6h.saddr =3D c->ip6.gw; else - b->ip6h.saddr =3D c->addr6_ll; + b->ip6h.saddr =3D c->ip6.addr_ll; =20 udp_tap_map[V6][src_port].ts =3D now->tv_sec; udp_tap_map[V6][src_port].flags |=3D PORT_LOCAL; @@ -788,18 +788,18 @@ static void udp_sock_fill_data_v6(const struct ctx *c, = int n, else udp_tap_map[V6][src_port].flags &=3D ~PORT_LOOPBACK; =20 - if (IN6_ARE_ADDR_EQUAL(src, &c->addr6)) + if (IN6_ARE_ADDR_EQUAL(src, &c->ip6.addr)) udp_tap_map[V6][src_port].flags |=3D PORT_GUA; else udp_tap_map[V6][src_port].flags &=3D ~PORT_GUA; =20 bitmap_set(udp_act[V6][UDP_ACT_TAP], src_port); - } else if (!IN6_IS_ADDR_UNSPECIFIED(&c->dns6_fwd) && - IN6_ARE_ADDR_EQUAL(src, &c->dns6_fwd) && src_port =3D=3D 53) { - b->ip6h.daddr =3D c->addr6_seen; - b->ip6h.saddr =3D c->dns6_fwd; + } else if (!IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_fwd) && + IN6_ARE_ADDR_EQUAL(src, &c->ip6.dns_fwd) && src_port =3D=3D 53) { + b->ip6h.daddr =3D c->ip6.addr_seen; + b->ip6h.saddr =3D c->ip6.dns_fwd; } else { - b->ip6h.daddr =3D c->addr6_seen; + b->ip6h.daddr =3D c->ip6.addr_seen; b->ip6h.saddr =3D b->s_in6.sin6_addr; } =20 @@ -1015,15 +1015,15 @@ int udp_tap_handler(struct ctx *c, int af, const void= *addr, =20 udp_tap_map[V4][src].ts =3D now->tv_sec; =20 - if (s_in.sin_addr.s_addr =3D=3D c->gw4 && !c->no_map_gw) { + if (s_in.sin_addr.s_addr =3D=3D c->ip4.gw && !c->no_map_gw) { if (!(udp_tap_map[V4][dst].flags & PORT_LOCAL) || (udp_tap_map[V4][dst].flags & PORT_LOOPBACK)) s_in.sin_addr.s_addr =3D htonl(INADDR_LOOPBACK); else - s_in.sin_addr.s_addr =3D c->addr4_seen; - } else if (s_in.sin_addr.s_addr =3D=3D c->dns4_fwd && + s_in.sin_addr.s_addr =3D c->ip4.addr_seen; + } else if (s_in.sin_addr.s_addr =3D=3D c->ip4.dns_fwd && ntohs(s_in.sin_port) =3D=3D 53) { - s_in.sin_addr.s_addr =3D c->dns4[0]; + s_in.sin_addr.s_addr =3D c->ip4.dns[0]; } } else { s_in6 =3D (struct sockaddr_in6) { @@ -1036,19 +1036,19 @@ int udp_tap_handler(struct ctx *c, int af, const void= *addr, sa =3D (struct sockaddr *)&s_in6; sl =3D sizeof(s_in6); =20 - if (IN6_ARE_ADDR_EQUAL(addr, &c->gw6) && !c->no_map_gw) { + if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.gw) && !c->no_map_gw) { if (!(udp_tap_map[V6][dst].flags & PORT_LOCAL) || (udp_tap_map[V6][dst].flags & PORT_LOOPBACK)) s_in6.sin6_addr =3D in6addr_loopback; else if (udp_tap_map[V6][dst].flags & PORT_GUA) - s_in6.sin6_addr =3D c->addr6; + s_in6.sin6_addr =3D c->ip6.addr; else - s_in6.sin6_addr =3D c->addr6_seen; - } else if (IN6_ARE_ADDR_EQUAL(addr, &c->dns6_fwd) && + s_in6.sin6_addr =3D c->ip6.addr_seen; + } else if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.dns_fwd) && ntohs(s_in6.sin6_port) =3D=3D 53) { - s_in6.sin6_addr =3D c->dns6[0]; + s_in6.sin6_addr =3D c->ip6.dns[0]; } else if (IN6_IS_ADDR_LINKLOCAL(&s_in6.sin6_addr)) { - bind_addr =3D &c->addr6_ll; + bind_addr =3D &c->ip6.addr_ll; } =20 if (!(s =3D udp_tap_map[V6][src].sock)) { @@ -1122,7 +1122,7 @@ void udp_sock_init(const struct ctx *c, int ns, sa_fami= ly_t af, =20 if (af =3D=3D AF_INET || af =3D=3D AF_UNSPEC) { if (!addr && c->mode =3D=3D MODE_PASTA) - bind_addr =3D &c->addr4; + bind_addr =3D &c->ip4.addr; else bind_addr =3D addr; =20 @@ -1155,7 +1155,7 @@ void udp_sock_init(const struct ctx *c, int ns, sa_fami= ly_t af, =20 if (af =3D=3D AF_INET6 || af =3D=3D AF_UNSPEC) { if (!addr && c->mode =3D=3D MODE_PASTA) - bind_addr =3D &c->addr6; + bind_addr =3D &c->ip6.addr; else bind_addr =3D addr; =20 diff --git a/util.c b/util.c index f4ec102..9b87b65 100644 --- a/util.c +++ b/util.c @@ -278,8 +278,8 @@ int sock_l4(const struct ctx *c, int af, uint8_t proto, if (bind_addr) { addr6.sin6_addr =3D *(struct in6_addr *)bind_addr; =20 - if (!memcmp(bind_addr, &c->addr6_ll, - sizeof(c->addr6_ll))) + if (!memcmp(bind_addr, &c->ip6.addr_ll, + sizeof(c->ip6.addr_ll))) addr6.sin6_scope_id =3D c->ifi6; } else { addr6.sin6_addr =3D in6addr_any; --=20 2.37.1 --===============8016919413673228046==--