Commit 0b324400 authored by Matthieu Boutier's avatar Matthieu Boutier Committed by Juliusz Chroboczek

Refactor netlink: link import.

parent 87f55f5e
...@@ -112,6 +112,19 @@ kernel_addr_notify(struct kernel_addr *addr, void *closure) ...@@ -112,6 +112,19 @@ kernel_addr_notify(struct kernel_addr *addr, void *closure)
return -1; return -1;
} }
static int
kernel_link_notify(struct kernel_link *link, void *closure)
{
struct interface *ifp;
FOR_ALL_INTERFACES(ifp) {
if(strcmp(ifp->name, link->ifname) == 0) {
kernel_link_changed = 1;
return -1;
}
}
return 0;
}
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
...@@ -605,6 +618,7 @@ main(int argc, char **argv) ...@@ -605,6 +618,7 @@ main(int argc, char **argv)
struct kernel_filter filter = {0}; struct kernel_filter filter = {0};
filter.route = kernel_route_notify; filter.route = kernel_route_notify;
filter.addr = kernel_addr_notify; filter.addr = kernel_addr_notify;
filter.link = kernel_link_notify;
kernel_callback(&filter); kernel_callback(&filter);
} }
......
...@@ -41,12 +41,18 @@ struct kernel_addr { ...@@ -41,12 +41,18 @@ struct kernel_addr {
unsigned int ifindex; unsigned int ifindex;
}; };
struct kernel_link {
char *ifname;
};
struct kernel_filter { struct kernel_filter {
/* return -1 to interrupt search. */ /* return -1 to interrupt search. */
int (*addr)(struct kernel_addr *, void *); int (*addr)(struct kernel_addr *, void *);
void *addr_closure; void *addr_closure;
int (*route)(struct kernel_route *, void *); int (*route)(struct kernel_route *, void *);
void *route_closure; void *route_closure;
int (*link)(struct kernel_link *, void *);
void *link_closure;
}; };
#define ROUTE_FLUSH 0 #define ROUTE_FLUSH 0
......
...@@ -1335,14 +1335,12 @@ parse_addr_rta(struct ifaddrmsg *addr, int len, struct in6_addr *res) ...@@ -1335,14 +1335,12 @@ parse_addr_rta(struct ifaddrmsg *addr, int len, struct in6_addr *res)
} }
static int static int
filter_link(struct nlmsghdr *nh, void *data) filter_link(struct nlmsghdr *nh, struct kernel_link *link)
{ {
struct ifinfomsg *info; struct ifinfomsg *info;
int len; int len;
int ifindex; int ifindex;
char *ifname;
unsigned int ifflags; unsigned int ifflags;
struct interface *ifp;
len = nh->nlmsg_len; len = nh->nlmsg_len;
...@@ -1355,16 +1353,12 @@ filter_link(struct nlmsghdr *nh, void *data) ...@@ -1355,16 +1353,12 @@ filter_link(struct nlmsghdr *nh, void *data)
ifindex = info->ifi_index; ifindex = info->ifi_index;
ifflags = info->ifi_flags; ifflags = info->ifi_flags;
ifname = parse_ifname_rta(info, len); link->ifname = parse_ifname_rta(info, len);
if(ifname == NULL) if(link->ifname == NULL)
return 0; return 0;
kdebugf("filter_interfaces: link change on if %s(%d): 0x%x\n", kdebugf("filter_interfaces: link change on if %s(%d): 0x%x\n",
ifname, ifindex, (unsigned)ifflags); link->ifname, ifindex, (unsigned)ifflags);
FOR_ALL_INTERFACES(ifp) { return 1;
if(strcmp(ifp->name, ifname) == 0)
return 1;
}
return 0;
} }
/* If data is null, takes all addresses. If data is not null, takes /* If data is null, takes all addresses. If data is not null, takes
...@@ -1408,6 +1402,7 @@ filter_netlink(struct nlmsghdr *nh, struct kernel_filter *filter) ...@@ -1408,6 +1402,7 @@ filter_netlink(struct nlmsghdr *nh, struct kernel_filter *filter)
union { union {
struct kernel_route route; struct kernel_route route;
struct kernel_addr addr; struct kernel_addr addr;
struct kernel_link link;
} u; } u;
switch(nh->nlmsg_type) { switch(nh->nlmsg_type) {
...@@ -1419,10 +1414,10 @@ filter_netlink(struct nlmsghdr *nh, struct kernel_filter *filter) ...@@ -1419,10 +1414,10 @@ filter_netlink(struct nlmsghdr *nh, struct kernel_filter *filter)
return filter->route(&u.route, filter->route_closure); return filter->route(&u.route, filter->route_closure);
case RTM_NEWLINK: case RTM_NEWLINK:
case RTM_DELLINK: case RTM_DELLINK:
rc = filter_link(nh, NULL); if(!filter->link) break;
if(changed && rc > 0) rc = filter_link(nh, &u.link);
*changed |= CHANGE_LINK; if(rc <= 0) break;
return rc; return filter->link(&u.link, filter->link_closure);
case RTM_NEWADDR: case RTM_NEWADDR:
case RTM_DELADDR: case RTM_DELADDR:
if(!filter->addr) break; if(!filter->addr) break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment