Is Anyone Using Netlink for Ipc

Is anyone using netlink for IPC?

What you are looking for is NETLINK_USERSOCK if you want to communicate between userspace processes.

Netlink documentation is awfully scarce unfortunately. This might help a bit: Who can give me the latest netlink programming samples?

Just make sure nl_pid is non-zero and matches what userspace peer is bind'ed to and that you're sending a unicast.

Is there a way I can use netlink for Inter-process communication (IPC) between two user space processes?

Netlink was originally designed to provide kernel-userspace communication. There is no reason why it can't be used for userspace-userspace communication, but that said, I don't see why you would.

If you want to go ahead and use it, you can do so solely in userspace. There is no need to perform any of the setup in kernel space first. Just call socket() using a socket family of AF_NETLINK. To send a message, populate a struct sockaddr_nl and set the nl_pid property appropriately (this is generally set to the PID of the current process), then call sendto(). A standard recv() call can be used to receive messages.

All that said, and given that you say you are new to Linux, I would suggest that you look at Unix domain sockets for your userspace IPC needs since I suspect it would satisfy your requirements and should generally be easier to use. You could also look at message queues which can work quite well in some instances. There is a nice comparison here: Which is better for local IPC, POSIX message queues (mqueues) or Unix domain (local) sockets?. Note that you will need to link against the real-time library (librt) in order to use POSIX message queues. Bi-directional communication using message queues can easily be achieved using a pair of queues, one for each direction.

How to use netlink for IPC?

You are using the wrong kind of protocol to socket. The only one which can do what you want, IPC between user-space processes, is NETLINK_USERSOCK.

Bear in mind that in the way you are arranging communication with PIDs, you might miss some messages... For the purposes of verifying the communication does happen, you can leave msg_name NULL for the receiver and that will have no ill effect(s) - doing so & changing protocol, your code works as expected.

netlink and generic netlink protocol

Netlink protocol number IDs are predefined, and these numbers are not supposed to be reused or overridden. At the same time, the generic netlink allows dynamic protocol resolution via string IDs.

That's the main reason to use the generic netlink protocol for custom applications.

Another difference is that in a plain netlink like RTNL one should pass command type in the type field of the message header, while in the case of the generic netlink the protocol id is passed there:

# nlmsg header
uint32 length;
uint16 type; # command for rtnl and protocol id for genl
uint16 flags;
uint32 sequence_number;
uint32 pid;

The generic netlink command id is passed in the message data:

# genlmsg data
uint8 cmd;
uint8 version;
uint16 reserved;

Thus, all the data for genl should be passed in the NLA chain, while RTNL messages of different types can use the message data section as well.

Some additional info you can find in the docs

Communication between Linux kernel and user space program

There are several ways to implement this.

The easiest is to use the proc file interface to communicate, especially if the message and the result are less than one page in size.

General Sequence would be as under:

  • Implement proc_open(), proc_read() and proc_write(); proc_close();
  • Open and close can implement locking so that only one instance of userspace program can
    actually access the module request engine.

  • the task request is sent via a write to the proc file,

  • The write function will return successfully if the module understands the command, before returning the program will initialize the request processing, the processing can actually take place when the proc file is read if it is trivial. If the processing is significantly complex then i suggest that you read up on bottom halves1 (you can simply start a working queue).

  • The read either triggers the "processing you want the module to do". or waits for the BH to finish the processing in case you do it that way. You can use a spinlock or a mutex to control flow.

  • The kernel processing returns the result upon completion.



Related Topics



Leave a reply



Submit