Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 12: Networks


<netfilter.h>
#define NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, thresh) \
({int __ret; \
if ((__ret=nf_hook_thresh(pf, hook, &(skb), indev, outdev, okfn, thresh, 1)) == 1)\
__ret = (okfn)(skb); \
__ret;})

#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \
NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, INT_MIN)

The macro arguments have the following meanings:

❑ pfrefers to the protocol family from which the called netfilter hook should originate. All calls in
the IPv4 layer usePF_INET.
❑ hookis the hook number; possible values are defined in<netfilter_ipv4.h>. The values have
names such asNF_IP_FORWARDandNF_IP_LOCAL_OUTin IPv4, as mentioned above.
❑ skbis the socket buffer being processed.
❑ indevandoutdevare pointers tonet_deviceinstances of the network devices via which the
packet enters and leaves the kernel.
Null pointers can be assigned to these values because this information is not known for all hooks
(e.g., before routing is performed, the kernel does not know via which device a packet will leave
the kernel).
❑ okfnis a pointer to a function with prototypeint (*okfn)(struct sk_buff *).Itisexecuted
when the netfilter hook terminates.

The macro expansion makes a detour overNF_HOOK_THRESHandnf_hook_threshbeforenf_hook_slow
will take care of processing the netfilter hook and calling the continuation function. This seemingly com-
plicated way is necessary because the kernel also provides the possibility to consider only netfilter hooks
whose priority is above a certain threshold and skip all others. In the case ofNF_HOOK,thethresholdisset
to the smallest possible integer value so every hook function is considered. Nevertheless, it is possible
to useNF_HOOK_THRESHdirectly to set a specific threshold. Since only the bridging implementation and
connection tracking for IPv6 make use of this currently, I will not discuss it any further.

Consider the implementation ofNF_HOOK_THRESH.First,nf_hook_threshis called. The function checks
if the condition given incondis true. If that is not so, then 1 is directly passed to the caller. Otherwise,
nf_hook_slowis called. The function iterates over all registered netfilter hooks and calls them. If the
packet is accepted, 1 is returned, and otherwise some other value.

Ifnf_hook_threshreturned 1, that is, if the netfilter verdict was to accept the packet, then control is
passed to the continuation function specified inokfn.

The IP forwarding code includes a typicalNF_HOOKmacro call, which we will consider as an example:

net/ipv4/in_forward.c
int ip_forward(struct sk_buff *skb)
{
...
return NF_HOOK(PF_INET, NF_IP_FORWARD, skb, skb->dev, rt->u.dst.dev,
ip_forward_finish);
}
Free download pdf