linux网络协议处理函数

2021-02-17

内核版本:linux-source-4.19

协议处理函数的注册

无论是系统启动或其他时刻,当一个协议注册时,内核就会调用dev_add_pack,把一个定义在include/linux.netdevice.h类型为packet_type的数据结构传进去。

struct packet_type {
    __be16          type;   /* This is really htons(ether_type). */
    struct net_device   *dev;   /* NULL is wildcarded here       */
    int         (*func) (struct sk_buff *,
                     struct net_device *,
                     struct packet_type *,
                     struct net_device *);
    void            (*list_func) (struct list_head *,
                          struct packet_type *,
                          struct net_device *);
    bool            (*id_match)(struct packet_type *ptype,
                        struct sock *sk);
    void            *af_packet_priv;
    struct list_head    list;
};

为每个协议注册时,内核会对packet_type结构做初始化,然后调用dev_add_pack

当IPv4协议在引导期间初始化时,ip_init函数会被执行。其中一种结果是,IPv4 packet_type 结构中的函数ip_rcv会注册成此协议的函数处理函数。所有Ethernet帧接收时,若ETH_P_IP的值为Protocol Above,就会由函数ip_rcv处理。

ipv4对应的例子

// linux/net/ipv4/af_inet.c
static struct packet_type ip_packet_type __read_mostly = {
    .type = cpu_to_be16(ETH_P_IP),
    .func = ip_rcv,
    .list_func = ip_list_rcv,
};    
static int __init inet_init(void)
{
    struct inet_protosw *q;
    struct list_head *r;
    int rc = -EINVAL;

    sock_skb_cb_check_size(sizeof(struct inet_skb_parm));
    ...
    dev_add_pack(&ip_packet_type);
    ...  
}
words: 448 tags: linux kernel