netlink, conf: Actually get prefix/mask length

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
Stefano Brivio 2021-10-19 09:01:27 +02:00
parent 1ac0d52820
commit 17600d6d6e
4 changed files with 24 additions and 10 deletions

10
conf.c
View file

@ -469,7 +469,11 @@ static void conf_ip(struct ctx *c)
nl_route(0, c->ifi, AF_INET, &c->gw4); nl_route(0, c->ifi, AF_INET, &c->gw4);
if (!c->addr4) { if (!c->addr4) {
nl_addr(0, c->ifi, AF_INET, &c->addr4, 0, NULL); int mask_len = 0;
nl_addr(0, c->ifi, AF_INET, &c->addr4, &mask_len, NULL);
c->mask4 = htonl(0xffffffff << (32 - mask_len));
if (!c->mask4) { if (!c->mask4) {
if (IN_CLASSA(ntohl(c->addr4))) if (IN_CLASSA(ntohl(c->addr4)))
c->mask4 = htonl(IN_CLASSA_NET); c->mask4 = htonl(IN_CLASSA_NET);
@ -492,12 +496,14 @@ static void conf_ip(struct ctx *c)
memset(&c->mac_guest, 0xff, sizeof(c->mac_guest)); memset(&c->mac_guest, 0xff, sizeof(c->mac_guest));
if (v6 != IP_VERSION_DISABLED) { if (v6 != IP_VERSION_DISABLED) {
int prefix_len = 0;
if (IN6_IS_ADDR_UNSPECIFIED(&c->gw6)) if (IN6_IS_ADDR_UNSPECIFIED(&c->gw6))
nl_route(0, c->ifi, AF_INET6, &c->gw6); nl_route(0, c->ifi, AF_INET6, &c->gw6);
nl_addr(0, c->ifi, AF_INET6, nl_addr(0, c->ifi, AF_INET6,
IN6_IS_ADDR_UNSPECIFIED(&c->addr6) ? &c->addr6 : NULL, IN6_IS_ADDR_UNSPECIFIED(&c->addr6) ? &c->addr6 : NULL,
0, &c->addr6_ll); &prefix_len, &c->addr6_ll);
memcpy(&c->addr6_seen, &c->addr6, sizeof(c->addr4_seen)); memcpy(&c->addr6_seen, &c->addr6, sizeof(c->addr4_seen));
memcpy(&c->addr6_ll_seen, &c->addr6, sizeof(c->addr4_seen)); memcpy(&c->addr6_ll_seen, &c->addr6, sizeof(c->addr4_seen));

View file

@ -346,10 +346,11 @@ next:
* @ifi: Interface index * @ifi: Interface index
* @af: Address family * @af: Address family
* @addr: Global address to fill if zero, to set if not, ignored if NULL * @addr: Global address to fill if zero, to set if not, ignored if NULL
* @prefix_len: Mask or prefix length, set or fetched (for IPv4)
* @addr_l: Link-scoped address to fill, NULL if not requested * @addr_l: Link-scoped address to fill, NULL if not requested
*/ */
void nl_addr(int ns, unsigned int ifi, sa_family_t af, void nl_addr(int ns, unsigned int ifi, sa_family_t af,
void *addr, int prefix_len, void *addr_l) void *addr, int *prefix_len, void *addr_l)
{ {
int set = addr && ((af == AF_INET6 && !IN6_IS_ADDR_UNSPECIFIED(addr)) || int set = addr && ((af == AF_INET6 && !IN6_IS_ADDR_UNSPECIFIED(addr)) ||
(af == AF_INET && *(uint32_t *)addr)); (af == AF_INET && *(uint32_t *)addr));
@ -380,7 +381,7 @@ void nl_addr(int ns, unsigned int ifi, sa_family_t af,
.ifa.ifa_family = af, .ifa.ifa_family = af,
.ifa.ifa_index = ifi, .ifa.ifa_index = ifi,
.ifa.ifa_prefixlen = prefix_len, .ifa.ifa_prefixlen = *prefix_len,
}; };
struct ifaddrmsg *ifa; struct ifaddrmsg *ifa;
struct nlmsghdr *nh; struct nlmsghdr *nh;
@ -430,12 +431,14 @@ void nl_addr(int ns, unsigned int ifi, sa_family_t af,
if (rta->rta_type != IFA_ADDRESS) if (rta->rta_type != IFA_ADDRESS)
continue; continue;
if (af == AF_INET && addr && !*(uint32_t *)addr) if (af == AF_INET && addr && !*(uint32_t *)addr) {
memcpy(addr, RTA_DATA(rta), RTA_PAYLOAD(rta)); memcpy(addr, RTA_DATA(rta), RTA_PAYLOAD(rta));
else if (af == AF_INET6 && addr && *prefix_len = ifa->ifa_prefixlen;
} else if (af == AF_INET6 && addr &&
ifa->ifa_scope == RT_SCOPE_UNIVERSE && ifa->ifa_scope == RT_SCOPE_UNIVERSE &&
IN6_IS_ADDR_UNSPECIFIED(addr)) IN6_IS_ADDR_UNSPECIFIED(addr)) {
memcpy(addr, RTA_DATA(rta), RTA_PAYLOAD(rta)); memcpy(addr, RTA_DATA(rta), RTA_PAYLOAD(rta));
}
if (addr_l && if (addr_l &&
af == AF_INET6 && ifa->ifa_scope == RT_SCOPE_LINK && af == AF_INET6 && ifa->ifa_scope == RT_SCOPE_LINK &&

View file

@ -2,5 +2,5 @@ int nl_sock_init(struct ctx *c);
unsigned int nl_get_ext_if(int *v4, int *v6); unsigned int nl_get_ext_if(int *v4, int *v6);
void nl_route(int ns, unsigned int ifi, sa_family_t af, void *gw); 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 nl_addr(int ns, unsigned int ifi, sa_family_t af,
void *addr, int prefix_len, void *addr_l); void *addr, int *prefix_len, void *addr_l);
void nl_link(int ns, unsigned int ifi, void *mac, int up, int mtu); void nl_link(int ns, unsigned int ifi, void *mac, int up, int mtu);

View file

@ -233,16 +233,21 @@ void pasta_ns_conf(struct ctx *c)
nl_link(1, 1 /* lo */, MAC_ZERO, 1, 0); nl_link(1, 1 /* lo */, MAC_ZERO, 1, 0);
if (c->pasta_conf_ns) { if (c->pasta_conf_ns) {
int prefix_len;
nl_link(1, c->pasta_ifi, c->mac_guest, 1, c->mtu); nl_link(1, c->pasta_ifi, c->mac_guest, 1, c->mtu);
if (c->v4) { if (c->v4) {
prefix_len = __builtin_popcount(c->mask4);
nl_addr(1, c->pasta_ifi, AF_INET, &c->addr4, nl_addr(1, c->pasta_ifi, AF_INET, &c->addr4,
__builtin_popcount(c->mask4), NULL); &prefix_len, NULL);
nl_route(1, c->pasta_ifi, AF_INET, &c->gw4); nl_route(1, c->pasta_ifi, AF_INET, &c->gw4);
} }
if (c->v6) { if (c->v6) {
nl_addr(1, c->pasta_ifi, AF_INET6, &c->addr6, 64, NULL); prefix_len = 64;
nl_addr(1, c->pasta_ifi, AF_INET6, &c->addr6,
&prefix_len, NULL);
nl_route(1, c->pasta_ifi, AF_INET6, &c->gw6); nl_route(1, c->pasta_ifi, AF_INET6, &c->gw6);
} }
} else { } else {