diff --git a/conf.c b/conf.c index cddc769..943526d 100644 --- a/conf.c +++ b/conf.c @@ -630,17 +630,17 @@ static void conf_ip(struct ctx *c) v4 = v6 = IP_VERSION_PROBE; } - if (!c->ifi) - c->ifi = nl_get_ext_if(&v4, &v6); + if (!c->ifi4 && !c->ifi6) + c->ifi4 = c->ifi6 = nl_get_ext_if(&v4, &v6); if (v4 != IP_VERSION_DISABLED) { if (!c->gw4) - nl_route(0, c->ifi, AF_INET, &c->gw4); + nl_route(0, c->ifi4, AF_INET, &c->gw4); if (!c->addr4) { int mask_len = 0; - nl_addr(0, c->ifi, AF_INET, &c->addr4, &mask_len, NULL); + nl_addr(0, c->ifi4, AF_INET, &c->addr4, &mask_len, NULL); c->mask4 = htonl(0xffffffff << (32 - mask_len)); } @@ -658,7 +658,7 @@ static void conf_ip(struct ctx *c) memcpy(&c->addr4_seen, &c->addr4, sizeof(c->addr4_seen)); if (!memcmp(c->mac, MAC_ZERO, ETH_ALEN)) - nl_link(0, c->ifi, c->mac, 0, 0); + nl_link(0, c->ifi4, c->mac, 0, 0); } if (c->mode == MODE_PASST) @@ -668,9 +668,9 @@ static void conf_ip(struct ctx *c) int prefix_len = 0; if (IN6_IS_ADDR_UNSPECIFIED(&c->gw6)) - nl_route(0, c->ifi, AF_INET6, &c->gw6); + nl_route(0, c->ifi6, AF_INET6, &c->gw6); - nl_addr(0, c->ifi, AF_INET6, + nl_addr(0, c->ifi6, AF_INET6, IN6_IS_ADDR_UNSPECIFIED(&c->addr6) ? &c->addr6 : NULL, &prefix_len, &c->addr6_ll); @@ -883,12 +883,12 @@ static void conf_print(const struct ctx *c) char buf4[INET_ADDRSTRLEN], ifn[IFNAMSIZ]; int i; - if (c->mode == MODE_PASTA) { - info("Outbound interface: %s, namespace interface: %s", - if_indextoname(c->ifi, ifn), c->pasta_ifn); - } else { - info("Outbound interface: %s", if_indextoname(c->ifi, ifn)); - } + if (c->ifi4) + info("Outbound interface (IPv4): %s", if_indextoname(c->ifi4, ifn)); + if (c->ifi6) + info("Outbound interface (IPv6): %s", if_indextoname(c->ifi6, ifn)); + if (c->mode == MODE_PASTA) + info("Namespace interface: %s", c->pasta_ifn); if (c->v4) { info("ARP:"); @@ -1395,12 +1395,12 @@ void conf(struct ctx *c, int argc, char **argv) usage(argv[0]); break; case 'i': - if (c->ifi) { + if (c->ifi4 || c->ifi6) { err("Redundant interface: %s", optarg); usage(argv[0]); } - if (!(c->ifi = if_nametoindex(optarg))) { + if (!(c->ifi4 = c->ifi6 = if_nametoindex(optarg))) { err("Invalid interface name %s: %s", optarg, strerror(errno)); usage(argv[0]); @@ -1559,8 +1559,12 @@ void conf(struct ctx *c, int argc, char **argv) get_dns(c); - if (!*c->pasta_ifn) - if_indextoname(c->ifi, c->pasta_ifn); + if (!*c->pasta_ifn) { + if (c->ifi4) + if_indextoname(c->ifi4, c->pasta_ifn); + else + if_indextoname(c->ifi6, c->pasta_ifn); + } c->tcp.ns_detect_ports = c->udp.ns_detect_ports = 0; c->tcp.init_detect_ports = c->udp.init_detect_ports = 0; diff --git a/passt.h b/passt.h index e541341..23145c6 100644 --- a/passt.h +++ b/passt.h @@ -122,6 +122,7 @@ enum passt_modes { * @mac: Host MAC address * @mac_guest: MAC address of guest or namespace, seen or configured * @v4: Enable IPv4 transport + * @ifi4: Index of routable interface for IPv4 * @addr4: IPv4 address for external, routable interface * @addr4_seen: Latest IPv4 address seen as source from tap * @mask4: IPv4 netmask, network order @@ -130,6 +131,7 @@ enum passt_modes { * @dns4_fwd: Address forwarded (UDP) to first IPv4 DNS, network order * @dns_search: DNS search list * @v6: Enable IPv6 transport + * @ifi6: Index of routable interface for IPv6 * @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 @@ -137,7 +139,6 @@ enum passt_modes { * @gw6: Default IPv6 gateway * @dns6: IPv6 DNS addresses, zero-terminated * @dns6_fwd: Address forwarded (UDP) to first IPv6 DNS, network order - * @ifi: Index of routable interface * @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 @@ -193,6 +194,7 @@ struct ctx { unsigned char mac_guest[ETH_ALEN]; int v4; + unsigned int ifi4; uint32_t addr4; uint32_t addr4_seen; uint32_t mask4; @@ -203,6 +205,7 @@ struct ctx { struct fqdn dns_search[MAXDNSRCH]; int v6; + unsigned int ifi6; struct in6_addr addr6; struct in6_addr addr6_ll; struct in6_addr addr6_seen; @@ -211,7 +214,6 @@ struct ctx { struct in6_addr dns6[MAXNS + 1]; struct in6_addr dns6_fwd; - unsigned int ifi; char pasta_ifn[IF_NAMESIZE]; unsigned int pasta_ifi; int pasta_conf_ns; diff --git a/tcp.c b/tcp.c index 5b84110..3b27f11 100644 --- a/tcp.c +++ b/tcp.c @@ -2207,7 +2207,7 @@ static void tcp_conn_from_tap(struct ctx *c, int af, const void *addr, struct sockaddr_in6 addr6_ll = { .sin6_family = AF_INET6, .sin6_addr = c->addr6_ll, - .sin6_scope_id = c->ifi, + .sin6_scope_id = c->ifi6, }; if (bind(s, (struct sockaddr *)&addr6_ll, sizeof(addr6_ll))) { close(s); diff --git a/util.c b/util.c index 2eea0ef..f4ec102 100644 --- a/util.c +++ b/util.c @@ -280,7 +280,7 @@ int sock_l4(const struct ctx *c, int af, uint8_t proto, if (!memcmp(bind_addr, &c->addr6_ll, sizeof(c->addr6_ll))) - addr6.sin6_scope_id = c->ifi; + addr6.sin6_scope_id = c->ifi6; } else { addr6.sin6_addr = in6addr_any; }