Skip to content

Commit e5b9c45

Browse files
committed
add GETLINK IFF_UP check
1 parent f102e6a commit e5b9c45

File tree

1 file changed

+61
-5
lines changed

1 file changed

+61
-5
lines changed

src/net/linux/addrs.c

+61-5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#define DEBUG_LEVEL 5
2121
#include <re_dbg.h>
2222

23+
enum { BUFSZ = 8192, MAXIF = 255 };
24+
2325

2426
static void parse_rtattr(struct rtattr *tb[], struct rtattr *rta, int len)
2527
{
@@ -42,8 +44,38 @@ static bool is_ipv6_deprecated(uint32_t flags)
4244
return false;
4345
}
4446

45-
static bool parse_msg(struct nlmsghdr *msg, int len, net_ifaddr_h *ifh,
46-
void *arg)
47+
48+
static bool parse_msg_link(struct nlmsghdr *msg, size_t len, int *iff_up)
49+
{
50+
struct nlmsghdr *nlh;
51+
struct ifinfomsg *ifi;
52+
53+
for (nlh = msg; NLMSG_OK(nlh, len); nlh = NLMSG_NEXT(nlh, len)) {
54+
if (nlh->nlmsg_type == NLMSG_DONE) {
55+
return true;
56+
}
57+
if (nlh->nlmsg_type == NLMSG_ERROR) {
58+
DEBUG_WARNING("netlink recv error\n");
59+
return true;
60+
}
61+
62+
ifi = NLMSG_DATA(nlh);
63+
64+
if (ifi->ifi_index >= MAXIF) {
65+
DEBUG_WARNING("Max interface index [%d] reached!\n",
66+
MAXIF);
67+
return false;
68+
}
69+
70+
iff_up[ifi->ifi_index] = ifi->ifi_flags & IFF_UP;
71+
}
72+
73+
return false;
74+
}
75+
76+
77+
static bool parse_msg_addr(struct nlmsghdr *msg, size_t len, net_ifaddr_h *ifh,
78+
int *iff_up, void *arg)
4779
{
4880
struct nlmsghdr *nlh;
4981
for (nlh = msg; NLMSG_OK(nlh, len); nlh = NLMSG_NEXT(nlh, len)) {
@@ -56,7 +88,7 @@ static bool parse_msg(struct nlmsghdr *msg, int len, net_ifaddr_h *ifh,
5688
}
5789
if (nlh->nlmsg_type == NLMSG_ERROR) {
5890
DEBUG_WARNING("netlink recv error\n");
59-
return false;
91+
return true;
6092
}
6193

6294
struct ifaddrmsg *ifa = NLMSG_DATA(nlh);
@@ -68,6 +100,9 @@ static bool parse_msg(struct nlmsghdr *msg, int len, net_ifaddr_h *ifh,
68100
if (!rta_tb[IFA_ADDRESS])
69101
continue;
70102

103+
if (ifa->ifa_index < MAXIF && !iff_up[ifa->ifa_index])
104+
continue;
105+
71106
if (rta_tb[IFA_FLAGS] && ifa->ifa_family == AF_INET6) {
72107
flags = *(uint32_t *)RTA_DATA(rta_tb[IFA_FLAGS]);
73108
if (is_ipv6_deprecated(flags))
@@ -100,9 +135,10 @@ static bool parse_msg(struct nlmsghdr *msg, int len, net_ifaddr_h *ifh,
100135
int net_netlink_addrs(net_ifaddr_h *ifh, void *arg)
101136
{
102137
int err = 0;
103-
char buffer[8192];
138+
char buffer[BUFSZ];
104139
re_sock_t sock;
105140
int len;
141+
int iff_up[MAXIF] = {0};
106142

107143
struct {
108144
struct nlmsghdr nlh;
@@ -121,6 +157,25 @@ int net_netlink_addrs(net_ifaddr_h *ifh, void *arg)
121157
struct timeval timeout = {5, 0};
122158
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
123159

160+
/* GETLINK */
161+
memset(&req, 0, sizeof(req));
162+
req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
163+
req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
164+
req.nlh.nlmsg_type = RTM_GETLINK;
165+
166+
if (send(sock, &req, req.nlh.nlmsg_len, 0) < 0) {
167+
err = errno;
168+
DEBUG_WARNING("sendto failed %m\n", err);
169+
goto out;
170+
}
171+
172+
while ((len = (int)recv(sock, buffer, sizeof(buffer), 0)) > 0) {
173+
if (parse_msg_link((struct nlmsghdr *)buffer, (size_t)len,
174+
iff_up))
175+
break;
176+
}
177+
178+
/* GETADDR */
124179
memset(&req, 0, sizeof(req));
125180
req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
126181
req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
@@ -133,7 +188,8 @@ int net_netlink_addrs(net_ifaddr_h *ifh, void *arg)
133188
}
134189

135190
while ((len = (int)recv(sock, buffer, sizeof(buffer), 0)) > 0) {
136-
if (parse_msg((struct nlmsghdr *)buffer, len, ifh, arg))
191+
if (parse_msg_addr((struct nlmsghdr *)buffer, (size_t)len, ifh,
192+
iff_up, arg))
137193
break;
138194
}
139195

0 commit comments

Comments
 (0)