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/ipv4 | |
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/ipv4')
-rw-r--r-- | net/ipv4/netfilter/Kconfig | 30 | ||||
-rw-r--r-- | net/ipv4/netfilter/Makefile | 2 | ||||
-rw-r--r-- | net/ipv4/netfilter/arp_tables.c | 159 | ||||
-rw-r--r-- | net/ipv4/netfilter/arptable_filter.c | 2 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_queue.c | 2 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_tables.c | 153 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_LOG.c | 2 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_TTL.c | 97 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_ULOG.c | 2 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_ttl.c | 63 | ||||
-rw-r--r-- | net/ipv4/netfilter/iptable_filter.c | 1 | ||||
-rw-r--r-- | net/ipv4/netfilter/iptable_mangle.c | 1 | ||||
-rw-r--r-- | net/ipv4/netfilter/iptable_raw.c | 1 | ||||
-rw-r--r-- | net/ipv4/netfilter/iptable_security.c | 1 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 4 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_nat_rule.c | 1 |
16 files changed, 249 insertions, 272 deletions
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index 3816e1dc9295..1833bdbf9805 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig | |||
@@ -31,7 +31,7 @@ config NF_CONNTRACK_PROC_COMPAT | |||
31 | default y | 31 | default y |
32 | help | 32 | help |
33 | This option enables /proc and sysctl compatibility with the old | 33 | This option enables /proc and sysctl compatibility with the old |
34 | layer 3 dependant connection tracking. This is needed to keep | 34 | layer 3 dependent connection tracking. This is needed to keep |
35 | old programs that have not been adapted to the new names working. | 35 | old programs that have not been adapted to the new names working. |
36 | 36 | ||
37 | If unsure, say Y. | 37 | If unsure, say Y. |
@@ -95,11 +95,11 @@ config IP_NF_MATCH_ECN | |||
95 | config IP_NF_MATCH_TTL | 95 | config IP_NF_MATCH_TTL |
96 | tristate '"ttl" match support' | 96 | tristate '"ttl" match support' |
97 | depends on NETFILTER_ADVANCED | 97 | depends on NETFILTER_ADVANCED |
98 | help | 98 | select NETFILTER_XT_MATCH_HL |
99 | This adds CONFIG_IP_NF_MATCH_TTL option, which enabled the user | 99 | ---help--- |
100 | to match packets by their TTL value. | 100 | This is a backwards-compat option for the user's convenience |
101 | 101 | (e.g. when running oldconfig). It selects | |
102 | To compile it as a module, choose M here. If unsure, say N. | 102 | CONFIG_NETFILTER_XT_MATCH_HL. |
103 | 103 | ||
104 | # `filter', generic and specific targets | 104 | # `filter', generic and specific targets |
105 | config IP_NF_FILTER | 105 | config IP_NF_FILTER |
@@ -323,19 +323,13 @@ config IP_NF_TARGET_ECN | |||
323 | To compile it as a module, choose M here. If unsure, say N. | 323 | To compile it as a module, choose M here. If unsure, say N. |
324 | 324 | ||
325 | config IP_NF_TARGET_TTL | 325 | config IP_NF_TARGET_TTL |
326 | tristate 'TTL target support' | 326 | tristate '"TTL" target support' |
327 | depends on IP_NF_MANGLE | ||
328 | depends on NETFILTER_ADVANCED | 327 | depends on NETFILTER_ADVANCED |
329 | help | 328 | select NETFILTER_XT_TARGET_HL |
330 | This option adds a `TTL' target, which enables the user to modify | 329 | ---help--- |
331 | the TTL value of the IP header. | 330 | This is a backwards-compat option for the user's convenience |
332 | 331 | (e.g. when running oldconfig). It selects | |
333 | While it is safe to decrement/lower the TTL, this target also enables | 332 | CONFIG_NETFILTER_XT_TARGET_HL. |
334 | functionality to increment and set the TTL value of the IP header to | ||
335 | arbitrary values. This is EXTREMELY DANGEROUS since you can easily | ||
336 | create immortal packets that loop forever on the network. | ||
337 | |||
338 | To compile it as a module, choose M here. If unsure, say N. | ||
339 | 333 | ||
340 | # raw + specific targets | 334 | # raw + specific targets |
341 | config IP_NF_RAW | 335 | config IP_NF_RAW |
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index 5f9b650d90fc..48111594ee9b 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile | |||
@@ -51,7 +51,6 @@ obj-$(CONFIG_IP_NF_SECURITY) += iptable_security.o | |||
51 | obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o | 51 | obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o |
52 | obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o | 52 | obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o |
53 | obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o | 53 | obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o |
54 | obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o | ||
55 | 54 | ||
56 | # targets | 55 | # targets |
57 | obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o | 56 | obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o |
@@ -61,7 +60,6 @@ obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o | |||
61 | obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o | 60 | obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o |
62 | obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o | 61 | obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o |
63 | obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o | 62 | obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o |
64 | obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o | ||
65 | obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o | 63 | obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o |
66 | 64 | ||
67 | # generic ARP tables | 65 | # generic ARP tables |
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 7ea88b61cb0d..64a7c6ce0b98 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -73,6 +73,36 @@ static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap, | |||
73 | return (ret != 0); | 73 | return (ret != 0); |
74 | } | 74 | } |
75 | 75 | ||
76 | /* | ||
77 | * Unfortunatly, _b and _mask are not aligned to an int (or long int) | ||
78 | * Some arches dont care, unrolling the loop is a win on them. | ||
79 | */ | ||
80 | static unsigned long ifname_compare(const char *_a, const char *_b, const char *_mask) | ||
81 | { | ||
82 | #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS | ||
83 | const unsigned long *a = (const unsigned long *)_a; | ||
84 | const unsigned long *b = (const unsigned long *)_b; | ||
85 | const unsigned long *mask = (const unsigned long *)_mask; | ||
86 | unsigned long ret; | ||
87 | |||
88 | ret = (a[0] ^ b[0]) & mask[0]; | ||
89 | if (IFNAMSIZ > sizeof(unsigned long)) | ||
90 | ret |= (a[1] ^ b[1]) & mask[1]; | ||
91 | if (IFNAMSIZ > 2 * sizeof(unsigned long)) | ||
92 | ret |= (a[2] ^ b[2]) & mask[2]; | ||
93 | if (IFNAMSIZ > 3 * sizeof(unsigned long)) | ||
94 | ret |= (a[3] ^ b[3]) & mask[3]; | ||
95 | BUILD_BUG_ON(IFNAMSIZ > 4 * sizeof(unsigned long)); | ||
96 | #else | ||
97 | unsigned long ret = 0; | ||
98 | int i; | ||
99 | |||
100 | for (i = 0; i < IFNAMSIZ; i++) | ||
101 | ret |= (_a[i] ^ _b[i]) & _mask[i]; | ||
102 | #endif | ||
103 | return ret; | ||
104 | } | ||
105 | |||
76 | /* Returns whether packet matches rule or not. */ | 106 | /* Returns whether packet matches rule or not. */ |
77 | static inline int arp_packet_match(const struct arphdr *arphdr, | 107 | static inline int arp_packet_match(const struct arphdr *arphdr, |
78 | struct net_device *dev, | 108 | struct net_device *dev, |
@@ -83,7 +113,7 @@ static inline int arp_packet_match(const struct arphdr *arphdr, | |||
83 | const char *arpptr = (char *)(arphdr + 1); | 113 | const char *arpptr = (char *)(arphdr + 1); |
84 | const char *src_devaddr, *tgt_devaddr; | 114 | const char *src_devaddr, *tgt_devaddr; |
85 | __be32 src_ipaddr, tgt_ipaddr; | 115 | __be32 src_ipaddr, tgt_ipaddr; |
86 | int i, ret; | 116 | long ret; |
87 | 117 | ||
88 | #define FWINV(bool, invflg) ((bool) ^ !!(arpinfo->invflags & (invflg))) | 118 | #define FWINV(bool, invflg) ((bool) ^ !!(arpinfo->invflags & (invflg))) |
89 | 119 | ||
@@ -156,10 +186,7 @@ static inline int arp_packet_match(const struct arphdr *arphdr, | |||
156 | } | 186 | } |
157 | 187 | ||
158 | /* Look for ifname matches. */ | 188 | /* Look for ifname matches. */ |
159 | for (i = 0, ret = 0; i < IFNAMSIZ; i++) { | 189 | ret = ifname_compare(indev, arpinfo->iniface, arpinfo->iniface_mask); |
160 | ret |= (indev[i] ^ arpinfo->iniface[i]) | ||
161 | & arpinfo->iniface_mask[i]; | ||
162 | } | ||
163 | 190 | ||
164 | if (FWINV(ret != 0, ARPT_INV_VIA_IN)) { | 191 | if (FWINV(ret != 0, ARPT_INV_VIA_IN)) { |
165 | dprintf("VIA in mismatch (%s vs %s).%s\n", | 192 | dprintf("VIA in mismatch (%s vs %s).%s\n", |
@@ -168,10 +195,7 @@ static inline int arp_packet_match(const struct arphdr *arphdr, | |||
168 | return 0; | 195 | return 0; |
169 | } | 196 | } |
170 | 197 | ||
171 | for (i = 0, ret = 0; i < IFNAMSIZ; i++) { | 198 | ret = ifname_compare(outdev, arpinfo->outiface, arpinfo->outiface_mask); |
172 | ret |= (outdev[i] ^ arpinfo->outiface[i]) | ||
173 | & arpinfo->outiface_mask[i]; | ||
174 | } | ||
175 | 199 | ||
176 | if (FWINV(ret != 0, ARPT_INV_VIA_OUT)) { | 200 | if (FWINV(ret != 0, ARPT_INV_VIA_OUT)) { |
177 | dprintf("VIA out mismatch (%s vs %s).%s\n", | 201 | dprintf("VIA out mismatch (%s vs %s).%s\n", |
@@ -221,7 +245,7 @@ unsigned int arpt_do_table(struct sk_buff *skb, | |||
221 | const struct net_device *out, | 245 | const struct net_device *out, |
222 | struct xt_table *table) | 246 | struct xt_table *table) |
223 | { | 247 | { |
224 | static const char nulldevname[IFNAMSIZ]; | 248 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); |
225 | unsigned int verdict = NF_DROP; | 249 | unsigned int verdict = NF_DROP; |
226 | const struct arphdr *arp; | 250 | const struct arphdr *arp; |
227 | bool hotdrop = false; | 251 | bool hotdrop = false; |
@@ -237,9 +261,10 @@ unsigned int arpt_do_table(struct sk_buff *skb, | |||
237 | indev = in ? in->name : nulldevname; | 261 | indev = in ? in->name : nulldevname; |
238 | outdev = out ? out->name : nulldevname; | 262 | outdev = out ? out->name : nulldevname; |
239 | 263 | ||
240 | read_lock_bh(&table->lock); | 264 | rcu_read_lock(); |
241 | private = table->private; | 265 | private = rcu_dereference(table->private); |
242 | table_base = (void *)private->entries[smp_processor_id()]; | 266 | table_base = rcu_dereference(private->entries[smp_processor_id()]); |
267 | |||
243 | e = get_entry(table_base, private->hook_entry[hook]); | 268 | e = get_entry(table_base, private->hook_entry[hook]); |
244 | back = get_entry(table_base, private->underflow[hook]); | 269 | back = get_entry(table_base, private->underflow[hook]); |
245 | 270 | ||
@@ -311,7 +336,8 @@ unsigned int arpt_do_table(struct sk_buff *skb, | |||
311 | e = (void *)e + e->next_offset; | 336 | e = (void *)e + e->next_offset; |
312 | } | 337 | } |
313 | } while (!hotdrop); | 338 | } while (!hotdrop); |
314 | read_unlock_bh(&table->lock); | 339 | |
340 | rcu_read_unlock(); | ||
315 | 341 | ||
316 | if (hotdrop) | 342 | if (hotdrop) |
317 | return NF_DROP; | 343 | return NF_DROP; |
@@ -714,11 +740,65 @@ static void get_counters(const struct xt_table_info *t, | |||
714 | } | 740 | } |
715 | } | 741 | } |
716 | 742 | ||
717 | static inline struct xt_counters *alloc_counters(struct xt_table *table) | 743 | |
744 | /* We're lazy, and add to the first CPU; overflow works its fey magic | ||
745 | * and everything is OK. */ | ||
746 | static int | ||
747 | add_counter_to_entry(struct arpt_entry *e, | ||
748 | const struct xt_counters addme[], | ||
749 | unsigned int *i) | ||
750 | { | ||
751 | ADD_COUNTER(e->counters, addme[*i].bcnt, addme[*i].pcnt); | ||
752 | |||
753 | (*i)++; | ||
754 | return 0; | ||
755 | } | ||
756 | |||
757 | /* Take values from counters and add them back onto the current cpu */ | ||
758 | static void put_counters(struct xt_table_info *t, | ||
759 | const struct xt_counters counters[]) | ||
760 | { | ||
761 | unsigned int i, cpu; | ||
762 | |||
763 | local_bh_disable(); | ||
764 | cpu = smp_processor_id(); | ||
765 | i = 0; | ||
766 | ARPT_ENTRY_ITERATE(t->entries[cpu], | ||
767 | t->size, | ||
768 | add_counter_to_entry, | ||
769 | counters, | ||
770 | &i); | ||
771 | local_bh_enable(); | ||
772 | } | ||
773 | |||
774 | static inline int | ||
775 | zero_entry_counter(struct arpt_entry *e, void *arg) | ||
776 | { | ||
777 | e->counters.bcnt = 0; | ||
778 | e->counters.pcnt = 0; | ||
779 | return 0; | ||
780 | } | ||
781 | |||
782 | static void | ||
783 | clone_counters(struct xt_table_info *newinfo, const struct xt_table_info *info) | ||
784 | { | ||
785 | unsigned int cpu; | ||
786 | const void *loc_cpu_entry = info->entries[raw_smp_processor_id()]; | ||
787 | |||
788 | memcpy(newinfo, info, offsetof(struct xt_table_info, entries)); | ||
789 | for_each_possible_cpu(cpu) { | ||
790 | memcpy(newinfo->entries[cpu], loc_cpu_entry, info->size); | ||
791 | ARPT_ENTRY_ITERATE(newinfo->entries[cpu], newinfo->size, | ||
792 | zero_entry_counter, NULL); | ||
793 | } | ||
794 | } | ||
795 | |||
796 | static struct xt_counters *alloc_counters(struct xt_table *table) | ||
718 | { | 797 | { |
719 | unsigned int countersize; | 798 | unsigned int countersize; |
720 | struct xt_counters *counters; | 799 | struct xt_counters *counters; |
721 | const struct xt_table_info *private = table->private; | 800 | struct xt_table_info *private = table->private; |
801 | struct xt_table_info *info; | ||
722 | 802 | ||
723 | /* We need atomic snapshot of counters: rest doesn't change | 803 | /* We need atomic snapshot of counters: rest doesn't change |
724 | * (other than comefrom, which userspace doesn't care | 804 | * (other than comefrom, which userspace doesn't care |
@@ -728,14 +808,30 @@ static inline struct xt_counters *alloc_counters(struct xt_table *table) | |||
728 | counters = vmalloc_node(countersize, numa_node_id()); | 808 | counters = vmalloc_node(countersize, numa_node_id()); |
729 | 809 | ||
730 | if (counters == NULL) | 810 | if (counters == NULL) |
731 | return ERR_PTR(-ENOMEM); | 811 | goto nomem; |
812 | |||
813 | info = xt_alloc_table_info(private->size); | ||
814 | if (!info) | ||
815 | goto free_counters; | ||
816 | |||
817 | clone_counters(info, private); | ||
818 | |||
819 | mutex_lock(&table->lock); | ||
820 | xt_table_entry_swap_rcu(private, info); | ||
821 | synchronize_net(); /* Wait until smoke has cleared */ | ||
822 | |||
823 | get_counters(info, counters); | ||
824 | put_counters(private, counters); | ||
825 | mutex_unlock(&table->lock); | ||
732 | 826 | ||
733 | /* First, sum counters... */ | 827 | xt_free_table_info(info); |
734 | write_lock_bh(&table->lock); | ||
735 | get_counters(private, counters); | ||
736 | write_unlock_bh(&table->lock); | ||
737 | 828 | ||
738 | return counters; | 829 | return counters; |
830 | |||
831 | free_counters: | ||
832 | vfree(counters); | ||
833 | nomem: | ||
834 | return ERR_PTR(-ENOMEM); | ||
739 | } | 835 | } |
740 | 836 | ||
741 | static int copy_entries_to_user(unsigned int total_size, | 837 | static int copy_entries_to_user(unsigned int total_size, |
@@ -1075,20 +1171,6 @@ static int do_replace(struct net *net, void __user *user, unsigned int len) | |||
1075 | return ret; | 1171 | return ret; |
1076 | } | 1172 | } |
1077 | 1173 | ||
1078 | /* We're lazy, and add to the first CPU; overflow works its fey magic | ||
1079 | * and everything is OK. | ||
1080 | */ | ||
1081 | static inline int add_counter_to_entry(struct arpt_entry *e, | ||
1082 | const struct xt_counters addme[], | ||
1083 | unsigned int *i) | ||
1084 | { | ||
1085 | |||
1086 | ADD_COUNTER(e->counters, addme[*i].bcnt, addme[*i].pcnt); | ||
1087 | |||
1088 | (*i)++; | ||
1089 | return 0; | ||
1090 | } | ||
1091 | |||
1092 | static int do_add_counters(struct net *net, void __user *user, unsigned int len, | 1174 | static int do_add_counters(struct net *net, void __user *user, unsigned int len, |
1093 | int compat) | 1175 | int compat) |
1094 | { | 1176 | { |
@@ -1148,13 +1230,14 @@ static int do_add_counters(struct net *net, void __user *user, unsigned int len, | |||
1148 | goto free; | 1230 | goto free; |
1149 | } | 1231 | } |
1150 | 1232 | ||
1151 | write_lock_bh(&t->lock); | 1233 | mutex_lock(&t->lock); |
1152 | private = t->private; | 1234 | private = t->private; |
1153 | if (private->number != num_counters) { | 1235 | if (private->number != num_counters) { |
1154 | ret = -EINVAL; | 1236 | ret = -EINVAL; |
1155 | goto unlock_up_free; | 1237 | goto unlock_up_free; |
1156 | } | 1238 | } |
1157 | 1239 | ||
1240 | preempt_disable(); | ||
1158 | i = 0; | 1241 | i = 0; |
1159 | /* Choose the copy that is on our node */ | 1242 | /* Choose the copy that is on our node */ |
1160 | loc_cpu_entry = private->entries[smp_processor_id()]; | 1243 | loc_cpu_entry = private->entries[smp_processor_id()]; |
@@ -1163,8 +1246,10 @@ static int do_add_counters(struct net *net, void __user *user, unsigned int len, | |||
1163 | add_counter_to_entry, | 1246 | add_counter_to_entry, |
1164 | paddc, | 1247 | paddc, |
1165 | &i); | 1248 | &i); |
1249 | preempt_enable(); | ||
1166 | unlock_up_free: | 1250 | unlock_up_free: |
1167 | write_unlock_bh(&t->lock); | 1251 | mutex_unlock(&t->lock); |
1252 | |||
1168 | xt_table_unlock(t); | 1253 | xt_table_unlock(t); |
1169 | module_put(t->me); | 1254 | module_put(t->me); |
1170 | free: | 1255 | free: |
diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c index e091187e864f..6ecfdae7c589 100644 --- a/net/ipv4/netfilter/arptable_filter.c +++ b/net/ipv4/netfilter/arptable_filter.c | |||
@@ -48,8 +48,6 @@ static struct | |||
48 | static struct xt_table packet_filter = { | 48 | static struct xt_table packet_filter = { |
49 | .name = "filter", | 49 | .name = "filter", |
50 | .valid_hooks = FILTER_VALID_HOOKS, | 50 | .valid_hooks = FILTER_VALID_HOOKS, |
51 | .lock = __RW_LOCK_UNLOCKED(packet_filter.lock), | ||
52 | .private = NULL, | ||
53 | .me = THIS_MODULE, | 51 | .me = THIS_MODULE, |
54 | .af = NFPROTO_ARP, | 52 | .af = NFPROTO_ARP, |
55 | }; | 53 | }; |
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 432ce9d1c11c..5f22c91c6e15 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/proc_fs.h> | 24 | #include <linux/proc_fs.h> |
25 | #include <linux/seq_file.h> | 25 | #include <linux/seq_file.h> |
26 | #include <linux/security.h> | 26 | #include <linux/security.h> |
27 | #include <linux/net.h> | ||
27 | #include <linux/mutex.h> | 28 | #include <linux/mutex.h> |
28 | #include <net/net_namespace.h> | 29 | #include <net/net_namespace.h> |
29 | #include <net/sock.h> | 30 | #include <net/sock.h> |
@@ -640,6 +641,7 @@ static void __exit ip_queue_fini(void) | |||
640 | MODULE_DESCRIPTION("IPv4 packet queue handler"); | 641 | MODULE_DESCRIPTION("IPv4 packet queue handler"); |
641 | MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); | 642 | MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); |
642 | MODULE_LICENSE("GPL"); | 643 | MODULE_LICENSE("GPL"); |
644 | MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_FIREWALL); | ||
643 | 645 | ||
644 | module_init(ip_queue_init); | 646 | module_init(ip_queue_init); |
645 | module_exit(ip_queue_fini); | 647 | module_exit(ip_queue_fini); |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index ef8b6ca068b2..e5294aec967d 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -74,6 +74,25 @@ do { \ | |||
74 | 74 | ||
75 | Hence the start of any table is given by get_table() below. */ | 75 | Hence the start of any table is given by get_table() below. */ |
76 | 76 | ||
77 | static unsigned long ifname_compare(const char *_a, const char *_b, | ||
78 | const unsigned char *_mask) | ||
79 | { | ||
80 | const unsigned long *a = (const unsigned long *)_a; | ||
81 | const unsigned long *b = (const unsigned long *)_b; | ||
82 | const unsigned long *mask = (const unsigned long *)_mask; | ||
83 | unsigned long ret; | ||
84 | |||
85 | ret = (a[0] ^ b[0]) & mask[0]; | ||
86 | if (IFNAMSIZ > sizeof(unsigned long)) | ||
87 | ret |= (a[1] ^ b[1]) & mask[1]; | ||
88 | if (IFNAMSIZ > 2 * sizeof(unsigned long)) | ||
89 | ret |= (a[2] ^ b[2]) & mask[2]; | ||
90 | if (IFNAMSIZ > 3 * sizeof(unsigned long)) | ||
91 | ret |= (a[3] ^ b[3]) & mask[3]; | ||
92 | BUILD_BUG_ON(IFNAMSIZ > 4 * sizeof(unsigned long)); | ||
93 | return ret; | ||
94 | } | ||
95 | |||
77 | /* Returns whether matches rule or not. */ | 96 | /* Returns whether matches rule or not. */ |
78 | /* Performance critical - called for every packet */ | 97 | /* Performance critical - called for every packet */ |
79 | static inline bool | 98 | static inline bool |
@@ -83,7 +102,6 @@ ip_packet_match(const struct iphdr *ip, | |||
83 | const struct ipt_ip *ipinfo, | 102 | const struct ipt_ip *ipinfo, |
84 | int isfrag) | 103 | int isfrag) |
85 | { | 104 | { |
86 | size_t i; | ||
87 | unsigned long ret; | 105 | unsigned long ret; |
88 | 106 | ||
89 | #define FWINV(bool, invflg) ((bool) ^ !!(ipinfo->invflags & (invflg))) | 107 | #define FWINV(bool, invflg) ((bool) ^ !!(ipinfo->invflags & (invflg))) |
@@ -103,12 +121,7 @@ ip_packet_match(const struct iphdr *ip, | |||
103 | return false; | 121 | return false; |
104 | } | 122 | } |
105 | 123 | ||
106 | /* Look for ifname matches; this should unroll nicely. */ | 124 | ret = ifname_compare(indev, ipinfo->iniface, ipinfo->iniface_mask); |
107 | for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) { | ||
108 | ret |= (((const unsigned long *)indev)[i] | ||
109 | ^ ((const unsigned long *)ipinfo->iniface)[i]) | ||
110 | & ((const unsigned long *)ipinfo->iniface_mask)[i]; | ||
111 | } | ||
112 | 125 | ||
113 | if (FWINV(ret != 0, IPT_INV_VIA_IN)) { | 126 | if (FWINV(ret != 0, IPT_INV_VIA_IN)) { |
114 | dprintf("VIA in mismatch (%s vs %s).%s\n", | 127 | dprintf("VIA in mismatch (%s vs %s).%s\n", |
@@ -117,11 +130,7 @@ ip_packet_match(const struct iphdr *ip, | |||
117 | return false; | 130 | return false; |
118 | } | 131 | } |
119 | 132 | ||
120 | for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) { | 133 | ret = ifname_compare(outdev, ipinfo->outiface, ipinfo->outiface_mask); |
121 | ret |= (((const unsigned long *)outdev)[i] | ||
122 | ^ ((const unsigned long *)ipinfo->outiface)[i]) | ||
123 | & ((const unsigned long *)ipinfo->outiface_mask)[i]; | ||
124 | } | ||
125 | 134 | ||
126 | if (FWINV(ret != 0, IPT_INV_VIA_OUT)) { | 135 | if (FWINV(ret != 0, IPT_INV_VIA_OUT)) { |
127 | dprintf("VIA out mismatch (%s vs %s).%s\n", | 136 | dprintf("VIA out mismatch (%s vs %s).%s\n", |
@@ -347,10 +356,12 @@ ipt_do_table(struct sk_buff *skb, | |||
347 | mtpar.family = tgpar.family = NFPROTO_IPV4; | 356 | mtpar.family = tgpar.family = NFPROTO_IPV4; |
348 | tgpar.hooknum = hook; | 357 | tgpar.hooknum = hook; |
349 | 358 | ||
350 | read_lock_bh(&table->lock); | ||
351 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); | 359 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); |
352 | private = table->private; | 360 | |
353 | table_base = (void *)private->entries[smp_processor_id()]; | 361 | rcu_read_lock(); |
362 | private = rcu_dereference(table->private); | ||
363 | table_base = rcu_dereference(private->entries[smp_processor_id()]); | ||
364 | |||
354 | e = get_entry(table_base, private->hook_entry[hook]); | 365 | e = get_entry(table_base, private->hook_entry[hook]); |
355 | 366 | ||
356 | /* For return from builtin chain */ | 367 | /* For return from builtin chain */ |
@@ -445,7 +456,7 @@ ipt_do_table(struct sk_buff *skb, | |||
445 | } | 456 | } |
446 | } while (!hotdrop); | 457 | } while (!hotdrop); |
447 | 458 | ||
448 | read_unlock_bh(&table->lock); | 459 | rcu_read_unlock(); |
449 | 460 | ||
450 | #ifdef DEBUG_ALLOW_ALL | 461 | #ifdef DEBUG_ALLOW_ALL |
451 | return NF_ACCEPT; | 462 | return NF_ACCEPT; |
@@ -924,13 +935,68 @@ get_counters(const struct xt_table_info *t, | |||
924 | counters, | 935 | counters, |
925 | &i); | 936 | &i); |
926 | } | 937 | } |
938 | |||
939 | } | ||
940 | |||
941 | /* We're lazy, and add to the first CPU; overflow works its fey magic | ||
942 | * and everything is OK. */ | ||
943 | static int | ||
944 | add_counter_to_entry(struct ipt_entry *e, | ||
945 | const struct xt_counters addme[], | ||
946 | unsigned int *i) | ||
947 | { | ||
948 | ADD_COUNTER(e->counters, addme[*i].bcnt, addme[*i].pcnt); | ||
949 | |||
950 | (*i)++; | ||
951 | return 0; | ||
952 | } | ||
953 | |||
954 | /* Take values from counters and add them back onto the current cpu */ | ||
955 | static void put_counters(struct xt_table_info *t, | ||
956 | const struct xt_counters counters[]) | ||
957 | { | ||
958 | unsigned int i, cpu; | ||
959 | |||
960 | local_bh_disable(); | ||
961 | cpu = smp_processor_id(); | ||
962 | i = 0; | ||
963 | IPT_ENTRY_ITERATE(t->entries[cpu], | ||
964 | t->size, | ||
965 | add_counter_to_entry, | ||
966 | counters, | ||
967 | &i); | ||
968 | local_bh_enable(); | ||
969 | } | ||
970 | |||
971 | |||
972 | static inline int | ||
973 | zero_entry_counter(struct ipt_entry *e, void *arg) | ||
974 | { | ||
975 | e->counters.bcnt = 0; | ||
976 | e->counters.pcnt = 0; | ||
977 | return 0; | ||
978 | } | ||
979 | |||
980 | static void | ||
981 | clone_counters(struct xt_table_info *newinfo, const struct xt_table_info *info) | ||
982 | { | ||
983 | unsigned int cpu; | ||
984 | const void *loc_cpu_entry = info->entries[raw_smp_processor_id()]; | ||
985 | |||
986 | memcpy(newinfo, info, offsetof(struct xt_table_info, entries)); | ||
987 | for_each_possible_cpu(cpu) { | ||
988 | memcpy(newinfo->entries[cpu], loc_cpu_entry, info->size); | ||
989 | IPT_ENTRY_ITERATE(newinfo->entries[cpu], newinfo->size, | ||
990 | zero_entry_counter, NULL); | ||
991 | } | ||
927 | } | 992 | } |
928 | 993 | ||
929 | static struct xt_counters * alloc_counters(struct xt_table *table) | 994 | static struct xt_counters * alloc_counters(struct xt_table *table) |
930 | { | 995 | { |
931 | unsigned int countersize; | 996 | unsigned int countersize; |
932 | struct xt_counters *counters; | 997 | struct xt_counters *counters; |
933 | const struct xt_table_info *private = table->private; | 998 | struct xt_table_info *private = table->private; |
999 | struct xt_table_info *info; | ||
934 | 1000 | ||
935 | /* We need atomic snapshot of counters: rest doesn't change | 1001 | /* We need atomic snapshot of counters: rest doesn't change |
936 | (other than comefrom, which userspace doesn't care | 1002 | (other than comefrom, which userspace doesn't care |
@@ -939,14 +1005,30 @@ static struct xt_counters * alloc_counters(struct xt_table *table) | |||
939 | counters = vmalloc_node(countersize, numa_node_id()); | 1005 | counters = vmalloc_node(countersize, numa_node_id()); |
940 | 1006 | ||
941 | if (counters == NULL) | 1007 | if (counters == NULL) |
942 | return ERR_PTR(-ENOMEM); | 1008 | goto nomem; |
1009 | |||
1010 | info = xt_alloc_table_info(private->size); | ||
1011 | if (!info) | ||
1012 | goto free_counters; | ||
943 | 1013 | ||
944 | /* First, sum counters... */ | 1014 | clone_counters(info, private); |
945 | write_lock_bh(&table->lock); | 1015 | |
946 | get_counters(private, counters); | 1016 | mutex_lock(&table->lock); |
947 | write_unlock_bh(&table->lock); | 1017 | xt_table_entry_swap_rcu(private, info); |
1018 | synchronize_net(); /* Wait until smoke has cleared */ | ||
1019 | |||
1020 | get_counters(info, counters); | ||
1021 | put_counters(private, counters); | ||
1022 | mutex_unlock(&table->lock); | ||
1023 | |||
1024 | xt_free_table_info(info); | ||
948 | 1025 | ||
949 | return counters; | 1026 | return counters; |
1027 | |||
1028 | free_counters: | ||
1029 | vfree(counters); | ||
1030 | nomem: | ||
1031 | return ERR_PTR(-ENOMEM); | ||
950 | } | 1032 | } |
951 | 1033 | ||
952 | static int | 1034 | static int |
@@ -1312,27 +1394,6 @@ do_replace(struct net *net, void __user *user, unsigned int len) | |||
1312 | return ret; | 1394 | return ret; |
1313 | } | 1395 | } |
1314 | 1396 | ||
1315 | /* We're lazy, and add to the first CPU; overflow works its fey magic | ||
1316 | * and everything is OK. */ | ||
1317 | static int | ||
1318 | add_counter_to_entry(struct ipt_entry *e, | ||
1319 | const struct xt_counters addme[], | ||
1320 | unsigned int *i) | ||
1321 | { | ||
1322 | #if 0 | ||
1323 | duprintf("add_counter: Entry %u %lu/%lu + %lu/%lu\n", | ||
1324 | *i, | ||
1325 | (long unsigned int)e->counters.pcnt, | ||
1326 | (long unsigned int)e->counters.bcnt, | ||
1327 | (long unsigned int)addme[*i].pcnt, | ||
1328 | (long unsigned int)addme[*i].bcnt); | ||
1329 | #endif | ||
1330 | |||
1331 | ADD_COUNTER(e->counters, addme[*i].bcnt, addme[*i].pcnt); | ||
1332 | |||
1333 | (*i)++; | ||
1334 | return 0; | ||
1335 | } | ||
1336 | 1397 | ||
1337 | static int | 1398 | static int |
1338 | do_add_counters(struct net *net, void __user *user, unsigned int len, int compat) | 1399 | do_add_counters(struct net *net, void __user *user, unsigned int len, int compat) |
@@ -1393,13 +1454,14 @@ do_add_counters(struct net *net, void __user *user, unsigned int len, int compat | |||
1393 | goto free; | 1454 | goto free; |
1394 | } | 1455 | } |
1395 | 1456 | ||
1396 | write_lock_bh(&t->lock); | 1457 | mutex_lock(&t->lock); |
1397 | private = t->private; | 1458 | private = t->private; |
1398 | if (private->number != num_counters) { | 1459 | if (private->number != num_counters) { |
1399 | ret = -EINVAL; | 1460 | ret = -EINVAL; |
1400 | goto unlock_up_free; | 1461 | goto unlock_up_free; |
1401 | } | 1462 | } |
1402 | 1463 | ||
1464 | preempt_disable(); | ||
1403 | i = 0; | 1465 | i = 0; |
1404 | /* Choose the copy that is on our node */ | 1466 | /* Choose the copy that is on our node */ |
1405 | loc_cpu_entry = private->entries[raw_smp_processor_id()]; | 1467 | loc_cpu_entry = private->entries[raw_smp_processor_id()]; |
@@ -1408,8 +1470,9 @@ do_add_counters(struct net *net, void __user *user, unsigned int len, int compat | |||
1408 | add_counter_to_entry, | 1470 | add_counter_to_entry, |
1409 | paddc, | 1471 | paddc, |
1410 | &i); | 1472 | &i); |
1473 | preempt_enable(); | ||
1411 | unlock_up_free: | 1474 | unlock_up_free: |
1412 | write_unlock_bh(&t->lock); | 1475 | mutex_unlock(&t->lock); |
1413 | xt_table_unlock(t); | 1476 | xt_table_unlock(t); |
1414 | module_put(t->me); | 1477 | module_put(t->me); |
1415 | free: | 1478 | free: |
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c index 27a78fbbd92b..acc44c69eb68 100644 --- a/net/ipv4/netfilter/ipt_LOG.c +++ b/net/ipv4/netfilter/ipt_LOG.c | |||
@@ -464,7 +464,7 @@ static struct xt_target log_tg_reg __read_mostly = { | |||
464 | .me = THIS_MODULE, | 464 | .me = THIS_MODULE, |
465 | }; | 465 | }; |
466 | 466 | ||
467 | static const struct nf_logger ipt_log_logger ={ | 467 | static struct nf_logger ipt_log_logger __read_mostly = { |
468 | .name = "ipt_LOG", | 468 | .name = "ipt_LOG", |
469 | .logfn = &ipt_log_packet, | 469 | .logfn = &ipt_log_packet, |
470 | .me = THIS_MODULE, | 470 | .me = THIS_MODULE, |
diff --git a/net/ipv4/netfilter/ipt_TTL.c b/net/ipv4/netfilter/ipt_TTL.c deleted file mode 100644 index 6d76aae90cc0..000000000000 --- a/net/ipv4/netfilter/ipt_TTL.c +++ /dev/null | |||
@@ -1,97 +0,0 @@ | |||
1 | /* TTL modification target for IP tables | ||
2 | * (C) 2000,2005 by Harald Welte <laforge@netfilter.org> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/skbuff.h> | ||
12 | #include <linux/ip.h> | ||
13 | #include <net/checksum.h> | ||
14 | |||
15 | #include <linux/netfilter/x_tables.h> | ||
16 | #include <linux/netfilter_ipv4/ipt_TTL.h> | ||
17 | |||
18 | MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); | ||
19 | MODULE_DESCRIPTION("Xtables: IPv4 TTL field modification target"); | ||
20 | MODULE_LICENSE("GPL"); | ||
21 | |||
22 | static unsigned int | ||
23 | ttl_tg(struct sk_buff *skb, const struct xt_target_param *par) | ||
24 | { | ||
25 | struct iphdr *iph; | ||
26 | const struct ipt_TTL_info *info = par->targinfo; | ||
27 | int new_ttl; | ||
28 | |||
29 | if (!skb_make_writable(skb, skb->len)) | ||
30 | return NF_DROP; | ||
31 | |||
32 | iph = ip_hdr(skb); | ||
33 | |||
34 | switch (info->mode) { | ||
35 | case IPT_TTL_SET: | ||
36 | new_ttl = info->ttl; | ||
37 | break; | ||
38 | case IPT_TTL_INC: | ||
39 | new_ttl = iph->ttl + info->ttl; | ||
40 | if (new_ttl > 255) | ||
41 | new_ttl = 255; | ||
42 | break; | ||
43 | case IPT_TTL_DEC: | ||
44 | new_ttl = iph->ttl - info->ttl; | ||
45 | if (new_ttl < 0) | ||
46 | new_ttl = 0; | ||
47 | break; | ||
48 | default: | ||
49 | new_ttl = iph->ttl; | ||
50 | break; | ||
51 | } | ||
52 | |||
53 | if (new_ttl != iph->ttl) { | ||
54 | csum_replace2(&iph->check, htons(iph->ttl << 8), | ||
55 | htons(new_ttl << 8)); | ||
56 | iph->ttl = new_ttl; | ||
57 | } | ||
58 | |||
59 | return XT_CONTINUE; | ||
60 | } | ||
61 | |||
62 | static bool ttl_tg_check(const struct xt_tgchk_param *par) | ||
63 | { | ||
64 | const struct ipt_TTL_info *info = par->targinfo; | ||
65 | |||
66 | if (info->mode > IPT_TTL_MAXMODE) { | ||
67 | printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n", | ||
68 | info->mode); | ||
69 | return false; | ||
70 | } | ||
71 | if (info->mode != IPT_TTL_SET && info->ttl == 0) | ||
72 | return false; | ||
73 | return true; | ||
74 | } | ||
75 | |||
76 | static struct xt_target ttl_tg_reg __read_mostly = { | ||
77 | .name = "TTL", | ||
78 | .family = NFPROTO_IPV4, | ||
79 | .target = ttl_tg, | ||
80 | .targetsize = sizeof(struct ipt_TTL_info), | ||
81 | .table = "mangle", | ||
82 | .checkentry = ttl_tg_check, | ||
83 | .me = THIS_MODULE, | ||
84 | }; | ||
85 | |||
86 | static int __init ttl_tg_init(void) | ||
87 | { | ||
88 | return xt_register_target(&ttl_tg_reg); | ||
89 | } | ||
90 | |||
91 | static void __exit ttl_tg_exit(void) | ||
92 | { | ||
93 | xt_unregister_target(&ttl_tg_reg); | ||
94 | } | ||
95 | |||
96 | module_init(ttl_tg_init); | ||
97 | module_exit(ttl_tg_exit); | ||
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index 18a2826b57c6..d32cc4bb328a 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c | |||
@@ -379,7 +379,7 @@ static struct xt_target ulog_tg_reg __read_mostly = { | |||
379 | .me = THIS_MODULE, | 379 | .me = THIS_MODULE, |
380 | }; | 380 | }; |
381 | 381 | ||
382 | static struct nf_logger ipt_ulog_logger = { | 382 | static struct nf_logger ipt_ulog_logger __read_mostly = { |
383 | .name = "ipt_ULOG", | 383 | .name = "ipt_ULOG", |
384 | .logfn = ipt_logfn, | 384 | .logfn = ipt_logfn, |
385 | .me = THIS_MODULE, | 385 | .me = THIS_MODULE, |
diff --git a/net/ipv4/netfilter/ipt_ttl.c b/net/ipv4/netfilter/ipt_ttl.c deleted file mode 100644 index 297f1cbf4ff5..000000000000 --- a/net/ipv4/netfilter/ipt_ttl.c +++ /dev/null | |||
@@ -1,63 +0,0 @@ | |||
1 | /* IP tables module for matching the value of the TTL | ||
2 | * | ||
3 | * (C) 2000,2001 by Harald Welte <laforge@netfilter.org> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | #include <linux/ip.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/skbuff.h> | ||
13 | |||
14 | #include <linux/netfilter_ipv4/ipt_ttl.h> | ||
15 | #include <linux/netfilter/x_tables.h> | ||
16 | |||
17 | MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); | ||
18 | MODULE_DESCRIPTION("Xtables: IPv4 TTL field match"); | ||
19 | MODULE_LICENSE("GPL"); | ||
20 | |||
21 | static bool ttl_mt(const struct sk_buff *skb, const struct xt_match_param *par) | ||
22 | { | ||
23 | const struct ipt_ttl_info *info = par->matchinfo; | ||
24 | const u8 ttl = ip_hdr(skb)->ttl; | ||
25 | |||
26 | switch (info->mode) { | ||
27 | case IPT_TTL_EQ: | ||
28 | return ttl == info->ttl; | ||
29 | case IPT_TTL_NE: | ||
30 | return ttl != info->ttl; | ||
31 | case IPT_TTL_LT: | ||
32 | return ttl < info->ttl; | ||
33 | case IPT_TTL_GT: | ||
34 | return ttl > info->ttl; | ||
35 | default: | ||
36 | printk(KERN_WARNING "ipt_ttl: unknown mode %d\n", | ||
37 | info->mode); | ||
38 | return false; | ||
39 | } | ||
40 | |||
41 | return false; | ||
42 | } | ||
43 | |||
44 | static struct xt_match ttl_mt_reg __read_mostly = { | ||
45 | .name = "ttl", | ||
46 | .family = NFPROTO_IPV4, | ||
47 | .match = ttl_mt, | ||
48 | .matchsize = sizeof(struct ipt_ttl_info), | ||
49 | .me = THIS_MODULE, | ||
50 | }; | ||
51 | |||
52 | static int __init ttl_mt_init(void) | ||
53 | { | ||
54 | return xt_register_match(&ttl_mt_reg); | ||
55 | } | ||
56 | |||
57 | static void __exit ttl_mt_exit(void) | ||
58 | { | ||
59 | xt_unregister_match(&ttl_mt_reg); | ||
60 | } | ||
61 | |||
62 | module_init(ttl_mt_init); | ||
63 | module_exit(ttl_mt_exit); | ||
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c index 52cb6939d093..c30a969724f8 100644 --- a/net/ipv4/netfilter/iptable_filter.c +++ b/net/ipv4/netfilter/iptable_filter.c | |||
@@ -56,7 +56,6 @@ static struct | |||
56 | static struct xt_table packet_filter = { | 56 | static struct xt_table packet_filter = { |
57 | .name = "filter", | 57 | .name = "filter", |
58 | .valid_hooks = FILTER_VALID_HOOKS, | 58 | .valid_hooks = FILTER_VALID_HOOKS, |
59 | .lock = __RW_LOCK_UNLOCKED(packet_filter.lock), | ||
60 | .me = THIS_MODULE, | 59 | .me = THIS_MODULE, |
61 | .af = AF_INET, | 60 | .af = AF_INET, |
62 | }; | 61 | }; |
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c index 3929d20b9e45..4087614d9519 100644 --- a/net/ipv4/netfilter/iptable_mangle.c +++ b/net/ipv4/netfilter/iptable_mangle.c | |||
@@ -67,7 +67,6 @@ static struct | |||
67 | static struct xt_table packet_mangler = { | 67 | static struct xt_table packet_mangler = { |
68 | .name = "mangle", | 68 | .name = "mangle", |
69 | .valid_hooks = MANGLE_VALID_HOOKS, | 69 | .valid_hooks = MANGLE_VALID_HOOKS, |
70 | .lock = __RW_LOCK_UNLOCKED(packet_mangler.lock), | ||
71 | .me = THIS_MODULE, | 70 | .me = THIS_MODULE, |
72 | .af = AF_INET, | 71 | .af = AF_INET, |
73 | }; | 72 | }; |
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c index 7f65d18333e3..e5356da1fb54 100644 --- a/net/ipv4/netfilter/iptable_raw.c +++ b/net/ipv4/netfilter/iptable_raw.c | |||
@@ -39,7 +39,6 @@ static struct | |||
39 | static struct xt_table packet_raw = { | 39 | static struct xt_table packet_raw = { |
40 | .name = "raw", | 40 | .name = "raw", |
41 | .valid_hooks = RAW_VALID_HOOKS, | 41 | .valid_hooks = RAW_VALID_HOOKS, |
42 | .lock = __RW_LOCK_UNLOCKED(packet_raw.lock), | ||
43 | .me = THIS_MODULE, | 42 | .me = THIS_MODULE, |
44 | .af = AF_INET, | 43 | .af = AF_INET, |
45 | }; | 44 | }; |
diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c index a52a35f4a584..29ab630f240a 100644 --- a/net/ipv4/netfilter/iptable_security.c +++ b/net/ipv4/netfilter/iptable_security.c | |||
@@ -60,7 +60,6 @@ static struct | |||
60 | static struct xt_table security_table = { | 60 | static struct xt_table security_table = { |
61 | .name = "security", | 61 | .name = "security", |
62 | .valid_hooks = SECURITY_VALID_HOOKS, | 62 | .valid_hooks = SECURITY_VALID_HOOKS, |
63 | .lock = __RW_LOCK_UNLOCKED(security_table.lock), | ||
64 | .me = THIS_MODULE, | 63 | .me = THIS_MODULE, |
65 | .af = AF_INET, | 64 | .af = AF_INET, |
66 | }; | 65 | }; |
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 4beb04fac588..8b681f24e271 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | |||
@@ -120,8 +120,10 @@ static unsigned int ipv4_confirm(unsigned int hooknum, | |||
120 | typeof(nf_nat_seq_adjust_hook) seq_adjust; | 120 | typeof(nf_nat_seq_adjust_hook) seq_adjust; |
121 | 121 | ||
122 | seq_adjust = rcu_dereference(nf_nat_seq_adjust_hook); | 122 | seq_adjust = rcu_dereference(nf_nat_seq_adjust_hook); |
123 | if (!seq_adjust || !seq_adjust(skb, ct, ctinfo)) | 123 | if (!seq_adjust || !seq_adjust(skb, ct, ctinfo)) { |
124 | NF_CT_STAT_INC_ATOMIC(nf_ct_net(ct), drop); | ||
124 | return NF_DROP; | 125 | return NF_DROP; |
126 | } | ||
125 | } | 127 | } |
126 | out: | 128 | out: |
127 | /* We've seen it coming out the other side: confirm it */ | 129 | /* We've seen it coming out the other side: confirm it */ |
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c index a7eb04719044..6348a793936e 100644 --- a/net/ipv4/netfilter/nf_nat_rule.c +++ b/net/ipv4/netfilter/nf_nat_rule.c | |||
@@ -61,7 +61,6 @@ static struct | |||
61 | static struct xt_table nat_table = { | 61 | static struct xt_table nat_table = { |
62 | .name = "nat", | 62 | .name = "nat", |
63 | .valid_hooks = NAT_VALID_HOOKS, | 63 | .valid_hooks = NAT_VALID_HOOKS, |
64 | .lock = __RW_LOCK_UNLOCKED(nat_table.lock), | ||
65 | .me = THIS_MODULE, | 64 | .me = THIS_MODULE, |
66 | .af = AF_INET, | 65 | .af = AF_INET, |
67 | }; | 66 | }; |