X-Git-Url: http://git.archive.openwrt.org/?a=blobdiff_plain;f=system-linux.c;h=9d6451fdbd524a19bf72de93f2cfdad4718bc419;hb=37d529a958dfbcbb35404b0255506690b4537552;hp=e313cbc97934bf37f410e180419fe66bef039f99;hpb=beecba5195b2f1180f0bdfb6f61f0dbd3dff0eba;p=project%2Fnetifd.git diff --git a/system-linux.c b/system-linux.c index e313cbc..9d6451f 100644 --- a/system-linux.c +++ b/system-linux.c @@ -24,17 +24,29 @@ #include "device.h" #include "system.h" +struct event_socket { + struct uloop_fd uloop; + struct nl_sock *sock; + struct nl_cb *cb; +}; + static int sock_ioctl = -1; static struct nl_sock *sock_rtnl = NULL; -static struct nl_sock *sock_rtnl_event = NULL; -static void handler_rtnl_event(struct uloop_fd *u, unsigned int events); static int cb_rtnl_event(struct nl_msg *msg, void *arg); -static struct uloop_fd rtnl_event = {.cb = handler_rtnl_event}; -static struct nl_cb *nl_cb_rtnl_event; + +static void handler_nl_event(struct uloop_fd *u, unsigned int events) +{ + struct event_socket *ev = container_of(u, struct event_socket, uloop); + nl_recvmsgs(ev->sock, ev->cb); +} int system_init(void) { + static struct event_socket rtnl_event = { + .uloop.cb = handler_nl_event, + }; + sock_ioctl = socket(AF_LOCAL, SOCK_DGRAM, 0); fcntl(sock_ioctl, F_SETFD, fcntl(sock_ioctl, F_GETFD) | FD_CLOEXEC); @@ -44,47 +56,30 @@ int system_init(void) return -1; if (nl_connect(sock_rtnl, NETLINK_ROUTE)) - goto error_free_sock; + return -1; // Prepare socket for link events - nl_cb_rtnl_event = nl_cb_alloc(NL_CB_DEFAULT); - if (!nl_cb_rtnl_event) - goto error_free_sock; + rtnl_event.cb = nl_cb_alloc(NL_CB_DEFAULT); + if (!rtnl_event.cb) + return -1; - nl_cb_set(nl_cb_rtnl_event, NL_CB_VALID, NL_CB_CUSTOM, + nl_cb_set(rtnl_event.cb, NL_CB_VALID, NL_CB_CUSTOM, cb_rtnl_event, NULL); - sock_rtnl_event = nl_socket_alloc(); - if (!sock_rtnl_event) - goto error_free_cb; + rtnl_event.sock = nl_socket_alloc(); + if (!rtnl_event.sock) + return -1; - if (nl_connect(sock_rtnl_event, NETLINK_ROUTE)) - goto error_free_event; + if (nl_connect(rtnl_event.sock, NETLINK_ROUTE)) + return -1; // Receive network link events form kernel - nl_socket_add_membership(sock_rtnl_event, RTNLGRP_LINK); + nl_socket_add_membership(rtnl_event.sock, RTNLGRP_LINK); - rtnl_event.fd = nl_socket_get_fd(sock_rtnl_event); - uloop_fd_add(&rtnl_event, ULOOP_READ | ULOOP_EDGE_TRIGGER); + rtnl_event.uloop.fd = nl_socket_get_fd(rtnl_event.sock); + uloop_fd_add(&rtnl_event.uloop, ULOOP_READ | ULOOP_EDGE_TRIGGER); return 0; - -error_free_event: - nl_socket_free(sock_rtnl_event); - sock_rtnl_event = NULL; -error_free_cb: - nl_cb_put(nl_cb_rtnl_event); - nl_cb_rtnl_event = NULL; -error_free_sock: - nl_socket_free(sock_rtnl); - sock_rtnl = NULL; - return -1; -} - -// If socket is ready for reading parse netlink events -static void handler_rtnl_event(struct uloop_fd *u, unsigned int events) -{ - nl_recvmsgs(sock_rtnl_event, nl_cb_rtnl_event); } static void system_set_sysctl(const char *path, const char *val) @@ -101,7 +96,7 @@ static void system_set_sysctl(const char *path, const char *val) static void system_set_dev_sysctl(const char *path, const char *device, const char *val) { - char buf[256]; + static char buf[256]; snprintf(buf, sizeof(buf), path, val); system_set_sysctl(buf, val); @@ -367,9 +362,12 @@ out: */ void system_if_clear_state(struct device *dev) { - char buf[256]; + static char buf[256]; char *bridge; + if (dev->external) + return; + dev->ifindex = system_if_resolve(dev); if (!dev->ifindex) return; @@ -562,7 +560,17 @@ static int system_addr(struct device *dev, struct device_addr *addr, int cmd) .ifa_index = dev->ifindex, }; - struct nl_msg *msg = nlmsg_alloc_simple(cmd, 0); + struct nl_msg *msg; + + dev = addr->device; + if (dev) { + if (!dev->ifindex) + return -1; + + ifa.ifa_index = dev->ifindex; + } + + msg = nlmsg_alloc_simple(cmd, 0); if (!msg) return -1; @@ -586,6 +594,7 @@ static int system_rt(struct device *dev, struct device_route *route, int cmd) int alen = ((route->flags & DEVADDR_FAMILY) == DEVADDR_INET4) ? 4 : 16; bool have_gw; unsigned int flags = 0; + int ifindex = dev->ifindex; if (alen == 4) have_gw = !!route->nexthop.in.s_addr; @@ -606,11 +615,20 @@ static int system_rt(struct device *dev, struct device_route *route, int cmd) .rtm_scope = scope, .rtm_type = (cmd == RTM_DELROUTE) ? 0: RTN_UNICAST, }; + struct nl_msg *msg; if (cmd == RTM_NEWROUTE) flags |= NLM_F_CREATE | NLM_F_REPLACE; - struct nl_msg *msg = nlmsg_alloc_simple(cmd, flags); + dev = route->device; + if (dev) { + if (!dev->ifindex) + return -1; + + ifindex = dev->ifindex; + } + + msg = nlmsg_alloc_simple(cmd, flags); if (!msg) return -1; @@ -623,7 +641,7 @@ static int system_rt(struct device *dev, struct device_route *route, int cmd) nla_put(msg, RTA_GATEWAY, alen, &route->nexthop); if (route->flags & DEVADDR_DEVICE) - nla_put_u32(msg, RTA_OIF, dev->ifindex); + nla_put_u32(msg, RTA_OIF, ifindex); return system_rtnl_call(msg); }