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);

netlink_ack(skb, nlh, err); } else if (nlh->nlmsg_flags & NLM_F_ACK)

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 with skb_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 with nlmsg_hdr, and the total length including padding is computed with nlmsg_align. audit_receive_msg is then responsible to analyze the audit-specific contents 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_ack is 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 the nlm_f_ack flag, the kernel sends the desired acknowledgment again by netlink_ack. This time the input message is not contained in the reply because the error argument of netlink_ack is set to 0.

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

Continue reading here: Summary

Was this article helpful?

0 0