Does netlink use 'broadcast' for passing messages?

639 views Asked by At

I am following netlink example on this question and answer.

But, I don't see a sort of connection identifier in source codes. Say:

Kernel

my_nl_sock = netlink_kernel_create(&init_net, NETLINK_USERSOCK, 0,
                 my_nl_rcv_msg, NULL, THIS_MODULE);

User space

nls = nl_socket_alloc();
ret = nl_connect(nls, NETLINK_USERSOCK);
ret = nl_send_simple(nls, MY_MSG_TYPE, 0, msg, sizeof(msg));

where NETLINK_USERSOCK and MY_MSG_TYPE don't seem to be a connection identifier.

In such a case, how does netlink know which data comes from which user space app or kernel module and which user space app or kernel module the data should go?

In my guess, netlink receives data from user space app or kernel module and broadcasts it. And every netlink-connected app or module checks message type if data is destined to 'me'

Is what I think right?

1

There are 1 answers

0
sim On

Firstly, I recommend to read some doc, for example http://www.linuxfoundation.org/collaborate/workgroups/networking/generic_netlink_howto

To communicate you have to register a family with supported operations. It can be done with the following functions

int genl_register_family( struct genl_family *family)   
int genl_register_ops( struct genl_family * family, struct genl_ops *ops)

An example of a family definition:

/* 
 *  Attributes (variables): the index in this enum is used as a reference for the type,
 *  userspace application has to indicate the corresponding type
 */
enum {
    CTRL_ATT_R_UNSPEC = 0,
    CTRL_ATT_CNT_SESSIONS,
    __CTRL_ATT_R_MAX
};

#define CTRL_ATT_R_MAX ( __CTRL_ATT_R_MAX - 1 )

#define CTRL_FAMILY "your-family"
#define CTRL_PROTO_VERSION 1

/* Family definition */
static struct genl_family ctrl_bin_gnl_family = {
    .id = GENL_ID_GENERATE,         // genetlink should generate an id
    .hdrsize = 0,
    .name = CTRL_FAMILY,            // the name of this family, used by userspace application
    .version = CTRL_PROTO_VERSION,  // version number  
    .maxattr = CTRL_ATT_R_MAX,      // max number of attr 
};

An example of an operation definition:

struct genl_ops ctrl_info = {
    .cmd = CTRL_CMD_INFO,
    .flags = 0,
    .policy = 0,      // you can use policy if you need 
    .doit = 0,        // set this callback if this op does some interval stuff 
    .dumpit = __info, // set this callback if this op dump data
};

After that you can use in your userspace app your family and operations to communicate. Make a connection:

struct nl_sock * _nl = nl_socket_alloc();

int ret = genl_connect(nl);
// test if fail

int gid = genl_ctrl_resolve( nl, CTRL_FAMILY );
// test if fail

Send info operation

struct nl_msg * msg = msg_alloc( 
    CTRL_CMD_INFO,
    NLM_F_DUMP 
);

int ret = nl_send_auto(_nl, msg );
// test if fail
// wait for the ack
// read a reply