diff options
author | David S. Miller <davem@davemloft.net> | 2009-03-24 16:24:36 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-03-24 16:24:36 -0400 |
commit | b5bb14386eabcb4229ade2bc0a2b237ca166d37d (patch) | |
tree | 1966e65479f0d12cec0a204443a95b8eb57946db /net/ipv6 | |
parent | bb4f92b3a33bfc31f55098da85be44702bea2d16 (diff) | |
parent | 1d45209d89e647e9f27e4afa1f47338df73bc112 (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/Kconfig | 38 | ||||
-rw-r--r-- | net/ipv6/netfilter/Makefile | 2 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_queue.c | 1 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 152 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_HL.c | 95 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_LOG.c | 2 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_hl.c | 68 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6table_filter.c | 1 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6table_mangle.c | 1 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6table_raw.c | 1 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6table_security.c | 1 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 1 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 4 |
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 | ||
97 | config IP6_NF_MATCH_HL | 97 | config 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 | ||
106 | config IP6_NF_MATCH_IPV6HEADER | 106 | config 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 |
133 | config 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 | |||
133 | config IP6_NF_TARGET_LOG | 142 | config 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 | ||
173 | config 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 | |||
190 | config IP6_NF_RAW | 182 | config 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 | |||
20 | obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o | 20 | obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o |
21 | obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o | 21 | obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o |
22 | obj-$(CONFIG_IP6_NF_MATCH_FRAG) += ip6t_frag.o | 22 | obj-$(CONFIG_IP6_NF_MATCH_FRAG) += ip6t_frag.o |
23 | obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o | ||
24 | obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o | 23 | obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o |
25 | obj-$(CONFIG_IP6_NF_MATCH_MH) += ip6t_mh.o | 24 | obj-$(CONFIG_IP6_NF_MATCH_MH) += ip6t_mh.o |
26 | obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o | 25 | obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o |
27 | obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o | 26 | obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o |
28 | 27 | ||
29 | # targets | 28 | # targets |
30 | obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o | ||
31 | obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o | 29 | obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o |
32 | obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o | 30 | obj-$(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 | ||
644 | MODULE_DESCRIPTION("IPv6 packet queue handler"); | 644 | MODULE_DESCRIPTION("IPv6 packet queue handler"); |
645 | MODULE_LICENSE("GPL"); | 645 | MODULE_LICENSE("GPL"); |
646 | MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_IP6_FW); | ||
646 | 647 | ||
647 | module_init(ip6_queue_init); | 648 | module_init(ip6_queue_init); |
648 | module_exit(ip6_queue_fini); | 649 | module_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 | ||
92 | static 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 */ |
94 | static inline bool | 113 | static 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. */ | ||
971 | static int | ||
972 | add_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 */ | ||
983 | static 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 | |||
999 | static inline int | ||
1000 | zero_entry_counter(struct ip6t_entry *e, void *arg) | ||
1001 | { | ||
1002 | e->counters.bcnt = 0; | ||
1003 | e->counters.pcnt = 0; | ||
1004 | return 0; | ||
1005 | } | ||
1006 | |||
1007 | static void | ||
1008 | clone_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 | |||
958 | static struct xt_counters *alloc_counters(struct xt_table *table) | 1021 | static 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 | ||
981 | static int | 1059 | static 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. */ | ||
1347 | static inline int | ||
1348 | add_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 | |||
1367 | static int | 1423 | static int |
1368 | do_add_counters(struct net *net, void __user *user, unsigned int len, | 1424 | do_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 | |||
17 | MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>"); | ||
18 | MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field modification target"); | ||
19 | MODULE_LICENSE("GPL"); | ||
20 | |||
21 | static unsigned int | ||
22 | hl_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 | |||
57 | static 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 | |||
74 | static 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 | |||
84 | static int __init hl_tg6_init(void) | ||
85 | { | ||
86 | return xt_register_target(&hl_tg6_reg); | ||
87 | } | ||
88 | |||
89 | static void __exit hl_tg6_exit(void) | ||
90 | { | ||
91 | xt_unregister_target(&hl_tg6_reg); | ||
92 | } | ||
93 | |||
94 | module_init(hl_tg6_init); | ||
95 | module_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 | ||
480 | static const struct nf_logger ip6t_logger = { | 480 | static 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 | |||
18 | MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>"); | ||
19 | MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field match"); | ||
20 | MODULE_LICENSE("GPL"); | ||
21 | |||
22 | static 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 | |||
49 | static 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 | |||
57 | static int __init hl_mt6_init(void) | ||
58 | { | ||
59 | return xt_register_match(&hl_mt6_reg); | ||
60 | } | ||
61 | |||
62 | static void __exit hl_mt6_exit(void) | ||
63 | { | ||
64 | xt_unregister_match(&hl_mt6_reg); | ||
65 | } | ||
66 | |||
67 | module_init(hl_mt6_init); | ||
68 | module_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 | |||
54 | static struct xt_table packet_filter = { | 54 | static 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 | |||
60 | static struct xt_table packet_mangler = { | 60 | static 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 | |||
38 | static struct xt_table packet_raw = { | 38 | static 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 | |||
59 | static struct xt_table security_table = { | 59 | static 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 | ||
30 | static bool ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, | 31 | static 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); |