Generic netlink howto

1. Registering a family

Registering a family is including four steps: define the family, define operations, register the family, register the operations.

  • Define the family, is just creating an instance of genl_family struct.
    /* attributes */
    enum {
        DOC_EXMPL_A_UNSPEC,
        DOC_EXMPL_A_MSG,
        __DOC_EXMPL_A_MAX,
    };
    
    #define  DOC_EXMPL_A_MAX (__DOC_EXMPL_A_MAX - 1)
    
    /* attribute policy */
    static struct nla_policy doc_exmpl_genl_policy[DOC_EXMPL_A_MAX + 1] = {
        [DOC_EXMPL_A_MSG] = { .type = NLA_NUL_STRING },
    };
    
    /* family definition */
    static struct genl_family doc_exmpl_genl_family = {
        .id = GENL_ID_GENERATE,
        .hdrsize = 0,
        .name = "DOC_EXMPL",
        .version = 1,
        .maxattr = DOC_EXMPL_A_MAX,
    };
    

    We define a new family and the family recognizes a single attribute, DOC_EXMPL_A_MSG, which is a NULL terminated string. The GENL_ID_GENERATE macro/constant is really just the value 0x0 and it signifies that we want the Generic Netlink controller to assign the channel number when we register the family.

  • Define the operations for the family, which we do by creating at least one instance of the genl_ops structure.
    /* handler */
    static int doc_exmpl_echo(struct sk_buff *skb, struct genl_info *info)
    {
        /* message handling code goes here;
            return 0 on success, negative value on failure
        */
    }
    
    /* commands */
    enum {
        DOC_EXMPL_C_UNSPEC,
        DOC_EXMPL_C_ECHO,
        __DOC_EXMPL_C_MAX,
    };
    
    #define DOC_EXMPL_C_MAX (__DOC_EXMPL_C_MAX - 1)
    
    /* operation definition */
    static struct genl_ops doc_exmpl_genl_ops_echo = {
        .cmd = DOC_EXMPL_C_ECHO,
        .flags = 0,
        .policy = doc_exmpl_genl_policy,
        .dumpit  = NULL,
    };
    

    Here we defined a single operation, DOC_EXMPL_C_ECHO, which uses the Netlink attribute policy we defined above. Once registered, this particular  operation would call the doc_exmpl_echo() function whenever a DOC_EXMPL_C_ECHO message is sent to the DOC_EXMPL family over the Generic Netlink bus.

  • Register teh DOC_EXMPL family with the Generic Netlink operation.
    int rc;
    rc = genl_register_family(&doc_exmpl_gnl_family);
    if (rc != 0)
        goto failure;
    

    This call registers the new family name with the Generic Netlink mechanism and requests a new channel number which is stored in the genl_family struct, replacing the GENL_ID_GENERATE value.

  • Register the operations for the family.
    int rc;
    rc = genl_register_ops(&doc_exmpl_gnl_family, &doc_exmpl_gnl_ops_echo);
    if (rc != 0)
        goto failure;
    

    This call registers the DOC_EXMPL_C_ECHO operation in association with the DOC_EXMPL family. After this, other Generic Netlink users can now issue DOC_EXMPL_C_ECHO commands and they will be handled as desired.

2. Kernel communication

  • Sending message is a three step process: allocate memory for the message buffer, create the message, send the message. 
    struct sk_buff *skb;
    skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
    if (skb == NULL)
        goto failure;
    

    NLMSG_GOODSIZE is a good value to use when you don't know the size of the message buffer at the time of allocation. The genlmsg_new() function automatically adds space for the Netlink and Generic Netlink message headers.

    int rc;
    void *msg_head;
    /* create the message headers */
    msg_head = genlmsg_put(skb, pid, seq, type, 0, flags, DOC_EXMPL_C_ECHO, 1);
    if (msg_head == NULL) {
        rc = -ENOMEM;
        goto failure;
    }
    /* add a DOC_EXMPL_A_MSG attribute */
    rc = nla_put_string(skb, DOC_EXMPL_A_MSG, "Generic Netlink Rocks");
    if (rc != 0)
        goto failure;
    /* finalize the message */
    genlmsg_end(skb, msg_head);
    

    The genlmsg_put() function creates the required Netlink and Generic Netlink message headers, populating them with the given values; The nla_put_string() function is a standard Netlink attribute which adds a string attribute to the end of the Netlink message. The genlmsg_end() function updates the Netlink message header once the message payload has been finalized.

    int rc;
    rc = genlmsg_unicast(skb, pid);
    if (rc != 0)
        goto failure;

 

  • Receiving messages Typically, kernel modules act as Generic Netlink servers which means that the act of receiving messages is handled automatically by the Generic Netlink bus. Once the bus receives the message and determines the correct routing, the message is passed directly to the family specific operation callback for processing. If the kernel is acting as a Generic Netlink client, server response messages can be received over the Generic Netlink socket using standard kernel socket interfaces.

 

转载于:https://www.cnblogs.com/memo-store/p/5529050.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值