aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-03-24 16:24:36 -0400
committerDavid S. Miller <davem@davemloft.net>2009-03-24 16:24:36 -0400
commitb5bb14386eabcb4229ade2bc0a2b237ca166d37d (patch)
tree1966e65479f0d12cec0a204443a95b8eb57946db /net/ipv6
parentbb4f92b3a33bfc31f55098da85be44702bea2d16 (diff)
parent1d45209d89e647e9f27e4afa1f47338df73bc112 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/netfilter/Kconfig38
-rw-r--r--net/ipv6/netfilter/Makefile2
-rw-r--r--net/ipv6/netfilter/ip6_queue.c1
-rw-r--r--net/ipv6/netfilter/ip6_tables.c152
-rw-r--r--net/ipv6/netfilter/ip6t_HL.c95
-rw-r--r--net/ipv6/netfilter/ip6t_LOG.c2
-rw-r--r--net/ipv6/netfilter/ip6t_hl.c68
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c1
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c1
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c1
-rw-r--r--net/ipv6/netfilter/ip6table_security.c1
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c1
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c4
13 files changed, 127 insertions, 240 deletions
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 53ea512c4608..625353a5fe18 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -95,13 +95,13 @@ config IP6_NF_MATCH_OPTS
95 To compile it as a module, choose M here. If unsure, say N. 95 To compile it as a module, choose M here. If unsure, say N.
96 96
97config IP6_NF_MATCH_HL 97config IP6_NF_MATCH_HL
98 tristate '"hl" match support' 98 tristate '"hl" hoplimit match support'
99 depends on NETFILTER_ADVANCED 99 depends on NETFILTER_ADVANCED
100 help 100 select NETFILTER_XT_MATCH_HL
101 HL matching allows you to match packets based on the hop 101 ---help---
102 limit of the packet. 102 This is a backwards-compat option for the user's convenience
103 103 (e.g. when running oldconfig). It selects
104 To compile it as a module, choose M here. If unsure, say N. 104 COFNIG_NETFILTER_XT_MATCH_HL.
105 105
106config IP6_NF_MATCH_IPV6HEADER 106config IP6_NF_MATCH_IPV6HEADER
107 tristate '"ipv6header" IPv6 Extension Headers Match' 107 tristate '"ipv6header" IPv6 Extension Headers Match'
@@ -130,6 +130,15 @@ config IP6_NF_MATCH_RT
130 To compile it as a module, choose M here. If unsure, say N. 130 To compile it as a module, choose M here. If unsure, say N.
131 131
132# The targets 132# The targets
133config IP6_NF_TARGET_HL
134 tristate '"HL" hoplimit target support'
135 depends on NETFILTER_ADVANCED
136 select NETFILTER_XT_TARGET_HL
137 ---help---
138 This is a backwards-compat option for the user's convenience
139 (e.g. when running oldconfig). It selects
140 COFNIG_NETFILTER_XT_TARGET_HL.
141
133config IP6_NF_TARGET_LOG 142config IP6_NF_TARGET_LOG
134 tristate "LOG target support" 143 tristate "LOG target support"
135 default m if NETFILTER_ADVANCED=n 144 default m if NETFILTER_ADVANCED=n
@@ -170,23 +179,6 @@ config IP6_NF_MANGLE
170 179
171 To compile it as a module, choose M here. If unsure, say N. 180 To compile it as a module, choose M here. If unsure, say N.
172 181
173config IP6_NF_TARGET_HL
174 tristate 'HL (hoplimit) target support'
175 depends on IP6_NF_MANGLE
176 depends on NETFILTER_ADVANCED
177 help
178 This option adds a `HL' target, which enables the user to decrement
179 the hoplimit value of the IPv6 header or set it to a given (lower)
180 value.
181
182 While it is safe to decrement the hoplimit value, this option also
183 enables functionality to increment and set the hoplimit value of the
184 IPv6 header to arbitrary values. This is EXTREMELY DANGEROUS since
185 you can easily create immortal packets that loop forever on the
186 network.
187
188 To compile it as a module, choose M here. If unsure, say N.
189
190config IP6_NF_RAW 182config IP6_NF_RAW
191 tristate 'raw table support (required for TRACE)' 183 tristate 'raw table support (required for TRACE)'
192 depends on NETFILTER_ADVANCED 184 depends on NETFILTER_ADVANCED
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index 3f17c948eefb..aafbba30c899 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -20,13 +20,11 @@ obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o
20obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o 20obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o
21obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o 21obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o
22obj-$(CONFIG_IP6_NF_MATCH_FRAG) += ip6t_frag.o 22obj-$(CONFIG_IP6_NF_MATCH_FRAG) += ip6t_frag.o
23obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
24obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o 23obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
25obj-$(CONFIG_IP6_NF_MATCH_MH) += ip6t_mh.o 24obj-$(CONFIG_IP6_NF_MATCH_MH) += ip6t_mh.o
26obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o 25obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o
27obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o 26obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
28 27
29# targets 28# targets
30obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o
31obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o 29obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
32obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o 30obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index 5859c046cbc4..b693f841aeb4 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -643,6 +643,7 @@ static void __exit ip6_queue_fini(void)
643 643
644MODULE_DESCRIPTION("IPv6 packet queue handler"); 644MODULE_DESCRIPTION("IPv6 packet queue handler");
645MODULE_LICENSE("GPL"); 645MODULE_LICENSE("GPL");
646MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_IP6_FW);
646 647
647module_init(ip6_queue_init); 648module_init(ip6_queue_init);
648module_exit(ip6_queue_fini); 649module_exit(ip6_queue_fini);
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index a33485dc81cb..34af7bb8df5f 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -89,6 +89,25 @@ ip6t_ext_hdr(u8 nexthdr)
89 (nexthdr == IPPROTO_DSTOPTS) ); 89 (nexthdr == IPPROTO_DSTOPTS) );
90} 90}
91 91
92static unsigned long ifname_compare(const char *_a, const char *_b,
93 const unsigned char *_mask)
94{
95 const unsigned long *a = (const unsigned long *)_a;
96 const unsigned long *b = (const unsigned long *)_b;
97 const unsigned long *mask = (const unsigned long *)_mask;
98 unsigned long ret;
99
100 ret = (a[0] ^ b[0]) & mask[0];
101 if (IFNAMSIZ > sizeof(unsigned long))
102 ret |= (a[1] ^ b[1]) & mask[1];
103 if (IFNAMSIZ > 2 * sizeof(unsigned long))
104 ret |= (a[2] ^ b[2]) & mask[2];
105 if (IFNAMSIZ > 3 * sizeof(unsigned long))
106 ret |= (a[3] ^ b[3]) & mask[3];
107 BUILD_BUG_ON(IFNAMSIZ > 4 * sizeof(unsigned long));
108 return ret;
109}
110
92/* Returns whether matches rule or not. */ 111/* Returns whether matches rule or not. */
93/* Performance critical - called for every packet */ 112/* Performance critical - called for every packet */
94static inline bool 113static inline bool
@@ -99,7 +118,6 @@ ip6_packet_match(const struct sk_buff *skb,
99 unsigned int *protoff, 118 unsigned int *protoff,
100 int *fragoff, bool *hotdrop) 119 int *fragoff, bool *hotdrop)
101{ 120{
102 size_t i;
103 unsigned long ret; 121 unsigned long ret;
104 const struct ipv6hdr *ipv6 = ipv6_hdr(skb); 122 const struct ipv6hdr *ipv6 = ipv6_hdr(skb);
105 123
@@ -120,12 +138,7 @@ ip6_packet_match(const struct sk_buff *skb,
120 return false; 138 return false;
121 } 139 }
122 140
123 /* Look for ifname matches; this should unroll nicely. */ 141 ret = ifname_compare(indev, ip6info->iniface, ip6info->iniface_mask);
124 for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
125 ret |= (((const unsigned long *)indev)[i]
126 ^ ((const unsigned long *)ip6info->iniface)[i])
127 & ((const unsigned long *)ip6info->iniface_mask)[i];
128 }
129 142
130 if (FWINV(ret != 0, IP6T_INV_VIA_IN)) { 143 if (FWINV(ret != 0, IP6T_INV_VIA_IN)) {
131 dprintf("VIA in mismatch (%s vs %s).%s\n", 144 dprintf("VIA in mismatch (%s vs %s).%s\n",
@@ -134,11 +147,7 @@ ip6_packet_match(const struct sk_buff *skb,
134 return false; 147 return false;
135 } 148 }
136 149
137 for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) { 150 ret = ifname_compare(outdev, ip6info->outiface, ip6info->outiface_mask);
138 ret |= (((const unsigned long *)outdev)[i]
139 ^ ((const unsigned long *)ip6info->outiface)[i])
140 & ((const unsigned long *)ip6info->outiface_mask)[i];
141 }
142 151
143 if (FWINV(ret != 0, IP6T_INV_VIA_OUT)) { 152 if (FWINV(ret != 0, IP6T_INV_VIA_OUT)) {
144 dprintf("VIA out mismatch (%s vs %s).%s\n", 153 dprintf("VIA out mismatch (%s vs %s).%s\n",
@@ -373,10 +382,12 @@ ip6t_do_table(struct sk_buff *skb,
373 mtpar.family = tgpar.family = NFPROTO_IPV6; 382 mtpar.family = tgpar.family = NFPROTO_IPV6;
374 tgpar.hooknum = hook; 383 tgpar.hooknum = hook;
375 384
376 read_lock_bh(&table->lock);
377 IP_NF_ASSERT(table->valid_hooks & (1 << hook)); 385 IP_NF_ASSERT(table->valid_hooks & (1 << hook));
378 private = table->private; 386
379 table_base = (void *)private->entries[smp_processor_id()]; 387 rcu_read_lock();
388 private = rcu_dereference(table->private);
389 table_base = rcu_dereference(private->entries[smp_processor_id()]);
390
380 e = get_entry(table_base, private->hook_entry[hook]); 391 e = get_entry(table_base, private->hook_entry[hook]);
381 392
382 /* For return from builtin chain */ 393 /* For return from builtin chain */
@@ -474,7 +485,7 @@ ip6t_do_table(struct sk_buff *skb,
474#ifdef CONFIG_NETFILTER_DEBUG 485#ifdef CONFIG_NETFILTER_DEBUG
475 ((struct ip6t_entry *)table_base)->comefrom = NETFILTER_LINK_POISON; 486 ((struct ip6t_entry *)table_base)->comefrom = NETFILTER_LINK_POISON;
476#endif 487#endif
477 read_unlock_bh(&table->lock); 488 rcu_read_unlock();
478 489
479#ifdef DEBUG_ALLOW_ALL 490#ifdef DEBUG_ALLOW_ALL
480 return NF_ACCEPT; 491 return NF_ACCEPT;
@@ -955,11 +966,64 @@ get_counters(const struct xt_table_info *t,
955 } 966 }
956} 967}
957 968
969/* We're lazy, and add to the first CPU; overflow works its fey magic
970 * and everything is OK. */
971static int
972add_counter_to_entry(struct ip6t_entry *e,
973 const struct xt_counters addme[],
974 unsigned int *i)
975{
976 ADD_COUNTER(e->counters, addme[*i].bcnt, addme[*i].pcnt);
977
978 (*i)++;
979 return 0;
980}
981
982/* Take values from counters and add them back onto the current cpu */
983static void put_counters(struct xt_table_info *t,
984 const struct xt_counters counters[])
985{
986 unsigned int i, cpu;
987
988 local_bh_disable();
989 cpu = smp_processor_id();
990 i = 0;
991 IP6T_ENTRY_ITERATE(t->entries[cpu],
992 t->size,
993 add_counter_to_entry,
994 counters,
995 &i);
996 local_bh_enable();
997}
998
999static inline int
1000zero_entry_counter(struct ip6t_entry *e, void *arg)
1001{
1002 e->counters.bcnt = 0;
1003 e->counters.pcnt = 0;
1004 return 0;
1005}
1006
1007static void
1008clone_counters(struct xt_table_info *newinfo, const struct xt_table_info *info)
1009{
1010 unsigned int cpu;
1011 const void *loc_cpu_entry = info->entries[raw_smp_processor_id()];
1012
1013 memcpy(newinfo, info, offsetof(struct xt_table_info, entries));
1014 for_each_possible_cpu(cpu) {
1015 memcpy(newinfo->entries[cpu], loc_cpu_entry, info->size);
1016 IP6T_ENTRY_ITERATE(newinfo->entries[cpu], newinfo->size,
1017 zero_entry_counter, NULL);
1018 }
1019}
1020
958static struct xt_counters *alloc_counters(struct xt_table *table) 1021static struct xt_counters *alloc_counters(struct xt_table *table)
959{ 1022{
960 unsigned int countersize; 1023 unsigned int countersize;
961 struct xt_counters *counters; 1024 struct xt_counters *counters;
962 const struct xt_table_info *private = table->private; 1025 struct xt_table_info *private = table->private;
1026 struct xt_table_info *info;
963 1027
964 /* We need atomic snapshot of counters: rest doesn't change 1028 /* We need atomic snapshot of counters: rest doesn't change
965 (other than comefrom, which userspace doesn't care 1029 (other than comefrom, which userspace doesn't care
@@ -968,14 +1032,28 @@ static struct xt_counters *alloc_counters(struct xt_table *table)
968 counters = vmalloc_node(countersize, numa_node_id()); 1032 counters = vmalloc_node(countersize, numa_node_id());
969 1033
970 if (counters == NULL) 1034 if (counters == NULL)
971 return ERR_PTR(-ENOMEM); 1035 goto nomem;
1036
1037 info = xt_alloc_table_info(private->size);
1038 if (!info)
1039 goto free_counters;
1040
1041 clone_counters(info, private);
972 1042
973 /* First, sum counters... */ 1043 mutex_lock(&table->lock);
974 write_lock_bh(&table->lock); 1044 xt_table_entry_swap_rcu(private, info);
975 get_counters(private, counters); 1045 synchronize_net(); /* Wait until smoke has cleared */
976 write_unlock_bh(&table->lock);
977 1046
978 return counters; 1047 get_counters(info, counters);
1048 put_counters(private, counters);
1049 mutex_unlock(&table->lock);
1050
1051 xt_free_table_info(info);
1052
1053 free_counters:
1054 vfree(counters);
1055 nomem:
1056 return ERR_PTR(-ENOMEM);
979} 1057}
980 1058
981static int 1059static int
@@ -1342,28 +1420,6 @@ do_replace(struct net *net, void __user *user, unsigned int len)
1342 return ret; 1420 return ret;
1343} 1421}
1344 1422
1345/* We're lazy, and add to the first CPU; overflow works its fey magic
1346 * and everything is OK. */
1347static inline int
1348add_counter_to_entry(struct ip6t_entry *e,
1349 const struct xt_counters addme[],
1350 unsigned int *i)
1351{
1352#if 0
1353 duprintf("add_counter: Entry %u %lu/%lu + %lu/%lu\n",
1354 *i,
1355 (long unsigned int)e->counters.pcnt,
1356 (long unsigned int)e->counters.bcnt,
1357 (long unsigned int)addme[*i].pcnt,
1358 (long unsigned int)addme[*i].bcnt);
1359#endif
1360
1361 ADD_COUNTER(e->counters, addme[*i].bcnt, addme[*i].pcnt);
1362
1363 (*i)++;
1364 return 0;
1365}
1366
1367static int 1423static int
1368do_add_counters(struct net *net, void __user *user, unsigned int len, 1424do_add_counters(struct net *net, void __user *user, unsigned int len,
1369 int compat) 1425 int compat)
@@ -1424,13 +1480,14 @@ do_add_counters(struct net *net, void __user *user, unsigned int len,
1424 goto free; 1480 goto free;
1425 } 1481 }
1426 1482
1427 write_lock_bh(&t->lock); 1483 mutex_lock(&t->lock);
1428 private = t->private; 1484 private = t->private;
1429 if (private->number != num_counters) { 1485 if (private->number != num_counters) {
1430 ret = -EINVAL; 1486 ret = -EINVAL;
1431 goto unlock_up_free; 1487 goto unlock_up_free;
1432 } 1488 }
1433 1489
1490 preempt_disable();
1434 i = 0; 1491 i = 0;
1435 /* Choose the copy that is on our node */ 1492 /* Choose the copy that is on our node */
1436 loc_cpu_entry = private->entries[raw_smp_processor_id()]; 1493 loc_cpu_entry = private->entries[raw_smp_processor_id()];
@@ -1439,8 +1496,9 @@ do_add_counters(struct net *net, void __user *user, unsigned int len,
1439 add_counter_to_entry, 1496 add_counter_to_entry,
1440 paddc, 1497 paddc,
1441 &i); 1498 &i);
1499 preempt_enable();
1442 unlock_up_free: 1500 unlock_up_free:
1443 write_unlock_bh(&t->lock); 1501 mutex_unlock(&t->lock);
1444 xt_table_unlock(t); 1502 xt_table_unlock(t);
1445 module_put(t->me); 1503 module_put(t->me);
1446 free: 1504 free:
diff --git a/net/ipv6/netfilter/ip6t_HL.c b/net/ipv6/netfilter/ip6t_HL.c
deleted file mode 100644
index 27b5adf670a2..000000000000
--- a/net/ipv6/netfilter/ip6t_HL.c
+++ /dev/null
@@ -1,95 +0,0 @@
1/*
2 * Hop Limit modification target for ip6tables
3 * Maciej Soltysiak <solt@dns.toxicfilms.tv>
4 * Based on HW's TTL module
5 *
6 * This software is distributed under the terms of GNU GPL
7 */
8
9#include <linux/module.h>
10#include <linux/skbuff.h>
11#include <linux/ip.h>
12#include <linux/ipv6.h>
13
14#include <linux/netfilter/x_tables.h>
15#include <linux/netfilter_ipv6/ip6t_HL.h>
16
17MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
18MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field modification target");
19MODULE_LICENSE("GPL");
20
21static unsigned int
22hl_tg6(struct sk_buff *skb, const struct xt_target_param *par)
23{
24 struct ipv6hdr *ip6h;
25 const struct ip6t_HL_info *info = par->targinfo;
26 int new_hl;
27
28 if (!skb_make_writable(skb, skb->len))
29 return NF_DROP;
30
31 ip6h = ipv6_hdr(skb);
32
33 switch (info->mode) {
34 case IP6T_HL_SET:
35 new_hl = info->hop_limit;
36 break;
37 case IP6T_HL_INC:
38 new_hl = ip6h->hop_limit + info->hop_limit;
39 if (new_hl > 255)
40 new_hl = 255;
41 break;
42 case IP6T_HL_DEC:
43 new_hl = ip6h->hop_limit - info->hop_limit;
44 if (new_hl < 0)
45 new_hl = 0;
46 break;
47 default:
48 new_hl = ip6h->hop_limit;
49 break;
50 }
51
52 ip6h->hop_limit = new_hl;
53
54 return XT_CONTINUE;
55}
56
57static bool hl_tg6_check(const struct xt_tgchk_param *par)
58{
59 const struct ip6t_HL_info *info = par->targinfo;
60
61 if (info->mode > IP6T_HL_MAXMODE) {
62 printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n",
63 info->mode);
64 return false;
65 }
66 if (info->mode != IP6T_HL_SET && info->hop_limit == 0) {
67 printk(KERN_WARNING "ip6t_HL: increment/decrement doesn't "
68 "make sense with value 0\n");
69 return false;
70 }
71 return true;
72}
73
74static struct xt_target hl_tg6_reg __read_mostly = {
75 .name = "HL",
76 .family = NFPROTO_IPV6,
77 .target = hl_tg6,
78 .targetsize = sizeof(struct ip6t_HL_info),
79 .table = "mangle",
80 .checkentry = hl_tg6_check,
81 .me = THIS_MODULE
82};
83
84static int __init hl_tg6_init(void)
85{
86 return xt_register_target(&hl_tg6_reg);
87}
88
89static void __exit hl_tg6_exit(void)
90{
91 xt_unregister_target(&hl_tg6_reg);
92}
93
94module_init(hl_tg6_init);
95module_exit(hl_tg6_exit);
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index 37adf5abc51e..7018cac4fddc 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -477,7 +477,7 @@ static struct xt_target log_tg6_reg __read_mostly = {
477 .me = THIS_MODULE, 477 .me = THIS_MODULE,
478}; 478};
479 479
480static const struct nf_logger ip6t_logger = { 480static struct nf_logger ip6t_logger __read_mostly = {
481 .name = "ip6t_LOG", 481 .name = "ip6t_LOG",
482 .logfn = &ip6t_log_packet, 482 .logfn = &ip6t_log_packet,
483 .me = THIS_MODULE, 483 .me = THIS_MODULE,
diff --git a/net/ipv6/netfilter/ip6t_hl.c b/net/ipv6/netfilter/ip6t_hl.c
deleted file mode 100644
index c964dca1132d..000000000000
--- a/net/ipv6/netfilter/ip6t_hl.c
+++ /dev/null
@@ -1,68 +0,0 @@
1/* Hop Limit matching module */
2
3/* (C) 2001-2002 Maciej Soltysiak <solt@dns.toxicfilms.tv>
4 * Based on HW's ttl module
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/ipv6.h>
12#include <linux/module.h>
13#include <linux/skbuff.h>
14
15#include <linux/netfilter_ipv6/ip6t_hl.h>
16#include <linux/netfilter/x_tables.h>
17
18MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
19MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field match");
20MODULE_LICENSE("GPL");
21
22static bool hl_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
23{
24 const struct ip6t_hl_info *info = par->matchinfo;
25 const struct ipv6hdr *ip6h = ipv6_hdr(skb);
26
27 switch (info->mode) {
28 case IP6T_HL_EQ:
29 return ip6h->hop_limit == info->hop_limit;
30 break;
31 case IP6T_HL_NE:
32 return ip6h->hop_limit != info->hop_limit;
33 break;
34 case IP6T_HL_LT:
35 return ip6h->hop_limit < info->hop_limit;
36 break;
37 case IP6T_HL_GT:
38 return ip6h->hop_limit > info->hop_limit;
39 break;
40 default:
41 printk(KERN_WARNING "ip6t_hl: unknown mode %d\n",
42 info->mode);
43 return false;
44 }
45
46 return false;
47}
48
49static struct xt_match hl_mt6_reg __read_mostly = {
50 .name = "hl",
51 .family = NFPROTO_IPV6,
52 .match = hl_mt6,
53 .matchsize = sizeof(struct ip6t_hl_info),
54 .me = THIS_MODULE,
55};
56
57static int __init hl_mt6_init(void)
58{
59 return xt_register_match(&hl_mt6_reg);
60}
61
62static void __exit hl_mt6_exit(void)
63{
64 xt_unregister_match(&hl_mt6_reg);
65}
66
67module_init(hl_mt6_init);
68module_exit(hl_mt6_exit);
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index 40d2e36d8fac..ef5a0a32bf8e 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -54,7 +54,6 @@ static struct
54static struct xt_table packet_filter = { 54static struct xt_table packet_filter = {
55 .name = "filter", 55 .name = "filter",
56 .valid_hooks = FILTER_VALID_HOOKS, 56 .valid_hooks = FILTER_VALID_HOOKS,
57 .lock = __RW_LOCK_UNLOCKED(packet_filter.lock),
58 .me = THIS_MODULE, 57 .me = THIS_MODULE,
59 .af = AF_INET6, 58 .af = AF_INET6,
60}; 59};
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index d0b31b259d4d..ab0d398a2ba7 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -60,7 +60,6 @@ static struct
60static struct xt_table packet_mangler = { 60static struct xt_table packet_mangler = {
61 .name = "mangle", 61 .name = "mangle",
62 .valid_hooks = MANGLE_VALID_HOOKS, 62 .valid_hooks = MANGLE_VALID_HOOKS,
63 .lock = __RW_LOCK_UNLOCKED(packet_mangler.lock),
64 .me = THIS_MODULE, 63 .me = THIS_MODULE,
65 .af = AF_INET6, 64 .af = AF_INET6,
66}; 65};
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index 109fab6f831a..4b792b6ca321 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -38,7 +38,6 @@ static struct
38static struct xt_table packet_raw = { 38static struct xt_table packet_raw = {
39 .name = "raw", 39 .name = "raw",
40 .valid_hooks = RAW_VALID_HOOKS, 40 .valid_hooks = RAW_VALID_HOOKS,
41 .lock = __RW_LOCK_UNLOCKED(packet_raw.lock),
42 .me = THIS_MODULE, 41 .me = THIS_MODULE,
43 .af = AF_INET6, 42 .af = AF_INET6,
44}; 43};
diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c
index 20bc52f13e43..0ea37ff15d56 100644
--- a/net/ipv6/netfilter/ip6table_security.c
+++ b/net/ipv6/netfilter/ip6table_security.c
@@ -59,7 +59,6 @@ static struct
59static struct xt_table security_table = { 59static struct xt_table security_table = {
60 .name = "security", 60 .name = "security",
61 .valid_hooks = SECURITY_VALID_HOOKS, 61 .valid_hooks = SECURITY_VALID_HOOKS,
62 .lock = __RW_LOCK_UNLOCKED(security_table.lock),
63 .me = THIS_MODULE, 62 .me = THIS_MODULE,
64 .af = AF_INET6, 63 .af = AF_INET6,
65}; 64};
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 727b9530448a..e6852f617217 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -26,6 +26,7 @@
26#include <net/netfilter/nf_conntrack_l4proto.h> 26#include <net/netfilter/nf_conntrack_l4proto.h>
27#include <net/netfilter/nf_conntrack_l3proto.h> 27#include <net/netfilter/nf_conntrack_l3proto.h>
28#include <net/netfilter/nf_conntrack_core.h> 28#include <net/netfilter/nf_conntrack_core.h>
29#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
29 30
30static bool ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, 31static bool ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
31 struct nf_conntrack_tuple *tuple) 32 struct nf_conntrack_tuple *tuple)
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 72dbb6d1a6b3..41b8a956e1be 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -126,6 +126,10 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb,
126 pr_debug("icmpv6: can't create new conn with type %u\n", 126 pr_debug("icmpv6: can't create new conn with type %u\n",
127 type + 128); 127 type + 128);
128 nf_ct_dump_tuple_ipv6(&ct->tuplehash[0].tuple); 128 nf_ct_dump_tuple_ipv6(&ct->tuplehash[0].tuple);
129 if (LOG_INVALID(nf_ct_net(ct), IPPROTO_ICMPV6))
130 nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
131 "nf_ct_icmpv6: invalid new with type %d ",
132 type + 128);
129 return false; 133 return false;
130 } 134 }
131 atomic_set(&ct->proto.icmp.count, 0); 135 atomic_set(&ct->proto.icmp.count, 0);