aboutgitcodebugslistschat
diff options
context:
space:
mode:
-rw-r--r--conf.c19
-rw-r--r--netlink.c79
-rw-r--r--netlink.h2
-rw-r--r--test/dhcp/passt3
-rw-r--r--test/dhcp/pasta3
-rw-r--r--test/ndp/passt4
-rw-r--r--test/two_guests/basic3
7 files changed, 33 insertions, 80 deletions
diff --git a/conf.c b/conf.c
index 943526d..cc08de3 100644
--- a/conf.c
+++ b/conf.c
@@ -630,8 +630,23 @@ static void conf_ip(struct ctx *c)
v4 = v6 = IP_VERSION_PROBE;
}
- if (!c->ifi4 && !c->ifi6)
- c->ifi4 = c->ifi6 = nl_get_ext_if(&v4, &v6);
+ if (v4 != IP_VERSION_DISABLED) {
+ if (!c->ifi4)
+ c->ifi4 = nl_get_ext_if(AF_INET);
+ if (!c->ifi4) {
+ warn("No external routable interface for IPv4");
+ v4 = IP_VERSION_DISABLED;
+ }
+ }
+
+ if (v6 != IP_VERSION_DISABLED) {
+ if (!c->ifi6)
+ c->ifi6 = nl_get_ext_if(AF_INET6);
+ if (!c->ifi6) {
+ warn("No external routable interface for IPv6");
+ v6 = IP_VERSION_DISABLED;
+ }
+ }
if (v4 != IP_VERSION_DISABLED) {
if (!c->gw4)
diff --git a/netlink.c b/netlink.c
index 66a95e4..8ad6a0c 100644
--- a/netlink.c
+++ b/netlink.c
@@ -126,13 +126,13 @@ static int nl_req(int ns, char *buf, const void *req, ssize_t len)
}
/**
- * nl_get_ext_if() - Get interface index supporting IP versions being probed
- * @v4: Probe IPv4 support, set to ENABLED or DISABLED on return
- * @v6: Probe IPv4 support, set to ENABLED or DISABLED on return
+ * nl_get_ext_if() - Get interface index supporting IP version being probed
+ * @af: Address family (AF_INET or AF_INET6) to look for connectivity
+ * for.
*
* Return: interface index, 0 if not found
*/
-unsigned int nl_get_ext_if(int *v4, int *v6)
+unsigned int nl_get_ext_if(sa_family_t af)
{
struct { struct nlmsghdr nlh; struct rtmsg rtm; } req = {
.nlh.nlmsg_type = RTM_GETROUTE,
@@ -143,32 +143,14 @@ unsigned int nl_get_ext_if(int *v4, int *v6)
.rtm.rtm_table = RT_TABLE_MAIN,
.rtm.rtm_scope = RT_SCOPE_UNIVERSE,
.rtm.rtm_type = RTN_UNICAST,
+ .rtm.rtm_family = af,
};
- unsigned int i, first_v4 = 0, first_v6 = 0;
- uint8_t has_v4[PAGE_SIZE * 8 / 8] = { 0 }; /* See __dev_alloc_name() */
- uint8_t has_v6[PAGE_SIZE * 8 / 8] = { 0 }; /* in kernel */
struct nlmsghdr *nh;
struct rtattr *rta;
struct rtmsg *rtm;
char buf[BUFSIZ];
- long *word, tmp;
- uint8_t *vmap;
ssize_t n;
size_t na;
- int *v;
-
- if (*v4 == IP_VERSION_PROBE) {
- v = v4;
- req.rtm.rtm_family = AF_INET;
- vmap = has_v4;
- } else if (*v6 == IP_VERSION_PROBE) {
-v6:
- v = v6;
- req.rtm.rtm_family = AF_INET6;
- vmap = has_v6;
- } else {
- return 0;
- }
if ((n = nl_req(0, buf, &req, sizeof(req))) < 0)
return 0;
@@ -178,7 +160,7 @@ v6:
for ( ; NLMSG_OK(nh, n); nh = NLMSG_NEXT(nh, n)) {
rtm = (struct rtmsg *)NLMSG_DATA(nh);
- if (rtm->rtm_dst_len || rtm->rtm_family != req.rtm.rtm_family)
+ if (rtm->rtm_dst_len || rtm->rtm_family != af)
continue;
for (rta = RTM_RTA(rtm), na = RTM_PAYLOAD(nh); RTA_OK(rta, na);
@@ -190,57 +172,10 @@ v6:
ifi = *(unsigned int *)RTA_DATA(rta);
- if (*v4 == IP_VERSION_DISABLED ||
- *v6 == IP_VERSION_DISABLED) {
- *v = IP_VERSION_ENABLED;
- return ifi;
- }
-
- if (v == v4 && !first_v4)
- first_v4 = ifi;
-
- if (v == v6 && !first_v6)
- first_v6 = ifi;
-
- bitmap_set(vmap, ifi);
+ return ifi;
}
}
- if (v == v4 && *v6 == IP_VERSION_PROBE) {
- req.nlh.nlmsg_seq = nl_seq++;
- goto v6;
- }
-
- word = (long *)has_v4;
- for (i = 0; i < ARRAY_SIZE(has_v4) / sizeof(long); i++, word++) {
- tmp = *word;
- while ((n = ffsl(tmp))) {
- int ifi = i * sizeof(long) * 8 + n - 1;
-
- if (!first_v4)
- first_v4 = ifi;
-
- tmp &= ~(1UL << (n - 1));
- if (bitmap_isset(has_v6, ifi)) {
- *v4 = *v6 = IP_VERSION_ENABLED;
- return ifi;
- }
- }
- }
-
- if (first_v4) {
- *v4 = IP_VERSION_ENABLED;
- *v6 = IP_VERSION_DISABLED;
- return first_v4;
- }
-
- if (first_v6) {
- *v4 = IP_VERSION_DISABLED;
- *v6 = IP_VERSION_ENABLED;
- return first_v6;
- }
-
- err("No external routable interface for any IP protocol");
return 0;
}
diff --git a/netlink.h b/netlink.h
index 261904e..5ce5037 100644
--- a/netlink.h
+++ b/netlink.h
@@ -7,7 +7,7 @@
#define NETLINK_H
int nl_sock_init(const struct ctx *c);
-unsigned int nl_get_ext_if(int *v4, int *v6);
+unsigned int nl_get_ext_if(sa_family_t af);
void nl_route(int ns, unsigned int ifi, sa_family_t af, void *gw);
void nl_addr(int ns, unsigned int ifi, sa_family_t af,
void *addr, int *prefix_len, void *addr_l);
diff --git a/test/dhcp/passt b/test/dhcp/passt
index f45227a..11e0eb3 100644
--- a/test/dhcp/passt
+++ b/test/dhcp/passt
@@ -17,6 +17,7 @@ htools ip jq sed tr head
test Interface name
gout IFNAME ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname'
hout HOST_IFNAME ip -j -4 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]'
+hout HOST_IFNAME6 ip -j -6 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]'
check [ -n "__IFNAME__" ]
test DHCP: address
@@ -49,7 +50,7 @@ check [ "__SEARCH__" = "__HOST_SEARCH__" ]
test DHCPv6: address
guest /sbin/dhclient -6 __IFNAME__
gout ADDR6 ip -j -6 addr show|jq -rM '.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.prefixlen == 128).local'
-hout HOST_ADDR6 ip -j -6 addr show|jq -rM '.[] | select(.ifname == "__HOST_IFNAME__").addr_info[] | select(.scope == "global").local'
+hout HOST_ADDR6 ip -j -6 addr show|jq -rM '.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global").local'
check [ "__ADDR6__" = "__HOST_ADDR6__" ]
test DHCPv6: route
diff --git a/test/dhcp/pasta b/test/dhcp/pasta
index 65b1d42..076ec8d 100644
--- a/test/dhcp/pasta
+++ b/test/dhcp/pasta
@@ -35,8 +35,9 @@ check [ __MTU__ = 65520 ]
test DHCPv6: address
ns /sbin/dhclient -6 --no-pid __IFNAME__
+hout HOST_IFNAME6 ip -j -6 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]'
nsout ADDR6 ip -j -6 addr show|jq -rM '.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.prefixlen == 128).local'
-hout HOST_ADDR6 ip -j -6 addr show|jq -rM '.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.scope == "global").local'
+hout HOST_ADDR6 ip -j -6 addr show|jq -rM '.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global").local'
check [ __ADDR6__ = __HOST_ADDR6__ ]
test DHCPv6: route
diff --git a/test/ndp/passt b/test/ndp/passt
index d6b4c40..8ef15e7 100644
--- a/test/ndp/passt
+++ b/test/ndp/passt
@@ -17,13 +17,13 @@ htools ip jq sipcalc grep cut
test Interface name
gout IFNAME ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname'
guest ip link set dev __IFNAME__ up && sleep 2
-hout HOST_IFNAME ip -j -4 route show|jq -rM '.[] | select(.dst == "default").dev'
+hout HOST_IFNAME6 ip -j -6 route show|jq -rM '.[] | select(.dst == "default").dev'
check [ -n "__IFNAME__" ]
test SLAAC: prefix
gout ADDR6 ip -j -6 addr show|jq -rM '.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.scope == "global" and .prefixlen == 64).local'
gout PREFIX6 sipcalc __ADDR6__/64 | grep prefix | cut -d' ' -f4
-hout HOST_ADDR6 ip -j -6 addr show|jq -rM '.[] | select(.ifname == "__HOST_IFNAME__").addr_info[] | select(.scope == "global").local'
+hout HOST_ADDR6 ip -j -6 addr show|jq -rM '.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global").local'
hout HOST_PREFIX6 sipcalc __HOST_ADDR6__/64 | grep prefix | cut -d' ' -f4
check [ "__PREFIX6__" = "__HOST_PREFIX6__" ]
diff --git a/test/two_guests/basic b/test/two_guests/basic
index f7c016d..e226178 100644
--- a/test/two_guests/basic
+++ b/test/two_guests/basic
@@ -19,6 +19,7 @@ test Interface names
g1out IFNAME1 ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname'
g2out IFNAME2 ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname'
hout HOST_IFNAME ip -j -4 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]'
+hout HOST_IFNAME6 ip -j -6 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]'
check [ -n "__IFNAME1__" ]
check [ -n "__IFNAME2__" ]
@@ -40,7 +41,7 @@ guest1 /sbin/dhclient -6 __IFNAME1__
guest2 /sbin/dhclient -6 __IFNAME2__
g1out ADDR1_6 ip -j -6 addr show|jq -rM '.[] | select(.ifname == "__IFNAME1__").addr_info[] | select(.prefixlen == 128).local'
g2out ADDR2_6 ip -j -6 addr show|jq -rM '.[] | select(.ifname == "__IFNAME2__").addr_info[] | select(.prefixlen == 128).local'
-hout HOST_ADDR6 ip -j -6 addr show|jq -rM '.[] | select(.ifname == "__HOST_IFNAME__").addr_info[] | select(.scope == "global").local'
+hout HOST_ADDR6 ip -j -6 addr show|jq -rM '.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global").local'
check [ "__ADDR1_6__" = "__HOST_ADDR6__" ]
check [ "__ADDR2_6__" = "__HOST_ADDR6__" ]