Netlink与Genetlink接口执行流程简要分析:

netlink_proto_init  ///< 内核层
    proto_register(&netlink_proto, 0);
    nl_table = kcalloc(MAX_LINKS, sizeof(*nl_table), GFP_KERNEL);
    netlink_add_usersock_entry();
    sock_register(&netlink_family_ops);

sys_socket  ///< 应用层
    retval = sock_create(family, type, protocol, &sock);
        pf = rcu_dereference(net_families[family]);
        err = pf->create(net, sock, protocol, kern);
            netlink_create
                __netlink_create(net, sock, cb_mutex, protocol, kern);
                    sk->sk_data_ready = sock_def_readable;        ///< 应用层注册为-

sys_bind ///< bind之后可以使用 recv、recvmsg 接收消息
    sock = sockfd_lookup_light(fd, &err, &fput_needed);
    err = move_addr_to_kernel(umyaddr, addrlen, &address);
    err = security_socket_bind(sock, (struct sockaddr *)&address, addrlen);
    err = sock->ops->bind(sock, (struct sockaddr *)&address, addrlen);

sys_send  ///< 内核层
    sys_sendto
        import_single_range(WRITE, buff, len, &iov, &msg.msg_iter);
        sockfd_lookup_light(fd, &err, &fput_needed);
        move_addr_to_kernel(addr, addr_len, &address);
        sock_sendmsg(sock, &msg);
            netlink_sendmsg
                memcpy_from_msg(skb_put(skb, len), msg, len)
                security_netlink_send(sk, skb);
          /* 单播 */ netlink_unicast(sk, skb, dst_portid, msg->msg_flags&MSG_DONTWAIT); netlink_unicast_kernel(sk, skb, ssk); nlk->netlink_rcv(skb); ///< 之前 nlk_sk(sk)->netlink_rcv = cfg->input; /* 多播 */ netlink_broadcast(sk, skb, dst_portid, dst_group, GFP_KERNEL); netlink_broadcast_filtered sk_for_each_bound(sk, &nl_table[ssk->sk_protocol].mc_list) do_one_broadcast(sk, &info); netlink_broadcast_deliver(sk, p->skb2); __netlink_sendskb(sk, skb); sk->sk_data_ready(sk); BUG(); sys_recv  ///< 内核层 sys_recvfrom sock = sockfd_lookup_light(fd, &err, &fput_needed); err = sock_recvmsg(sock, &msg, flags); security_socket_recvmsg(sock, msg, msg_data_left(msg), flags); sock_recvmsg_nosec(sock, msg, flags); sock->ops->recvmsg(sock, msg, msg_data_left(msg), flags); netlink_recvmsg skb = skb_recv_datagram(sk, flags, noblock, &err); __skb_try_recv_datagram __skb_wait_for_more_packets prepare_to_wait_exclusive(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); ///< 阻塞等待消息 nlmsg_unicast  ///< 内核层 netlink_unicast(sk, skb, portid, MSG_DONTWAIT); netlink_sendskb(sk, skb); __netlink_sendskb(sk, skb); sk->sk_data_ready(sk); ///< sock_def_readable sock_def_readable wake_up_interruptible_sync_poll(&wq->wait, POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND); ///< 唤醒 ------------------------------------------------------------------------------------------------------------- genetlink genl_register_family(&genl_ctrl)  ///< 内核层 genl_validate_ops(family); family->id = idr_alloc(&genl_fam_idr, family, start, end + 1, GFP_KERNEL); ///< 加入genl_fam_idr, 分配ID register_pernet_subsys(&genl_pernet_ops); ///< 注册netlink .input = genl_rcv  ///< 接收函数 netlink_rcv_skb(skb, &genl_rcv_msg); family = genl_family_find_byid(nlh->nlmsg_type); ///< 通过ID找到family genl_family_rcv_msg(family, skb, nlh, extack); ops = genl_get_cmd(hdr->cmd, family); nlmsg_parse(nlh, hdrlen, attrbuf, family->maxattr, ops->policy, extack); tb[type] = (struct nlattr *)nla; ///< tb <==> attrbuf info.attrs = attrbuf; ops->doit(skb, &info); if (info->attrs[CTRL_ATTR_FAMILY_NAME]) res = genl_family_find_byname(name); msg = ctrl_build_family_msg(res, info->snd_portid, info->snd_seq, CTRL_CMD_NEWFAMILY); genlmsg_reply(msg, info);

详细的分析过程可以查看这位博主的文章,很全面:blog.csdn.net/luckyapple1028/article/details/50839395

12-16 21:57