1/* This is a module which is used for setting the NFMARK field of an skb. */
2#include <linux/module.h>
3#include <linux/skbuff.h>
4#include <linux/ip.h>
5#include <net/checksum.h>
6
7#include <linux/netfilter_ipv4/ip_tables.h>
8#include <linux/netfilter_ipv4/ipt_MARK.h>
9
10static unsigned int
11target(struct sk_buff **pskb,
12       unsigned int hooknum,
13       const struct net_device *in,
14       const struct net_device *out,
15       const void *targinfo,
16       void *userinfo)
17{
18	const struct ipt_mark_target_info *markinfo = targinfo;
19
20	if((*pskb)->nfmark != markinfo->mark) {
21		(*pskb)->nfmark = markinfo->mark;
22		(*pskb)->nfcache |= NFC_ALTERED;
23	}
24	return IPT_CONTINUE;
25}
26
27static int
28checkentry(const char *tablename,
29	   const struct ipt_entry *e,
30           void *targinfo,
31           unsigned int targinfosize,
32           unsigned int hook_mask)
33{
34	if (targinfosize != IPT_ALIGN(sizeof(struct ipt_mark_target_info))) {
35		printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n",
36		       targinfosize,
37		       IPT_ALIGN(sizeof(struct ipt_mark_target_info)));
38		return 0;
39	}
40
41	if (strcmp(tablename, "mangle") != 0) {
42		printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
43		return 0;
44	}
45
46	return 1;
47}
48
49static struct ipt_target ipt_mark_reg
50= { { NULL, NULL }, "MARK", target, checkentry, NULL, THIS_MODULE };
51
52static int __init init(void)
53{
54	if (ipt_register_target(&ipt_mark_reg))
55		return -EINVAL;
56
57	return 0;
58}
59
60static void __exit fini(void)
61{
62	ipt_unregister_target(&ipt_mark_reg);
63}
64
65module_init(init);
66module_exit(fini);
67MODULE_LICENSE("GPL");
68