diff options
author | David S. Miller <davem@davemloft.net> | 2008-04-14 06:50:43 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-04-14 06:50:43 -0400 |
commit | 334f8b2afd9652e20f67ddee4fec483ed860425b (patch) | |
tree | 35d4fb46a9dc145e831fe5da026f2bfd9ee6657c /net/ipv4 | |
parent | 7477fd2e6b676fcd15861c2a96a7172f71afe0a5 (diff) | |
parent | ef1a5a50bbd509b8697dcd4d13017e9e0053867b (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6.26
Diffstat (limited to 'net/ipv4')
33 files changed, 768 insertions, 487 deletions
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index 9a904c6c0dc8..f8edacdf991d 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c | |||
@@ -182,21 +182,44 @@ __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook, | |||
182 | } | 182 | } |
183 | return csum; | 183 | return csum; |
184 | } | 184 | } |
185 | |||
186 | EXPORT_SYMBOL(nf_ip_checksum); | 185 | EXPORT_SYMBOL(nf_ip_checksum); |
187 | 186 | ||
187 | static __sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook, | ||
188 | unsigned int dataoff, unsigned int len, | ||
189 | u_int8_t protocol) | ||
190 | { | ||
191 | const struct iphdr *iph = ip_hdr(skb); | ||
192 | __sum16 csum = 0; | ||
193 | |||
194 | switch (skb->ip_summed) { | ||
195 | case CHECKSUM_COMPLETE: | ||
196 | if (len == skb->len - dataoff) | ||
197 | return nf_ip_checksum(skb, hook, dataoff, protocol); | ||
198 | /* fall through */ | ||
199 | case CHECKSUM_NONE: | ||
200 | skb->csum = csum_tcpudp_nofold(iph->saddr, iph->daddr, protocol, | ||
201 | skb->len - dataoff, 0); | ||
202 | skb->ip_summed = CHECKSUM_NONE; | ||
203 | csum = __skb_checksum_complete_head(skb, dataoff + len); | ||
204 | if (!csum) | ||
205 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
206 | } | ||
207 | return csum; | ||
208 | } | ||
209 | |||
188 | static int nf_ip_route(struct dst_entry **dst, struct flowi *fl) | 210 | static int nf_ip_route(struct dst_entry **dst, struct flowi *fl) |
189 | { | 211 | { |
190 | return ip_route_output_key(&init_net, (struct rtable **)dst, fl); | 212 | return ip_route_output_key(&init_net, (struct rtable **)dst, fl); |
191 | } | 213 | } |
192 | 214 | ||
193 | static const struct nf_afinfo nf_ip_afinfo = { | 215 | static const struct nf_afinfo nf_ip_afinfo = { |
194 | .family = AF_INET, | 216 | .family = AF_INET, |
195 | .checksum = nf_ip_checksum, | 217 | .checksum = nf_ip_checksum, |
196 | .route = nf_ip_route, | 218 | .checksum_partial = nf_ip_checksum_partial, |
197 | .saveroute = nf_ip_saveroute, | 219 | .route = nf_ip_route, |
198 | .reroute = nf_ip_reroute, | 220 | .saveroute = nf_ip_saveroute, |
199 | .route_key_size = sizeof(struct ip_rt_info), | 221 | .reroute = nf_ip_reroute, |
222 | .route_key_size = sizeof(struct ip_rt_info), | ||
200 | }; | 223 | }; |
201 | 224 | ||
202 | static int ipv4_netfilter_init(void) | 225 | static int ipv4_netfilter_init(void) |
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index 9a077cb24798..0c95cd5872f3 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig | |||
@@ -241,10 +241,25 @@ config NF_NAT_SNMP_BASIC | |||
241 | # <expr> '&&' <expr> (6) | 241 | # <expr> '&&' <expr> (6) |
242 | # | 242 | # |
243 | # (6) Returns the result of min(/expr/, /expr/). | 243 | # (6) Returns the result of min(/expr/, /expr/). |
244 | config NF_NAT_PROTO_DCCP | ||
245 | tristate | ||
246 | depends on NF_NAT && NF_CT_PROTO_DCCP | ||
247 | default NF_NAT && NF_CT_PROTO_DCCP | ||
248 | |||
244 | config NF_NAT_PROTO_GRE | 249 | config NF_NAT_PROTO_GRE |
245 | tristate | 250 | tristate |
246 | depends on NF_NAT && NF_CT_PROTO_GRE | 251 | depends on NF_NAT && NF_CT_PROTO_GRE |
247 | 252 | ||
253 | config NF_NAT_PROTO_UDPLITE | ||
254 | tristate | ||
255 | depends on NF_NAT && NF_CT_PROTO_UDPLITE | ||
256 | default NF_NAT && NF_CT_PROTO_UDPLITE | ||
257 | |||
258 | config NF_NAT_PROTO_SCTP | ||
259 | tristate | ||
260 | default NF_NAT && NF_CT_PROTO_SCTP | ||
261 | depends on NF_NAT && NF_CT_PROTO_SCTP | ||
262 | |||
248 | config NF_NAT_FTP | 263 | config NF_NAT_FTP |
249 | tristate | 264 | tristate |
250 | depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT | 265 | depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT |
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index 0c7dc78a62e9..d9b92fbf5579 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile | |||
@@ -10,7 +10,7 @@ nf_conntrack_ipv4-objs += nf_conntrack_l3proto_ipv4_compat.o | |||
10 | endif | 10 | endif |
11 | endif | 11 | endif |
12 | 12 | ||
13 | nf_nat-objs := nf_nat_core.o nf_nat_helper.o nf_nat_proto_unknown.o nf_nat_proto_tcp.o nf_nat_proto_udp.o nf_nat_proto_icmp.o | 13 | nf_nat-objs := nf_nat_core.o nf_nat_helper.o nf_nat_proto_unknown.o nf_nat_proto_common.o nf_nat_proto_tcp.o nf_nat_proto_udp.o nf_nat_proto_icmp.o |
14 | iptable_nat-objs := nf_nat_rule.o nf_nat_standalone.o | 14 | iptable_nat-objs := nf_nat_rule.o nf_nat_standalone.o |
15 | 15 | ||
16 | # connection tracking | 16 | # connection tracking |
@@ -29,7 +29,10 @@ obj-$(CONFIG_NF_NAT_SNMP_BASIC) += nf_nat_snmp_basic.o | |||
29 | obj-$(CONFIG_NF_NAT_TFTP) += nf_nat_tftp.o | 29 | obj-$(CONFIG_NF_NAT_TFTP) += nf_nat_tftp.o |
30 | 30 | ||
31 | # NAT protocols (nf_nat) | 31 | # NAT protocols (nf_nat) |
32 | obj-$(CONFIG_NF_NAT_PROTO_DCCP) += nf_nat_proto_dccp.o | ||
32 | obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o | 33 | obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o |
34 | obj-$(CONFIG_NF_NAT_PROTO_UDPLITE) += nf_nat_proto_udplite.o | ||
35 | obj-$(CONFIG_NF_NAT_PROTO_SCTP) += nf_nat_proto_sctp.o | ||
33 | 36 | ||
34 | # generic IP tables | 37 | # generic IP tables |
35 | obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o | 38 | obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o |
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 1563f29b5117..03e83a65aec5 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -59,7 +59,7 @@ do { \ | |||
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap, | 61 | static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap, |
62 | char *hdr_addr, int len) | 62 | const char *hdr_addr, int len) |
63 | { | 63 | { |
64 | int i, ret; | 64 | int i, ret; |
65 | 65 | ||
@@ -80,8 +80,8 @@ static inline int arp_packet_match(const struct arphdr *arphdr, | |||
80 | const char *outdev, | 80 | const char *outdev, |
81 | const struct arpt_arp *arpinfo) | 81 | const struct arpt_arp *arpinfo) |
82 | { | 82 | { |
83 | char *arpptr = (char *)(arphdr + 1); | 83 | const char *arpptr = (char *)(arphdr + 1); |
84 | char *src_devaddr, *tgt_devaddr; | 84 | const char *src_devaddr, *tgt_devaddr; |
85 | __be32 src_ipaddr, tgt_ipaddr; | 85 | __be32 src_ipaddr, tgt_ipaddr; |
86 | int i, ret; | 86 | int i, ret; |
87 | 87 | ||
@@ -222,16 +222,16 @@ unsigned int arpt_do_table(struct sk_buff *skb, | |||
222 | unsigned int hook, | 222 | unsigned int hook, |
223 | const struct net_device *in, | 223 | const struct net_device *in, |
224 | const struct net_device *out, | 224 | const struct net_device *out, |
225 | struct arpt_table *table) | 225 | struct xt_table *table) |
226 | { | 226 | { |
227 | static const char nulldevname[IFNAMSIZ]; | 227 | static const char nulldevname[IFNAMSIZ]; |
228 | unsigned int verdict = NF_DROP; | 228 | unsigned int verdict = NF_DROP; |
229 | struct arphdr *arp; | 229 | const struct arphdr *arp; |
230 | bool hotdrop = false; | 230 | bool hotdrop = false; |
231 | struct arpt_entry *e, *back; | 231 | struct arpt_entry *e, *back; |
232 | const char *indev, *outdev; | 232 | const char *indev, *outdev; |
233 | void *table_base; | 233 | void *table_base; |
234 | struct xt_table_info *private; | 234 | const struct xt_table_info *private; |
235 | 235 | ||
236 | if (!pskb_may_pull(skb, arp_hdr_len(skb->dev))) | 236 | if (!pskb_may_pull(skb, arp_hdr_len(skb->dev))) |
237 | return NF_DROP; | 237 | return NF_DROP; |
@@ -352,7 +352,7 @@ static int mark_source_chains(struct xt_table_info *newinfo, | |||
352 | e->counters.pcnt = pos; | 352 | e->counters.pcnt = pos; |
353 | 353 | ||
354 | for (;;) { | 354 | for (;;) { |
355 | struct arpt_standard_target *t | 355 | const struct arpt_standard_target *t |
356 | = (void *)arpt_get_target(e); | 356 | = (void *)arpt_get_target(e); |
357 | int visited = e->comefrom & (1 << hook); | 357 | int visited = e->comefrom & (1 << hook); |
358 | 358 | ||
@@ -437,7 +437,7 @@ static int mark_source_chains(struct xt_table_info *newinfo, | |||
437 | 437 | ||
438 | static inline int check_entry(struct arpt_entry *e, const char *name) | 438 | static inline int check_entry(struct arpt_entry *e, const char *name) |
439 | { | 439 | { |
440 | struct arpt_entry_target *t; | 440 | const struct arpt_entry_target *t; |
441 | 441 | ||
442 | if (!arp_checkentry(&e->arp)) { | 442 | if (!arp_checkentry(&e->arp)) { |
443 | duprintf("arp_tables: arp check failed %p %s.\n", e, name); | 443 | duprintf("arp_tables: arp check failed %p %s.\n", e, name); |
@@ -457,7 +457,7 @@ static inline int check_entry(struct arpt_entry *e, const char *name) | |||
457 | static inline int check_target(struct arpt_entry *e, const char *name) | 457 | static inline int check_target(struct arpt_entry *e, const char *name) |
458 | { | 458 | { |
459 | struct arpt_entry_target *t; | 459 | struct arpt_entry_target *t; |
460 | struct arpt_target *target; | 460 | struct xt_target *target; |
461 | int ret; | 461 | int ret; |
462 | 462 | ||
463 | t = arpt_get_target(e); | 463 | t = arpt_get_target(e); |
@@ -480,7 +480,7 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size, | |||
480 | unsigned int *i) | 480 | unsigned int *i) |
481 | { | 481 | { |
482 | struct arpt_entry_target *t; | 482 | struct arpt_entry_target *t; |
483 | struct arpt_target *target; | 483 | struct xt_target *target; |
484 | int ret; | 484 | int ret; |
485 | 485 | ||
486 | ret = check_entry(e, name); | 486 | ret = check_entry(e, name); |
@@ -706,11 +706,11 @@ static void get_counters(const struct xt_table_info *t, | |||
706 | } | 706 | } |
707 | } | 707 | } |
708 | 708 | ||
709 | static inline struct xt_counters *alloc_counters(struct arpt_table *table) | 709 | static inline struct xt_counters *alloc_counters(struct xt_table *table) |
710 | { | 710 | { |
711 | unsigned int countersize; | 711 | unsigned int countersize; |
712 | struct xt_counters *counters; | 712 | struct xt_counters *counters; |
713 | struct xt_table_info *private = table->private; | 713 | const struct xt_table_info *private = table->private; |
714 | 714 | ||
715 | /* We need atomic snapshot of counters: rest doesn't change | 715 | /* We need atomic snapshot of counters: rest doesn't change |
716 | * (other than comefrom, which userspace doesn't care | 716 | * (other than comefrom, which userspace doesn't care |
@@ -731,7 +731,7 @@ static inline struct xt_counters *alloc_counters(struct arpt_table *table) | |||
731 | } | 731 | } |
732 | 732 | ||
733 | static int copy_entries_to_user(unsigned int total_size, | 733 | static int copy_entries_to_user(unsigned int total_size, |
734 | struct arpt_table *table, | 734 | struct xt_table *table, |
735 | void __user *userptr) | 735 | void __user *userptr) |
736 | { | 736 | { |
737 | unsigned int off, num; | 737 | unsigned int off, num; |
@@ -851,7 +851,7 @@ static int compat_table_info(const struct xt_table_info *info, | |||
851 | static int get_info(struct net *net, void __user *user, int *len, int compat) | 851 | static int get_info(struct net *net, void __user *user, int *len, int compat) |
852 | { | 852 | { |
853 | char name[ARPT_TABLE_MAXNAMELEN]; | 853 | char name[ARPT_TABLE_MAXNAMELEN]; |
854 | struct arpt_table *t; | 854 | struct xt_table *t; |
855 | int ret; | 855 | int ret; |
856 | 856 | ||
857 | if (*len != sizeof(struct arpt_getinfo)) { | 857 | if (*len != sizeof(struct arpt_getinfo)) { |
@@ -872,7 +872,7 @@ static int get_info(struct net *net, void __user *user, int *len, int compat) | |||
872 | "arptable_%s", name); | 872 | "arptable_%s", name); |
873 | if (t && !IS_ERR(t)) { | 873 | if (t && !IS_ERR(t)) { |
874 | struct arpt_getinfo info; | 874 | struct arpt_getinfo info; |
875 | struct xt_table_info *private = t->private; | 875 | const struct xt_table_info *private = t->private; |
876 | 876 | ||
877 | #ifdef CONFIG_COMPAT | 877 | #ifdef CONFIG_COMPAT |
878 | if (compat) { | 878 | if (compat) { |
@@ -911,7 +911,7 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr, | |||
911 | { | 911 | { |
912 | int ret; | 912 | int ret; |
913 | struct arpt_get_entries get; | 913 | struct arpt_get_entries get; |
914 | struct arpt_table *t; | 914 | struct xt_table *t; |
915 | 915 | ||
916 | if (*len < sizeof(get)) { | 916 | if (*len < sizeof(get)) { |
917 | duprintf("get_entries: %u < %Zu\n", *len, sizeof(get)); | 917 | duprintf("get_entries: %u < %Zu\n", *len, sizeof(get)); |
@@ -927,7 +927,8 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr, | |||
927 | 927 | ||
928 | t = xt_find_table_lock(net, NF_ARP, get.name); | 928 | t = xt_find_table_lock(net, NF_ARP, get.name); |
929 | if (t && !IS_ERR(t)) { | 929 | if (t && !IS_ERR(t)) { |
930 | struct xt_table_info *private = t->private; | 930 | const struct xt_table_info *private = t->private; |
931 | |||
931 | duprintf("t->private->number = %u\n", | 932 | duprintf("t->private->number = %u\n", |
932 | private->number); | 933 | private->number); |
933 | if (get.size == private->size) | 934 | if (get.size == private->size) |
@@ -936,7 +937,7 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr, | |||
936 | else { | 937 | else { |
937 | duprintf("get_entries: I've got %u not %u!\n", | 938 | duprintf("get_entries: I've got %u not %u!\n", |
938 | private->size, get.size); | 939 | private->size, get.size); |
939 | ret = -EINVAL; | 940 | ret = -EAGAIN; |
940 | } | 941 | } |
941 | module_put(t->me); | 942 | module_put(t->me); |
942 | xt_table_unlock(t); | 943 | xt_table_unlock(t); |
@@ -953,7 +954,7 @@ static int __do_replace(struct net *net, const char *name, | |||
953 | void __user *counters_ptr) | 954 | void __user *counters_ptr) |
954 | { | 955 | { |
955 | int ret; | 956 | int ret; |
956 | struct arpt_table *t; | 957 | struct xt_table *t; |
957 | struct xt_table_info *oldinfo; | 958 | struct xt_table_info *oldinfo; |
958 | struct xt_counters *counters; | 959 | struct xt_counters *counters; |
959 | void *loc_cpu_old_entry; | 960 | void *loc_cpu_old_entry; |
@@ -1087,11 +1088,11 @@ static int do_add_counters(struct net *net, void __user *user, unsigned int len, | |||
1087 | struct xt_counters_info tmp; | 1088 | struct xt_counters_info tmp; |
1088 | struct xt_counters *paddc; | 1089 | struct xt_counters *paddc; |
1089 | unsigned int num_counters; | 1090 | unsigned int num_counters; |
1090 | char *name; | 1091 | const char *name; |
1091 | int size; | 1092 | int size; |
1092 | void *ptmp; | 1093 | void *ptmp; |
1093 | struct arpt_table *t; | 1094 | struct xt_table *t; |
1094 | struct xt_table_info *private; | 1095 | const struct xt_table_info *private; |
1095 | int ret = 0; | 1096 | int ret = 0; |
1096 | void *loc_cpu_entry; | 1097 | void *loc_cpu_entry; |
1097 | #ifdef CONFIG_COMPAT | 1098 | #ifdef CONFIG_COMPAT |
@@ -1554,11 +1555,11 @@ out: | |||
1554 | } | 1555 | } |
1555 | 1556 | ||
1556 | static int compat_copy_entries_to_user(unsigned int total_size, | 1557 | static int compat_copy_entries_to_user(unsigned int total_size, |
1557 | struct arpt_table *table, | 1558 | struct xt_table *table, |
1558 | void __user *userptr) | 1559 | void __user *userptr) |
1559 | { | 1560 | { |
1560 | struct xt_counters *counters; | 1561 | struct xt_counters *counters; |
1561 | struct xt_table_info *private = table->private; | 1562 | const struct xt_table_info *private = table->private; |
1562 | void __user *pos; | 1563 | void __user *pos; |
1563 | unsigned int size; | 1564 | unsigned int size; |
1564 | int ret = 0; | 1565 | int ret = 0; |
@@ -1592,7 +1593,7 @@ static int compat_get_entries(struct net *net, | |||
1592 | { | 1593 | { |
1593 | int ret; | 1594 | int ret; |
1594 | struct compat_arpt_get_entries get; | 1595 | struct compat_arpt_get_entries get; |
1595 | struct arpt_table *t; | 1596 | struct xt_table *t; |
1596 | 1597 | ||
1597 | if (*len < sizeof(get)) { | 1598 | if (*len < sizeof(get)) { |
1598 | duprintf("compat_get_entries: %u < %zu\n", *len, sizeof(get)); | 1599 | duprintf("compat_get_entries: %u < %zu\n", *len, sizeof(get)); |
@@ -1609,7 +1610,7 @@ static int compat_get_entries(struct net *net, | |||
1609 | xt_compat_lock(NF_ARP); | 1610 | xt_compat_lock(NF_ARP); |
1610 | t = xt_find_table_lock(net, NF_ARP, get.name); | 1611 | t = xt_find_table_lock(net, NF_ARP, get.name); |
1611 | if (t && !IS_ERR(t)) { | 1612 | if (t && !IS_ERR(t)) { |
1612 | struct xt_table_info *private = t->private; | 1613 | const struct xt_table_info *private = t->private; |
1613 | struct xt_table_info info; | 1614 | struct xt_table_info info; |
1614 | 1615 | ||
1615 | duprintf("t->private->number = %u\n", private->number); | 1616 | duprintf("t->private->number = %u\n", private->number); |
@@ -1620,7 +1621,7 @@ static int compat_get_entries(struct net *net, | |||
1620 | } else if (!ret) { | 1621 | } else if (!ret) { |
1621 | duprintf("compat_get_entries: I've got %u not %u!\n", | 1622 | duprintf("compat_get_entries: I've got %u not %u!\n", |
1622 | private->size, get.size); | 1623 | private->size, get.size); |
1623 | ret = -EINVAL; | 1624 | ret = -EAGAIN; |
1624 | } | 1625 | } |
1625 | xt_compat_flush_offsets(NF_ARP); | 1626 | xt_compat_flush_offsets(NF_ARP); |
1626 | module_put(t->me); | 1627 | module_put(t->me); |
@@ -1722,9 +1723,8 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len | |||
1722 | return ret; | 1723 | return ret; |
1723 | } | 1724 | } |
1724 | 1725 | ||
1725 | struct arpt_table *arpt_register_table(struct net *net, | 1726 | struct xt_table *arpt_register_table(struct net *net, struct xt_table *table, |
1726 | struct arpt_table *table, | 1727 | const struct arpt_replace *repl) |
1727 | const struct arpt_replace *repl) | ||
1728 | { | 1728 | { |
1729 | int ret; | 1729 | int ret; |
1730 | struct xt_table_info *newinfo; | 1730 | struct xt_table_info *newinfo; |
@@ -1766,7 +1766,7 @@ out: | |||
1766 | return ERR_PTR(ret); | 1766 | return ERR_PTR(ret); |
1767 | } | 1767 | } |
1768 | 1768 | ||
1769 | void arpt_unregister_table(struct arpt_table *table) | 1769 | void arpt_unregister_table(struct xt_table *table) |
1770 | { | 1770 | { |
1771 | struct xt_table_info *private; | 1771 | struct xt_table_info *private; |
1772 | void *loc_cpu_entry; | 1772 | void *loc_cpu_entry; |
@@ -1784,7 +1784,7 @@ void arpt_unregister_table(struct arpt_table *table) | |||
1784 | } | 1784 | } |
1785 | 1785 | ||
1786 | /* The built-in targets: standard (NULL) and error. */ | 1786 | /* The built-in targets: standard (NULL) and error. */ |
1787 | static struct arpt_target arpt_standard_target __read_mostly = { | 1787 | static struct xt_target arpt_standard_target __read_mostly = { |
1788 | .name = ARPT_STANDARD_TARGET, | 1788 | .name = ARPT_STANDARD_TARGET, |
1789 | .targetsize = sizeof(int), | 1789 | .targetsize = sizeof(int), |
1790 | .family = NF_ARP, | 1790 | .family = NF_ARP, |
@@ -1795,7 +1795,7 @@ static struct arpt_target arpt_standard_target __read_mostly = { | |||
1795 | #endif | 1795 | #endif |
1796 | }; | 1796 | }; |
1797 | 1797 | ||
1798 | static struct arpt_target arpt_error_target __read_mostly = { | 1798 | static struct xt_target arpt_error_target __read_mostly = { |
1799 | .name = ARPT_ERROR_TARGET, | 1799 | .name = ARPT_ERROR_TARGET, |
1800 | .target = arpt_error, | 1800 | .target = arpt_error, |
1801 | .targetsize = ARPT_FUNCTION_MAXNAMELEN, | 1801 | .targetsize = ARPT_FUNCTION_MAXNAMELEN, |
diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c index 3f4222b0a803..a385959d2655 100644 --- a/net/ipv4/netfilter/arpt_mangle.c +++ b/net/ipv4/netfilter/arpt_mangle.c | |||
@@ -15,7 +15,7 @@ target(struct sk_buff *skb, | |||
15 | const void *targinfo) | 15 | const void *targinfo) |
16 | { | 16 | { |
17 | const struct arpt_mangle *mangle = targinfo; | 17 | const struct arpt_mangle *mangle = targinfo; |
18 | struct arphdr *arp; | 18 | const struct arphdr *arp; |
19 | unsigned char *arpptr; | 19 | unsigned char *arpptr; |
20 | int pln, hln; | 20 | int pln, hln; |
21 | 21 | ||
@@ -73,8 +73,9 @@ checkentry(const char *tablename, const void *e, const struct xt_target *target, | |||
73 | return true; | 73 | return true; |
74 | } | 74 | } |
75 | 75 | ||
76 | static struct arpt_target arpt_mangle_reg __read_mostly = { | 76 | static struct xt_target arpt_mangle_reg __read_mostly = { |
77 | .name = "mangle", | 77 | .name = "mangle", |
78 | .family = NF_ARP, | ||
78 | .target = target, | 79 | .target = target, |
79 | .targetsize = sizeof(struct arpt_mangle), | 80 | .targetsize = sizeof(struct arpt_mangle), |
80 | .checkentry = checkentry, | 81 | .checkentry = checkentry, |
@@ -83,15 +84,12 @@ static struct arpt_target arpt_mangle_reg __read_mostly = { | |||
83 | 84 | ||
84 | static int __init arpt_mangle_init(void) | 85 | static int __init arpt_mangle_init(void) |
85 | { | 86 | { |
86 | if (arpt_register_target(&arpt_mangle_reg)) | 87 | return xt_register_target(&arpt_mangle_reg); |
87 | return -EINVAL; | ||
88 | |||
89 | return 0; | ||
90 | } | 88 | } |
91 | 89 | ||
92 | static void __exit arpt_mangle_fini(void) | 90 | static void __exit arpt_mangle_fini(void) |
93 | { | 91 | { |
94 | arpt_unregister_target(&arpt_mangle_reg); | 92 | xt_unregister_target(&arpt_mangle_reg); |
95 | } | 93 | } |
96 | 94 | ||
97 | module_init(arpt_mangle_init); | 95 | module_init(arpt_mangle_init); |
diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c index 4e9c496a30c2..3be4d07e7ed9 100644 --- a/net/ipv4/netfilter/arptable_filter.c +++ b/net/ipv4/netfilter/arptable_filter.c | |||
@@ -45,10 +45,10 @@ static struct | |||
45 | .term = ARPT_ERROR_INIT, | 45 | .term = ARPT_ERROR_INIT, |
46 | }; | 46 | }; |
47 | 47 | ||
48 | static struct arpt_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, | 51 | .lock = __RW_LOCK_UNLOCKED(packet_filter.lock), |
52 | .private = NULL, | 52 | .private = NULL, |
53 | .me = THIS_MODULE, | 53 | .me = THIS_MODULE, |
54 | .af = NF_ARP, | 54 | .af = NF_ARP, |
@@ -70,18 +70,21 @@ static struct nf_hook_ops arpt_ops[] __read_mostly = { | |||
70 | .owner = THIS_MODULE, | 70 | .owner = THIS_MODULE, |
71 | .pf = NF_ARP, | 71 | .pf = NF_ARP, |
72 | .hooknum = NF_ARP_IN, | 72 | .hooknum = NF_ARP_IN, |
73 | .priority = NF_IP_PRI_FILTER, | ||
73 | }, | 74 | }, |
74 | { | 75 | { |
75 | .hook = arpt_hook, | 76 | .hook = arpt_hook, |
76 | .owner = THIS_MODULE, | 77 | .owner = THIS_MODULE, |
77 | .pf = NF_ARP, | 78 | .pf = NF_ARP, |
78 | .hooknum = NF_ARP_OUT, | 79 | .hooknum = NF_ARP_OUT, |
80 | .priority = NF_IP_PRI_FILTER, | ||
79 | }, | 81 | }, |
80 | { | 82 | { |
81 | .hook = arpt_hook, | 83 | .hook = arpt_hook, |
82 | .owner = THIS_MODULE, | 84 | .owner = THIS_MODULE, |
83 | .pf = NF_ARP, | 85 | .pf = NF_ARP, |
84 | .hooknum = NF_ARP_FORWARD, | 86 | .hooknum = NF_ARP_FORWARD, |
87 | .priority = NF_IP_PRI_FILTER, | ||
85 | }, | 88 | }, |
86 | }; | 89 | }; |
87 | 90 | ||
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index a819d191e1aa..4e7c719445c2 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -296,7 +296,7 @@ static void trace_packet(struct sk_buff *skb, | |||
296 | struct ipt_entry *e) | 296 | struct ipt_entry *e) |
297 | { | 297 | { |
298 | void *table_base; | 298 | void *table_base; |
299 | struct ipt_entry *root; | 299 | const struct ipt_entry *root; |
300 | char *hookname, *chainname, *comment; | 300 | char *hookname, *chainname, *comment; |
301 | unsigned int rulenum = 0; | 301 | unsigned int rulenum = 0; |
302 | 302 | ||
@@ -327,7 +327,7 @@ ipt_do_table(struct sk_buff *skb, | |||
327 | { | 327 | { |
328 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); | 328 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); |
329 | u_int16_t offset; | 329 | u_int16_t offset; |
330 | struct iphdr *ip; | 330 | const struct iphdr *ip; |
331 | u_int16_t datalen; | 331 | u_int16_t datalen; |
332 | bool hotdrop = false; | 332 | bool hotdrop = false; |
333 | /* Initializing verdict to NF_DROP keeps gcc happy. */ | 333 | /* Initializing verdict to NF_DROP keeps gcc happy. */ |
@@ -926,7 +926,7 @@ static struct xt_counters * alloc_counters(struct xt_table *table) | |||
926 | { | 926 | { |
927 | unsigned int countersize; | 927 | unsigned int countersize; |
928 | struct xt_counters *counters; | 928 | struct xt_counters *counters; |
929 | struct xt_table_info *private = table->private; | 929 | const struct xt_table_info *private = table->private; |
930 | 930 | ||
931 | /* We need atomic snapshot of counters: rest doesn't change | 931 | /* We need atomic snapshot of counters: rest doesn't change |
932 | (other than comefrom, which userspace doesn't care | 932 | (other than comefrom, which userspace doesn't care |
@@ -953,9 +953,9 @@ copy_entries_to_user(unsigned int total_size, | |||
953 | unsigned int off, num; | 953 | unsigned int off, num; |
954 | struct ipt_entry *e; | 954 | struct ipt_entry *e; |
955 | struct xt_counters *counters; | 955 | struct xt_counters *counters; |
956 | struct xt_table_info *private = table->private; | 956 | const struct xt_table_info *private = table->private; |
957 | int ret = 0; | 957 | int ret = 0; |
958 | void *loc_cpu_entry; | 958 | const void *loc_cpu_entry; |
959 | 959 | ||
960 | counters = alloc_counters(table); | 960 | counters = alloc_counters(table); |
961 | if (IS_ERR(counters)) | 961 | if (IS_ERR(counters)) |
@@ -975,8 +975,8 @@ copy_entries_to_user(unsigned int total_size, | |||
975 | /* ... then go back and fix counters and names */ | 975 | /* ... then go back and fix counters and names */ |
976 | for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){ | 976 | for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){ |
977 | unsigned int i; | 977 | unsigned int i; |
978 | struct ipt_entry_match *m; | 978 | const struct ipt_entry_match *m; |
979 | struct ipt_entry_target *t; | 979 | const struct ipt_entry_target *t; |
980 | 980 | ||
981 | e = (struct ipt_entry *)(loc_cpu_entry + off); | 981 | e = (struct ipt_entry *)(loc_cpu_entry + off); |
982 | if (copy_to_user(userptr + off | 982 | if (copy_to_user(userptr + off |
@@ -1116,7 +1116,7 @@ static int get_info(struct net *net, void __user *user, int *len, int compat) | |||
1116 | "iptable_%s", name); | 1116 | "iptable_%s", name); |
1117 | if (t && !IS_ERR(t)) { | 1117 | if (t && !IS_ERR(t)) { |
1118 | struct ipt_getinfo info; | 1118 | struct ipt_getinfo info; |
1119 | struct xt_table_info *private = t->private; | 1119 | const struct xt_table_info *private = t->private; |
1120 | 1120 | ||
1121 | #ifdef CONFIG_COMPAT | 1121 | #ifdef CONFIG_COMPAT |
1122 | if (compat) { | 1122 | if (compat) { |
@@ -1172,7 +1172,7 @@ get_entries(struct net *net, struct ipt_get_entries __user *uptr, int *len) | |||
1172 | 1172 | ||
1173 | t = xt_find_table_lock(net, AF_INET, get.name); | 1173 | t = xt_find_table_lock(net, AF_INET, get.name); |
1174 | if (t && !IS_ERR(t)) { | 1174 | if (t && !IS_ERR(t)) { |
1175 | struct xt_table_info *private = t->private; | 1175 | const struct xt_table_info *private = t->private; |
1176 | duprintf("t->private->number = %u\n", private->number); | 1176 | duprintf("t->private->number = %u\n", private->number); |
1177 | if (get.size == private->size) | 1177 | if (get.size == private->size) |
1178 | ret = copy_entries_to_user(private->size, | 1178 | ret = copy_entries_to_user(private->size, |
@@ -1180,7 +1180,7 @@ get_entries(struct net *net, struct ipt_get_entries __user *uptr, int *len) | |||
1180 | else { | 1180 | else { |
1181 | duprintf("get_entries: I've got %u not %u!\n", | 1181 | duprintf("get_entries: I've got %u not %u!\n", |
1182 | private->size, get.size); | 1182 | private->size, get.size); |
1183 | ret = -EINVAL; | 1183 | ret = -EAGAIN; |
1184 | } | 1184 | } |
1185 | module_put(t->me); | 1185 | module_put(t->me); |
1186 | xt_table_unlock(t); | 1186 | xt_table_unlock(t); |
@@ -1337,11 +1337,11 @@ do_add_counters(struct net *net, void __user *user, unsigned int len, int compat | |||
1337 | struct xt_counters_info tmp; | 1337 | struct xt_counters_info tmp; |
1338 | struct xt_counters *paddc; | 1338 | struct xt_counters *paddc; |
1339 | unsigned int num_counters; | 1339 | unsigned int num_counters; |
1340 | char *name; | 1340 | const char *name; |
1341 | int size; | 1341 | int size; |
1342 | void *ptmp; | 1342 | void *ptmp; |
1343 | struct xt_table *t; | 1343 | struct xt_table *t; |
1344 | struct xt_table_info *private; | 1344 | const struct xt_table_info *private; |
1345 | int ret = 0; | 1345 | int ret = 0; |
1346 | void *loc_cpu_entry; | 1346 | void *loc_cpu_entry; |
1347 | #ifdef CONFIG_COMPAT | 1347 | #ifdef CONFIG_COMPAT |
@@ -1878,11 +1878,11 @@ compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table, | |||
1878 | void __user *userptr) | 1878 | void __user *userptr) |
1879 | { | 1879 | { |
1880 | struct xt_counters *counters; | 1880 | struct xt_counters *counters; |
1881 | struct xt_table_info *private = table->private; | 1881 | const struct xt_table_info *private = table->private; |
1882 | void __user *pos; | 1882 | void __user *pos; |
1883 | unsigned int size; | 1883 | unsigned int size; |
1884 | int ret = 0; | 1884 | int ret = 0; |
1885 | void *loc_cpu_entry; | 1885 | const void *loc_cpu_entry; |
1886 | unsigned int i = 0; | 1886 | unsigned int i = 0; |
1887 | 1887 | ||
1888 | counters = alloc_counters(table); | 1888 | counters = alloc_counters(table); |
@@ -1929,7 +1929,7 @@ compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr, | |||
1929 | xt_compat_lock(AF_INET); | 1929 | xt_compat_lock(AF_INET); |
1930 | t = xt_find_table_lock(net, AF_INET, get.name); | 1930 | t = xt_find_table_lock(net, AF_INET, get.name); |
1931 | if (t && !IS_ERR(t)) { | 1931 | if (t && !IS_ERR(t)) { |
1932 | struct xt_table_info *private = t->private; | 1932 | const struct xt_table_info *private = t->private; |
1933 | struct xt_table_info info; | 1933 | struct xt_table_info info; |
1934 | duprintf("t->private->number = %u\n", private->number); | 1934 | duprintf("t->private->number = %u\n", private->number); |
1935 | ret = compat_table_info(private, &info); | 1935 | ret = compat_table_info(private, &info); |
@@ -1939,7 +1939,7 @@ compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr, | |||
1939 | } else if (!ret) { | 1939 | } else if (!ret) { |
1940 | duprintf("compat_get_entries: I've got %u not %u!\n", | 1940 | duprintf("compat_get_entries: I've got %u not %u!\n", |
1941 | private->size, get.size); | 1941 | private->size, get.size); |
1942 | ret = -EINVAL; | 1942 | ret = -EAGAIN; |
1943 | } | 1943 | } |
1944 | xt_compat_flush_offsets(AF_INET); | 1944 | xt_compat_flush_offsets(AF_INET); |
1945 | module_put(t->me); | 1945 | module_put(t->me); |
@@ -2130,7 +2130,8 @@ icmp_match(const struct sk_buff *skb, | |||
2130 | unsigned int protoff, | 2130 | unsigned int protoff, |
2131 | bool *hotdrop) | 2131 | bool *hotdrop) |
2132 | { | 2132 | { |
2133 | struct icmphdr _icmph, *ic; | 2133 | const struct icmphdr *ic; |
2134 | struct icmphdr _icmph; | ||
2134 | const struct ipt_icmp *icmpinfo = matchinfo; | 2135 | const struct ipt_icmp *icmpinfo = matchinfo; |
2135 | 2136 | ||
2136 | /* Must not be a fragment. */ | 2137 | /* Must not be a fragment. */ |
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 380d8daac72b..22d8e7cd9197 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c | |||
@@ -144,7 +144,7 @@ clusterip_config_init_nodelist(struct clusterip_config *c, | |||
144 | } | 144 | } |
145 | 145 | ||
146 | static struct clusterip_config * | 146 | static struct clusterip_config * |
147 | clusterip_config_init(struct ipt_clusterip_tgt_info *i, __be32 ip, | 147 | clusterip_config_init(const struct ipt_clusterip_tgt_info *i, __be32 ip, |
148 | struct net_device *dev) | 148 | struct net_device *dev) |
149 | { | 149 | { |
150 | struct clusterip_config *c; | 150 | struct clusterip_config *c; |
@@ -333,7 +333,7 @@ clusterip_tg(struct sk_buff *skb, const struct net_device *in, | |||
333 | } | 333 | } |
334 | 334 | ||
335 | #ifdef DEBUG | 335 | #ifdef DEBUG |
336 | NF_CT_DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); | 336 | nf_ct_dump_tuple_ip(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); |
337 | #endif | 337 | #endif |
338 | pr_debug("hash=%u ct_hash=%u ", hash, ct->mark); | 338 | pr_debug("hash=%u ct_hash=%u ", hash, ct->mark); |
339 | if (!clusterip_responsible(cipinfo->config, hash)) { | 339 | if (!clusterip_responsible(cipinfo->config, hash)) { |
@@ -418,7 +418,7 @@ clusterip_tg_check(const char *tablename, const void *e_void, | |||
418 | /* drop reference count of cluster config when rule is deleted */ | 418 | /* drop reference count of cluster config when rule is deleted */ |
419 | static void clusterip_tg_destroy(const struct xt_target *target, void *targinfo) | 419 | static void clusterip_tg_destroy(const struct xt_target *target, void *targinfo) |
420 | { | 420 | { |
421 | struct ipt_clusterip_tgt_info *cipinfo = targinfo; | 421 | const struct ipt_clusterip_tgt_info *cipinfo = targinfo; |
422 | 422 | ||
423 | /* if no more entries are referencing the config, remove it | 423 | /* if no more entries are referencing the config, remove it |
424 | * from the list and destroy the proc entry */ | 424 | * from the list and destroy the proc entry */ |
@@ -567,7 +567,7 @@ struct clusterip_seq_position { | |||
567 | 567 | ||
568 | static void *clusterip_seq_start(struct seq_file *s, loff_t *pos) | 568 | static void *clusterip_seq_start(struct seq_file *s, loff_t *pos) |
569 | { | 569 | { |
570 | struct proc_dir_entry *pde = s->private; | 570 | const struct proc_dir_entry *pde = s->private; |
571 | struct clusterip_config *c = pde->data; | 571 | struct clusterip_config *c = pde->data; |
572 | unsigned int weight; | 572 | unsigned int weight; |
573 | u_int32_t local_nodes; | 573 | u_int32_t local_nodes; |
@@ -594,7 +594,7 @@ static void *clusterip_seq_start(struct seq_file *s, loff_t *pos) | |||
594 | 594 | ||
595 | static void *clusterip_seq_next(struct seq_file *s, void *v, loff_t *pos) | 595 | static void *clusterip_seq_next(struct seq_file *s, void *v, loff_t *pos) |
596 | { | 596 | { |
597 | struct clusterip_seq_position *idx = (struct clusterip_seq_position *)v; | 597 | struct clusterip_seq_position *idx = v; |
598 | 598 | ||
599 | *pos = ++idx->pos; | 599 | *pos = ++idx->pos; |
600 | if (*pos >= idx->weight) { | 600 | if (*pos >= idx->weight) { |
@@ -613,7 +613,7 @@ static void clusterip_seq_stop(struct seq_file *s, void *v) | |||
613 | 613 | ||
614 | static int clusterip_seq_show(struct seq_file *s, void *v) | 614 | static int clusterip_seq_show(struct seq_file *s, void *v) |
615 | { | 615 | { |
616 | struct clusterip_seq_position *idx = (struct clusterip_seq_position *)v; | 616 | struct clusterip_seq_position *idx = v; |
617 | 617 | ||
618 | if (idx->pos != 0) | 618 | if (idx->pos != 0) |
619 | seq_putc(s, ','); | 619 | seq_putc(s, ','); |
@@ -669,7 +669,7 @@ static ssize_t clusterip_proc_write(struct file *file, const char __user *input, | |||
669 | { | 669 | { |
670 | #define PROC_WRITELEN 10 | 670 | #define PROC_WRITELEN 10 |
671 | char buffer[PROC_WRITELEN+1]; | 671 | char buffer[PROC_WRITELEN+1]; |
672 | struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode); | 672 | const struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode); |
673 | struct clusterip_config *c = pde->data; | 673 | struct clusterip_config *c = pde->data; |
674 | unsigned long nodenum; | 674 | unsigned long nodenum; |
675 | 675 | ||
diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c index 21395bc2b27f..d60139c134ca 100644 --- a/net/ipv4/netfilter/ipt_ECN.c +++ b/net/ipv4/netfilter/ipt_ECN.c | |||
@@ -100,7 +100,7 @@ ecn_tg_check(const char *tablename, const void *e_void, | |||
100 | const struct xt_target *target, void *targinfo, | 100 | const struct xt_target *target, void *targinfo, |
101 | unsigned int hook_mask) | 101 | unsigned int hook_mask) |
102 | { | 102 | { |
103 | const struct ipt_ECN_info *einfo = (struct ipt_ECN_info *)targinfo; | 103 | const struct ipt_ECN_info *einfo = targinfo; |
104 | const struct ipt_entry *e = e_void; | 104 | const struct ipt_entry *e = e_void; |
105 | 105 | ||
106 | if (einfo->operation & IPT_ECN_OP_MASK) { | 106 | if (einfo->operation & IPT_ECN_OP_MASK) { |
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c index b38d7850f506..0af14137137b 100644 --- a/net/ipv4/netfilter/ipt_LOG.c +++ b/net/ipv4/netfilter/ipt_LOG.c | |||
@@ -76,7 +76,8 @@ static void dump_packet(const struct nf_loginfo *info, | |||
76 | 76 | ||
77 | if ((logflags & IPT_LOG_IPOPT) | 77 | if ((logflags & IPT_LOG_IPOPT) |
78 | && ih->ihl * 4 > sizeof(struct iphdr)) { | 78 | && ih->ihl * 4 > sizeof(struct iphdr)) { |
79 | unsigned char _opt[4 * 15 - sizeof(struct iphdr)], *op; | 79 | const unsigned char *op; |
80 | unsigned char _opt[4 * 15 - sizeof(struct iphdr)]; | ||
80 | unsigned int i, optsize; | 81 | unsigned int i, optsize; |
81 | 82 | ||
82 | optsize = ih->ihl * 4 - sizeof(struct iphdr); | 83 | optsize = ih->ihl * 4 - sizeof(struct iphdr); |
@@ -338,12 +339,16 @@ static void dump_packet(const struct nf_loginfo *info, | |||
338 | if ((logflags & IPT_LOG_UID) && !iphoff && skb->sk) { | 339 | if ((logflags & IPT_LOG_UID) && !iphoff && skb->sk) { |
339 | read_lock_bh(&skb->sk->sk_callback_lock); | 340 | read_lock_bh(&skb->sk->sk_callback_lock); |
340 | if (skb->sk->sk_socket && skb->sk->sk_socket->file) | 341 | if (skb->sk->sk_socket && skb->sk->sk_socket->file) |
341 | printk("UID=%u GID=%u", | 342 | printk("UID=%u GID=%u ", |
342 | skb->sk->sk_socket->file->f_uid, | 343 | skb->sk->sk_socket->file->f_uid, |
343 | skb->sk->sk_socket->file->f_gid); | 344 | skb->sk->sk_socket->file->f_gid); |
344 | read_unlock_bh(&skb->sk->sk_callback_lock); | 345 | read_unlock_bh(&skb->sk->sk_callback_lock); |
345 | } | 346 | } |
346 | 347 | ||
348 | /* Max length: 16 "MARK=0xFFFFFFFF " */ | ||
349 | if (!iphoff && skb->mark) | ||
350 | printk("MARK=0x%x ", skb->mark); | ||
351 | |||
347 | /* Proto Max log string length */ | 352 | /* Proto Max log string length */ |
348 | /* IP: 40+46+6+11+127 = 230 */ | 353 | /* IP: 40+46+6+11+127 = 230 */ |
349 | /* TCP: 10+max(25,20+30+13+9+32+11+127) = 252 */ | 354 | /* TCP: 10+max(25,20+30+13+9+32+11+127) = 252 */ |
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index 22606e2baa16..2639872849da 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c | |||
@@ -35,8 +35,10 @@ MODULE_DESCRIPTION("Xtables: packet \"rejection\" target for IPv4"); | |||
35 | static void send_reset(struct sk_buff *oldskb, int hook) | 35 | static void send_reset(struct sk_buff *oldskb, int hook) |
36 | { | 36 | { |
37 | struct sk_buff *nskb; | 37 | struct sk_buff *nskb; |
38 | struct iphdr *oiph, *niph; | 38 | const struct iphdr *oiph; |
39 | struct tcphdr _otcph, *oth, *tcph; | 39 | struct iphdr *niph; |
40 | const struct tcphdr *oth; | ||
41 | struct tcphdr _otcph, *tcph; | ||
40 | unsigned int addr_type; | 42 | unsigned int addr_type; |
41 | 43 | ||
42 | /* IP header checks: fragment. */ | 44 | /* IP header checks: fragment. */ |
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c index 50e06690eb5b..21cb053f5d7d 100644 --- a/net/ipv4/netfilter/ipt_recent.c +++ b/net/ipv4/netfilter/ipt_recent.c | |||
@@ -340,7 +340,7 @@ static void *recent_seq_start(struct seq_file *seq, loff_t *pos) | |||
340 | static void *recent_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 340 | static void *recent_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
341 | { | 341 | { |
342 | struct recent_iter_state *st = seq->private; | 342 | struct recent_iter_state *st = seq->private; |
343 | struct recent_table *t = st->table; | 343 | const struct recent_table *t = st->table; |
344 | struct recent_entry *e = v; | 344 | struct recent_entry *e = v; |
345 | struct list_head *head = e->list.next; | 345 | struct list_head *head = e->list.next; |
346 | 346 | ||
@@ -361,7 +361,7 @@ static void recent_seq_stop(struct seq_file *s, void *v) | |||
361 | 361 | ||
362 | static int recent_seq_show(struct seq_file *seq, void *v) | 362 | static int recent_seq_show(struct seq_file *seq, void *v) |
363 | { | 363 | { |
364 | struct recent_entry *e = v; | 364 | const struct recent_entry *e = v; |
365 | unsigned int i; | 365 | unsigned int i; |
366 | 366 | ||
367 | i = (e->index - 1) % ip_pkt_list_tot; | 367 | i = (e->index - 1) % ip_pkt_list_tot; |
@@ -396,7 +396,7 @@ static int recent_seq_open(struct inode *inode, struct file *file) | |||
396 | static ssize_t recent_proc_write(struct file *file, const char __user *input, | 396 | static ssize_t recent_proc_write(struct file *file, const char __user *input, |
397 | size_t size, loff_t *loff) | 397 | size_t size, loff_t *loff) |
398 | { | 398 | { |
399 | struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode); | 399 | const struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode); |
400 | struct recent_table *t = pde->data; | 400 | struct recent_table *t = pde->data; |
401 | struct recent_entry *e; | 401 | struct recent_entry *e; |
402 | char buf[sizeof("+255.255.255.255")], *c = buf; | 402 | char buf[sizeof("+255.255.255.255")], *c = buf; |
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c index 69f3d7e6e96f..1ea677dcf845 100644 --- a/net/ipv4/netfilter/iptable_filter.c +++ b/net/ipv4/netfilter/iptable_filter.c | |||
@@ -56,20 +56,32 @@ 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, | 59 | .lock = __RW_LOCK_UNLOCKED(packet_filter.lock), |
60 | .me = THIS_MODULE, | 60 | .me = THIS_MODULE, |
61 | .af = AF_INET, | 61 | .af = AF_INET, |
62 | }; | 62 | }; |
63 | 63 | ||
64 | /* The work comes in here from netfilter.c. */ | 64 | /* The work comes in here from netfilter.c. */ |
65 | static unsigned int | 65 | static unsigned int |
66 | ipt_local_in_hook(unsigned int hook, | ||
67 | struct sk_buff *skb, | ||
68 | const struct net_device *in, | ||
69 | const struct net_device *out, | ||
70 | int (*okfn)(struct sk_buff *)) | ||
71 | { | ||
72 | return ipt_do_table(skb, hook, in, out, | ||
73 | nf_local_in_net(in, out)->ipv4.iptable_filter); | ||
74 | } | ||
75 | |||
76 | static unsigned int | ||
66 | ipt_hook(unsigned int hook, | 77 | ipt_hook(unsigned int hook, |
67 | struct sk_buff *skb, | 78 | struct sk_buff *skb, |
68 | const struct net_device *in, | 79 | const struct net_device *in, |
69 | const struct net_device *out, | 80 | const struct net_device *out, |
70 | int (*okfn)(struct sk_buff *)) | 81 | int (*okfn)(struct sk_buff *)) |
71 | { | 82 | { |
72 | return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_filter); | 83 | return ipt_do_table(skb, hook, in, out, |
84 | nf_forward_net(in, out)->ipv4.iptable_filter); | ||
73 | } | 85 | } |
74 | 86 | ||
75 | static unsigned int | 87 | static unsigned int |
@@ -88,12 +100,13 @@ ipt_local_out_hook(unsigned int hook, | |||
88 | return NF_ACCEPT; | 100 | return NF_ACCEPT; |
89 | } | 101 | } |
90 | 102 | ||
91 | return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_filter); | 103 | return ipt_do_table(skb, hook, in, out, |
104 | nf_local_out_net(in, out)->ipv4.iptable_filter); | ||
92 | } | 105 | } |
93 | 106 | ||
94 | static struct nf_hook_ops ipt_ops[] __read_mostly = { | 107 | static struct nf_hook_ops ipt_ops[] __read_mostly = { |
95 | { | 108 | { |
96 | .hook = ipt_hook, | 109 | .hook = ipt_local_in_hook, |
97 | .owner = THIS_MODULE, | 110 | .owner = THIS_MODULE, |
98 | .pf = PF_INET, | 111 | .pf = PF_INET, |
99 | .hooknum = NF_INET_LOCAL_IN, | 112 | .hooknum = NF_INET_LOCAL_IN, |
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c index c55a210853a7..da59182f2226 100644 --- a/net/ipv4/netfilter/iptable_mangle.c +++ b/net/ipv4/netfilter/iptable_mangle.c | |||
@@ -67,20 +67,54 @@ 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, | 70 | .lock = __RW_LOCK_UNLOCKED(packet_mangler.lock), |
71 | .me = THIS_MODULE, | 71 | .me = THIS_MODULE, |
72 | .af = AF_INET, | 72 | .af = AF_INET, |
73 | }; | 73 | }; |
74 | 74 | ||
75 | /* The work comes in here from netfilter.c. */ | 75 | /* The work comes in here from netfilter.c. */ |
76 | static unsigned int | 76 | static unsigned int |
77 | ipt_route_hook(unsigned int hook, | 77 | ipt_pre_routing_hook(unsigned int hook, |
78 | struct sk_buff *skb, | ||
79 | const struct net_device *in, | ||
80 | const struct net_device *out, | ||
81 | int (*okfn)(struct sk_buff *)) | ||
82 | { | ||
83 | return ipt_do_table(skb, hook, in, out, | ||
84 | nf_pre_routing_net(in, out)->ipv4.iptable_mangle); | ||
85 | } | ||
86 | |||
87 | static unsigned int | ||
88 | ipt_post_routing_hook(unsigned int hook, | ||
89 | struct sk_buff *skb, | ||
90 | const struct net_device *in, | ||
91 | const struct net_device *out, | ||
92 | int (*okfn)(struct sk_buff *)) | ||
93 | { | ||
94 | return ipt_do_table(skb, hook, in, out, | ||
95 | nf_post_routing_net(in, out)->ipv4.iptable_mangle); | ||
96 | } | ||
97 | |||
98 | static unsigned int | ||
99 | ipt_local_in_hook(unsigned int hook, | ||
100 | struct sk_buff *skb, | ||
101 | const struct net_device *in, | ||
102 | const struct net_device *out, | ||
103 | int (*okfn)(struct sk_buff *)) | ||
104 | { | ||
105 | return ipt_do_table(skb, hook, in, out, | ||
106 | nf_local_in_net(in, out)->ipv4.iptable_mangle); | ||
107 | } | ||
108 | |||
109 | static unsigned int | ||
110 | ipt_forward_hook(unsigned int hook, | ||
78 | struct sk_buff *skb, | 111 | struct sk_buff *skb, |
79 | const struct net_device *in, | 112 | const struct net_device *in, |
80 | const struct net_device *out, | 113 | const struct net_device *out, |
81 | int (*okfn)(struct sk_buff *)) | 114 | int (*okfn)(struct sk_buff *)) |
82 | { | 115 | { |
83 | return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_mangle); | 116 | return ipt_do_table(skb, hook, in, out, |
117 | nf_forward_net(in, out)->ipv4.iptable_mangle); | ||
84 | } | 118 | } |
85 | 119 | ||
86 | static unsigned int | 120 | static unsigned int |
@@ -112,7 +146,8 @@ ipt_local_hook(unsigned int hook, | |||
112 | daddr = iph->daddr; | 146 | daddr = iph->daddr; |
113 | tos = iph->tos; | 147 | tos = iph->tos; |
114 | 148 | ||
115 | ret = ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_mangle); | 149 | ret = ipt_do_table(skb, hook, in, out, |
150 | nf_local_out_net(in, out)->ipv4.iptable_mangle); | ||
116 | /* Reroute for ANY change. */ | 151 | /* Reroute for ANY change. */ |
117 | if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) { | 152 | if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) { |
118 | iph = ip_hdr(skb); | 153 | iph = ip_hdr(skb); |
@@ -130,21 +165,21 @@ ipt_local_hook(unsigned int hook, | |||
130 | 165 | ||
131 | static struct nf_hook_ops ipt_ops[] __read_mostly = { | 166 | static struct nf_hook_ops ipt_ops[] __read_mostly = { |
132 | { | 167 | { |
133 | .hook = ipt_route_hook, | 168 | .hook = ipt_pre_routing_hook, |
134 | .owner = THIS_MODULE, | 169 | .owner = THIS_MODULE, |
135 | .pf = PF_INET, | 170 | .pf = PF_INET, |
136 | .hooknum = NF_INET_PRE_ROUTING, | 171 | .hooknum = NF_INET_PRE_ROUTING, |
137 | .priority = NF_IP_PRI_MANGLE, | 172 | .priority = NF_IP_PRI_MANGLE, |
138 | }, | 173 | }, |
139 | { | 174 | { |
140 | .hook = ipt_route_hook, | 175 | .hook = ipt_local_in_hook, |
141 | .owner = THIS_MODULE, | 176 | .owner = THIS_MODULE, |
142 | .pf = PF_INET, | 177 | .pf = PF_INET, |
143 | .hooknum = NF_INET_LOCAL_IN, | 178 | .hooknum = NF_INET_LOCAL_IN, |
144 | .priority = NF_IP_PRI_MANGLE, | 179 | .priority = NF_IP_PRI_MANGLE, |
145 | }, | 180 | }, |
146 | { | 181 | { |
147 | .hook = ipt_route_hook, | 182 | .hook = ipt_forward_hook, |
148 | .owner = THIS_MODULE, | 183 | .owner = THIS_MODULE, |
149 | .pf = PF_INET, | 184 | .pf = PF_INET, |
150 | .hooknum = NF_INET_FORWARD, | 185 | .hooknum = NF_INET_FORWARD, |
@@ -158,7 +193,7 @@ static struct nf_hook_ops ipt_ops[] __read_mostly = { | |||
158 | .priority = NF_IP_PRI_MANGLE, | 193 | .priority = NF_IP_PRI_MANGLE, |
159 | }, | 194 | }, |
160 | { | 195 | { |
161 | .hook = ipt_route_hook, | 196 | .hook = ipt_post_routing_hook, |
162 | .owner = THIS_MODULE, | 197 | .owner = THIS_MODULE, |
163 | .pf = PF_INET, | 198 | .pf = PF_INET, |
164 | .hooknum = NF_INET_POST_ROUTING, | 199 | .hooknum = NF_INET_POST_ROUTING, |
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c index e41fe8ca4e1c..fddce7754b72 100644 --- a/net/ipv4/netfilter/iptable_raw.c +++ b/net/ipv4/netfilter/iptable_raw.c | |||
@@ -39,7 +39,7 @@ 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, | 42 | .lock = __RW_LOCK_UNLOCKED(packet_raw.lock), |
43 | .me = THIS_MODULE, | 43 | .me = THIS_MODULE, |
44 | .af = AF_INET, | 44 | .af = AF_INET, |
45 | }; | 45 | }; |
@@ -52,7 +52,8 @@ ipt_hook(unsigned int hook, | |||
52 | const struct net_device *out, | 52 | const struct net_device *out, |
53 | int (*okfn)(struct sk_buff *)) | 53 | int (*okfn)(struct sk_buff *)) |
54 | { | 54 | { |
55 | return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_raw); | 55 | return ipt_do_table(skb, hook, in, out, |
56 | nf_pre_routing_net(in, out)->ipv4.iptable_raw); | ||
56 | } | 57 | } |
57 | 58 | ||
58 | static unsigned int | 59 | static unsigned int |
@@ -70,7 +71,8 @@ ipt_local_hook(unsigned int hook, | |||
70 | "packet.\n"); | 71 | "packet.\n"); |
71 | return NF_ACCEPT; | 72 | return NF_ACCEPT; |
72 | } | 73 | } |
73 | return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_raw); | 74 | return ipt_do_table(skb, hook, in, out, |
75 | nf_local_out_net(in, out)->ipv4.iptable_raw); | ||
74 | } | 76 | } |
75 | 77 | ||
76 | /* 'raw' is the very first table. */ | 78 | /* 'raw' is the very first table. */ |
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index a65b845c5f15..cacb9cb27dab 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | |||
@@ -23,30 +23,36 @@ | |||
23 | #include <net/netfilter/nf_conntrack_l3proto.h> | 23 | #include <net/netfilter/nf_conntrack_l3proto.h> |
24 | #include <net/netfilter/nf_conntrack_core.h> | 24 | #include <net/netfilter/nf_conntrack_core.h> |
25 | #include <net/netfilter/ipv4/nf_conntrack_ipv4.h> | 25 | #include <net/netfilter/ipv4/nf_conntrack_ipv4.h> |
26 | #include <net/netfilter/nf_nat_helper.h> | ||
26 | 27 | ||
27 | static int ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, | 28 | int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb, |
28 | struct nf_conntrack_tuple *tuple) | 29 | struct nf_conn *ct, |
30 | enum ip_conntrack_info ctinfo); | ||
31 | EXPORT_SYMBOL_GPL(nf_nat_seq_adjust_hook); | ||
32 | |||
33 | static bool ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, | ||
34 | struct nf_conntrack_tuple *tuple) | ||
29 | { | 35 | { |
30 | const __be32 *ap; | 36 | const __be32 *ap; |
31 | __be32 _addrs[2]; | 37 | __be32 _addrs[2]; |
32 | ap = skb_header_pointer(skb, nhoff + offsetof(struct iphdr, saddr), | 38 | ap = skb_header_pointer(skb, nhoff + offsetof(struct iphdr, saddr), |
33 | sizeof(u_int32_t) * 2, _addrs); | 39 | sizeof(u_int32_t) * 2, _addrs); |
34 | if (ap == NULL) | 40 | if (ap == NULL) |
35 | return 0; | 41 | return false; |
36 | 42 | ||
37 | tuple->src.u3.ip = ap[0]; | 43 | tuple->src.u3.ip = ap[0]; |
38 | tuple->dst.u3.ip = ap[1]; | 44 | tuple->dst.u3.ip = ap[1]; |
39 | 45 | ||
40 | return 1; | 46 | return true; |
41 | } | 47 | } |
42 | 48 | ||
43 | static int ipv4_invert_tuple(struct nf_conntrack_tuple *tuple, | 49 | static bool ipv4_invert_tuple(struct nf_conntrack_tuple *tuple, |
44 | const struct nf_conntrack_tuple *orig) | 50 | const struct nf_conntrack_tuple *orig) |
45 | { | 51 | { |
46 | tuple->src.u3.ip = orig->dst.u3.ip; | 52 | tuple->src.u3.ip = orig->dst.u3.ip; |
47 | tuple->dst.u3.ip = orig->src.u3.ip; | 53 | tuple->dst.u3.ip = orig->src.u3.ip; |
48 | 54 | ||
49 | return 1; | 55 | return true; |
50 | } | 56 | } |
51 | 57 | ||
52 | static int ipv4_print_tuple(struct seq_file *s, | 58 | static int ipv4_print_tuple(struct seq_file *s, |
@@ -101,35 +107,41 @@ static unsigned int ipv4_confirm(unsigned int hooknum, | |||
101 | const struct net_device *out, | 107 | const struct net_device *out, |
102 | int (*okfn)(struct sk_buff *)) | 108 | int (*okfn)(struct sk_buff *)) |
103 | { | 109 | { |
104 | /* We've seen it coming out the other side: confirm it */ | ||
105 | return nf_conntrack_confirm(skb); | ||
106 | } | ||
107 | |||
108 | static unsigned int ipv4_conntrack_help(unsigned int hooknum, | ||
109 | struct sk_buff *skb, | ||
110 | const struct net_device *in, | ||
111 | const struct net_device *out, | ||
112 | int (*okfn)(struct sk_buff *)) | ||
113 | { | ||
114 | struct nf_conn *ct; | 110 | struct nf_conn *ct; |
115 | enum ip_conntrack_info ctinfo; | 111 | enum ip_conntrack_info ctinfo; |
116 | const struct nf_conn_help *help; | 112 | const struct nf_conn_help *help; |
117 | const struct nf_conntrack_helper *helper; | 113 | const struct nf_conntrack_helper *helper; |
114 | unsigned int ret; | ||
118 | 115 | ||
119 | /* This is where we call the helper: as the packet goes out. */ | 116 | /* This is where we call the helper: as the packet goes out. */ |
120 | ct = nf_ct_get(skb, &ctinfo); | 117 | ct = nf_ct_get(skb, &ctinfo); |
121 | if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY) | 118 | if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY) |
122 | return NF_ACCEPT; | 119 | goto out; |
123 | 120 | ||
124 | help = nfct_help(ct); | 121 | help = nfct_help(ct); |
125 | if (!help) | 122 | if (!help) |
126 | return NF_ACCEPT; | 123 | goto out; |
124 | |||
127 | /* rcu_read_lock()ed by nf_hook_slow */ | 125 | /* rcu_read_lock()ed by nf_hook_slow */ |
128 | helper = rcu_dereference(help->helper); | 126 | helper = rcu_dereference(help->helper); |
129 | if (!helper) | 127 | if (!helper) |
130 | return NF_ACCEPT; | 128 | goto out; |
131 | return helper->help(skb, skb_network_offset(skb) + ip_hdrlen(skb), | 129 | |
132 | ct, ctinfo); | 130 | ret = helper->help(skb, skb_network_offset(skb) + ip_hdrlen(skb), |
131 | ct, ctinfo); | ||
132 | if (ret != NF_ACCEPT) | ||
133 | return ret; | ||
134 | |||
135 | if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) { | ||
136 | typeof(nf_nat_seq_adjust_hook) seq_adjust; | ||
137 | |||
138 | seq_adjust = rcu_dereference(nf_nat_seq_adjust_hook); | ||
139 | if (!seq_adjust || !seq_adjust(skb, ct, ctinfo)) | ||
140 | return NF_DROP; | ||
141 | } | ||
142 | out: | ||
143 | /* We've seen it coming out the other side: confirm it */ | ||
144 | return nf_conntrack_confirm(skb); | ||
133 | } | 145 | } |
134 | 146 | ||
135 | static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, | 147 | static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, |
@@ -211,20 +223,6 @@ static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = { | |||
211 | .priority = NF_IP_PRI_CONNTRACK, | 223 | .priority = NF_IP_PRI_CONNTRACK, |
212 | }, | 224 | }, |
213 | { | 225 | { |
214 | .hook = ipv4_conntrack_help, | ||
215 | .owner = THIS_MODULE, | ||
216 | .pf = PF_INET, | ||
217 | .hooknum = NF_INET_POST_ROUTING, | ||
218 | .priority = NF_IP_PRI_CONNTRACK_HELPER, | ||
219 | }, | ||
220 | { | ||
221 | .hook = ipv4_conntrack_help, | ||
222 | .owner = THIS_MODULE, | ||
223 | .pf = PF_INET, | ||
224 | .hooknum = NF_INET_LOCAL_IN, | ||
225 | .priority = NF_IP_PRI_CONNTRACK_HELPER, | ||
226 | }, | ||
227 | { | ||
228 | .hook = ipv4_confirm, | 226 | .hook = ipv4_confirm, |
229 | .owner = THIS_MODULE, | 227 | .owner = THIS_MODULE, |
230 | .pf = PF_INET, | 228 | .pf = PF_INET, |
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c index e60b885d2dcd..40a46d482490 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c | |||
@@ -106,21 +106,16 @@ static int ct_seq_show(struct seq_file *s, void *v) | |||
106 | /* we only want to print DIR_ORIGINAL */ | 106 | /* we only want to print DIR_ORIGINAL */ |
107 | if (NF_CT_DIRECTION(hash)) | 107 | if (NF_CT_DIRECTION(hash)) |
108 | return 0; | 108 | return 0; |
109 | if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num != AF_INET) | 109 | if (nf_ct_l3num(ct) != AF_INET) |
110 | return 0; | 110 | return 0; |
111 | 111 | ||
112 | l3proto = __nf_ct_l3proto_find(ct->tuplehash[IP_CT_DIR_ORIGINAL] | 112 | l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct)); |
113 | .tuple.src.l3num); | ||
114 | NF_CT_ASSERT(l3proto); | 113 | NF_CT_ASSERT(l3proto); |
115 | l4proto = __nf_ct_l4proto_find(ct->tuplehash[IP_CT_DIR_ORIGINAL] | 114 | l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct)); |
116 | .tuple.src.l3num, | ||
117 | ct->tuplehash[IP_CT_DIR_ORIGINAL] | ||
118 | .tuple.dst.protonum); | ||
119 | NF_CT_ASSERT(l4proto); | 115 | NF_CT_ASSERT(l4proto); |
120 | 116 | ||
121 | if (seq_printf(s, "%-8s %u %ld ", | 117 | if (seq_printf(s, "%-8s %u %ld ", |
122 | l4proto->name, | 118 | l4proto->name, nf_ct_protonum(ct), |
123 | ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum, | ||
124 | timer_pending(&ct->timeout) | 119 | timer_pending(&ct->timeout) |
125 | ? (long)(ct->timeout.expires - jiffies)/HZ : 0) != 0) | 120 | ? (long)(ct->timeout.expires - jiffies)/HZ : 0) != 0) |
126 | return -ENOSPC; | 121 | return -ENOSPC; |
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index 6873fddb3529..78ab19accace 100644 --- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c | |||
@@ -22,22 +22,21 @@ | |||
22 | 22 | ||
23 | static unsigned long nf_ct_icmp_timeout __read_mostly = 30*HZ; | 23 | static unsigned long nf_ct_icmp_timeout __read_mostly = 30*HZ; |
24 | 24 | ||
25 | static int icmp_pkt_to_tuple(const struct sk_buff *skb, | 25 | static bool icmp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, |
26 | unsigned int dataoff, | 26 | struct nf_conntrack_tuple *tuple) |
27 | struct nf_conntrack_tuple *tuple) | ||
28 | { | 27 | { |
29 | const struct icmphdr *hp; | 28 | const struct icmphdr *hp; |
30 | struct icmphdr _hdr; | 29 | struct icmphdr _hdr; |
31 | 30 | ||
32 | hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr); | 31 | hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr); |
33 | if (hp == NULL) | 32 | if (hp == NULL) |
34 | return 0; | 33 | return false; |
35 | 34 | ||
36 | tuple->dst.u.icmp.type = hp->type; | 35 | tuple->dst.u.icmp.type = hp->type; |
37 | tuple->src.u.icmp.id = hp->un.echo.id; | 36 | tuple->src.u.icmp.id = hp->un.echo.id; |
38 | tuple->dst.u.icmp.code = hp->code; | 37 | tuple->dst.u.icmp.code = hp->code; |
39 | 38 | ||
40 | return 1; | 39 | return true; |
41 | } | 40 | } |
42 | 41 | ||
43 | /* Add 1; spaces filled with 0. */ | 42 | /* Add 1; spaces filled with 0. */ |
@@ -52,17 +51,17 @@ static const u_int8_t invmap[] = { | |||
52 | [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1 | 51 | [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1 |
53 | }; | 52 | }; |
54 | 53 | ||
55 | static int icmp_invert_tuple(struct nf_conntrack_tuple *tuple, | 54 | static bool icmp_invert_tuple(struct nf_conntrack_tuple *tuple, |
56 | const struct nf_conntrack_tuple *orig) | 55 | const struct nf_conntrack_tuple *orig) |
57 | { | 56 | { |
58 | if (orig->dst.u.icmp.type >= sizeof(invmap) | 57 | if (orig->dst.u.icmp.type >= sizeof(invmap) |
59 | || !invmap[orig->dst.u.icmp.type]) | 58 | || !invmap[orig->dst.u.icmp.type]) |
60 | return 0; | 59 | return false; |
61 | 60 | ||
62 | tuple->src.u.icmp.id = orig->src.u.icmp.id; | 61 | tuple->src.u.icmp.id = orig->src.u.icmp.id; |
63 | tuple->dst.u.icmp.type = invmap[orig->dst.u.icmp.type] - 1; | 62 | tuple->dst.u.icmp.type = invmap[orig->dst.u.icmp.type] - 1; |
64 | tuple->dst.u.icmp.code = orig->dst.u.icmp.code; | 63 | tuple->dst.u.icmp.code = orig->dst.u.icmp.code; |
65 | return 1; | 64 | return true; |
66 | } | 65 | } |
67 | 66 | ||
68 | /* Print out the per-protocol part of the tuple. */ | 67 | /* Print out the per-protocol part of the tuple. */ |
@@ -101,8 +100,8 @@ static int icmp_packet(struct nf_conn *ct, | |||
101 | } | 100 | } |
102 | 101 | ||
103 | /* Called when a new connection for this protocol found. */ | 102 | /* Called when a new connection for this protocol found. */ |
104 | static int icmp_new(struct nf_conn *ct, | 103 | static bool icmp_new(struct nf_conn *ct, const struct sk_buff *skb, |
105 | const struct sk_buff *skb, unsigned int dataoff) | 104 | unsigned int dataoff) |
106 | { | 105 | { |
107 | static const u_int8_t valid_new[] = { | 106 | static const u_int8_t valid_new[] = { |
108 | [ICMP_ECHO] = 1, | 107 | [ICMP_ECHO] = 1, |
@@ -116,11 +115,11 @@ static int icmp_new(struct nf_conn *ct, | |||
116 | /* Can't create a new ICMP `conn' with this. */ | 115 | /* Can't create a new ICMP `conn' with this. */ |
117 | pr_debug("icmp: can't create new conn with type %u\n", | 116 | pr_debug("icmp: can't create new conn with type %u\n", |
118 | ct->tuplehash[0].tuple.dst.u.icmp.type); | 117 | ct->tuplehash[0].tuple.dst.u.icmp.type); |
119 | NF_CT_DUMP_TUPLE(&ct->tuplehash[0].tuple); | 118 | nf_ct_dump_tuple_ip(&ct->tuplehash[0].tuple); |
120 | return 0; | 119 | return false; |
121 | } | 120 | } |
122 | atomic_set(&ct->proto.icmp.count, 0); | 121 | atomic_set(&ct->proto.icmp.count, 0); |
123 | return 1; | 122 | return true; |
124 | } | 123 | } |
125 | 124 | ||
126 | /* Returns conntrack if it dealt with ICMP, and filled in skb fields */ | 125 | /* Returns conntrack if it dealt with ICMP, and filled in skb fields */ |
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index 36b4e3bb056f..04578593e100 100644 --- a/net/ipv4/netfilter/nf_nat_core.c +++ b/net/ipv4/netfilter/nf_nat_core.c | |||
@@ -150,9 +150,9 @@ find_appropriate_src(const struct nf_conntrack_tuple *tuple, | |||
150 | const struct nf_nat_range *range) | 150 | const struct nf_nat_range *range) |
151 | { | 151 | { |
152 | unsigned int h = hash_by_src(tuple); | 152 | unsigned int h = hash_by_src(tuple); |
153 | struct nf_conn_nat *nat; | 153 | const struct nf_conn_nat *nat; |
154 | struct nf_conn *ct; | 154 | const struct nf_conn *ct; |
155 | struct hlist_node *n; | 155 | const struct hlist_node *n; |
156 | 156 | ||
157 | rcu_read_lock(); | 157 | rcu_read_lock(); |
158 | hlist_for_each_entry_rcu(nat, n, &bysource[h], bysource) { | 158 | hlist_for_each_entry_rcu(nat, n, &bysource[h], bysource) { |
@@ -349,7 +349,7 @@ nf_nat_setup_info(struct nf_conn *ct, | |||
349 | EXPORT_SYMBOL(nf_nat_setup_info); | 349 | EXPORT_SYMBOL(nf_nat_setup_info); |
350 | 350 | ||
351 | /* Returns true if succeeded. */ | 351 | /* Returns true if succeeded. */ |
352 | static int | 352 | static bool |
353 | manip_pkt(u_int16_t proto, | 353 | manip_pkt(u_int16_t proto, |
354 | struct sk_buff *skb, | 354 | struct sk_buff *skb, |
355 | unsigned int iphdroff, | 355 | unsigned int iphdroff, |
@@ -360,7 +360,7 @@ manip_pkt(u_int16_t proto, | |||
360 | const struct nf_nat_protocol *p; | 360 | const struct nf_nat_protocol *p; |
361 | 361 | ||
362 | if (!skb_make_writable(skb, iphdroff + sizeof(*iph))) | 362 | if (!skb_make_writable(skb, iphdroff + sizeof(*iph))) |
363 | return 0; | 363 | return false; |
364 | 364 | ||
365 | iph = (void *)skb->data + iphdroff; | 365 | iph = (void *)skb->data + iphdroff; |
366 | 366 | ||
@@ -369,7 +369,7 @@ manip_pkt(u_int16_t proto, | |||
369 | /* rcu_read_lock()ed by nf_hook_slow */ | 369 | /* rcu_read_lock()ed by nf_hook_slow */ |
370 | p = __nf_nat_proto_find(proto); | 370 | p = __nf_nat_proto_find(proto); |
371 | if (!p->manip_pkt(skb, iphdroff, target, maniptype)) | 371 | if (!p->manip_pkt(skb, iphdroff, target, maniptype)) |
372 | return 0; | 372 | return false; |
373 | 373 | ||
374 | iph = (void *)skb->data + iphdroff; | 374 | iph = (void *)skb->data + iphdroff; |
375 | 375 | ||
@@ -380,7 +380,7 @@ manip_pkt(u_int16_t proto, | |||
380 | csum_replace4(&iph->check, iph->daddr, target->dst.u3.ip); | 380 | csum_replace4(&iph->check, iph->daddr, target->dst.u3.ip); |
381 | iph->daddr = target->dst.u3.ip; | 381 | iph->daddr = target->dst.u3.ip; |
382 | } | 382 | } |
383 | return 1; | 383 | return true; |
384 | } | 384 | } |
385 | 385 | ||
386 | /* Do packet manipulations according to nf_nat_setup_info. */ | 386 | /* Do packet manipulations according to nf_nat_setup_info. */ |
@@ -426,7 +426,7 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct, | |||
426 | struct icmphdr icmp; | 426 | struct icmphdr icmp; |
427 | struct iphdr ip; | 427 | struct iphdr ip; |
428 | } *inside; | 428 | } *inside; |
429 | struct nf_conntrack_l4proto *l4proto; | 429 | const struct nf_conntrack_l4proto *l4proto; |
430 | struct nf_conntrack_tuple inner, target; | 430 | struct nf_conntrack_tuple inner, target; |
431 | int hdrlen = ip_hdrlen(skb); | 431 | int hdrlen = ip_hdrlen(skb); |
432 | enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); | 432 | enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); |
@@ -544,46 +544,6 @@ void nf_nat_protocol_unregister(const struct nf_nat_protocol *proto) | |||
544 | } | 544 | } |
545 | EXPORT_SYMBOL(nf_nat_protocol_unregister); | 545 | EXPORT_SYMBOL(nf_nat_protocol_unregister); |
546 | 546 | ||
547 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | ||
548 | int | ||
549 | nf_nat_port_range_to_nlattr(struct sk_buff *skb, | ||
550 | const struct nf_nat_range *range) | ||
551 | { | ||
552 | NLA_PUT_BE16(skb, CTA_PROTONAT_PORT_MIN, range->min.tcp.port); | ||
553 | NLA_PUT_BE16(skb, CTA_PROTONAT_PORT_MAX, range->max.tcp.port); | ||
554 | |||
555 | return 0; | ||
556 | |||
557 | nla_put_failure: | ||
558 | return -1; | ||
559 | } | ||
560 | EXPORT_SYMBOL_GPL(nf_nat_port_nlattr_to_range); | ||
561 | |||
562 | int | ||
563 | nf_nat_port_nlattr_to_range(struct nlattr *tb[], struct nf_nat_range *range) | ||
564 | { | ||
565 | int ret = 0; | ||
566 | |||
567 | /* we have to return whether we actually parsed something or not */ | ||
568 | |||
569 | if (tb[CTA_PROTONAT_PORT_MIN]) { | ||
570 | ret = 1; | ||
571 | range->min.tcp.port = nla_get_be16(tb[CTA_PROTONAT_PORT_MIN]); | ||
572 | } | ||
573 | |||
574 | if (!tb[CTA_PROTONAT_PORT_MAX]) { | ||
575 | if (ret) | ||
576 | range->max.tcp.port = range->min.tcp.port; | ||
577 | } else { | ||
578 | ret = 1; | ||
579 | range->max.tcp.port = nla_get_be16(tb[CTA_PROTONAT_PORT_MAX]); | ||
580 | } | ||
581 | |||
582 | return ret; | ||
583 | } | ||
584 | EXPORT_SYMBOL_GPL(nf_nat_port_range_to_nlattr); | ||
585 | #endif | ||
586 | |||
587 | /* Noone using conntrack by the time this called. */ | 547 | /* Noone using conntrack by the time this called. */ |
588 | static void nf_nat_cleanup_conntrack(struct nf_conn *ct) | 548 | static void nf_nat_cleanup_conntrack(struct nf_conn *ct) |
589 | { | 549 | { |
@@ -660,6 +620,9 @@ static int __init nf_nat_init(void) | |||
660 | nf_conntrack_untracked.status |= IPS_NAT_DONE_MASK; | 620 | nf_conntrack_untracked.status |= IPS_NAT_DONE_MASK; |
661 | 621 | ||
662 | l3proto = nf_ct_l3proto_find_get((u_int16_t)AF_INET); | 622 | l3proto = nf_ct_l3proto_find_get((u_int16_t)AF_INET); |
623 | |||
624 | BUG_ON(nf_nat_seq_adjust_hook != NULL); | ||
625 | rcu_assign_pointer(nf_nat_seq_adjust_hook, nf_nat_seq_adjust); | ||
663 | return 0; | 626 | return 0; |
664 | 627 | ||
665 | cleanup_extend: | 628 | cleanup_extend: |
@@ -686,6 +649,8 @@ static void __exit nf_nat_cleanup(void) | |||
686 | nf_ct_free_hashtable(bysource, nf_nat_vmalloced, nf_nat_htable_size); | 649 | nf_ct_free_hashtable(bysource, nf_nat_vmalloced, nf_nat_htable_size); |
687 | nf_ct_l3proto_put(l3proto); | 650 | nf_ct_l3proto_put(l3proto); |
688 | nf_ct_extend_unregister(&nat_extend); | 651 | nf_ct_extend_unregister(&nat_extend); |
652 | rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL); | ||
653 | synchronize_net(); | ||
689 | } | 654 | } |
690 | 655 | ||
691 | MODULE_LICENSE("GPL"); | 656 | MODULE_LICENSE("GPL"); |
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c index 2fca727aa8ba..11976ea29884 100644 --- a/net/ipv4/netfilter/nf_nat_helper.c +++ b/net/ipv4/netfilter/nf_nat_helper.c | |||
@@ -416,7 +416,6 @@ nf_nat_seq_adjust(struct sk_buff *skb, | |||
416 | 416 | ||
417 | return 1; | 417 | return 1; |
418 | } | 418 | } |
419 | EXPORT_SYMBOL(nf_nat_seq_adjust); | ||
420 | 419 | ||
421 | /* Setup NAT on this expected conntrack so it follows master. */ | 420 | /* Setup NAT on this expected conntrack so it follows master. */ |
422 | /* If we fail to get a free NAT slot, we'll get dropped on confirm */ | 421 | /* If we fail to get a free NAT slot, we'll get dropped on confirm */ |
diff --git a/net/ipv4/netfilter/nf_nat_pptp.c b/net/ipv4/netfilter/nf_nat_pptp.c index 3a1e6d6afc0a..da3d91a5ef5c 100644 --- a/net/ipv4/netfilter/nf_nat_pptp.c +++ b/net/ipv4/netfilter/nf_nat_pptp.c | |||
@@ -72,7 +72,7 @@ static void pptp_nat_expected(struct nf_conn *ct, | |||
72 | } | 72 | } |
73 | 73 | ||
74 | pr_debug("trying to unexpect other dir: "); | 74 | pr_debug("trying to unexpect other dir: "); |
75 | NF_CT_DUMP_TUPLE(&t); | 75 | nf_ct_dump_tuple_ip(&t); |
76 | other_exp = nf_ct_expect_find_get(&t); | 76 | other_exp = nf_ct_expect_find_get(&t); |
77 | if (other_exp) { | 77 | if (other_exp) { |
78 | nf_ct_unexpect_related(other_exp); | 78 | nf_ct_unexpect_related(other_exp); |
diff --git a/net/ipv4/netfilter/nf_nat_proto_common.c b/net/ipv4/netfilter/nf_nat_proto_common.c new file mode 100644 index 000000000000..91537f11273f --- /dev/null +++ b/net/ipv4/netfilter/nf_nat_proto_common.c | |||
@@ -0,0 +1,120 @@ | |||
1 | /* (C) 1999-2001 Paul `Rusty' Russell | ||
2 | * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org> | ||
3 | * (C) 2008 Patrick McHardy <kaber@trash.net> | ||
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/types.h> | ||
11 | #include <linux/random.h> | ||
12 | #include <linux/ip.h> | ||
13 | |||
14 | #include <linux/netfilter.h> | ||
15 | #include <net/netfilter/nf_nat.h> | ||
16 | #include <net/netfilter/nf_nat_core.h> | ||
17 | #include <net/netfilter/nf_nat_rule.h> | ||
18 | #include <net/netfilter/nf_nat_protocol.h> | ||
19 | |||
20 | bool nf_nat_proto_in_range(const struct nf_conntrack_tuple *tuple, | ||
21 | enum nf_nat_manip_type maniptype, | ||
22 | const union nf_conntrack_man_proto *min, | ||
23 | const union nf_conntrack_man_proto *max) | ||
24 | { | ||
25 | __be16 port; | ||
26 | |||
27 | if (maniptype == IP_NAT_MANIP_SRC) | ||
28 | port = tuple->src.u.all; | ||
29 | else | ||
30 | port = tuple->dst.u.all; | ||
31 | |||
32 | return ntohs(port) >= ntohs(min->all) && | ||
33 | ntohs(port) <= ntohs(max->all); | ||
34 | } | ||
35 | EXPORT_SYMBOL_GPL(nf_nat_proto_in_range); | ||
36 | |||
37 | bool nf_nat_proto_unique_tuple(struct nf_conntrack_tuple *tuple, | ||
38 | const struct nf_nat_range *range, | ||
39 | enum nf_nat_manip_type maniptype, | ||
40 | const struct nf_conn *ct, | ||
41 | u_int16_t *rover) | ||
42 | { | ||
43 | unsigned int range_size, min, i; | ||
44 | __be16 *portptr; | ||
45 | u_int16_t off; | ||
46 | |||
47 | if (maniptype == IP_NAT_MANIP_SRC) | ||
48 | portptr = &tuple->src.u.all; | ||
49 | else | ||
50 | portptr = &tuple->dst.u.all; | ||
51 | |||
52 | /* If no range specified... */ | ||
53 | if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) { | ||
54 | /* If it's dst rewrite, can't change port */ | ||
55 | if (maniptype == IP_NAT_MANIP_DST) | ||
56 | return false; | ||
57 | |||
58 | if (ntohs(*portptr) < 1024) { | ||
59 | /* Loose convention: >> 512 is credential passing */ | ||
60 | if (ntohs(*portptr) < 512) { | ||
61 | min = 1; | ||
62 | range_size = 511 - min + 1; | ||
63 | } else { | ||
64 | min = 600; | ||
65 | range_size = 1023 - min + 1; | ||
66 | } | ||
67 | } else { | ||
68 | min = 1024; | ||
69 | range_size = 65535 - 1024 + 1; | ||
70 | } | ||
71 | } else { | ||
72 | min = ntohs(range->min.all); | ||
73 | range_size = ntohs(range->max.all) - min + 1; | ||
74 | } | ||
75 | |||
76 | off = *rover; | ||
77 | if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) | ||
78 | off = net_random(); | ||
79 | |||
80 | for (i = 0; i < range_size; i++, off++) { | ||
81 | *portptr = htons(min + off % range_size); | ||
82 | if (nf_nat_used_tuple(tuple, ct)) | ||
83 | continue; | ||
84 | if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) | ||
85 | *rover = off; | ||
86 | return true; | ||
87 | } | ||
88 | return false; | ||
89 | } | ||
90 | EXPORT_SYMBOL_GPL(nf_nat_proto_unique_tuple); | ||
91 | |||
92 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | ||
93 | int nf_nat_proto_range_to_nlattr(struct sk_buff *skb, | ||
94 | const struct nf_nat_range *range) | ||
95 | { | ||
96 | NLA_PUT_BE16(skb, CTA_PROTONAT_PORT_MIN, range->min.all); | ||
97 | NLA_PUT_BE16(skb, CTA_PROTONAT_PORT_MAX, range->max.all); | ||
98 | return 0; | ||
99 | |||
100 | nla_put_failure: | ||
101 | return -1; | ||
102 | } | ||
103 | EXPORT_SYMBOL_GPL(nf_nat_proto_nlattr_to_range); | ||
104 | |||
105 | int nf_nat_proto_nlattr_to_range(struct nlattr *tb[], | ||
106 | struct nf_nat_range *range) | ||
107 | { | ||
108 | if (tb[CTA_PROTONAT_PORT_MIN]) { | ||
109 | range->min.all = nla_get_be16(tb[CTA_PROTONAT_PORT_MIN]); | ||
110 | range->max.all = range->min.tcp.port; | ||
111 | range->flags |= IP_NAT_RANGE_PROTO_SPECIFIED; | ||
112 | } | ||
113 | if (tb[CTA_PROTONAT_PORT_MAX]) { | ||
114 | range->max.all = nla_get_be16(tb[CTA_PROTONAT_PORT_MAX]); | ||
115 | range->flags |= IP_NAT_RANGE_PROTO_SPECIFIED; | ||
116 | } | ||
117 | return 0; | ||
118 | } | ||
119 | EXPORT_SYMBOL_GPL(nf_nat_proto_range_to_nlattr); | ||
120 | #endif | ||
diff --git a/net/ipv4/netfilter/nf_nat_proto_dccp.c b/net/ipv4/netfilter/nf_nat_proto_dccp.c new file mode 100644 index 000000000000..22485ce306d4 --- /dev/null +++ b/net/ipv4/netfilter/nf_nat_proto_dccp.c | |||
@@ -0,0 +1,108 @@ | |||
1 | /* | ||
2 | * DCCP NAT protocol helper | ||
3 | * | ||
4 | * Copyright (c) 2005, 2006. 2008 Patrick McHardy <kaber@trash.net> | ||
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 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/skbuff.h> | ||
16 | #include <linux/ip.h> | ||
17 | #include <linux/dccp.h> | ||
18 | |||
19 | #include <net/netfilter/nf_conntrack.h> | ||
20 | #include <net/netfilter/nf_nat.h> | ||
21 | #include <net/netfilter/nf_nat_protocol.h> | ||
22 | |||
23 | static u_int16_t dccp_port_rover; | ||
24 | |||
25 | static bool | ||
26 | dccp_unique_tuple(struct nf_conntrack_tuple *tuple, | ||
27 | const struct nf_nat_range *range, | ||
28 | enum nf_nat_manip_type maniptype, | ||
29 | const struct nf_conn *ct) | ||
30 | { | ||
31 | return nf_nat_proto_unique_tuple(tuple, range, maniptype, ct, | ||
32 | &dccp_port_rover); | ||
33 | } | ||
34 | |||
35 | static bool | ||
36 | dccp_manip_pkt(struct sk_buff *skb, | ||
37 | unsigned int iphdroff, | ||
38 | const struct nf_conntrack_tuple *tuple, | ||
39 | enum nf_nat_manip_type maniptype) | ||
40 | { | ||
41 | const struct iphdr *iph = (const void *)(skb->data + iphdroff); | ||
42 | struct dccp_hdr *hdr; | ||
43 | unsigned int hdroff = iphdroff + iph->ihl * 4; | ||
44 | __be32 oldip, newip; | ||
45 | __be16 *portptr, oldport, newport; | ||
46 | int hdrsize = 8; /* DCCP connection tracking guarantees this much */ | ||
47 | |||
48 | if (skb->len >= hdroff + sizeof(struct dccp_hdr)) | ||
49 | hdrsize = sizeof(struct dccp_hdr); | ||
50 | |||
51 | if (!skb_make_writable(skb, hdroff + hdrsize)) | ||
52 | return false; | ||
53 | |||
54 | iph = (struct iphdr *)(skb->data + iphdroff); | ||
55 | hdr = (struct dccp_hdr *)(skb->data + hdroff); | ||
56 | |||
57 | if (maniptype == IP_NAT_MANIP_SRC) { | ||
58 | oldip = iph->saddr; | ||
59 | newip = tuple->src.u3.ip; | ||
60 | newport = tuple->src.u.dccp.port; | ||
61 | portptr = &hdr->dccph_sport; | ||
62 | } else { | ||
63 | oldip = iph->daddr; | ||
64 | newip = tuple->dst.u3.ip; | ||
65 | newport = tuple->dst.u.dccp.port; | ||
66 | portptr = &hdr->dccph_dport; | ||
67 | } | ||
68 | |||
69 | oldport = *portptr; | ||
70 | *portptr = newport; | ||
71 | |||
72 | if (hdrsize < sizeof(*hdr)) | ||
73 | return true; | ||
74 | |||
75 | inet_proto_csum_replace4(&hdr->dccph_checksum, skb, oldip, newip, 1); | ||
76 | inet_proto_csum_replace2(&hdr->dccph_checksum, skb, oldport, newport, | ||
77 | 0); | ||
78 | return true; | ||
79 | } | ||
80 | |||
81 | static const struct nf_nat_protocol nf_nat_protocol_dccp = { | ||
82 | .protonum = IPPROTO_DCCP, | ||
83 | .me = THIS_MODULE, | ||
84 | .manip_pkt = dccp_manip_pkt, | ||
85 | .in_range = nf_nat_proto_in_range, | ||
86 | .unique_tuple = dccp_unique_tuple, | ||
87 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | ||
88 | .range_to_nlattr = nf_nat_proto_range_to_nlattr, | ||
89 | .nlattr_to_range = nf_nat_proto_nlattr_to_range, | ||
90 | #endif | ||
91 | }; | ||
92 | |||
93 | static int __init nf_nat_proto_dccp_init(void) | ||
94 | { | ||
95 | return nf_nat_protocol_register(&nf_nat_protocol_dccp); | ||
96 | } | ||
97 | |||
98 | static void __exit nf_nat_proto_dccp_fini(void) | ||
99 | { | ||
100 | nf_nat_protocol_unregister(&nf_nat_protocol_dccp); | ||
101 | } | ||
102 | |||
103 | module_init(nf_nat_proto_dccp_init); | ||
104 | module_exit(nf_nat_proto_dccp_fini); | ||
105 | |||
106 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | ||
107 | MODULE_DESCRIPTION("DCCP NAT protocol helper"); | ||
108 | MODULE_LICENSE("GPL"); | ||
diff --git a/net/ipv4/netfilter/nf_nat_proto_gre.c b/net/ipv4/netfilter/nf_nat_proto_gre.c index a1e4da16da2e..d7e89201351e 100644 --- a/net/ipv4/netfilter/nf_nat_proto_gre.c +++ b/net/ipv4/netfilter/nf_nat_proto_gre.c | |||
@@ -36,26 +36,8 @@ MODULE_LICENSE("GPL"); | |||
36 | MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>"); | 36 | MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>"); |
37 | MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE"); | 37 | MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE"); |
38 | 38 | ||
39 | /* is key in given range between min and max */ | ||
40 | static int | ||
41 | gre_in_range(const struct nf_conntrack_tuple *tuple, | ||
42 | enum nf_nat_manip_type maniptype, | ||
43 | const union nf_conntrack_man_proto *min, | ||
44 | const union nf_conntrack_man_proto *max) | ||
45 | { | ||
46 | __be16 key; | ||
47 | |||
48 | if (maniptype == IP_NAT_MANIP_SRC) | ||
49 | key = tuple->src.u.gre.key; | ||
50 | else | ||
51 | key = tuple->dst.u.gre.key; | ||
52 | |||
53 | return ntohs(key) >= ntohs(min->gre.key) && | ||
54 | ntohs(key) <= ntohs(max->gre.key); | ||
55 | } | ||
56 | |||
57 | /* generate unique tuple ... */ | 39 | /* generate unique tuple ... */ |
58 | static int | 40 | static bool |
59 | gre_unique_tuple(struct nf_conntrack_tuple *tuple, | 41 | gre_unique_tuple(struct nf_conntrack_tuple *tuple, |
60 | const struct nf_nat_range *range, | 42 | const struct nf_nat_range *range, |
61 | enum nf_nat_manip_type maniptype, | 43 | enum nf_nat_manip_type maniptype, |
@@ -68,7 +50,7 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple, | |||
68 | /* If there is no master conntrack we are not PPTP, | 50 | /* If there is no master conntrack we are not PPTP, |
69 | do not change tuples */ | 51 | do not change tuples */ |
70 | if (!ct->master) | 52 | if (!ct->master) |
71 | return 0; | 53 | return false; |
72 | 54 | ||
73 | if (maniptype == IP_NAT_MANIP_SRC) | 55 | if (maniptype == IP_NAT_MANIP_SRC) |
74 | keyptr = &tuple->src.u.gre.key; | 56 | keyptr = &tuple->src.u.gre.key; |
@@ -89,20 +71,20 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple, | |||
89 | for (i = 0; i < range_size; i++, key++) { | 71 | for (i = 0; i < range_size; i++, key++) { |
90 | *keyptr = htons(min + key % range_size); | 72 | *keyptr = htons(min + key % range_size); |
91 | if (!nf_nat_used_tuple(tuple, ct)) | 73 | if (!nf_nat_used_tuple(tuple, ct)) |
92 | return 1; | 74 | return true; |
93 | } | 75 | } |
94 | 76 | ||
95 | pr_debug("%p: no NAT mapping\n", ct); | 77 | pr_debug("%p: no NAT mapping\n", ct); |
96 | return 0; | 78 | return false; |
97 | } | 79 | } |
98 | 80 | ||
99 | /* manipulate a GRE packet according to maniptype */ | 81 | /* manipulate a GRE packet according to maniptype */ |
100 | static int | 82 | static bool |
101 | gre_manip_pkt(struct sk_buff *skb, unsigned int iphdroff, | 83 | gre_manip_pkt(struct sk_buff *skb, unsigned int iphdroff, |
102 | const struct nf_conntrack_tuple *tuple, | 84 | const struct nf_conntrack_tuple *tuple, |
103 | enum nf_nat_manip_type maniptype) | 85 | enum nf_nat_manip_type maniptype) |
104 | { | 86 | { |
105 | struct gre_hdr *greh; | 87 | const struct gre_hdr *greh; |
106 | struct gre_hdr_pptp *pgreh; | 88 | struct gre_hdr_pptp *pgreh; |
107 | const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff); | 89 | const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff); |
108 | unsigned int hdroff = iphdroff + iph->ihl * 4; | 90 | unsigned int hdroff = iphdroff + iph->ihl * 4; |
@@ -110,7 +92,7 @@ gre_manip_pkt(struct sk_buff *skb, unsigned int iphdroff, | |||
110 | /* pgreh includes two optional 32bit fields which are not required | 92 | /* pgreh includes two optional 32bit fields which are not required |
111 | * to be there. That's where the magic '8' comes from */ | 93 | * to be there. That's where the magic '8' comes from */ |
112 | if (!skb_make_writable(skb, hdroff + sizeof(*pgreh) - 8)) | 94 | if (!skb_make_writable(skb, hdroff + sizeof(*pgreh) - 8)) |
113 | return 0; | 95 | return false; |
114 | 96 | ||
115 | greh = (void *)skb->data + hdroff; | 97 | greh = (void *)skb->data + hdroff; |
116 | pgreh = (struct gre_hdr_pptp *)greh; | 98 | pgreh = (struct gre_hdr_pptp *)greh; |
@@ -118,7 +100,7 @@ gre_manip_pkt(struct sk_buff *skb, unsigned int iphdroff, | |||
118 | /* we only have destination manip of a packet, since 'source key' | 100 | /* we only have destination manip of a packet, since 'source key' |
119 | * is not present in the packet itself */ | 101 | * is not present in the packet itself */ |
120 | if (maniptype != IP_NAT_MANIP_DST) | 102 | if (maniptype != IP_NAT_MANIP_DST) |
121 | return 1; | 103 | return true; |
122 | switch (greh->version) { | 104 | switch (greh->version) { |
123 | case GRE_VERSION_1701: | 105 | case GRE_VERSION_1701: |
124 | /* We do not currently NAT any GREv0 packets. | 106 | /* We do not currently NAT any GREv0 packets. |
@@ -130,21 +112,20 @@ gre_manip_pkt(struct sk_buff *skb, unsigned int iphdroff, | |||
130 | break; | 112 | break; |
131 | default: | 113 | default: |
132 | pr_debug("can't nat unknown GRE version\n"); | 114 | pr_debug("can't nat unknown GRE version\n"); |
133 | return 0; | 115 | return false; |
134 | } | 116 | } |
135 | return 1; | 117 | return true; |
136 | } | 118 | } |
137 | 119 | ||
138 | static const struct nf_nat_protocol gre = { | 120 | static const struct nf_nat_protocol gre = { |
139 | .name = "GRE", | ||
140 | .protonum = IPPROTO_GRE, | 121 | .protonum = IPPROTO_GRE, |
141 | .me = THIS_MODULE, | 122 | .me = THIS_MODULE, |
142 | .manip_pkt = gre_manip_pkt, | 123 | .manip_pkt = gre_manip_pkt, |
143 | .in_range = gre_in_range, | 124 | .in_range = nf_nat_proto_in_range, |
144 | .unique_tuple = gre_unique_tuple, | 125 | .unique_tuple = gre_unique_tuple, |
145 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 126 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) |
146 | .range_to_nlattr = nf_nat_port_range_to_nlattr, | 127 | .range_to_nlattr = nf_nat_proto_range_to_nlattr, |
147 | .nlattr_to_range = nf_nat_port_nlattr_to_range, | 128 | .nlattr_to_range = nf_nat_proto_nlattr_to_range, |
148 | #endif | 129 | #endif |
149 | }; | 130 | }; |
150 | 131 | ||
diff --git a/net/ipv4/netfilter/nf_nat_proto_icmp.c b/net/ipv4/netfilter/nf_nat_proto_icmp.c index 03a02969aa57..19a8b0b07d8e 100644 --- a/net/ipv4/netfilter/nf_nat_proto_icmp.c +++ b/net/ipv4/netfilter/nf_nat_proto_icmp.c | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <net/netfilter/nf_nat_rule.h> | 17 | #include <net/netfilter/nf_nat_rule.h> |
18 | #include <net/netfilter/nf_nat_protocol.h> | 18 | #include <net/netfilter/nf_nat_protocol.h> |
19 | 19 | ||
20 | static int | 20 | static bool |
21 | icmp_in_range(const struct nf_conntrack_tuple *tuple, | 21 | icmp_in_range(const struct nf_conntrack_tuple *tuple, |
22 | enum nf_nat_manip_type maniptype, | 22 | enum nf_nat_manip_type maniptype, |
23 | const union nf_conntrack_man_proto *min, | 23 | const union nf_conntrack_man_proto *min, |
@@ -27,7 +27,7 @@ icmp_in_range(const struct nf_conntrack_tuple *tuple, | |||
27 | ntohs(tuple->src.u.icmp.id) <= ntohs(max->icmp.id); | 27 | ntohs(tuple->src.u.icmp.id) <= ntohs(max->icmp.id); |
28 | } | 28 | } |
29 | 29 | ||
30 | static int | 30 | static bool |
31 | icmp_unique_tuple(struct nf_conntrack_tuple *tuple, | 31 | icmp_unique_tuple(struct nf_conntrack_tuple *tuple, |
32 | const struct nf_nat_range *range, | 32 | const struct nf_nat_range *range, |
33 | enum nf_nat_manip_type maniptype, | 33 | enum nf_nat_manip_type maniptype, |
@@ -46,12 +46,12 @@ icmp_unique_tuple(struct nf_conntrack_tuple *tuple, | |||
46 | tuple->src.u.icmp.id = htons(ntohs(range->min.icmp.id) + | 46 | tuple->src.u.icmp.id = htons(ntohs(range->min.icmp.id) + |
47 | (id % range_size)); | 47 | (id % range_size)); |
48 | if (!nf_nat_used_tuple(tuple, ct)) | 48 | if (!nf_nat_used_tuple(tuple, ct)) |
49 | return 1; | 49 | return true; |
50 | } | 50 | } |
51 | return 0; | 51 | return false; |
52 | } | 52 | } |
53 | 53 | ||
54 | static int | 54 | static bool |
55 | icmp_manip_pkt(struct sk_buff *skb, | 55 | icmp_manip_pkt(struct sk_buff *skb, |
56 | unsigned int iphdroff, | 56 | unsigned int iphdroff, |
57 | const struct nf_conntrack_tuple *tuple, | 57 | const struct nf_conntrack_tuple *tuple, |
@@ -62,24 +62,23 @@ icmp_manip_pkt(struct sk_buff *skb, | |||
62 | unsigned int hdroff = iphdroff + iph->ihl*4; | 62 | unsigned int hdroff = iphdroff + iph->ihl*4; |
63 | 63 | ||
64 | if (!skb_make_writable(skb, hdroff + sizeof(*hdr))) | 64 | if (!skb_make_writable(skb, hdroff + sizeof(*hdr))) |
65 | return 0; | 65 | return false; |
66 | 66 | ||
67 | hdr = (struct icmphdr *)(skb->data + hdroff); | 67 | hdr = (struct icmphdr *)(skb->data + hdroff); |
68 | inet_proto_csum_replace2(&hdr->checksum, skb, | 68 | inet_proto_csum_replace2(&hdr->checksum, skb, |
69 | hdr->un.echo.id, tuple->src.u.icmp.id, 0); | 69 | hdr->un.echo.id, tuple->src.u.icmp.id, 0); |
70 | hdr->un.echo.id = tuple->src.u.icmp.id; | 70 | hdr->un.echo.id = tuple->src.u.icmp.id; |
71 | return 1; | 71 | return true; |
72 | } | 72 | } |
73 | 73 | ||
74 | const struct nf_nat_protocol nf_nat_protocol_icmp = { | 74 | const struct nf_nat_protocol nf_nat_protocol_icmp = { |
75 | .name = "ICMP", | ||
76 | .protonum = IPPROTO_ICMP, | 75 | .protonum = IPPROTO_ICMP, |
77 | .me = THIS_MODULE, | 76 | .me = THIS_MODULE, |
78 | .manip_pkt = icmp_manip_pkt, | 77 | .manip_pkt = icmp_manip_pkt, |
79 | .in_range = icmp_in_range, | 78 | .in_range = icmp_in_range, |
80 | .unique_tuple = icmp_unique_tuple, | 79 | .unique_tuple = icmp_unique_tuple, |
81 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 80 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) |
82 | .range_to_nlattr = nf_nat_port_range_to_nlattr, | 81 | .range_to_nlattr = nf_nat_proto_range_to_nlattr, |
83 | .nlattr_to_range = nf_nat_port_nlattr_to_range, | 82 | .nlattr_to_range = nf_nat_proto_nlattr_to_range, |
84 | #endif | 83 | #endif |
85 | }; | 84 | }; |
diff --git a/net/ipv4/netfilter/nf_nat_proto_sctp.c b/net/ipv4/netfilter/nf_nat_proto_sctp.c new file mode 100644 index 000000000000..82e4c0e286b8 --- /dev/null +++ b/net/ipv4/netfilter/nf_nat_proto_sctp.c | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008 Patrick McHardy <kaber@trash.net> | ||
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 | #include <linux/types.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/ip.h> | ||
12 | #include <linux/sctp.h> | ||
13 | #include <net/sctp/checksum.h> | ||
14 | |||
15 | #include <net/netfilter/nf_nat_protocol.h> | ||
16 | |||
17 | static u_int16_t nf_sctp_port_rover; | ||
18 | |||
19 | static bool | ||
20 | sctp_unique_tuple(struct nf_conntrack_tuple *tuple, | ||
21 | const struct nf_nat_range *range, | ||
22 | enum nf_nat_manip_type maniptype, | ||
23 | const struct nf_conn *ct) | ||
24 | { | ||
25 | return nf_nat_proto_unique_tuple(tuple, range, maniptype, ct, | ||
26 | &nf_sctp_port_rover); | ||
27 | } | ||
28 | |||
29 | static bool | ||
30 | sctp_manip_pkt(struct sk_buff *skb, | ||
31 | unsigned int iphdroff, | ||
32 | const struct nf_conntrack_tuple *tuple, | ||
33 | enum nf_nat_manip_type maniptype) | ||
34 | { | ||
35 | const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff); | ||
36 | sctp_sctphdr_t *hdr; | ||
37 | unsigned int hdroff = iphdroff + iph->ihl*4; | ||
38 | __be32 oldip, newip; | ||
39 | u32 crc32; | ||
40 | |||
41 | if (!skb_make_writable(skb, hdroff + sizeof(*hdr))) | ||
42 | return false; | ||
43 | |||
44 | iph = (struct iphdr *)(skb->data + iphdroff); | ||
45 | hdr = (struct sctphdr *)(skb->data + hdroff); | ||
46 | |||
47 | if (maniptype == IP_NAT_MANIP_SRC) { | ||
48 | /* Get rid of src ip and src pt */ | ||
49 | oldip = iph->saddr; | ||
50 | newip = tuple->src.u3.ip; | ||
51 | hdr->source = tuple->src.u.sctp.port; | ||
52 | } else { | ||
53 | /* Get rid of dst ip and dst pt */ | ||
54 | oldip = iph->daddr; | ||
55 | newip = tuple->dst.u3.ip; | ||
56 | hdr->dest = tuple->dst.u.sctp.port; | ||
57 | } | ||
58 | |||
59 | crc32 = sctp_start_cksum((u8 *)hdr, skb_headlen(skb) - hdroff); | ||
60 | for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next) | ||
61 | crc32 = sctp_update_cksum((u8 *)skb->data, skb_headlen(skb), | ||
62 | crc32); | ||
63 | crc32 = sctp_end_cksum(crc32); | ||
64 | hdr->checksum = htonl(crc32); | ||
65 | |||
66 | return true; | ||
67 | } | ||
68 | |||
69 | static const struct nf_nat_protocol nf_nat_protocol_sctp = { | ||
70 | .protonum = IPPROTO_SCTP, | ||
71 | .me = THIS_MODULE, | ||
72 | .manip_pkt = sctp_manip_pkt, | ||
73 | .in_range = nf_nat_proto_in_range, | ||
74 | .unique_tuple = sctp_unique_tuple, | ||
75 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | ||
76 | .range_to_nlattr = nf_nat_proto_range_to_nlattr, | ||
77 | .nlattr_to_range = nf_nat_proto_nlattr_to_range, | ||
78 | #endif | ||
79 | }; | ||
80 | |||
81 | static int __init nf_nat_proto_sctp_init(void) | ||
82 | { | ||
83 | return nf_nat_protocol_register(&nf_nat_protocol_sctp); | ||
84 | } | ||
85 | |||
86 | static void __exit nf_nat_proto_sctp_exit(void) | ||
87 | { | ||
88 | nf_nat_protocol_unregister(&nf_nat_protocol_sctp); | ||
89 | } | ||
90 | |||
91 | module_init(nf_nat_proto_sctp_init); | ||
92 | module_exit(nf_nat_proto_sctp_exit); | ||
93 | |||
94 | MODULE_LICENSE("GPL"); | ||
95 | MODULE_DESCRIPTION("SCTP NAT protocol helper"); | ||
96 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | ||
diff --git a/net/ipv4/netfilter/nf_nat_proto_tcp.c b/net/ipv4/netfilter/nf_nat_proto_tcp.c index ffd5d1589eca..399e2cfa263b 100644 --- a/net/ipv4/netfilter/nf_nat_proto_tcp.c +++ b/net/ipv4/netfilter/nf_nat_proto_tcp.c | |||
@@ -8,7 +8,6 @@ | |||
8 | 8 | ||
9 | #include <linux/types.h> | 9 | #include <linux/types.h> |
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/random.h> | ||
12 | #include <linux/ip.h> | 11 | #include <linux/ip.h> |
13 | #include <linux/tcp.h> | 12 | #include <linux/tcp.h> |
14 | 13 | ||
@@ -19,75 +18,19 @@ | |||
19 | #include <net/netfilter/nf_nat_protocol.h> | 18 | #include <net/netfilter/nf_nat_protocol.h> |
20 | #include <net/netfilter/nf_nat_core.h> | 19 | #include <net/netfilter/nf_nat_core.h> |
21 | 20 | ||
22 | static int | 21 | static u_int16_t tcp_port_rover; |
23 | tcp_in_range(const struct nf_conntrack_tuple *tuple, | ||
24 | enum nf_nat_manip_type maniptype, | ||
25 | const union nf_conntrack_man_proto *min, | ||
26 | const union nf_conntrack_man_proto *max) | ||
27 | { | ||
28 | __be16 port; | ||
29 | |||
30 | if (maniptype == IP_NAT_MANIP_SRC) | ||
31 | port = tuple->src.u.tcp.port; | ||
32 | else | ||
33 | port = tuple->dst.u.tcp.port; | ||
34 | |||
35 | return ntohs(port) >= ntohs(min->tcp.port) && | ||
36 | ntohs(port) <= ntohs(max->tcp.port); | ||
37 | } | ||
38 | 22 | ||
39 | static int | 23 | static bool |
40 | tcp_unique_tuple(struct nf_conntrack_tuple *tuple, | 24 | tcp_unique_tuple(struct nf_conntrack_tuple *tuple, |
41 | const struct nf_nat_range *range, | 25 | const struct nf_nat_range *range, |
42 | enum nf_nat_manip_type maniptype, | 26 | enum nf_nat_manip_type maniptype, |
43 | const struct nf_conn *ct) | 27 | const struct nf_conn *ct) |
44 | { | 28 | { |
45 | static u_int16_t port; | 29 | return nf_nat_proto_unique_tuple(tuple, range, maniptype, ct, |
46 | __be16 *portptr; | 30 | &tcp_port_rover); |
47 | unsigned int range_size, min, i; | ||
48 | |||
49 | if (maniptype == IP_NAT_MANIP_SRC) | ||
50 | portptr = &tuple->src.u.tcp.port; | ||
51 | else | ||
52 | portptr = &tuple->dst.u.tcp.port; | ||
53 | |||
54 | /* If no range specified... */ | ||
55 | if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) { | ||
56 | /* If it's dst rewrite, can't change port */ | ||
57 | if (maniptype == IP_NAT_MANIP_DST) | ||
58 | return 0; | ||
59 | |||
60 | /* Map privileged onto privileged. */ | ||
61 | if (ntohs(*portptr) < 1024) { | ||
62 | /* Loose convention: >> 512 is credential passing */ | ||
63 | if (ntohs(*portptr)<512) { | ||
64 | min = 1; | ||
65 | range_size = 511 - min + 1; | ||
66 | } else { | ||
67 | min = 600; | ||
68 | range_size = 1023 - min + 1; | ||
69 | } | ||
70 | } else { | ||
71 | min = 1024; | ||
72 | range_size = 65535 - 1024 + 1; | ||
73 | } | ||
74 | } else { | ||
75 | min = ntohs(range->min.tcp.port); | ||
76 | range_size = ntohs(range->max.tcp.port) - min + 1; | ||
77 | } | ||
78 | |||
79 | if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) | ||
80 | port = net_random(); | ||
81 | |||
82 | for (i = 0; i < range_size; i++, port++) { | ||
83 | *portptr = htons(min + port % range_size); | ||
84 | if (!nf_nat_used_tuple(tuple, ct)) | ||
85 | return 1; | ||
86 | } | ||
87 | return 0; | ||
88 | } | 31 | } |
89 | 32 | ||
90 | static int | 33 | static bool |
91 | tcp_manip_pkt(struct sk_buff *skb, | 34 | tcp_manip_pkt(struct sk_buff *skb, |
92 | unsigned int iphdroff, | 35 | unsigned int iphdroff, |
93 | const struct nf_conntrack_tuple *tuple, | 36 | const struct nf_conntrack_tuple *tuple, |
@@ -107,7 +50,7 @@ tcp_manip_pkt(struct sk_buff *skb, | |||
107 | hdrsize = sizeof(struct tcphdr); | 50 | hdrsize = sizeof(struct tcphdr); |
108 | 51 | ||
109 | if (!skb_make_writable(skb, hdroff + hdrsize)) | 52 | if (!skb_make_writable(skb, hdroff + hdrsize)) |
110 | return 0; | 53 | return false; |
111 | 54 | ||
112 | iph = (struct iphdr *)(skb->data + iphdroff); | 55 | iph = (struct iphdr *)(skb->data + iphdroff); |
113 | hdr = (struct tcphdr *)(skb->data + hdroff); | 56 | hdr = (struct tcphdr *)(skb->data + hdroff); |
@@ -130,22 +73,21 @@ tcp_manip_pkt(struct sk_buff *skb, | |||
130 | *portptr = newport; | 73 | *portptr = newport; |
131 | 74 | ||
132 | if (hdrsize < sizeof(*hdr)) | 75 | if (hdrsize < sizeof(*hdr)) |
133 | return 1; | 76 | return true; |
134 | 77 | ||
135 | inet_proto_csum_replace4(&hdr->check, skb, oldip, newip, 1); | 78 | inet_proto_csum_replace4(&hdr->check, skb, oldip, newip, 1); |
136 | inet_proto_csum_replace2(&hdr->check, skb, oldport, newport, 0); | 79 | inet_proto_csum_replace2(&hdr->check, skb, oldport, newport, 0); |
137 | return 1; | 80 | return true; |
138 | } | 81 | } |
139 | 82 | ||
140 | const struct nf_nat_protocol nf_nat_protocol_tcp = { | 83 | const struct nf_nat_protocol nf_nat_protocol_tcp = { |
141 | .name = "TCP", | ||
142 | .protonum = IPPROTO_TCP, | 84 | .protonum = IPPROTO_TCP, |
143 | .me = THIS_MODULE, | 85 | .me = THIS_MODULE, |
144 | .manip_pkt = tcp_manip_pkt, | 86 | .manip_pkt = tcp_manip_pkt, |
145 | .in_range = tcp_in_range, | 87 | .in_range = nf_nat_proto_in_range, |
146 | .unique_tuple = tcp_unique_tuple, | 88 | .unique_tuple = tcp_unique_tuple, |
147 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 89 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) |
148 | .range_to_nlattr = nf_nat_port_range_to_nlattr, | 90 | .range_to_nlattr = nf_nat_proto_range_to_nlattr, |
149 | .nlattr_to_range = nf_nat_port_nlattr_to_range, | 91 | .nlattr_to_range = nf_nat_proto_nlattr_to_range, |
150 | #endif | 92 | #endif |
151 | }; | 93 | }; |
diff --git a/net/ipv4/netfilter/nf_nat_proto_udp.c b/net/ipv4/netfilter/nf_nat_proto_udp.c index 4b8f49910ff2..9e61c79492e4 100644 --- a/net/ipv4/netfilter/nf_nat_proto_udp.c +++ b/net/ipv4/netfilter/nf_nat_proto_udp.c | |||
@@ -8,7 +8,6 @@ | |||
8 | 8 | ||
9 | #include <linux/types.h> | 9 | #include <linux/types.h> |
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/random.h> | ||
12 | #include <linux/ip.h> | 11 | #include <linux/ip.h> |
13 | #include <linux/udp.h> | 12 | #include <linux/udp.h> |
14 | 13 | ||
@@ -18,74 +17,19 @@ | |||
18 | #include <net/netfilter/nf_nat_rule.h> | 17 | #include <net/netfilter/nf_nat_rule.h> |
19 | #include <net/netfilter/nf_nat_protocol.h> | 18 | #include <net/netfilter/nf_nat_protocol.h> |
20 | 19 | ||
21 | static int | 20 | static u_int16_t udp_port_rover; |
22 | udp_in_range(const struct nf_conntrack_tuple *tuple, | ||
23 | enum nf_nat_manip_type maniptype, | ||
24 | const union nf_conntrack_man_proto *min, | ||
25 | const union nf_conntrack_man_proto *max) | ||
26 | { | ||
27 | __be16 port; | ||
28 | |||
29 | if (maniptype == IP_NAT_MANIP_SRC) | ||
30 | port = tuple->src.u.udp.port; | ||
31 | else | ||
32 | port = tuple->dst.u.udp.port; | ||
33 | |||
34 | return ntohs(port) >= ntohs(min->udp.port) && | ||
35 | ntohs(port) <= ntohs(max->udp.port); | ||
36 | } | ||
37 | 21 | ||
38 | static int | 22 | static bool |
39 | udp_unique_tuple(struct nf_conntrack_tuple *tuple, | 23 | udp_unique_tuple(struct nf_conntrack_tuple *tuple, |
40 | const struct nf_nat_range *range, | 24 | const struct nf_nat_range *range, |
41 | enum nf_nat_manip_type maniptype, | 25 | enum nf_nat_manip_type maniptype, |
42 | const struct nf_conn *ct) | 26 | const struct nf_conn *ct) |
43 | { | 27 | { |
44 | static u_int16_t port; | 28 | return nf_nat_proto_unique_tuple(tuple, range, maniptype, ct, |
45 | __be16 *portptr; | 29 | &udp_port_rover); |
46 | unsigned int range_size, min, i; | ||
47 | |||
48 | if (maniptype == IP_NAT_MANIP_SRC) | ||
49 | portptr = &tuple->src.u.udp.port; | ||
50 | else | ||
51 | portptr = &tuple->dst.u.udp.port; | ||
52 | |||
53 | /* If no range specified... */ | ||
54 | if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) { | ||
55 | /* If it's dst rewrite, can't change port */ | ||
56 | if (maniptype == IP_NAT_MANIP_DST) | ||
57 | return 0; | ||
58 | |||
59 | if (ntohs(*portptr) < 1024) { | ||
60 | /* Loose convention: >> 512 is credential passing */ | ||
61 | if (ntohs(*portptr)<512) { | ||
62 | min = 1; | ||
63 | range_size = 511 - min + 1; | ||
64 | } else { | ||
65 | min = 600; | ||
66 | range_size = 1023 - min + 1; | ||
67 | } | ||
68 | } else { | ||
69 | min = 1024; | ||
70 | range_size = 65535 - 1024 + 1; | ||
71 | } | ||
72 | } else { | ||
73 | min = ntohs(range->min.udp.port); | ||
74 | range_size = ntohs(range->max.udp.port) - min + 1; | ||
75 | } | ||
76 | |||
77 | if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) | ||
78 | port = net_random(); | ||
79 | |||
80 | for (i = 0; i < range_size; i++, port++) { | ||
81 | *portptr = htons(min + port % range_size); | ||
82 | if (!nf_nat_used_tuple(tuple, ct)) | ||
83 | return 1; | ||
84 | } | ||
85 | return 0; | ||
86 | } | 30 | } |
87 | 31 | ||
88 | static int | 32 | static bool |
89 | udp_manip_pkt(struct sk_buff *skb, | 33 | udp_manip_pkt(struct sk_buff *skb, |
90 | unsigned int iphdroff, | 34 | unsigned int iphdroff, |
91 | const struct nf_conntrack_tuple *tuple, | 35 | const struct nf_conntrack_tuple *tuple, |
@@ -98,7 +42,7 @@ udp_manip_pkt(struct sk_buff *skb, | |||
98 | __be16 *portptr, newport; | 42 | __be16 *portptr, newport; |
99 | 43 | ||
100 | if (!skb_make_writable(skb, hdroff + sizeof(*hdr))) | 44 | if (!skb_make_writable(skb, hdroff + sizeof(*hdr))) |
101 | return 0; | 45 | return false; |
102 | 46 | ||
103 | iph = (struct iphdr *)(skb->data + iphdroff); | 47 | iph = (struct iphdr *)(skb->data + iphdroff); |
104 | hdr = (struct udphdr *)(skb->data + hdroff); | 48 | hdr = (struct udphdr *)(skb->data + hdroff); |
@@ -124,18 +68,17 @@ udp_manip_pkt(struct sk_buff *skb, | |||
124 | hdr->check = CSUM_MANGLED_0; | 68 | hdr->check = CSUM_MANGLED_0; |
125 | } | 69 | } |
126 | *portptr = newport; | 70 | *portptr = newport; |
127 | return 1; | 71 | return true; |
128 | } | 72 | } |
129 | 73 | ||
130 | const struct nf_nat_protocol nf_nat_protocol_udp = { | 74 | const struct nf_nat_protocol nf_nat_protocol_udp = { |
131 | .name = "UDP", | ||
132 | .protonum = IPPROTO_UDP, | 75 | .protonum = IPPROTO_UDP, |
133 | .me = THIS_MODULE, | 76 | .me = THIS_MODULE, |
134 | .manip_pkt = udp_manip_pkt, | 77 | .manip_pkt = udp_manip_pkt, |
135 | .in_range = udp_in_range, | 78 | .in_range = nf_nat_proto_in_range, |
136 | .unique_tuple = udp_unique_tuple, | 79 | .unique_tuple = udp_unique_tuple, |
137 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 80 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) |
138 | .range_to_nlattr = nf_nat_port_range_to_nlattr, | 81 | .range_to_nlattr = nf_nat_proto_range_to_nlattr, |
139 | .nlattr_to_range = nf_nat_port_nlattr_to_range, | 82 | .nlattr_to_range = nf_nat_proto_nlattr_to_range, |
140 | #endif | 83 | #endif |
141 | }; | 84 | }; |
diff --git a/net/ipv4/netfilter/nf_nat_proto_udplite.c b/net/ipv4/netfilter/nf_nat_proto_udplite.c new file mode 100644 index 000000000000..440a229bbd87 --- /dev/null +++ b/net/ipv4/netfilter/nf_nat_proto_udplite.c | |||
@@ -0,0 +1,99 @@ | |||
1 | /* (C) 1999-2001 Paul `Rusty' Russell | ||
2 | * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org> | ||
3 | * (C) 2008 Patrick McHardy <kaber@trash.net> | ||
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/types.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/ip.h> | ||
13 | #include <linux/udp.h> | ||
14 | |||
15 | #include <linux/netfilter.h> | ||
16 | #include <net/netfilter/nf_nat.h> | ||
17 | #include <net/netfilter/nf_nat_protocol.h> | ||
18 | |||
19 | static u_int16_t udplite_port_rover; | ||
20 | |||
21 | static bool | ||
22 | udplite_unique_tuple(struct nf_conntrack_tuple *tuple, | ||
23 | const struct nf_nat_range *range, | ||
24 | enum nf_nat_manip_type maniptype, | ||
25 | const struct nf_conn *ct) | ||
26 | { | ||
27 | return nf_nat_proto_unique_tuple(tuple, range, maniptype, ct, | ||
28 | &udplite_port_rover); | ||
29 | } | ||
30 | |||
31 | static bool | ||
32 | udplite_manip_pkt(struct sk_buff *skb, | ||
33 | unsigned int iphdroff, | ||
34 | const struct nf_conntrack_tuple *tuple, | ||
35 | enum nf_nat_manip_type maniptype) | ||
36 | { | ||
37 | const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff); | ||
38 | struct udphdr *hdr; | ||
39 | unsigned int hdroff = iphdroff + iph->ihl*4; | ||
40 | __be32 oldip, newip; | ||
41 | __be16 *portptr, newport; | ||
42 | |||
43 | if (!skb_make_writable(skb, hdroff + sizeof(*hdr))) | ||
44 | return false; | ||
45 | |||
46 | iph = (struct iphdr *)(skb->data + iphdroff); | ||
47 | hdr = (struct udphdr *)(skb->data + hdroff); | ||
48 | |||
49 | if (maniptype == IP_NAT_MANIP_SRC) { | ||
50 | /* Get rid of src ip and src pt */ | ||
51 | oldip = iph->saddr; | ||
52 | newip = tuple->src.u3.ip; | ||
53 | newport = tuple->src.u.udp.port; | ||
54 | portptr = &hdr->source; | ||
55 | } else { | ||
56 | /* Get rid of dst ip and dst pt */ | ||
57 | oldip = iph->daddr; | ||
58 | newip = tuple->dst.u3.ip; | ||
59 | newport = tuple->dst.u.udp.port; | ||
60 | portptr = &hdr->dest; | ||
61 | } | ||
62 | |||
63 | inet_proto_csum_replace4(&hdr->check, skb, oldip, newip, 1); | ||
64 | inet_proto_csum_replace2(&hdr->check, skb, *portptr, newport, 0); | ||
65 | if (!hdr->check) | ||
66 | hdr->check = CSUM_MANGLED_0; | ||
67 | |||
68 | *portptr = newport; | ||
69 | return true; | ||
70 | } | ||
71 | |||
72 | static const struct nf_nat_protocol nf_nat_protocol_udplite = { | ||
73 | .protonum = IPPROTO_UDPLITE, | ||
74 | .me = THIS_MODULE, | ||
75 | .manip_pkt = udplite_manip_pkt, | ||
76 | .in_range = nf_nat_proto_in_range, | ||
77 | .unique_tuple = udplite_unique_tuple, | ||
78 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | ||
79 | .range_to_nlattr = nf_nat_proto_range_to_nlattr, | ||
80 | .nlattr_to_range = nf_nat_proto_nlattr_to_range, | ||
81 | #endif | ||
82 | }; | ||
83 | |||
84 | static int __init nf_nat_proto_udplite_init(void) | ||
85 | { | ||
86 | return nf_nat_protocol_register(&nf_nat_protocol_udplite); | ||
87 | } | ||
88 | |||
89 | static void __exit nf_nat_proto_udplite_fini(void) | ||
90 | { | ||
91 | nf_nat_protocol_unregister(&nf_nat_protocol_udplite); | ||
92 | } | ||
93 | |||
94 | module_init(nf_nat_proto_udplite_init); | ||
95 | module_exit(nf_nat_proto_udplite_fini); | ||
96 | |||
97 | MODULE_LICENSE("GPL"); | ||
98 | MODULE_DESCRIPTION("UDP-Lite NAT protocol helper"); | ||
99 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | ||
diff --git a/net/ipv4/netfilter/nf_nat_proto_unknown.c b/net/ipv4/netfilter/nf_nat_proto_unknown.c index a26efeb073cb..14381c62acea 100644 --- a/net/ipv4/netfilter/nf_nat_proto_unknown.c +++ b/net/ipv4/netfilter/nf_nat_proto_unknown.c | |||
@@ -18,35 +18,34 @@ | |||
18 | #include <net/netfilter/nf_nat_rule.h> | 18 | #include <net/netfilter/nf_nat_rule.h> |
19 | #include <net/netfilter/nf_nat_protocol.h> | 19 | #include <net/netfilter/nf_nat_protocol.h> |
20 | 20 | ||
21 | static int unknown_in_range(const struct nf_conntrack_tuple *tuple, | 21 | static bool unknown_in_range(const struct nf_conntrack_tuple *tuple, |
22 | enum nf_nat_manip_type manip_type, | 22 | enum nf_nat_manip_type manip_type, |
23 | const union nf_conntrack_man_proto *min, | 23 | const union nf_conntrack_man_proto *min, |
24 | const union nf_conntrack_man_proto *max) | 24 | const union nf_conntrack_man_proto *max) |
25 | { | 25 | { |
26 | return 1; | 26 | return true; |
27 | } | 27 | } |
28 | 28 | ||
29 | static int unknown_unique_tuple(struct nf_conntrack_tuple *tuple, | 29 | static bool unknown_unique_tuple(struct nf_conntrack_tuple *tuple, |
30 | const struct nf_nat_range *range, | 30 | const struct nf_nat_range *range, |
31 | enum nf_nat_manip_type maniptype, | 31 | enum nf_nat_manip_type maniptype, |
32 | const struct nf_conn *ct) | 32 | const struct nf_conn *ct) |
33 | { | 33 | { |
34 | /* Sorry: we can't help you; if it's not unique, we can't frob | 34 | /* Sorry: we can't help you; if it's not unique, we can't frob |
35 | anything. */ | 35 | anything. */ |
36 | return 0; | 36 | return false; |
37 | } | 37 | } |
38 | 38 | ||
39 | static int | 39 | static bool |
40 | unknown_manip_pkt(struct sk_buff *skb, | 40 | unknown_manip_pkt(struct sk_buff *skb, |
41 | unsigned int iphdroff, | 41 | unsigned int iphdroff, |
42 | const struct nf_conntrack_tuple *tuple, | 42 | const struct nf_conntrack_tuple *tuple, |
43 | enum nf_nat_manip_type maniptype) | 43 | enum nf_nat_manip_type maniptype) |
44 | { | 44 | { |
45 | return 1; | 45 | return true; |
46 | } | 46 | } |
47 | 47 | ||
48 | const struct nf_nat_protocol nf_nat_unknown_protocol = { | 48 | const struct nf_nat_protocol nf_nat_unknown_protocol = { |
49 | .name = "unknown", | ||
50 | /* .me isn't set: getting a ref to this cannot fail. */ | 49 | /* .me isn't set: getting a ref to this cannot fail. */ |
51 | .manip_pkt = unknown_manip_pkt, | 50 | .manip_pkt = unknown_manip_pkt, |
52 | .in_range = unknown_in_range, | 51 | .in_range = unknown_in_range, |
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c index f8fda57ba20b..e8b4d0d4439e 100644 --- a/net/ipv4/netfilter/nf_nat_rule.c +++ b/net/ipv4/netfilter/nf_nat_rule.c | |||
@@ -61,7 +61,7 @@ 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, | 64 | .lock = __RW_LOCK_UNLOCKED(__nat_table.lock), |
65 | .me = THIS_MODULE, | 65 | .me = THIS_MODULE, |
66 | .af = AF_INET, | 66 | .af = AF_INET, |
67 | }; | 67 | }; |
@@ -143,7 +143,7 @@ static bool ipt_snat_checkentry(const char *tablename, | |||
143 | void *targinfo, | 143 | void *targinfo, |
144 | unsigned int hook_mask) | 144 | unsigned int hook_mask) |
145 | { | 145 | { |
146 | struct nf_nat_multi_range_compat *mr = targinfo; | 146 | const struct nf_nat_multi_range_compat *mr = targinfo; |
147 | 147 | ||
148 | /* Must be a valid range */ | 148 | /* Must be a valid range */ |
149 | if (mr->rangesize != 1) { | 149 | if (mr->rangesize != 1) { |
@@ -159,7 +159,7 @@ static bool ipt_dnat_checkentry(const char *tablename, | |||
159 | void *targinfo, | 159 | void *targinfo, |
160 | unsigned int hook_mask) | 160 | unsigned int hook_mask) |
161 | { | 161 | { |
162 | struct nf_nat_multi_range_compat *mr = targinfo; | 162 | const struct nf_nat_multi_range_compat *mr = targinfo; |
163 | 163 | ||
164 | /* Must be a valid range */ | 164 | /* Must be a valid range */ |
165 | if (mr->rangesize != 1) { | 165 | if (mr->rangesize != 1) { |
@@ -188,25 +188,6 @@ alloc_null_binding(struct nf_conn *ct, unsigned int hooknum) | |||
188 | return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum)); | 188 | return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum)); |
189 | } | 189 | } |
190 | 190 | ||
191 | unsigned int | ||
192 | alloc_null_binding_confirmed(struct nf_conn *ct, unsigned int hooknum) | ||
193 | { | ||
194 | __be32 ip | ||
195 | = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC | ||
196 | ? ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip | ||
197 | : ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip); | ||
198 | __be16 all | ||
199 | = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC | ||
200 | ? ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.all | ||
201 | : ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.all); | ||
202 | struct nf_nat_range range | ||
203 | = { IP_NAT_RANGE_MAP_IPS, ip, ip, { all }, { all } }; | ||
204 | |||
205 | pr_debug("Allocating NULL binding for confirmed %p (%u.%u.%u.%u)\n", | ||
206 | ct, NIPQUAD(ip)); | ||
207 | return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum)); | ||
208 | } | ||
209 | |||
210 | int nf_nat_rule_find(struct sk_buff *skb, | 191 | int nf_nat_rule_find(struct sk_buff *skb, |
211 | unsigned int hooknum, | 192 | unsigned int hooknum, |
212 | const struct net_device *in, | 193 | const struct net_device *in, |
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c index 000e080bac5c..5daefad3d193 100644 --- a/net/ipv4/netfilter/nf_nat_snmp_basic.c +++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c | |||
@@ -220,7 +220,7 @@ static unsigned char asn1_length_decode(struct asn1_ctx *ctx, | |||
220 | if (ch < 0x80) | 220 | if (ch < 0x80) |
221 | *len = ch; | 221 | *len = ch; |
222 | else { | 222 | else { |
223 | cnt = (unsigned char) (ch & 0x7F); | 223 | cnt = ch & 0x7F; |
224 | *len = 0; | 224 | *len = 0; |
225 | 225 | ||
226 | while (cnt > 0) { | 226 | while (cnt > 0) { |
@@ -618,8 +618,7 @@ struct snmp_cnv | |||
618 | int syntax; | 618 | int syntax; |
619 | }; | 619 | }; |
620 | 620 | ||
621 | static struct snmp_cnv snmp_conv [] = | 621 | static const struct snmp_cnv snmp_conv[] = { |
622 | { | ||
623 | {ASN1_UNI, ASN1_NUL, SNMP_NULL}, | 622 | {ASN1_UNI, ASN1_NUL, SNMP_NULL}, |
624 | {ASN1_UNI, ASN1_INT, SNMP_INTEGER}, | 623 | {ASN1_UNI, ASN1_INT, SNMP_INTEGER}, |
625 | {ASN1_UNI, ASN1_OTS, SNMP_OCTETSTR}, | 624 | {ASN1_UNI, ASN1_OTS, SNMP_OCTETSTR}, |
@@ -644,7 +643,7 @@ static unsigned char snmp_tag_cls2syntax(unsigned int tag, | |||
644 | unsigned int cls, | 643 | unsigned int cls, |
645 | unsigned short *syntax) | 644 | unsigned short *syntax) |
646 | { | 645 | { |
647 | struct snmp_cnv *cnv; | 646 | const struct snmp_cnv *cnv; |
648 | 647 | ||
649 | cnv = snmp_conv; | 648 | cnv = snmp_conv; |
650 | 649 | ||
@@ -904,7 +903,7 @@ static inline void mangle_address(unsigned char *begin, | |||
904 | u_int32_t old; | 903 | u_int32_t old; |
905 | 904 | ||
906 | if (debug) | 905 | if (debug) |
907 | memcpy(&old, (unsigned char *)addr, sizeof(old)); | 906 | memcpy(&old, addr, sizeof(old)); |
908 | 907 | ||
909 | *addr = map->to; | 908 | *addr = map->to; |
910 | 909 | ||
@@ -999,7 +998,7 @@ err_id_free: | |||
999 | * | 998 | * |
1000 | *****************************************************************************/ | 999 | *****************************************************************************/ |
1001 | 1000 | ||
1002 | static void hex_dump(unsigned char *buf, size_t len) | 1001 | static void hex_dump(const unsigned char *buf, size_t len) |
1003 | { | 1002 | { |
1004 | size_t i; | 1003 | size_t i; |
1005 | 1004 | ||
@@ -1080,7 +1079,7 @@ static int snmp_parse_mangle(unsigned char *msg, | |||
1080 | if (cls != ASN1_CTX || con != ASN1_CON) | 1079 | if (cls != ASN1_CTX || con != ASN1_CON) |
1081 | return 0; | 1080 | return 0; |
1082 | if (debug > 1) { | 1081 | if (debug > 1) { |
1083 | unsigned char *pdus[] = { | 1082 | static const unsigned char *const pdus[] = { |
1084 | [SNMP_PDU_GET] = "get", | 1083 | [SNMP_PDU_GET] = "get", |
1085 | [SNMP_PDU_NEXT] = "get-next", | 1084 | [SNMP_PDU_NEXT] = "get-next", |
1086 | [SNMP_PDU_RESPONSE] = "response", | 1085 | [SNMP_PDU_RESPONSE] = "response", |
@@ -1232,8 +1231,8 @@ static int help(struct sk_buff *skb, unsigned int protoff, | |||
1232 | { | 1231 | { |
1233 | int dir = CTINFO2DIR(ctinfo); | 1232 | int dir = CTINFO2DIR(ctinfo); |
1234 | unsigned int ret; | 1233 | unsigned int ret; |
1235 | struct iphdr *iph = ip_hdr(skb); | 1234 | const struct iphdr *iph = ip_hdr(skb); |
1236 | struct udphdr *udph = (struct udphdr *)((u_int32_t *)iph + iph->ihl); | 1235 | const struct udphdr *udph = (struct udphdr *)((__be32 *)iph + iph->ihl); |
1237 | 1236 | ||
1238 | /* SNMP replies and originating SNMP traps get mangled */ | 1237 | /* SNMP replies and originating SNMP traps get mangled */ |
1239 | if (udph->source == htons(SNMP_PORT) && dir != IP_CT_DIR_REPLY) | 1238 | if (udph->source == htons(SNMP_PORT) && dir != IP_CT_DIR_REPLY) |
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c index 99b2c788d5a8..b7dd695691a0 100644 --- a/net/ipv4/netfilter/nf_nat_standalone.c +++ b/net/ipv4/netfilter/nf_nat_standalone.c | |||
@@ -30,8 +30,8 @@ | |||
30 | #ifdef CONFIG_XFRM | 30 | #ifdef CONFIG_XFRM |
31 | static void nat_decode_session(struct sk_buff *skb, struct flowi *fl) | 31 | static void nat_decode_session(struct sk_buff *skb, struct flowi *fl) |
32 | { | 32 | { |
33 | struct nf_conn *ct; | 33 | const struct nf_conn *ct; |
34 | struct nf_conntrack_tuple *t; | 34 | const struct nf_conntrack_tuple *t; |
35 | enum ip_conntrack_info ctinfo; | 35 | enum ip_conntrack_info ctinfo; |
36 | enum ip_conntrack_dir dir; | 36 | enum ip_conntrack_dir dir; |
37 | unsigned long statusbit; | 37 | unsigned long statusbit; |
@@ -50,7 +50,10 @@ static void nat_decode_session(struct sk_buff *skb, struct flowi *fl) | |||
50 | if (ct->status & statusbit) { | 50 | if (ct->status & statusbit) { |
51 | fl->fl4_dst = t->dst.u3.ip; | 51 | fl->fl4_dst = t->dst.u3.ip; |
52 | if (t->dst.protonum == IPPROTO_TCP || | 52 | if (t->dst.protonum == IPPROTO_TCP || |
53 | t->dst.protonum == IPPROTO_UDP) | 53 | t->dst.protonum == IPPROTO_UDP || |
54 | t->dst.protonum == IPPROTO_UDPLITE || | ||
55 | t->dst.protonum == IPPROTO_DCCP || | ||
56 | t->dst.protonum == IPPROTO_SCTP) | ||
54 | fl->fl_ip_dport = t->dst.u.tcp.port; | 57 | fl->fl_ip_dport = t->dst.u.tcp.port; |
55 | } | 58 | } |
56 | 59 | ||
@@ -59,7 +62,10 @@ static void nat_decode_session(struct sk_buff *skb, struct flowi *fl) | |||
59 | if (ct->status & statusbit) { | 62 | if (ct->status & statusbit) { |
60 | fl->fl4_src = t->src.u3.ip; | 63 | fl->fl4_src = t->src.u3.ip; |
61 | if (t->dst.protonum == IPPROTO_TCP || | 64 | if (t->dst.protonum == IPPROTO_TCP || |
62 | t->dst.protonum == IPPROTO_UDP) | 65 | t->dst.protonum == IPPROTO_UDP || |
66 | t->dst.protonum == IPPROTO_UDPLITE || | ||
67 | t->dst.protonum == IPPROTO_DCCP || | ||
68 | t->dst.protonum == IPPROTO_SCTP) | ||
63 | fl->fl_ip_sport = t->src.u.tcp.port; | 69 | fl->fl_ip_sport = t->src.u.tcp.port; |
64 | } | 70 | } |
65 | } | 71 | } |
@@ -87,21 +93,8 @@ nf_nat_fn(unsigned int hooknum, | |||
87 | have dropped it. Hence it's the user's responsibilty to | 93 | have dropped it. Hence it's the user's responsibilty to |
88 | packet filter it out, or implement conntrack/NAT for that | 94 | packet filter it out, or implement conntrack/NAT for that |
89 | protocol. 8) --RR */ | 95 | protocol. 8) --RR */ |
90 | if (!ct) { | 96 | if (!ct) |
91 | /* Exception: ICMP redirect to new connection (not in | ||
92 | hash table yet). We must not let this through, in | ||
93 | case we're doing NAT to the same network. */ | ||
94 | if (ip_hdr(skb)->protocol == IPPROTO_ICMP) { | ||
95 | struct icmphdr _hdr, *hp; | ||
96 | |||
97 | hp = skb_header_pointer(skb, ip_hdrlen(skb), | ||
98 | sizeof(_hdr), &_hdr); | ||
99 | if (hp != NULL && | ||
100 | hp->type == ICMP_REDIRECT) | ||
101 | return NF_DROP; | ||
102 | } | ||
103 | return NF_ACCEPT; | 97 | return NF_ACCEPT; |
104 | } | ||
105 | 98 | ||
106 | /* Don't try to NAT if this packet is not conntracked */ | 99 | /* Don't try to NAT if this packet is not conntracked */ |
107 | if (ct == &nf_conntrack_untracked) | 100 | if (ct == &nf_conntrack_untracked) |
@@ -109,6 +102,9 @@ nf_nat_fn(unsigned int hooknum, | |||
109 | 102 | ||
110 | nat = nfct_nat(ct); | 103 | nat = nfct_nat(ct); |
111 | if (!nat) { | 104 | if (!nat) { |
105 | /* NAT module was loaded late. */ | ||
106 | if (nf_ct_is_confirmed(ct)) | ||
107 | return NF_ACCEPT; | ||
112 | nat = nf_ct_ext_add(ct, NF_CT_EXT_NAT, GFP_ATOMIC); | 108 | nat = nf_ct_ext_add(ct, NF_CT_EXT_NAT, GFP_ATOMIC); |
113 | if (nat == NULL) { | 109 | if (nat == NULL) { |
114 | pr_debug("failed to add NAT extension\n"); | 110 | pr_debug("failed to add NAT extension\n"); |
@@ -134,10 +130,7 @@ nf_nat_fn(unsigned int hooknum, | |||
134 | if (!nf_nat_initialized(ct, maniptype)) { | 130 | if (!nf_nat_initialized(ct, maniptype)) { |
135 | unsigned int ret; | 131 | unsigned int ret; |
136 | 132 | ||
137 | if (unlikely(nf_ct_is_confirmed(ct))) | 133 | if (hooknum == NF_INET_LOCAL_IN) |
138 | /* NAT module was loaded late */ | ||
139 | ret = alloc_null_binding_confirmed(ct, hooknum); | ||
140 | else if (hooknum == NF_INET_LOCAL_IN) | ||
141 | /* LOCAL_IN hook doesn't have a chain! */ | 134 | /* LOCAL_IN hook doesn't have a chain! */ |
142 | ret = alloc_null_binding(ct, hooknum); | 135 | ret = alloc_null_binding(ct, hooknum); |
143 | else | 136 | else |
@@ -189,7 +182,7 @@ nf_nat_out(unsigned int hooknum, | |||
189 | int (*okfn)(struct sk_buff *)) | 182 | int (*okfn)(struct sk_buff *)) |
190 | { | 183 | { |
191 | #ifdef CONFIG_XFRM | 184 | #ifdef CONFIG_XFRM |
192 | struct nf_conn *ct; | 185 | const struct nf_conn *ct; |
193 | enum ip_conntrack_info ctinfo; | 186 | enum ip_conntrack_info ctinfo; |
194 | #endif | 187 | #endif |
195 | unsigned int ret; | 188 | unsigned int ret; |
@@ -223,7 +216,7 @@ nf_nat_local_fn(unsigned int hooknum, | |||
223 | const struct net_device *out, | 216 | const struct net_device *out, |
224 | int (*okfn)(struct sk_buff *)) | 217 | int (*okfn)(struct sk_buff *)) |
225 | { | 218 | { |
226 | struct nf_conn *ct; | 219 | const struct nf_conn *ct; |
227 | enum ip_conntrack_info ctinfo; | 220 | enum ip_conntrack_info ctinfo; |
228 | unsigned int ret; | 221 | unsigned int ret; |
229 | 222 | ||
@@ -252,25 +245,6 @@ nf_nat_local_fn(unsigned int hooknum, | |||
252 | return ret; | 245 | return ret; |
253 | } | 246 | } |
254 | 247 | ||
255 | static unsigned int | ||
256 | nf_nat_adjust(unsigned int hooknum, | ||
257 | struct sk_buff *skb, | ||
258 | const struct net_device *in, | ||
259 | const struct net_device *out, | ||
260 | int (*okfn)(struct sk_buff *)) | ||
261 | { | ||
262 | struct nf_conn *ct; | ||
263 | enum ip_conntrack_info ctinfo; | ||
264 | |||
265 | ct = nf_ct_get(skb, &ctinfo); | ||
266 | if (ct && test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) { | ||
267 | pr_debug("nf_nat_standalone: adjusting sequence number\n"); | ||
268 | if (!nf_nat_seq_adjust(skb, ct, ctinfo)) | ||
269 | return NF_DROP; | ||
270 | } | ||
271 | return NF_ACCEPT; | ||
272 | } | ||
273 | |||
274 | /* We must be after connection tracking and before packet filtering. */ | 248 | /* We must be after connection tracking and before packet filtering. */ |
275 | 249 | ||
276 | static struct nf_hook_ops nf_nat_ops[] __read_mostly = { | 250 | static struct nf_hook_ops nf_nat_ops[] __read_mostly = { |
@@ -290,14 +264,6 @@ static struct nf_hook_ops nf_nat_ops[] __read_mostly = { | |||
290 | .hooknum = NF_INET_POST_ROUTING, | 264 | .hooknum = NF_INET_POST_ROUTING, |
291 | .priority = NF_IP_PRI_NAT_SRC, | 265 | .priority = NF_IP_PRI_NAT_SRC, |
292 | }, | 266 | }, |
293 | /* After conntrack, adjust sequence number */ | ||
294 | { | ||
295 | .hook = nf_nat_adjust, | ||
296 | .owner = THIS_MODULE, | ||
297 | .pf = PF_INET, | ||
298 | .hooknum = NF_INET_POST_ROUTING, | ||
299 | .priority = NF_IP_PRI_NAT_SEQ_ADJUST, | ||
300 | }, | ||
301 | /* Before packet filtering, change destination */ | 267 | /* Before packet filtering, change destination */ |
302 | { | 268 | { |
303 | .hook = nf_nat_local_fn, | 269 | .hook = nf_nat_local_fn, |
@@ -314,14 +280,6 @@ static struct nf_hook_ops nf_nat_ops[] __read_mostly = { | |||
314 | .hooknum = NF_INET_LOCAL_IN, | 280 | .hooknum = NF_INET_LOCAL_IN, |
315 | .priority = NF_IP_PRI_NAT_SRC, | 281 | .priority = NF_IP_PRI_NAT_SRC, |
316 | }, | 282 | }, |
317 | /* After conntrack, adjust sequence number */ | ||
318 | { | ||
319 | .hook = nf_nat_adjust, | ||
320 | .owner = THIS_MODULE, | ||
321 | .pf = PF_INET, | ||
322 | .hooknum = NF_INET_LOCAL_IN, | ||
323 | .priority = NF_IP_PRI_NAT_SEQ_ADJUST, | ||
324 | }, | ||
325 | }; | 283 | }; |
326 | 284 | ||
327 | static int __init nf_nat_standalone_init(void) | 285 | static int __init nf_nat_standalone_init(void) |