open wrt netifd netlink

static void
handle_hotplug_msg(char *data, int size)
{       
        const char *subsystem = NULL, *interface = NULL;
        char *cur, *end, *sep;
        struct device *dev;
        int skip;
        bool add;
        
        if (!strncmp(data, "add@", 4))
                add = true;
        else if (!strncmp(data, "remove@", 7))
                add = false;
        else    
                return;
        
        skip = strlen(data) + 1;
        end = data + size;
        
        for (cur = data + skip; cur < end; cur += skip) {
                skip = strlen(cur) + 1;
                
                sep = strchr(cur, '=');
                if (!sep)
                        continue;
                
                *sep = 0;
                if (!strcmp(cur, "INTERFACE"))
                        interface = sep + 1;
                else if (!strcmp(cur, "SUBSYSTEM")) {
                        subsystem = sep + 1;
                        if (strcmp(subsystem, "net") != 0)
                                return;
                }
                if (subsystem && interface)
                        goto found;
        }
        return;

found:  
        dev = device_get(interface, false);
        if (!dev)
                return;
        
        if (dev->type != &simple_device_type)
                return;

        if (add && system_if_force_external(dev->ifname))
                return;

        device_set_present(dev, add);
}


static void
handle_hotplug_event(struct uloop_fd *u, unsigned int events)
{
        struct event_socket *ev = container_of(u, struct event_socket, uloop);
        struct sockaddr_nl nla;
        unsigned char *buf = NULL;
        int size;

        while ((size = nl_recv(ev->sock, &nla, &buf, NULL)) > 0) {
                if (nla.nl_pid == 0)
                        handle_hotplug_msg((char *) buf, size);

                free(buf);
        }
}


static int cb_rtnl_event(struct nl_msg *msg, void *arg)
{
        struct nlmsghdr *nh = nlmsg_hdr(msg);
        struct nlattr *nla[__IFLA_MAX];
        int link_state = 0;
        char buf[10];

        if (nh->nlmsg_type != RTM_NEWLINK)
                goto out;

        nlmsg_parse(nh, sizeof(struct ifinfomsg), nla, __IFLA_MAX - 1, NULL);
        if (!nla[IFLA_IFNAME])
                goto out;

        struct device *dev = device_get(nla_data(nla[IFLA_IFNAME]), false);
        if (!dev || dev->type->keep_link_status)
                goto out;

        if (!system_get_dev_sysctl("/sys/class/net/%s/carrier", dev->ifname, buf, sizeof(buf)))
                link_state = strtoul(buf, NULL, 0);

        device_set_link(dev, link_state ? true : false);

out:
        return 0;
}


int system_init(void)
{
        static struct event_socket rtnl_event;
        static struct event_socket hotplug_event;

        sock_ioctl = socket(AF_LOCAL, SOCK_DGRAM, 0);
        system_fd_set_cloexec(sock_ioctl);

        // Prepare socket for routing / address control
        sock_rtnl = create_socket(NETLINK_ROUTE, 0);
        if (!sock_rtnl)
                return -1;

        if (!create_event_socket(&rtnl_event, NETLINK_ROUTE, cb_rtnl_event))
                return -1;

        if (!create_raw_event_socket(&hotplug_event, NETLINK_KOBJECT_UEVENT, 1,
                                     handle_hotplug_event, 0))
                return -1;

        // Receive network link events form kernel
        nl_socket_add_membership(rtnl_event.sock, RTNLGRP_LINK);

        return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值