Linux kernel netfilter module analysis: Registration and invocation of hooks points

Source: Internet
Author: User
Tags prev iptables firewall

-1: Why write this thing?
Recently looking for a job, before netfilter this piece of code also carefully studied, should everyone is such you know not necessarily you can be very accurate expression. So we must take some time to sum up the relevant things.

0: Related documents

Linux under Nf_conntrack_tuple Trace records which can obtain the connection trace record according to the data structure provided by the kernel.

The use of NAT in Iptables summarizes the application of iptable on the firewall.

The hooks of the three tables in the 1:iptable

In fact, this problem is very simple to run iptables open look to know that the hook here and the kernel hook is corresponding.



So the 5 hook points registered in the kernel are as follows:

enum Nf_inet_hooks {
Nf_inet_pre_routing,
Nf_inet_local_in,
Nf_inet_forward,
Nf_inet_local_out,
Nf_inet_post_routing,

Nf_inet_numhooks
};

Before looking down on the implementation in the Linux kernel, look at a packet neitfilter processing in the Linux kernel.

The implementation points of these 5 hook points are described below:
The datagram is processed by the first hook function nf_ip_pre_routing after the IP checksum is entered into the system.
And then enter the routing code, which determines whether the datagram needs to be forwarded or sent to the local machine;
If the datagram is sent to the local computer, the data is processed by the hook function nf_ip_local_in and then passed to the upper layer protocol;
If the datagram should be forwarded, it is nf_ip_forward processed;

The forwarded datagram is transferred to the network after the last hook function nf_ip_post_routing processing.

Locally generated data after the hook function nf_ip_local_out processing, routing processing, and then after nf_ip_post_routing processing sent out.




The image above can be known as the processing point for a packet of hooks in the kernel.
2:p tracking record under ROC documents

The above is the connection tracking record, which records the Linux system established every connection, including source IP, destination IP, source port, destination port, protocol ID, which can be called 5-tuple. For this definition in the Linux inclusion, the variable in the struct nf_conn of the struct body

/* Connection Tracking (link tracking) is used to track and record information for each link (currently only supports connection tracking for IP protocols).
Each link is uniquely identified by "tuple", where the "tuple" has different meanings for different protocols, such as the TCP,UDP
Is five Yuan group: (Source IP, source port, destination IP, destination port, protocol number), for the ICMP protocol is: (source IP, mesh
IP, ID, type, code, where Id,type and code are the ICMP protocol information. Link Tracking is a firewall implementation status check
The basis of the measurement, many functions need to use link tracking to achieve, such as NAT, fast forwarding, and so on. */

/* XXX should I move this to the tail? -Y.K *
/* this are my tuples; Original and Reply * *
struct Nf_conntrack_tuple_hash Tuplehash[ip_ct_dir_max]; This variable holds the trace record above,


definition and registration of 3:hooks points


each of the different hooks in each protocol will eventually be registered in the Global nf_hooks list variable: the processing functions registered to the same hook are processed successively according to the different priorities.

extern struct List_head nf_hooks[nfproto_numproto][nf_max_hooks];

The protocols defined therein are as follows:

enum {
Nfproto_unspec = 0,
Nfproto_ipv4 = 2,//ipv4
Nfproto_arp = 3,//arp
Nfproto_bridge = 7,//brigde
Nfproto_ipv6 = 10,
Nfproto_decnet = 12,
Nfproto_numproto,

};

The definition of the Nf_max_hooks macro is already described earlier. The definition of the hook point.


The difference can be seen in contrast to the struct nf_hook_ops of the following hooks: The value of the variable PF is different, the priority is different, that is, the kernel can register different mount points according to different protocol types to handle different priority packets.


Its registration function is: the Nf_register_hooks () function appears in multiple places in the kernel, because the user can add a hook occurrence function to a particular protocol at a specific location according to their needs.


The implementation of the Nf_register_hook () function is:

int Nf_register_hook (struct nf_hook_ops *reg)
{struct Nf_hook_ops
	;
	int err;

	Err = mutex_lock_interruptible (&nf_hook_mutex);
	if (Err < 0)
		return err;////traverses the registered Hook,ops, adds the newly added based priority to the list last
	list_for_each_entry (Elem, &nf_hooks[ Reg->pf][reg->hooknum], List {
		if (Reg->priority < elem->priority) break
			;
	}
	List_add_rcu (®->list, elem->list.prev);
	Mutex_unlock (&nf_hook_mutex);
	return 0;
}

The above is the registration function of the hook point, which is registered to nf_hooks[][in the global array according to the protocol type and hook point.

4: When the registered hook point is used.

In the Linux kernel, use a function when you need to use a registered hook point:

#define Nf_hook (PF, HOOK, SKB, Indev, Outdev, OKFN) \
Nf_hook_thresh (PF, HOOK, SKB, Indev, Outdev, OKFN, Int_min)


nf_hook->nf_hook_thresh->nf_hook_thresh->nf_hook_slow--This is the final executive function.

Let's take a look at the following function returns a value:

/* Responses from hook functions. */
#define NF_DROP 0
#define NF_ACCEPT 1
#define Nf_stolen 2
#define NF_QUEUE 3
#define NF_REPEAT 4
#define NF_STOP 5
#define NF_MAX_VERDICT Nf_stop

int Nf_hook_slow (u_int8_t pf, unsigned int hook, struct sk_buff *skb,
		 struct net_device *indev,
		 struct net_device *outdev,
		 Int (*OKFN) (struct Sk_buff *),
		 int hook_thresh)
{struct List_head
	;
	unsigned int verdict;
	int ret = 0;

	/* We may already have this, but read-locks nest anyway * * rcu_read_lock
	();

	Elem = &nf_hooks[pf][hook];//is not very familiar is the above global variable is specifically used to register the global hook point variables.
next_hook:/* begins to traverse the corresponding NetFilter rule, that is, the corresponding proto and hook mount point * *
	verdict = Nf_iterate (&nf_hooks[pf][hook), SKB, Hooks, Indev,outdev, &elem, OKFN, Hook_thresh);
	if (verdict = = Nf_accept | | verdict = = nf_stop) {
		ret = 1;
	} else if (verdict = Nf_drop) {
		kfree_skb (SKB);
		ret =-eperm;
	} else if ((Verdict & nf_verdict_mask) = = Nf_queue) {
		if!nf_queue (SKB, Elem, pf, Hook, Indev, Outdev, Okfn
			      , Verdict >> Nf_verdict_bits))
			goto Next_hook;
	Rcu_read_unlock ();
	return ret;
}


Now look at the Nf_iterate () function:

unsigned int nf_iterate (struct list_head *head, struct sk_buff *skb, unsigned int hook, const struct Net_device *
Indev, const struct Net_device *outdev, struct list_head **i, int (*OKFN) (struct Sk_buff *), int hook_thresh) {unsigned int verdict;//Where Head is the global 2-D array nf_hooks, * * The caller must not block between calls to this * function b
	 Ecause of risk of continuing from deleted element.

		* * LIST_FOR_EACH_CONTINUE_RCU (*i, head) {struct Nf_hook_ops *elem = (struct nf_hook_ops *) *i;

		if (Hook_thresh > Elem->priority) continue; /* Optimization:we don ' t need to hold module reference here, since function can ' t sleep. --RR/verdict = Elem->hook (hooks, SKB, Indev, Outdev, OKFN);//execute the processing function that hangs on the protocol and Hook Point if (verdict!=) {//return knot
Fruit to judge. #ifdef Config_netfilter_debug if (Unlikely (Verdict & Nf_verdict_mask) > Nf_max_verdict)) {Nfdebug ("
				Evil return from%p (%u). \ n ", Elem->hook, Hook);
			Continue } #enDIF if (verdict!= Nf_repeat) return verdict;
		*i = (*i)->prev;
} return nf_accept; }

The explanations for each return value are as follows:

nf_drop: Drop off the packet directly; nf_accept: The packet passed all the rules of the mount point; Nf_stolen: This has not appeared, left behind to explain; Nf_queue: Enque the packet to the Enque handler of user space; Nf_repeat: As an internal judgment result of NetFilter, it is necessary to repeat the rule until it is not nf_repeat; Nf_stop: The packet passed all the rules for the mount point. However, when different from the nf_accept, when the result of a rule is nf_stop, then the result can be returned directly nf_stop without any subsequent judgment. and nf_accept need so the rules are ACCEPT, in order to return to nf_accept.

In the entire process of packets flowing through the kernel stack, such as pre_routing, local_in, FORWARD, Local_out, and post_routing in the defined hooks are based on the packet's protocol cluster pf_ Inet to these key points to find out if there is a hook function registered. If not, return directly to the function pointed to by the OKFN function pointer to continue the stack; if so, call the Nf_hook_slow function to go to the netfilter frame to further invoke the hook function that has been registered under the filter point. Based on its return value to determine whether to continue executing the function pointed to by the function pointer okfn

an IP packet acceptance process is as follows:










Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.