conf: Avoid getifaddrs(), split L2/L3 address fetching, get filtered dumps
getifaddrs() needs to allocate heap memory, and gets a ton of results we don't need. Use explicit netlink messages with "strict checking" instead. While at it, separate L2/L3 address handling, so that we don't fetch MAC addresses for IPv6, and also use netlink instead of ioctl() to get the MAC address. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
e871fa9f22
commit
580581fd96
2 changed files with 179 additions and 133 deletions
276
conf.c
276
conf.c
|
@ -267,14 +267,27 @@ overlap:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct nl_request - Netlink request filled and sent by get_routes()
|
* nl_req() - Send netlink request and read response, doesn't return on failure
|
||||||
* @nlh: Netlink message header
|
* @buf: Buffer for response (BUFSIZ long)
|
||||||
* @rtm: Routing Netlink message
|
* @req: Request with netlink header
|
||||||
|
* @len: Request length
|
||||||
*/
|
*/
|
||||||
struct nl_request {
|
static void nl_req(char *buf, void *req, ssize_t len)
|
||||||
struct nlmsghdr nlh;
|
{
|
||||||
struct rtmsg rtm;
|
int s = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE), v = 1;
|
||||||
};
|
struct sockaddr_nl addr = { .nl_family = AF_NETLINK, };
|
||||||
|
|
||||||
|
if (s < 0 ||
|
||||||
|
setsockopt(s, SOL_NETLINK, NETLINK_GET_STRICT_CHK, &v, sizeof(v)) ||
|
||||||
|
bind(s, (struct sockaddr *)&addr, sizeof(addr)) ||
|
||||||
|
(send(s, req, len, 0) < len) ||
|
||||||
|
(recv(s, buf, BUFSIZ, 0) < 0)) {
|
||||||
|
perror("netlink recv");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
close(s);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get_routes() - Get default route and fill in routable interface name
|
* get_routes() - Get default route and fill in routable interface name
|
||||||
|
@ -282,57 +295,33 @@ struct nl_request {
|
||||||
*/
|
*/
|
||||||
static void get_routes(struct ctx *c)
|
static void get_routes(struct ctx *c)
|
||||||
{
|
{
|
||||||
struct nl_request req = {
|
struct { struct nlmsghdr nlh; struct rtmsg rtm; } req = {
|
||||||
.nlh.nlmsg_type = RTM_GETROUTE,
|
.nlh.nlmsg_type = RTM_GETROUTE,
|
||||||
.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP | NLM_F_EXCL,
|
.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP | NLM_F_EXCL,
|
||||||
.nlh.nlmsg_len = sizeof(struct nl_request),
|
.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)),
|
||||||
.nlh.nlmsg_seq = 1,
|
.nlh.nlmsg_seq = 1,
|
||||||
.rtm.rtm_family = AF_INET,
|
.rtm.rtm_family = AF_INET,
|
||||||
.rtm.rtm_table = RT_TABLE_MAIN,
|
.rtm.rtm_table = RT_TABLE_MAIN,
|
||||||
.rtm.rtm_scope = RT_SCOPE_UNIVERSE,
|
.rtm.rtm_scope = RT_SCOPE_UNIVERSE,
|
||||||
.rtm.rtm_type = RTN_UNICAST,
|
.rtm.rtm_type = RTN_UNICAST,
|
||||||
};
|
};
|
||||||
struct sockaddr_nl addr = {
|
char ifn[IFNAMSIZ], buf[BUFSIZ];
|
||||||
.nl_family = AF_NETLINK,
|
struct nlmsghdr *nh;
|
||||||
};
|
|
||||||
struct nlmsghdr *nlh;
|
|
||||||
int s, n, na, v4, v6;
|
|
||||||
char ifn[IFNAMSIZ];
|
|
||||||
struct rtattr *rta;
|
struct rtattr *rta;
|
||||||
struct rtmsg *rtm;
|
struct rtmsg *rtm;
|
||||||
char buf[BUFSIZ];
|
int n, na, v4, v6;
|
||||||
|
|
||||||
if (!c->v4 && !c->v6)
|
if (!c->v4 && !c->v6)
|
||||||
v4 = v6 = -1;
|
v4 = v6 = -1;
|
||||||
else
|
else
|
||||||
v6 = -!(v4 = -c->v4);
|
v6 = -!(v4 = -c->v4);
|
||||||
|
|
||||||
s = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
|
||||||
if (s < 0) {
|
|
||||||
perror("netlink socket");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
|
||||||
perror("netlink bind");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
v6:
|
v6:
|
||||||
if (send(s, &req, sizeof(req), 0) < 0) {
|
nl_req(buf, &req, sizeof(req));
|
||||||
perror("netlink send");
|
nh = (struct nlmsghdr *)buf;
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
n = recv(s, &buf, sizeof(buf), 0);
|
for ( ; NLMSG_OK(nh, n); nh = NLMSG_NEXT(nh, n)) {
|
||||||
if (n < 0) {
|
rtm = (struct rtmsg *)NLMSG_DATA(nh);
|
||||||
perror("netlink recv");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
nlh = (struct nlmsghdr *)buf;
|
|
||||||
for ( ; NLMSG_OK(nlh, n); nlh = NLMSG_NEXT(nlh, n)) {
|
|
||||||
rtm = (struct rtmsg *)NLMSG_DATA(nlh);
|
|
||||||
|
|
||||||
if (rtm->rtm_dst_len ||
|
if (rtm->rtm_dst_len ||
|
||||||
(rtm->rtm_family != AF_INET && rtm->rtm_family != AF_INET6))
|
(rtm->rtm_family != AF_INET && rtm->rtm_family != AF_INET6))
|
||||||
|
@ -342,7 +331,7 @@ v6:
|
||||||
if (*c->ifn) {
|
if (*c->ifn) {
|
||||||
*ifn = 0;
|
*ifn = 0;
|
||||||
for (rta = (struct rtattr *)RTM_RTA(rtm),
|
for (rta = (struct rtattr *)RTM_RTA(rtm),
|
||||||
na = RTM_PAYLOAD(nlh);
|
na = RTM_PAYLOAD(nh);
|
||||||
RTA_OK(rta, na); rta = RTA_NEXT(rta, na)) {
|
RTA_OK(rta, na); rta = RTA_NEXT(rta, na)) {
|
||||||
if (rta->rta_type != RTA_OIF)
|
if (rta->rta_type != RTA_OIF)
|
||||||
continue;
|
continue;
|
||||||
|
@ -355,7 +344,7 @@ v6:
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (rta = (struct rtattr *)RTM_RTA(rtm), na = RTM_PAYLOAD(nlh);
|
for (rta = (struct rtattr *)RTM_RTA(rtm), na = RTM_PAYLOAD(nh);
|
||||||
RTA_OK(rta, na); rta = RTA_NEXT(rta, na)) {
|
RTA_OK(rta, na); rta = RTA_NEXT(rta, na)) {
|
||||||
if (!*c->ifn && rta->rta_type == RTA_OIF)
|
if (!*c->ifn && rta->rta_type == RTA_OIF)
|
||||||
if_indextoname(*(unsigned *)RTA_DATA(rta), ifn);
|
if_indextoname(*(unsigned *)RTA_DATA(rta), ifn);
|
||||||
|
@ -380,23 +369,18 @@ v6:
|
||||||
}
|
}
|
||||||
|
|
||||||
next:
|
next:
|
||||||
if (nlh->nlmsg_type == NLMSG_DONE)
|
if (nh->nlmsg_type == NLMSG_DONE)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v6 == -1) {
|
if (v6 < 0 && req.rtm.rtm_family == AF_INET) {
|
||||||
req.rtm.rtm_family = AF_INET6;
|
req.rtm.rtm_family = AF_INET6;
|
||||||
req.nlh.nlmsg_seq++;
|
req.nlh.nlmsg_seq++;
|
||||||
recv(s, &buf, sizeof(buf), 0);
|
|
||||||
v6--;
|
|
||||||
goto v6;
|
goto v6;
|
||||||
} else if (v6 < 0) {
|
} else if (v6 < 0) {
|
||||||
v6 = 0;
|
v6 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
close(s);
|
|
||||||
|
|
||||||
if ((v4 <= 0 && v6 <= 0) || (!*c->ifn && !*ifn)) {
|
if ((v4 <= 0 && v6 <= 0) || (!*c->ifn && !*ifn)) {
|
||||||
err("No routing information");
|
err("No routing information");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
@ -409,80 +393,98 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get_addrs() - Fetch MAC, IP addresses, masks of external routable interface
|
* get_l3_addrs() - Fetch IP addresses of external routable interface
|
||||||
* @c: Execution context
|
* @c: Execution context
|
||||||
*/
|
*/
|
||||||
static void get_addrs(struct ctx *c)
|
static void get_l3_addrs(struct ctx *c)
|
||||||
{
|
{
|
||||||
struct ifreq ifr = {
|
struct { struct nlmsghdr nlh; struct ifaddrmsg ifa; } req = {
|
||||||
.ifr_addr.sa_family = AF_INET,
|
.nlh.nlmsg_type = RTM_GETADDR,
|
||||||
|
.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP,
|
||||||
|
.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)),
|
||||||
|
.nlh.nlmsg_seq = 1,
|
||||||
|
.ifa.ifa_family = AF_INET,
|
||||||
|
.ifa.ifa_index = if_nametoindex(c->ifn),
|
||||||
};
|
};
|
||||||
struct ifaddrs *ifaddr, *ifa;
|
struct ifaddrmsg *ifa;
|
||||||
int s, v4 = 0, v6 = 0;
|
struct nlmsghdr *nh;
|
||||||
|
struct rtattr *rta;
|
||||||
|
int n, na, v4, v6;
|
||||||
|
char buf[BUFSIZ];
|
||||||
|
|
||||||
if (getifaddrs(&ifaddr) == -1) {
|
if (c->v4) {
|
||||||
perror("getifaddrs");
|
v4 = -1;
|
||||||
goto out;
|
if ((c->addr4_seen = c->addr4))
|
||||||
}
|
|
||||||
|
|
||||||
if (c->addr4) {
|
|
||||||
c->addr4_seen = c->addr4;
|
|
||||||
v4 = 1;
|
v4 = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c->v6) {
|
||||||
|
v6 = -2;
|
||||||
if (!IN6_IS_ADDR_UNSPECIFIED(&c->addr6)) {
|
if (!IN6_IS_ADDR_UNSPECIFIED(&c->addr6)) {
|
||||||
memcpy(&c->addr6_seen, &c->addr6, sizeof(c->addr6));
|
memcpy(&c->addr6_seen, &c->addr6, sizeof(c->addr6));
|
||||||
memcpy(&c->addr6_ll_seen, &c->addr6, sizeof(c->addr6));
|
memcpy(&c->addr6_ll_seen, &c->addr6, sizeof(c->addr6));
|
||||||
v6 = 1;
|
v6 = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill in any missing information */
|
next_v:
|
||||||
for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
|
if (v4 < 0)
|
||||||
struct sockaddr_in *in_addr;
|
req.ifa.ifa_family = AF_INET;
|
||||||
struct sockaddr_in *in_mask;
|
else if (v6 < 0)
|
||||||
struct sockaddr_in6 *in6_addr;
|
req.ifa.ifa_family = AF_INET6;
|
||||||
|
else
|
||||||
|
goto mask_only;
|
||||||
|
|
||||||
if (strcmp(ifa->ifa_name, c->ifn))
|
nl_req(buf, &req, sizeof(req));
|
||||||
|
nh = (struct nlmsghdr *)buf;
|
||||||
|
|
||||||
|
for ( ; NLMSG_OK(nh, n); nh = NLMSG_NEXT(nh, n)) {
|
||||||
|
if (nh->nlmsg_type != RTM_NEWADDR)
|
||||||
|
goto next;
|
||||||
|
|
||||||
|
ifa = (struct ifaddrmsg *)NLMSG_DATA(nh);
|
||||||
|
|
||||||
|
for (rta = (struct rtattr *)IFA_RTA(ifa), na = RTM_PAYLOAD(nh);
|
||||||
|
RTA_OK(rta, na); rta = RTA_NEXT(rta, na)) {
|
||||||
|
if (rta->rta_type != IFA_ADDRESS)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!ifa->ifa_addr)
|
if (v4 < 0) {
|
||||||
continue;
|
memcpy(&c->addr4, RTA_DATA(rta),
|
||||||
|
sizeof(c->addr4));
|
||||||
in_addr = (struct sockaddr_in *)ifa->ifa_addr;
|
memcpy(&c->addr4_seen, RTA_DATA(rta),
|
||||||
if (ifa->ifa_addr->sa_family == AF_INET && !c->addr4) {
|
sizeof(c->addr4_seen));
|
||||||
c->addr4_seen = c->addr4 = in_addr->sin_addr.s_addr;
|
|
||||||
v4 = 1;
|
v4 = 1;
|
||||||
}
|
} else if (v6 < 0) {
|
||||||
|
if (v6 == -2 &&
|
||||||
if (ifa->ifa_addr->sa_family == AF_INET && !c->mask4 &&
|
ifa->ifa_scope == RT_SCOPE_UNIVERSE) {
|
||||||
in_addr->sin_addr.s_addr == c->addr4) {
|
memcpy(&c->addr6, RTA_DATA(rta),
|
||||||
in_mask = (struct sockaddr_in *)ifa->ifa_netmask;
|
|
||||||
c->mask4 = in_mask->sin_addr.s_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ifa->ifa_addr->sa_family == AF_INET6) {
|
|
||||||
in6_addr = (struct sockaddr_in6 *)ifa->ifa_addr;
|
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(&in6_addr->sin6_addr) &&
|
|
||||||
IN6_IS_ADDR_UNSPECIFIED(&c->addr6_ll)) {
|
|
||||||
memcpy(&c->addr6_ll, &in6_addr->sin6_addr,
|
|
||||||
sizeof(c->addr6_ll));
|
|
||||||
} else if (IN6_IS_ADDR_UNSPECIFIED(&c->addr6)) {
|
|
||||||
memcpy(&c->addr6, &in6_addr->sin6_addr,
|
|
||||||
sizeof(c->addr6));
|
sizeof(c->addr6));
|
||||||
memcpy(&c->addr6_seen, &in6_addr->sin6_addr,
|
memcpy(&c->addr6_seen, RTA_DATA(rta),
|
||||||
sizeof(c->addr6_seen));
|
|
||||||
memcpy(&c->addr6_ll_seen, &in6_addr->sin6_addr,
|
|
||||||
sizeof(c->addr6_seen));
|
sizeof(c->addr6_seen));
|
||||||
|
memcpy(&c->addr6_ll_seen, RTA_DATA(rta),
|
||||||
|
sizeof(c->addr6_ll_seen));
|
||||||
|
} else if (ifa->ifa_scope == RT_SCOPE_LINK) {
|
||||||
|
memcpy(&c->addr6_ll, RTA_DATA(rta),
|
||||||
|
sizeof(c->addr6_ll));
|
||||||
|
}
|
||||||
|
if (!IN6_IS_ADDR_UNSPECIFIED(&c->addr6) &&
|
||||||
|
!IN6_IS_ADDR_UNSPECIFIED(&c->addr6_ll))
|
||||||
v6 = 1;
|
v6 = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
next:
|
||||||
|
if (nh->nlmsg_type == NLMSG_DONE)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
freeifaddrs(ifaddr);
|
if (v4 >= 0 && v6 < 0)
|
||||||
|
goto next_v;
|
||||||
|
|
||||||
if (v4 < c->v4 || v6 < c->v6)
|
if (v4 < c->v4 || v6 < c->v6)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
mask_only:
|
||||||
if (v4 && !c->mask4) {
|
if (v4 && !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);
|
||||||
|
@ -494,31 +496,71 @@ static void get_addrs(struct ctx *c)
|
||||||
c->mask4 = 0xffffffff;
|
c->mask4 = 0xffffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!memcmp(c->mac, ((uint8_t [ETH_ALEN]){ 0 }), ETH_ALEN)) {
|
|
||||||
s = socket(AF_INET, SOCK_DGRAM, 0);
|
|
||||||
if (s < 0) {
|
|
||||||
perror("socket SIOCGIFHWADDR");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(ifr.ifr_name, c->ifn, IF_NAMESIZE);
|
|
||||||
if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
|
|
||||||
perror("SIOCGIFHWADDR");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
close(s);
|
|
||||||
memcpy(c->mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&c->mac_guest, 0xff, sizeof(c->mac_guest));
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
out:
|
out:
|
||||||
err("Couldn't get addresses for routable interface");
|
err("Couldn't get addresses for routable interface");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_l2_addr() - Fetch hardware addresses of external routable interface
|
||||||
|
* @c: Execution context
|
||||||
|
*/
|
||||||
|
static void get_l2_addr(struct ctx *c)
|
||||||
|
{
|
||||||
|
struct { struct nlmsghdr nlh; struct ifinfomsg ifi; } req = {
|
||||||
|
.nlh.nlmsg_type = RTM_GETLINK,
|
||||||
|
.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP_FILTERED,
|
||||||
|
.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
|
||||||
|
.nlh.nlmsg_seq = 1,
|
||||||
|
.ifi.ifi_family = AF_UNSPEC,
|
||||||
|
.ifi.ifi_index = if_nametoindex(c->ifn),
|
||||||
|
};
|
||||||
|
struct ifinfomsg *ifi;
|
||||||
|
struct nlmsghdr *nh;
|
||||||
|
struct rtattr *rta;
|
||||||
|
char buf[BUFSIZ];
|
||||||
|
int n, na;
|
||||||
|
|
||||||
|
if (memcmp(c->mac, ((uint8_t [ETH_ALEN]){ 0 }), ETH_ALEN))
|
||||||
|
goto mac_guest;
|
||||||
|
|
||||||
|
nl_req(buf, &req, sizeof(req));
|
||||||
|
nh = (struct nlmsghdr *)buf;
|
||||||
|
|
||||||
|
for ( ; NLMSG_OK(nh, n); nh = NLMSG_NEXT(nh, n)) {
|
||||||
|
if (nh->nlmsg_type != RTM_NEWLINK)
|
||||||
|
goto next;
|
||||||
|
|
||||||
|
ifi = (struct ifinfomsg *)NLMSG_DATA(nh);
|
||||||
|
|
||||||
|
for (rta = (struct rtattr *)IFLA_RTA(ifi), na = RTM_PAYLOAD(nh);
|
||||||
|
RTA_OK(rta, na); rta = RTA_NEXT(rta, na)) {
|
||||||
|
if (rta->rta_type != IFLA_ADDRESS)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
memcpy(c->mac, RTA_DATA(rta), ETH_ALEN);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
next:
|
||||||
|
if (nh->nlmsg_type == NLMSG_DONE)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!memcmp(c->mac, ((uint8_t [ETH_ALEN]){ 0 }), ETH_ALEN))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
mac_guest:
|
||||||
|
if (memcmp(c->mac_guest, ((uint8_t [ETH_ALEN]){ 0 }), ETH_ALEN))
|
||||||
|
memset(&c->mac_guest, 0xff, sizeof(c->mac_guest));
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
out:
|
||||||
|
err("Couldn't get hardware address for routable interface");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get_dns() - Get nameserver addresses from local /etc/resolv.conf
|
* get_dns() - Get nameserver addresses from local /etc/resolv.conf
|
||||||
* @c: Execution context
|
* @c: Execution context
|
||||||
|
@ -888,6 +930,8 @@ void conf_print(struct ctx *c)
|
||||||
inet_ntop(AF_INET6, &c->addr6, buf6, sizeof(buf6)));
|
inet_ntop(AF_INET6, &c->addr6, buf6, sizeof(buf6)));
|
||||||
info(" router: %s",
|
info(" router: %s",
|
||||||
inet_ntop(AF_INET6, &c->gw6, buf6, sizeof(buf6)));
|
inet_ntop(AF_INET6, &c->gw6, buf6, sizeof(buf6)));
|
||||||
|
info(" our link-local: %s",
|
||||||
|
inet_ntop(AF_INET6, &c->addr6_ll, buf6, sizeof(buf6)));
|
||||||
|
|
||||||
for (i = 0; !IN6_IS_ADDR_UNSPECIFIED(&c->dns6[i]); i++) {
|
for (i = 0; !IN6_IS_ADDR_UNSPECIFIED(&c->dns6[i]); i++) {
|
||||||
if (!i)
|
if (!i)
|
||||||
|
@ -1290,7 +1334,9 @@ void conf(struct ctx *c, int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
get_routes(c);
|
get_routes(c);
|
||||||
get_addrs(c);
|
get_l3_addrs(c);
|
||||||
|
if (c->v4)
|
||||||
|
get_l2_addr(c);
|
||||||
|
|
||||||
if (c->mode == MODE_PASTA && dns4 == c->dns4 && dns6 == c->dns6)
|
if (c->mode == MODE_PASTA && dns4 == c->dns4 && dns6 == c->dns6)
|
||||||
c->no_dns = 1;
|
c->no_dns = 1;
|
||||||
|
|
2
passt.h
2
passt.h
|
@ -98,7 +98,7 @@ enum passt_modes {
|
||||||
* @fd_tap_listen: File descriptor for listening AF_UNIX socket, if any
|
* @fd_tap_listen: File descriptor for listening AF_UNIX socket, if any
|
||||||
* @fd_tap: File descriptor for AF_UNIX socket or tuntap device
|
* @fd_tap: File descriptor for AF_UNIX socket or tuntap device
|
||||||
* @mac: Host MAC address
|
* @mac: Host MAC address
|
||||||
* @mac_guest: Guest MAC address
|
* @mac_guest: MAC address of guest or namespace, seen or configured
|
||||||
* @v4: Enable IPv4 transport
|
* @v4: Enable IPv4 transport
|
||||||
* @addr4: IPv4 address for external, routable interface
|
* @addr4: IPv4 address for external, routable interface
|
||||||
* @addr4_seen: Latest IPv4 address seen as source from tap
|
* @addr4_seen: Latest IPv4 address seen as source from tap
|
||||||
|
|
Loading…
Reference in a new issue