Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 12: Networks


Naturally, things get more involved when bidirectional communication is allowed. Take, for example,
the audit subsystem, which can not only send messages to userspace, but also receive some in the inverse
direction. First of all, an input function is required whennetlink_kernel_createis called:

kernel/audit.c
audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT, 0,
audit_receive, NULL, THIS_MODULE);

audit_receiveis responsible to handle received messages stored in socket buffers.audit_receiveis
just a wrapper that ensures correct locking and dispatches the real work toaudit_receive_skb.Sinceall
receive functions follow a similar pattern, it is instructive to observe the code of this function:

kernel/audit.c
static void audit_receive_skb(struct sk_buff *skb)
{
int err;
struct nlmsghdr *nlh;
u32 rlen;

while (skb->len >= NLMSG_SPACE(0)) {
nlh = nlmsg_hdr(skb);
...
rlen = NLMSG_ALIGN(nlh->nlmsg_len);
...
if ((err = audit_receive_msg(skb, nlh))) {
netlink_ack(skb, nlh, err);
} else if (nlh->nlmsg_flags & NLM_F_ACK)
netlink_ack(skb, nlh, 0);
skb_pull(skb, rlen);
}
}

Multiple netlink messages can be contained in a single socket buffer, so the kernel needs to iterate over
all of them until no more payload is left. This is the purpose of the while loop. The general structure is to
process one message, remove the processed data withskb_pull,^40 and process the next message. Since
NLMSG_SPACE(0)specifies the space required for the netlink header, without any payload, the kernel can
easily check if more messages wait to be processed by comparing the remaining length of the socket
buffer with this quantity.

For each message, the header is extracted withnlmsg_hdr, and the total length including padding is
computed withNLMSG_ALIGN.audit_receive_msgis then responsible to analyze the audit-specific con-
tents of the message, which does not concern us any further here. Once the data have been parsed, two
alternatives are possible:


  1. An error has occurred during parsing.netlink_ackis used to send an acknowledgment
    response that contains the erroneous message and the error code.

  2. If the message requested to be acknowledged by setting theNLM_F_ACKflag, the kernel sends
    the desired acknowledgment again bynetlink_ack. This time the input message is not con-
    tained in the reply because the error argument ofnetlink_ackis set to 0.


(^40) To be precise, the function does not remove the data, but just sets thedatapointer of the socket buffer accordingly. The effect is,
however, identical.

Free download pdf