aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netfilter/nfnetlink.h2
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netlink.c83
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_icmp.c15
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_tcp.c11
-rw-r--r--net/ipv4/netfilter/ip_nat_helper_pptp.c28
-rw-r--r--net/ipv6/addrconf.c3
-rw-r--r--net/ipv6/ip6_tunnel.c1
-rw-r--r--net/netfilter/nfnetlink.c21
8 files changed, 92 insertions, 72 deletions
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
index f08e870100f4..72975fa8795d 100644
--- a/include/linux/netfilter/nfnetlink.h
+++ b/include/linux/netfilter/nfnetlink.h
@@ -146,7 +146,7 @@ extern void nfnl_unlock(void);
146extern int nfnetlink_subsys_register(struct nfnetlink_subsystem *n); 146extern int nfnetlink_subsys_register(struct nfnetlink_subsystem *n);
147extern int nfnetlink_subsys_unregister(struct nfnetlink_subsystem *n); 147extern int nfnetlink_subsys_unregister(struct nfnetlink_subsystem *n);
148 148
149extern int nfattr_parse(struct nfattr *tb[], int maxattr, 149extern void nfattr_parse(struct nfattr *tb[], int maxattr,
150 struct nfattr *nfa, int len); 150 struct nfattr *nfa, int len);
151 151
152#define nfattr_parse_nested(tb, max, nfa) \ 152#define nfattr_parse_nested(tb, max, nfa) \
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index 82a65043a8ef..5c1c0a3d1c4b 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -28,11 +28,8 @@
28#include <linux/netlink.h> 28#include <linux/netlink.h>
29#include <linux/spinlock.h> 29#include <linux/spinlock.h>
30#include <linux/notifier.h> 30#include <linux/notifier.h>
31#include <linux/rtnetlink.h>
32 31
33#include <linux/netfilter.h> 32#include <linux/netfilter.h>
34#include <linux/netfilter_ipv4.h>
35#include <linux/netfilter_ipv4/ip_tables.h>
36#include <linux/netfilter_ipv4/ip_conntrack.h> 33#include <linux/netfilter_ipv4/ip_conntrack.h>
37#include <linux/netfilter_ipv4/ip_conntrack_core.h> 34#include <linux/netfilter_ipv4/ip_conntrack_core.h>
38#include <linux/netfilter_ipv4/ip_conntrack_helper.h> 35#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
@@ -58,14 +55,17 @@ ctnetlink_dump_tuples_proto(struct sk_buff *skb,
58 const struct ip_conntrack_tuple *tuple) 55 const struct ip_conntrack_tuple *tuple)
59{ 56{
60 struct ip_conntrack_protocol *proto; 57 struct ip_conntrack_protocol *proto;
58 int ret = 0;
61 59
62 NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum); 60 NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum);
63 61
64 proto = ip_conntrack_proto_find_get(tuple->dst.protonum); 62 proto = ip_conntrack_proto_find_get(tuple->dst.protonum);
65 if (proto && proto->tuple_to_nfattr) 63 if (likely(proto && proto->tuple_to_nfattr)) {
66 return proto->tuple_to_nfattr(skb, tuple); 64 ret = proto->tuple_to_nfattr(skb, tuple);
65 ip_conntrack_proto_put(proto);
66 }
67 67
68 return 0; 68 return ret;
69 69
70nfattr_failure: 70nfattr_failure:
71 return -1; 71 return -1;
@@ -175,7 +175,7 @@ ctnetlink_dump_counters(struct sk_buff *skb, const struct ip_conntrack *ct,
175{ 175{
176 enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG; 176 enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG;
177 struct nfattr *nest_count = NFA_NEST(skb, type); 177 struct nfattr *nest_count = NFA_NEST(skb, type);
178 u_int64_t tmp; 178 u_int32_t tmp;
179 179
180 tmp = htonl(ct->counters[dir].packets); 180 tmp = htonl(ct->counters[dir].packets);
181 NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp); 181 NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp);
@@ -479,9 +479,7 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct ip_conntrack_tuple *tuple)
479 479
480 DEBUGP("entered %s\n", __FUNCTION__); 480 DEBUGP("entered %s\n", __FUNCTION__);
481 481
482 482 nfattr_parse_nested(tb, CTA_IP_MAX, attr);
483 if (nfattr_parse_nested(tb, CTA_IP_MAX, attr) < 0)
484 goto nfattr_failure;
485 483
486 if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip)) 484 if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip))
487 return -EINVAL; 485 return -EINVAL;
@@ -497,9 +495,6 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct ip_conntrack_tuple *tuple)
497 DEBUGP("leaving\n"); 495 DEBUGP("leaving\n");
498 496
499 return 0; 497 return 0;
500
501nfattr_failure:
502 return -1;
503} 498}
504 499
505static const int cta_min_proto[CTA_PROTO_MAX] = { 500static const int cta_min_proto[CTA_PROTO_MAX] = {
@@ -521,8 +516,7 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr,
521 516
522 DEBUGP("entered %s\n", __FUNCTION__); 517 DEBUGP("entered %s\n", __FUNCTION__);
523 518
524 if (nfattr_parse_nested(tb, CTA_PROTO_MAX, attr) < 0) 519 nfattr_parse_nested(tb, CTA_PROTO_MAX, attr);
525 goto nfattr_failure;
526 520
527 if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) 521 if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto))
528 return -EINVAL; 522 return -EINVAL;
@@ -539,9 +533,6 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr,
539 } 533 }
540 534
541 return ret; 535 return ret;
542
543nfattr_failure:
544 return -1;
545} 536}
546 537
547static inline int 538static inline int
@@ -555,8 +546,7 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct ip_conntrack_tuple *tuple,
555 546
556 memset(tuple, 0, sizeof(*tuple)); 547 memset(tuple, 0, sizeof(*tuple));
557 548
558 if (nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]) < 0) 549 nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]);
559 goto nfattr_failure;
560 550
561 if (!tb[CTA_TUPLE_IP-1]) 551 if (!tb[CTA_TUPLE_IP-1])
562 return -EINVAL; 552 return -EINVAL;
@@ -583,9 +573,6 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct ip_conntrack_tuple *tuple,
583 DEBUGP("leaving\n"); 573 DEBUGP("leaving\n");
584 574
585 return 0; 575 return 0;
586
587nfattr_failure:
588 return -1;
589} 576}
590 577
591#ifdef CONFIG_IP_NF_NAT_NEEDED 578#ifdef CONFIG_IP_NF_NAT_NEEDED
@@ -603,11 +590,10 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
603 590
604 DEBUGP("entered %s\n", __FUNCTION__); 591 DEBUGP("entered %s\n", __FUNCTION__);
605 592
606 if (nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr) < 0) 593 nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr);
607 goto nfattr_failure;
608 594
609 if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat)) 595 if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat))
610 goto nfattr_failure; 596 return -EINVAL;
611 597
612 npt = ip_nat_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum); 598 npt = ip_nat_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum);
613 if (!npt) 599 if (!npt)
@@ -626,9 +612,6 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
626 612
627 DEBUGP("leaving\n"); 613 DEBUGP("leaving\n");
628 return 0; 614 return 0;
629
630nfattr_failure:
631 return -1;
632} 615}
633 616
634static inline int 617static inline int
@@ -642,8 +625,7 @@ ctnetlink_parse_nat(struct nfattr *cda[],
642 625
643 memset(range, 0, sizeof(*range)); 626 memset(range, 0, sizeof(*range));
644 627
645 if (nfattr_parse_nested(tb, CTA_NAT_MAX, cda[CTA_NAT-1]) < 0) 628 nfattr_parse_nested(tb, CTA_NAT_MAX, cda[CTA_NAT-1]);
646 goto nfattr_failure;
647 629
648 if (tb[CTA_NAT_MINIP-1]) 630 if (tb[CTA_NAT_MINIP-1])
649 range->min_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MINIP-1]); 631 range->min_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MINIP-1]);
@@ -665,9 +647,6 @@ ctnetlink_parse_nat(struct nfattr *cda[],
665 647
666 DEBUGP("leaving\n"); 648 DEBUGP("leaving\n");
667 return 0; 649 return 0;
668
669nfattr_failure:
670 return -1;
671} 650}
672#endif 651#endif
673 652
@@ -678,8 +657,7 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name)
678 657
679 DEBUGP("entered %s\n", __FUNCTION__); 658 DEBUGP("entered %s\n", __FUNCTION__);
680 659
681 if (nfattr_parse_nested(tb, CTA_HELP_MAX, attr) < 0) 660 nfattr_parse_nested(tb, CTA_HELP_MAX, attr);
682 goto nfattr_failure;
683 661
684 if (!tb[CTA_HELP_NAME-1]) 662 if (!tb[CTA_HELP_NAME-1])
685 return -EINVAL; 663 return -EINVAL;
@@ -687,9 +665,6 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name)
687 *helper_name = NFA_DATA(tb[CTA_HELP_NAME-1]); 665 *helper_name = NFA_DATA(tb[CTA_HELP_NAME-1]);
688 666
689 return 0; 667 return 0;
690
691nfattr_failure:
692 return -1;
693} 668}
694 669
695static int 670static int
@@ -804,7 +779,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
804 ct = tuplehash_to_ctrack(h); 779 ct = tuplehash_to_ctrack(h);
805 780
806 err = -ENOMEM; 781 err = -ENOMEM;
807 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC); 782 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
808 if (!skb2) { 783 if (!skb2) {
809 ip_conntrack_put(ct); 784 ip_conntrack_put(ct);
810 return -ENOMEM; 785 return -ENOMEM;
@@ -827,7 +802,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
827free: 802free:
828 kfree_skb(skb2); 803 kfree_skb(skb2);
829out: 804out:
830 return -1; 805 return err;
831} 806}
832 807
833static inline int 808static inline int
@@ -957,8 +932,7 @@ ctnetlink_change_protoinfo(struct ip_conntrack *ct, struct nfattr *cda[])
957 u_int16_t npt = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum; 932 u_int16_t npt = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum;
958 int err = 0; 933 int err = 0;
959 934
960 if (nfattr_parse_nested(tb, CTA_PROTOINFO_MAX, attr) < 0) 935 nfattr_parse_nested(tb, CTA_PROTOINFO_MAX, attr);
961 goto nfattr_failure;
962 936
963 proto = ip_conntrack_proto_find_get(npt); 937 proto = ip_conntrack_proto_find_get(npt);
964 if (!proto) 938 if (!proto)
@@ -969,9 +943,6 @@ ctnetlink_change_protoinfo(struct ip_conntrack *ct, struct nfattr *cda[])
969 ip_conntrack_proto_put(proto); 943 ip_conntrack_proto_put(proto);
970 944
971 return err; 945 return err;
972
973nfattr_failure:
974 return -ENOMEM;
975} 946}
976 947
977static int 948static int
@@ -1005,6 +976,11 @@ ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[])
1005 return err; 976 return err;
1006 } 977 }
1007 978
979#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
980 if (cda[CTA_MARK-1])
981 ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
982#endif
983
1008 DEBUGP("all done\n"); 984 DEBUGP("all done\n");
1009 return 0; 985 return 0;
1010} 986}
@@ -1048,6 +1024,11 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
1048 if (ct->helper) 1024 if (ct->helper)
1049 ip_conntrack_helper_put(ct->helper); 1025 ip_conntrack_helper_put(ct->helper);
1050 1026
1027#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
1028 if (cda[CTA_MARK-1])
1029 ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
1030#endif
1031
1051 DEBUGP("conntrack with id %u inserted\n", ct->id); 1032 DEBUGP("conntrack with id %u inserted\n", ct->id);
1052 return 0; 1033 return 0;
1053 1034
@@ -1312,6 +1293,14 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
1312 if (!exp) 1293 if (!exp)
1313 return -ENOENT; 1294 return -ENOENT;
1314 1295
1296 if (cda[CTA_EXPECT_ID-1]) {
1297 u_int32_t id = *(u_int32_t *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
1298 if (exp->id != ntohl(id)) {
1299 ip_conntrack_expect_put(exp);
1300 return -ENOENT;
1301 }
1302 }
1303
1315 err = -ENOMEM; 1304 err = -ENOMEM;
1316 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 1305 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
1317 if (!skb2) 1306 if (!skb2)
@@ -1554,6 +1543,8 @@ static struct nfnetlink_subsystem ctnl_exp_subsys = {
1554 .cb = ctnl_exp_cb, 1543 .cb = ctnl_exp_cb,
1555}; 1544};
1556 1545
1546MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
1547
1557static int __init ctnetlink_init(void) 1548static int __init ctnetlink_init(void)
1558{ 1549{
1559 int ret; 1550 int ret;
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
index 98f0015dd255..5198f3a1e2cd 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
@@ -151,13 +151,13 @@ icmp_error_message(struct sk_buff *skb,
151 /* Not enough header? */ 151 /* Not enough header? */
152 inside = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_in), &_in); 152 inside = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_in), &_in);
153 if (inside == NULL) 153 if (inside == NULL)
154 return NF_ACCEPT; 154 return -NF_ACCEPT;
155 155
156 /* Ignore ICMP's containing fragments (shouldn't happen) */ 156 /* Ignore ICMP's containing fragments (shouldn't happen) */
157 if (inside->ip.frag_off & htons(IP_OFFSET)) { 157 if (inside->ip.frag_off & htons(IP_OFFSET)) {
158 DEBUGP("icmp_error_track: fragment of proto %u\n", 158 DEBUGP("icmp_error_track: fragment of proto %u\n",
159 inside->ip.protocol); 159 inside->ip.protocol);
160 return NF_ACCEPT; 160 return -NF_ACCEPT;
161 } 161 }
162 162
163 innerproto = ip_conntrack_proto_find_get(inside->ip.protocol); 163 innerproto = ip_conntrack_proto_find_get(inside->ip.protocol);
@@ -166,7 +166,7 @@ icmp_error_message(struct sk_buff *skb,
166 if (!ip_ct_get_tuple(&inside->ip, skb, dataoff, &origtuple, innerproto)) { 166 if (!ip_ct_get_tuple(&inside->ip, skb, dataoff, &origtuple, innerproto)) {
167 DEBUGP("icmp_error: ! get_tuple p=%u", inside->ip.protocol); 167 DEBUGP("icmp_error: ! get_tuple p=%u", inside->ip.protocol);
168 ip_conntrack_proto_put(innerproto); 168 ip_conntrack_proto_put(innerproto);
169 return NF_ACCEPT; 169 return -NF_ACCEPT;
170 } 170 }
171 171
172 /* Ordinarily, we'd expect the inverted tupleproto, but it's 172 /* Ordinarily, we'd expect the inverted tupleproto, but it's
@@ -174,7 +174,7 @@ icmp_error_message(struct sk_buff *skb,
174 if (!ip_ct_invert_tuple(&innertuple, &origtuple, innerproto)) { 174 if (!ip_ct_invert_tuple(&innertuple, &origtuple, innerproto)) {
175 DEBUGP("icmp_error_track: Can't invert tuple\n"); 175 DEBUGP("icmp_error_track: Can't invert tuple\n");
176 ip_conntrack_proto_put(innerproto); 176 ip_conntrack_proto_put(innerproto);
177 return NF_ACCEPT; 177 return -NF_ACCEPT;
178 } 178 }
179 ip_conntrack_proto_put(innerproto); 179 ip_conntrack_proto_put(innerproto);
180 180
@@ -190,7 +190,7 @@ icmp_error_message(struct sk_buff *skb,
190 190
191 if (!h) { 191 if (!h) {
192 DEBUGP("icmp_error_track: no match\n"); 192 DEBUGP("icmp_error_track: no match\n");
193 return NF_ACCEPT; 193 return -NF_ACCEPT;
194 } 194 }
195 /* Reverse direction from that found */ 195 /* Reverse direction from that found */
196 if (DIRECTION(h) != IP_CT_DIR_REPLY) 196 if (DIRECTION(h) != IP_CT_DIR_REPLY)
@@ -296,7 +296,8 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[],
296 struct ip_conntrack_tuple *tuple) 296 struct ip_conntrack_tuple *tuple)
297{ 297{
298 if (!tb[CTA_PROTO_ICMP_TYPE-1] 298 if (!tb[CTA_PROTO_ICMP_TYPE-1]
299 || !tb[CTA_PROTO_ICMP_CODE-1]) 299 || !tb[CTA_PROTO_ICMP_CODE-1]
300 || !tb[CTA_PROTO_ICMP_ID-1])
300 return -1; 301 return -1;
301 302
302 tuple->dst.u.icmp.type = 303 tuple->dst.u.icmp.type =
@@ -304,7 +305,7 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[],
304 tuple->dst.u.icmp.code = 305 tuple->dst.u.icmp.code =
305 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_CODE-1]); 306 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_CODE-1]);
306 tuple->src.u.icmp.id = 307 tuple->src.u.icmp.id =
307 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]); 308 *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]);
308 309
309 return 0; 310 return 0;
310} 311}
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index d6701cafbcc2..468c6003b4c7 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -362,8 +362,12 @@ static int nfattr_to_tcp(struct nfattr *cda[], struct ip_conntrack *ct)
362 struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1]; 362 struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1];
363 struct nfattr *tb[CTA_PROTOINFO_TCP_MAX]; 363 struct nfattr *tb[CTA_PROTOINFO_TCP_MAX];
364 364
365 if (nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr) < 0) 365 /* updates could not contain anything about the private
366 goto nfattr_failure; 366 * protocol info, in that case skip the parsing */
367 if (!attr)
368 return 0;
369
370 nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr);
367 371
368 if (!tb[CTA_PROTOINFO_TCP_STATE-1]) 372 if (!tb[CTA_PROTOINFO_TCP_STATE-1])
369 return -EINVAL; 373 return -EINVAL;
@@ -374,9 +378,6 @@ static int nfattr_to_tcp(struct nfattr *cda[], struct ip_conntrack *ct)
374 write_unlock_bh(&tcp_lock); 378 write_unlock_bh(&tcp_lock);
375 379
376 return 0; 380 return 0;
377
378nfattr_failure:
379 return -1;
380} 381}
381#endif 382#endif
382 383
diff --git a/net/ipv4/netfilter/ip_nat_helper_pptp.c b/net/ipv4/netfilter/ip_nat_helper_pptp.c
index ee6ab74ad3a9..e546203f5662 100644
--- a/net/ipv4/netfilter/ip_nat_helper_pptp.c
+++ b/net/ipv4/netfilter/ip_nat_helper_pptp.c
@@ -73,6 +73,7 @@ static void pptp_nat_expected(struct ip_conntrack *ct,
73 struct ip_conntrack_tuple t; 73 struct ip_conntrack_tuple t;
74 struct ip_ct_pptp_master *ct_pptp_info; 74 struct ip_ct_pptp_master *ct_pptp_info;
75 struct ip_nat_pptp *nat_pptp_info; 75 struct ip_nat_pptp *nat_pptp_info;
76 struct ip_nat_range range;
76 77
77 ct_pptp_info = &master->help.ct_pptp_info; 78 ct_pptp_info = &master->help.ct_pptp_info;
78 nat_pptp_info = &master->nat.help.nat_pptp_info; 79 nat_pptp_info = &master->nat.help.nat_pptp_info;
@@ -110,7 +111,30 @@ static void pptp_nat_expected(struct ip_conntrack *ct,
110 DEBUGP("not found!\n"); 111 DEBUGP("not found!\n");
111 } 112 }
112 113
113 ip_nat_follow_master(ct, exp); 114 /* This must be a fresh one. */
115 BUG_ON(ct->status & IPS_NAT_DONE_MASK);
116
117 /* Change src to where master sends to */
118 range.flags = IP_NAT_RANGE_MAP_IPS;
119 range.min_ip = range.max_ip
120 = ct->master->tuplehash[!exp->dir].tuple.dst.ip;
121 if (exp->dir == IP_CT_DIR_ORIGINAL) {
122 range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
123 range.min = range.max = exp->saved_proto;
124 }
125 /* hook doesn't matter, but it has to do source manip */
126 ip_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
127
128 /* For DST manip, map port here to where it's expected. */
129 range.flags = IP_NAT_RANGE_MAP_IPS;
130 range.min_ip = range.max_ip
131 = ct->master->tuplehash[!exp->dir].tuple.src.ip;
132 if (exp->dir == IP_CT_DIR_REPLY) {
133 range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
134 range.min = range.max = exp->saved_proto;
135 }
136 /* hook doesn't matter, but it has to do destination manip */
137 ip_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
114} 138}
115 139
116/* outbound packets == from PNS to PAC */ 140/* outbound packets == from PNS to PAC */
@@ -213,7 +237,7 @@ pptp_exp_gre(struct ip_conntrack_expect *expect_orig,
213 237
214 /* alter expectation for PNS->PAC direction */ 238 /* alter expectation for PNS->PAC direction */
215 invert_tuplepr(&inv_t, &expect_orig->tuple); 239 invert_tuplepr(&inv_t, &expect_orig->tuple);
216 expect_orig->saved_proto.gre.key = htons(nat_pptp_info->pac_call_id); 240 expect_orig->saved_proto.gre.key = htons(ct_pptp_info->pns_call_id);
217 expect_orig->tuple.src.u.gre.key = htons(nat_pptp_info->pns_call_id); 241 expect_orig->tuple.src.u.gre.key = htons(nat_pptp_info->pns_call_id);
218 expect_orig->tuple.dst.u.gre.key = htons(ct_pptp_info->pac_call_id); 242 expect_orig->tuple.dst.u.gre.key = htons(ct_pptp_info->pac_call_id);
219 expect_orig->dir = IP_CT_DIR_ORIGINAL; 243 expect_orig->dir = IP_CT_DIR_ORIGINAL;
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index b7a5f51238b3..ddcf7754eec2 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1022,6 +1022,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev,
1022 continue; 1022 continue;
1023 } 1023 }
1024 1024
1025#ifdef CONFIG_IPV6_PRIVACY
1025 /* Rule 7: Prefer public address 1026 /* Rule 7: Prefer public address
1026 * Note: prefer temprary address if use_tempaddr >= 2 1027 * Note: prefer temprary address if use_tempaddr >= 2
1027 */ 1028 */
@@ -1042,7 +1043,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev,
1042 if (hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY) 1043 if (hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY)
1043 continue; 1044 continue;
1044 } 1045 }
1045 1046#endif
1046 /* Rule 8: Use longest matching prefix */ 1047 /* Rule 8: Use longest matching prefix */
1047 if (hiscore.rule < 8) 1048 if (hiscore.rule < 8)
1048 hiscore.matchlen = ipv6_addr_diff(&ifa_result->addr, daddr); 1049 hiscore.matchlen = ipv6_addr_diff(&ifa_result->addr, daddr);
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index e6b0e3954c02..e315d0f80af1 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -525,6 +525,7 @@ ip6ip6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
525 525
526 if ((t = ip6ip6_tnl_lookup(&ipv6h->saddr, &ipv6h->daddr)) != NULL) { 526 if ((t = ip6ip6_tnl_lookup(&ipv6h->saddr, &ipv6h->daddr)) != NULL) {
527 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { 527 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
528 read_unlock(&ip6ip6_lock);
528 kfree_skb(skb); 529 kfree_skb(skb);
529 return 0; 530 return 0;
530 } 531 }
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 4bc27a6334c1..83f4c53030fc 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -128,7 +128,7 @@ void __nfa_fill(struct sk_buff *skb, int attrtype, int attrlen,
128 memset(NFA_DATA(nfa) + attrlen, 0, NFA_ALIGN(size) - size); 128 memset(NFA_DATA(nfa) + attrlen, 0, NFA_ALIGN(size) - size);
129} 129}
130 130
131int nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len) 131void nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len)
132{ 132{
133 memset(tb, 0, sizeof(struct nfattr *) * maxattr); 133 memset(tb, 0, sizeof(struct nfattr *) * maxattr);
134 134
@@ -138,8 +138,6 @@ int nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len)
138 tb[flavor-1] = nfa; 138 tb[flavor-1] = nfa;
139 nfa = NFA_NEXT(nfa, len); 139 nfa = NFA_NEXT(nfa, len);
140 } 140 }
141
142 return 0;
143} 141}
144 142
145/** 143/**
@@ -242,15 +240,18 @@ static inline int nfnetlink_rcv_msg(struct sk_buff *skb,
242 ss = nfnetlink_get_subsys(type); 240 ss = nfnetlink_get_subsys(type);
243 if (!ss) { 241 if (!ss) {
244#ifdef CONFIG_KMOD 242#ifdef CONFIG_KMOD
245 /* don't call nfnl_shunlock, since it would reenter 243 if (cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) {
246 * with further packet processing */ 244 /* don't call nfnl_shunlock, since it would reenter
247 up(&nfnl_sem); 245 * with further packet processing */
248 request_module("nfnetlink-subsys-%d", NFNL_SUBSYS_ID(type)); 246 up(&nfnl_sem);
249 nfnl_shlock(); 247 request_module("nfnetlink-subsys-%d",
250 ss = nfnetlink_get_subsys(type); 248 NFNL_SUBSYS_ID(type));
249 nfnl_shlock();
250 ss = nfnetlink_get_subsys(type);
251 }
251 if (!ss) 252 if (!ss)
252#endif 253#endif
253 goto err_inval; 254 goto err_inval;
254 } 255 }
255 256
256 nc = nfnetlink_find_client(type, ss); 257 nc = nfnetlink_find_client(type, ss);