aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/Makefile2
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netlink.c66
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_tcp.c8
-rw-r--r--net/ipv6/netfilter/Kconfig50
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c8
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c50
-rw-r--r--net/ipv6/route.c8
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c7
-rw-r--r--net/netfilter/nfnetlink.c28
-rw-r--r--net/netfilter/nfnetlink_log.c6
-rw-r--r--net/netfilter/nfnetlink_queue.c9
11 files changed, 134 insertions, 108 deletions
diff --git a/net/Makefile b/net/Makefile
index 4aa2f46d2a56..f5141b9d4f38 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -15,8 +15,8 @@ obj-$(CONFIG_NET) += $(tmp-y)
15# LLC has to be linked before the files in net/802/ 15# LLC has to be linked before the files in net/802/
16obj-$(CONFIG_LLC) += llc/ 16obj-$(CONFIG_LLC) += llc/
17obj-$(CONFIG_NET) += ethernet/ 802/ sched/ netlink/ 17obj-$(CONFIG_NET) += ethernet/ 802/ sched/ netlink/
18obj-$(CONFIG_INET) += ipv4/
19obj-$(CONFIG_NETFILTER) += netfilter/ 18obj-$(CONFIG_NETFILTER) += netfilter/
19obj-$(CONFIG_INET) += ipv4/
20obj-$(CONFIG_XFRM) += xfrm/ 20obj-$(CONFIG_XFRM) += xfrm/
21obj-$(CONFIG_UNIX) += unix/ 21obj-$(CONFIG_UNIX) += unix/
22ifneq ($(CONFIG_IPV6),) 22ifneq ($(CONFIG_IPV6),)
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index d2a4fec22862..de9f4464438d 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -467,7 +467,7 @@ out:
467} 467}
468#endif 468#endif
469 469
470static const int cta_min_ip[CTA_IP_MAX] = { 470static const size_t cta_min_ip[CTA_IP_MAX] = {
471 [CTA_IP_V4_SRC-1] = sizeof(u_int32_t), 471 [CTA_IP_V4_SRC-1] = sizeof(u_int32_t),
472 [CTA_IP_V4_DST-1] = sizeof(u_int32_t), 472 [CTA_IP_V4_DST-1] = sizeof(u_int32_t),
473}; 473};
@@ -497,7 +497,7 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct ip_conntrack_tuple *tuple)
497 return 0; 497 return 0;
498} 498}
499 499
500static const int cta_min_proto[CTA_PROTO_MAX] = { 500static const size_t cta_min_proto[CTA_PROTO_MAX] = {
501 [CTA_PROTO_NUM-1] = sizeof(u_int16_t), 501 [CTA_PROTO_NUM-1] = sizeof(u_int16_t),
502 [CTA_PROTO_SRC_PORT-1] = sizeof(u_int16_t), 502 [CTA_PROTO_SRC_PORT-1] = sizeof(u_int16_t),
503 [CTA_PROTO_DST_PORT-1] = sizeof(u_int16_t), 503 [CTA_PROTO_DST_PORT-1] = sizeof(u_int16_t),
@@ -576,7 +576,7 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct ip_conntrack_tuple *tuple,
576} 576}
577 577
578#ifdef CONFIG_IP_NF_NAT_NEEDED 578#ifdef CONFIG_IP_NF_NAT_NEEDED
579static const int cta_min_protonat[CTA_PROTONAT_MAX] = { 579static const size_t cta_min_protonat[CTA_PROTONAT_MAX] = {
580 [CTA_PROTONAT_PORT_MIN-1] = sizeof(u_int16_t), 580 [CTA_PROTONAT_PORT_MIN-1] = sizeof(u_int16_t),
581 [CTA_PROTONAT_PORT_MAX-1] = sizeof(u_int16_t), 581 [CTA_PROTONAT_PORT_MAX-1] = sizeof(u_int16_t),
582}; 582};
@@ -614,6 +614,11 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
614 return 0; 614 return 0;
615} 615}
616 616
617static const size_t cta_min_nat[CTA_NAT_MAX] = {
618 [CTA_NAT_MINIP-1] = sizeof(u_int32_t),
619 [CTA_NAT_MAXIP-1] = sizeof(u_int32_t),
620};
621
617static inline int 622static inline int
618ctnetlink_parse_nat(struct nfattr *cda[], 623ctnetlink_parse_nat(struct nfattr *cda[],
619 const struct ip_conntrack *ct, struct ip_nat_range *range) 624 const struct ip_conntrack *ct, struct ip_nat_range *range)
@@ -627,6 +632,9 @@ ctnetlink_parse_nat(struct nfattr *cda[],
627 632
628 nfattr_parse_nested(tb, CTA_NAT_MAX, cda[CTA_NAT-1]); 633 nfattr_parse_nested(tb, CTA_NAT_MAX, cda[CTA_NAT-1]);
629 634
635 if (nfattr_bad_size(tb, CTA_NAT_MAX, cta_min_nat))
636 return -EINVAL;
637
630 if (tb[CTA_NAT_MINIP-1]) 638 if (tb[CTA_NAT_MINIP-1])
631 range->min_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MINIP-1]); 639 range->min_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MINIP-1]);
632 640
@@ -667,6 +675,14 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name)
667 return 0; 675 return 0;
668} 676}
669 677
678static const size_t cta_min[CTA_MAX] = {
679 [CTA_STATUS-1] = sizeof(u_int32_t),
680 [CTA_TIMEOUT-1] = sizeof(u_int32_t),
681 [CTA_MARK-1] = sizeof(u_int32_t),
682 [CTA_USE-1] = sizeof(u_int32_t),
683 [CTA_ID-1] = sizeof(u_int32_t)
684};
685
670static int 686static int
671ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, 687ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
672 struct nlmsghdr *nlh, struct nfattr *cda[], int *errp) 688 struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
@@ -678,6 +694,9 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
678 694
679 DEBUGP("entered %s\n", __FUNCTION__); 695 DEBUGP("entered %s\n", __FUNCTION__);
680 696
697 if (nfattr_bad_size(cda, CTA_MAX, cta_min))
698 return -EINVAL;
699
681 if (cda[CTA_TUPLE_ORIG-1]) 700 if (cda[CTA_TUPLE_ORIG-1])
682 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG); 701 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG);
683 else if (cda[CTA_TUPLE_REPLY-1]) 702 else if (cda[CTA_TUPLE_REPLY-1])
@@ -760,6 +779,9 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
760 return 0; 779 return 0;
761 } 780 }
762 781
782 if (nfattr_bad_size(cda, CTA_MAX, cta_min))
783 return -EINVAL;
784
763 if (cda[CTA_TUPLE_ORIG-1]) 785 if (cda[CTA_TUPLE_ORIG-1])
764 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG); 786 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG);
765 else if (cda[CTA_TUPLE_REPLY-1]) 787 else if (cda[CTA_TUPLE_REPLY-1])
@@ -1047,6 +1069,9 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
1047 1069
1048 DEBUGP("entered %s\n", __FUNCTION__); 1070 DEBUGP("entered %s\n", __FUNCTION__);
1049 1071
1072 if (nfattr_bad_size(cda, CTA_MAX, cta_min))
1073 return -EINVAL;
1074
1050 if (cda[CTA_TUPLE_ORIG-1]) { 1075 if (cda[CTA_TUPLE_ORIG-1]) {
1051 err = ctnetlink_parse_tuple(cda, &otuple, CTA_TUPLE_ORIG); 1076 err = ctnetlink_parse_tuple(cda, &otuple, CTA_TUPLE_ORIG);
1052 if (err < 0) 1077 if (err < 0)
@@ -1252,6 +1277,11 @@ out:
1252 return skb->len; 1277 return skb->len;
1253} 1278}
1254 1279
1280static const size_t cta_min_exp[CTA_EXPECT_MAX] = {
1281 [CTA_EXPECT_TIMEOUT-1] = sizeof(u_int32_t),
1282 [CTA_EXPECT_ID-1] = sizeof(u_int32_t)
1283};
1284
1255static int 1285static int
1256ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, 1286ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
1257 struct nlmsghdr *nlh, struct nfattr *cda[], int *errp) 1287 struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
@@ -1263,6 +1293,9 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
1263 1293
1264 DEBUGP("entered %s\n", __FUNCTION__); 1294 DEBUGP("entered %s\n", __FUNCTION__);
1265 1295
1296 if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
1297 return -EINVAL;
1298
1266 if (nlh->nlmsg_flags & NLM_F_DUMP) { 1299 if (nlh->nlmsg_flags & NLM_F_DUMP) {
1267 struct nfgenmsg *msg = NLMSG_DATA(nlh); 1300 struct nfgenmsg *msg = NLMSG_DATA(nlh);
1268 u32 rlen; 1301 u32 rlen;
@@ -1333,6 +1366,9 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1333 struct ip_conntrack_helper *h; 1366 struct ip_conntrack_helper *h;
1334 int err; 1367 int err;
1335 1368
1369 if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
1370 return -EINVAL;
1371
1336 if (cda[CTA_EXPECT_TUPLE-1]) { 1372 if (cda[CTA_EXPECT_TUPLE-1]) {
1337 /* delete a single expect by tuple */ 1373 /* delete a single expect by tuple */
1338 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE); 1374 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE);
@@ -1462,6 +1498,9 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
1462 1498
1463 DEBUGP("entered %s\n", __FUNCTION__); 1499 DEBUGP("entered %s\n", __FUNCTION__);
1464 1500
1501 if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
1502 return -EINVAL;
1503
1465 if (!cda[CTA_EXPECT_TUPLE-1] 1504 if (!cda[CTA_EXPECT_TUPLE-1]
1466 || !cda[CTA_EXPECT_MASK-1] 1505 || !cda[CTA_EXPECT_MASK-1]
1467 || !cda[CTA_EXPECT_MASTER-1]) 1506 || !cda[CTA_EXPECT_MASTER-1])
@@ -1504,29 +1543,22 @@ static struct notifier_block ctnl_notifier_exp = {
1504 1543
1505static struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = { 1544static struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = {
1506 [IPCTNL_MSG_CT_NEW] = { .call = ctnetlink_new_conntrack, 1545 [IPCTNL_MSG_CT_NEW] = { .call = ctnetlink_new_conntrack,
1507 .attr_count = CTA_MAX, 1546 .attr_count = CTA_MAX, },
1508 .cap_required = CAP_NET_ADMIN },
1509 [IPCTNL_MSG_CT_GET] = { .call = ctnetlink_get_conntrack, 1547 [IPCTNL_MSG_CT_GET] = { .call = ctnetlink_get_conntrack,
1510 .attr_count = CTA_MAX, 1548 .attr_count = CTA_MAX, },
1511 .cap_required = CAP_NET_ADMIN },
1512 [IPCTNL_MSG_CT_DELETE] = { .call = ctnetlink_del_conntrack, 1549 [IPCTNL_MSG_CT_DELETE] = { .call = ctnetlink_del_conntrack,
1513 .attr_count = CTA_MAX, 1550 .attr_count = CTA_MAX, },
1514 .cap_required = CAP_NET_ADMIN },
1515 [IPCTNL_MSG_CT_GET_CTRZERO] = { .call = ctnetlink_get_conntrack, 1551 [IPCTNL_MSG_CT_GET_CTRZERO] = { .call = ctnetlink_get_conntrack,
1516 .attr_count = CTA_MAX, 1552 .attr_count = CTA_MAX, },
1517 .cap_required = CAP_NET_ADMIN },
1518}; 1553};
1519 1554
1520static struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_EXP_MAX] = { 1555static struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_EXP_MAX] = {
1521 [IPCTNL_MSG_EXP_GET] = { .call = ctnetlink_get_expect, 1556 [IPCTNL_MSG_EXP_GET] = { .call = ctnetlink_get_expect,
1522 .attr_count = CTA_EXPECT_MAX, 1557 .attr_count = CTA_EXPECT_MAX, },
1523 .cap_required = CAP_NET_ADMIN },
1524 [IPCTNL_MSG_EXP_NEW] = { .call = ctnetlink_new_expect, 1558 [IPCTNL_MSG_EXP_NEW] = { .call = ctnetlink_new_expect,
1525 .attr_count = CTA_EXPECT_MAX, 1559 .attr_count = CTA_EXPECT_MAX, },
1526 .cap_required = CAP_NET_ADMIN },
1527 [IPCTNL_MSG_EXP_DELETE] = { .call = ctnetlink_del_expect, 1560 [IPCTNL_MSG_EXP_DELETE] = { .call = ctnetlink_del_expect,
1528 .attr_count = CTA_EXPECT_MAX, 1561 .attr_count = CTA_EXPECT_MAX, },
1529 .cap_required = CAP_NET_ADMIN },
1530}; 1562};
1531 1563
1532static struct nfnetlink_subsystem ctnl_subsys = { 1564static struct nfnetlink_subsystem ctnl_subsys = {
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index 468c6003b4c7..ee3b7d6c4d2e 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -357,6 +357,10 @@ nfattr_failure:
357 return -1; 357 return -1;
358} 358}
359 359
360static const size_t cta_min_tcp[CTA_PROTOINFO_TCP_MAX] = {
361 [CTA_PROTOINFO_TCP_STATE-1] = sizeof(u_int8_t),
362};
363
360static int nfattr_to_tcp(struct nfattr *cda[], struct ip_conntrack *ct) 364static int nfattr_to_tcp(struct nfattr *cda[], struct ip_conntrack *ct)
361{ 365{
362 struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1]; 366 struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1];
@@ -369,6 +373,9 @@ static int nfattr_to_tcp(struct nfattr *cda[], struct ip_conntrack *ct)
369 373
370 nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr); 374 nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr);
371 375
376 if (nfattr_bad_size(tb, CTA_PROTOINFO_TCP_MAX, cta_min_tcp))
377 return -EINVAL;
378
372 if (!tb[CTA_PROTOINFO_TCP_STATE-1]) 379 if (!tb[CTA_PROTOINFO_TCP_STATE-1])
373 return -EINVAL; 380 return -EINVAL;
374 381
@@ -814,6 +821,7 @@ static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] =
814{ 821{
815 [TH_SYN] = 1, 822 [TH_SYN] = 1,
816 [TH_SYN|TH_ACK] = 1, 823 [TH_SYN|TH_ACK] = 1,
824 [TH_SYN|TH_PUSH] = 1,
817 [TH_SYN|TH_ACK|TH_PUSH] = 1, 825 [TH_SYN|TH_ACK|TH_PUSH] = 1,
818 [TH_RST] = 1, 826 [TH_RST] = 1,
819 [TH_RST|TH_ACK] = 1, 827 [TH_RST|TH_ACK] = 1,
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 971ba60bf6e9..060d61202412 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -5,10 +5,20 @@
5menu "IPv6: Netfilter Configuration (EXPERIMENTAL)" 5menu "IPv6: Netfilter Configuration (EXPERIMENTAL)"
6 depends on INET && IPV6 && NETFILTER && EXPERIMENTAL 6 depends on INET && IPV6 && NETFILTER && EXPERIMENTAL
7 7
8#tristate 'Connection tracking (required for masq/NAT)' CONFIG_IP6_NF_CONNTRACK 8config NF_CONNTRACK_IPV6
9#if [ "$CONFIG_IP6_NF_CONNTRACK" != "n" ]; then 9 tristate "IPv6 support for new connection tracking (EXPERIMENTAL)"
10# dep_tristate ' FTP protocol support' CONFIG_IP6_NF_FTP $CONFIG_IP6_NF_CONNTRACK 10 depends on EXPERIMENTAL && NF_CONNTRACK
11#fi 11 ---help---
12 Connection tracking keeps a record of what packets have passed
13 through your machine, in order to figure out how they are related
14 into connections.
15
16 This is IPv6 support on Layer 3 independent connection tracking.
17 Layer 3 independent connection tracking is experimental scheme
18 which generalize ip_conntrack to support other layer 3 protocols.
19
20 To compile it as a module, choose M here. If unsure, say N.
21
12config IP6_NF_QUEUE 22config IP6_NF_QUEUE
13 tristate "IP6 Userspace queueing via NETLINK (OBSOLETE)" 23 tristate "IP6 Userspace queueing via NETLINK (OBSOLETE)"
14 ---help--- 24 ---help---
@@ -114,7 +124,6 @@ config IP6_NF_MATCH_OWNER
114 124
115 To compile it as a module, choose M here. If unsure, say N. 125 To compile it as a module, choose M here. If unsure, say N.
116 126
117# dep_tristate ' MAC address match support' CONFIG_IP6_NF_MATCH_MAC $CONFIG_IP6_NF_IPTABLES
118config IP6_NF_MATCH_MARK 127config IP6_NF_MATCH_MARK
119 tristate "netfilter MARK match support" 128 tristate "netfilter MARK match support"
120 depends on IP6_NF_IPTABLES 129 depends on IP6_NF_IPTABLES
@@ -170,15 +179,6 @@ config IP6_NF_MATCH_PHYSDEV
170 179
171 To compile it as a module, choose M here. If unsure, say N. 180 To compile it as a module, choose M here. If unsure, say N.
172 181
173# dep_tristate ' Multiple port match support' CONFIG_IP6_NF_MATCH_MULTIPORT $CONFIG_IP6_NF_IPTABLES
174# dep_tristate ' TOS match support' CONFIG_IP6_NF_MATCH_TOS $CONFIG_IP6_NF_IPTABLES
175# if [ "$CONFIG_IP6_NF_CONNTRACK" != "n" ]; then
176# dep_tristate ' Connection state match support' CONFIG_IP6_NF_MATCH_STATE $CONFIG_IP6_NF_CONNTRACK $CONFIG_IP6_NF_IPTABLES
177# fi
178# if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
179# dep_tristate ' Unclean match support (EXPERIMENTAL)' CONFIG_IP6_NF_MATCH_UNCLEAN $CONFIG_IP6_NF_IPTABLES
180# dep_tristate ' Owner match support (EXPERIMENTAL)' CONFIG_IP6_NF_MATCH_OWNER $CONFIG_IP6_NF_IPTABLES
181# fi
182# The targets 182# The targets
183config IP6_NF_FILTER 183config IP6_NF_FILTER
184 tristate "Packet filtering" 184 tristate "Packet filtering"
@@ -220,12 +220,6 @@ config IP6_NF_TARGET_NFQUEUE
220 220
221 To compile it as a module, choose M here. If unsure, say N. 221 To compile it as a module, choose M here. If unsure, say N.
222 222
223# if [ "$CONFIG_IP6_NF_FILTER" != "n" ]; then
224# dep_tristate ' REJECT target support' CONFIG_IP6_NF_TARGET_REJECT $CONFIG_IP6_NF_FILTER
225# if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
226# dep_tristate ' MIRROR target support (EXPERIMENTAL)' CONFIG_IP6_NF_TARGET_MIRROR $CONFIG_IP6_NF_FILTER
227# fi
228# fi
229config IP6_NF_MANGLE 223config IP6_NF_MANGLE
230 tristate "Packet mangling" 224 tristate "Packet mangling"
231 depends on IP6_NF_IPTABLES 225 depends on IP6_NF_IPTABLES
@@ -236,7 +230,6 @@ config IP6_NF_MANGLE
236 230
237 To compile it as a module, choose M here. If unsure, say N. 231 To compile it as a module, choose M here. If unsure, say N.
238 232
239# dep_tristate ' TOS target support' CONFIG_IP6_NF_TARGET_TOS $CONFIG_IP_NF_MANGLE
240config IP6_NF_TARGET_MARK 233config IP6_NF_TARGET_MARK
241 tristate "MARK target support" 234 tristate "MARK target support"
242 depends on IP6_NF_MANGLE 235 depends on IP6_NF_MANGLE
@@ -266,7 +259,6 @@ config IP6_NF_TARGET_HL
266 259
267 To compile it as a module, choose M here. If unsure, say N. 260 To compile it as a module, choose M here. If unsure, say N.
268 261
269#dep_tristate ' LOG target support' CONFIG_IP6_NF_TARGET_LOG $CONFIG_IP6_NF_IPTABLES
270config IP6_NF_RAW 262config IP6_NF_RAW
271 tristate 'raw table support (required for TRACE)' 263 tristate 'raw table support (required for TRACE)'
272 depends on IP6_NF_IPTABLES 264 depends on IP6_NF_IPTABLES
@@ -278,19 +270,5 @@ config IP6_NF_RAW
278 If you want to compile it as a module, say M here and read 270 If you want to compile it as a module, say M here and read
279 <file:Documentation/modules.txt>. If unsure, say `N'. 271 <file:Documentation/modules.txt>. If unsure, say `N'.
280 272
281config NF_CONNTRACK_IPV6
282 tristate "IPv6 support for new connection tracking (EXPERIMENTAL)"
283 depends on EXPERIMENTAL && NF_CONNTRACK
284 ---help---
285 Connection tracking keeps a record of what packets have passed
286 through your machine, in order to figure out how they are related
287 into connections.
288
289 This is IPv6 support on Layer 3 independent connection tracking.
290 Layer 3 independent connection tracking is experimental scheme
291 which generalize ip_conntrack to support other layer 3 protocols.
292
293 To compile it as a module, choose M here. If unsure, say N.
294
295endmenu 273endmenu
296 274
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index e2c90b3a8074..753a3ae8502b 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -339,8 +339,8 @@ extern unsigned long nf_ct_icmpv6_timeout;
339 339
340/* From nf_conntrack_frag6.c */ 340/* From nf_conntrack_frag6.c */
341extern unsigned long nf_ct_frag6_timeout; 341extern unsigned long nf_ct_frag6_timeout;
342extern unsigned long nf_ct_frag6_low_thresh; 342extern unsigned int nf_ct_frag6_low_thresh;
343extern unsigned long nf_ct_frag6_high_thresh; 343extern unsigned int nf_ct_frag6_high_thresh;
344 344
345static struct ctl_table_header *nf_ct_ipv6_sysctl_header; 345static struct ctl_table_header *nf_ct_ipv6_sysctl_header;
346 346
@@ -367,7 +367,7 @@ static ctl_table nf_ct_sysctl_table[] = {
367 .data = &nf_ct_frag6_low_thresh, 367 .data = &nf_ct_frag6_low_thresh,
368 .maxlen = sizeof(unsigned int), 368 .maxlen = sizeof(unsigned int),
369 .mode = 0644, 369 .mode = 0644,
370 .proc_handler = &proc_dointvec_jiffies, 370 .proc_handler = &proc_dointvec,
371 }, 371 },
372 { 372 {
373 .ctl_name = NET_NF_CONNTRACK_FRAG6_HIGH_THRESH, 373 .ctl_name = NET_NF_CONNTRACK_FRAG6_HIGH_THRESH,
@@ -375,7 +375,7 @@ static ctl_table nf_ct_sysctl_table[] = {
375 .data = &nf_ct_frag6_high_thresh, 375 .data = &nf_ct_frag6_high_thresh,
376 .maxlen = sizeof(unsigned int), 376 .maxlen = sizeof(unsigned int),
377 .mode = 0644, 377 .mode = 0644,
378 .proc_handler = &proc_dointvec_jiffies, 378 .proc_handler = &proc_dointvec,
379 }, 379 },
380 { .ctl_name = 0 } 380 { .ctl_name = 0 }
381}; 381};
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 7640b9bb7694..c2c52af9e560 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -55,9 +55,9 @@
55#define NF_CT_FRAG6_LOW_THRESH 196608 /* == 192*1024 */ 55#define NF_CT_FRAG6_LOW_THRESH 196608 /* == 192*1024 */
56#define NF_CT_FRAG6_TIMEOUT IPV6_FRAG_TIMEOUT 56#define NF_CT_FRAG6_TIMEOUT IPV6_FRAG_TIMEOUT
57 57
58int nf_ct_frag6_high_thresh = 256*1024; 58unsigned int nf_ct_frag6_high_thresh = 256*1024;
59int nf_ct_frag6_low_thresh = 192*1024; 59unsigned int nf_ct_frag6_low_thresh = 192*1024;
60int nf_ct_frag6_timeout = IPV6_FRAG_TIMEOUT; 60unsigned long nf_ct_frag6_timeout = IPV6_FRAG_TIMEOUT;
61 61
62struct nf_ct_frag6_skb_cb 62struct nf_ct_frag6_skb_cb
63{ 63{
@@ -190,8 +190,10 @@ static void nf_ct_frag6_secret_rebuild(unsigned long dummy)
190atomic_t nf_ct_frag6_mem = ATOMIC_INIT(0); 190atomic_t nf_ct_frag6_mem = ATOMIC_INIT(0);
191 191
192/* Memory Tracking Functions. */ 192/* Memory Tracking Functions. */
193static inline void frag_kfree_skb(struct sk_buff *skb) 193static inline void frag_kfree_skb(struct sk_buff *skb, unsigned int *work)
194{ 194{
195 if (work)
196 *work -= skb->truesize;
195 atomic_sub(skb->truesize, &nf_ct_frag6_mem); 197 atomic_sub(skb->truesize, &nf_ct_frag6_mem);
196 if (NFCT_FRAG6_CB(skb)->orig) 198 if (NFCT_FRAG6_CB(skb)->orig)
197 kfree_skb(NFCT_FRAG6_CB(skb)->orig); 199 kfree_skb(NFCT_FRAG6_CB(skb)->orig);
@@ -199,8 +201,11 @@ static inline void frag_kfree_skb(struct sk_buff *skb)
199 kfree_skb(skb); 201 kfree_skb(skb);
200} 202}
201 203
202static inline void frag_free_queue(struct nf_ct_frag6_queue *fq) 204static inline void frag_free_queue(struct nf_ct_frag6_queue *fq,
205 unsigned int *work)
203{ 206{
207 if (work)
208 *work -= sizeof(struct nf_ct_frag6_queue);
204 atomic_sub(sizeof(struct nf_ct_frag6_queue), &nf_ct_frag6_mem); 209 atomic_sub(sizeof(struct nf_ct_frag6_queue), &nf_ct_frag6_mem);
205 kfree(fq); 210 kfree(fq);
206} 211}
@@ -218,7 +223,8 @@ static inline struct nf_ct_frag6_queue *frag_alloc_queue(void)
218/* Destruction primitives. */ 223/* Destruction primitives. */
219 224
220/* Complete destruction of fq. */ 225/* Complete destruction of fq. */
221static void nf_ct_frag6_destroy(struct nf_ct_frag6_queue *fq) 226static void nf_ct_frag6_destroy(struct nf_ct_frag6_queue *fq,
227 unsigned int *work)
222{ 228{
223 struct sk_buff *fp; 229 struct sk_buff *fp;
224 230
@@ -230,17 +236,17 @@ static void nf_ct_frag6_destroy(struct nf_ct_frag6_queue *fq)
230 while (fp) { 236 while (fp) {
231 struct sk_buff *xp = fp->next; 237 struct sk_buff *xp = fp->next;
232 238
233 frag_kfree_skb(fp); 239 frag_kfree_skb(fp, work);
234 fp = xp; 240 fp = xp;
235 } 241 }
236 242
237 frag_free_queue(fq); 243 frag_free_queue(fq, work);
238} 244}
239 245
240static __inline__ void fq_put(struct nf_ct_frag6_queue *fq) 246static __inline__ void fq_put(struct nf_ct_frag6_queue *fq, unsigned int *work)
241{ 247{
242 if (atomic_dec_and_test(&fq->refcnt)) 248 if (atomic_dec_and_test(&fq->refcnt))
243 nf_ct_frag6_destroy(fq); 249 nf_ct_frag6_destroy(fq, work);
244} 250}
245 251
246/* Kill fq entry. It is not destroyed immediately, 252/* Kill fq entry. It is not destroyed immediately,
@@ -262,16 +268,21 @@ static void nf_ct_frag6_evictor(void)
262{ 268{
263 struct nf_ct_frag6_queue *fq; 269 struct nf_ct_frag6_queue *fq;
264 struct list_head *tmp; 270 struct list_head *tmp;
271 unsigned int work;
265 272
266 for (;;) { 273 work = atomic_read(&nf_ct_frag6_mem);
267 if (atomic_read(&nf_ct_frag6_mem) <= nf_ct_frag6_low_thresh) 274 if (work <= nf_ct_frag6_low_thresh)
268 return; 275 return;
276
277 work -= nf_ct_frag6_low_thresh;
278 while (work > 0) {
269 read_lock(&nf_ct_frag6_lock); 279 read_lock(&nf_ct_frag6_lock);
270 if (list_empty(&nf_ct_frag6_lru_list)) { 280 if (list_empty(&nf_ct_frag6_lru_list)) {
271 read_unlock(&nf_ct_frag6_lock); 281 read_unlock(&nf_ct_frag6_lock);
272 return; 282 return;
273 } 283 }
274 tmp = nf_ct_frag6_lru_list.next; 284 tmp = nf_ct_frag6_lru_list.next;
285 BUG_ON(tmp == NULL);
275 fq = list_entry(tmp, struct nf_ct_frag6_queue, lru_list); 286 fq = list_entry(tmp, struct nf_ct_frag6_queue, lru_list);
276 atomic_inc(&fq->refcnt); 287 atomic_inc(&fq->refcnt);
277 read_unlock(&nf_ct_frag6_lock); 288 read_unlock(&nf_ct_frag6_lock);
@@ -281,7 +292,7 @@ static void nf_ct_frag6_evictor(void)
281 fq_kill(fq); 292 fq_kill(fq);
282 spin_unlock(&fq->lock); 293 spin_unlock(&fq->lock);
283 294
284 fq_put(fq); 295 fq_put(fq, &work);
285 } 296 }
286} 297}
287 298
@@ -298,7 +309,7 @@ static void nf_ct_frag6_expire(unsigned long data)
298 309
299out: 310out:
300 spin_unlock(&fq->lock); 311 spin_unlock(&fq->lock);
301 fq_put(fq); 312 fq_put(fq, NULL);
302} 313}
303 314
304/* Creation primitives. */ 315/* Creation primitives. */
@@ -318,7 +329,7 @@ static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash,
318 atomic_inc(&fq->refcnt); 329 atomic_inc(&fq->refcnt);
319 write_unlock(&nf_ct_frag6_lock); 330 write_unlock(&nf_ct_frag6_lock);
320 fq_in->last_in |= COMPLETE; 331 fq_in->last_in |= COMPLETE;
321 fq_put(fq_in); 332 fq_put(fq_in, NULL);
322 return fq; 333 return fq;
323 } 334 }
324 } 335 }
@@ -535,7 +546,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
535 fq->fragments = next; 546 fq->fragments = next;
536 547
537 fq->meat -= free_it->len; 548 fq->meat -= free_it->len;
538 frag_kfree_skb(free_it); 549 frag_kfree_skb(free_it, NULL);
539 } 550 }
540 } 551 }
541 552
@@ -811,7 +822,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
811 if (nf_ct_frag6_queue(fq, clone, fhdr, nhoff) < 0) { 822 if (nf_ct_frag6_queue(fq, clone, fhdr, nhoff) < 0) {
812 spin_unlock(&fq->lock); 823 spin_unlock(&fq->lock);
813 DEBUGP("Can't insert skb to queue\n"); 824 DEBUGP("Can't insert skb to queue\n");
814 fq_put(fq); 825 fq_put(fq, NULL);
815 goto ret_orig; 826 goto ret_orig;
816 } 827 }
817 828
@@ -822,7 +833,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
822 } 833 }
823 spin_unlock(&fq->lock); 834 spin_unlock(&fq->lock);
824 835
825 fq_put(fq); 836 fq_put(fq, NULL);
826 return ret_skb; 837 return ret_skb;
827 838
828ret_orig: 839ret_orig:
@@ -881,5 +892,6 @@ int nf_ct_frag6_init(void)
881void nf_ct_frag6_cleanup(void) 892void nf_ct_frag6_cleanup(void)
882{ 893{
883 del_timer(&nf_ct_frag6_secret_timer); 894 del_timer(&nf_ct_frag6_secret_timer);
895 nf_ct_frag6_low_thresh = 0;
884 nf_ct_frag6_evictor(); 896 nf_ct_frag6_evictor();
885} 897}
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index f7f42c3e96cb..9a71a8d1078a 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1701,10 +1701,8 @@ static void fib6_dump_end(struct netlink_callback *cb)
1701 fib6_walker_unlink(w); 1701 fib6_walker_unlink(w);
1702 kfree(w); 1702 kfree(w);
1703 } 1703 }
1704 if (cb->args[1]) { 1704 cb->done = (void*)cb->args[1];
1705 cb->done = (void*)cb->args[1]; 1705 cb->args[1] = 0;
1706 cb->args[1] = 0;
1707 }
1708} 1706}
1709 1707
1710static int fib6_dump_done(struct netlink_callback *cb) 1708static int fib6_dump_done(struct netlink_callback *cb)
@@ -1734,7 +1732,7 @@ int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
1734 /* 1732 /*
1735 * 2. allocate and initialize walker. 1733 * 2. allocate and initialize walker.
1736 */ 1734 */
1737 w = kmalloc(sizeof(*w), GFP_ATOMIC); 1735 w = kmalloc(sizeof(*w), GFP_KERNEL);
1738 if (w == NULL) 1736 if (w == NULL)
1739 return -ENOMEM; 1737 return -ENOMEM;
1740 RT6_TRACE("dump<%p", w); 1738 RT6_TRACE("dump<%p", w);
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 83d90dd624f0..5a6fcf349bdf 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -779,6 +779,7 @@ static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] =
779{ 779{
780 [TH_SYN] = 1, 780 [TH_SYN] = 1,
781 [TH_SYN|TH_ACK] = 1, 781 [TH_SYN|TH_ACK] = 1,
782 [TH_SYN|TH_PUSH] = 1,
782 [TH_SYN|TH_ACK|TH_PUSH] = 1, 783 [TH_SYN|TH_ACK|TH_PUSH] = 1,
783 [TH_RST] = 1, 784 [TH_RST] = 1,
784 [TH_RST|TH_ACK] = 1, 785 [TH_RST|TH_ACK] = 1,
@@ -969,6 +970,12 @@ static int tcp_packet(struct nf_conn *conntrack,
969 conntrack->timeout.function((unsigned long) 970 conntrack->timeout.function((unsigned long)
970 conntrack); 971 conntrack);
971 return -NF_REPEAT; 972 return -NF_REPEAT;
973 } else {
974 write_unlock_bh(&tcp_lock);
975 if (LOG_INVALID(IPPROTO_TCP))
976 nf_log_packet(pf, 0, skb, NULL, NULL,
977 NULL, "nf_ct_tcp: invalid SYN");
978 return -NF_ACCEPT;
972 } 979 }
973 case TCP_CONNTRACK_CLOSE: 980 case TCP_CONNTRACK_CLOSE:
974 if (index == TCP_RST_SET 981 if (index == TCP_RST_SET
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 83f4c53030fc..a60c59b97631 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -223,6 +223,12 @@ static inline int nfnetlink_rcv_msg(struct sk_buff *skb,
223 NFNL_SUBSYS_ID(nlh->nlmsg_type), 223 NFNL_SUBSYS_ID(nlh->nlmsg_type),
224 NFNL_MSG_TYPE(nlh->nlmsg_type)); 224 NFNL_MSG_TYPE(nlh->nlmsg_type));
225 225
226 if (!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) {
227 DEBUGP("missing CAP_NET_ADMIN\n");
228 *errp = -EPERM;
229 return -1;
230 }
231
226 /* Only requests are handled by kernel now. */ 232 /* Only requests are handled by kernel now. */
227 if (!(nlh->nlmsg_flags & NLM_F_REQUEST)) { 233 if (!(nlh->nlmsg_flags & NLM_F_REQUEST)) {
228 DEBUGP("received non-request message\n"); 234 DEBUGP("received non-request message\n");
@@ -240,15 +246,12 @@ static inline int nfnetlink_rcv_msg(struct sk_buff *skb,
240 ss = nfnetlink_get_subsys(type); 246 ss = nfnetlink_get_subsys(type);
241 if (!ss) { 247 if (!ss) {
242#ifdef CONFIG_KMOD 248#ifdef CONFIG_KMOD
243 if (cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) { 249 /* don't call nfnl_shunlock, since it would reenter
244 /* don't call nfnl_shunlock, since it would reenter 250 * with further packet processing */
245 * with further packet processing */ 251 up(&nfnl_sem);
246 up(&nfnl_sem); 252 request_module("nfnetlink-subsys-%d", NFNL_SUBSYS_ID(type));
247 request_module("nfnetlink-subsys-%d", 253 nfnl_shlock();
248 NFNL_SUBSYS_ID(type)); 254 ss = nfnetlink_get_subsys(type);
249 nfnl_shlock();
250 ss = nfnetlink_get_subsys(type);
251 }
252 if (!ss) 255 if (!ss)
253#endif 256#endif
254 goto err_inval; 257 goto err_inval;
@@ -260,13 +263,6 @@ static inline int nfnetlink_rcv_msg(struct sk_buff *skb,
260 goto err_inval; 263 goto err_inval;
261 } 264 }
262 265
263 if (nc->cap_required &&
264 !cap_raised(NETLINK_CB(skb).eff_cap, nc->cap_required)) {
265 DEBUGP("permission denied for type %d\n", type);
266 *errp = -EPERM;
267 return -1;
268 }
269
270 { 266 {
271 u_int16_t attr_count = 267 u_int16_t attr_count =
272 ss->cb[NFNL_MSG_TYPE(nlh->nlmsg_type)].attr_count; 268 ss->cb[NFNL_MSG_TYPE(nlh->nlmsg_type)].attr_count;
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index d194676f3655..cba63729313d 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -862,11 +862,9 @@ out_put:
862 862
863static struct nfnl_callback nfulnl_cb[NFULNL_MSG_MAX] = { 863static struct nfnl_callback nfulnl_cb[NFULNL_MSG_MAX] = {
864 [NFULNL_MSG_PACKET] = { .call = nfulnl_recv_unsupp, 864 [NFULNL_MSG_PACKET] = { .call = nfulnl_recv_unsupp,
865 .attr_count = NFULA_MAX, 865 .attr_count = NFULA_MAX, },
866 .cap_required = CAP_NET_ADMIN, },
867 [NFULNL_MSG_CONFIG] = { .call = nfulnl_recv_config, 866 [NFULNL_MSG_CONFIG] = { .call = nfulnl_recv_config,
868 .attr_count = NFULA_CFG_MAX, 867 .attr_count = NFULA_CFG_MAX, },
869 .cap_required = CAP_NET_ADMIN },
870}; 868};
871 869
872static struct nfnetlink_subsystem nfulnl_subsys = { 870static struct nfnetlink_subsystem nfulnl_subsys = {
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index f065a6c94953..f28460b61e47 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -931,14 +931,11 @@ out_put:
931 931
932static struct nfnl_callback nfqnl_cb[NFQNL_MSG_MAX] = { 932static struct nfnl_callback nfqnl_cb[NFQNL_MSG_MAX] = {
933 [NFQNL_MSG_PACKET] = { .call = nfqnl_recv_unsupp, 933 [NFQNL_MSG_PACKET] = { .call = nfqnl_recv_unsupp,
934 .attr_count = NFQA_MAX, 934 .attr_count = NFQA_MAX, },
935 .cap_required = CAP_NET_ADMIN },
936 [NFQNL_MSG_VERDICT] = { .call = nfqnl_recv_verdict, 935 [NFQNL_MSG_VERDICT] = { .call = nfqnl_recv_verdict,
937 .attr_count = NFQA_MAX, 936 .attr_count = NFQA_MAX, },
938 .cap_required = CAP_NET_ADMIN },
939 [NFQNL_MSG_CONFIG] = { .call = nfqnl_recv_config, 937 [NFQNL_MSG_CONFIG] = { .call = nfqnl_recv_config,
940 .attr_count = NFQA_CFG_MAX, 938 .attr_count = NFQA_CFG_MAX, },
941 .cap_required = CAP_NET_ADMIN },
942}; 939};
943 940
944static struct nfnetlink_subsystem nfqnl_subsys = { 941static struct nfnetlink_subsystem nfqnl_subsys = {