diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 00:04:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 00:04:44 -0400 |
commit | f8965467f366fd18f01feafb5db10512d7b4422c (patch) | |
tree | 3706a9cd779859271ca61b85c63a1bc3f82d626e /net/ipv4 | |
parent | a26272e5200765691e67d6780e52b32498fdb659 (diff) | |
parent | 2ec8c6bb5d8f3a62a79f463525054bae1e3d4487 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1674 commits)
qlcnic: adding co maintainer
ixgbe: add support for active DA cables
ixgbe: dcb, do not tag tc_prio_control frames
ixgbe: fix ixgbe_tx_is_paused logic
ixgbe: always enable vlan strip/insert when DCB is enabled
ixgbe: remove some redundant code in setting FCoE FIP filter
ixgbe: fix wrong offset to fc_frame_header in ixgbe_fcoe_ddp
ixgbe: fix header len when unsplit packet overflows to data buffer
ipv6: Never schedule DAD timer on dead address
ipv6: Use POSTDAD state
ipv6: Use state_lock to protect ifa state
ipv6: Replace inet6_ifaddr->dead with state
cxgb4: notify upper drivers if the device is already up when they load
cxgb4: keep interrupts available when the ports are brought down
cxgb4: fix initial addition of MAC address
cnic: Return SPQ credit to bnx2x after ring setup and shutdown.
cnic: Convert cnic_local_flags to atomic ops.
can: Fix SJA1000 command register writes on SMP systems
bridge: fix build for CONFIG_SYSFS disabled
ARCNET: Limit com20020 PCI ID matches for SOHARD cards
...
Fix up various conflicts with pcmcia tree drivers/net/
{pcmcia/3c589_cs.c, wireless/orinoco/orinoco_cs.c and
wireless/orinoco/spectrum_cs.c} and feature removal
(Documentation/feature-removal-schedule.txt).
Also fix a non-content conflict due to pm_qos_requirement getting
renamed in the PM tree (now pm_qos_request) in net/mac80211/scan.c
Diffstat (limited to 'net/ipv4')
58 files changed, 1277 insertions, 1001 deletions
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 0c94a1ac294..8e3a1fd938a 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig | |||
@@ -250,6 +250,20 @@ config IP_MROUTE | |||
250 | <file:Documentation/networking/multicast.txt>. If you haven't heard | 250 | <file:Documentation/networking/multicast.txt>. If you haven't heard |
251 | about it, you don't need it. | 251 | about it, you don't need it. |
252 | 252 | ||
253 | config IP_MROUTE_MULTIPLE_TABLES | ||
254 | bool "IP: multicast policy routing" | ||
255 | depends on IP_MROUTE && IP_ADVANCED_ROUTER | ||
256 | select FIB_RULES | ||
257 | help | ||
258 | Normally, a multicast router runs a userspace daemon and decides | ||
259 | what to do with a multicast packet based on the source and | ||
260 | destination addresses. If you say Y here, the multicast router | ||
261 | will also be able to take interfaces and packet marks into | ||
262 | account and run multiple instances of userspace daemons | ||
263 | simultaneously, each one handling a single table. | ||
264 | |||
265 | If unsure, say N. | ||
266 | |||
253 | config IP_PIMSM_V1 | 267 | config IP_PIMSM_V1 |
254 | bool "IP: PIM-SM version 1 support" | 268 | bool "IP: PIM-SM version 1 support" |
255 | depends on IP_MROUTE | 269 | depends on IP_MROUTE |
@@ -587,9 +601,15 @@ choice | |||
587 | config DEFAULT_HTCP | 601 | config DEFAULT_HTCP |
588 | bool "Htcp" if TCP_CONG_HTCP=y | 602 | bool "Htcp" if TCP_CONG_HTCP=y |
589 | 603 | ||
604 | config DEFAULT_HYBLA | ||
605 | bool "Hybla" if TCP_CONG_HYBLA=y | ||
606 | |||
590 | config DEFAULT_VEGAS | 607 | config DEFAULT_VEGAS |
591 | bool "Vegas" if TCP_CONG_VEGAS=y | 608 | bool "Vegas" if TCP_CONG_VEGAS=y |
592 | 609 | ||
610 | config DEFAULT_VENO | ||
611 | bool "Veno" if TCP_CONG_VENO=y | ||
612 | |||
593 | config DEFAULT_WESTWOOD | 613 | config DEFAULT_WESTWOOD |
594 | bool "Westwood" if TCP_CONG_WESTWOOD=y | 614 | bool "Westwood" if TCP_CONG_WESTWOOD=y |
595 | 615 | ||
@@ -610,8 +630,10 @@ config DEFAULT_TCP_CONG | |||
610 | default "bic" if DEFAULT_BIC | 630 | default "bic" if DEFAULT_BIC |
611 | default "cubic" if DEFAULT_CUBIC | 631 | default "cubic" if DEFAULT_CUBIC |
612 | default "htcp" if DEFAULT_HTCP | 632 | default "htcp" if DEFAULT_HTCP |
633 | default "hybla" if DEFAULT_HYBLA | ||
613 | default "vegas" if DEFAULT_VEGAS | 634 | default "vegas" if DEFAULT_VEGAS |
614 | default "westwood" if DEFAULT_WESTWOOD | 635 | default "westwood" if DEFAULT_WESTWOOD |
636 | default "veno" if DEFAULT_VENO | ||
615 | default "reno" if DEFAULT_RENO | 637 | default "reno" if DEFAULT_RENO |
616 | default "cubic" | 638 | default "cubic" |
617 | 639 | ||
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index f7135742238..551ce564b03 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -154,7 +154,7 @@ void inet_sock_destruct(struct sock *sk) | |||
154 | WARN_ON(sk->sk_forward_alloc); | 154 | WARN_ON(sk->sk_forward_alloc); |
155 | 155 | ||
156 | kfree(inet->opt); | 156 | kfree(inet->opt); |
157 | dst_release(sk->sk_dst_cache); | 157 | dst_release(rcu_dereference_check(sk->sk_dst_cache, 1)); |
158 | sk_refcnt_debug_dec(sk); | 158 | sk_refcnt_debug_dec(sk); |
159 | } | 159 | } |
160 | EXPORT_SYMBOL(inet_sock_destruct); | 160 | EXPORT_SYMBOL(inet_sock_destruct); |
@@ -419,6 +419,8 @@ int inet_release(struct socket *sock) | |||
419 | if (sk) { | 419 | if (sk) { |
420 | long timeout; | 420 | long timeout; |
421 | 421 | ||
422 | sock_rps_reset_flow(sk); | ||
423 | |||
422 | /* Applications forget to leave groups before exiting */ | 424 | /* Applications forget to leave groups before exiting */ |
423 | ip_mc_drop_socket(sk); | 425 | ip_mc_drop_socket(sk); |
424 | 426 | ||
@@ -546,7 +548,7 @@ static long inet_wait_for_connect(struct sock *sk, long timeo) | |||
546 | { | 548 | { |
547 | DEFINE_WAIT(wait); | 549 | DEFINE_WAIT(wait); |
548 | 550 | ||
549 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 551 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
550 | 552 | ||
551 | /* Basic assumption: if someone sets sk->sk_err, he _must_ | 553 | /* Basic assumption: if someone sets sk->sk_err, he _must_ |
552 | * change state of the socket from TCP_SYN_*. | 554 | * change state of the socket from TCP_SYN_*. |
@@ -559,9 +561,9 @@ static long inet_wait_for_connect(struct sock *sk, long timeo) | |||
559 | lock_sock(sk); | 561 | lock_sock(sk); |
560 | if (signal_pending(current) || !timeo) | 562 | if (signal_pending(current) || !timeo) |
561 | break; | 563 | break; |
562 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 564 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
563 | } | 565 | } |
564 | finish_wait(sk->sk_sleep, &wait); | 566 | finish_wait(sk_sleep(sk), &wait); |
565 | return timeo; | 567 | return timeo; |
566 | } | 568 | } |
567 | 569 | ||
@@ -720,6 +722,8 @@ int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
720 | { | 722 | { |
721 | struct sock *sk = sock->sk; | 723 | struct sock *sk = sock->sk; |
722 | 724 | ||
725 | sock_rps_record_flow(sk); | ||
726 | |||
723 | /* We may need to bind the socket. */ | 727 | /* We may need to bind the socket. */ |
724 | if (!inet_sk(sk)->inet_num && inet_autobind(sk)) | 728 | if (!inet_sk(sk)->inet_num && inet_autobind(sk)) |
725 | return -EAGAIN; | 729 | return -EAGAIN; |
@@ -728,12 +732,13 @@ int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
728 | } | 732 | } |
729 | EXPORT_SYMBOL(inet_sendmsg); | 733 | EXPORT_SYMBOL(inet_sendmsg); |
730 | 734 | ||
731 | |||
732 | static ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, | 735 | static ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, |
733 | size_t size, int flags) | 736 | size_t size, int flags) |
734 | { | 737 | { |
735 | struct sock *sk = sock->sk; | 738 | struct sock *sk = sock->sk; |
736 | 739 | ||
740 | sock_rps_record_flow(sk); | ||
741 | |||
737 | /* We may need to bind the socket. */ | 742 | /* We may need to bind the socket. */ |
738 | if (!inet_sk(sk)->inet_num && inet_autobind(sk)) | 743 | if (!inet_sk(sk)->inet_num && inet_autobind(sk)) |
739 | return -EAGAIN; | 744 | return -EAGAIN; |
@@ -743,6 +748,22 @@ static ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, | |||
743 | return sock_no_sendpage(sock, page, offset, size, flags); | 748 | return sock_no_sendpage(sock, page, offset, size, flags); |
744 | } | 749 | } |
745 | 750 | ||
751 | int inet_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | ||
752 | size_t size, int flags) | ||
753 | { | ||
754 | struct sock *sk = sock->sk; | ||
755 | int addr_len = 0; | ||
756 | int err; | ||
757 | |||
758 | sock_rps_record_flow(sk); | ||
759 | |||
760 | err = sk->sk_prot->recvmsg(iocb, sk, msg, size, flags & MSG_DONTWAIT, | ||
761 | flags & ~MSG_DONTWAIT, &addr_len); | ||
762 | if (err >= 0) | ||
763 | msg->msg_namelen = addr_len; | ||
764 | return err; | ||
765 | } | ||
766 | EXPORT_SYMBOL(inet_recvmsg); | ||
746 | 767 | ||
747 | int inet_shutdown(struct socket *sock, int how) | 768 | int inet_shutdown(struct socket *sock, int how) |
748 | { | 769 | { |
@@ -872,7 +893,7 @@ const struct proto_ops inet_stream_ops = { | |||
872 | .setsockopt = sock_common_setsockopt, | 893 | .setsockopt = sock_common_setsockopt, |
873 | .getsockopt = sock_common_getsockopt, | 894 | .getsockopt = sock_common_getsockopt, |
874 | .sendmsg = tcp_sendmsg, | 895 | .sendmsg = tcp_sendmsg, |
875 | .recvmsg = sock_common_recvmsg, | 896 | .recvmsg = inet_recvmsg, |
876 | .mmap = sock_no_mmap, | 897 | .mmap = sock_no_mmap, |
877 | .sendpage = tcp_sendpage, | 898 | .sendpage = tcp_sendpage, |
878 | .splice_read = tcp_splice_read, | 899 | .splice_read = tcp_splice_read, |
@@ -899,7 +920,7 @@ const struct proto_ops inet_dgram_ops = { | |||
899 | .setsockopt = sock_common_setsockopt, | 920 | .setsockopt = sock_common_setsockopt, |
900 | .getsockopt = sock_common_getsockopt, | 921 | .getsockopt = sock_common_getsockopt, |
901 | .sendmsg = inet_sendmsg, | 922 | .sendmsg = inet_sendmsg, |
902 | .recvmsg = sock_common_recvmsg, | 923 | .recvmsg = inet_recvmsg, |
903 | .mmap = sock_no_mmap, | 924 | .mmap = sock_no_mmap, |
904 | .sendpage = inet_sendpage, | 925 | .sendpage = inet_sendpage, |
905 | #ifdef CONFIG_COMPAT | 926 | #ifdef CONFIG_COMPAT |
@@ -929,7 +950,7 @@ static const struct proto_ops inet_sockraw_ops = { | |||
929 | .setsockopt = sock_common_setsockopt, | 950 | .setsockopt = sock_common_setsockopt, |
930 | .getsockopt = sock_common_getsockopt, | 951 | .getsockopt = sock_common_getsockopt, |
931 | .sendmsg = inet_sendmsg, | 952 | .sendmsg = inet_sendmsg, |
932 | .recvmsg = sock_common_recvmsg, | 953 | .recvmsg = inet_recvmsg, |
933 | .mmap = sock_no_mmap, | 954 | .mmap = sock_no_mmap, |
934 | .sendpage = inet_sendpage, | 955 | .sendpage = inet_sendpage, |
935 | #ifdef CONFIG_COMPAT | 956 | #ifdef CONFIG_COMPAT |
@@ -1302,8 +1323,8 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head, | |||
1302 | if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl))) | 1323 | if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl))) |
1303 | goto out_unlock; | 1324 | goto out_unlock; |
1304 | 1325 | ||
1305 | id = ntohl(*(u32 *)&iph->id); | 1326 | id = ntohl(*(__be32 *)&iph->id); |
1306 | flush = (u16)((ntohl(*(u32 *)iph) ^ skb_gro_len(skb)) | (id ^ IP_DF)); | 1327 | flush = (u16)((ntohl(*(__be32 *)iph) ^ skb_gro_len(skb)) | (id ^ IP_DF)); |
1307 | id >>= 16; | 1328 | id >>= 16; |
1308 | 1329 | ||
1309 | for (p = *head; p; p = p->next) { | 1330 | for (p = *head; p; p = p->next) { |
@@ -1316,8 +1337,8 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head, | |||
1316 | 1337 | ||
1317 | if ((iph->protocol ^ iph2->protocol) | | 1338 | if ((iph->protocol ^ iph2->protocol) | |
1318 | (iph->tos ^ iph2->tos) | | 1339 | (iph->tos ^ iph2->tos) | |
1319 | (iph->saddr ^ iph2->saddr) | | 1340 | ((__force u32)iph->saddr ^ (__force u32)iph2->saddr) | |
1320 | (iph->daddr ^ iph2->daddr)) { | 1341 | ((__force u32)iph->daddr ^ (__force u32)iph2->daddr)) { |
1321 | NAPI_GRO_CB(p)->same_flow = 0; | 1342 | NAPI_GRO_CB(p)->same_flow = 0; |
1322 | continue; | 1343 | continue; |
1323 | } | 1344 | } |
@@ -1407,10 +1428,10 @@ EXPORT_SYMBOL_GPL(snmp_fold_field); | |||
1407 | int snmp_mib_init(void __percpu *ptr[2], size_t mibsize) | 1428 | int snmp_mib_init(void __percpu *ptr[2], size_t mibsize) |
1408 | { | 1429 | { |
1409 | BUG_ON(ptr == NULL); | 1430 | BUG_ON(ptr == NULL); |
1410 | ptr[0] = __alloc_percpu(mibsize, __alignof__(unsigned long long)); | 1431 | ptr[0] = __alloc_percpu(mibsize, __alignof__(unsigned long)); |
1411 | if (!ptr[0]) | 1432 | if (!ptr[0]) |
1412 | goto err0; | 1433 | goto err0; |
1413 | ptr[1] = __alloc_percpu(mibsize, __alignof__(unsigned long long)); | 1434 | ptr[1] = __alloc_percpu(mibsize, __alignof__(unsigned long)); |
1414 | if (!ptr[1]) | 1435 | if (!ptr[1]) |
1415 | goto err1; | 1436 | goto err1; |
1416 | return 0; | 1437 | return 0; |
@@ -1552,9 +1573,13 @@ static int __init inet_init(void) | |||
1552 | 1573 | ||
1553 | BUILD_BUG_ON(sizeof(struct inet_skb_parm) > sizeof(dummy_skb->cb)); | 1574 | BUILD_BUG_ON(sizeof(struct inet_skb_parm) > sizeof(dummy_skb->cb)); |
1554 | 1575 | ||
1576 | sysctl_local_reserved_ports = kzalloc(65536 / 8, GFP_KERNEL); | ||
1577 | if (!sysctl_local_reserved_ports) | ||
1578 | goto out; | ||
1579 | |||
1555 | rc = proto_register(&tcp_prot, 1); | 1580 | rc = proto_register(&tcp_prot, 1); |
1556 | if (rc) | 1581 | if (rc) |
1557 | goto out; | 1582 | goto out_free_reserved_ports; |
1558 | 1583 | ||
1559 | rc = proto_register(&udp_prot, 1); | 1584 | rc = proto_register(&udp_prot, 1); |
1560 | if (rc) | 1585 | if (rc) |
@@ -1653,6 +1678,8 @@ out_unregister_udp_proto: | |||
1653 | proto_unregister(&udp_prot); | 1678 | proto_unregister(&udp_prot); |
1654 | out_unregister_tcp_proto: | 1679 | out_unregister_tcp_proto: |
1655 | proto_unregister(&tcp_prot); | 1680 | proto_unregister(&tcp_prot); |
1681 | out_free_reserved_ports: | ||
1682 | kfree(sysctl_local_reserved_ports); | ||
1656 | goto out; | 1683 | goto out; |
1657 | } | 1684 | } |
1658 | 1685 | ||
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 80769f1f9fa..f094b75810d 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -854,7 +854,7 @@ static int arp_process(struct sk_buff *skb) | |||
854 | } | 854 | } |
855 | 855 | ||
856 | if (arp->ar_op == htons(ARPOP_REQUEST) && | 856 | if (arp->ar_op == htons(ARPOP_REQUEST) && |
857 | ip_route_input(skb, tip, sip, 0, dev) == 0) { | 857 | ip_route_input_noref(skb, tip, sip, 0, dev) == 0) { |
858 | 858 | ||
859 | rt = skb_rtable(skb); | 859 | rt = skb_rtable(skb); |
860 | addr_type = rt->rt_type; | 860 | addr_type = rt->rt_type; |
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index c97cd9ff697..3a92a76ae41 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c | |||
@@ -290,8 +290,6 @@ void cipso_v4_cache_invalidate(void) | |||
290 | cipso_v4_cache[iter].size = 0; | 290 | cipso_v4_cache[iter].size = 0; |
291 | spin_unlock_bh(&cipso_v4_cache[iter].lock); | 291 | spin_unlock_bh(&cipso_v4_cache[iter].lock); |
292 | } | 292 | } |
293 | |||
294 | return; | ||
295 | } | 293 | } |
296 | 294 | ||
297 | /** | 295 | /** |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 90e3d6379a4..382bc768ed5 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -1096,10 +1096,10 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, | |||
1096 | case NETDEV_DOWN: | 1096 | case NETDEV_DOWN: |
1097 | ip_mc_down(in_dev); | 1097 | ip_mc_down(in_dev); |
1098 | break; | 1098 | break; |
1099 | case NETDEV_BONDING_OLDTYPE: | 1099 | case NETDEV_PRE_TYPE_CHANGE: |
1100 | ip_mc_unmap(in_dev); | 1100 | ip_mc_unmap(in_dev); |
1101 | break; | 1101 | break; |
1102 | case NETDEV_BONDING_NEWTYPE: | 1102 | case NETDEV_POST_TYPE_CHANGE: |
1103 | ip_mc_remap(in_dev); | 1103 | ip_mc_remap(in_dev); |
1104 | break; | 1104 | break; |
1105 | case NETDEV_CHANGEMTU: | 1105 | case NETDEV_CHANGEMTU: |
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index ca2d07b1c70..76daeb5ff56 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
@@ -213,7 +213,6 @@ static int fib4_rule_fill(struct fib_rule *rule, struct sk_buff *skb, | |||
213 | { | 213 | { |
214 | struct fib4_rule *rule4 = (struct fib4_rule *) rule; | 214 | struct fib4_rule *rule4 = (struct fib4_rule *) rule; |
215 | 215 | ||
216 | frh->family = AF_INET; | ||
217 | frh->dst_len = rule4->dst_len; | 216 | frh->dst_len = rule4->dst_len; |
218 | frh->src_len = rule4->src_len; | 217 | frh->src_len = rule4->src_len; |
219 | frh->tos = rule4->tos; | 218 | frh->tos = rule4->tos; |
@@ -234,23 +233,6 @@ nla_put_failure: | |||
234 | return -ENOBUFS; | 233 | return -ENOBUFS; |
235 | } | 234 | } |
236 | 235 | ||
237 | static u32 fib4_rule_default_pref(struct fib_rules_ops *ops) | ||
238 | { | ||
239 | struct list_head *pos; | ||
240 | struct fib_rule *rule; | ||
241 | |||
242 | if (!list_empty(&ops->rules_list)) { | ||
243 | pos = ops->rules_list.next; | ||
244 | if (pos->next != &ops->rules_list) { | ||
245 | rule = list_entry(pos->next, struct fib_rule, list); | ||
246 | if (rule->pref) | ||
247 | return rule->pref - 1; | ||
248 | } | ||
249 | } | ||
250 | |||
251 | return 0; | ||
252 | } | ||
253 | |||
254 | static size_t fib4_rule_nlmsg_payload(struct fib_rule *rule) | 236 | static size_t fib4_rule_nlmsg_payload(struct fib_rule *rule) |
255 | { | 237 | { |
256 | return nla_total_size(4) /* dst */ | 238 | return nla_total_size(4) /* dst */ |
@@ -263,7 +245,7 @@ static void fib4_rule_flush_cache(struct fib_rules_ops *ops) | |||
263 | rt_cache_flush(ops->fro_net, -1); | 245 | rt_cache_flush(ops->fro_net, -1); |
264 | } | 246 | } |
265 | 247 | ||
266 | static struct fib_rules_ops fib4_rules_ops_template = { | 248 | static const struct fib_rules_ops __net_initdata fib4_rules_ops_template = { |
267 | .family = AF_INET, | 249 | .family = AF_INET, |
268 | .rule_size = sizeof(struct fib4_rule), | 250 | .rule_size = sizeof(struct fib4_rule), |
269 | .addr_size = sizeof(u32), | 251 | .addr_size = sizeof(u32), |
@@ -272,7 +254,7 @@ static struct fib_rules_ops fib4_rules_ops_template = { | |||
272 | .configure = fib4_rule_configure, | 254 | .configure = fib4_rule_configure, |
273 | .compare = fib4_rule_compare, | 255 | .compare = fib4_rule_compare, |
274 | .fill = fib4_rule_fill, | 256 | .fill = fib4_rule_fill, |
275 | .default_pref = fib4_rule_default_pref, | 257 | .default_pref = fib_default_rule_pref, |
276 | .nlmsg_payload = fib4_rule_nlmsg_payload, | 258 | .nlmsg_payload = fib4_rule_nlmsg_payload, |
277 | .flush_cache = fib4_rule_flush_cache, | 259 | .flush_cache = fib4_rule_flush_cache, |
278 | .nlgroup = RTNLGRP_IPV4_RULE, | 260 | .nlgroup = RTNLGRP_IPV4_RULE, |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index c98f115fb0f..79d057a939b 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -1022,8 +1022,6 @@ static void trie_rebalance(struct trie *t, struct tnode *tn) | |||
1022 | 1022 | ||
1023 | rcu_assign_pointer(t->trie, (struct node *)tn); | 1023 | rcu_assign_pointer(t->trie, (struct node *)tn); |
1024 | tnode_free_flush(); | 1024 | tnode_free_flush(); |
1025 | |||
1026 | return; | ||
1027 | } | 1025 | } |
1028 | 1026 | ||
1029 | /* only used from updater-side */ | 1027 | /* only used from updater-side */ |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index ac4dec13273..d65e9215bcd 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
@@ -331,9 +331,10 @@ static void icmp_push_reply(struct icmp_bxm *icmp_param, | |||
331 | if (ip_append_data(sk, icmp_glue_bits, icmp_param, | 331 | if (ip_append_data(sk, icmp_glue_bits, icmp_param, |
332 | icmp_param->data_len+icmp_param->head_len, | 332 | icmp_param->data_len+icmp_param->head_len, |
333 | icmp_param->head_len, | 333 | icmp_param->head_len, |
334 | ipc, rt, MSG_DONTWAIT) < 0) | 334 | ipc, rt, MSG_DONTWAIT) < 0) { |
335 | ICMP_INC_STATS_BH(sock_net(sk), ICMP_MIB_OUTERRORS); | ||
335 | ip_flush_pending_frames(sk); | 336 | ip_flush_pending_frames(sk); |
336 | else if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) { | 337 | } else if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) { |
337 | struct icmphdr *icmph = icmp_hdr(skb); | 338 | struct icmphdr *icmph = icmp_hdr(skb); |
338 | __wsum csum = 0; | 339 | __wsum csum = 0; |
339 | struct sk_buff *skb1; | 340 | struct sk_buff *skb1; |
@@ -586,20 +587,20 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
586 | err = __ip_route_output_key(net, &rt2, &fl); | 587 | err = __ip_route_output_key(net, &rt2, &fl); |
587 | else { | 588 | else { |
588 | struct flowi fl2 = {}; | 589 | struct flowi fl2 = {}; |
589 | struct dst_entry *odst; | 590 | unsigned long orefdst; |
590 | 591 | ||
591 | fl2.fl4_dst = fl.fl4_src; | 592 | fl2.fl4_dst = fl.fl4_src; |
592 | if (ip_route_output_key(net, &rt2, &fl2)) | 593 | if (ip_route_output_key(net, &rt2, &fl2)) |
593 | goto relookup_failed; | 594 | goto relookup_failed; |
594 | 595 | ||
595 | /* Ugh! */ | 596 | /* Ugh! */ |
596 | odst = skb_dst(skb_in); | 597 | orefdst = skb_in->_skb_refdst; /* save old refdst */ |
597 | err = ip_route_input(skb_in, fl.fl4_dst, fl.fl4_src, | 598 | err = ip_route_input(skb_in, fl.fl4_dst, fl.fl4_src, |
598 | RT_TOS(tos), rt2->u.dst.dev); | 599 | RT_TOS(tos), rt2->u.dst.dev); |
599 | 600 | ||
600 | dst_release(&rt2->u.dst); | 601 | dst_release(&rt2->u.dst); |
601 | rt2 = skb_rtable(skb_in); | 602 | rt2 = skb_rtable(skb_in); |
602 | skb_dst_set(skb_in, odst); | 603 | skb_in->_skb_refdst = orefdst; /* restore old refdst */ |
603 | } | 604 | } |
604 | 605 | ||
605 | if (err) | 606 | if (err) |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 15d3eeda92f..5fff865a4fa 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -998,7 +998,7 @@ static void ip_mc_filter_add(struct in_device *in_dev, __be32 addr) | |||
998 | --ANK | 998 | --ANK |
999 | */ | 999 | */ |
1000 | if (arp_mc_map(addr, buf, dev, 0) == 0) | 1000 | if (arp_mc_map(addr, buf, dev, 0) == 0) |
1001 | dev_mc_add(dev, buf, dev->addr_len, 0); | 1001 | dev_mc_add(dev, buf); |
1002 | } | 1002 | } |
1003 | 1003 | ||
1004 | /* | 1004 | /* |
@@ -1011,7 +1011,7 @@ static void ip_mc_filter_del(struct in_device *in_dev, __be32 addr) | |||
1011 | struct net_device *dev = in_dev->dev; | 1011 | struct net_device *dev = in_dev->dev; |
1012 | 1012 | ||
1013 | if (arp_mc_map(addr, buf, dev, 0) == 0) | 1013 | if (arp_mc_map(addr, buf, dev, 0) == 0) |
1014 | dev_mc_delete(dev, buf, dev->addr_len, 0); | 1014 | dev_mc_del(dev, buf); |
1015 | } | 1015 | } |
1016 | 1016 | ||
1017 | #ifdef CONFIG_IP_MULTICAST | 1017 | #ifdef CONFIG_IP_MULTICAST |
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 8da6429269d..70eb3507c40 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
@@ -37,6 +37,9 @@ struct local_ports sysctl_local_ports __read_mostly = { | |||
37 | .range = { 32768, 61000 }, | 37 | .range = { 32768, 61000 }, |
38 | }; | 38 | }; |
39 | 39 | ||
40 | unsigned long *sysctl_local_reserved_ports; | ||
41 | EXPORT_SYMBOL(sysctl_local_reserved_ports); | ||
42 | |||
40 | void inet_get_local_port_range(int *low, int *high) | 43 | void inet_get_local_port_range(int *low, int *high) |
41 | { | 44 | { |
42 | unsigned seq; | 45 | unsigned seq; |
@@ -108,6 +111,8 @@ again: | |||
108 | 111 | ||
109 | smallest_size = -1; | 112 | smallest_size = -1; |
110 | do { | 113 | do { |
114 | if (inet_is_reserved_local_port(rover)) | ||
115 | goto next_nolock; | ||
111 | head = &hashinfo->bhash[inet_bhashfn(net, rover, | 116 | head = &hashinfo->bhash[inet_bhashfn(net, rover, |
112 | hashinfo->bhash_size)]; | 117 | hashinfo->bhash_size)]; |
113 | spin_lock(&head->lock); | 118 | spin_lock(&head->lock); |
@@ -130,6 +135,7 @@ again: | |||
130 | break; | 135 | break; |
131 | next: | 136 | next: |
132 | spin_unlock(&head->lock); | 137 | spin_unlock(&head->lock); |
138 | next_nolock: | ||
133 | if (++rover > high) | 139 | if (++rover > high) |
134 | rover = low; | 140 | rover = low; |
135 | } while (--remaining > 0); | 141 | } while (--remaining > 0); |
@@ -234,7 +240,7 @@ static int inet_csk_wait_for_connect(struct sock *sk, long timeo) | |||
234 | * having to remove and re-insert us on the wait queue. | 240 | * having to remove and re-insert us on the wait queue. |
235 | */ | 241 | */ |
236 | for (;;) { | 242 | for (;;) { |
237 | prepare_to_wait_exclusive(sk->sk_sleep, &wait, | 243 | prepare_to_wait_exclusive(sk_sleep(sk), &wait, |
238 | TASK_INTERRUPTIBLE); | 244 | TASK_INTERRUPTIBLE); |
239 | release_sock(sk); | 245 | release_sock(sk); |
240 | if (reqsk_queue_empty(&icsk->icsk_accept_queue)) | 246 | if (reqsk_queue_empty(&icsk->icsk_accept_queue)) |
@@ -253,7 +259,7 @@ static int inet_csk_wait_for_connect(struct sock *sk, long timeo) | |||
253 | if (!timeo) | 259 | if (!timeo) |
254 | break; | 260 | break; |
255 | } | 261 | } |
256 | finish_wait(sk->sk_sleep, &wait); | 262 | finish_wait(sk_sleep(sk), &wait); |
257 | return err; | 263 | return err; |
258 | } | 264 | } |
259 | 265 | ||
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 2b79377b468..d3e160a8821 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c | |||
@@ -456,6 +456,8 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, | |||
456 | local_bh_disable(); | 456 | local_bh_disable(); |
457 | for (i = 1; i <= remaining; i++) { | 457 | for (i = 1; i <= remaining; i++) { |
458 | port = low + (i + offset) % remaining; | 458 | port = low + (i + offset) % remaining; |
459 | if (inet_is_reserved_local_port(port)) | ||
460 | continue; | ||
459 | head = &hinfo->bhash[inet_bhashfn(net, port, | 461 | head = &hinfo->bhash[inet_bhashfn(net, port, |
460 | hinfo->bhash_size)]; | 462 | hinfo->bhash_size)]; |
461 | spin_lock(&head->lock); | 463 | spin_lock(&head->lock); |
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c index af10942b326..56cdf68a074 100644 --- a/net/ipv4/ip_forward.c +++ b/net/ipv4/ip_forward.c | |||
@@ -112,8 +112,8 @@ int ip_forward(struct sk_buff *skb) | |||
112 | 112 | ||
113 | skb->priority = rt_tos2priority(iph->tos); | 113 | skb->priority = rt_tos2priority(iph->tos); |
114 | 114 | ||
115 | return NF_HOOK(PF_INET, NF_INET_FORWARD, skb, skb->dev, rt->u.dst.dev, | 115 | return NF_HOOK(NFPROTO_IPV4, NF_INET_FORWARD, skb, skb->dev, |
116 | ip_forward_finish); | 116 | rt->u.dst.dev, ip_forward_finish); |
117 | 117 | ||
118 | sr_failed: | 118 | sr_failed: |
119 | /* | 119 | /* |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index fe381d12ecd..32618e11076 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -502,7 +502,6 @@ static void ipgre_err(struct sk_buff *skb, u32 info) | |||
502 | t->err_time = jiffies; | 502 | t->err_time = jiffies; |
503 | out: | 503 | out: |
504 | rcu_read_unlock(); | 504 | rcu_read_unlock(); |
505 | return; | ||
506 | } | 505 | } |
507 | 506 | ||
508 | static inline void ipgre_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb) | 507 | static inline void ipgre_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb) |
@@ -538,7 +537,6 @@ static int ipgre_rcv(struct sk_buff *skb) | |||
538 | struct ip_tunnel *tunnel; | 537 | struct ip_tunnel *tunnel; |
539 | int offset = 4; | 538 | int offset = 4; |
540 | __be16 gre_proto; | 539 | __be16 gre_proto; |
541 | unsigned int len; | ||
542 | 540 | ||
543 | if (!pskb_may_pull(skb, 16)) | 541 | if (!pskb_may_pull(skb, 16)) |
544 | goto drop_nolock; | 542 | goto drop_nolock; |
@@ -629,8 +627,6 @@ static int ipgre_rcv(struct sk_buff *skb) | |||
629 | tunnel->i_seqno = seqno + 1; | 627 | tunnel->i_seqno = seqno + 1; |
630 | } | 628 | } |
631 | 629 | ||
632 | len = skb->len; | ||
633 | |||
634 | /* Warning: All skb pointers will be invalidated! */ | 630 | /* Warning: All skb pointers will be invalidated! */ |
635 | if (tunnel->dev->type == ARPHRD_ETHER) { | 631 | if (tunnel->dev->type == ARPHRD_ETHER) { |
636 | if (!pskb_may_pull(skb, ETH_HLEN)) { | 632 | if (!pskb_may_pull(skb, ETH_HLEN)) { |
@@ -644,11 +640,7 @@ static int ipgre_rcv(struct sk_buff *skb) | |||
644 | skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); | 640 | skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); |
645 | } | 641 | } |
646 | 642 | ||
647 | stats->rx_packets++; | 643 | skb_tunnel_rx(skb, tunnel->dev); |
648 | stats->rx_bytes += len; | ||
649 | skb->dev = tunnel->dev; | ||
650 | skb_dst_drop(skb); | ||
651 | nf_reset(skb); | ||
652 | 644 | ||
653 | skb_reset_network_header(skb); | 645 | skb_reset_network_header(skb); |
654 | ipgre_ecn_decapsulate(iph, skb); | 646 | ipgre_ecn_decapsulate(iph, skb); |
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index f8ab7a380d4..d930dc5e4d8 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c | |||
@@ -266,7 +266,7 @@ int ip_local_deliver(struct sk_buff *skb) | |||
266 | return 0; | 266 | return 0; |
267 | } | 267 | } |
268 | 268 | ||
269 | return NF_HOOK(PF_INET, NF_INET_LOCAL_IN, skb, skb->dev, NULL, | 269 | return NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_IN, skb, skb->dev, NULL, |
270 | ip_local_deliver_finish); | 270 | ip_local_deliver_finish); |
271 | } | 271 | } |
272 | 272 | ||
@@ -331,8 +331,8 @@ static int ip_rcv_finish(struct sk_buff *skb) | |||
331 | * how the packet travels inside Linux networking. | 331 | * how the packet travels inside Linux networking. |
332 | */ | 332 | */ |
333 | if (skb_dst(skb) == NULL) { | 333 | if (skb_dst(skb) == NULL) { |
334 | int err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, | 334 | int err = ip_route_input_noref(skb, iph->daddr, iph->saddr, |
335 | skb->dev); | 335 | iph->tos, skb->dev); |
336 | if (unlikely(err)) { | 336 | if (unlikely(err)) { |
337 | if (err == -EHOSTUNREACH) | 337 | if (err == -EHOSTUNREACH) |
338 | IP_INC_STATS_BH(dev_net(skb->dev), | 338 | IP_INC_STATS_BH(dev_net(skb->dev), |
@@ -444,7 +444,7 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, | |||
444 | /* Must drop socket now because of tproxy. */ | 444 | /* Must drop socket now because of tproxy. */ |
445 | skb_orphan(skb); | 445 | skb_orphan(skb); |
446 | 446 | ||
447 | return NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, dev, NULL, | 447 | return NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, dev, NULL, |
448 | ip_rcv_finish); | 448 | ip_rcv_finish); |
449 | 449 | ||
450 | inhdr_error: | 450 | inhdr_error: |
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index 4c09a31fd14..ba9836c488e 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c | |||
@@ -238,7 +238,6 @@ void ip_options_fragment(struct sk_buff * skb) | |||
238 | opt->rr_needaddr = 0; | 238 | opt->rr_needaddr = 0; |
239 | opt->ts_needaddr = 0; | 239 | opt->ts_needaddr = 0; |
240 | opt->ts_needtime = 0; | 240 | opt->ts_needtime = 0; |
241 | return; | ||
242 | } | 241 | } |
243 | 242 | ||
244 | /* | 243 | /* |
@@ -601,6 +600,7 @@ int ip_options_rcv_srr(struct sk_buff *skb) | |||
601 | unsigned char *optptr = skb_network_header(skb) + opt->srr; | 600 | unsigned char *optptr = skb_network_header(skb) + opt->srr; |
602 | struct rtable *rt = skb_rtable(skb); | 601 | struct rtable *rt = skb_rtable(skb); |
603 | struct rtable *rt2; | 602 | struct rtable *rt2; |
603 | unsigned long orefdst; | ||
604 | int err; | 604 | int err; |
605 | 605 | ||
606 | if (!opt->srr) | 606 | if (!opt->srr) |
@@ -624,16 +624,16 @@ int ip_options_rcv_srr(struct sk_buff *skb) | |||
624 | } | 624 | } |
625 | memcpy(&nexthop, &optptr[srrptr-1], 4); | 625 | memcpy(&nexthop, &optptr[srrptr-1], 4); |
626 | 626 | ||
627 | rt = skb_rtable(skb); | 627 | orefdst = skb->_skb_refdst; |
628 | skb_dst_set(skb, NULL); | 628 | skb_dst_set(skb, NULL); |
629 | err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, skb->dev); | 629 | err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, skb->dev); |
630 | rt2 = skb_rtable(skb); | 630 | rt2 = skb_rtable(skb); |
631 | if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) { | 631 | if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) { |
632 | ip_rt_put(rt2); | 632 | skb_dst_drop(skb); |
633 | skb_dst_set(skb, &rt->u.dst); | 633 | skb->_skb_refdst = orefdst; |
634 | return -EINVAL; | 634 | return -EINVAL; |
635 | } | 635 | } |
636 | ip_rt_put(rt); | 636 | refdst_drop(orefdst); |
637 | if (rt2->rt_type != RTN_LOCAL) | 637 | if (rt2->rt_type != RTN_LOCAL) |
638 | break; | 638 | break; |
639 | /* Superfast 8) loopback forward */ | 639 | /* Superfast 8) loopback forward */ |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index d1bcc9f21d4..9a4a6c96cb0 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -96,8 +96,8 @@ int __ip_local_out(struct sk_buff *skb) | |||
96 | 96 | ||
97 | iph->tot_len = htons(skb->len); | 97 | iph->tot_len = htons(skb->len); |
98 | ip_send_check(iph); | 98 | ip_send_check(iph); |
99 | return nf_hook(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, skb_dst(skb)->dev, | 99 | return nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT, skb, NULL, |
100 | dst_output); | 100 | skb_dst(skb)->dev, dst_output); |
101 | } | 101 | } |
102 | 102 | ||
103 | int ip_local_out(struct sk_buff *skb) | 103 | int ip_local_out(struct sk_buff *skb) |
@@ -272,8 +272,8 @@ int ip_mc_output(struct sk_buff *skb) | |||
272 | ) { | 272 | ) { |
273 | struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); | 273 | struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); |
274 | if (newskb) | 274 | if (newskb) |
275 | NF_HOOK(PF_INET, NF_INET_POST_ROUTING, newskb, | 275 | NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING, |
276 | NULL, newskb->dev, | 276 | newskb, NULL, newskb->dev, |
277 | ip_dev_loopback_xmit); | 277 | ip_dev_loopback_xmit); |
278 | } | 278 | } |
279 | 279 | ||
@@ -288,12 +288,12 @@ int ip_mc_output(struct sk_buff *skb) | |||
288 | if (rt->rt_flags&RTCF_BROADCAST) { | 288 | if (rt->rt_flags&RTCF_BROADCAST) { |
289 | struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); | 289 | struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); |
290 | if (newskb) | 290 | if (newskb) |
291 | NF_HOOK(PF_INET, NF_INET_POST_ROUTING, newskb, NULL, | 291 | NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING, newskb, |
292 | newskb->dev, ip_dev_loopback_xmit); | 292 | NULL, newskb->dev, ip_dev_loopback_xmit); |
293 | } | 293 | } |
294 | 294 | ||
295 | return NF_HOOK_COND(PF_INET, NF_INET_POST_ROUTING, skb, NULL, skb->dev, | 295 | return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb, NULL, |
296 | ip_finish_output, | 296 | skb->dev, ip_finish_output, |
297 | !(IPCB(skb)->flags & IPSKB_REROUTED)); | 297 | !(IPCB(skb)->flags & IPSKB_REROUTED)); |
298 | } | 298 | } |
299 | 299 | ||
@@ -306,22 +306,24 @@ int ip_output(struct sk_buff *skb) | |||
306 | skb->dev = dev; | 306 | skb->dev = dev; |
307 | skb->protocol = htons(ETH_P_IP); | 307 | skb->protocol = htons(ETH_P_IP); |
308 | 308 | ||
309 | return NF_HOOK_COND(PF_INET, NF_INET_POST_ROUTING, skb, NULL, dev, | 309 | return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb, NULL, dev, |
310 | ip_finish_output, | 310 | ip_finish_output, |
311 | !(IPCB(skb)->flags & IPSKB_REROUTED)); | 311 | !(IPCB(skb)->flags & IPSKB_REROUTED)); |
312 | } | 312 | } |
313 | 313 | ||
314 | int ip_queue_xmit(struct sk_buff *skb, int ipfragok) | 314 | int ip_queue_xmit(struct sk_buff *skb) |
315 | { | 315 | { |
316 | struct sock *sk = skb->sk; | 316 | struct sock *sk = skb->sk; |
317 | struct inet_sock *inet = inet_sk(sk); | 317 | struct inet_sock *inet = inet_sk(sk); |
318 | struct ip_options *opt = inet->opt; | 318 | struct ip_options *opt = inet->opt; |
319 | struct rtable *rt; | 319 | struct rtable *rt; |
320 | struct iphdr *iph; | 320 | struct iphdr *iph; |
321 | int res; | ||
321 | 322 | ||
322 | /* Skip all of this if the packet is already routed, | 323 | /* Skip all of this if the packet is already routed, |
323 | * f.e. by something like SCTP. | 324 | * f.e. by something like SCTP. |
324 | */ | 325 | */ |
326 | rcu_read_lock(); | ||
325 | rt = skb_rtable(skb); | 327 | rt = skb_rtable(skb); |
326 | if (rt != NULL) | 328 | if (rt != NULL) |
327 | goto packet_routed; | 329 | goto packet_routed; |
@@ -359,7 +361,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok) | |||
359 | } | 361 | } |
360 | sk_setup_caps(sk, &rt->u.dst); | 362 | sk_setup_caps(sk, &rt->u.dst); |
361 | } | 363 | } |
362 | skb_dst_set(skb, dst_clone(&rt->u.dst)); | 364 | skb_dst_set_noref(skb, &rt->u.dst); |
363 | 365 | ||
364 | packet_routed: | 366 | packet_routed: |
365 | if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway) | 367 | if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway) |
@@ -370,7 +372,7 @@ packet_routed: | |||
370 | skb_reset_network_header(skb); | 372 | skb_reset_network_header(skb); |
371 | iph = ip_hdr(skb); | 373 | iph = ip_hdr(skb); |
372 | *((__be16 *)iph) = htons((4 << 12) | (5 << 8) | (inet->tos & 0xff)); | 374 | *((__be16 *)iph) = htons((4 << 12) | (5 << 8) | (inet->tos & 0xff)); |
373 | if (ip_dont_fragment(sk, &rt->u.dst) && !ipfragok) | 375 | if (ip_dont_fragment(sk, &rt->u.dst) && !skb->local_df) |
374 | iph->frag_off = htons(IP_DF); | 376 | iph->frag_off = htons(IP_DF); |
375 | else | 377 | else |
376 | iph->frag_off = 0; | 378 | iph->frag_off = 0; |
@@ -391,9 +393,12 @@ packet_routed: | |||
391 | skb->priority = sk->sk_priority; | 393 | skb->priority = sk->sk_priority; |
392 | skb->mark = sk->sk_mark; | 394 | skb->mark = sk->sk_mark; |
393 | 395 | ||
394 | return ip_local_out(skb); | 396 | res = ip_local_out(skb); |
397 | rcu_read_unlock(); | ||
398 | return res; | ||
395 | 399 | ||
396 | no_route: | 400 | no_route: |
401 | rcu_read_unlock(); | ||
397 | IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); | 402 | IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); |
398 | kfree_skb(skb); | 403 | kfree_skb(skb); |
399 | return -EHOSTUNREACH; | 404 | return -EHOSTUNREACH; |
@@ -469,6 +474,10 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
469 | 474 | ||
470 | hlen = iph->ihl * 4; | 475 | hlen = iph->ihl * 4; |
471 | mtu = dst_mtu(&rt->u.dst) - hlen; /* Size of data space */ | 476 | mtu = dst_mtu(&rt->u.dst) - hlen; /* Size of data space */ |
477 | #ifdef CONFIG_BRIDGE_NETFILTER | ||
478 | if (skb->nf_bridge) | ||
479 | mtu -= nf_bridge_mtu_reduction(skb); | ||
480 | #endif | ||
472 | IPCB(skb)->flags |= IPSKB_FRAG_COMPLETE; | 481 | IPCB(skb)->flags |= IPSKB_FRAG_COMPLETE; |
473 | 482 | ||
474 | /* When frag_list is given, use it. First, check its validity: | 483 | /* When frag_list is given, use it. First, check its validity: |
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 1e64dabbd23..ce231780a2b 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
@@ -287,12 +287,8 @@ int ip_ra_control(struct sock *sk, unsigned char on, | |||
287 | void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err, | 287 | void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err, |
288 | __be16 port, u32 info, u8 *payload) | 288 | __be16 port, u32 info, u8 *payload) |
289 | { | 289 | { |
290 | struct inet_sock *inet = inet_sk(sk); | ||
291 | struct sock_exterr_skb *serr; | 290 | struct sock_exterr_skb *serr; |
292 | 291 | ||
293 | if (!inet->recverr) | ||
294 | return; | ||
295 | |||
296 | skb = skb_clone(skb, GFP_ATOMIC); | 292 | skb = skb_clone(skb, GFP_ATOMIC); |
297 | if (!skb) | 293 | if (!skb) |
298 | return; | 294 | return; |
@@ -958,6 +954,22 @@ e_inval: | |||
958 | return -EINVAL; | 954 | return -EINVAL; |
959 | } | 955 | } |
960 | 956 | ||
957 | /** | ||
958 | * ip_queue_rcv_skb - Queue an skb into sock receive queue | ||
959 | * @sk: socket | ||
960 | * @skb: buffer | ||
961 | * | ||
962 | * Queues an skb into socket receive queue. If IP_CMSG_PKTINFO option | ||
963 | * is not set, we drop skb dst entry now, while dst cache line is hot. | ||
964 | */ | ||
965 | int ip_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | ||
966 | { | ||
967 | if (!(inet_sk(sk)->cmsg_flags & IP_CMSG_PKTINFO)) | ||
968 | skb_dst_drop(skb); | ||
969 | return sock_queue_rcv_skb(sk, skb); | ||
970 | } | ||
971 | EXPORT_SYMBOL(ip_queue_rcv_skb); | ||
972 | |||
961 | int ip_setsockopt(struct sock *sk, int level, | 973 | int ip_setsockopt(struct sock *sk, int level, |
962 | int optname, char __user *optval, unsigned int optlen) | 974 | int optname, char __user *optval, unsigned int optlen) |
963 | { | 975 | { |
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 067ce9e043d..b9d84e800cf 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c | |||
@@ -976,7 +976,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str | |||
976 | /* Is it a reply for the device we are configuring? */ | 976 | /* Is it a reply for the device we are configuring? */ |
977 | if (b->xid != ic_dev_xid) { | 977 | if (b->xid != ic_dev_xid) { |
978 | if (net_ratelimit()) | 978 | if (net_ratelimit()) |
979 | printk(KERN_ERR "DHCP/BOOTP: Ignoring delayed packet \n"); | 979 | printk(KERN_ERR "DHCP/BOOTP: Ignoring delayed packet\n"); |
980 | goto drop_unlock; | 980 | goto drop_unlock; |
981 | } | 981 | } |
982 | 982 | ||
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 0b27b14dcc9..7fd63671103 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
@@ -374,11 +374,8 @@ static int ipip_rcv(struct sk_buff *skb) | |||
374 | skb->protocol = htons(ETH_P_IP); | 374 | skb->protocol = htons(ETH_P_IP); |
375 | skb->pkt_type = PACKET_HOST; | 375 | skb->pkt_type = PACKET_HOST; |
376 | 376 | ||
377 | tunnel->dev->stats.rx_packets++; | 377 | skb_tunnel_rx(skb, tunnel->dev); |
378 | tunnel->dev->stats.rx_bytes += skb->len; | 378 | |
379 | skb->dev = tunnel->dev; | ||
380 | skb_dst_drop(skb); | ||
381 | nf_reset(skb); | ||
382 | ipip_ecn_decapsulate(iph, skb); | 379 | ipip_ecn_decapsulate(iph, skb); |
383 | netif_rx(skb); | 380 | netif_rx(skb); |
384 | rcu_read_unlock(); | 381 | rcu_read_unlock(); |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 82aa9c9e4ed..45889103b3e 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -63,11 +63,40 @@ | |||
63 | #include <net/ipip.h> | 63 | #include <net/ipip.h> |
64 | #include <net/checksum.h> | 64 | #include <net/checksum.h> |
65 | #include <net/netlink.h> | 65 | #include <net/netlink.h> |
66 | #include <net/fib_rules.h> | ||
66 | 67 | ||
67 | #if defined(CONFIG_IP_PIMSM_V1) || defined(CONFIG_IP_PIMSM_V2) | 68 | #if defined(CONFIG_IP_PIMSM_V1) || defined(CONFIG_IP_PIMSM_V2) |
68 | #define CONFIG_IP_PIMSM 1 | 69 | #define CONFIG_IP_PIMSM 1 |
69 | #endif | 70 | #endif |
70 | 71 | ||
72 | struct mr_table { | ||
73 | struct list_head list; | ||
74 | #ifdef CONFIG_NET_NS | ||
75 | struct net *net; | ||
76 | #endif | ||
77 | u32 id; | ||
78 | struct sock *mroute_sk; | ||
79 | struct timer_list ipmr_expire_timer; | ||
80 | struct list_head mfc_unres_queue; | ||
81 | struct list_head mfc_cache_array[MFC_LINES]; | ||
82 | struct vif_device vif_table[MAXVIFS]; | ||
83 | int maxvif; | ||
84 | atomic_t cache_resolve_queue_len; | ||
85 | int mroute_do_assert; | ||
86 | int mroute_do_pim; | ||
87 | #if defined(CONFIG_IP_PIMSM_V1) || defined(CONFIG_IP_PIMSM_V2) | ||
88 | int mroute_reg_vif_num; | ||
89 | #endif | ||
90 | }; | ||
91 | |||
92 | struct ipmr_rule { | ||
93 | struct fib_rule common; | ||
94 | }; | ||
95 | |||
96 | struct ipmr_result { | ||
97 | struct mr_table *mrt; | ||
98 | }; | ||
99 | |||
71 | /* Big lock, protecting vif table, mrt cache and mroute socket state. | 100 | /* Big lock, protecting vif table, mrt cache and mroute socket state. |
72 | Note that the changes are semaphored via rtnl_lock. | 101 | Note that the changes are semaphored via rtnl_lock. |
73 | */ | 102 | */ |
@@ -78,9 +107,7 @@ static DEFINE_RWLOCK(mrt_lock); | |||
78 | * Multicast router control variables | 107 | * Multicast router control variables |
79 | */ | 108 | */ |
80 | 109 | ||
81 | #define VIF_EXISTS(_net, _idx) ((_net)->ipv4.vif_table[_idx].dev != NULL) | 110 | #define VIF_EXISTS(_mrt, _idx) ((_mrt)->vif_table[_idx].dev != NULL) |
82 | |||
83 | static struct mfc_cache *mfc_unres_queue; /* Queue of unresolved entries */ | ||
84 | 111 | ||
85 | /* Special spinlock for queue of unresolved entries */ | 112 | /* Special spinlock for queue of unresolved entries */ |
86 | static DEFINE_SPINLOCK(mfc_unres_lock); | 113 | static DEFINE_SPINLOCK(mfc_unres_lock); |
@@ -95,12 +122,215 @@ static DEFINE_SPINLOCK(mfc_unres_lock); | |||
95 | 122 | ||
96 | static struct kmem_cache *mrt_cachep __read_mostly; | 123 | static struct kmem_cache *mrt_cachep __read_mostly; |
97 | 124 | ||
98 | static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local); | 125 | static struct mr_table *ipmr_new_table(struct net *net, u32 id); |
99 | static int ipmr_cache_report(struct net *net, | 126 | static int ip_mr_forward(struct net *net, struct mr_table *mrt, |
127 | struct sk_buff *skb, struct mfc_cache *cache, | ||
128 | int local); | ||
129 | static int ipmr_cache_report(struct mr_table *mrt, | ||
100 | struct sk_buff *pkt, vifi_t vifi, int assert); | 130 | struct sk_buff *pkt, vifi_t vifi, int assert); |
101 | static int ipmr_fill_mroute(struct sk_buff *skb, struct mfc_cache *c, struct rtmsg *rtm); | 131 | static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, |
132 | struct mfc_cache *c, struct rtmsg *rtm); | ||
133 | static void ipmr_expire_process(unsigned long arg); | ||
134 | |||
135 | #ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES | ||
136 | #define ipmr_for_each_table(mrt, net) \ | ||
137 | list_for_each_entry_rcu(mrt, &net->ipv4.mr_tables, list) | ||
138 | |||
139 | static struct mr_table *ipmr_get_table(struct net *net, u32 id) | ||
140 | { | ||
141 | struct mr_table *mrt; | ||
142 | |||
143 | ipmr_for_each_table(mrt, net) { | ||
144 | if (mrt->id == id) | ||
145 | return mrt; | ||
146 | } | ||
147 | return NULL; | ||
148 | } | ||
149 | |||
150 | static int ipmr_fib_lookup(struct net *net, struct flowi *flp, | ||
151 | struct mr_table **mrt) | ||
152 | { | ||
153 | struct ipmr_result res; | ||
154 | struct fib_lookup_arg arg = { .result = &res, }; | ||
155 | int err; | ||
156 | |||
157 | err = fib_rules_lookup(net->ipv4.mr_rules_ops, flp, 0, &arg); | ||
158 | if (err < 0) | ||
159 | return err; | ||
160 | *mrt = res.mrt; | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static int ipmr_rule_action(struct fib_rule *rule, struct flowi *flp, | ||
165 | int flags, struct fib_lookup_arg *arg) | ||
166 | { | ||
167 | struct ipmr_result *res = arg->result; | ||
168 | struct mr_table *mrt; | ||
102 | 169 | ||
103 | static struct timer_list ipmr_expire_timer; | 170 | switch (rule->action) { |
171 | case FR_ACT_TO_TBL: | ||
172 | break; | ||
173 | case FR_ACT_UNREACHABLE: | ||
174 | return -ENETUNREACH; | ||
175 | case FR_ACT_PROHIBIT: | ||
176 | return -EACCES; | ||
177 | case FR_ACT_BLACKHOLE: | ||
178 | default: | ||
179 | return -EINVAL; | ||
180 | } | ||
181 | |||
182 | mrt = ipmr_get_table(rule->fr_net, rule->table); | ||
183 | if (mrt == NULL) | ||
184 | return -EAGAIN; | ||
185 | res->mrt = mrt; | ||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static int ipmr_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) | ||
190 | { | ||
191 | return 1; | ||
192 | } | ||
193 | |||
194 | static const struct nla_policy ipmr_rule_policy[FRA_MAX + 1] = { | ||
195 | FRA_GENERIC_POLICY, | ||
196 | }; | ||
197 | |||
198 | static int ipmr_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | ||
199 | struct fib_rule_hdr *frh, struct nlattr **tb) | ||
200 | { | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static int ipmr_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, | ||
205 | struct nlattr **tb) | ||
206 | { | ||
207 | return 1; | ||
208 | } | ||
209 | |||
210 | static int ipmr_rule_fill(struct fib_rule *rule, struct sk_buff *skb, | ||
211 | struct fib_rule_hdr *frh) | ||
212 | { | ||
213 | frh->dst_len = 0; | ||
214 | frh->src_len = 0; | ||
215 | frh->tos = 0; | ||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | static const struct fib_rules_ops __net_initdata ipmr_rules_ops_template = { | ||
220 | .family = RTNL_FAMILY_IPMR, | ||
221 | .rule_size = sizeof(struct ipmr_rule), | ||
222 | .addr_size = sizeof(u32), | ||
223 | .action = ipmr_rule_action, | ||
224 | .match = ipmr_rule_match, | ||
225 | .configure = ipmr_rule_configure, | ||
226 | .compare = ipmr_rule_compare, | ||
227 | .default_pref = fib_default_rule_pref, | ||
228 | .fill = ipmr_rule_fill, | ||
229 | .nlgroup = RTNLGRP_IPV4_RULE, | ||
230 | .policy = ipmr_rule_policy, | ||
231 | .owner = THIS_MODULE, | ||
232 | }; | ||
233 | |||
234 | static int __net_init ipmr_rules_init(struct net *net) | ||
235 | { | ||
236 | struct fib_rules_ops *ops; | ||
237 | struct mr_table *mrt; | ||
238 | int err; | ||
239 | |||
240 | ops = fib_rules_register(&ipmr_rules_ops_template, net); | ||
241 | if (IS_ERR(ops)) | ||
242 | return PTR_ERR(ops); | ||
243 | |||
244 | INIT_LIST_HEAD(&net->ipv4.mr_tables); | ||
245 | |||
246 | mrt = ipmr_new_table(net, RT_TABLE_DEFAULT); | ||
247 | if (mrt == NULL) { | ||
248 | err = -ENOMEM; | ||
249 | goto err1; | ||
250 | } | ||
251 | |||
252 | err = fib_default_rule_add(ops, 0x7fff, RT_TABLE_DEFAULT, 0); | ||
253 | if (err < 0) | ||
254 | goto err2; | ||
255 | |||
256 | net->ipv4.mr_rules_ops = ops; | ||
257 | return 0; | ||
258 | |||
259 | err2: | ||
260 | kfree(mrt); | ||
261 | err1: | ||
262 | fib_rules_unregister(ops); | ||
263 | return err; | ||
264 | } | ||
265 | |||
266 | static void __net_exit ipmr_rules_exit(struct net *net) | ||
267 | { | ||
268 | struct mr_table *mrt, *next; | ||
269 | |||
270 | list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list) | ||
271 | kfree(mrt); | ||
272 | fib_rules_unregister(net->ipv4.mr_rules_ops); | ||
273 | } | ||
274 | #else | ||
275 | #define ipmr_for_each_table(mrt, net) \ | ||
276 | for (mrt = net->ipv4.mrt; mrt; mrt = NULL) | ||
277 | |||
278 | static struct mr_table *ipmr_get_table(struct net *net, u32 id) | ||
279 | { | ||
280 | return net->ipv4.mrt; | ||
281 | } | ||
282 | |||
283 | static int ipmr_fib_lookup(struct net *net, struct flowi *flp, | ||
284 | struct mr_table **mrt) | ||
285 | { | ||
286 | *mrt = net->ipv4.mrt; | ||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | static int __net_init ipmr_rules_init(struct net *net) | ||
291 | { | ||
292 | net->ipv4.mrt = ipmr_new_table(net, RT_TABLE_DEFAULT); | ||
293 | return net->ipv4.mrt ? 0 : -ENOMEM; | ||
294 | } | ||
295 | |||
296 | static void __net_exit ipmr_rules_exit(struct net *net) | ||
297 | { | ||
298 | kfree(net->ipv4.mrt); | ||
299 | } | ||
300 | #endif | ||
301 | |||
302 | static struct mr_table *ipmr_new_table(struct net *net, u32 id) | ||
303 | { | ||
304 | struct mr_table *mrt; | ||
305 | unsigned int i; | ||
306 | |||
307 | mrt = ipmr_get_table(net, id); | ||
308 | if (mrt != NULL) | ||
309 | return mrt; | ||
310 | |||
311 | mrt = kzalloc(sizeof(*mrt), GFP_KERNEL); | ||
312 | if (mrt == NULL) | ||
313 | return NULL; | ||
314 | write_pnet(&mrt->net, net); | ||
315 | mrt->id = id; | ||
316 | |||
317 | /* Forwarding cache */ | ||
318 | for (i = 0; i < MFC_LINES; i++) | ||
319 | INIT_LIST_HEAD(&mrt->mfc_cache_array[i]); | ||
320 | |||
321 | INIT_LIST_HEAD(&mrt->mfc_unres_queue); | ||
322 | |||
323 | setup_timer(&mrt->ipmr_expire_timer, ipmr_expire_process, | ||
324 | (unsigned long)mrt); | ||
325 | |||
326 | #ifdef CONFIG_IP_PIMSM | ||
327 | mrt->mroute_reg_vif_num = -1; | ||
328 | #endif | ||
329 | #ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES | ||
330 | list_add_tail_rcu(&mrt->list, &net->ipv4.mr_tables); | ||
331 | #endif | ||
332 | return mrt; | ||
333 | } | ||
104 | 334 | ||
105 | /* Service routines creating virtual interfaces: DVMRP tunnels and PIMREG */ | 335 | /* Service routines creating virtual interfaces: DVMRP tunnels and PIMREG */ |
106 | 336 | ||
@@ -201,12 +431,22 @@ failure: | |||
201 | static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, struct net_device *dev) | 431 | static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, struct net_device *dev) |
202 | { | 432 | { |
203 | struct net *net = dev_net(dev); | 433 | struct net *net = dev_net(dev); |
434 | struct mr_table *mrt; | ||
435 | struct flowi fl = { | ||
436 | .oif = dev->ifindex, | ||
437 | .iif = skb->skb_iif, | ||
438 | .mark = skb->mark, | ||
439 | }; | ||
440 | int err; | ||
441 | |||
442 | err = ipmr_fib_lookup(net, &fl, &mrt); | ||
443 | if (err < 0) | ||
444 | return err; | ||
204 | 445 | ||
205 | read_lock(&mrt_lock); | 446 | read_lock(&mrt_lock); |
206 | dev->stats.tx_bytes += skb->len; | 447 | dev->stats.tx_bytes += skb->len; |
207 | dev->stats.tx_packets++; | 448 | dev->stats.tx_packets++; |
208 | ipmr_cache_report(net, skb, net->ipv4.mroute_reg_vif_num, | 449 | ipmr_cache_report(mrt, skb, mrt->mroute_reg_vif_num, IGMPMSG_WHOLEPKT); |
209 | IGMPMSG_WHOLEPKT); | ||
210 | read_unlock(&mrt_lock); | 450 | read_unlock(&mrt_lock); |
211 | kfree_skb(skb); | 451 | kfree_skb(skb); |
212 | return NETDEV_TX_OK; | 452 | return NETDEV_TX_OK; |
@@ -226,12 +466,18 @@ static void reg_vif_setup(struct net_device *dev) | |||
226 | dev->features |= NETIF_F_NETNS_LOCAL; | 466 | dev->features |= NETIF_F_NETNS_LOCAL; |
227 | } | 467 | } |
228 | 468 | ||
229 | static struct net_device *ipmr_reg_vif(struct net *net) | 469 | static struct net_device *ipmr_reg_vif(struct net *net, struct mr_table *mrt) |
230 | { | 470 | { |
231 | struct net_device *dev; | 471 | struct net_device *dev; |
232 | struct in_device *in_dev; | 472 | struct in_device *in_dev; |
473 | char name[IFNAMSIZ]; | ||
474 | |||
475 | if (mrt->id == RT_TABLE_DEFAULT) | ||
476 | sprintf(name, "pimreg"); | ||
477 | else | ||
478 | sprintf(name, "pimreg%u", mrt->id); | ||
233 | 479 | ||
234 | dev = alloc_netdev(0, "pimreg", reg_vif_setup); | 480 | dev = alloc_netdev(0, name, reg_vif_setup); |
235 | 481 | ||
236 | if (dev == NULL) | 482 | if (dev == NULL) |
237 | return NULL; | 483 | return NULL; |
@@ -276,17 +522,17 @@ failure: | |||
276 | * @notify: Set to 1, if the caller is a notifier_call | 522 | * @notify: Set to 1, if the caller is a notifier_call |
277 | */ | 523 | */ |
278 | 524 | ||
279 | static int vif_delete(struct net *net, int vifi, int notify, | 525 | static int vif_delete(struct mr_table *mrt, int vifi, int notify, |
280 | struct list_head *head) | 526 | struct list_head *head) |
281 | { | 527 | { |
282 | struct vif_device *v; | 528 | struct vif_device *v; |
283 | struct net_device *dev; | 529 | struct net_device *dev; |
284 | struct in_device *in_dev; | 530 | struct in_device *in_dev; |
285 | 531 | ||
286 | if (vifi < 0 || vifi >= net->ipv4.maxvif) | 532 | if (vifi < 0 || vifi >= mrt->maxvif) |
287 | return -EADDRNOTAVAIL; | 533 | return -EADDRNOTAVAIL; |
288 | 534 | ||
289 | v = &net->ipv4.vif_table[vifi]; | 535 | v = &mrt->vif_table[vifi]; |
290 | 536 | ||
291 | write_lock_bh(&mrt_lock); | 537 | write_lock_bh(&mrt_lock); |
292 | dev = v->dev; | 538 | dev = v->dev; |
@@ -298,17 +544,17 @@ static int vif_delete(struct net *net, int vifi, int notify, | |||
298 | } | 544 | } |
299 | 545 | ||
300 | #ifdef CONFIG_IP_PIMSM | 546 | #ifdef CONFIG_IP_PIMSM |
301 | if (vifi == net->ipv4.mroute_reg_vif_num) | 547 | if (vifi == mrt->mroute_reg_vif_num) |
302 | net->ipv4.mroute_reg_vif_num = -1; | 548 | mrt->mroute_reg_vif_num = -1; |
303 | #endif | 549 | #endif |
304 | 550 | ||
305 | if (vifi+1 == net->ipv4.maxvif) { | 551 | if (vifi+1 == mrt->maxvif) { |
306 | int tmp; | 552 | int tmp; |
307 | for (tmp=vifi-1; tmp>=0; tmp--) { | 553 | for (tmp=vifi-1; tmp>=0; tmp--) { |
308 | if (VIF_EXISTS(net, tmp)) | 554 | if (VIF_EXISTS(mrt, tmp)) |
309 | break; | 555 | break; |
310 | } | 556 | } |
311 | net->ipv4.maxvif = tmp+1; | 557 | mrt->maxvif = tmp+1; |
312 | } | 558 | } |
313 | 559 | ||
314 | write_unlock_bh(&mrt_lock); | 560 | write_unlock_bh(&mrt_lock); |
@@ -329,7 +575,6 @@ static int vif_delete(struct net *net, int vifi, int notify, | |||
329 | 575 | ||
330 | static inline void ipmr_cache_free(struct mfc_cache *c) | 576 | static inline void ipmr_cache_free(struct mfc_cache *c) |
331 | { | 577 | { |
332 | release_net(mfc_net(c)); | ||
333 | kmem_cache_free(mrt_cachep, c); | 578 | kmem_cache_free(mrt_cachep, c); |
334 | } | 579 | } |
335 | 580 | ||
@@ -337,13 +582,13 @@ static inline void ipmr_cache_free(struct mfc_cache *c) | |||
337 | and reporting error to netlink readers. | 582 | and reporting error to netlink readers. |
338 | */ | 583 | */ |
339 | 584 | ||
340 | static void ipmr_destroy_unres(struct mfc_cache *c) | 585 | static void ipmr_destroy_unres(struct mr_table *mrt, struct mfc_cache *c) |
341 | { | 586 | { |
587 | struct net *net = read_pnet(&mrt->net); | ||
342 | struct sk_buff *skb; | 588 | struct sk_buff *skb; |
343 | struct nlmsgerr *e; | 589 | struct nlmsgerr *e; |
344 | struct net *net = mfc_net(c); | ||
345 | 590 | ||
346 | atomic_dec(&net->ipv4.cache_resolve_queue_len); | 591 | atomic_dec(&mrt->cache_resolve_queue_len); |
347 | 592 | ||
348 | while ((skb = skb_dequeue(&c->mfc_un.unres.unresolved))) { | 593 | while ((skb = skb_dequeue(&c->mfc_un.unres.unresolved))) { |
349 | if (ip_hdr(skb)->version == 0) { | 594 | if (ip_hdr(skb)->version == 0) { |
@@ -364,42 +609,40 @@ static void ipmr_destroy_unres(struct mfc_cache *c) | |||
364 | } | 609 | } |
365 | 610 | ||
366 | 611 | ||
367 | /* Single timer process for all the unresolved queue. */ | 612 | /* Timer process for the unresolved queue. */ |
368 | 613 | ||
369 | static void ipmr_expire_process(unsigned long dummy) | 614 | static void ipmr_expire_process(unsigned long arg) |
370 | { | 615 | { |
616 | struct mr_table *mrt = (struct mr_table *)arg; | ||
371 | unsigned long now; | 617 | unsigned long now; |
372 | unsigned long expires; | 618 | unsigned long expires; |
373 | struct mfc_cache *c, **cp; | 619 | struct mfc_cache *c, *next; |
374 | 620 | ||
375 | if (!spin_trylock(&mfc_unres_lock)) { | 621 | if (!spin_trylock(&mfc_unres_lock)) { |
376 | mod_timer(&ipmr_expire_timer, jiffies+HZ/10); | 622 | mod_timer(&mrt->ipmr_expire_timer, jiffies+HZ/10); |
377 | return; | 623 | return; |
378 | } | 624 | } |
379 | 625 | ||
380 | if (mfc_unres_queue == NULL) | 626 | if (list_empty(&mrt->mfc_unres_queue)) |
381 | goto out; | 627 | goto out; |
382 | 628 | ||
383 | now = jiffies; | 629 | now = jiffies; |
384 | expires = 10*HZ; | 630 | expires = 10*HZ; |
385 | cp = &mfc_unres_queue; | ||
386 | 631 | ||
387 | while ((c=*cp) != NULL) { | 632 | list_for_each_entry_safe(c, next, &mrt->mfc_unres_queue, list) { |
388 | if (time_after(c->mfc_un.unres.expires, now)) { | 633 | if (time_after(c->mfc_un.unres.expires, now)) { |
389 | unsigned long interval = c->mfc_un.unres.expires - now; | 634 | unsigned long interval = c->mfc_un.unres.expires - now; |
390 | if (interval < expires) | 635 | if (interval < expires) |
391 | expires = interval; | 636 | expires = interval; |
392 | cp = &c->next; | ||
393 | continue; | 637 | continue; |
394 | } | 638 | } |
395 | 639 | ||
396 | *cp = c->next; | 640 | list_del(&c->list); |
397 | 641 | ipmr_destroy_unres(mrt, c); | |
398 | ipmr_destroy_unres(c); | ||
399 | } | 642 | } |
400 | 643 | ||
401 | if (mfc_unres_queue != NULL) | 644 | if (!list_empty(&mrt->mfc_unres_queue)) |
402 | mod_timer(&ipmr_expire_timer, jiffies + expires); | 645 | mod_timer(&mrt->ipmr_expire_timer, jiffies + expires); |
403 | 646 | ||
404 | out: | 647 | out: |
405 | spin_unlock(&mfc_unres_lock); | 648 | spin_unlock(&mfc_unres_lock); |
@@ -407,17 +650,17 @@ out: | |||
407 | 650 | ||
408 | /* Fill oifs list. It is called under write locked mrt_lock. */ | 651 | /* Fill oifs list. It is called under write locked mrt_lock. */ |
409 | 652 | ||
410 | static void ipmr_update_thresholds(struct mfc_cache *cache, unsigned char *ttls) | 653 | static void ipmr_update_thresholds(struct mr_table *mrt, struct mfc_cache *cache, |
654 | unsigned char *ttls) | ||
411 | { | 655 | { |
412 | int vifi; | 656 | int vifi; |
413 | struct net *net = mfc_net(cache); | ||
414 | 657 | ||
415 | cache->mfc_un.res.minvif = MAXVIFS; | 658 | cache->mfc_un.res.minvif = MAXVIFS; |
416 | cache->mfc_un.res.maxvif = 0; | 659 | cache->mfc_un.res.maxvif = 0; |
417 | memset(cache->mfc_un.res.ttls, 255, MAXVIFS); | 660 | memset(cache->mfc_un.res.ttls, 255, MAXVIFS); |
418 | 661 | ||
419 | for (vifi = 0; vifi < net->ipv4.maxvif; vifi++) { | 662 | for (vifi = 0; vifi < mrt->maxvif; vifi++) { |
420 | if (VIF_EXISTS(net, vifi) && | 663 | if (VIF_EXISTS(mrt, vifi) && |
421 | ttls[vifi] && ttls[vifi] < 255) { | 664 | ttls[vifi] && ttls[vifi] < 255) { |
422 | cache->mfc_un.res.ttls[vifi] = ttls[vifi]; | 665 | cache->mfc_un.res.ttls[vifi] = ttls[vifi]; |
423 | if (cache->mfc_un.res.minvif > vifi) | 666 | if (cache->mfc_un.res.minvif > vifi) |
@@ -428,16 +671,17 @@ static void ipmr_update_thresholds(struct mfc_cache *cache, unsigned char *ttls) | |||
428 | } | 671 | } |
429 | } | 672 | } |
430 | 673 | ||
431 | static int vif_add(struct net *net, struct vifctl *vifc, int mrtsock) | 674 | static int vif_add(struct net *net, struct mr_table *mrt, |
675 | struct vifctl *vifc, int mrtsock) | ||
432 | { | 676 | { |
433 | int vifi = vifc->vifc_vifi; | 677 | int vifi = vifc->vifc_vifi; |
434 | struct vif_device *v = &net->ipv4.vif_table[vifi]; | 678 | struct vif_device *v = &mrt->vif_table[vifi]; |
435 | struct net_device *dev; | 679 | struct net_device *dev; |
436 | struct in_device *in_dev; | 680 | struct in_device *in_dev; |
437 | int err; | 681 | int err; |
438 | 682 | ||
439 | /* Is vif busy ? */ | 683 | /* Is vif busy ? */ |
440 | if (VIF_EXISTS(net, vifi)) | 684 | if (VIF_EXISTS(mrt, vifi)) |
441 | return -EADDRINUSE; | 685 | return -EADDRINUSE; |
442 | 686 | ||
443 | switch (vifc->vifc_flags) { | 687 | switch (vifc->vifc_flags) { |
@@ -447,9 +691,9 @@ static int vif_add(struct net *net, struct vifctl *vifc, int mrtsock) | |||
447 | * Special Purpose VIF in PIM | 691 | * Special Purpose VIF in PIM |
448 | * All the packets will be sent to the daemon | 692 | * All the packets will be sent to the daemon |
449 | */ | 693 | */ |
450 | if (net->ipv4.mroute_reg_vif_num >= 0) | 694 | if (mrt->mroute_reg_vif_num >= 0) |
451 | return -EADDRINUSE; | 695 | return -EADDRINUSE; |
452 | dev = ipmr_reg_vif(net); | 696 | dev = ipmr_reg_vif(net, mrt); |
453 | if (!dev) | 697 | if (!dev) |
454 | return -ENOBUFS; | 698 | return -ENOBUFS; |
455 | err = dev_set_allmulti(dev, 1); | 699 | err = dev_set_allmulti(dev, 1); |
@@ -525,49 +769,47 @@ static int vif_add(struct net *net, struct vifctl *vifc, int mrtsock) | |||
525 | v->dev = dev; | 769 | v->dev = dev; |
526 | #ifdef CONFIG_IP_PIMSM | 770 | #ifdef CONFIG_IP_PIMSM |
527 | if (v->flags&VIFF_REGISTER) | 771 | if (v->flags&VIFF_REGISTER) |
528 | net->ipv4.mroute_reg_vif_num = vifi; | 772 | mrt->mroute_reg_vif_num = vifi; |
529 | #endif | 773 | #endif |
530 | if (vifi+1 > net->ipv4.maxvif) | 774 | if (vifi+1 > mrt->maxvif) |
531 | net->ipv4.maxvif = vifi+1; | 775 | mrt->maxvif = vifi+1; |
532 | write_unlock_bh(&mrt_lock); | 776 | write_unlock_bh(&mrt_lock); |
533 | return 0; | 777 | return 0; |
534 | } | 778 | } |
535 | 779 | ||
536 | static struct mfc_cache *ipmr_cache_find(struct net *net, | 780 | static struct mfc_cache *ipmr_cache_find(struct mr_table *mrt, |
537 | __be32 origin, | 781 | __be32 origin, |
538 | __be32 mcastgrp) | 782 | __be32 mcastgrp) |
539 | { | 783 | { |
540 | int line = MFC_HASH(mcastgrp, origin); | 784 | int line = MFC_HASH(mcastgrp, origin); |
541 | struct mfc_cache *c; | 785 | struct mfc_cache *c; |
542 | 786 | ||
543 | for (c = net->ipv4.mfc_cache_array[line]; c; c = c->next) { | 787 | list_for_each_entry(c, &mrt->mfc_cache_array[line], list) { |
544 | if (c->mfc_origin==origin && c->mfc_mcastgrp==mcastgrp) | 788 | if (c->mfc_origin == origin && c->mfc_mcastgrp == mcastgrp) |
545 | break; | 789 | return c; |
546 | } | 790 | } |
547 | return c; | 791 | return NULL; |
548 | } | 792 | } |
549 | 793 | ||
550 | /* | 794 | /* |
551 | * Allocate a multicast cache entry | 795 | * Allocate a multicast cache entry |
552 | */ | 796 | */ |
553 | static struct mfc_cache *ipmr_cache_alloc(struct net *net) | 797 | static struct mfc_cache *ipmr_cache_alloc(void) |
554 | { | 798 | { |
555 | struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL); | 799 | struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL); |
556 | if (c == NULL) | 800 | if (c == NULL) |
557 | return NULL; | 801 | return NULL; |
558 | c->mfc_un.res.minvif = MAXVIFS; | 802 | c->mfc_un.res.minvif = MAXVIFS; |
559 | mfc_net_set(c, net); | ||
560 | return c; | 803 | return c; |
561 | } | 804 | } |
562 | 805 | ||
563 | static struct mfc_cache *ipmr_cache_alloc_unres(struct net *net) | 806 | static struct mfc_cache *ipmr_cache_alloc_unres(void) |
564 | { | 807 | { |
565 | struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC); | 808 | struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC); |
566 | if (c == NULL) | 809 | if (c == NULL) |
567 | return NULL; | 810 | return NULL; |
568 | skb_queue_head_init(&c->mfc_un.unres.unresolved); | 811 | skb_queue_head_init(&c->mfc_un.unres.unresolved); |
569 | c->mfc_un.unres.expires = jiffies + 10*HZ; | 812 | c->mfc_un.unres.expires = jiffies + 10*HZ; |
570 | mfc_net_set(c, net); | ||
571 | return c; | 813 | return c; |
572 | } | 814 | } |
573 | 815 | ||
@@ -575,7 +817,8 @@ static struct mfc_cache *ipmr_cache_alloc_unres(struct net *net) | |||
575 | * A cache entry has gone into a resolved state from queued | 817 | * A cache entry has gone into a resolved state from queued |
576 | */ | 818 | */ |
577 | 819 | ||
578 | static void ipmr_cache_resolve(struct mfc_cache *uc, struct mfc_cache *c) | 820 | static void ipmr_cache_resolve(struct net *net, struct mr_table *mrt, |
821 | struct mfc_cache *uc, struct mfc_cache *c) | ||
579 | { | 822 | { |
580 | struct sk_buff *skb; | 823 | struct sk_buff *skb; |
581 | struct nlmsgerr *e; | 824 | struct nlmsgerr *e; |
@@ -588,7 +831,7 @@ static void ipmr_cache_resolve(struct mfc_cache *uc, struct mfc_cache *c) | |||
588 | if (ip_hdr(skb)->version == 0) { | 831 | if (ip_hdr(skb)->version == 0) { |
589 | struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct iphdr)); | 832 | struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct iphdr)); |
590 | 833 | ||
591 | if (ipmr_fill_mroute(skb, c, NLMSG_DATA(nlh)) > 0) { | 834 | if (__ipmr_fill_mroute(mrt, skb, c, NLMSG_DATA(nlh)) > 0) { |
592 | nlh->nlmsg_len = (skb_tail_pointer(skb) - | 835 | nlh->nlmsg_len = (skb_tail_pointer(skb) - |
593 | (u8 *)nlh); | 836 | (u8 *)nlh); |
594 | } else { | 837 | } else { |
@@ -600,9 +843,9 @@ static void ipmr_cache_resolve(struct mfc_cache *uc, struct mfc_cache *c) | |||
600 | memset(&e->msg, 0, sizeof(e->msg)); | 843 | memset(&e->msg, 0, sizeof(e->msg)); |
601 | } | 844 | } |
602 | 845 | ||
603 | rtnl_unicast(skb, mfc_net(c), NETLINK_CB(skb).pid); | 846 | rtnl_unicast(skb, net, NETLINK_CB(skb).pid); |
604 | } else | 847 | } else |
605 | ip_mr_forward(skb, c, 0); | 848 | ip_mr_forward(net, mrt, skb, c, 0); |
606 | } | 849 | } |
607 | } | 850 | } |
608 | 851 | ||
@@ -613,7 +856,7 @@ static void ipmr_cache_resolve(struct mfc_cache *uc, struct mfc_cache *c) | |||
613 | * Called under mrt_lock. | 856 | * Called under mrt_lock. |
614 | */ | 857 | */ |
615 | 858 | ||
616 | static int ipmr_cache_report(struct net *net, | 859 | static int ipmr_cache_report(struct mr_table *mrt, |
617 | struct sk_buff *pkt, vifi_t vifi, int assert) | 860 | struct sk_buff *pkt, vifi_t vifi, int assert) |
618 | { | 861 | { |
619 | struct sk_buff *skb; | 862 | struct sk_buff *skb; |
@@ -646,7 +889,7 @@ static int ipmr_cache_report(struct net *net, | |||
646 | memcpy(msg, skb_network_header(pkt), sizeof(struct iphdr)); | 889 | memcpy(msg, skb_network_header(pkt), sizeof(struct iphdr)); |
647 | msg->im_msgtype = IGMPMSG_WHOLEPKT; | 890 | msg->im_msgtype = IGMPMSG_WHOLEPKT; |
648 | msg->im_mbz = 0; | 891 | msg->im_mbz = 0; |
649 | msg->im_vif = net->ipv4.mroute_reg_vif_num; | 892 | msg->im_vif = mrt->mroute_reg_vif_num; |
650 | ip_hdr(skb)->ihl = sizeof(struct iphdr) >> 2; | 893 | ip_hdr(skb)->ihl = sizeof(struct iphdr) >> 2; |
651 | ip_hdr(skb)->tot_len = htons(ntohs(ip_hdr(pkt)->tot_len) + | 894 | ip_hdr(skb)->tot_len = htons(ntohs(ip_hdr(pkt)->tot_len) + |
652 | sizeof(struct iphdr)); | 895 | sizeof(struct iphdr)); |
@@ -678,7 +921,7 @@ static int ipmr_cache_report(struct net *net, | |||
678 | skb->transport_header = skb->network_header; | 921 | skb->transport_header = skb->network_header; |
679 | } | 922 | } |
680 | 923 | ||
681 | if (net->ipv4.mroute_sk == NULL) { | 924 | if (mrt->mroute_sk == NULL) { |
682 | kfree_skb(skb); | 925 | kfree_skb(skb); |
683 | return -EINVAL; | 926 | return -EINVAL; |
684 | } | 927 | } |
@@ -686,7 +929,7 @@ static int ipmr_cache_report(struct net *net, | |||
686 | /* | 929 | /* |
687 | * Deliver to mrouted | 930 | * Deliver to mrouted |
688 | */ | 931 | */ |
689 | ret = sock_queue_rcv_skb(net->ipv4.mroute_sk, skb); | 932 | ret = sock_queue_rcv_skb(mrt->mroute_sk, skb); |
690 | if (ret < 0) { | 933 | if (ret < 0) { |
691 | if (net_ratelimit()) | 934 | if (net_ratelimit()) |
692 | printk(KERN_WARNING "mroute: pending queue full, dropping entries.\n"); | 935 | printk(KERN_WARNING "mroute: pending queue full, dropping entries.\n"); |
@@ -701,27 +944,29 @@ static int ipmr_cache_report(struct net *net, | |||
701 | */ | 944 | */ |
702 | 945 | ||
703 | static int | 946 | static int |
704 | ipmr_cache_unresolved(struct net *net, vifi_t vifi, struct sk_buff *skb) | 947 | ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi, struct sk_buff *skb) |
705 | { | 948 | { |
949 | bool found = false; | ||
706 | int err; | 950 | int err; |
707 | struct mfc_cache *c; | 951 | struct mfc_cache *c; |
708 | const struct iphdr *iph = ip_hdr(skb); | 952 | const struct iphdr *iph = ip_hdr(skb); |
709 | 953 | ||
710 | spin_lock_bh(&mfc_unres_lock); | 954 | spin_lock_bh(&mfc_unres_lock); |
711 | for (c=mfc_unres_queue; c; c=c->next) { | 955 | list_for_each_entry(c, &mrt->mfc_unres_queue, list) { |
712 | if (net_eq(mfc_net(c), net) && | 956 | if (c->mfc_mcastgrp == iph->daddr && |
713 | c->mfc_mcastgrp == iph->daddr && | 957 | c->mfc_origin == iph->saddr) { |
714 | c->mfc_origin == iph->saddr) | 958 | found = true; |
715 | break; | 959 | break; |
960 | } | ||
716 | } | 961 | } |
717 | 962 | ||
718 | if (c == NULL) { | 963 | if (!found) { |
719 | /* | 964 | /* |
720 | * Create a new entry if allowable | 965 | * Create a new entry if allowable |
721 | */ | 966 | */ |
722 | 967 | ||
723 | if (atomic_read(&net->ipv4.cache_resolve_queue_len) >= 10 || | 968 | if (atomic_read(&mrt->cache_resolve_queue_len) >= 10 || |
724 | (c = ipmr_cache_alloc_unres(net)) == NULL) { | 969 | (c = ipmr_cache_alloc_unres()) == NULL) { |
725 | spin_unlock_bh(&mfc_unres_lock); | 970 | spin_unlock_bh(&mfc_unres_lock); |
726 | 971 | ||
727 | kfree_skb(skb); | 972 | kfree_skb(skb); |
@@ -738,7 +983,7 @@ ipmr_cache_unresolved(struct net *net, vifi_t vifi, struct sk_buff *skb) | |||
738 | /* | 983 | /* |
739 | * Reflect first query at mrouted. | 984 | * Reflect first query at mrouted. |
740 | */ | 985 | */ |
741 | err = ipmr_cache_report(net, skb, vifi, IGMPMSG_NOCACHE); | 986 | err = ipmr_cache_report(mrt, skb, vifi, IGMPMSG_NOCACHE); |
742 | if (err < 0) { | 987 | if (err < 0) { |
743 | /* If the report failed throw the cache entry | 988 | /* If the report failed throw the cache entry |
744 | out - Brad Parker | 989 | out - Brad Parker |
@@ -750,12 +995,11 @@ ipmr_cache_unresolved(struct net *net, vifi_t vifi, struct sk_buff *skb) | |||
750 | return err; | 995 | return err; |
751 | } | 996 | } |
752 | 997 | ||
753 | atomic_inc(&net->ipv4.cache_resolve_queue_len); | 998 | atomic_inc(&mrt->cache_resolve_queue_len); |
754 | c->next = mfc_unres_queue; | 999 | list_add(&c->list, &mrt->mfc_unres_queue); |
755 | mfc_unres_queue = c; | ||
756 | 1000 | ||
757 | if (atomic_read(&net->ipv4.cache_resolve_queue_len) == 1) | 1001 | if (atomic_read(&mrt->cache_resolve_queue_len) == 1) |
758 | mod_timer(&ipmr_expire_timer, c->mfc_un.unres.expires); | 1002 | mod_timer(&mrt->ipmr_expire_timer, c->mfc_un.unres.expires); |
759 | } | 1003 | } |
760 | 1004 | ||
761 | /* | 1005 | /* |
@@ -777,19 +1021,18 @@ ipmr_cache_unresolved(struct net *net, vifi_t vifi, struct sk_buff *skb) | |||
777 | * MFC cache manipulation by user space mroute daemon | 1021 | * MFC cache manipulation by user space mroute daemon |
778 | */ | 1022 | */ |
779 | 1023 | ||
780 | static int ipmr_mfc_delete(struct net *net, struct mfcctl *mfc) | 1024 | static int ipmr_mfc_delete(struct mr_table *mrt, struct mfcctl *mfc) |
781 | { | 1025 | { |
782 | int line; | 1026 | int line; |
783 | struct mfc_cache *c, **cp; | 1027 | struct mfc_cache *c, *next; |
784 | 1028 | ||
785 | line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr); | 1029 | line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr); |
786 | 1030 | ||
787 | for (cp = &net->ipv4.mfc_cache_array[line]; | 1031 | list_for_each_entry_safe(c, next, &mrt->mfc_cache_array[line], list) { |
788 | (c = *cp) != NULL; cp = &c->next) { | ||
789 | if (c->mfc_origin == mfc->mfcc_origin.s_addr && | 1032 | if (c->mfc_origin == mfc->mfcc_origin.s_addr && |
790 | c->mfc_mcastgrp == mfc->mfcc_mcastgrp.s_addr) { | 1033 | c->mfc_mcastgrp == mfc->mfcc_mcastgrp.s_addr) { |
791 | write_lock_bh(&mrt_lock); | 1034 | write_lock_bh(&mrt_lock); |
792 | *cp = c->next; | 1035 | list_del(&c->list); |
793 | write_unlock_bh(&mrt_lock); | 1036 | write_unlock_bh(&mrt_lock); |
794 | 1037 | ||
795 | ipmr_cache_free(c); | 1038 | ipmr_cache_free(c); |
@@ -799,27 +1042,30 @@ static int ipmr_mfc_delete(struct net *net, struct mfcctl *mfc) | |||
799 | return -ENOENT; | 1042 | return -ENOENT; |
800 | } | 1043 | } |
801 | 1044 | ||
802 | static int ipmr_mfc_add(struct net *net, struct mfcctl *mfc, int mrtsock) | 1045 | static int ipmr_mfc_add(struct net *net, struct mr_table *mrt, |
1046 | struct mfcctl *mfc, int mrtsock) | ||
803 | { | 1047 | { |
1048 | bool found = false; | ||
804 | int line; | 1049 | int line; |
805 | struct mfc_cache *uc, *c, **cp; | 1050 | struct mfc_cache *uc, *c; |
806 | 1051 | ||
807 | if (mfc->mfcc_parent >= MAXVIFS) | 1052 | if (mfc->mfcc_parent >= MAXVIFS) |
808 | return -ENFILE; | 1053 | return -ENFILE; |
809 | 1054 | ||
810 | line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr); | 1055 | line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr); |
811 | 1056 | ||
812 | for (cp = &net->ipv4.mfc_cache_array[line]; | 1057 | list_for_each_entry(c, &mrt->mfc_cache_array[line], list) { |
813 | (c = *cp) != NULL; cp = &c->next) { | ||
814 | if (c->mfc_origin == mfc->mfcc_origin.s_addr && | 1058 | if (c->mfc_origin == mfc->mfcc_origin.s_addr && |
815 | c->mfc_mcastgrp == mfc->mfcc_mcastgrp.s_addr) | 1059 | c->mfc_mcastgrp == mfc->mfcc_mcastgrp.s_addr) { |
1060 | found = true; | ||
816 | break; | 1061 | break; |
1062 | } | ||
817 | } | 1063 | } |
818 | 1064 | ||
819 | if (c != NULL) { | 1065 | if (found) { |
820 | write_lock_bh(&mrt_lock); | 1066 | write_lock_bh(&mrt_lock); |
821 | c->mfc_parent = mfc->mfcc_parent; | 1067 | c->mfc_parent = mfc->mfcc_parent; |
822 | ipmr_update_thresholds(c, mfc->mfcc_ttls); | 1068 | ipmr_update_thresholds(mrt, c, mfc->mfcc_ttls); |
823 | if (!mrtsock) | 1069 | if (!mrtsock) |
824 | c->mfc_flags |= MFC_STATIC; | 1070 | c->mfc_flags |= MFC_STATIC; |
825 | write_unlock_bh(&mrt_lock); | 1071 | write_unlock_bh(&mrt_lock); |
@@ -829,43 +1075,42 @@ static int ipmr_mfc_add(struct net *net, struct mfcctl *mfc, int mrtsock) | |||
829 | if (!ipv4_is_multicast(mfc->mfcc_mcastgrp.s_addr)) | 1075 | if (!ipv4_is_multicast(mfc->mfcc_mcastgrp.s_addr)) |
830 | return -EINVAL; | 1076 | return -EINVAL; |
831 | 1077 | ||
832 | c = ipmr_cache_alloc(net); | 1078 | c = ipmr_cache_alloc(); |
833 | if (c == NULL) | 1079 | if (c == NULL) |
834 | return -ENOMEM; | 1080 | return -ENOMEM; |
835 | 1081 | ||
836 | c->mfc_origin = mfc->mfcc_origin.s_addr; | 1082 | c->mfc_origin = mfc->mfcc_origin.s_addr; |
837 | c->mfc_mcastgrp = mfc->mfcc_mcastgrp.s_addr; | 1083 | c->mfc_mcastgrp = mfc->mfcc_mcastgrp.s_addr; |
838 | c->mfc_parent = mfc->mfcc_parent; | 1084 | c->mfc_parent = mfc->mfcc_parent; |
839 | ipmr_update_thresholds(c, mfc->mfcc_ttls); | 1085 | ipmr_update_thresholds(mrt, c, mfc->mfcc_ttls); |
840 | if (!mrtsock) | 1086 | if (!mrtsock) |
841 | c->mfc_flags |= MFC_STATIC; | 1087 | c->mfc_flags |= MFC_STATIC; |
842 | 1088 | ||
843 | write_lock_bh(&mrt_lock); | 1089 | write_lock_bh(&mrt_lock); |
844 | c->next = net->ipv4.mfc_cache_array[line]; | 1090 | list_add(&c->list, &mrt->mfc_cache_array[line]); |
845 | net->ipv4.mfc_cache_array[line] = c; | ||
846 | write_unlock_bh(&mrt_lock); | 1091 | write_unlock_bh(&mrt_lock); |
847 | 1092 | ||
848 | /* | 1093 | /* |
849 | * Check to see if we resolved a queued list. If so we | 1094 | * Check to see if we resolved a queued list. If so we |
850 | * need to send on the frames and tidy up. | 1095 | * need to send on the frames and tidy up. |
851 | */ | 1096 | */ |
1097 | found = false; | ||
852 | spin_lock_bh(&mfc_unres_lock); | 1098 | spin_lock_bh(&mfc_unres_lock); |
853 | for (cp = &mfc_unres_queue; (uc=*cp) != NULL; | 1099 | list_for_each_entry(uc, &mrt->mfc_unres_queue, list) { |
854 | cp = &uc->next) { | 1100 | if (uc->mfc_origin == c->mfc_origin && |
855 | if (net_eq(mfc_net(uc), net) && | ||
856 | uc->mfc_origin == c->mfc_origin && | ||
857 | uc->mfc_mcastgrp == c->mfc_mcastgrp) { | 1101 | uc->mfc_mcastgrp == c->mfc_mcastgrp) { |
858 | *cp = uc->next; | 1102 | list_del(&uc->list); |
859 | atomic_dec(&net->ipv4.cache_resolve_queue_len); | 1103 | atomic_dec(&mrt->cache_resolve_queue_len); |
1104 | found = true; | ||
860 | break; | 1105 | break; |
861 | } | 1106 | } |
862 | } | 1107 | } |
863 | if (mfc_unres_queue == NULL) | 1108 | if (list_empty(&mrt->mfc_unres_queue)) |
864 | del_timer(&ipmr_expire_timer); | 1109 | del_timer(&mrt->ipmr_expire_timer); |
865 | spin_unlock_bh(&mfc_unres_lock); | 1110 | spin_unlock_bh(&mfc_unres_lock); |
866 | 1111 | ||
867 | if (uc) { | 1112 | if (found) { |
868 | ipmr_cache_resolve(uc, c); | 1113 | ipmr_cache_resolve(net, mrt, uc, c); |
869 | ipmr_cache_free(uc); | 1114 | ipmr_cache_free(uc); |
870 | } | 1115 | } |
871 | return 0; | 1116 | return 0; |
@@ -875,53 +1120,41 @@ static int ipmr_mfc_add(struct net *net, struct mfcctl *mfc, int mrtsock) | |||
875 | * Close the multicast socket, and clear the vif tables etc | 1120 | * Close the multicast socket, and clear the vif tables etc |
876 | */ | 1121 | */ |
877 | 1122 | ||
878 | static void mroute_clean_tables(struct net *net) | 1123 | static void mroute_clean_tables(struct mr_table *mrt) |
879 | { | 1124 | { |
880 | int i; | 1125 | int i; |
881 | LIST_HEAD(list); | 1126 | LIST_HEAD(list); |
1127 | struct mfc_cache *c, *next; | ||
882 | 1128 | ||
883 | /* | 1129 | /* |
884 | * Shut down all active vif entries | 1130 | * Shut down all active vif entries |
885 | */ | 1131 | */ |
886 | for (i = 0; i < net->ipv4.maxvif; i++) { | 1132 | for (i = 0; i < mrt->maxvif; i++) { |
887 | if (!(net->ipv4.vif_table[i].flags&VIFF_STATIC)) | 1133 | if (!(mrt->vif_table[i].flags&VIFF_STATIC)) |
888 | vif_delete(net, i, 0, &list); | 1134 | vif_delete(mrt, i, 0, &list); |
889 | } | 1135 | } |
890 | unregister_netdevice_many(&list); | 1136 | unregister_netdevice_many(&list); |
891 | 1137 | ||
892 | /* | 1138 | /* |
893 | * Wipe the cache | 1139 | * Wipe the cache |
894 | */ | 1140 | */ |
895 | for (i=0; i<MFC_LINES; i++) { | 1141 | for (i = 0; i < MFC_LINES; i++) { |
896 | struct mfc_cache *c, **cp; | 1142 | list_for_each_entry_safe(c, next, &mrt->mfc_cache_array[i], list) { |
897 | 1143 | if (c->mfc_flags&MFC_STATIC) | |
898 | cp = &net->ipv4.mfc_cache_array[i]; | ||
899 | while ((c = *cp) != NULL) { | ||
900 | if (c->mfc_flags&MFC_STATIC) { | ||
901 | cp = &c->next; | ||
902 | continue; | 1144 | continue; |
903 | } | ||
904 | write_lock_bh(&mrt_lock); | 1145 | write_lock_bh(&mrt_lock); |
905 | *cp = c->next; | 1146 | list_del(&c->list); |
906 | write_unlock_bh(&mrt_lock); | 1147 | write_unlock_bh(&mrt_lock); |
907 | 1148 | ||
908 | ipmr_cache_free(c); | 1149 | ipmr_cache_free(c); |
909 | } | 1150 | } |
910 | } | 1151 | } |
911 | 1152 | ||
912 | if (atomic_read(&net->ipv4.cache_resolve_queue_len) != 0) { | 1153 | if (atomic_read(&mrt->cache_resolve_queue_len) != 0) { |
913 | struct mfc_cache *c, **cp; | ||
914 | |||
915 | spin_lock_bh(&mfc_unres_lock); | 1154 | spin_lock_bh(&mfc_unres_lock); |
916 | cp = &mfc_unres_queue; | 1155 | list_for_each_entry_safe(c, next, &mrt->mfc_unres_queue, list) { |
917 | while ((c = *cp) != NULL) { | 1156 | list_del(&c->list); |
918 | if (!net_eq(mfc_net(c), net)) { | 1157 | ipmr_destroy_unres(mrt, c); |
919 | cp = &c->next; | ||
920 | continue; | ||
921 | } | ||
922 | *cp = c->next; | ||
923 | |||
924 | ipmr_destroy_unres(c); | ||
925 | } | 1158 | } |
926 | spin_unlock_bh(&mfc_unres_lock); | 1159 | spin_unlock_bh(&mfc_unres_lock); |
927 | } | 1160 | } |
@@ -930,16 +1163,19 @@ static void mroute_clean_tables(struct net *net) | |||
930 | static void mrtsock_destruct(struct sock *sk) | 1163 | static void mrtsock_destruct(struct sock *sk) |
931 | { | 1164 | { |
932 | struct net *net = sock_net(sk); | 1165 | struct net *net = sock_net(sk); |
1166 | struct mr_table *mrt; | ||
933 | 1167 | ||
934 | rtnl_lock(); | 1168 | rtnl_lock(); |
935 | if (sk == net->ipv4.mroute_sk) { | 1169 | ipmr_for_each_table(mrt, net) { |
936 | IPV4_DEVCONF_ALL(net, MC_FORWARDING)--; | 1170 | if (sk == mrt->mroute_sk) { |
1171 | IPV4_DEVCONF_ALL(net, MC_FORWARDING)--; | ||
937 | 1172 | ||
938 | write_lock_bh(&mrt_lock); | 1173 | write_lock_bh(&mrt_lock); |
939 | net->ipv4.mroute_sk = NULL; | 1174 | mrt->mroute_sk = NULL; |
940 | write_unlock_bh(&mrt_lock); | 1175 | write_unlock_bh(&mrt_lock); |
941 | 1176 | ||
942 | mroute_clean_tables(net); | 1177 | mroute_clean_tables(mrt); |
1178 | } | ||
943 | } | 1179 | } |
944 | rtnl_unlock(); | 1180 | rtnl_unlock(); |
945 | } | 1181 | } |
@@ -957,9 +1193,14 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi | |||
957 | struct vifctl vif; | 1193 | struct vifctl vif; |
958 | struct mfcctl mfc; | 1194 | struct mfcctl mfc; |
959 | struct net *net = sock_net(sk); | 1195 | struct net *net = sock_net(sk); |
1196 | struct mr_table *mrt; | ||
1197 | |||
1198 | mrt = ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT); | ||
1199 | if (mrt == NULL) | ||
1200 | return -ENOENT; | ||
960 | 1201 | ||
961 | if (optname != MRT_INIT) { | 1202 | if (optname != MRT_INIT) { |
962 | if (sk != net->ipv4.mroute_sk && !capable(CAP_NET_ADMIN)) | 1203 | if (sk != mrt->mroute_sk && !capable(CAP_NET_ADMIN)) |
963 | return -EACCES; | 1204 | return -EACCES; |
964 | } | 1205 | } |
965 | 1206 | ||
@@ -972,7 +1213,7 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi | |||
972 | return -ENOPROTOOPT; | 1213 | return -ENOPROTOOPT; |
973 | 1214 | ||
974 | rtnl_lock(); | 1215 | rtnl_lock(); |
975 | if (net->ipv4.mroute_sk) { | 1216 | if (mrt->mroute_sk) { |
976 | rtnl_unlock(); | 1217 | rtnl_unlock(); |
977 | return -EADDRINUSE; | 1218 | return -EADDRINUSE; |
978 | } | 1219 | } |
@@ -980,7 +1221,7 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi | |||
980 | ret = ip_ra_control(sk, 1, mrtsock_destruct); | 1221 | ret = ip_ra_control(sk, 1, mrtsock_destruct); |
981 | if (ret == 0) { | 1222 | if (ret == 0) { |
982 | write_lock_bh(&mrt_lock); | 1223 | write_lock_bh(&mrt_lock); |
983 | net->ipv4.mroute_sk = sk; | 1224 | mrt->mroute_sk = sk; |
984 | write_unlock_bh(&mrt_lock); | 1225 | write_unlock_bh(&mrt_lock); |
985 | 1226 | ||
986 | IPV4_DEVCONF_ALL(net, MC_FORWARDING)++; | 1227 | IPV4_DEVCONF_ALL(net, MC_FORWARDING)++; |
@@ -988,7 +1229,7 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi | |||
988 | rtnl_unlock(); | 1229 | rtnl_unlock(); |
989 | return ret; | 1230 | return ret; |
990 | case MRT_DONE: | 1231 | case MRT_DONE: |
991 | if (sk != net->ipv4.mroute_sk) | 1232 | if (sk != mrt->mroute_sk) |
992 | return -EACCES; | 1233 | return -EACCES; |
993 | return ip_ra_control(sk, 0, NULL); | 1234 | return ip_ra_control(sk, 0, NULL); |
994 | case MRT_ADD_VIF: | 1235 | case MRT_ADD_VIF: |
@@ -1001,9 +1242,9 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi | |||
1001 | return -ENFILE; | 1242 | return -ENFILE; |
1002 | rtnl_lock(); | 1243 | rtnl_lock(); |
1003 | if (optname == MRT_ADD_VIF) { | 1244 | if (optname == MRT_ADD_VIF) { |
1004 | ret = vif_add(net, &vif, sk == net->ipv4.mroute_sk); | 1245 | ret = vif_add(net, mrt, &vif, sk == mrt->mroute_sk); |
1005 | } else { | 1246 | } else { |
1006 | ret = vif_delete(net, vif.vifc_vifi, 0, NULL); | 1247 | ret = vif_delete(mrt, vif.vifc_vifi, 0, NULL); |
1007 | } | 1248 | } |
1008 | rtnl_unlock(); | 1249 | rtnl_unlock(); |
1009 | return ret; | 1250 | return ret; |
@@ -1020,9 +1261,9 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi | |||
1020 | return -EFAULT; | 1261 | return -EFAULT; |
1021 | rtnl_lock(); | 1262 | rtnl_lock(); |
1022 | if (optname == MRT_DEL_MFC) | 1263 | if (optname == MRT_DEL_MFC) |
1023 | ret = ipmr_mfc_delete(net, &mfc); | 1264 | ret = ipmr_mfc_delete(mrt, &mfc); |
1024 | else | 1265 | else |
1025 | ret = ipmr_mfc_add(net, &mfc, sk == net->ipv4.mroute_sk); | 1266 | ret = ipmr_mfc_add(net, mrt, &mfc, sk == mrt->mroute_sk); |
1026 | rtnl_unlock(); | 1267 | rtnl_unlock(); |
1027 | return ret; | 1268 | return ret; |
1028 | /* | 1269 | /* |
@@ -1033,7 +1274,7 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi | |||
1033 | int v; | 1274 | int v; |
1034 | if (get_user(v,(int __user *)optval)) | 1275 | if (get_user(v,(int __user *)optval)) |
1035 | return -EFAULT; | 1276 | return -EFAULT; |
1036 | net->ipv4.mroute_do_assert = (v) ? 1 : 0; | 1277 | mrt->mroute_do_assert = (v) ? 1 : 0; |
1037 | return 0; | 1278 | return 0; |
1038 | } | 1279 | } |
1039 | #ifdef CONFIG_IP_PIMSM | 1280 | #ifdef CONFIG_IP_PIMSM |
@@ -1047,14 +1288,35 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi | |||
1047 | 1288 | ||
1048 | rtnl_lock(); | 1289 | rtnl_lock(); |
1049 | ret = 0; | 1290 | ret = 0; |
1050 | if (v != net->ipv4.mroute_do_pim) { | 1291 | if (v != mrt->mroute_do_pim) { |
1051 | net->ipv4.mroute_do_pim = v; | 1292 | mrt->mroute_do_pim = v; |
1052 | net->ipv4.mroute_do_assert = v; | 1293 | mrt->mroute_do_assert = v; |
1053 | } | 1294 | } |
1054 | rtnl_unlock(); | 1295 | rtnl_unlock(); |
1055 | return ret; | 1296 | return ret; |
1056 | } | 1297 | } |
1057 | #endif | 1298 | #endif |
1299 | #ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES | ||
1300 | case MRT_TABLE: | ||
1301 | { | ||
1302 | u32 v; | ||
1303 | |||
1304 | if (optlen != sizeof(u32)) | ||
1305 | return -EINVAL; | ||
1306 | if (get_user(v, (u32 __user *)optval)) | ||
1307 | return -EFAULT; | ||
1308 | if (sk == mrt->mroute_sk) | ||
1309 | return -EBUSY; | ||
1310 | |||
1311 | rtnl_lock(); | ||
1312 | ret = 0; | ||
1313 | if (!ipmr_new_table(net, v)) | ||
1314 | ret = -ENOMEM; | ||
1315 | raw_sk(sk)->ipmr_table = v; | ||
1316 | rtnl_unlock(); | ||
1317 | return ret; | ||
1318 | } | ||
1319 | #endif | ||
1058 | /* | 1320 | /* |
1059 | * Spurious command, or MRT_VERSION which you cannot | 1321 | * Spurious command, or MRT_VERSION which you cannot |
1060 | * set. | 1322 | * set. |
@@ -1073,6 +1335,11 @@ int ip_mroute_getsockopt(struct sock *sk, int optname, char __user *optval, int | |||
1073 | int olr; | 1335 | int olr; |
1074 | int val; | 1336 | int val; |
1075 | struct net *net = sock_net(sk); | 1337 | struct net *net = sock_net(sk); |
1338 | struct mr_table *mrt; | ||
1339 | |||
1340 | mrt = ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT); | ||
1341 | if (mrt == NULL) | ||
1342 | return -ENOENT; | ||
1076 | 1343 | ||
1077 | if (optname != MRT_VERSION && | 1344 | if (optname != MRT_VERSION && |
1078 | #ifdef CONFIG_IP_PIMSM | 1345 | #ifdef CONFIG_IP_PIMSM |
@@ -1094,10 +1361,10 @@ int ip_mroute_getsockopt(struct sock *sk, int optname, char __user *optval, int | |||
1094 | val = 0x0305; | 1361 | val = 0x0305; |
1095 | #ifdef CONFIG_IP_PIMSM | 1362 | #ifdef CONFIG_IP_PIMSM |
1096 | else if (optname == MRT_PIM) | 1363 | else if (optname == MRT_PIM) |
1097 | val = net->ipv4.mroute_do_pim; | 1364 | val = mrt->mroute_do_pim; |
1098 | #endif | 1365 | #endif |
1099 | else | 1366 | else |
1100 | val = net->ipv4.mroute_do_assert; | 1367 | val = mrt->mroute_do_assert; |
1101 | if (copy_to_user(optval, &val, olr)) | 1368 | if (copy_to_user(optval, &val, olr)) |
1102 | return -EFAULT; | 1369 | return -EFAULT; |
1103 | return 0; | 1370 | return 0; |
@@ -1114,16 +1381,21 @@ int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg) | |||
1114 | struct vif_device *vif; | 1381 | struct vif_device *vif; |
1115 | struct mfc_cache *c; | 1382 | struct mfc_cache *c; |
1116 | struct net *net = sock_net(sk); | 1383 | struct net *net = sock_net(sk); |
1384 | struct mr_table *mrt; | ||
1385 | |||
1386 | mrt = ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT); | ||
1387 | if (mrt == NULL) | ||
1388 | return -ENOENT; | ||
1117 | 1389 | ||
1118 | switch (cmd) { | 1390 | switch (cmd) { |
1119 | case SIOCGETVIFCNT: | 1391 | case SIOCGETVIFCNT: |
1120 | if (copy_from_user(&vr, arg, sizeof(vr))) | 1392 | if (copy_from_user(&vr, arg, sizeof(vr))) |
1121 | return -EFAULT; | 1393 | return -EFAULT; |
1122 | if (vr.vifi >= net->ipv4.maxvif) | 1394 | if (vr.vifi >= mrt->maxvif) |
1123 | return -EINVAL; | 1395 | return -EINVAL; |
1124 | read_lock(&mrt_lock); | 1396 | read_lock(&mrt_lock); |
1125 | vif = &net->ipv4.vif_table[vr.vifi]; | 1397 | vif = &mrt->vif_table[vr.vifi]; |
1126 | if (VIF_EXISTS(net, vr.vifi)) { | 1398 | if (VIF_EXISTS(mrt, vr.vifi)) { |
1127 | vr.icount = vif->pkt_in; | 1399 | vr.icount = vif->pkt_in; |
1128 | vr.ocount = vif->pkt_out; | 1400 | vr.ocount = vif->pkt_out; |
1129 | vr.ibytes = vif->bytes_in; | 1401 | vr.ibytes = vif->bytes_in; |
@@ -1141,7 +1413,7 @@ int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg) | |||
1141 | return -EFAULT; | 1413 | return -EFAULT; |
1142 | 1414 | ||
1143 | read_lock(&mrt_lock); | 1415 | read_lock(&mrt_lock); |
1144 | c = ipmr_cache_find(net, sr.src.s_addr, sr.grp.s_addr); | 1416 | c = ipmr_cache_find(mrt, sr.src.s_addr, sr.grp.s_addr); |
1145 | if (c) { | 1417 | if (c) { |
1146 | sr.pktcnt = c->mfc_un.res.pkt; | 1418 | sr.pktcnt = c->mfc_un.res.pkt; |
1147 | sr.bytecnt = c->mfc_un.res.bytes; | 1419 | sr.bytecnt = c->mfc_un.res.bytes; |
@@ -1164,16 +1436,20 @@ static int ipmr_device_event(struct notifier_block *this, unsigned long event, v | |||
1164 | { | 1436 | { |
1165 | struct net_device *dev = ptr; | 1437 | struct net_device *dev = ptr; |
1166 | struct net *net = dev_net(dev); | 1438 | struct net *net = dev_net(dev); |
1439 | struct mr_table *mrt; | ||
1167 | struct vif_device *v; | 1440 | struct vif_device *v; |
1168 | int ct; | 1441 | int ct; |
1169 | LIST_HEAD(list); | 1442 | LIST_HEAD(list); |
1170 | 1443 | ||
1171 | if (event != NETDEV_UNREGISTER) | 1444 | if (event != NETDEV_UNREGISTER) |
1172 | return NOTIFY_DONE; | 1445 | return NOTIFY_DONE; |
1173 | v = &net->ipv4.vif_table[0]; | 1446 | |
1174 | for (ct = 0; ct < net->ipv4.maxvif; ct++, v++) { | 1447 | ipmr_for_each_table(mrt, net) { |
1175 | if (v->dev == dev) | 1448 | v = &mrt->vif_table[0]; |
1176 | vif_delete(net, ct, 1, &list); | 1449 | for (ct = 0; ct < mrt->maxvif; ct++, v++) { |
1450 | if (v->dev == dev) | ||
1451 | vif_delete(mrt, ct, 1, &list); | ||
1452 | } | ||
1177 | } | 1453 | } |
1178 | unregister_netdevice_many(&list); | 1454 | unregister_netdevice_many(&list); |
1179 | return NOTIFY_DONE; | 1455 | return NOTIFY_DONE; |
@@ -1232,11 +1508,11 @@ static inline int ipmr_forward_finish(struct sk_buff *skb) | |||
1232 | * Processing handlers for ipmr_forward | 1508 | * Processing handlers for ipmr_forward |
1233 | */ | 1509 | */ |
1234 | 1510 | ||
1235 | static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi) | 1511 | static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, |
1512 | struct sk_buff *skb, struct mfc_cache *c, int vifi) | ||
1236 | { | 1513 | { |
1237 | struct net *net = mfc_net(c); | ||
1238 | const struct iphdr *iph = ip_hdr(skb); | 1514 | const struct iphdr *iph = ip_hdr(skb); |
1239 | struct vif_device *vif = &net->ipv4.vif_table[vifi]; | 1515 | struct vif_device *vif = &mrt->vif_table[vifi]; |
1240 | struct net_device *dev; | 1516 | struct net_device *dev; |
1241 | struct rtable *rt; | 1517 | struct rtable *rt; |
1242 | int encap = 0; | 1518 | int encap = 0; |
@@ -1250,7 +1526,7 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi) | |||
1250 | vif->bytes_out += skb->len; | 1526 | vif->bytes_out += skb->len; |
1251 | vif->dev->stats.tx_bytes += skb->len; | 1527 | vif->dev->stats.tx_bytes += skb->len; |
1252 | vif->dev->stats.tx_packets++; | 1528 | vif->dev->stats.tx_packets++; |
1253 | ipmr_cache_report(net, skb, vifi, IGMPMSG_WHOLEPKT); | 1529 | ipmr_cache_report(mrt, skb, vifi, IGMPMSG_WHOLEPKT); |
1254 | goto out_free; | 1530 | goto out_free; |
1255 | } | 1531 | } |
1256 | #endif | 1532 | #endif |
@@ -1324,21 +1600,20 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi) | |||
1324 | * not mrouter) cannot join to more than one interface - it will | 1600 | * not mrouter) cannot join to more than one interface - it will |
1325 | * result in receiving multiple packets. | 1601 | * result in receiving multiple packets. |
1326 | */ | 1602 | */ |
1327 | NF_HOOK(PF_INET, NF_INET_FORWARD, skb, skb->dev, dev, | 1603 | NF_HOOK(NFPROTO_IPV4, NF_INET_FORWARD, skb, skb->dev, dev, |
1328 | ipmr_forward_finish); | 1604 | ipmr_forward_finish); |
1329 | return; | 1605 | return; |
1330 | 1606 | ||
1331 | out_free: | 1607 | out_free: |
1332 | kfree_skb(skb); | 1608 | kfree_skb(skb); |
1333 | return; | ||
1334 | } | 1609 | } |
1335 | 1610 | ||
1336 | static int ipmr_find_vif(struct net_device *dev) | 1611 | static int ipmr_find_vif(struct mr_table *mrt, struct net_device *dev) |
1337 | { | 1612 | { |
1338 | struct net *net = dev_net(dev); | ||
1339 | int ct; | 1613 | int ct; |
1340 | for (ct = net->ipv4.maxvif-1; ct >= 0; ct--) { | 1614 | |
1341 | if (net->ipv4.vif_table[ct].dev == dev) | 1615 | for (ct = mrt->maxvif-1; ct >= 0; ct--) { |
1616 | if (mrt->vif_table[ct].dev == dev) | ||
1342 | break; | 1617 | break; |
1343 | } | 1618 | } |
1344 | return ct; | 1619 | return ct; |
@@ -1346,11 +1621,12 @@ static int ipmr_find_vif(struct net_device *dev) | |||
1346 | 1621 | ||
1347 | /* "local" means that we should preserve one skb (for local delivery) */ | 1622 | /* "local" means that we should preserve one skb (for local delivery) */ |
1348 | 1623 | ||
1349 | static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local) | 1624 | static int ip_mr_forward(struct net *net, struct mr_table *mrt, |
1625 | struct sk_buff *skb, struct mfc_cache *cache, | ||
1626 | int local) | ||
1350 | { | 1627 | { |
1351 | int psend = -1; | 1628 | int psend = -1; |
1352 | int vif, ct; | 1629 | int vif, ct; |
1353 | struct net *net = mfc_net(cache); | ||
1354 | 1630 | ||
1355 | vif = cache->mfc_parent; | 1631 | vif = cache->mfc_parent; |
1356 | cache->mfc_un.res.pkt++; | 1632 | cache->mfc_un.res.pkt++; |
@@ -1359,7 +1635,7 @@ static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local | |||
1359 | /* | 1635 | /* |
1360 | * Wrong interface: drop packet and (maybe) send PIM assert. | 1636 | * Wrong interface: drop packet and (maybe) send PIM assert. |
1361 | */ | 1637 | */ |
1362 | if (net->ipv4.vif_table[vif].dev != skb->dev) { | 1638 | if (mrt->vif_table[vif].dev != skb->dev) { |
1363 | int true_vifi; | 1639 | int true_vifi; |
1364 | 1640 | ||
1365 | if (skb_rtable(skb)->fl.iif == 0) { | 1641 | if (skb_rtable(skb)->fl.iif == 0) { |
@@ -1378,26 +1654,26 @@ static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local | |||
1378 | } | 1654 | } |
1379 | 1655 | ||
1380 | cache->mfc_un.res.wrong_if++; | 1656 | cache->mfc_un.res.wrong_if++; |
1381 | true_vifi = ipmr_find_vif(skb->dev); | 1657 | true_vifi = ipmr_find_vif(mrt, skb->dev); |
1382 | 1658 | ||
1383 | if (true_vifi >= 0 && net->ipv4.mroute_do_assert && | 1659 | if (true_vifi >= 0 && mrt->mroute_do_assert && |
1384 | /* pimsm uses asserts, when switching from RPT to SPT, | 1660 | /* pimsm uses asserts, when switching from RPT to SPT, |
1385 | so that we cannot check that packet arrived on an oif. | 1661 | so that we cannot check that packet arrived on an oif. |
1386 | It is bad, but otherwise we would need to move pretty | 1662 | It is bad, but otherwise we would need to move pretty |
1387 | large chunk of pimd to kernel. Ough... --ANK | 1663 | large chunk of pimd to kernel. Ough... --ANK |
1388 | */ | 1664 | */ |
1389 | (net->ipv4.mroute_do_pim || | 1665 | (mrt->mroute_do_pim || |
1390 | cache->mfc_un.res.ttls[true_vifi] < 255) && | 1666 | cache->mfc_un.res.ttls[true_vifi] < 255) && |
1391 | time_after(jiffies, | 1667 | time_after(jiffies, |
1392 | cache->mfc_un.res.last_assert + MFC_ASSERT_THRESH)) { | 1668 | cache->mfc_un.res.last_assert + MFC_ASSERT_THRESH)) { |
1393 | cache->mfc_un.res.last_assert = jiffies; | 1669 | cache->mfc_un.res.last_assert = jiffies; |
1394 | ipmr_cache_report(net, skb, true_vifi, IGMPMSG_WRONGVIF); | 1670 | ipmr_cache_report(mrt, skb, true_vifi, IGMPMSG_WRONGVIF); |
1395 | } | 1671 | } |
1396 | goto dont_forward; | 1672 | goto dont_forward; |
1397 | } | 1673 | } |
1398 | 1674 | ||
1399 | net->ipv4.vif_table[vif].pkt_in++; | 1675 | mrt->vif_table[vif].pkt_in++; |
1400 | net->ipv4.vif_table[vif].bytes_in += skb->len; | 1676 | mrt->vif_table[vif].bytes_in += skb->len; |
1401 | 1677 | ||
1402 | /* | 1678 | /* |
1403 | * Forward the frame | 1679 | * Forward the frame |
@@ -1407,7 +1683,8 @@ static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local | |||
1407 | if (psend != -1) { | 1683 | if (psend != -1) { |
1408 | struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); | 1684 | struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); |
1409 | if (skb2) | 1685 | if (skb2) |
1410 | ipmr_queue_xmit(skb2, cache, psend); | 1686 | ipmr_queue_xmit(net, mrt, skb2, cache, |
1687 | psend); | ||
1411 | } | 1688 | } |
1412 | psend = ct; | 1689 | psend = ct; |
1413 | } | 1690 | } |
@@ -1416,9 +1693,9 @@ static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local | |||
1416 | if (local) { | 1693 | if (local) { |
1417 | struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); | 1694 | struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); |
1418 | if (skb2) | 1695 | if (skb2) |
1419 | ipmr_queue_xmit(skb2, cache, psend); | 1696 | ipmr_queue_xmit(net, mrt, skb2, cache, psend); |
1420 | } else { | 1697 | } else { |
1421 | ipmr_queue_xmit(skb, cache, psend); | 1698 | ipmr_queue_xmit(net, mrt, skb, cache, psend); |
1422 | return 0; | 1699 | return 0; |
1423 | } | 1700 | } |
1424 | } | 1701 | } |
@@ -1439,6 +1716,8 @@ int ip_mr_input(struct sk_buff *skb) | |||
1439 | struct mfc_cache *cache; | 1716 | struct mfc_cache *cache; |
1440 | struct net *net = dev_net(skb->dev); | 1717 | struct net *net = dev_net(skb->dev); |
1441 | int local = skb_rtable(skb)->rt_flags & RTCF_LOCAL; | 1718 | int local = skb_rtable(skb)->rt_flags & RTCF_LOCAL; |
1719 | struct mr_table *mrt; | ||
1720 | int err; | ||
1442 | 1721 | ||
1443 | /* Packet is looped back after forward, it should not be | 1722 | /* Packet is looped back after forward, it should not be |
1444 | forwarded second time, but still can be delivered locally. | 1723 | forwarded second time, but still can be delivered locally. |
@@ -1446,6 +1725,10 @@ int ip_mr_input(struct sk_buff *skb) | |||
1446 | if (IPCB(skb)->flags&IPSKB_FORWARDED) | 1725 | if (IPCB(skb)->flags&IPSKB_FORWARDED) |
1447 | goto dont_forward; | 1726 | goto dont_forward; |
1448 | 1727 | ||
1728 | err = ipmr_fib_lookup(net, &skb_rtable(skb)->fl, &mrt); | ||
1729 | if (err < 0) | ||
1730 | return err; | ||
1731 | |||
1449 | if (!local) { | 1732 | if (!local) { |
1450 | if (IPCB(skb)->opt.router_alert) { | 1733 | if (IPCB(skb)->opt.router_alert) { |
1451 | if (ip_call_ra_chain(skb)) | 1734 | if (ip_call_ra_chain(skb)) |
@@ -1458,9 +1741,9 @@ int ip_mr_input(struct sk_buff *skb) | |||
1458 | that we can forward NO IGMP messages. | 1741 | that we can forward NO IGMP messages. |
1459 | */ | 1742 | */ |
1460 | read_lock(&mrt_lock); | 1743 | read_lock(&mrt_lock); |
1461 | if (net->ipv4.mroute_sk) { | 1744 | if (mrt->mroute_sk) { |
1462 | nf_reset(skb); | 1745 | nf_reset(skb); |
1463 | raw_rcv(net->ipv4.mroute_sk, skb); | 1746 | raw_rcv(mrt->mroute_sk, skb); |
1464 | read_unlock(&mrt_lock); | 1747 | read_unlock(&mrt_lock); |
1465 | return 0; | 1748 | return 0; |
1466 | } | 1749 | } |
@@ -1469,7 +1752,7 @@ int ip_mr_input(struct sk_buff *skb) | |||
1469 | } | 1752 | } |
1470 | 1753 | ||
1471 | read_lock(&mrt_lock); | 1754 | read_lock(&mrt_lock); |
1472 | cache = ipmr_cache_find(net, ip_hdr(skb)->saddr, ip_hdr(skb)->daddr); | 1755 | cache = ipmr_cache_find(mrt, ip_hdr(skb)->saddr, ip_hdr(skb)->daddr); |
1473 | 1756 | ||
1474 | /* | 1757 | /* |
1475 | * No usable cache entry | 1758 | * No usable cache entry |
@@ -1487,19 +1770,19 @@ int ip_mr_input(struct sk_buff *skb) | |||
1487 | skb = skb2; | 1770 | skb = skb2; |
1488 | } | 1771 | } |
1489 | 1772 | ||
1490 | vif = ipmr_find_vif(skb->dev); | 1773 | vif = ipmr_find_vif(mrt, skb->dev); |
1491 | if (vif >= 0) { | 1774 | if (vif >= 0) { |
1492 | int err = ipmr_cache_unresolved(net, vif, skb); | 1775 | int err2 = ipmr_cache_unresolved(mrt, vif, skb); |
1493 | read_unlock(&mrt_lock); | 1776 | read_unlock(&mrt_lock); |
1494 | 1777 | ||
1495 | return err; | 1778 | return err2; |
1496 | } | 1779 | } |
1497 | read_unlock(&mrt_lock); | 1780 | read_unlock(&mrt_lock); |
1498 | kfree_skb(skb); | 1781 | kfree_skb(skb); |
1499 | return -ENODEV; | 1782 | return -ENODEV; |
1500 | } | 1783 | } |
1501 | 1784 | ||
1502 | ip_mr_forward(skb, cache, local); | 1785 | ip_mr_forward(net, mrt, skb, cache, local); |
1503 | 1786 | ||
1504 | read_unlock(&mrt_lock); | 1787 | read_unlock(&mrt_lock); |
1505 | 1788 | ||
@@ -1516,11 +1799,11 @@ dont_forward: | |||
1516 | } | 1799 | } |
1517 | 1800 | ||
1518 | #ifdef CONFIG_IP_PIMSM | 1801 | #ifdef CONFIG_IP_PIMSM |
1519 | static int __pim_rcv(struct sk_buff *skb, unsigned int pimlen) | 1802 | static int __pim_rcv(struct mr_table *mrt, struct sk_buff *skb, |
1803 | unsigned int pimlen) | ||
1520 | { | 1804 | { |
1521 | struct net_device *reg_dev = NULL; | 1805 | struct net_device *reg_dev = NULL; |
1522 | struct iphdr *encap; | 1806 | struct iphdr *encap; |
1523 | struct net *net = dev_net(skb->dev); | ||
1524 | 1807 | ||
1525 | encap = (struct iphdr *)(skb_transport_header(skb) + pimlen); | 1808 | encap = (struct iphdr *)(skb_transport_header(skb) + pimlen); |
1526 | /* | 1809 | /* |
@@ -1535,8 +1818,8 @@ static int __pim_rcv(struct sk_buff *skb, unsigned int pimlen) | |||
1535 | return 1; | 1818 | return 1; |
1536 | 1819 | ||
1537 | read_lock(&mrt_lock); | 1820 | read_lock(&mrt_lock); |
1538 | if (net->ipv4.mroute_reg_vif_num >= 0) | 1821 | if (mrt->mroute_reg_vif_num >= 0) |
1539 | reg_dev = net->ipv4.vif_table[net->ipv4.mroute_reg_vif_num].dev; | 1822 | reg_dev = mrt->vif_table[mrt->mroute_reg_vif_num].dev; |
1540 | if (reg_dev) | 1823 | if (reg_dev) |
1541 | dev_hold(reg_dev); | 1824 | dev_hold(reg_dev); |
1542 | read_unlock(&mrt_lock); | 1825 | read_unlock(&mrt_lock); |
@@ -1547,14 +1830,12 @@ static int __pim_rcv(struct sk_buff *skb, unsigned int pimlen) | |||
1547 | skb->mac_header = skb->network_header; | 1830 | skb->mac_header = skb->network_header; |
1548 | skb_pull(skb, (u8*)encap - skb->data); | 1831 | skb_pull(skb, (u8*)encap - skb->data); |
1549 | skb_reset_network_header(skb); | 1832 | skb_reset_network_header(skb); |
1550 | skb->dev = reg_dev; | ||
1551 | skb->protocol = htons(ETH_P_IP); | 1833 | skb->protocol = htons(ETH_P_IP); |
1552 | skb->ip_summed = 0; | 1834 | skb->ip_summed = 0; |
1553 | skb->pkt_type = PACKET_HOST; | 1835 | skb->pkt_type = PACKET_HOST; |
1554 | skb_dst_drop(skb); | 1836 | |
1555 | reg_dev->stats.rx_bytes += skb->len; | 1837 | skb_tunnel_rx(skb, reg_dev); |
1556 | reg_dev->stats.rx_packets++; | 1838 | |
1557 | nf_reset(skb); | ||
1558 | netif_rx(skb); | 1839 | netif_rx(skb); |
1559 | dev_put(reg_dev); | 1840 | dev_put(reg_dev); |
1560 | 1841 | ||
@@ -1571,17 +1852,21 @@ int pim_rcv_v1(struct sk_buff * skb) | |||
1571 | { | 1852 | { |
1572 | struct igmphdr *pim; | 1853 | struct igmphdr *pim; |
1573 | struct net *net = dev_net(skb->dev); | 1854 | struct net *net = dev_net(skb->dev); |
1855 | struct mr_table *mrt; | ||
1574 | 1856 | ||
1575 | if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(struct iphdr))) | 1857 | if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(struct iphdr))) |
1576 | goto drop; | 1858 | goto drop; |
1577 | 1859 | ||
1578 | pim = igmp_hdr(skb); | 1860 | pim = igmp_hdr(skb); |
1579 | 1861 | ||
1580 | if (!net->ipv4.mroute_do_pim || | 1862 | if (ipmr_fib_lookup(net, &skb_rtable(skb)->fl, &mrt) < 0) |
1863 | goto drop; | ||
1864 | |||
1865 | if (!mrt->mroute_do_pim || | ||
1581 | pim->group != PIM_V1_VERSION || pim->code != PIM_V1_REGISTER) | 1866 | pim->group != PIM_V1_VERSION || pim->code != PIM_V1_REGISTER) |
1582 | goto drop; | 1867 | goto drop; |
1583 | 1868 | ||
1584 | if (__pim_rcv(skb, sizeof(*pim))) { | 1869 | if (__pim_rcv(mrt, skb, sizeof(*pim))) { |
1585 | drop: | 1870 | drop: |
1586 | kfree_skb(skb); | 1871 | kfree_skb(skb); |
1587 | } | 1872 | } |
@@ -1593,6 +1878,8 @@ drop: | |||
1593 | static int pim_rcv(struct sk_buff * skb) | 1878 | static int pim_rcv(struct sk_buff * skb) |
1594 | { | 1879 | { |
1595 | struct pimreghdr *pim; | 1880 | struct pimreghdr *pim; |
1881 | struct net *net = dev_net(skb->dev); | ||
1882 | struct mr_table *mrt; | ||
1596 | 1883 | ||
1597 | if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(struct iphdr))) | 1884 | if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(struct iphdr))) |
1598 | goto drop; | 1885 | goto drop; |
@@ -1604,7 +1891,10 @@ static int pim_rcv(struct sk_buff * skb) | |||
1604 | csum_fold(skb_checksum(skb, 0, skb->len, 0)))) | 1891 | csum_fold(skb_checksum(skb, 0, skb->len, 0)))) |
1605 | goto drop; | 1892 | goto drop; |
1606 | 1893 | ||
1607 | if (__pim_rcv(skb, sizeof(*pim))) { | 1894 | if (ipmr_fib_lookup(net, &skb_rtable(skb)->fl, &mrt) < 0) |
1895 | goto drop; | ||
1896 | |||
1897 | if (__pim_rcv(mrt, skb, sizeof(*pim))) { | ||
1608 | drop: | 1898 | drop: |
1609 | kfree_skb(skb); | 1899 | kfree_skb(skb); |
1610 | } | 1900 | } |
@@ -1612,12 +1902,11 @@ drop: | |||
1612 | } | 1902 | } |
1613 | #endif | 1903 | #endif |
1614 | 1904 | ||
1615 | static int | 1905 | static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, |
1616 | ipmr_fill_mroute(struct sk_buff *skb, struct mfc_cache *c, struct rtmsg *rtm) | 1906 | struct mfc_cache *c, struct rtmsg *rtm) |
1617 | { | 1907 | { |
1618 | int ct; | 1908 | int ct; |
1619 | struct rtnexthop *nhp; | 1909 | struct rtnexthop *nhp; |
1620 | struct net *net = mfc_net(c); | ||
1621 | u8 *b = skb_tail_pointer(skb); | 1910 | u8 *b = skb_tail_pointer(skb); |
1622 | struct rtattr *mp_head; | 1911 | struct rtattr *mp_head; |
1623 | 1912 | ||
@@ -1625,19 +1914,19 @@ ipmr_fill_mroute(struct sk_buff *skb, struct mfc_cache *c, struct rtmsg *rtm) | |||
1625 | if (c->mfc_parent > MAXVIFS) | 1914 | if (c->mfc_parent > MAXVIFS) |
1626 | return -ENOENT; | 1915 | return -ENOENT; |
1627 | 1916 | ||
1628 | if (VIF_EXISTS(net, c->mfc_parent)) | 1917 | if (VIF_EXISTS(mrt, c->mfc_parent)) |
1629 | RTA_PUT(skb, RTA_IIF, 4, &net->ipv4.vif_table[c->mfc_parent].dev->ifindex); | 1918 | RTA_PUT(skb, RTA_IIF, 4, &mrt->vif_table[c->mfc_parent].dev->ifindex); |
1630 | 1919 | ||
1631 | mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0)); | 1920 | mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0)); |
1632 | 1921 | ||
1633 | for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) { | 1922 | for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) { |
1634 | if (VIF_EXISTS(net, ct) && c->mfc_un.res.ttls[ct] < 255) { | 1923 | if (VIF_EXISTS(mrt, ct) && c->mfc_un.res.ttls[ct] < 255) { |
1635 | if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) | 1924 | if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) |
1636 | goto rtattr_failure; | 1925 | goto rtattr_failure; |
1637 | nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); | 1926 | nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); |
1638 | nhp->rtnh_flags = 0; | 1927 | nhp->rtnh_flags = 0; |
1639 | nhp->rtnh_hops = c->mfc_un.res.ttls[ct]; | 1928 | nhp->rtnh_hops = c->mfc_un.res.ttls[ct]; |
1640 | nhp->rtnh_ifindex = net->ipv4.vif_table[ct].dev->ifindex; | 1929 | nhp->rtnh_ifindex = mrt->vif_table[ct].dev->ifindex; |
1641 | nhp->rtnh_len = sizeof(*nhp); | 1930 | nhp->rtnh_len = sizeof(*nhp); |
1642 | } | 1931 | } |
1643 | } | 1932 | } |
@@ -1655,11 +1944,16 @@ int ipmr_get_route(struct net *net, | |||
1655 | struct sk_buff *skb, struct rtmsg *rtm, int nowait) | 1944 | struct sk_buff *skb, struct rtmsg *rtm, int nowait) |
1656 | { | 1945 | { |
1657 | int err; | 1946 | int err; |
1947 | struct mr_table *mrt; | ||
1658 | struct mfc_cache *cache; | 1948 | struct mfc_cache *cache; |
1659 | struct rtable *rt = skb_rtable(skb); | 1949 | struct rtable *rt = skb_rtable(skb); |
1660 | 1950 | ||
1951 | mrt = ipmr_get_table(net, RT_TABLE_DEFAULT); | ||
1952 | if (mrt == NULL) | ||
1953 | return -ENOENT; | ||
1954 | |||
1661 | read_lock(&mrt_lock); | 1955 | read_lock(&mrt_lock); |
1662 | cache = ipmr_cache_find(net, rt->rt_src, rt->rt_dst); | 1956 | cache = ipmr_cache_find(mrt, rt->rt_src, rt->rt_dst); |
1663 | 1957 | ||
1664 | if (cache == NULL) { | 1958 | if (cache == NULL) { |
1665 | struct sk_buff *skb2; | 1959 | struct sk_buff *skb2; |
@@ -1673,7 +1967,7 @@ int ipmr_get_route(struct net *net, | |||
1673 | } | 1967 | } |
1674 | 1968 | ||
1675 | dev = skb->dev; | 1969 | dev = skb->dev; |
1676 | if (dev == NULL || (vif = ipmr_find_vif(dev)) < 0) { | 1970 | if (dev == NULL || (vif = ipmr_find_vif(mrt, dev)) < 0) { |
1677 | read_unlock(&mrt_lock); | 1971 | read_unlock(&mrt_lock); |
1678 | return -ENODEV; | 1972 | return -ENODEV; |
1679 | } | 1973 | } |
@@ -1690,24 +1984,107 @@ int ipmr_get_route(struct net *net, | |||
1690 | iph->saddr = rt->rt_src; | 1984 | iph->saddr = rt->rt_src; |
1691 | iph->daddr = rt->rt_dst; | 1985 | iph->daddr = rt->rt_dst; |
1692 | iph->version = 0; | 1986 | iph->version = 0; |
1693 | err = ipmr_cache_unresolved(net, vif, skb2); | 1987 | err = ipmr_cache_unresolved(mrt, vif, skb2); |
1694 | read_unlock(&mrt_lock); | 1988 | read_unlock(&mrt_lock); |
1695 | return err; | 1989 | return err; |
1696 | } | 1990 | } |
1697 | 1991 | ||
1698 | if (!nowait && (rtm->rtm_flags&RTM_F_NOTIFY)) | 1992 | if (!nowait && (rtm->rtm_flags&RTM_F_NOTIFY)) |
1699 | cache->mfc_flags |= MFC_NOTIFY; | 1993 | cache->mfc_flags |= MFC_NOTIFY; |
1700 | err = ipmr_fill_mroute(skb, cache, rtm); | 1994 | err = __ipmr_fill_mroute(mrt, skb, cache, rtm); |
1701 | read_unlock(&mrt_lock); | 1995 | read_unlock(&mrt_lock); |
1702 | return err; | 1996 | return err; |
1703 | } | 1997 | } |
1704 | 1998 | ||
1999 | static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, | ||
2000 | u32 pid, u32 seq, struct mfc_cache *c) | ||
2001 | { | ||
2002 | struct nlmsghdr *nlh; | ||
2003 | struct rtmsg *rtm; | ||
2004 | |||
2005 | nlh = nlmsg_put(skb, pid, seq, RTM_NEWROUTE, sizeof(*rtm), NLM_F_MULTI); | ||
2006 | if (nlh == NULL) | ||
2007 | return -EMSGSIZE; | ||
2008 | |||
2009 | rtm = nlmsg_data(nlh); | ||
2010 | rtm->rtm_family = RTNL_FAMILY_IPMR; | ||
2011 | rtm->rtm_dst_len = 32; | ||
2012 | rtm->rtm_src_len = 32; | ||
2013 | rtm->rtm_tos = 0; | ||
2014 | rtm->rtm_table = mrt->id; | ||
2015 | NLA_PUT_U32(skb, RTA_TABLE, mrt->id); | ||
2016 | rtm->rtm_type = RTN_MULTICAST; | ||
2017 | rtm->rtm_scope = RT_SCOPE_UNIVERSE; | ||
2018 | rtm->rtm_protocol = RTPROT_UNSPEC; | ||
2019 | rtm->rtm_flags = 0; | ||
2020 | |||
2021 | NLA_PUT_BE32(skb, RTA_SRC, c->mfc_origin); | ||
2022 | NLA_PUT_BE32(skb, RTA_DST, c->mfc_mcastgrp); | ||
2023 | |||
2024 | if (__ipmr_fill_mroute(mrt, skb, c, rtm) < 0) | ||
2025 | goto nla_put_failure; | ||
2026 | |||
2027 | return nlmsg_end(skb, nlh); | ||
2028 | |||
2029 | nla_put_failure: | ||
2030 | nlmsg_cancel(skb, nlh); | ||
2031 | return -EMSGSIZE; | ||
2032 | } | ||
2033 | |||
2034 | static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb) | ||
2035 | { | ||
2036 | struct net *net = sock_net(skb->sk); | ||
2037 | struct mr_table *mrt; | ||
2038 | struct mfc_cache *mfc; | ||
2039 | unsigned int t = 0, s_t; | ||
2040 | unsigned int h = 0, s_h; | ||
2041 | unsigned int e = 0, s_e; | ||
2042 | |||
2043 | s_t = cb->args[0]; | ||
2044 | s_h = cb->args[1]; | ||
2045 | s_e = cb->args[2]; | ||
2046 | |||
2047 | read_lock(&mrt_lock); | ||
2048 | ipmr_for_each_table(mrt, net) { | ||
2049 | if (t < s_t) | ||
2050 | goto next_table; | ||
2051 | if (t > s_t) | ||
2052 | s_h = 0; | ||
2053 | for (h = s_h; h < MFC_LINES; h++) { | ||
2054 | list_for_each_entry(mfc, &mrt->mfc_cache_array[h], list) { | ||
2055 | if (e < s_e) | ||
2056 | goto next_entry; | ||
2057 | if (ipmr_fill_mroute(mrt, skb, | ||
2058 | NETLINK_CB(cb->skb).pid, | ||
2059 | cb->nlh->nlmsg_seq, | ||
2060 | mfc) < 0) | ||
2061 | goto done; | ||
2062 | next_entry: | ||
2063 | e++; | ||
2064 | } | ||
2065 | e = s_e = 0; | ||
2066 | } | ||
2067 | s_h = 0; | ||
2068 | next_table: | ||
2069 | t++; | ||
2070 | } | ||
2071 | done: | ||
2072 | read_unlock(&mrt_lock); | ||
2073 | |||
2074 | cb->args[2] = e; | ||
2075 | cb->args[1] = h; | ||
2076 | cb->args[0] = t; | ||
2077 | |||
2078 | return skb->len; | ||
2079 | } | ||
2080 | |||
1705 | #ifdef CONFIG_PROC_FS | 2081 | #ifdef CONFIG_PROC_FS |
1706 | /* | 2082 | /* |
1707 | * The /proc interfaces to multicast routing /proc/ip_mr_cache /proc/ip_mr_vif | 2083 | * The /proc interfaces to multicast routing /proc/ip_mr_cache /proc/ip_mr_vif |
1708 | */ | 2084 | */ |
1709 | struct ipmr_vif_iter { | 2085 | struct ipmr_vif_iter { |
1710 | struct seq_net_private p; | 2086 | struct seq_net_private p; |
2087 | struct mr_table *mrt; | ||
1711 | int ct; | 2088 | int ct; |
1712 | }; | 2089 | }; |
1713 | 2090 | ||
@@ -1715,11 +2092,13 @@ static struct vif_device *ipmr_vif_seq_idx(struct net *net, | |||
1715 | struct ipmr_vif_iter *iter, | 2092 | struct ipmr_vif_iter *iter, |
1716 | loff_t pos) | 2093 | loff_t pos) |
1717 | { | 2094 | { |
1718 | for (iter->ct = 0; iter->ct < net->ipv4.maxvif; ++iter->ct) { | 2095 | struct mr_table *mrt = iter->mrt; |
1719 | if (!VIF_EXISTS(net, iter->ct)) | 2096 | |
2097 | for (iter->ct = 0; iter->ct < mrt->maxvif; ++iter->ct) { | ||
2098 | if (!VIF_EXISTS(mrt, iter->ct)) | ||
1720 | continue; | 2099 | continue; |
1721 | if (pos-- == 0) | 2100 | if (pos-- == 0) |
1722 | return &net->ipv4.vif_table[iter->ct]; | 2101 | return &mrt->vif_table[iter->ct]; |
1723 | } | 2102 | } |
1724 | return NULL; | 2103 | return NULL; |
1725 | } | 2104 | } |
@@ -1727,7 +2106,15 @@ static struct vif_device *ipmr_vif_seq_idx(struct net *net, | |||
1727 | static void *ipmr_vif_seq_start(struct seq_file *seq, loff_t *pos) | 2106 | static void *ipmr_vif_seq_start(struct seq_file *seq, loff_t *pos) |
1728 | __acquires(mrt_lock) | 2107 | __acquires(mrt_lock) |
1729 | { | 2108 | { |
2109 | struct ipmr_vif_iter *iter = seq->private; | ||
1730 | struct net *net = seq_file_net(seq); | 2110 | struct net *net = seq_file_net(seq); |
2111 | struct mr_table *mrt; | ||
2112 | |||
2113 | mrt = ipmr_get_table(net, RT_TABLE_DEFAULT); | ||
2114 | if (mrt == NULL) | ||
2115 | return ERR_PTR(-ENOENT); | ||
2116 | |||
2117 | iter->mrt = mrt; | ||
1731 | 2118 | ||
1732 | read_lock(&mrt_lock); | 2119 | read_lock(&mrt_lock); |
1733 | return *pos ? ipmr_vif_seq_idx(net, seq->private, *pos - 1) | 2120 | return *pos ? ipmr_vif_seq_idx(net, seq->private, *pos - 1) |
@@ -1738,15 +2125,16 @@ static void *ipmr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
1738 | { | 2125 | { |
1739 | struct ipmr_vif_iter *iter = seq->private; | 2126 | struct ipmr_vif_iter *iter = seq->private; |
1740 | struct net *net = seq_file_net(seq); | 2127 | struct net *net = seq_file_net(seq); |
2128 | struct mr_table *mrt = iter->mrt; | ||
1741 | 2129 | ||
1742 | ++*pos; | 2130 | ++*pos; |
1743 | if (v == SEQ_START_TOKEN) | 2131 | if (v == SEQ_START_TOKEN) |
1744 | return ipmr_vif_seq_idx(net, iter, 0); | 2132 | return ipmr_vif_seq_idx(net, iter, 0); |
1745 | 2133 | ||
1746 | while (++iter->ct < net->ipv4.maxvif) { | 2134 | while (++iter->ct < mrt->maxvif) { |
1747 | if (!VIF_EXISTS(net, iter->ct)) | 2135 | if (!VIF_EXISTS(mrt, iter->ct)) |
1748 | continue; | 2136 | continue; |
1749 | return &net->ipv4.vif_table[iter->ct]; | 2137 | return &mrt->vif_table[iter->ct]; |
1750 | } | 2138 | } |
1751 | return NULL; | 2139 | return NULL; |
1752 | } | 2140 | } |
@@ -1759,7 +2147,8 @@ static void ipmr_vif_seq_stop(struct seq_file *seq, void *v) | |||
1759 | 2147 | ||
1760 | static int ipmr_vif_seq_show(struct seq_file *seq, void *v) | 2148 | static int ipmr_vif_seq_show(struct seq_file *seq, void *v) |
1761 | { | 2149 | { |
1762 | struct net *net = seq_file_net(seq); | 2150 | struct ipmr_vif_iter *iter = seq->private; |
2151 | struct mr_table *mrt = iter->mrt; | ||
1763 | 2152 | ||
1764 | if (v == SEQ_START_TOKEN) { | 2153 | if (v == SEQ_START_TOKEN) { |
1765 | seq_puts(seq, | 2154 | seq_puts(seq, |
@@ -1770,7 +2159,7 @@ static int ipmr_vif_seq_show(struct seq_file *seq, void *v) | |||
1770 | 2159 | ||
1771 | seq_printf(seq, | 2160 | seq_printf(seq, |
1772 | "%2Zd %-10s %8ld %7ld %8ld %7ld %05X %08X %08X\n", | 2161 | "%2Zd %-10s %8ld %7ld %8ld %7ld %05X %08X %08X\n", |
1773 | vif - net->ipv4.vif_table, | 2162 | vif - mrt->vif_table, |
1774 | name, vif->bytes_in, vif->pkt_in, | 2163 | name, vif->bytes_in, vif->pkt_in, |
1775 | vif->bytes_out, vif->pkt_out, | 2164 | vif->bytes_out, vif->pkt_out, |
1776 | vif->flags, vif->local, vif->remote); | 2165 | vif->flags, vif->local, vif->remote); |
@@ -1801,7 +2190,8 @@ static const struct file_operations ipmr_vif_fops = { | |||
1801 | 2190 | ||
1802 | struct ipmr_mfc_iter { | 2191 | struct ipmr_mfc_iter { |
1803 | struct seq_net_private p; | 2192 | struct seq_net_private p; |
1804 | struct mfc_cache **cache; | 2193 | struct mr_table *mrt; |
2194 | struct list_head *cache; | ||
1805 | int ct; | 2195 | int ct; |
1806 | }; | 2196 | }; |
1807 | 2197 | ||
@@ -1809,22 +2199,22 @@ struct ipmr_mfc_iter { | |||
1809 | static struct mfc_cache *ipmr_mfc_seq_idx(struct net *net, | 2199 | static struct mfc_cache *ipmr_mfc_seq_idx(struct net *net, |
1810 | struct ipmr_mfc_iter *it, loff_t pos) | 2200 | struct ipmr_mfc_iter *it, loff_t pos) |
1811 | { | 2201 | { |
2202 | struct mr_table *mrt = it->mrt; | ||
1812 | struct mfc_cache *mfc; | 2203 | struct mfc_cache *mfc; |
1813 | 2204 | ||
1814 | it->cache = net->ipv4.mfc_cache_array; | ||
1815 | read_lock(&mrt_lock); | 2205 | read_lock(&mrt_lock); |
1816 | for (it->ct = 0; it->ct < MFC_LINES; it->ct++) | 2206 | for (it->ct = 0; it->ct < MFC_LINES; it->ct++) { |
1817 | for (mfc = net->ipv4.mfc_cache_array[it->ct]; | 2207 | it->cache = &mrt->mfc_cache_array[it->ct]; |
1818 | mfc; mfc = mfc->next) | 2208 | list_for_each_entry(mfc, it->cache, list) |
1819 | if (pos-- == 0) | 2209 | if (pos-- == 0) |
1820 | return mfc; | 2210 | return mfc; |
2211 | } | ||
1821 | read_unlock(&mrt_lock); | 2212 | read_unlock(&mrt_lock); |
1822 | 2213 | ||
1823 | it->cache = &mfc_unres_queue; | ||
1824 | spin_lock_bh(&mfc_unres_lock); | 2214 | spin_lock_bh(&mfc_unres_lock); |
1825 | for (mfc = mfc_unres_queue; mfc; mfc = mfc->next) | 2215 | it->cache = &mrt->mfc_unres_queue; |
1826 | if (net_eq(mfc_net(mfc), net) && | 2216 | list_for_each_entry(mfc, it->cache, list) |
1827 | pos-- == 0) | 2217 | if (pos-- == 0) |
1828 | return mfc; | 2218 | return mfc; |
1829 | spin_unlock_bh(&mfc_unres_lock); | 2219 | spin_unlock_bh(&mfc_unres_lock); |
1830 | 2220 | ||
@@ -1837,7 +2227,13 @@ static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos) | |||
1837 | { | 2227 | { |
1838 | struct ipmr_mfc_iter *it = seq->private; | 2228 | struct ipmr_mfc_iter *it = seq->private; |
1839 | struct net *net = seq_file_net(seq); | 2229 | struct net *net = seq_file_net(seq); |
2230 | struct mr_table *mrt; | ||
1840 | 2231 | ||
2232 | mrt = ipmr_get_table(net, RT_TABLE_DEFAULT); | ||
2233 | if (mrt == NULL) | ||
2234 | return ERR_PTR(-ENOENT); | ||
2235 | |||
2236 | it->mrt = mrt; | ||
1841 | it->cache = NULL; | 2237 | it->cache = NULL; |
1842 | it->ct = 0; | 2238 | it->ct = 0; |
1843 | return *pos ? ipmr_mfc_seq_idx(net, seq->private, *pos - 1) | 2239 | return *pos ? ipmr_mfc_seq_idx(net, seq->private, *pos - 1) |
@@ -1849,37 +2245,36 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
1849 | struct mfc_cache *mfc = v; | 2245 | struct mfc_cache *mfc = v; |
1850 | struct ipmr_mfc_iter *it = seq->private; | 2246 | struct ipmr_mfc_iter *it = seq->private; |
1851 | struct net *net = seq_file_net(seq); | 2247 | struct net *net = seq_file_net(seq); |
2248 | struct mr_table *mrt = it->mrt; | ||
1852 | 2249 | ||
1853 | ++*pos; | 2250 | ++*pos; |
1854 | 2251 | ||
1855 | if (v == SEQ_START_TOKEN) | 2252 | if (v == SEQ_START_TOKEN) |
1856 | return ipmr_mfc_seq_idx(net, seq->private, 0); | 2253 | return ipmr_mfc_seq_idx(net, seq->private, 0); |
1857 | 2254 | ||
1858 | if (mfc->next) | 2255 | if (mfc->list.next != it->cache) |
1859 | return mfc->next; | 2256 | return list_entry(mfc->list.next, struct mfc_cache, list); |
1860 | 2257 | ||
1861 | if (it->cache == &mfc_unres_queue) | 2258 | if (it->cache == &mrt->mfc_unres_queue) |
1862 | goto end_of_list; | 2259 | goto end_of_list; |
1863 | 2260 | ||
1864 | BUG_ON(it->cache != net->ipv4.mfc_cache_array); | 2261 | BUG_ON(it->cache != &mrt->mfc_cache_array[it->ct]); |
1865 | 2262 | ||
1866 | while (++it->ct < MFC_LINES) { | 2263 | while (++it->ct < MFC_LINES) { |
1867 | mfc = net->ipv4.mfc_cache_array[it->ct]; | 2264 | it->cache = &mrt->mfc_cache_array[it->ct]; |
1868 | if (mfc) | 2265 | if (list_empty(it->cache)) |
1869 | return mfc; | 2266 | continue; |
2267 | return list_first_entry(it->cache, struct mfc_cache, list); | ||
1870 | } | 2268 | } |
1871 | 2269 | ||
1872 | /* exhausted cache_array, show unresolved */ | 2270 | /* exhausted cache_array, show unresolved */ |
1873 | read_unlock(&mrt_lock); | 2271 | read_unlock(&mrt_lock); |
1874 | it->cache = &mfc_unres_queue; | 2272 | it->cache = &mrt->mfc_unres_queue; |
1875 | it->ct = 0; | 2273 | it->ct = 0; |
1876 | 2274 | ||
1877 | spin_lock_bh(&mfc_unres_lock); | 2275 | spin_lock_bh(&mfc_unres_lock); |
1878 | mfc = mfc_unres_queue; | 2276 | if (!list_empty(it->cache)) |
1879 | while (mfc && !net_eq(mfc_net(mfc), net)) | 2277 | return list_first_entry(it->cache, struct mfc_cache, list); |
1880 | mfc = mfc->next; | ||
1881 | if (mfc) | ||
1882 | return mfc; | ||
1883 | 2278 | ||
1884 | end_of_list: | 2279 | end_of_list: |
1885 | spin_unlock_bh(&mfc_unres_lock); | 2280 | spin_unlock_bh(&mfc_unres_lock); |
@@ -1891,18 +2286,17 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
1891 | static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v) | 2286 | static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v) |
1892 | { | 2287 | { |
1893 | struct ipmr_mfc_iter *it = seq->private; | 2288 | struct ipmr_mfc_iter *it = seq->private; |
1894 | struct net *net = seq_file_net(seq); | 2289 | struct mr_table *mrt = it->mrt; |
1895 | 2290 | ||
1896 | if (it->cache == &mfc_unres_queue) | 2291 | if (it->cache == &mrt->mfc_unres_queue) |
1897 | spin_unlock_bh(&mfc_unres_lock); | 2292 | spin_unlock_bh(&mfc_unres_lock); |
1898 | else if (it->cache == net->ipv4.mfc_cache_array) | 2293 | else if (it->cache == &mrt->mfc_cache_array[it->ct]) |
1899 | read_unlock(&mrt_lock); | 2294 | read_unlock(&mrt_lock); |
1900 | } | 2295 | } |
1901 | 2296 | ||
1902 | static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) | 2297 | static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) |
1903 | { | 2298 | { |
1904 | int n; | 2299 | int n; |
1905 | struct net *net = seq_file_net(seq); | ||
1906 | 2300 | ||
1907 | if (v == SEQ_START_TOKEN) { | 2301 | if (v == SEQ_START_TOKEN) { |
1908 | seq_puts(seq, | 2302 | seq_puts(seq, |
@@ -1910,20 +2304,21 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) | |||
1910 | } else { | 2304 | } else { |
1911 | const struct mfc_cache *mfc = v; | 2305 | const struct mfc_cache *mfc = v; |
1912 | const struct ipmr_mfc_iter *it = seq->private; | 2306 | const struct ipmr_mfc_iter *it = seq->private; |
2307 | const struct mr_table *mrt = it->mrt; | ||
1913 | 2308 | ||
1914 | seq_printf(seq, "%08lX %08lX %-3hd", | 2309 | seq_printf(seq, "%08X %08X %-3hd", |
1915 | (unsigned long) mfc->mfc_mcastgrp, | 2310 | (__force u32) mfc->mfc_mcastgrp, |
1916 | (unsigned long) mfc->mfc_origin, | 2311 | (__force u32) mfc->mfc_origin, |
1917 | mfc->mfc_parent); | 2312 | mfc->mfc_parent); |
1918 | 2313 | ||
1919 | if (it->cache != &mfc_unres_queue) { | 2314 | if (it->cache != &mrt->mfc_unres_queue) { |
1920 | seq_printf(seq, " %8lu %8lu %8lu", | 2315 | seq_printf(seq, " %8lu %8lu %8lu", |
1921 | mfc->mfc_un.res.pkt, | 2316 | mfc->mfc_un.res.pkt, |
1922 | mfc->mfc_un.res.bytes, | 2317 | mfc->mfc_un.res.bytes, |
1923 | mfc->mfc_un.res.wrong_if); | 2318 | mfc->mfc_un.res.wrong_if); |
1924 | for (n = mfc->mfc_un.res.minvif; | 2319 | for (n = mfc->mfc_un.res.minvif; |
1925 | n < mfc->mfc_un.res.maxvif; n++ ) { | 2320 | n < mfc->mfc_un.res.maxvif; n++ ) { |
1926 | if (VIF_EXISTS(net, n) && | 2321 | if (VIF_EXISTS(mrt, n) && |
1927 | mfc->mfc_un.res.ttls[n] < 255) | 2322 | mfc->mfc_un.res.ttls[n] < 255) |
1928 | seq_printf(seq, | 2323 | seq_printf(seq, |
1929 | " %2d:%-3d", | 2324 | " %2d:%-3d", |
@@ -1975,27 +2370,11 @@ static const struct net_protocol pim_protocol = { | |||
1975 | */ | 2370 | */ |
1976 | static int __net_init ipmr_net_init(struct net *net) | 2371 | static int __net_init ipmr_net_init(struct net *net) |
1977 | { | 2372 | { |
1978 | int err = 0; | 2373 | int err; |
1979 | 2374 | ||
1980 | net->ipv4.vif_table = kcalloc(MAXVIFS, sizeof(struct vif_device), | 2375 | err = ipmr_rules_init(net); |
1981 | GFP_KERNEL); | 2376 | if (err < 0) |
1982 | if (!net->ipv4.vif_table) { | ||
1983 | err = -ENOMEM; | ||
1984 | goto fail; | 2377 | goto fail; |
1985 | } | ||
1986 | |||
1987 | /* Forwarding cache */ | ||
1988 | net->ipv4.mfc_cache_array = kcalloc(MFC_LINES, | ||
1989 | sizeof(struct mfc_cache *), | ||
1990 | GFP_KERNEL); | ||
1991 | if (!net->ipv4.mfc_cache_array) { | ||
1992 | err = -ENOMEM; | ||
1993 | goto fail_mfc_cache; | ||
1994 | } | ||
1995 | |||
1996 | #ifdef CONFIG_IP_PIMSM | ||
1997 | net->ipv4.mroute_reg_vif_num = -1; | ||
1998 | #endif | ||
1999 | 2378 | ||
2000 | #ifdef CONFIG_PROC_FS | 2379 | #ifdef CONFIG_PROC_FS |
2001 | err = -ENOMEM; | 2380 | err = -ENOMEM; |
@@ -2010,10 +2389,8 @@ static int __net_init ipmr_net_init(struct net *net) | |||
2010 | proc_cache_fail: | 2389 | proc_cache_fail: |
2011 | proc_net_remove(net, "ip_mr_vif"); | 2390 | proc_net_remove(net, "ip_mr_vif"); |
2012 | proc_vif_fail: | 2391 | proc_vif_fail: |
2013 | kfree(net->ipv4.mfc_cache_array); | 2392 | ipmr_rules_exit(net); |
2014 | #endif | 2393 | #endif |
2015 | fail_mfc_cache: | ||
2016 | kfree(net->ipv4.vif_table); | ||
2017 | fail: | 2394 | fail: |
2018 | return err; | 2395 | return err; |
2019 | } | 2396 | } |
@@ -2024,8 +2401,7 @@ static void __net_exit ipmr_net_exit(struct net *net) | |||
2024 | proc_net_remove(net, "ip_mr_cache"); | 2401 | proc_net_remove(net, "ip_mr_cache"); |
2025 | proc_net_remove(net, "ip_mr_vif"); | 2402 | proc_net_remove(net, "ip_mr_vif"); |
2026 | #endif | 2403 | #endif |
2027 | kfree(net->ipv4.mfc_cache_array); | 2404 | ipmr_rules_exit(net); |
2028 | kfree(net->ipv4.vif_table); | ||
2029 | } | 2405 | } |
2030 | 2406 | ||
2031 | static struct pernet_operations ipmr_net_ops = { | 2407 | static struct pernet_operations ipmr_net_ops = { |
@@ -2048,7 +2424,6 @@ int __init ip_mr_init(void) | |||
2048 | if (err) | 2424 | if (err) |
2049 | goto reg_pernet_fail; | 2425 | goto reg_pernet_fail; |
2050 | 2426 | ||
2051 | setup_timer(&ipmr_expire_timer, ipmr_expire_process, 0); | ||
2052 | err = register_netdevice_notifier(&ip_mr_notifier); | 2427 | err = register_netdevice_notifier(&ip_mr_notifier); |
2053 | if (err) | 2428 | if (err) |
2054 | goto reg_notif_fail; | 2429 | goto reg_notif_fail; |
@@ -2059,6 +2434,7 @@ int __init ip_mr_init(void) | |||
2059 | goto add_proto_fail; | 2434 | goto add_proto_fail; |
2060 | } | 2435 | } |
2061 | #endif | 2436 | #endif |
2437 | rtnl_register(RTNL_FAMILY_IPMR, RTM_GETROUTE, NULL, ipmr_rtm_dumproute); | ||
2062 | return 0; | 2438 | return 0; |
2063 | 2439 | ||
2064 | #ifdef CONFIG_IP_PIMSM_V2 | 2440 | #ifdef CONFIG_IP_PIMSM_V2 |
@@ -2066,7 +2442,6 @@ add_proto_fail: | |||
2066 | unregister_netdevice_notifier(&ip_mr_notifier); | 2442 | unregister_netdevice_notifier(&ip_mr_notifier); |
2067 | #endif | 2443 | #endif |
2068 | reg_notif_fail: | 2444 | reg_notif_fail: |
2069 | del_timer(&ipmr_expire_timer); | ||
2070 | unregister_pernet_subsys(&ipmr_net_ops); | 2445 | unregister_pernet_subsys(&ipmr_net_ops); |
2071 | reg_pernet_fail: | 2446 | reg_pernet_fail: |
2072 | kmem_cache_destroy(mrt_cachep); | 2447 | kmem_cache_destroy(mrt_cachep); |
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index 82fb43c5c59..07de855e217 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c | |||
@@ -17,7 +17,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | |||
17 | const struct iphdr *iph = ip_hdr(skb); | 17 | const struct iphdr *iph = ip_hdr(skb); |
18 | struct rtable *rt; | 18 | struct rtable *rt; |
19 | struct flowi fl = {}; | 19 | struct flowi fl = {}; |
20 | struct dst_entry *odst; | 20 | unsigned long orefdst; |
21 | unsigned int hh_len; | 21 | unsigned int hh_len; |
22 | unsigned int type; | 22 | unsigned int type; |
23 | 23 | ||
@@ -51,14 +51,14 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | |||
51 | if (ip_route_output_key(net, &rt, &fl) != 0) | 51 | if (ip_route_output_key(net, &rt, &fl) != 0) |
52 | return -1; | 52 | return -1; |
53 | 53 | ||
54 | odst = skb_dst(skb); | 54 | orefdst = skb->_skb_refdst; |
55 | if (ip_route_input(skb, iph->daddr, iph->saddr, | 55 | if (ip_route_input(skb, iph->daddr, iph->saddr, |
56 | RT_TOS(iph->tos), rt->u.dst.dev) != 0) { | 56 | RT_TOS(iph->tos), rt->u.dst.dev) != 0) { |
57 | dst_release(&rt->u.dst); | 57 | dst_release(&rt->u.dst); |
58 | return -1; | 58 | return -1; |
59 | } | 59 | } |
60 | dst_release(&rt->u.dst); | 60 | dst_release(&rt->u.dst); |
61 | dst_release(odst); | 61 | refdst_drop(orefdst); |
62 | } | 62 | } |
63 | 63 | ||
64 | if (skb_dst(skb)->error) | 64 | if (skb_dst(skb)->error) |
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index f07d77f6575..1ac01b12862 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -49,12 +49,7 @@ MODULE_DESCRIPTION("arptables core"); | |||
49 | #endif | 49 | #endif |
50 | 50 | ||
51 | #ifdef CONFIG_NETFILTER_DEBUG | 51 | #ifdef CONFIG_NETFILTER_DEBUG |
52 | #define ARP_NF_ASSERT(x) \ | 52 | #define ARP_NF_ASSERT(x) WARN_ON(!(x)) |
53 | do { \ | ||
54 | if (!(x)) \ | ||
55 | printk("ARP_NF_ASSERT: %s:%s:%u\n", \ | ||
56 | __func__, __FILE__, __LINE__); \ | ||
57 | } while(0) | ||
58 | #else | 53 | #else |
59 | #define ARP_NF_ASSERT(x) | 54 | #define ARP_NF_ASSERT(x) |
60 | #endif | 55 | #endif |
@@ -224,10 +219,10 @@ static inline int arp_checkentry(const struct arpt_arp *arp) | |||
224 | } | 219 | } |
225 | 220 | ||
226 | static unsigned int | 221 | static unsigned int |
227 | arpt_error(struct sk_buff *skb, const struct xt_target_param *par) | 222 | arpt_error(struct sk_buff *skb, const struct xt_action_param *par) |
228 | { | 223 | { |
229 | if (net_ratelimit()) | 224 | if (net_ratelimit()) |
230 | printk("arp_tables: error: '%s'\n", | 225 | pr_err("arp_tables: error: '%s'\n", |
231 | (const char *)par->targinfo); | 226 | (const char *)par->targinfo); |
232 | 227 | ||
233 | return NF_DROP; | 228 | return NF_DROP; |
@@ -260,12 +255,11 @@ unsigned int arpt_do_table(struct sk_buff *skb, | |||
260 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); | 255 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); |
261 | unsigned int verdict = NF_DROP; | 256 | unsigned int verdict = NF_DROP; |
262 | const struct arphdr *arp; | 257 | const struct arphdr *arp; |
263 | bool hotdrop = false; | ||
264 | struct arpt_entry *e, *back; | 258 | struct arpt_entry *e, *back; |
265 | const char *indev, *outdev; | 259 | const char *indev, *outdev; |
266 | void *table_base; | 260 | void *table_base; |
267 | const struct xt_table_info *private; | 261 | const struct xt_table_info *private; |
268 | struct xt_target_param tgpar; | 262 | struct xt_action_param acpar; |
269 | 263 | ||
270 | if (!pskb_may_pull(skb, arp_hdr_len(skb->dev))) | 264 | if (!pskb_may_pull(skb, arp_hdr_len(skb->dev))) |
271 | return NF_DROP; | 265 | return NF_DROP; |
@@ -280,10 +274,11 @@ unsigned int arpt_do_table(struct sk_buff *skb, | |||
280 | e = get_entry(table_base, private->hook_entry[hook]); | 274 | e = get_entry(table_base, private->hook_entry[hook]); |
281 | back = get_entry(table_base, private->underflow[hook]); | 275 | back = get_entry(table_base, private->underflow[hook]); |
282 | 276 | ||
283 | tgpar.in = in; | 277 | acpar.in = in; |
284 | tgpar.out = out; | 278 | acpar.out = out; |
285 | tgpar.hooknum = hook; | 279 | acpar.hooknum = hook; |
286 | tgpar.family = NFPROTO_ARP; | 280 | acpar.family = NFPROTO_ARP; |
281 | acpar.hotdrop = false; | ||
287 | 282 | ||
288 | arp = arp_hdr(skb); | 283 | arp = arp_hdr(skb); |
289 | do { | 284 | do { |
@@ -333,9 +328,9 @@ unsigned int arpt_do_table(struct sk_buff *skb, | |||
333 | /* Targets which reenter must return | 328 | /* Targets which reenter must return |
334 | * abs. verdicts | 329 | * abs. verdicts |
335 | */ | 330 | */ |
336 | tgpar.target = t->u.kernel.target; | 331 | acpar.target = t->u.kernel.target; |
337 | tgpar.targinfo = t->data; | 332 | acpar.targinfo = t->data; |
338 | verdict = t->u.kernel.target->target(skb, &tgpar); | 333 | verdict = t->u.kernel.target->target(skb, &acpar); |
339 | 334 | ||
340 | /* Target might have changed stuff. */ | 335 | /* Target might have changed stuff. */ |
341 | arp = arp_hdr(skb); | 336 | arp = arp_hdr(skb); |
@@ -345,10 +340,10 @@ unsigned int arpt_do_table(struct sk_buff *skb, | |||
345 | else | 340 | else |
346 | /* Verdict */ | 341 | /* Verdict */ |
347 | break; | 342 | break; |
348 | } while (!hotdrop); | 343 | } while (!acpar.hotdrop); |
349 | xt_info_rdunlock_bh(); | 344 | xt_info_rdunlock_bh(); |
350 | 345 | ||
351 | if (hotdrop) | 346 | if (acpar.hotdrop) |
352 | return NF_DROP; | 347 | return NF_DROP; |
353 | else | 348 | else |
354 | return verdict; | 349 | return verdict; |
@@ -390,7 +385,7 @@ static int mark_source_chains(const struct xt_table_info *newinfo, | |||
390 | int visited = e->comefrom & (1 << hook); | 385 | int visited = e->comefrom & (1 << hook); |
391 | 386 | ||
392 | if (e->comefrom & (1 << NF_ARP_NUMHOOKS)) { | 387 | if (e->comefrom & (1 << NF_ARP_NUMHOOKS)) { |
393 | printk("arptables: loop hook %u pos %u %08X.\n", | 388 | pr_notice("arptables: loop hook %u pos %u %08X.\n", |
394 | hook, pos, e->comefrom); | 389 | hook, pos, e->comefrom); |
395 | return 0; | 390 | return 0; |
396 | } | 391 | } |
@@ -523,13 +518,11 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size) | |||
523 | return ret; | 518 | return ret; |
524 | 519 | ||
525 | t = arpt_get_target(e); | 520 | t = arpt_get_target(e); |
526 | target = try_then_request_module(xt_find_target(NFPROTO_ARP, | 521 | target = xt_request_find_target(NFPROTO_ARP, t->u.user.name, |
527 | t->u.user.name, | 522 | t->u.user.revision); |
528 | t->u.user.revision), | 523 | if (IS_ERR(target)) { |
529 | "arpt_%s", t->u.user.name); | ||
530 | if (IS_ERR(target) || !target) { | ||
531 | duprintf("find_check_entry: `%s' not found\n", t->u.user.name); | 524 | duprintf("find_check_entry: `%s' not found\n", t->u.user.name); |
532 | ret = target ? PTR_ERR(target) : -ENOENT; | 525 | ret = PTR_ERR(target); |
533 | goto out; | 526 | goto out; |
534 | } | 527 | } |
535 | t->u.kernel.target = target; | 528 | t->u.kernel.target = target; |
@@ -651,6 +644,9 @@ static int translate_table(struct xt_table_info *newinfo, void *entry0, | |||
651 | if (ret != 0) | 644 | if (ret != 0) |
652 | break; | 645 | break; |
653 | ++i; | 646 | ++i; |
647 | if (strcmp(arpt_get_target(iter)->u.user.name, | ||
648 | XT_ERROR_TARGET) == 0) | ||
649 | ++newinfo->stacksize; | ||
654 | } | 650 | } |
655 | duprintf("translate_table: ARPT_ENTRY_ITERATE gives %d\n", ret); | 651 | duprintf("translate_table: ARPT_ENTRY_ITERATE gives %d\n", ret); |
656 | if (ret != 0) | 652 | if (ret != 0) |
@@ -1252,14 +1248,12 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e, | |||
1252 | entry_offset = (void *)e - (void *)base; | 1248 | entry_offset = (void *)e - (void *)base; |
1253 | 1249 | ||
1254 | t = compat_arpt_get_target(e); | 1250 | t = compat_arpt_get_target(e); |
1255 | target = try_then_request_module(xt_find_target(NFPROTO_ARP, | 1251 | target = xt_request_find_target(NFPROTO_ARP, t->u.user.name, |
1256 | t->u.user.name, | 1252 | t->u.user.revision); |
1257 | t->u.user.revision), | 1253 | if (IS_ERR(target)) { |
1258 | "arpt_%s", t->u.user.name); | ||
1259 | if (IS_ERR(target) || !target) { | ||
1260 | duprintf("check_compat_entry_size_and_hooks: `%s' not found\n", | 1254 | duprintf("check_compat_entry_size_and_hooks: `%s' not found\n", |
1261 | t->u.user.name); | 1255 | t->u.user.name); |
1262 | ret = target ? PTR_ERR(target) : -ENOENT; | 1256 | ret = PTR_ERR(target); |
1263 | goto out; | 1257 | goto out; |
1264 | } | 1258 | } |
1265 | t->u.kernel.target = target; | 1259 | t->u.kernel.target = target; |
@@ -1778,8 +1772,7 @@ struct xt_table *arpt_register_table(struct net *net, | |||
1778 | { | 1772 | { |
1779 | int ret; | 1773 | int ret; |
1780 | struct xt_table_info *newinfo; | 1774 | struct xt_table_info *newinfo; |
1781 | struct xt_table_info bootstrap | 1775 | struct xt_table_info bootstrap = {0}; |
1782 | = { 0, 0, 0, { 0 }, { 0 }, { } }; | ||
1783 | void *loc_cpu_entry; | 1776 | void *loc_cpu_entry; |
1784 | struct xt_table *new_table; | 1777 | struct xt_table *new_table; |
1785 | 1778 | ||
@@ -1830,22 +1823,23 @@ void arpt_unregister_table(struct xt_table *table) | |||
1830 | } | 1823 | } |
1831 | 1824 | ||
1832 | /* The built-in targets: standard (NULL) and error. */ | 1825 | /* The built-in targets: standard (NULL) and error. */ |
1833 | static struct xt_target arpt_standard_target __read_mostly = { | 1826 | static struct xt_target arpt_builtin_tg[] __read_mostly = { |
1834 | .name = ARPT_STANDARD_TARGET, | 1827 | { |
1835 | .targetsize = sizeof(int), | 1828 | .name = ARPT_STANDARD_TARGET, |
1836 | .family = NFPROTO_ARP, | 1829 | .targetsize = sizeof(int), |
1830 | .family = NFPROTO_ARP, | ||
1837 | #ifdef CONFIG_COMPAT | 1831 | #ifdef CONFIG_COMPAT |
1838 | .compatsize = sizeof(compat_int_t), | 1832 | .compatsize = sizeof(compat_int_t), |
1839 | .compat_from_user = compat_standard_from_user, | 1833 | .compat_from_user = compat_standard_from_user, |
1840 | .compat_to_user = compat_standard_to_user, | 1834 | .compat_to_user = compat_standard_to_user, |
1841 | #endif | 1835 | #endif |
1842 | }; | 1836 | }, |
1843 | 1837 | { | |
1844 | static struct xt_target arpt_error_target __read_mostly = { | 1838 | .name = ARPT_ERROR_TARGET, |
1845 | .name = ARPT_ERROR_TARGET, | 1839 | .target = arpt_error, |
1846 | .target = arpt_error, | 1840 | .targetsize = ARPT_FUNCTION_MAXNAMELEN, |
1847 | .targetsize = ARPT_FUNCTION_MAXNAMELEN, | 1841 | .family = NFPROTO_ARP, |
1848 | .family = NFPROTO_ARP, | 1842 | }, |
1849 | }; | 1843 | }; |
1850 | 1844 | ||
1851 | static struct nf_sockopt_ops arpt_sockopts = { | 1845 | static struct nf_sockopt_ops arpt_sockopts = { |
@@ -1889,12 +1883,9 @@ static int __init arp_tables_init(void) | |||
1889 | goto err1; | 1883 | goto err1; |
1890 | 1884 | ||
1891 | /* Noone else will be downing sem now, so we won't sleep */ | 1885 | /* Noone else will be downing sem now, so we won't sleep */ |
1892 | ret = xt_register_target(&arpt_standard_target); | 1886 | ret = xt_register_targets(arpt_builtin_tg, ARRAY_SIZE(arpt_builtin_tg)); |
1893 | if (ret < 0) | 1887 | if (ret < 0) |
1894 | goto err2; | 1888 | goto err2; |
1895 | ret = xt_register_target(&arpt_error_target); | ||
1896 | if (ret < 0) | ||
1897 | goto err3; | ||
1898 | 1889 | ||
1899 | /* Register setsockopt */ | 1890 | /* Register setsockopt */ |
1900 | ret = nf_register_sockopt(&arpt_sockopts); | 1891 | ret = nf_register_sockopt(&arpt_sockopts); |
@@ -1905,9 +1896,7 @@ static int __init arp_tables_init(void) | |||
1905 | return 0; | 1896 | return 0; |
1906 | 1897 | ||
1907 | err4: | 1898 | err4: |
1908 | xt_unregister_target(&arpt_error_target); | 1899 | xt_unregister_targets(arpt_builtin_tg, ARRAY_SIZE(arpt_builtin_tg)); |
1909 | err3: | ||
1910 | xt_unregister_target(&arpt_standard_target); | ||
1911 | err2: | 1900 | err2: |
1912 | unregister_pernet_subsys(&arp_tables_net_ops); | 1901 | unregister_pernet_subsys(&arp_tables_net_ops); |
1913 | err1: | 1902 | err1: |
@@ -1917,8 +1906,7 @@ err1: | |||
1917 | static void __exit arp_tables_fini(void) | 1906 | static void __exit arp_tables_fini(void) |
1918 | { | 1907 | { |
1919 | nf_unregister_sockopt(&arpt_sockopts); | 1908 | nf_unregister_sockopt(&arpt_sockopts); |
1920 | xt_unregister_target(&arpt_error_target); | 1909 | xt_unregister_targets(arpt_builtin_tg, ARRAY_SIZE(arpt_builtin_tg)); |
1921 | xt_unregister_target(&arpt_standard_target); | ||
1922 | unregister_pernet_subsys(&arp_tables_net_ops); | 1910 | unregister_pernet_subsys(&arp_tables_net_ops); |
1923 | } | 1911 | } |
1924 | 1912 | ||
diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c index b0d5b1d0a76..e1be7dd1171 100644 --- a/net/ipv4/netfilter/arpt_mangle.c +++ b/net/ipv4/netfilter/arpt_mangle.c | |||
@@ -9,7 +9,7 @@ MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>"); | |||
9 | MODULE_DESCRIPTION("arptables arp payload mangle target"); | 9 | MODULE_DESCRIPTION("arptables arp payload mangle target"); |
10 | 10 | ||
11 | static unsigned int | 11 | static unsigned int |
12 | target(struct sk_buff *skb, const struct xt_target_param *par) | 12 | target(struct sk_buff *skb, const struct xt_action_param *par) |
13 | { | 13 | { |
14 | const struct arpt_mangle *mangle = par->targinfo; | 14 | const struct arpt_mangle *mangle = par->targinfo; |
15 | const struct arphdr *arp; | 15 | const struct arphdr *arp; |
@@ -54,7 +54,7 @@ target(struct sk_buff *skb, const struct xt_target_param *par) | |||
54 | return mangle->target; | 54 | return mangle->target; |
55 | } | 55 | } |
56 | 56 | ||
57 | static bool checkentry(const struct xt_tgchk_param *par) | 57 | static int checkentry(const struct xt_tgchk_param *par) |
58 | { | 58 | { |
59 | const struct arpt_mangle *mangle = par->targinfo; | 59 | const struct arpt_mangle *mangle = par->targinfo; |
60 | 60 | ||
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index e2787048aa0..a4e5fc5df4b 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
@@ -161,8 +161,7 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp) | |||
161 | break; | 161 | break; |
162 | 162 | ||
163 | case IPQ_COPY_PACKET: | 163 | case IPQ_COPY_PACKET: |
164 | if ((entry->skb->ip_summed == CHECKSUM_PARTIAL || | 164 | if (entry->skb->ip_summed == CHECKSUM_PARTIAL && |
165 | entry->skb->ip_summed == CHECKSUM_COMPLETE) && | ||
166 | (*errp = skb_checksum_help(entry->skb))) { | 165 | (*errp = skb_checksum_help(entry->skb))) { |
167 | read_unlock_bh(&queue_lock); | 166 | read_unlock_bh(&queue_lock); |
168 | return NULL; | 167 | return NULL; |
@@ -462,7 +461,6 @@ __ipq_rcv_skb(struct sk_buff *skb) | |||
462 | 461 | ||
463 | if (flags & NLM_F_ACK) | 462 | if (flags & NLM_F_ACK) |
464 | netlink_ack(skb, nlh, 0); | 463 | netlink_ack(skb, nlh, 0); |
465 | return; | ||
466 | } | 464 | } |
467 | 465 | ||
468 | static void | 466 | static void |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index b29c66df8d1..63958f3394a 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -39,24 +39,19 @@ MODULE_DESCRIPTION("IPv4 packet filter"); | |||
39 | /*#define DEBUG_IP_FIREWALL_USER*/ | 39 | /*#define DEBUG_IP_FIREWALL_USER*/ |
40 | 40 | ||
41 | #ifdef DEBUG_IP_FIREWALL | 41 | #ifdef DEBUG_IP_FIREWALL |
42 | #define dprintf(format, args...) printk(format , ## args) | 42 | #define dprintf(format, args...) pr_info(format , ## args) |
43 | #else | 43 | #else |
44 | #define dprintf(format, args...) | 44 | #define dprintf(format, args...) |
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | #ifdef DEBUG_IP_FIREWALL_USER | 47 | #ifdef DEBUG_IP_FIREWALL_USER |
48 | #define duprintf(format, args...) printk(format , ## args) | 48 | #define duprintf(format, args...) pr_info(format , ## args) |
49 | #else | 49 | #else |
50 | #define duprintf(format, args...) | 50 | #define duprintf(format, args...) |
51 | #endif | 51 | #endif |
52 | 52 | ||
53 | #ifdef CONFIG_NETFILTER_DEBUG | 53 | #ifdef CONFIG_NETFILTER_DEBUG |
54 | #define IP_NF_ASSERT(x) \ | 54 | #define IP_NF_ASSERT(x) WARN_ON(!(x)) |
55 | do { \ | ||
56 | if (!(x)) \ | ||
57 | printk("IP_NF_ASSERT: %s:%s:%u\n", \ | ||
58 | __func__, __FILE__, __LINE__); \ | ||
59 | } while(0) | ||
60 | #else | 55 | #else |
61 | #define IP_NF_ASSERT(x) | 56 | #define IP_NF_ASSERT(x) |
62 | #endif | 57 | #endif |
@@ -165,30 +160,14 @@ ip_checkentry(const struct ipt_ip *ip) | |||
165 | } | 160 | } |
166 | 161 | ||
167 | static unsigned int | 162 | static unsigned int |
168 | ipt_error(struct sk_buff *skb, const struct xt_target_param *par) | 163 | ipt_error(struct sk_buff *skb, const struct xt_action_param *par) |
169 | { | 164 | { |
170 | if (net_ratelimit()) | 165 | if (net_ratelimit()) |
171 | printk("ip_tables: error: `%s'\n", | 166 | pr_info("error: `%s'\n", (const char *)par->targinfo); |
172 | (const char *)par->targinfo); | ||
173 | 167 | ||
174 | return NF_DROP; | 168 | return NF_DROP; |
175 | } | 169 | } |
176 | 170 | ||
177 | /* Performance critical - called for every packet */ | ||
178 | static inline bool | ||
179 | do_match(const struct ipt_entry_match *m, const struct sk_buff *skb, | ||
180 | struct xt_match_param *par) | ||
181 | { | ||
182 | par->match = m->u.kernel.match; | ||
183 | par->matchinfo = m->data; | ||
184 | |||
185 | /* Stop iteration if it doesn't match */ | ||
186 | if (!m->u.kernel.match->match(skb, par)) | ||
187 | return true; | ||
188 | else | ||
189 | return false; | ||
190 | } | ||
191 | |||
192 | /* Performance critical */ | 171 | /* Performance critical */ |
193 | static inline struct ipt_entry * | 172 | static inline struct ipt_entry * |
194 | get_entry(const void *base, unsigned int offset) | 173 | get_entry(const void *base, unsigned int offset) |
@@ -322,19 +301,16 @@ ipt_do_table(struct sk_buff *skb, | |||
322 | const struct net_device *out, | 301 | const struct net_device *out, |
323 | struct xt_table *table) | 302 | struct xt_table *table) |
324 | { | 303 | { |
325 | #define tb_comefrom ((struct ipt_entry *)table_base)->comefrom | ||
326 | |||
327 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); | 304 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); |
328 | const struct iphdr *ip; | 305 | const struct iphdr *ip; |
329 | bool hotdrop = false; | ||
330 | /* Initializing verdict to NF_DROP keeps gcc happy. */ | 306 | /* Initializing verdict to NF_DROP keeps gcc happy. */ |
331 | unsigned int verdict = NF_DROP; | 307 | unsigned int verdict = NF_DROP; |
332 | const char *indev, *outdev; | 308 | const char *indev, *outdev; |
333 | const void *table_base; | 309 | const void *table_base; |
334 | struct ipt_entry *e, *back; | 310 | struct ipt_entry *e, **jumpstack; |
311 | unsigned int *stackptr, origptr, cpu; | ||
335 | const struct xt_table_info *private; | 312 | const struct xt_table_info *private; |
336 | struct xt_match_param mtpar; | 313 | struct xt_action_param acpar; |
337 | struct xt_target_param tgpar; | ||
338 | 314 | ||
339 | /* Initialization */ | 315 | /* Initialization */ |
340 | ip = ip_hdr(skb); | 316 | ip = ip_hdr(skb); |
@@ -346,40 +322,47 @@ ipt_do_table(struct sk_buff *skb, | |||
346 | * things we don't know, ie. tcp syn flag or ports). If the | 322 | * things we don't know, ie. tcp syn flag or ports). If the |
347 | * rule is also a fragment-specific rule, non-fragments won't | 323 | * rule is also a fragment-specific rule, non-fragments won't |
348 | * match it. */ | 324 | * match it. */ |
349 | mtpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET; | 325 | acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET; |
350 | mtpar.thoff = ip_hdrlen(skb); | 326 | acpar.thoff = ip_hdrlen(skb); |
351 | mtpar.hotdrop = &hotdrop; | 327 | acpar.hotdrop = false; |
352 | mtpar.in = tgpar.in = in; | 328 | acpar.in = in; |
353 | mtpar.out = tgpar.out = out; | 329 | acpar.out = out; |
354 | mtpar.family = tgpar.family = NFPROTO_IPV4; | 330 | acpar.family = NFPROTO_IPV4; |
355 | mtpar.hooknum = tgpar.hooknum = hook; | 331 | acpar.hooknum = hook; |
356 | 332 | ||
357 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); | 333 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); |
358 | xt_info_rdlock_bh(); | 334 | xt_info_rdlock_bh(); |
359 | private = table->private; | 335 | private = table->private; |
360 | table_base = private->entries[smp_processor_id()]; | 336 | cpu = smp_processor_id(); |
337 | table_base = private->entries[cpu]; | ||
338 | jumpstack = (struct ipt_entry **)private->jumpstack[cpu]; | ||
339 | stackptr = &private->stackptr[cpu]; | ||
340 | origptr = *stackptr; | ||
361 | 341 | ||
362 | e = get_entry(table_base, private->hook_entry[hook]); | 342 | e = get_entry(table_base, private->hook_entry[hook]); |
363 | 343 | ||
364 | /* For return from builtin chain */ | 344 | pr_debug("Entering %s(hook %u); sp at %u (UF %p)\n", |
365 | back = get_entry(table_base, private->underflow[hook]); | 345 | table->name, hook, origptr, |
346 | get_entry(table_base, private->underflow[hook])); | ||
366 | 347 | ||
367 | do { | 348 | do { |
368 | const struct ipt_entry_target *t; | 349 | const struct ipt_entry_target *t; |
369 | const struct xt_entry_match *ematch; | 350 | const struct xt_entry_match *ematch; |
370 | 351 | ||
371 | IP_NF_ASSERT(e); | 352 | IP_NF_ASSERT(e); |
372 | IP_NF_ASSERT(back); | ||
373 | if (!ip_packet_match(ip, indev, outdev, | 353 | if (!ip_packet_match(ip, indev, outdev, |
374 | &e->ip, mtpar.fragoff)) { | 354 | &e->ip, acpar.fragoff)) { |
375 | no_match: | 355 | no_match: |
376 | e = ipt_next_entry(e); | 356 | e = ipt_next_entry(e); |
377 | continue; | 357 | continue; |
378 | } | 358 | } |
379 | 359 | ||
380 | xt_ematch_foreach(ematch, e) | 360 | xt_ematch_foreach(ematch, e) { |
381 | if (do_match(ematch, skb, &mtpar) != 0) | 361 | acpar.match = ematch->u.kernel.match; |
362 | acpar.matchinfo = ematch->data; | ||
363 | if (!acpar.match->match(skb, &acpar)) | ||
382 | goto no_match; | 364 | goto no_match; |
365 | } | ||
383 | 366 | ||
384 | ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); | 367 | ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); |
385 | 368 | ||
@@ -404,41 +387,38 @@ ipt_do_table(struct sk_buff *skb, | |||
404 | verdict = (unsigned)(-v) - 1; | 387 | verdict = (unsigned)(-v) - 1; |
405 | break; | 388 | break; |
406 | } | 389 | } |
407 | e = back; | 390 | if (*stackptr == 0) { |
408 | back = get_entry(table_base, back->comefrom); | 391 | e = get_entry(table_base, |
392 | private->underflow[hook]); | ||
393 | pr_debug("Underflow (this is normal) " | ||
394 | "to %p\n", e); | ||
395 | } else { | ||
396 | e = jumpstack[--*stackptr]; | ||
397 | pr_debug("Pulled %p out from pos %u\n", | ||
398 | e, *stackptr); | ||
399 | e = ipt_next_entry(e); | ||
400 | } | ||
409 | continue; | 401 | continue; |
410 | } | 402 | } |
411 | if (table_base + v != ipt_next_entry(e) && | 403 | if (table_base + v != ipt_next_entry(e) && |
412 | !(e->ip.flags & IPT_F_GOTO)) { | 404 | !(e->ip.flags & IPT_F_GOTO)) { |
413 | /* Save old back ptr in next entry */ | 405 | if (*stackptr >= private->stacksize) { |
414 | struct ipt_entry *next = ipt_next_entry(e); | 406 | verdict = NF_DROP; |
415 | next->comefrom = (void *)back - table_base; | 407 | break; |
416 | /* set back pointer to next entry */ | 408 | } |
417 | back = next; | 409 | jumpstack[(*stackptr)++] = e; |
410 | pr_debug("Pushed %p into pos %u\n", | ||
411 | e, *stackptr - 1); | ||
418 | } | 412 | } |
419 | 413 | ||
420 | e = get_entry(table_base, v); | 414 | e = get_entry(table_base, v); |
421 | continue; | 415 | continue; |
422 | } | 416 | } |
423 | 417 | ||
424 | /* Targets which reenter must return | 418 | acpar.target = t->u.kernel.target; |
425 | abs. verdicts */ | 419 | acpar.targinfo = t->data; |
426 | tgpar.target = t->u.kernel.target; | ||
427 | tgpar.targinfo = t->data; | ||
428 | |||
429 | 420 | ||
430 | #ifdef CONFIG_NETFILTER_DEBUG | 421 | verdict = t->u.kernel.target->target(skb, &acpar); |
431 | tb_comefrom = 0xeeeeeeec; | ||
432 | #endif | ||
433 | verdict = t->u.kernel.target->target(skb, &tgpar); | ||
434 | #ifdef CONFIG_NETFILTER_DEBUG | ||
435 | if (tb_comefrom != 0xeeeeeeec && verdict == IPT_CONTINUE) { | ||
436 | printk("Target %s reentered!\n", | ||
437 | t->u.kernel.target->name); | ||
438 | verdict = NF_DROP; | ||
439 | } | ||
440 | tb_comefrom = 0x57acc001; | ||
441 | #endif | ||
442 | /* Target might have changed stuff. */ | 422 | /* Target might have changed stuff. */ |
443 | ip = ip_hdr(skb); | 423 | ip = ip_hdr(skb); |
444 | if (verdict == IPT_CONTINUE) | 424 | if (verdict == IPT_CONTINUE) |
@@ -446,18 +426,18 @@ ipt_do_table(struct sk_buff *skb, | |||
446 | else | 426 | else |
447 | /* Verdict */ | 427 | /* Verdict */ |
448 | break; | 428 | break; |
449 | } while (!hotdrop); | 429 | } while (!acpar.hotdrop); |
450 | xt_info_rdunlock_bh(); | 430 | xt_info_rdunlock_bh(); |
451 | 431 | pr_debug("Exiting %s; resetting sp from %u to %u\n", | |
432 | __func__, *stackptr, origptr); | ||
433 | *stackptr = origptr; | ||
452 | #ifdef DEBUG_ALLOW_ALL | 434 | #ifdef DEBUG_ALLOW_ALL |
453 | return NF_ACCEPT; | 435 | return NF_ACCEPT; |
454 | #else | 436 | #else |
455 | if (hotdrop) | 437 | if (acpar.hotdrop) |
456 | return NF_DROP; | 438 | return NF_DROP; |
457 | else return verdict; | 439 | else return verdict; |
458 | #endif | 440 | #endif |
459 | |||
460 | #undef tb_comefrom | ||
461 | } | 441 | } |
462 | 442 | ||
463 | /* Figures out from what hook each rule can be called: returns 0 if | 443 | /* Figures out from what hook each rule can be called: returns 0 if |
@@ -486,7 +466,7 @@ mark_source_chains(const struct xt_table_info *newinfo, | |||
486 | int visited = e->comefrom & (1 << hook); | 466 | int visited = e->comefrom & (1 << hook); |
487 | 467 | ||
488 | if (e->comefrom & (1 << NF_INET_NUMHOOKS)) { | 468 | if (e->comefrom & (1 << NF_INET_NUMHOOKS)) { |
489 | printk("iptables: loop hook %u pos %u %08X.\n", | 469 | pr_err("iptables: loop hook %u pos %u %08X.\n", |
490 | hook, pos, e->comefrom); | 470 | hook, pos, e->comefrom); |
491 | return 0; | 471 | return 0; |
492 | } | 472 | } |
@@ -591,7 +571,7 @@ check_entry(const struct ipt_entry *e, const char *name) | |||
591 | const struct ipt_entry_target *t; | 571 | const struct ipt_entry_target *t; |
592 | 572 | ||
593 | if (!ip_checkentry(&e->ip)) { | 573 | if (!ip_checkentry(&e->ip)) { |
594 | duprintf("ip_tables: ip check failed %p %s.\n", e, name); | 574 | duprintf("ip check failed %p %s.\n", e, par->match->name); |
595 | return -EINVAL; | 575 | return -EINVAL; |
596 | } | 576 | } |
597 | 577 | ||
@@ -618,8 +598,7 @@ check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par) | |||
618 | ret = xt_check_match(par, m->u.match_size - sizeof(*m), | 598 | ret = xt_check_match(par, m->u.match_size - sizeof(*m), |
619 | ip->proto, ip->invflags & IPT_INV_PROTO); | 599 | ip->proto, ip->invflags & IPT_INV_PROTO); |
620 | if (ret < 0) { | 600 | if (ret < 0) { |
621 | duprintf("ip_tables: check failed for `%s'.\n", | 601 | duprintf("check failed for `%s'.\n", par->match->name); |
622 | par.match->name); | ||
623 | return ret; | 602 | return ret; |
624 | } | 603 | } |
625 | return 0; | 604 | return 0; |
@@ -631,12 +610,11 @@ find_check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par) | |||
631 | struct xt_match *match; | 610 | struct xt_match *match; |
632 | int ret; | 611 | int ret; |
633 | 612 | ||
634 | match = try_then_request_module(xt_find_match(AF_INET, m->u.user.name, | 613 | match = xt_request_find_match(NFPROTO_IPV4, m->u.user.name, |
635 | m->u.user.revision), | 614 | m->u.user.revision); |
636 | "ipt_%s", m->u.user.name); | 615 | if (IS_ERR(match)) { |
637 | if (IS_ERR(match) || !match) { | ||
638 | duprintf("find_check_match: `%s' not found\n", m->u.user.name); | 616 | duprintf("find_check_match: `%s' not found\n", m->u.user.name); |
639 | return match ? PTR_ERR(match) : -ENOENT; | 617 | return PTR_ERR(match); |
640 | } | 618 | } |
641 | m->u.kernel.match = match; | 619 | m->u.kernel.match = match; |
642 | 620 | ||
@@ -667,7 +645,7 @@ static int check_target(struct ipt_entry *e, struct net *net, const char *name) | |||
667 | ret = xt_check_target(&par, t->u.target_size - sizeof(*t), | 645 | ret = xt_check_target(&par, t->u.target_size - sizeof(*t), |
668 | e->ip.proto, e->ip.invflags & IPT_INV_PROTO); | 646 | e->ip.proto, e->ip.invflags & IPT_INV_PROTO); |
669 | if (ret < 0) { | 647 | if (ret < 0) { |
670 | duprintf("ip_tables: check failed for `%s'.\n", | 648 | duprintf("check failed for `%s'.\n", |
671 | t->u.kernel.target->name); | 649 | t->u.kernel.target->name); |
672 | return ret; | 650 | return ret; |
673 | } | 651 | } |
@@ -703,13 +681,11 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name, | |||
703 | } | 681 | } |
704 | 682 | ||
705 | t = ipt_get_target(e); | 683 | t = ipt_get_target(e); |
706 | target = try_then_request_module(xt_find_target(AF_INET, | 684 | target = xt_request_find_target(NFPROTO_IPV4, t->u.user.name, |
707 | t->u.user.name, | 685 | t->u.user.revision); |
708 | t->u.user.revision), | 686 | if (IS_ERR(target)) { |
709 | "ipt_%s", t->u.user.name); | ||
710 | if (IS_ERR(target) || !target) { | ||
711 | duprintf("find_check_entry: `%s' not found\n", t->u.user.name); | 687 | duprintf("find_check_entry: `%s' not found\n", t->u.user.name); |
712 | ret = target ? PTR_ERR(target) : -ENOENT; | 688 | ret = PTR_ERR(target); |
713 | goto cleanup_matches; | 689 | goto cleanup_matches; |
714 | } | 690 | } |
715 | t->u.kernel.target = target; | 691 | t->u.kernel.target = target; |
@@ -843,6 +819,9 @@ translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0, | |||
843 | if (ret != 0) | 819 | if (ret != 0) |
844 | return ret; | 820 | return ret; |
845 | ++i; | 821 | ++i; |
822 | if (strcmp(ipt_get_target(iter)->u.user.name, | ||
823 | XT_ERROR_TARGET) == 0) | ||
824 | ++newinfo->stacksize; | ||
846 | } | 825 | } |
847 | 826 | ||
848 | if (i != repl->num_entries) { | 827 | if (i != repl->num_entries) { |
@@ -1311,7 +1290,7 @@ do_replace(struct net *net, const void __user *user, unsigned int len) | |||
1311 | if (ret != 0) | 1290 | if (ret != 0) |
1312 | goto free_newinfo; | 1291 | goto free_newinfo; |
1313 | 1292 | ||
1314 | duprintf("ip_tables: Translated table\n"); | 1293 | duprintf("Translated table\n"); |
1315 | 1294 | ||
1316 | ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo, | 1295 | ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo, |
1317 | tmp.num_counters, tmp.counters); | 1296 | tmp.num_counters, tmp.counters); |
@@ -1476,13 +1455,12 @@ compat_find_calc_match(struct ipt_entry_match *m, | |||
1476 | { | 1455 | { |
1477 | struct xt_match *match; | 1456 | struct xt_match *match; |
1478 | 1457 | ||
1479 | match = try_then_request_module(xt_find_match(AF_INET, m->u.user.name, | 1458 | match = xt_request_find_match(NFPROTO_IPV4, m->u.user.name, |
1480 | m->u.user.revision), | 1459 | m->u.user.revision); |
1481 | "ipt_%s", m->u.user.name); | 1460 | if (IS_ERR(match)) { |
1482 | if (IS_ERR(match) || !match) { | ||
1483 | duprintf("compat_check_calc_match: `%s' not found\n", | 1461 | duprintf("compat_check_calc_match: `%s' not found\n", |
1484 | m->u.user.name); | 1462 | m->u.user.name); |
1485 | return match ? PTR_ERR(match) : -ENOENT; | 1463 | return PTR_ERR(match); |
1486 | } | 1464 | } |
1487 | m->u.kernel.match = match; | 1465 | m->u.kernel.match = match; |
1488 | *size += xt_compat_match_offset(match); | 1466 | *size += xt_compat_match_offset(match); |
@@ -1549,14 +1527,12 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e, | |||
1549 | } | 1527 | } |
1550 | 1528 | ||
1551 | t = compat_ipt_get_target(e); | 1529 | t = compat_ipt_get_target(e); |
1552 | target = try_then_request_module(xt_find_target(AF_INET, | 1530 | target = xt_request_find_target(NFPROTO_IPV4, t->u.user.name, |
1553 | t->u.user.name, | 1531 | t->u.user.revision); |
1554 | t->u.user.revision), | 1532 | if (IS_ERR(target)) { |
1555 | "ipt_%s", t->u.user.name); | ||
1556 | if (IS_ERR(target) || !target) { | ||
1557 | duprintf("check_compat_entry_size_and_hooks: `%s' not found\n", | 1533 | duprintf("check_compat_entry_size_and_hooks: `%s' not found\n", |
1558 | t->u.user.name); | 1534 | t->u.user.name); |
1559 | ret = target ? PTR_ERR(target) : -ENOENT; | 1535 | ret = PTR_ERR(target); |
1560 | goto release_matches; | 1536 | goto release_matches; |
1561 | } | 1537 | } |
1562 | t->u.kernel.target = target; | 1538 | t->u.kernel.target = target; |
@@ -2094,8 +2070,7 @@ struct xt_table *ipt_register_table(struct net *net, | |||
2094 | { | 2070 | { |
2095 | int ret; | 2071 | int ret; |
2096 | struct xt_table_info *newinfo; | 2072 | struct xt_table_info *newinfo; |
2097 | struct xt_table_info bootstrap | 2073 | struct xt_table_info bootstrap = {0}; |
2098 | = { 0, 0, 0, { 0 }, { 0 }, { } }; | ||
2099 | void *loc_cpu_entry; | 2074 | void *loc_cpu_entry; |
2100 | struct xt_table *new_table; | 2075 | struct xt_table *new_table; |
2101 | 2076 | ||
@@ -2157,7 +2132,7 @@ icmp_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code, | |||
2157 | } | 2132 | } |
2158 | 2133 | ||
2159 | static bool | 2134 | static bool |
2160 | icmp_match(const struct sk_buff *skb, const struct xt_match_param *par) | 2135 | icmp_match(const struct sk_buff *skb, struct xt_action_param *par) |
2161 | { | 2136 | { |
2162 | const struct icmphdr *ic; | 2137 | const struct icmphdr *ic; |
2163 | struct icmphdr _icmph; | 2138 | struct icmphdr _icmph; |
@@ -2173,7 +2148,7 @@ icmp_match(const struct sk_buff *skb, const struct xt_match_param *par) | |||
2173 | * can't. Hence, no choice but to drop. | 2148 | * can't. Hence, no choice but to drop. |
2174 | */ | 2149 | */ |
2175 | duprintf("Dropping evil ICMP tinygram.\n"); | 2150 | duprintf("Dropping evil ICMP tinygram.\n"); |
2176 | *par->hotdrop = true; | 2151 | par->hotdrop = true; |
2177 | return false; | 2152 | return false; |
2178 | } | 2153 | } |
2179 | 2154 | ||
@@ -2184,31 +2159,31 @@ icmp_match(const struct sk_buff *skb, const struct xt_match_param *par) | |||
2184 | !!(icmpinfo->invflags&IPT_ICMP_INV)); | 2159 | !!(icmpinfo->invflags&IPT_ICMP_INV)); |
2185 | } | 2160 | } |
2186 | 2161 | ||
2187 | static bool icmp_checkentry(const struct xt_mtchk_param *par) | 2162 | static int icmp_checkentry(const struct xt_mtchk_param *par) |
2188 | { | 2163 | { |
2189 | const struct ipt_icmp *icmpinfo = par->matchinfo; | 2164 | const struct ipt_icmp *icmpinfo = par->matchinfo; |
2190 | 2165 | ||
2191 | /* Must specify no unknown invflags */ | 2166 | /* Must specify no unknown invflags */ |
2192 | return !(icmpinfo->invflags & ~IPT_ICMP_INV); | 2167 | return (icmpinfo->invflags & ~IPT_ICMP_INV) ? -EINVAL : 0; |
2193 | } | 2168 | } |
2194 | 2169 | ||
2195 | /* The built-in targets: standard (NULL) and error. */ | 2170 | static struct xt_target ipt_builtin_tg[] __read_mostly = { |
2196 | static struct xt_target ipt_standard_target __read_mostly = { | 2171 | { |
2197 | .name = IPT_STANDARD_TARGET, | 2172 | .name = IPT_STANDARD_TARGET, |
2198 | .targetsize = sizeof(int), | 2173 | .targetsize = sizeof(int), |
2199 | .family = NFPROTO_IPV4, | 2174 | .family = NFPROTO_IPV4, |
2200 | #ifdef CONFIG_COMPAT | 2175 | #ifdef CONFIG_COMPAT |
2201 | .compatsize = sizeof(compat_int_t), | 2176 | .compatsize = sizeof(compat_int_t), |
2202 | .compat_from_user = compat_standard_from_user, | 2177 | .compat_from_user = compat_standard_from_user, |
2203 | .compat_to_user = compat_standard_to_user, | 2178 | .compat_to_user = compat_standard_to_user, |
2204 | #endif | 2179 | #endif |
2205 | }; | 2180 | }, |
2206 | 2181 | { | |
2207 | static struct xt_target ipt_error_target __read_mostly = { | 2182 | .name = IPT_ERROR_TARGET, |
2208 | .name = IPT_ERROR_TARGET, | 2183 | .target = ipt_error, |
2209 | .target = ipt_error, | 2184 | .targetsize = IPT_FUNCTION_MAXNAMELEN, |
2210 | .targetsize = IPT_FUNCTION_MAXNAMELEN, | 2185 | .family = NFPROTO_IPV4, |
2211 | .family = NFPROTO_IPV4, | 2186 | }, |
2212 | }; | 2187 | }; |
2213 | 2188 | ||
2214 | static struct nf_sockopt_ops ipt_sockopts = { | 2189 | static struct nf_sockopt_ops ipt_sockopts = { |
@@ -2228,13 +2203,15 @@ static struct nf_sockopt_ops ipt_sockopts = { | |||
2228 | .owner = THIS_MODULE, | 2203 | .owner = THIS_MODULE, |
2229 | }; | 2204 | }; |
2230 | 2205 | ||
2231 | static struct xt_match icmp_matchstruct __read_mostly = { | 2206 | static struct xt_match ipt_builtin_mt[] __read_mostly = { |
2232 | .name = "icmp", | 2207 | { |
2233 | .match = icmp_match, | 2208 | .name = "icmp", |
2234 | .matchsize = sizeof(struct ipt_icmp), | 2209 | .match = icmp_match, |
2235 | .checkentry = icmp_checkentry, | 2210 | .matchsize = sizeof(struct ipt_icmp), |
2236 | .proto = IPPROTO_ICMP, | 2211 | .checkentry = icmp_checkentry, |
2237 | .family = NFPROTO_IPV4, | 2212 | .proto = IPPROTO_ICMP, |
2213 | .family = NFPROTO_IPV4, | ||
2214 | }, | ||
2238 | }; | 2215 | }; |
2239 | 2216 | ||
2240 | static int __net_init ip_tables_net_init(struct net *net) | 2217 | static int __net_init ip_tables_net_init(struct net *net) |
@@ -2261,13 +2238,10 @@ static int __init ip_tables_init(void) | |||
2261 | goto err1; | 2238 | goto err1; |
2262 | 2239 | ||
2263 | /* Noone else will be downing sem now, so we won't sleep */ | 2240 | /* Noone else will be downing sem now, so we won't sleep */ |
2264 | ret = xt_register_target(&ipt_standard_target); | 2241 | ret = xt_register_targets(ipt_builtin_tg, ARRAY_SIZE(ipt_builtin_tg)); |
2265 | if (ret < 0) | 2242 | if (ret < 0) |
2266 | goto err2; | 2243 | goto err2; |
2267 | ret = xt_register_target(&ipt_error_target); | 2244 | ret = xt_register_matches(ipt_builtin_mt, ARRAY_SIZE(ipt_builtin_mt)); |
2268 | if (ret < 0) | ||
2269 | goto err3; | ||
2270 | ret = xt_register_match(&icmp_matchstruct); | ||
2271 | if (ret < 0) | 2245 | if (ret < 0) |
2272 | goto err4; | 2246 | goto err4; |
2273 | 2247 | ||
@@ -2276,15 +2250,13 @@ static int __init ip_tables_init(void) | |||
2276 | if (ret < 0) | 2250 | if (ret < 0) |
2277 | goto err5; | 2251 | goto err5; |
2278 | 2252 | ||
2279 | printk(KERN_INFO "ip_tables: (C) 2000-2006 Netfilter Core Team\n"); | 2253 | pr_info("(C) 2000-2006 Netfilter Core Team\n"); |
2280 | return 0; | 2254 | return 0; |
2281 | 2255 | ||
2282 | err5: | 2256 | err5: |
2283 | xt_unregister_match(&icmp_matchstruct); | 2257 | xt_unregister_matches(ipt_builtin_mt, ARRAY_SIZE(ipt_builtin_mt)); |
2284 | err4: | 2258 | err4: |
2285 | xt_unregister_target(&ipt_error_target); | 2259 | xt_unregister_targets(ipt_builtin_tg, ARRAY_SIZE(ipt_builtin_tg)); |
2286 | err3: | ||
2287 | xt_unregister_target(&ipt_standard_target); | ||
2288 | err2: | 2260 | err2: |
2289 | unregister_pernet_subsys(&ip_tables_net_ops); | 2261 | unregister_pernet_subsys(&ip_tables_net_ops); |
2290 | err1: | 2262 | err1: |
@@ -2295,10 +2267,8 @@ static void __exit ip_tables_fini(void) | |||
2295 | { | 2267 | { |
2296 | nf_unregister_sockopt(&ipt_sockopts); | 2268 | nf_unregister_sockopt(&ipt_sockopts); |
2297 | 2269 | ||
2298 | xt_unregister_match(&icmp_matchstruct); | 2270 | xt_unregister_matches(ipt_builtin_mt, ARRAY_SIZE(ipt_builtin_mt)); |
2299 | xt_unregister_target(&ipt_error_target); | 2271 | xt_unregister_targets(ipt_builtin_tg, ARRAY_SIZE(ipt_builtin_tg)); |
2300 | xt_unregister_target(&ipt_standard_target); | ||
2301 | |||
2302 | unregister_pernet_subsys(&ip_tables_net_ops); | 2272 | unregister_pernet_subsys(&ip_tables_net_ops); |
2303 | } | 2273 | } |
2304 | 2274 | ||
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index ab828400ed7..f91c94b9a79 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
12 | #include <linux/module.h> | 13 | #include <linux/module.h> |
13 | #include <linux/proc_fs.h> | 14 | #include <linux/proc_fs.h> |
14 | #include <linux/jhash.h> | 15 | #include <linux/jhash.h> |
@@ -88,7 +89,7 @@ clusterip_config_entry_put(struct clusterip_config *c) | |||
88 | list_del(&c->list); | 89 | list_del(&c->list); |
89 | write_unlock_bh(&clusterip_lock); | 90 | write_unlock_bh(&clusterip_lock); |
90 | 91 | ||
91 | dev_mc_delete(c->dev, c->clustermac, ETH_ALEN, 0); | 92 | dev_mc_del(c->dev, c->clustermac); |
92 | dev_put(c->dev); | 93 | dev_put(c->dev); |
93 | 94 | ||
94 | /* In case anyone still accesses the file, the open/close | 95 | /* In case anyone still accesses the file, the open/close |
@@ -239,8 +240,7 @@ clusterip_hashfn(const struct sk_buff *skb, | |||
239 | break; | 240 | break; |
240 | default: | 241 | default: |
241 | if (net_ratelimit()) | 242 | if (net_ratelimit()) |
242 | printk(KERN_NOTICE "CLUSTERIP: unknown protocol `%u'\n", | 243 | pr_info("unknown protocol %u\n", iph->protocol); |
243 | iph->protocol); | ||
244 | sport = dport = 0; | 244 | sport = dport = 0; |
245 | } | 245 | } |
246 | 246 | ||
@@ -262,7 +262,7 @@ clusterip_hashfn(const struct sk_buff *skb, | |||
262 | hashval = 0; | 262 | hashval = 0; |
263 | /* This cannot happen, unless the check function wasn't called | 263 | /* This cannot happen, unless the check function wasn't called |
264 | * at rule load time */ | 264 | * at rule load time */ |
265 | printk("CLUSTERIP: unknown mode `%u'\n", config->hash_mode); | 265 | pr_info("unknown mode %u\n", config->hash_mode); |
266 | BUG(); | 266 | BUG(); |
267 | break; | 267 | break; |
268 | } | 268 | } |
@@ -282,7 +282,7 @@ clusterip_responsible(const struct clusterip_config *config, u_int32_t hash) | |||
282 | ***********************************************************************/ | 282 | ***********************************************************************/ |
283 | 283 | ||
284 | static unsigned int | 284 | static unsigned int |
285 | clusterip_tg(struct sk_buff *skb, const struct xt_target_param *par) | 285 | clusterip_tg(struct sk_buff *skb, const struct xt_action_param *par) |
286 | { | 286 | { |
287 | const struct ipt_clusterip_tgt_info *cipinfo = par->targinfo; | 287 | const struct ipt_clusterip_tgt_info *cipinfo = par->targinfo; |
288 | struct nf_conn *ct; | 288 | struct nf_conn *ct; |
@@ -295,7 +295,7 @@ clusterip_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
295 | 295 | ||
296 | ct = nf_ct_get(skb, &ctinfo); | 296 | ct = nf_ct_get(skb, &ctinfo); |
297 | if (ct == NULL) { | 297 | if (ct == NULL) { |
298 | printk(KERN_ERR "CLUSTERIP: no conntrack!\n"); | 298 | pr_info("no conntrack!\n"); |
299 | /* FIXME: need to drop invalid ones, since replies | 299 | /* FIXME: need to drop invalid ones, since replies |
300 | * to outgoing connections of other nodes will be | 300 | * to outgoing connections of other nodes will be |
301 | * marked as INVALID */ | 301 | * marked as INVALID */ |
@@ -348,25 +348,24 @@ clusterip_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
348 | return XT_CONTINUE; | 348 | return XT_CONTINUE; |
349 | } | 349 | } |
350 | 350 | ||
351 | static bool clusterip_tg_check(const struct xt_tgchk_param *par) | 351 | static int clusterip_tg_check(const struct xt_tgchk_param *par) |
352 | { | 352 | { |
353 | struct ipt_clusterip_tgt_info *cipinfo = par->targinfo; | 353 | struct ipt_clusterip_tgt_info *cipinfo = par->targinfo; |
354 | const struct ipt_entry *e = par->entryinfo; | 354 | const struct ipt_entry *e = par->entryinfo; |
355 | |||
356 | struct clusterip_config *config; | 355 | struct clusterip_config *config; |
356 | int ret; | ||
357 | 357 | ||
358 | if (cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP && | 358 | if (cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP && |
359 | cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT && | 359 | cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT && |
360 | cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT_DPT) { | 360 | cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT_DPT) { |
361 | printk(KERN_WARNING "CLUSTERIP: unknown mode `%u'\n", | 361 | pr_info("unknown mode %u\n", cipinfo->hash_mode); |
362 | cipinfo->hash_mode); | 362 | return -EINVAL; |
363 | return false; | ||
364 | 363 | ||
365 | } | 364 | } |
366 | if (e->ip.dmsk.s_addr != htonl(0xffffffff) || | 365 | if (e->ip.dmsk.s_addr != htonl(0xffffffff) || |
367 | e->ip.dst.s_addr == 0) { | 366 | e->ip.dst.s_addr == 0) { |
368 | printk(KERN_ERR "CLUSTERIP: Please specify destination IP\n"); | 367 | pr_info("Please specify destination IP\n"); |
369 | return false; | 368 | return -EINVAL; |
370 | } | 369 | } |
371 | 370 | ||
372 | /* FIXME: further sanity checks */ | 371 | /* FIXME: further sanity checks */ |
@@ -374,41 +373,41 @@ static bool clusterip_tg_check(const struct xt_tgchk_param *par) | |||
374 | config = clusterip_config_find_get(e->ip.dst.s_addr, 1); | 373 | config = clusterip_config_find_get(e->ip.dst.s_addr, 1); |
375 | if (!config) { | 374 | if (!config) { |
376 | if (!(cipinfo->flags & CLUSTERIP_FLAG_NEW)) { | 375 | if (!(cipinfo->flags & CLUSTERIP_FLAG_NEW)) { |
377 | printk(KERN_WARNING "CLUSTERIP: no config found for %pI4, need 'new'\n", &e->ip.dst.s_addr); | 376 | pr_info("no config found for %pI4, need 'new'\n", |
378 | return false; | 377 | &e->ip.dst.s_addr); |
378 | return -EINVAL; | ||
379 | } else { | 379 | } else { |
380 | struct net_device *dev; | 380 | struct net_device *dev; |
381 | 381 | ||
382 | if (e->ip.iniface[0] == '\0') { | 382 | if (e->ip.iniface[0] == '\0') { |
383 | printk(KERN_WARNING "CLUSTERIP: Please specify an interface name\n"); | 383 | pr_info("Please specify an interface name\n"); |
384 | return false; | 384 | return -EINVAL; |
385 | } | 385 | } |
386 | 386 | ||
387 | dev = dev_get_by_name(&init_net, e->ip.iniface); | 387 | dev = dev_get_by_name(&init_net, e->ip.iniface); |
388 | if (!dev) { | 388 | if (!dev) { |
389 | printk(KERN_WARNING "CLUSTERIP: no such interface %s\n", e->ip.iniface); | 389 | pr_info("no such interface %s\n", |
390 | return false; | 390 | e->ip.iniface); |
391 | return -ENOENT; | ||
391 | } | 392 | } |
392 | 393 | ||
393 | config = clusterip_config_init(cipinfo, | 394 | config = clusterip_config_init(cipinfo, |
394 | e->ip.dst.s_addr, dev); | 395 | e->ip.dst.s_addr, dev); |
395 | if (!config) { | 396 | if (!config) { |
396 | printk(KERN_WARNING "CLUSTERIP: cannot allocate config\n"); | 397 | pr_info("cannot allocate config\n"); |
397 | dev_put(dev); | 398 | dev_put(dev); |
398 | return false; | 399 | return -ENOMEM; |
399 | } | 400 | } |
400 | dev_mc_add(config->dev,config->clustermac, ETH_ALEN, 0); | 401 | dev_mc_add(config->dev, config->clustermac); |
401 | } | 402 | } |
402 | } | 403 | } |
403 | cipinfo->config = config; | 404 | cipinfo->config = config; |
404 | 405 | ||
405 | if (nf_ct_l3proto_try_module_get(par->target->family) < 0) { | 406 | ret = nf_ct_l3proto_try_module_get(par->family); |
406 | printk(KERN_WARNING "can't load conntrack support for " | 407 | if (ret < 0) |
407 | "proto=%u\n", par->target->family); | 408 | pr_info("cannot load conntrack support for proto=%u\n", |
408 | return false; | 409 | par->family); |
409 | } | 410 | return ret; |
410 | |||
411 | return true; | ||
412 | } | 411 | } |
413 | 412 | ||
414 | /* drop reference count of cluster config when rule is deleted */ | 413 | /* drop reference count of cluster config when rule is deleted */ |
@@ -422,7 +421,7 @@ static void clusterip_tg_destroy(const struct xt_tgdtor_param *par) | |||
422 | 421 | ||
423 | clusterip_config_put(cipinfo->config); | 422 | clusterip_config_put(cipinfo->config); |
424 | 423 | ||
425 | nf_ct_l3proto_module_put(par->target->family); | 424 | nf_ct_l3proto_module_put(par->family); |
426 | } | 425 | } |
427 | 426 | ||
428 | #ifdef CONFIG_COMPAT | 427 | #ifdef CONFIG_COMPAT |
@@ -479,8 +478,8 @@ static void arp_print(struct arp_payload *payload) | |||
479 | } | 478 | } |
480 | hbuffer[--k]='\0'; | 479 | hbuffer[--k]='\0'; |
481 | 480 | ||
482 | printk("src %pI4@%s, dst %pI4\n", | 481 | pr_debug("src %pI4@%s, dst %pI4\n", |
483 | &payload->src_ip, hbuffer, &payload->dst_ip); | 482 | &payload->src_ip, hbuffer, &payload->dst_ip); |
484 | } | 483 | } |
485 | #endif | 484 | #endif |
486 | 485 | ||
@@ -519,7 +518,7 @@ arp_mangle(unsigned int hook, | |||
519 | * this wouldn't work, since we didn't subscribe the mcast group on | 518 | * this wouldn't work, since we didn't subscribe the mcast group on |
520 | * other interfaces */ | 519 | * other interfaces */ |
521 | if (c->dev != out) { | 520 | if (c->dev != out) { |
522 | pr_debug("CLUSTERIP: not mangling arp reply on different " | 521 | pr_debug("not mangling arp reply on different " |
523 | "interface: cip'%s'-skb'%s'\n", | 522 | "interface: cip'%s'-skb'%s'\n", |
524 | c->dev->name, out->name); | 523 | c->dev->name, out->name); |
525 | clusterip_config_put(c); | 524 | clusterip_config_put(c); |
@@ -530,7 +529,7 @@ arp_mangle(unsigned int hook, | |||
530 | memcpy(payload->src_hw, c->clustermac, arp->ar_hln); | 529 | memcpy(payload->src_hw, c->clustermac, arp->ar_hln); |
531 | 530 | ||
532 | #ifdef DEBUG | 531 | #ifdef DEBUG |
533 | pr_debug(KERN_DEBUG "CLUSTERIP mangled arp reply: "); | 532 | pr_debug("mangled arp reply: "); |
534 | arp_print(payload); | 533 | arp_print(payload); |
535 | #endif | 534 | #endif |
536 | 535 | ||
@@ -601,7 +600,8 @@ static void *clusterip_seq_next(struct seq_file *s, void *v, loff_t *pos) | |||
601 | 600 | ||
602 | static void clusterip_seq_stop(struct seq_file *s, void *v) | 601 | static void clusterip_seq_stop(struct seq_file *s, void *v) |
603 | { | 602 | { |
604 | kfree(v); | 603 | if (!IS_ERR(v)) |
604 | kfree(v); | ||
605 | } | 605 | } |
606 | 606 | ||
607 | static int clusterip_seq_show(struct seq_file *s, void *v) | 607 | static int clusterip_seq_show(struct seq_file *s, void *v) |
@@ -706,13 +706,13 @@ static int __init clusterip_tg_init(void) | |||
706 | #ifdef CONFIG_PROC_FS | 706 | #ifdef CONFIG_PROC_FS |
707 | clusterip_procdir = proc_mkdir("ipt_CLUSTERIP", init_net.proc_net); | 707 | clusterip_procdir = proc_mkdir("ipt_CLUSTERIP", init_net.proc_net); |
708 | if (!clusterip_procdir) { | 708 | if (!clusterip_procdir) { |
709 | printk(KERN_ERR "CLUSTERIP: Unable to proc dir entry\n"); | 709 | pr_err("Unable to proc dir entry\n"); |
710 | ret = -ENOMEM; | 710 | ret = -ENOMEM; |
711 | goto cleanup_hook; | 711 | goto cleanup_hook; |
712 | } | 712 | } |
713 | #endif /* CONFIG_PROC_FS */ | 713 | #endif /* CONFIG_PROC_FS */ |
714 | 714 | ||
715 | printk(KERN_NOTICE "ClusterIP Version %s loaded successfully\n", | 715 | pr_info("ClusterIP Version %s loaded successfully\n", |
716 | CLUSTERIP_VERSION); | 716 | CLUSTERIP_VERSION); |
717 | return 0; | 717 | return 0; |
718 | 718 | ||
@@ -727,8 +727,7 @@ cleanup_target: | |||
727 | 727 | ||
728 | static void __exit clusterip_tg_exit(void) | 728 | static void __exit clusterip_tg_exit(void) |
729 | { | 729 | { |
730 | printk(KERN_NOTICE "ClusterIP Version %s unloading\n", | 730 | pr_info("ClusterIP Version %s unloading\n", CLUSTERIP_VERSION); |
731 | CLUSTERIP_VERSION); | ||
732 | #ifdef CONFIG_PROC_FS | 731 | #ifdef CONFIG_PROC_FS |
733 | remove_proc_entry(clusterip_procdir->name, clusterip_procdir->parent); | 732 | remove_proc_entry(clusterip_procdir->name, clusterip_procdir->parent); |
734 | #endif | 733 | #endif |
diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c index ea5cea2415c..4bf3dc49ad1 100644 --- a/net/ipv4/netfilter/ipt_ECN.c +++ b/net/ipv4/netfilter/ipt_ECN.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * it under the terms of the GNU General Public License version 2 as | 6 | * it under the terms of the GNU General Public License version 2 as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | */ | 8 | */ |
9 | 9 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
10 | #include <linux/in.h> | 10 | #include <linux/in.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/skbuff.h> | 12 | #include <linux/skbuff.h> |
@@ -77,7 +77,7 @@ set_ect_tcp(struct sk_buff *skb, const struct ipt_ECN_info *einfo) | |||
77 | } | 77 | } |
78 | 78 | ||
79 | static unsigned int | 79 | static unsigned int |
80 | ecn_tg(struct sk_buff *skb, const struct xt_target_param *par) | 80 | ecn_tg(struct sk_buff *skb, const struct xt_action_param *par) |
81 | { | 81 | { |
82 | const struct ipt_ECN_info *einfo = par->targinfo; | 82 | const struct ipt_ECN_info *einfo = par->targinfo; |
83 | 83 | ||
@@ -93,28 +93,25 @@ ecn_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
93 | return XT_CONTINUE; | 93 | return XT_CONTINUE; |
94 | } | 94 | } |
95 | 95 | ||
96 | static bool ecn_tg_check(const struct xt_tgchk_param *par) | 96 | static int ecn_tg_check(const struct xt_tgchk_param *par) |
97 | { | 97 | { |
98 | const struct ipt_ECN_info *einfo = par->targinfo; | 98 | const struct ipt_ECN_info *einfo = par->targinfo; |
99 | const struct ipt_entry *e = par->entryinfo; | 99 | const struct ipt_entry *e = par->entryinfo; |
100 | 100 | ||
101 | if (einfo->operation & IPT_ECN_OP_MASK) { | 101 | if (einfo->operation & IPT_ECN_OP_MASK) { |
102 | printk(KERN_WARNING "ECN: unsupported ECN operation %x\n", | 102 | pr_info("unsupported ECN operation %x\n", einfo->operation); |
103 | einfo->operation); | 103 | return -EINVAL; |
104 | return false; | ||
105 | } | 104 | } |
106 | if (einfo->ip_ect & ~IPT_ECN_IP_MASK) { | 105 | if (einfo->ip_ect & ~IPT_ECN_IP_MASK) { |
107 | printk(KERN_WARNING "ECN: new ECT codepoint %x out of mask\n", | 106 | pr_info("new ECT codepoint %x out of mask\n", einfo->ip_ect); |
108 | einfo->ip_ect); | 107 | return -EINVAL; |
109 | return false; | ||
110 | } | 108 | } |
111 | if ((einfo->operation & (IPT_ECN_OP_SET_ECE|IPT_ECN_OP_SET_CWR)) && | 109 | if ((einfo->operation & (IPT_ECN_OP_SET_ECE|IPT_ECN_OP_SET_CWR)) && |
112 | (e->ip.proto != IPPROTO_TCP || (e->ip.invflags & XT_INV_PROTO))) { | 110 | (e->ip.proto != IPPROTO_TCP || (e->ip.invflags & XT_INV_PROTO))) { |
113 | printk(KERN_WARNING "ECN: cannot use TCP operations on a " | 111 | pr_info("cannot use TCP operations on a non-tcp rule\n"); |
114 | "non-tcp rule\n"); | 112 | return -EINVAL; |
115 | return false; | ||
116 | } | 113 | } |
117 | return true; | 114 | return 0; |
118 | } | 115 | } |
119 | 116 | ||
120 | static struct xt_target ecn_tg_reg __read_mostly = { | 117 | static struct xt_target ecn_tg_reg __read_mostly = { |
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c index ee128efa1c8..5234f4f3499 100644 --- a/net/ipv4/netfilter/ipt_LOG.c +++ b/net/ipv4/netfilter/ipt_LOG.c | |||
@@ -9,7 +9,7 @@ | |||
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/spinlock.h> | 14 | #include <linux/spinlock.h> |
15 | #include <linux/skbuff.h> | 15 | #include <linux/skbuff.h> |
@@ -367,7 +367,7 @@ static struct nf_loginfo default_loginfo = { | |||
367 | .type = NF_LOG_TYPE_LOG, | 367 | .type = NF_LOG_TYPE_LOG, |
368 | .u = { | 368 | .u = { |
369 | .log = { | 369 | .log = { |
370 | .level = 0, | 370 | .level = 5, |
371 | .logflags = NF_LOG_MASK, | 371 | .logflags = NF_LOG_MASK, |
372 | }, | 372 | }, |
373 | }, | 373 | }, |
@@ -425,7 +425,7 @@ ipt_log_packet(u_int8_t pf, | |||
425 | } | 425 | } |
426 | 426 | ||
427 | static unsigned int | 427 | static unsigned int |
428 | log_tg(struct sk_buff *skb, const struct xt_target_param *par) | 428 | log_tg(struct sk_buff *skb, const struct xt_action_param *par) |
429 | { | 429 | { |
430 | const struct ipt_log_info *loginfo = par->targinfo; | 430 | const struct ipt_log_info *loginfo = par->targinfo; |
431 | struct nf_loginfo li; | 431 | struct nf_loginfo li; |
@@ -439,20 +439,19 @@ log_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
439 | return XT_CONTINUE; | 439 | return XT_CONTINUE; |
440 | } | 440 | } |
441 | 441 | ||
442 | static bool log_tg_check(const struct xt_tgchk_param *par) | 442 | static int log_tg_check(const struct xt_tgchk_param *par) |
443 | { | 443 | { |
444 | const struct ipt_log_info *loginfo = par->targinfo; | 444 | const struct ipt_log_info *loginfo = par->targinfo; |
445 | 445 | ||
446 | if (loginfo->level >= 8) { | 446 | if (loginfo->level >= 8) { |
447 | pr_debug("LOG: level %u >= 8\n", loginfo->level); | 447 | pr_debug("level %u >= 8\n", loginfo->level); |
448 | return false; | 448 | return -EINVAL; |
449 | } | 449 | } |
450 | if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') { | 450 | if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') { |
451 | pr_debug("LOG: prefix term %i\n", | 451 | pr_debug("prefix is not null-terminated\n"); |
452 | loginfo->prefix[sizeof(loginfo->prefix)-1]); | 452 | return -EINVAL; |
453 | return false; | ||
454 | } | 453 | } |
455 | return true; | 454 | return 0; |
456 | } | 455 | } |
457 | 456 | ||
458 | static struct xt_target log_tg_reg __read_mostly = { | 457 | static struct xt_target log_tg_reg __read_mostly = { |
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c index 650b54042b0..d2ed9dc74eb 100644 --- a/net/ipv4/netfilter/ipt_MASQUERADE.c +++ b/net/ipv4/netfilter/ipt_MASQUERADE.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | #include <linux/inetdevice.h> | 13 | #include <linux/inetdevice.h> |
14 | #include <linux/ip.h> | 14 | #include <linux/ip.h> |
@@ -28,23 +28,23 @@ MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); | |||
28 | MODULE_DESCRIPTION("Xtables: automatic-address SNAT"); | 28 | MODULE_DESCRIPTION("Xtables: automatic-address SNAT"); |
29 | 29 | ||
30 | /* FIXME: Multiple targets. --RR */ | 30 | /* FIXME: Multiple targets. --RR */ |
31 | static bool masquerade_tg_check(const struct xt_tgchk_param *par) | 31 | static int masquerade_tg_check(const struct xt_tgchk_param *par) |
32 | { | 32 | { |
33 | const struct nf_nat_multi_range_compat *mr = par->targinfo; | 33 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
34 | 34 | ||
35 | if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { | 35 | if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { |
36 | pr_debug("masquerade_check: bad MAP_IPS.\n"); | 36 | pr_debug("bad MAP_IPS.\n"); |
37 | return false; | 37 | return -EINVAL; |
38 | } | 38 | } |
39 | if (mr->rangesize != 1) { | 39 | if (mr->rangesize != 1) { |
40 | pr_debug("masquerade_check: bad rangesize %u\n", mr->rangesize); | 40 | pr_debug("bad rangesize %u\n", mr->rangesize); |
41 | return false; | 41 | return -EINVAL; |
42 | } | 42 | } |
43 | return true; | 43 | return 0; |
44 | } | 44 | } |
45 | 45 | ||
46 | static unsigned int | 46 | static unsigned int |
47 | masquerade_tg(struct sk_buff *skb, const struct xt_target_param *par) | 47 | masquerade_tg(struct sk_buff *skb, const struct xt_action_param *par) |
48 | { | 48 | { |
49 | struct nf_conn *ct; | 49 | struct nf_conn *ct; |
50 | struct nf_conn_nat *nat; | 50 | struct nf_conn_nat *nat; |
@@ -72,7 +72,7 @@ masquerade_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
72 | rt = skb_rtable(skb); | 72 | rt = skb_rtable(skb); |
73 | newsrc = inet_select_addr(par->out, rt->rt_gateway, RT_SCOPE_UNIVERSE); | 73 | newsrc = inet_select_addr(par->out, rt->rt_gateway, RT_SCOPE_UNIVERSE); |
74 | if (!newsrc) { | 74 | if (!newsrc) { |
75 | printk("MASQUERADE: %s ate my IP address\n", par->out->name); | 75 | pr_info("%s ate my IP address\n", par->out->name); |
76 | return NF_DROP; | 76 | return NF_DROP; |
77 | } | 77 | } |
78 | 78 | ||
diff --git a/net/ipv4/netfilter/ipt_NETMAP.c b/net/ipv4/netfilter/ipt_NETMAP.c index 7c29582d4ec..f43867d1697 100644 --- a/net/ipv4/netfilter/ipt_NETMAP.c +++ b/net/ipv4/netfilter/ipt_NETMAP.c | |||
@@ -9,7 +9,7 @@ | |||
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
13 | #include <linux/ip.h> | 13 | #include <linux/ip.h> |
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/netdevice.h> | 15 | #include <linux/netdevice.h> |
@@ -22,23 +22,23 @@ MODULE_LICENSE("GPL"); | |||
22 | MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>"); | 22 | MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>"); |
23 | MODULE_DESCRIPTION("Xtables: 1:1 NAT mapping of IPv4 subnets"); | 23 | MODULE_DESCRIPTION("Xtables: 1:1 NAT mapping of IPv4 subnets"); |
24 | 24 | ||
25 | static bool netmap_tg_check(const struct xt_tgchk_param *par) | 25 | static int netmap_tg_check(const struct xt_tgchk_param *par) |
26 | { | 26 | { |
27 | const struct nf_nat_multi_range_compat *mr = par->targinfo; | 27 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
28 | 28 | ||
29 | if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) { | 29 | if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) { |
30 | pr_debug("NETMAP:check: bad MAP_IPS.\n"); | 30 | pr_debug("bad MAP_IPS.\n"); |
31 | return false; | 31 | return -EINVAL; |
32 | } | 32 | } |
33 | if (mr->rangesize != 1) { | 33 | if (mr->rangesize != 1) { |
34 | pr_debug("NETMAP:check: bad rangesize %u.\n", mr->rangesize); | 34 | pr_debug("bad rangesize %u.\n", mr->rangesize); |
35 | return false; | 35 | return -EINVAL; |
36 | } | 36 | } |
37 | return true; | 37 | return 0; |
38 | } | 38 | } |
39 | 39 | ||
40 | static unsigned int | 40 | static unsigned int |
41 | netmap_tg(struct sk_buff *skb, const struct xt_target_param *par) | 41 | netmap_tg(struct sk_buff *skb, const struct xt_action_param *par) |
42 | { | 42 | { |
43 | struct nf_conn *ct; | 43 | struct nf_conn *ct; |
44 | enum ip_conntrack_info ctinfo; | 44 | enum ip_conntrack_info ctinfo; |
diff --git a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c index 698e5e78685..18a0656505a 100644 --- a/net/ipv4/netfilter/ipt_REDIRECT.c +++ b/net/ipv4/netfilter/ipt_REDIRECT.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * it under the terms of the GNU General Public License version 2 as | 6 | * it under the terms of the GNU General Public License version 2 as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | */ | 8 | */ |
9 | 9 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
10 | #include <linux/types.h> | 10 | #include <linux/types.h> |
11 | #include <linux/ip.h> | 11 | #include <linux/ip.h> |
12 | #include <linux/timer.h> | 12 | #include <linux/timer.h> |
@@ -26,23 +26,23 @@ MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); | |||
26 | MODULE_DESCRIPTION("Xtables: Connection redirection to localhost"); | 26 | MODULE_DESCRIPTION("Xtables: Connection redirection to localhost"); |
27 | 27 | ||
28 | /* FIXME: Take multiple ranges --RR */ | 28 | /* FIXME: Take multiple ranges --RR */ |
29 | static bool redirect_tg_check(const struct xt_tgchk_param *par) | 29 | static int redirect_tg_check(const struct xt_tgchk_param *par) |
30 | { | 30 | { |
31 | const struct nf_nat_multi_range_compat *mr = par->targinfo; | 31 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
32 | 32 | ||
33 | if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { | 33 | if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { |
34 | pr_debug("redirect_check: bad MAP_IPS.\n"); | 34 | pr_debug("bad MAP_IPS.\n"); |
35 | return false; | 35 | return -EINVAL; |
36 | } | 36 | } |
37 | if (mr->rangesize != 1) { | 37 | if (mr->rangesize != 1) { |
38 | pr_debug("redirect_check: bad rangesize %u.\n", mr->rangesize); | 38 | pr_debug("bad rangesize %u.\n", mr->rangesize); |
39 | return false; | 39 | return -EINVAL; |
40 | } | 40 | } |
41 | return true; | 41 | return 0; |
42 | } | 42 | } |
43 | 43 | ||
44 | static unsigned int | 44 | static unsigned int |
45 | redirect_tg(struct sk_buff *skb, const struct xt_target_param *par) | 45 | redirect_tg(struct sk_buff *skb, const struct xt_action_param *par) |
46 | { | 46 | { |
47 | struct nf_conn *ct; | 47 | struct nf_conn *ct; |
48 | enum ip_conntrack_info ctinfo; | 48 | enum ip_conntrack_info ctinfo; |
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index a0e8bcf0415..f5f4a888e4e 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c | |||
@@ -9,7 +9,7 @@ | |||
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/skbuff.h> | 14 | #include <linux/skbuff.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
@@ -136,13 +136,10 @@ static inline void send_unreach(struct sk_buff *skb_in, int code) | |||
136 | } | 136 | } |
137 | 137 | ||
138 | static unsigned int | 138 | static unsigned int |
139 | reject_tg(struct sk_buff *skb, const struct xt_target_param *par) | 139 | reject_tg(struct sk_buff *skb, const struct xt_action_param *par) |
140 | { | 140 | { |
141 | const struct ipt_reject_info *reject = par->targinfo; | 141 | const struct ipt_reject_info *reject = par->targinfo; |
142 | 142 | ||
143 | /* WARNING: This code causes reentry within iptables. | ||
144 | This means that the iptables jump stack is now crap. We | ||
145 | must return an absolute verdict. --RR */ | ||
146 | switch (reject->with) { | 143 | switch (reject->with) { |
147 | case IPT_ICMP_NET_UNREACHABLE: | 144 | case IPT_ICMP_NET_UNREACHABLE: |
148 | send_unreach(skb, ICMP_NET_UNREACH); | 145 | send_unreach(skb, ICMP_NET_UNREACH); |
@@ -175,23 +172,23 @@ reject_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
175 | return NF_DROP; | 172 | return NF_DROP; |
176 | } | 173 | } |
177 | 174 | ||
178 | static bool reject_tg_check(const struct xt_tgchk_param *par) | 175 | static int reject_tg_check(const struct xt_tgchk_param *par) |
179 | { | 176 | { |
180 | const struct ipt_reject_info *rejinfo = par->targinfo; | 177 | const struct ipt_reject_info *rejinfo = par->targinfo; |
181 | const struct ipt_entry *e = par->entryinfo; | 178 | const struct ipt_entry *e = par->entryinfo; |
182 | 179 | ||
183 | if (rejinfo->with == IPT_ICMP_ECHOREPLY) { | 180 | if (rejinfo->with == IPT_ICMP_ECHOREPLY) { |
184 | printk("ipt_REJECT: ECHOREPLY no longer supported.\n"); | 181 | pr_info("ECHOREPLY no longer supported.\n"); |
185 | return false; | 182 | return -EINVAL; |
186 | } else if (rejinfo->with == IPT_TCP_RESET) { | 183 | } else if (rejinfo->with == IPT_TCP_RESET) { |
187 | /* Must specify that it's a TCP packet */ | 184 | /* Must specify that it's a TCP packet */ |
188 | if (e->ip.proto != IPPROTO_TCP || | 185 | if (e->ip.proto != IPPROTO_TCP || |
189 | (e->ip.invflags & XT_INV_PROTO)) { | 186 | (e->ip.invflags & XT_INV_PROTO)) { |
190 | printk("ipt_REJECT: TCP_RESET invalid for non-tcp\n"); | 187 | pr_info("TCP_RESET invalid for non-tcp\n"); |
191 | return false; | 188 | return -EINVAL; |
192 | } | 189 | } |
193 | } | 190 | } |
194 | return true; | 191 | return 0; |
195 | } | 192 | } |
196 | 193 | ||
197 | static struct xt_target reject_tg_reg __read_mostly = { | 194 | static struct xt_target reject_tg_reg __read_mostly = { |
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index 0dbe697f164..446e0f467a1 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c | |||
@@ -29,7 +29,7 @@ | |||
29 | * Specify, after how many hundredths of a second the queue should be | 29 | * Specify, after how many hundredths of a second the queue should be |
30 | * flushed even if it is not full yet. | 30 | * flushed even if it is not full yet. |
31 | */ | 31 | */ |
32 | 32 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
34 | #include <linux/spinlock.h> | 34 | #include <linux/spinlock.h> |
35 | #include <linux/socket.h> | 35 | #include <linux/socket.h> |
@@ -57,8 +57,6 @@ MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NFLOG); | |||
57 | #define ULOG_NL_EVENT 111 /* Harald's favorite number */ | 57 | #define ULOG_NL_EVENT 111 /* Harald's favorite number */ |
58 | #define ULOG_MAXNLGROUPS 32 /* numer of nlgroups */ | 58 | #define ULOG_MAXNLGROUPS 32 /* numer of nlgroups */ |
59 | 59 | ||
60 | #define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0) | ||
61 | |||
62 | static unsigned int nlbufsiz = NLMSG_GOODSIZE; | 60 | static unsigned int nlbufsiz = NLMSG_GOODSIZE; |
63 | module_param(nlbufsiz, uint, 0400); | 61 | module_param(nlbufsiz, uint, 0400); |
64 | MODULE_PARM_DESC(nlbufsiz, "netlink buffer size"); | 62 | MODULE_PARM_DESC(nlbufsiz, "netlink buffer size"); |
@@ -91,12 +89,12 @@ static void ulog_send(unsigned int nlgroupnum) | |||
91 | ulog_buff_t *ub = &ulog_buffers[nlgroupnum]; | 89 | ulog_buff_t *ub = &ulog_buffers[nlgroupnum]; |
92 | 90 | ||
93 | if (timer_pending(&ub->timer)) { | 91 | if (timer_pending(&ub->timer)) { |
94 | pr_debug("ipt_ULOG: ulog_send: timer was pending, deleting\n"); | 92 | pr_debug("ulog_send: timer was pending, deleting\n"); |
95 | del_timer(&ub->timer); | 93 | del_timer(&ub->timer); |
96 | } | 94 | } |
97 | 95 | ||
98 | if (!ub->skb) { | 96 | if (!ub->skb) { |
99 | pr_debug("ipt_ULOG: ulog_send: nothing to send\n"); | 97 | pr_debug("ulog_send: nothing to send\n"); |
100 | return; | 98 | return; |
101 | } | 99 | } |
102 | 100 | ||
@@ -105,7 +103,7 @@ static void ulog_send(unsigned int nlgroupnum) | |||
105 | ub->lastnlh->nlmsg_type = NLMSG_DONE; | 103 | ub->lastnlh->nlmsg_type = NLMSG_DONE; |
106 | 104 | ||
107 | NETLINK_CB(ub->skb).dst_group = nlgroupnum + 1; | 105 | NETLINK_CB(ub->skb).dst_group = nlgroupnum + 1; |
108 | pr_debug("ipt_ULOG: throwing %d packets to netlink group %u\n", | 106 | pr_debug("throwing %d packets to netlink group %u\n", |
109 | ub->qlen, nlgroupnum + 1); | 107 | ub->qlen, nlgroupnum + 1); |
110 | netlink_broadcast(nflognl, ub->skb, 0, nlgroupnum + 1, GFP_ATOMIC); | 108 | netlink_broadcast(nflognl, ub->skb, 0, nlgroupnum + 1, GFP_ATOMIC); |
111 | 109 | ||
@@ -118,7 +116,7 @@ static void ulog_send(unsigned int nlgroupnum) | |||
118 | /* timer function to flush queue in flushtimeout time */ | 116 | /* timer function to flush queue in flushtimeout time */ |
119 | static void ulog_timer(unsigned long data) | 117 | static void ulog_timer(unsigned long data) |
120 | { | 118 | { |
121 | pr_debug("ipt_ULOG: timer function called, calling ulog_send\n"); | 119 | pr_debug("timer function called, calling ulog_send\n"); |
122 | 120 | ||
123 | /* lock to protect against somebody modifying our structure | 121 | /* lock to protect against somebody modifying our structure |
124 | * from ipt_ulog_target at the same time */ | 122 | * from ipt_ulog_target at the same time */ |
@@ -139,7 +137,7 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size) | |||
139 | n = max(size, nlbufsiz); | 137 | n = max(size, nlbufsiz); |
140 | skb = alloc_skb(n, GFP_ATOMIC); | 138 | skb = alloc_skb(n, GFP_ATOMIC); |
141 | if (!skb) { | 139 | if (!skb) { |
142 | PRINTR("ipt_ULOG: can't alloc whole buffer %ub!\n", n); | 140 | pr_debug("cannot alloc whole buffer %ub!\n", n); |
143 | 141 | ||
144 | if (n > size) { | 142 | if (n > size) { |
145 | /* try to allocate only as much as we need for | 143 | /* try to allocate only as much as we need for |
@@ -147,8 +145,7 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size) | |||
147 | 145 | ||
148 | skb = alloc_skb(size, GFP_ATOMIC); | 146 | skb = alloc_skb(size, GFP_ATOMIC); |
149 | if (!skb) | 147 | if (!skb) |
150 | PRINTR("ipt_ULOG: can't even allocate %ub\n", | 148 | pr_debug("cannot even allocate %ub\n", size); |
151 | size); | ||
152 | } | 149 | } |
153 | } | 150 | } |
154 | 151 | ||
@@ -199,8 +196,7 @@ static void ipt_ulog_packet(unsigned int hooknum, | |||
199 | goto alloc_failure; | 196 | goto alloc_failure; |
200 | } | 197 | } |
201 | 198 | ||
202 | pr_debug("ipt_ULOG: qlen %d, qthreshold %Zu\n", ub->qlen, | 199 | pr_debug("qlen %d, qthreshold %Zu\n", ub->qlen, loginfo->qthreshold); |
203 | loginfo->qthreshold); | ||
204 | 200 | ||
205 | /* NLMSG_PUT contains a hidden goto nlmsg_failure !!! */ | 201 | /* NLMSG_PUT contains a hidden goto nlmsg_failure !!! */ |
206 | nlh = NLMSG_PUT(ub->skb, 0, ub->qlen, ULOG_NL_EVENT, | 202 | nlh = NLMSG_PUT(ub->skb, 0, ub->qlen, ULOG_NL_EVENT, |
@@ -273,16 +269,14 @@ static void ipt_ulog_packet(unsigned int hooknum, | |||
273 | return; | 269 | return; |
274 | 270 | ||
275 | nlmsg_failure: | 271 | nlmsg_failure: |
276 | PRINTR("ipt_ULOG: error during NLMSG_PUT\n"); | 272 | pr_debug("error during NLMSG_PUT\n"); |
277 | |||
278 | alloc_failure: | 273 | alloc_failure: |
279 | PRINTR("ipt_ULOG: Error building netlink message\n"); | 274 | pr_debug("Error building netlink message\n"); |
280 | |||
281 | spin_unlock_bh(&ulog_lock); | 275 | spin_unlock_bh(&ulog_lock); |
282 | } | 276 | } |
283 | 277 | ||
284 | static unsigned int | 278 | static unsigned int |
285 | ulog_tg(struct sk_buff *skb, const struct xt_target_param *par) | 279 | ulog_tg(struct sk_buff *skb, const struct xt_action_param *par) |
286 | { | 280 | { |
287 | ipt_ulog_packet(par->hooknum, skb, par->in, par->out, | 281 | ipt_ulog_packet(par->hooknum, skb, par->in, par->out, |
288 | par->targinfo, NULL); | 282 | par->targinfo, NULL); |
@@ -314,21 +308,20 @@ static void ipt_logfn(u_int8_t pf, | |||
314 | ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); | 308 | ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); |
315 | } | 309 | } |
316 | 310 | ||
317 | static bool ulog_tg_check(const struct xt_tgchk_param *par) | 311 | static int ulog_tg_check(const struct xt_tgchk_param *par) |
318 | { | 312 | { |
319 | const struct ipt_ulog_info *loginfo = par->targinfo; | 313 | const struct ipt_ulog_info *loginfo = par->targinfo; |
320 | 314 | ||
321 | if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') { | 315 | if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') { |
322 | pr_debug("ipt_ULOG: prefix term %i\n", | 316 | pr_debug("prefix not null-terminated\n"); |
323 | loginfo->prefix[sizeof(loginfo->prefix) - 1]); | 317 | return -EINVAL; |
324 | return false; | ||
325 | } | 318 | } |
326 | if (loginfo->qthreshold > ULOG_MAX_QLEN) { | 319 | if (loginfo->qthreshold > ULOG_MAX_QLEN) { |
327 | pr_debug("ipt_ULOG: queue threshold %Zu > MAX_QLEN\n", | 320 | pr_debug("queue threshold %Zu > MAX_QLEN\n", |
328 | loginfo->qthreshold); | 321 | loginfo->qthreshold); |
329 | return false; | 322 | return -EINVAL; |
330 | } | 323 | } |
331 | return true; | 324 | return 0; |
332 | } | 325 | } |
333 | 326 | ||
334 | #ifdef CONFIG_COMPAT | 327 | #ifdef CONFIG_COMPAT |
@@ -390,10 +383,10 @@ static int __init ulog_tg_init(void) | |||
390 | { | 383 | { |
391 | int ret, i; | 384 | int ret, i; |
392 | 385 | ||
393 | pr_debug("ipt_ULOG: init module\n"); | 386 | pr_debug("init module\n"); |
394 | 387 | ||
395 | if (nlbufsiz > 128*1024) { | 388 | if (nlbufsiz > 128*1024) { |
396 | printk("Netlink buffer has to be <= 128kB\n"); | 389 | pr_warning("Netlink buffer has to be <= 128kB\n"); |
397 | return -EINVAL; | 390 | return -EINVAL; |
398 | } | 391 | } |
399 | 392 | ||
@@ -423,7 +416,7 @@ static void __exit ulog_tg_exit(void) | |||
423 | ulog_buff_t *ub; | 416 | ulog_buff_t *ub; |
424 | int i; | 417 | int i; |
425 | 418 | ||
426 | pr_debug("ipt_ULOG: cleanup_module\n"); | 419 | pr_debug("cleanup_module\n"); |
427 | 420 | ||
428 | if (nflog) | 421 | if (nflog) |
429 | nf_log_unregister(&ipt_ulog_logger); | 422 | nf_log_unregister(&ipt_ulog_logger); |
diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c index 3b216be3bc9..db8bff0fb86 100644 --- a/net/ipv4/netfilter/ipt_addrtype.c +++ b/net/ipv4/netfilter/ipt_addrtype.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/skbuff.h> | 14 | #include <linux/skbuff.h> |
@@ -30,7 +30,7 @@ static inline bool match_type(struct net *net, const struct net_device *dev, | |||
30 | } | 30 | } |
31 | 31 | ||
32 | static bool | 32 | static bool |
33 | addrtype_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par) | 33 | addrtype_mt_v0(const struct sk_buff *skb, struct xt_action_param *par) |
34 | { | 34 | { |
35 | struct net *net = dev_net(par->in ? par->in : par->out); | 35 | struct net *net = dev_net(par->in ? par->in : par->out); |
36 | const struct ipt_addrtype_info *info = par->matchinfo; | 36 | const struct ipt_addrtype_info *info = par->matchinfo; |
@@ -48,7 +48,7 @@ addrtype_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par) | |||
48 | } | 48 | } |
49 | 49 | ||
50 | static bool | 50 | static bool |
51 | addrtype_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par) | 51 | addrtype_mt_v1(const struct sk_buff *skb, struct xt_action_param *par) |
52 | { | 52 | { |
53 | struct net *net = dev_net(par->in ? par->in : par->out); | 53 | struct net *net = dev_net(par->in ? par->in : par->out); |
54 | const struct ipt_addrtype_info_v1 *info = par->matchinfo; | 54 | const struct ipt_addrtype_info_v1 *info = par->matchinfo; |
@@ -70,34 +70,34 @@ addrtype_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par) | |||
70 | return ret; | 70 | return ret; |
71 | } | 71 | } |
72 | 72 | ||
73 | static bool addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par) | 73 | static int addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par) |
74 | { | 74 | { |
75 | struct ipt_addrtype_info_v1 *info = par->matchinfo; | 75 | struct ipt_addrtype_info_v1 *info = par->matchinfo; |
76 | 76 | ||
77 | if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN && | 77 | if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN && |
78 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { | 78 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { |
79 | printk(KERN_ERR "ipt_addrtype: both incoming and outgoing " | 79 | pr_info("both incoming and outgoing " |
80 | "interface limitation cannot be selected\n"); | 80 | "interface limitation cannot be selected\n"); |
81 | return false; | 81 | return -EINVAL; |
82 | } | 82 | } |
83 | 83 | ||
84 | if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) | | 84 | if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) | |
85 | (1 << NF_INET_LOCAL_IN)) && | 85 | (1 << NF_INET_LOCAL_IN)) && |
86 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { | 86 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { |
87 | printk(KERN_ERR "ipt_addrtype: output interface limitation " | 87 | pr_info("output interface limitation " |
88 | "not valid in PRE_ROUTING and INPUT\n"); | 88 | "not valid in PREROUTING and INPUT\n"); |
89 | return false; | 89 | return -EINVAL; |
90 | } | 90 | } |
91 | 91 | ||
92 | if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) | | 92 | if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) | |
93 | (1 << NF_INET_LOCAL_OUT)) && | 93 | (1 << NF_INET_LOCAL_OUT)) && |
94 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) { | 94 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) { |
95 | printk(KERN_ERR "ipt_addrtype: input interface limitation " | 95 | pr_info("input interface limitation " |
96 | "not valid in POST_ROUTING and OUTPUT\n"); | 96 | "not valid in POSTROUTING and OUTPUT\n"); |
97 | return false; | 97 | return -EINVAL; |
98 | } | 98 | } |
99 | 99 | ||
100 | return true; | 100 | return 0; |
101 | } | 101 | } |
102 | 102 | ||
103 | static struct xt_match addrtype_mt_reg[] __read_mostly = { | 103 | static struct xt_match addrtype_mt_reg[] __read_mostly = { |
diff --git a/net/ipv4/netfilter/ipt_ah.c b/net/ipv4/netfilter/ipt_ah.c index 0104c0b399d..14a2aa8b8a1 100644 --- a/net/ipv4/netfilter/ipt_ah.c +++ b/net/ipv4/netfilter/ipt_ah.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * it under the terms of the GNU General Public License version 2 as | 5 | * it under the terms of the GNU General Public License version 2 as |
6 | * published by the Free Software Foundation. | 6 | * published by the Free Software Foundation. |
7 | */ | 7 | */ |
8 | 8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
9 | #include <linux/in.h> | 9 | #include <linux/in.h> |
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/skbuff.h> | 11 | #include <linux/skbuff.h> |
@@ -18,25 +18,19 @@ MODULE_LICENSE("GPL"); | |||
18 | MODULE_AUTHOR("Yon Uriarte <yon@astaro.de>"); | 18 | MODULE_AUTHOR("Yon Uriarte <yon@astaro.de>"); |
19 | MODULE_DESCRIPTION("Xtables: IPv4 IPsec-AH SPI match"); | 19 | MODULE_DESCRIPTION("Xtables: IPv4 IPsec-AH SPI match"); |
20 | 20 | ||
21 | #ifdef DEBUG_CONNTRACK | ||
22 | #define duprintf(format, args...) printk(format , ## args) | ||
23 | #else | ||
24 | #define duprintf(format, args...) | ||
25 | #endif | ||
26 | |||
27 | /* Returns 1 if the spi is matched by the range, 0 otherwise */ | 21 | /* Returns 1 if the spi is matched by the range, 0 otherwise */ |
28 | static inline bool | 22 | static inline bool |
29 | spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert) | 23 | spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert) |
30 | { | 24 | { |
31 | bool r; | 25 | bool r; |
32 | duprintf("ah spi_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ', | 26 | pr_debug("spi_match:%c 0x%x <= 0x%x <= 0x%x\n", |
33 | min,spi,max); | 27 | invert ? '!' : ' ', min, spi, max); |
34 | r=(spi >= min && spi <= max) ^ invert; | 28 | r=(spi >= min && spi <= max) ^ invert; |
35 | duprintf(" result %s\n",r? "PASS" : "FAILED"); | 29 | pr_debug(" result %s\n", r ? "PASS" : "FAILED"); |
36 | return r; | 30 | return r; |
37 | } | 31 | } |
38 | 32 | ||
39 | static bool ah_mt(const struct sk_buff *skb, const struct xt_match_param *par) | 33 | static bool ah_mt(const struct sk_buff *skb, struct xt_action_param *par) |
40 | { | 34 | { |
41 | struct ip_auth_hdr _ahdr; | 35 | struct ip_auth_hdr _ahdr; |
42 | const struct ip_auth_hdr *ah; | 36 | const struct ip_auth_hdr *ah; |
@@ -51,8 +45,8 @@ static bool ah_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
51 | /* We've been asked to examine this packet, and we | 45 | /* We've been asked to examine this packet, and we |
52 | * can't. Hence, no choice but to drop. | 46 | * can't. Hence, no choice but to drop. |
53 | */ | 47 | */ |
54 | duprintf("Dropping evil AH tinygram.\n"); | 48 | pr_debug("Dropping evil AH tinygram.\n"); |
55 | *par->hotdrop = true; | 49 | par->hotdrop = true; |
56 | return 0; | 50 | return 0; |
57 | } | 51 | } |
58 | 52 | ||
@@ -61,16 +55,16 @@ static bool ah_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
61 | !!(ahinfo->invflags & IPT_AH_INV_SPI)); | 55 | !!(ahinfo->invflags & IPT_AH_INV_SPI)); |
62 | } | 56 | } |
63 | 57 | ||
64 | static bool ah_mt_check(const struct xt_mtchk_param *par) | 58 | static int ah_mt_check(const struct xt_mtchk_param *par) |
65 | { | 59 | { |
66 | const struct ipt_ah *ahinfo = par->matchinfo; | 60 | const struct ipt_ah *ahinfo = par->matchinfo; |
67 | 61 | ||
68 | /* Must specify no unknown invflags */ | 62 | /* Must specify no unknown invflags */ |
69 | if (ahinfo->invflags & ~IPT_AH_INV_MASK) { | 63 | if (ahinfo->invflags & ~IPT_AH_INV_MASK) { |
70 | duprintf("ipt_ah: unknown flags %X\n", ahinfo->invflags); | 64 | pr_debug("unknown flags %X\n", ahinfo->invflags); |
71 | return false; | 65 | return -EINVAL; |
72 | } | 66 | } |
73 | return true; | 67 | return 0; |
74 | } | 68 | } |
75 | 69 | ||
76 | static struct xt_match ah_mt_reg __read_mostly = { | 70 | static struct xt_match ah_mt_reg __read_mostly = { |
diff --git a/net/ipv4/netfilter/ipt_ecn.c b/net/ipv4/netfilter/ipt_ecn.c index 2a1e56b7190..af6e9c77834 100644 --- a/net/ipv4/netfilter/ipt_ecn.c +++ b/net/ipv4/netfilter/ipt_ecn.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * it under the terms of the GNU General Public License version 2 as | 6 | * it under the terms of the GNU General Public License version 2 as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | */ | 8 | */ |
9 | 9 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
10 | #include <linux/in.h> | 10 | #include <linux/in.h> |
11 | #include <linux/ip.h> | 11 | #include <linux/ip.h> |
12 | #include <net/ip.h> | 12 | #include <net/ip.h> |
@@ -67,7 +67,7 @@ static inline bool match_tcp(const struct sk_buff *skb, | |||
67 | return true; | 67 | return true; |
68 | } | 68 | } |
69 | 69 | ||
70 | static bool ecn_mt(const struct sk_buff *skb, const struct xt_match_param *par) | 70 | static bool ecn_mt(const struct sk_buff *skb, struct xt_action_param *par) |
71 | { | 71 | { |
72 | const struct ipt_ecn_info *info = par->matchinfo; | 72 | const struct ipt_ecn_info *info = par->matchinfo; |
73 | 73 | ||
@@ -78,32 +78,31 @@ static bool ecn_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
78 | if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) { | 78 | if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) { |
79 | if (ip_hdr(skb)->protocol != IPPROTO_TCP) | 79 | if (ip_hdr(skb)->protocol != IPPROTO_TCP) |
80 | return false; | 80 | return false; |
81 | if (!match_tcp(skb, info, par->hotdrop)) | 81 | if (!match_tcp(skb, info, &par->hotdrop)) |
82 | return false; | 82 | return false; |
83 | } | 83 | } |
84 | 84 | ||
85 | return true; | 85 | return true; |
86 | } | 86 | } |
87 | 87 | ||
88 | static bool ecn_mt_check(const struct xt_mtchk_param *par) | 88 | static int ecn_mt_check(const struct xt_mtchk_param *par) |
89 | { | 89 | { |
90 | const struct ipt_ecn_info *info = par->matchinfo; | 90 | const struct ipt_ecn_info *info = par->matchinfo; |
91 | const struct ipt_ip *ip = par->entryinfo; | 91 | const struct ipt_ip *ip = par->entryinfo; |
92 | 92 | ||
93 | if (info->operation & IPT_ECN_OP_MATCH_MASK) | 93 | if (info->operation & IPT_ECN_OP_MATCH_MASK) |
94 | return false; | 94 | return -EINVAL; |
95 | 95 | ||
96 | if (info->invert & IPT_ECN_OP_MATCH_MASK) | 96 | if (info->invert & IPT_ECN_OP_MATCH_MASK) |
97 | return false; | 97 | return -EINVAL; |
98 | 98 | ||
99 | if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR) && | 99 | if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR) && |
100 | ip->proto != IPPROTO_TCP) { | 100 | ip->proto != IPPROTO_TCP) { |
101 | printk(KERN_WARNING "ipt_ecn: can't match TCP bits in rule for" | 101 | pr_info("cannot match TCP bits in rule for non-tcp packets\n"); |
102 | " non-tcp packets\n"); | 102 | return -EINVAL; |
103 | return false; | ||
104 | } | 103 | } |
105 | 104 | ||
106 | return true; | 105 | return 0; |
107 | } | 106 | } |
108 | 107 | ||
109 | static struct xt_match ecn_mt_reg __read_mostly = { | 108 | static struct xt_match ecn_mt_reg __read_mostly = { |
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c index 55392466daa..c37641e819f 100644 --- a/net/ipv4/netfilter/iptable_filter.c +++ b/net/ipv4/netfilter/iptable_filter.c | |||
@@ -89,7 +89,7 @@ static int __init iptable_filter_init(void) | |||
89 | int ret; | 89 | int ret; |
90 | 90 | ||
91 | if (forward < 0 || forward > NF_MAX_VERDICT) { | 91 | if (forward < 0 || forward > NF_MAX_VERDICT) { |
92 | printk("iptables forward must be 0 or 1\n"); | 92 | pr_err("iptables forward must be 0 or 1\n"); |
93 | return -EINVAL; | 93 | return -EINVAL; |
94 | } | 94 | } |
95 | 95 | ||
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 2bb1f87051c..5a03c02af99 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | |||
@@ -382,32 +382,32 @@ static int __init nf_conntrack_l3proto_ipv4_init(void) | |||
382 | 382 | ||
383 | ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp4); | 383 | ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp4); |
384 | if (ret < 0) { | 384 | if (ret < 0) { |
385 | printk("nf_conntrack_ipv4: can't register tcp.\n"); | 385 | pr_err("nf_conntrack_ipv4: can't register tcp.\n"); |
386 | goto cleanup_sockopt; | 386 | goto cleanup_sockopt; |
387 | } | 387 | } |
388 | 388 | ||
389 | ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp4); | 389 | ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp4); |
390 | if (ret < 0) { | 390 | if (ret < 0) { |
391 | printk("nf_conntrack_ipv4: can't register udp.\n"); | 391 | pr_err("nf_conntrack_ipv4: can't register udp.\n"); |
392 | goto cleanup_tcp; | 392 | goto cleanup_tcp; |
393 | } | 393 | } |
394 | 394 | ||
395 | ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_icmp); | 395 | ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_icmp); |
396 | if (ret < 0) { | 396 | if (ret < 0) { |
397 | printk("nf_conntrack_ipv4: can't register icmp.\n"); | 397 | pr_err("nf_conntrack_ipv4: can't register icmp.\n"); |
398 | goto cleanup_udp; | 398 | goto cleanup_udp; |
399 | } | 399 | } |
400 | 400 | ||
401 | ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv4); | 401 | ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv4); |
402 | if (ret < 0) { | 402 | if (ret < 0) { |
403 | printk("nf_conntrack_ipv4: can't register ipv4\n"); | 403 | pr_err("nf_conntrack_ipv4: can't register ipv4\n"); |
404 | goto cleanup_icmp; | 404 | goto cleanup_icmp; |
405 | } | 405 | } |
406 | 406 | ||
407 | ret = nf_register_hooks(ipv4_conntrack_ops, | 407 | ret = nf_register_hooks(ipv4_conntrack_ops, |
408 | ARRAY_SIZE(ipv4_conntrack_ops)); | 408 | ARRAY_SIZE(ipv4_conntrack_ops)); |
409 | if (ret < 0) { | 409 | if (ret < 0) { |
410 | printk("nf_conntrack_ipv4: can't register hooks.\n"); | 410 | pr_err("nf_conntrack_ipv4: can't register hooks.\n"); |
411 | goto cleanup_ipv4; | 411 | goto cleanup_ipv4; |
412 | } | 412 | } |
413 | #if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) | 413 | #if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) |
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c index 2fb7b76da94..244f7cb08d6 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c | |||
@@ -336,12 +336,12 @@ static int ct_cpu_seq_show(struct seq_file *seq, void *v) | |||
336 | const struct ip_conntrack_stat *st = v; | 336 | const struct ip_conntrack_stat *st = v; |
337 | 337 | ||
338 | if (v == SEQ_START_TOKEN) { | 338 | if (v == SEQ_START_TOKEN) { |
339 | seq_printf(seq, "entries searched found new invalid ignore delete delete_list insert insert_failed drop early_drop icmp_error expect_new expect_create expect_delete\n"); | 339 | seq_printf(seq, "entries searched found new invalid ignore delete delete_list insert insert_failed drop early_drop icmp_error expect_new expect_create expect_delete search_restart\n"); |
340 | return 0; | 340 | return 0; |
341 | } | 341 | } |
342 | 342 | ||
343 | seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x " | 343 | seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x " |
344 | "%08x %08x %08x %08x %08x %08x %08x %08x \n", | 344 | "%08x %08x %08x %08x %08x %08x %08x %08x %08x\n", |
345 | nr_conntracks, | 345 | nr_conntracks, |
346 | st->searched, | 346 | st->searched, |
347 | st->found, | 347 | st->found, |
@@ -358,7 +358,8 @@ static int ct_cpu_seq_show(struct seq_file *seq, void *v) | |||
358 | 358 | ||
359 | st->expect_new, | 359 | st->expect_new, |
360 | st->expect_create, | 360 | st->expect_create, |
361 | st->expect_delete | 361 | st->expect_delete, |
362 | st->search_restart | ||
362 | ); | 363 | ); |
363 | return 0; | 364 | return 0; |
364 | } | 365 | } |
diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c index 7e8e6fc7541..5045196d853 100644 --- a/net/ipv4/netfilter/nf_nat_h323.c +++ b/net/ipv4/netfilter/nf_nat_h323.c | |||
@@ -10,7 +10,6 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/moduleparam.h> | ||
14 | #include <linux/tcp.h> | 13 | #include <linux/tcp.h> |
15 | #include <net/tcp.h> | 14 | #include <net/tcp.h> |
16 | 15 | ||
@@ -44,7 +43,7 @@ static int set_addr(struct sk_buff *skb, | |||
44 | addroff, sizeof(buf), | 43 | addroff, sizeof(buf), |
45 | (char *) &buf, sizeof(buf))) { | 44 | (char *) &buf, sizeof(buf))) { |
46 | if (net_ratelimit()) | 45 | if (net_ratelimit()) |
47 | printk("nf_nat_h323: nf_nat_mangle_tcp_packet" | 46 | pr_notice("nf_nat_h323: nf_nat_mangle_tcp_packet" |
48 | " error\n"); | 47 | " error\n"); |
49 | return -1; | 48 | return -1; |
50 | } | 49 | } |
@@ -60,7 +59,7 @@ static int set_addr(struct sk_buff *skb, | |||
60 | addroff, sizeof(buf), | 59 | addroff, sizeof(buf), |
61 | (char *) &buf, sizeof(buf))) { | 60 | (char *) &buf, sizeof(buf))) { |
62 | if (net_ratelimit()) | 61 | if (net_ratelimit()) |
63 | printk("nf_nat_h323: nf_nat_mangle_udp_packet" | 62 | pr_notice("nf_nat_h323: nf_nat_mangle_udp_packet" |
64 | " error\n"); | 63 | " error\n"); |
65 | return -1; | 64 | return -1; |
66 | } | 65 | } |
@@ -216,7 +215,7 @@ static int nat_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct, | |||
216 | /* Run out of expectations */ | 215 | /* Run out of expectations */ |
217 | if (i >= H323_RTP_CHANNEL_MAX) { | 216 | if (i >= H323_RTP_CHANNEL_MAX) { |
218 | if (net_ratelimit()) | 217 | if (net_ratelimit()) |
219 | printk("nf_nat_h323: out of expectations\n"); | 218 | pr_notice("nf_nat_h323: out of expectations\n"); |
220 | return 0; | 219 | return 0; |
221 | } | 220 | } |
222 | 221 | ||
@@ -235,7 +234,7 @@ static int nat_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct, | |||
235 | 234 | ||
236 | if (nated_port == 0) { /* No port available */ | 235 | if (nated_port == 0) { /* No port available */ |
237 | if (net_ratelimit()) | 236 | if (net_ratelimit()) |
238 | printk("nf_nat_h323: out of RTP ports\n"); | 237 | pr_notice("nf_nat_h323: out of RTP ports\n"); |
239 | return 0; | 238 | return 0; |
240 | } | 239 | } |
241 | 240 | ||
@@ -292,7 +291,7 @@ static int nat_t120(struct sk_buff *skb, struct nf_conn *ct, | |||
292 | 291 | ||
293 | if (nated_port == 0) { /* No port available */ | 292 | if (nated_port == 0) { /* No port available */ |
294 | if (net_ratelimit()) | 293 | if (net_ratelimit()) |
295 | printk("nf_nat_h323: out of TCP ports\n"); | 294 | pr_notice("nf_nat_h323: out of TCP ports\n"); |
296 | return 0; | 295 | return 0; |
297 | } | 296 | } |
298 | 297 | ||
@@ -342,7 +341,7 @@ static int nat_h245(struct sk_buff *skb, struct nf_conn *ct, | |||
342 | 341 | ||
343 | if (nated_port == 0) { /* No port available */ | 342 | if (nated_port == 0) { /* No port available */ |
344 | if (net_ratelimit()) | 343 | if (net_ratelimit()) |
345 | printk("nf_nat_q931: out of TCP ports\n"); | 344 | pr_notice("nf_nat_q931: out of TCP ports\n"); |
346 | return 0; | 345 | return 0; |
347 | } | 346 | } |
348 | 347 | ||
@@ -426,7 +425,7 @@ static int nat_q931(struct sk_buff *skb, struct nf_conn *ct, | |||
426 | 425 | ||
427 | if (nated_port == 0) { /* No port available */ | 426 | if (nated_port == 0) { /* No port available */ |
428 | if (net_ratelimit()) | 427 | if (net_ratelimit()) |
429 | printk("nf_nat_ras: out of TCP ports\n"); | 428 | pr_notice("nf_nat_ras: out of TCP ports\n"); |
430 | return 0; | 429 | return 0; |
431 | } | 430 | } |
432 | 431 | ||
@@ -508,7 +507,7 @@ static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct, | |||
508 | 507 | ||
509 | if (nated_port == 0) { /* No port available */ | 508 | if (nated_port == 0) { /* No port available */ |
510 | if (net_ratelimit()) | 509 | if (net_ratelimit()) |
511 | printk("nf_nat_q931: out of TCP ports\n"); | 510 | pr_notice("nf_nat_q931: out of TCP ports\n"); |
512 | return 0; | 511 | return 0; |
513 | } | 512 | } |
514 | 513 | ||
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c index 26de2c1f7fa..98ed78281ae 100644 --- a/net/ipv4/netfilter/nf_nat_rule.c +++ b/net/ipv4/netfilter/nf_nat_rule.c | |||
@@ -7,6 +7,7 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | /* Everything about the rules for NAT. */ | 9 | /* Everything about the rules for NAT. */ |
10 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
10 | #include <linux/types.h> | 11 | #include <linux/types.h> |
11 | #include <linux/ip.h> | 12 | #include <linux/ip.h> |
12 | #include <linux/netfilter.h> | 13 | #include <linux/netfilter.h> |
@@ -38,7 +39,7 @@ static const struct xt_table nat_table = { | |||
38 | 39 | ||
39 | /* Source NAT */ | 40 | /* Source NAT */ |
40 | static unsigned int | 41 | static unsigned int |
41 | ipt_snat_target(struct sk_buff *skb, const struct xt_target_param *par) | 42 | ipt_snat_target(struct sk_buff *skb, const struct xt_action_param *par) |
42 | { | 43 | { |
43 | struct nf_conn *ct; | 44 | struct nf_conn *ct; |
44 | enum ip_conntrack_info ctinfo; | 45 | enum ip_conntrack_info ctinfo; |
@@ -57,7 +58,7 @@ ipt_snat_target(struct sk_buff *skb, const struct xt_target_param *par) | |||
57 | } | 58 | } |
58 | 59 | ||
59 | static unsigned int | 60 | static unsigned int |
60 | ipt_dnat_target(struct sk_buff *skb, const struct xt_target_param *par) | 61 | ipt_dnat_target(struct sk_buff *skb, const struct xt_action_param *par) |
61 | { | 62 | { |
62 | struct nf_conn *ct; | 63 | struct nf_conn *ct; |
63 | enum ip_conntrack_info ctinfo; | 64 | enum ip_conntrack_info ctinfo; |
@@ -74,28 +75,28 @@ ipt_dnat_target(struct sk_buff *skb, const struct xt_target_param *par) | |||
74 | return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_DST); | 75 | return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_DST); |
75 | } | 76 | } |
76 | 77 | ||
77 | static bool ipt_snat_checkentry(const struct xt_tgchk_param *par) | 78 | static int ipt_snat_checkentry(const struct xt_tgchk_param *par) |
78 | { | 79 | { |
79 | const struct nf_nat_multi_range_compat *mr = par->targinfo; | 80 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
80 | 81 | ||
81 | /* Must be a valid range */ | 82 | /* Must be a valid range */ |
82 | if (mr->rangesize != 1) { | 83 | if (mr->rangesize != 1) { |
83 | printk("SNAT: multiple ranges no longer supported\n"); | 84 | pr_info("SNAT: multiple ranges no longer supported\n"); |
84 | return false; | 85 | return -EINVAL; |
85 | } | 86 | } |
86 | return true; | 87 | return 0; |
87 | } | 88 | } |
88 | 89 | ||
89 | static bool ipt_dnat_checkentry(const struct xt_tgchk_param *par) | 90 | static int ipt_dnat_checkentry(const struct xt_tgchk_param *par) |
90 | { | 91 | { |
91 | const struct nf_nat_multi_range_compat *mr = par->targinfo; | 92 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
92 | 93 | ||
93 | /* Must be a valid range */ | 94 | /* Must be a valid range */ |
94 | if (mr->rangesize != 1) { | 95 | if (mr->rangesize != 1) { |
95 | printk("DNAT: multiple ranges no longer supported\n"); | 96 | pr_info("DNAT: multiple ranges no longer supported\n"); |
96 | return false; | 97 | return -EINVAL; |
97 | } | 98 | } |
98 | return true; | 99 | return 0; |
99 | } | 100 | } |
100 | 101 | ||
101 | unsigned int | 102 | unsigned int |
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c index 4d85b6e55f2..1679e2c0963 100644 --- a/net/ipv4/netfilter/nf_nat_snmp_basic.c +++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c | |||
@@ -401,7 +401,7 @@ static unsigned char asn1_octets_decode(struct asn1_ctx *ctx, | |||
401 | *octets = kmalloc(eoc - ctx->pointer, GFP_ATOMIC); | 401 | *octets = kmalloc(eoc - ctx->pointer, GFP_ATOMIC); |
402 | if (*octets == NULL) { | 402 | if (*octets == NULL) { |
403 | if (net_ratelimit()) | 403 | if (net_ratelimit()) |
404 | printk("OOM in bsalg (%d)\n", __LINE__); | 404 | pr_notice("OOM in bsalg (%d)\n", __LINE__); |
405 | return 0; | 405 | return 0; |
406 | } | 406 | } |
407 | 407 | ||
@@ -452,7 +452,7 @@ static unsigned char asn1_oid_decode(struct asn1_ctx *ctx, | |||
452 | *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC); | 452 | *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC); |
453 | if (*oid == NULL) { | 453 | if (*oid == NULL) { |
454 | if (net_ratelimit()) | 454 | if (net_ratelimit()) |
455 | printk("OOM in bsalg (%d)\n", __LINE__); | 455 | pr_notice("OOM in bsalg (%d)\n", __LINE__); |
456 | return 0; | 456 | return 0; |
457 | } | 457 | } |
458 | 458 | ||
@@ -729,7 +729,7 @@ static unsigned char snmp_object_decode(struct asn1_ctx *ctx, | |||
729 | if (*obj == NULL) { | 729 | if (*obj == NULL) { |
730 | kfree(id); | 730 | kfree(id); |
731 | if (net_ratelimit()) | 731 | if (net_ratelimit()) |
732 | printk("OOM in bsalg (%d)\n", __LINE__); | 732 | pr_notice("OOM in bsalg (%d)\n", __LINE__); |
733 | return 0; | 733 | return 0; |
734 | } | 734 | } |
735 | (*obj)->syntax.l[0] = l; | 735 | (*obj)->syntax.l[0] = l; |
@@ -746,7 +746,7 @@ static unsigned char snmp_object_decode(struct asn1_ctx *ctx, | |||
746 | kfree(p); | 746 | kfree(p); |
747 | kfree(id); | 747 | kfree(id); |
748 | if (net_ratelimit()) | 748 | if (net_ratelimit()) |
749 | printk("OOM in bsalg (%d)\n", __LINE__); | 749 | pr_notice("OOM in bsalg (%d)\n", __LINE__); |
750 | return 0; | 750 | return 0; |
751 | } | 751 | } |
752 | memcpy((*obj)->syntax.c, p, len); | 752 | memcpy((*obj)->syntax.c, p, len); |
@@ -761,7 +761,7 @@ static unsigned char snmp_object_decode(struct asn1_ctx *ctx, | |||
761 | if (*obj == NULL) { | 761 | if (*obj == NULL) { |
762 | kfree(id); | 762 | kfree(id); |
763 | if (net_ratelimit()) | 763 | if (net_ratelimit()) |
764 | printk("OOM in bsalg (%d)\n", __LINE__); | 764 | pr_notice("OOM in bsalg (%d)\n", __LINE__); |
765 | return 0; | 765 | return 0; |
766 | } | 766 | } |
767 | if (!asn1_null_decode(ctx, end)) { | 767 | if (!asn1_null_decode(ctx, end)) { |
@@ -782,7 +782,7 @@ static unsigned char snmp_object_decode(struct asn1_ctx *ctx, | |||
782 | kfree(lp); | 782 | kfree(lp); |
783 | kfree(id); | 783 | kfree(id); |
784 | if (net_ratelimit()) | 784 | if (net_ratelimit()) |
785 | printk("OOM in bsalg (%d)\n", __LINE__); | 785 | pr_notice("OOM in bsalg (%d)\n", __LINE__); |
786 | return 0; | 786 | return 0; |
787 | } | 787 | } |
788 | memcpy((*obj)->syntax.ul, lp, len); | 788 | memcpy((*obj)->syntax.ul, lp, len); |
@@ -803,7 +803,7 @@ static unsigned char snmp_object_decode(struct asn1_ctx *ctx, | |||
803 | kfree(p); | 803 | kfree(p); |
804 | kfree(id); | 804 | kfree(id); |
805 | if (net_ratelimit()) | 805 | if (net_ratelimit()) |
806 | printk("OOM in bsalg (%d)\n", __LINE__); | 806 | pr_notice("OOM in bsalg (%d)\n", __LINE__); |
807 | return 0; | 807 | return 0; |
808 | } | 808 | } |
809 | memcpy((*obj)->syntax.uc, p, len); | 809 | memcpy((*obj)->syntax.uc, p, len); |
@@ -821,7 +821,7 @@ static unsigned char snmp_object_decode(struct asn1_ctx *ctx, | |||
821 | if (*obj == NULL) { | 821 | if (*obj == NULL) { |
822 | kfree(id); | 822 | kfree(id); |
823 | if (net_ratelimit()) | 823 | if (net_ratelimit()) |
824 | printk("OOM in bsalg (%d)\n", __LINE__); | 824 | pr_notice("OOM in bsalg (%d)\n", __LINE__); |
825 | return 0; | 825 | return 0; |
826 | } | 826 | } |
827 | (*obj)->syntax.ul[0] = ul; | 827 | (*obj)->syntax.ul[0] = ul; |
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c index c39c9cf6bee..beb25819c9c 100644 --- a/net/ipv4/netfilter/nf_nat_standalone.c +++ b/net/ipv4/netfilter/nf_nat_standalone.c | |||
@@ -138,9 +138,8 @@ nf_nat_fn(unsigned int hooknum, | |||
138 | ret = nf_nat_rule_find(skb, hooknum, in, out, | 138 | ret = nf_nat_rule_find(skb, hooknum, in, out, |
139 | ct); | 139 | ct); |
140 | 140 | ||
141 | if (ret != NF_ACCEPT) { | 141 | if (ret != NF_ACCEPT) |
142 | return ret; | 142 | return ret; |
143 | } | ||
144 | } else | 143 | } else |
145 | pr_debug("Already setup manip %s for ct %p\n", | 144 | pr_debug("Already setup manip %s for ct %p\n", |
146 | maniptype == IP_NAT_MANIP_SRC ? "SRC" : "DST", | 145 | maniptype == IP_NAT_MANIP_SRC ? "SRC" : "DST", |
@@ -294,12 +293,12 @@ static int __init nf_nat_standalone_init(void) | |||
294 | #endif | 293 | #endif |
295 | ret = nf_nat_rule_init(); | 294 | ret = nf_nat_rule_init(); |
296 | if (ret < 0) { | 295 | if (ret < 0) { |
297 | printk("nf_nat_init: can't setup rules.\n"); | 296 | pr_err("nf_nat_init: can't setup rules.\n"); |
298 | goto cleanup_decode_session; | 297 | goto cleanup_decode_session; |
299 | } | 298 | } |
300 | ret = nf_register_hooks(nf_nat_ops, ARRAY_SIZE(nf_nat_ops)); | 299 | ret = nf_register_hooks(nf_nat_ops, ARRAY_SIZE(nf_nat_ops)); |
301 | if (ret < 0) { | 300 | if (ret < 0) { |
302 | printk("nf_nat_init: can't register hooks.\n"); | 301 | pr_err("nf_nat_init: can't register hooks.\n"); |
303 | goto cleanup_rule_init; | 302 | goto cleanup_rule_init; |
304 | } | 303 | } |
305 | return ret; | 304 | return ret; |
diff --git a/net/ipv4/netfilter/nf_nat_tftp.c b/net/ipv4/netfilter/nf_nat_tftp.c index b096e81500a..7274a43c7a1 100644 --- a/net/ipv4/netfilter/nf_nat_tftp.c +++ b/net/ipv4/netfilter/nf_nat_tftp.c | |||
@@ -6,7 +6,6 @@ | |||
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/moduleparam.h> | ||
10 | #include <linux/udp.h> | 9 | #include <linux/udp.h> |
11 | 10 | ||
12 | #include <net/netfilter/nf_nat_helper.h> | 11 | #include <net/netfilter/nf_nat_helper.h> |
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 4f1f337f433..3dc9914c1dc 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
@@ -251,6 +251,7 @@ static const struct snmp_mib snmp4_net_list[] = { | |||
251 | SNMP_MIB_ITEM("TCPSackShiftFallback", LINUX_MIB_SACKSHIFTFALLBACK), | 251 | SNMP_MIB_ITEM("TCPSackShiftFallback", LINUX_MIB_SACKSHIFTFALLBACK), |
252 | SNMP_MIB_ITEM("TCPBacklogDrop", LINUX_MIB_TCPBACKLOGDROP), | 252 | SNMP_MIB_ITEM("TCPBacklogDrop", LINUX_MIB_TCPBACKLOGDROP), |
253 | SNMP_MIB_ITEM("TCPMinTTLDrop", LINUX_MIB_TCPMINTTLDROP), | 253 | SNMP_MIB_ITEM("TCPMinTTLDrop", LINUX_MIB_TCPMINTTLDROP), |
254 | SNMP_MIB_ITEM("TCPDeferAcceptDrop", LINUX_MIB_TCPDEFERACCEPTDROP), | ||
254 | SNMP_MIB_SENTINEL | 255 | SNMP_MIB_SENTINEL |
255 | }; | 256 | }; |
256 | 257 | ||
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index cc6f097fbd5..2c7a1639388 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -290,7 +290,7 @@ static int raw_rcv_skb(struct sock * sk, struct sk_buff * skb) | |||
290 | { | 290 | { |
291 | /* Charge it to the socket. */ | 291 | /* Charge it to the socket. */ |
292 | 292 | ||
293 | if (sock_queue_rcv_skb(sk, skb) < 0) { | 293 | if (ip_queue_rcv_skb(sk, skb) < 0) { |
294 | kfree_skb(skb); | 294 | kfree_skb(skb); |
295 | return NET_RX_DROP; | 295 | return NET_RX_DROP; |
296 | } | 296 | } |
@@ -381,8 +381,8 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, | |||
381 | icmp_out_count(net, ((struct icmphdr *) | 381 | icmp_out_count(net, ((struct icmphdr *) |
382 | skb_transport_header(skb))->type); | 382 | skb_transport_header(skb))->type); |
383 | 383 | ||
384 | err = NF_HOOK(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev, | 384 | err = NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, skb, NULL, |
385 | dst_output); | 385 | rt->u.dst.dev, dst_output); |
386 | if (err > 0) | 386 | if (err > 0) |
387 | err = net_xmit_errno(err); | 387 | err = net_xmit_errno(err); |
388 | if (err) | 388 | if (err) |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index cb562fdd9b9..560acc677ce 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -129,7 +129,6 @@ static int ip_rt_gc_elasticity __read_mostly = 8; | |||
129 | static int ip_rt_mtu_expires __read_mostly = 10 * 60 * HZ; | 129 | static int ip_rt_mtu_expires __read_mostly = 10 * 60 * HZ; |
130 | static int ip_rt_min_pmtu __read_mostly = 512 + 20 + 20; | 130 | static int ip_rt_min_pmtu __read_mostly = 512 + 20 + 20; |
131 | static int ip_rt_min_advmss __read_mostly = 256; | 131 | static int ip_rt_min_advmss __read_mostly = 256; |
132 | static int ip_rt_secret_interval __read_mostly = 10 * 60 * HZ; | ||
133 | static int rt_chain_length_max __read_mostly = 20; | 132 | static int rt_chain_length_max __read_mostly = 20; |
134 | 133 | ||
135 | static struct delayed_work expires_work; | 134 | static struct delayed_work expires_work; |
@@ -258,10 +257,9 @@ static DEFINE_PER_CPU(struct rt_cache_stat, rt_cache_stat); | |||
258 | (__raw_get_cpu_var(rt_cache_stat).field++) | 257 | (__raw_get_cpu_var(rt_cache_stat).field++) |
259 | 258 | ||
260 | static inline unsigned int rt_hash(__be32 daddr, __be32 saddr, int idx, | 259 | static inline unsigned int rt_hash(__be32 daddr, __be32 saddr, int idx, |
261 | int genid) | 260 | int genid) |
262 | { | 261 | { |
263 | return jhash_3words((__force u32)(__be32)(daddr), | 262 | return jhash_3words((__force u32)daddr, (__force u32)saddr, |
264 | (__force u32)(__be32)(saddr), | ||
265 | idx, genid) | 263 | idx, genid) |
266 | & rt_hash_mask; | 264 | & rt_hash_mask; |
267 | } | 265 | } |
@@ -378,12 +376,13 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v) | |||
378 | struct rtable *r = v; | 376 | struct rtable *r = v; |
379 | int len; | 377 | int len; |
380 | 378 | ||
381 | seq_printf(seq, "%s\t%08lX\t%08lX\t%8X\t%d\t%u\t%d\t" | 379 | seq_printf(seq, "%s\t%08X\t%08X\t%8X\t%d\t%u\t%d\t" |
382 | "%08lX\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X%n", | 380 | "%08X\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X%n", |
383 | r->u.dst.dev ? r->u.dst.dev->name : "*", | 381 | r->u.dst.dev ? r->u.dst.dev->name : "*", |
384 | (unsigned long)r->rt_dst, (unsigned long)r->rt_gateway, | 382 | (__force u32)r->rt_dst, |
383 | (__force u32)r->rt_gateway, | ||
385 | r->rt_flags, atomic_read(&r->u.dst.__refcnt), | 384 | r->rt_flags, atomic_read(&r->u.dst.__refcnt), |
386 | r->u.dst.__use, 0, (unsigned long)r->rt_src, | 385 | r->u.dst.__use, 0, (__force u32)r->rt_src, |
387 | (dst_metric(&r->u.dst, RTAX_ADVMSS) ? | 386 | (dst_metric(&r->u.dst, RTAX_ADVMSS) ? |
388 | (int)dst_metric(&r->u.dst, RTAX_ADVMSS) + 40 : 0), | 387 | (int)dst_metric(&r->u.dst, RTAX_ADVMSS) + 40 : 0), |
389 | dst_metric(&r->u.dst, RTAX_WINDOW), | 388 | dst_metric(&r->u.dst, RTAX_WINDOW), |
@@ -685,18 +684,17 @@ static inline bool rt_caching(const struct net *net) | |||
685 | static inline bool compare_hash_inputs(const struct flowi *fl1, | 684 | static inline bool compare_hash_inputs(const struct flowi *fl1, |
686 | const struct flowi *fl2) | 685 | const struct flowi *fl2) |
687 | { | 686 | { |
688 | return (__force u32)(((fl1->nl_u.ip4_u.daddr ^ fl2->nl_u.ip4_u.daddr) | | 687 | return ((((__force u32)fl1->nl_u.ip4_u.daddr ^ (__force u32)fl2->nl_u.ip4_u.daddr) | |
689 | (fl1->nl_u.ip4_u.saddr ^ fl2->nl_u.ip4_u.saddr) | | 688 | ((__force u32)fl1->nl_u.ip4_u.saddr ^ (__force u32)fl2->nl_u.ip4_u.saddr) | |
690 | (fl1->iif ^ fl2->iif)) == 0); | 689 | (fl1->iif ^ fl2->iif)) == 0); |
691 | } | 690 | } |
692 | 691 | ||
693 | static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) | 692 | static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) |
694 | { | 693 | { |
695 | return ((__force u32)((fl1->nl_u.ip4_u.daddr ^ fl2->nl_u.ip4_u.daddr) | | 694 | return (((__force u32)fl1->nl_u.ip4_u.daddr ^ (__force u32)fl2->nl_u.ip4_u.daddr) | |
696 | (fl1->nl_u.ip4_u.saddr ^ fl2->nl_u.ip4_u.saddr)) | | 695 | ((__force u32)fl1->nl_u.ip4_u.saddr ^ (__force u32)fl2->nl_u.ip4_u.saddr) | |
697 | (fl1->mark ^ fl2->mark) | | 696 | (fl1->mark ^ fl2->mark) | |
698 | (*(u16 *)&fl1->nl_u.ip4_u.tos ^ | 697 | (*(u16 *)&fl1->nl_u.ip4_u.tos ^ *(u16 *)&fl2->nl_u.ip4_u.tos) | |
699 | *(u16 *)&fl2->nl_u.ip4_u.tos) | | ||
700 | (fl1->oif ^ fl2->oif) | | 698 | (fl1->oif ^ fl2->oif) | |
701 | (fl1->iif ^ fl2->iif)) == 0; | 699 | (fl1->iif ^ fl2->iif)) == 0; |
702 | } | 700 | } |
@@ -919,32 +917,11 @@ void rt_cache_flush_batch(void) | |||
919 | rt_do_flush(!in_softirq()); | 917 | rt_do_flush(!in_softirq()); |
920 | } | 918 | } |
921 | 919 | ||
922 | /* | ||
923 | * We change rt_genid and let gc do the cleanup | ||
924 | */ | ||
925 | static void rt_secret_rebuild(unsigned long __net) | ||
926 | { | ||
927 | struct net *net = (struct net *)__net; | ||
928 | rt_cache_invalidate(net); | ||
929 | mod_timer(&net->ipv4.rt_secret_timer, jiffies + ip_rt_secret_interval); | ||
930 | } | ||
931 | |||
932 | static void rt_secret_rebuild_oneshot(struct net *net) | ||
933 | { | ||
934 | del_timer_sync(&net->ipv4.rt_secret_timer); | ||
935 | rt_cache_invalidate(net); | ||
936 | if (ip_rt_secret_interval) | ||
937 | mod_timer(&net->ipv4.rt_secret_timer, jiffies + ip_rt_secret_interval); | ||
938 | } | ||
939 | |||
940 | static void rt_emergency_hash_rebuild(struct net *net) | 920 | static void rt_emergency_hash_rebuild(struct net *net) |
941 | { | 921 | { |
942 | if (net_ratelimit()) { | 922 | if (net_ratelimit()) |
943 | printk(KERN_WARNING "Route hash chain too long!\n"); | 923 | printk(KERN_WARNING "Route hash chain too long!\n"); |
944 | printk(KERN_WARNING "Adjust your secret_interval!\n"); | 924 | rt_cache_invalidate(net); |
945 | } | ||
946 | |||
947 | rt_secret_rebuild_oneshot(net); | ||
948 | } | 925 | } |
949 | 926 | ||
950 | /* | 927 | /* |
@@ -2300,8 +2277,8 @@ martian_source: | |||
2300 | goto e_inval; | 2277 | goto e_inval; |
2301 | } | 2278 | } |
2302 | 2279 | ||
2303 | int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr, | 2280 | int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, |
2304 | u8 tos, struct net_device *dev) | 2281 | u8 tos, struct net_device *dev, bool noref) |
2305 | { | 2282 | { |
2306 | struct rtable * rth; | 2283 | struct rtable * rth; |
2307 | unsigned hash; | 2284 | unsigned hash; |
@@ -2319,18 +2296,23 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
2319 | rcu_read_lock(); | 2296 | rcu_read_lock(); |
2320 | for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; | 2297 | for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; |
2321 | rth = rcu_dereference(rth->u.dst.rt_next)) { | 2298 | rth = rcu_dereference(rth->u.dst.rt_next)) { |
2322 | if (((rth->fl.fl4_dst ^ daddr) | | 2299 | if ((((__force u32)rth->fl.fl4_dst ^ (__force u32)daddr) | |
2323 | (rth->fl.fl4_src ^ saddr) | | 2300 | ((__force u32)rth->fl.fl4_src ^ (__force u32)saddr) | |
2324 | (rth->fl.iif ^ iif) | | 2301 | (rth->fl.iif ^ iif) | |
2325 | rth->fl.oif | | 2302 | rth->fl.oif | |
2326 | (rth->fl.fl4_tos ^ tos)) == 0 && | 2303 | (rth->fl.fl4_tos ^ tos)) == 0 && |
2327 | rth->fl.mark == skb->mark && | 2304 | rth->fl.mark == skb->mark && |
2328 | net_eq(dev_net(rth->u.dst.dev), net) && | 2305 | net_eq(dev_net(rth->u.dst.dev), net) && |
2329 | !rt_is_expired(rth)) { | 2306 | !rt_is_expired(rth)) { |
2330 | dst_use(&rth->u.dst, jiffies); | 2307 | if (noref) { |
2308 | dst_use_noref(&rth->u.dst, jiffies); | ||
2309 | skb_dst_set_noref(skb, &rth->u.dst); | ||
2310 | } else { | ||
2311 | dst_use(&rth->u.dst, jiffies); | ||
2312 | skb_dst_set(skb, &rth->u.dst); | ||
2313 | } | ||
2331 | RT_CACHE_STAT_INC(in_hit); | 2314 | RT_CACHE_STAT_INC(in_hit); |
2332 | rcu_read_unlock(); | 2315 | rcu_read_unlock(); |
2333 | skb_dst_set(skb, &rth->u.dst); | ||
2334 | return 0; | 2316 | return 0; |
2335 | } | 2317 | } |
2336 | RT_CACHE_STAT_INC(in_hlist_search); | 2318 | RT_CACHE_STAT_INC(in_hlist_search); |
@@ -2373,6 +2355,7 @@ skip_cache: | |||
2373 | } | 2355 | } |
2374 | return ip_route_input_slow(skb, daddr, saddr, tos, dev); | 2356 | return ip_route_input_slow(skb, daddr, saddr, tos, dev); |
2375 | } | 2357 | } |
2358 | EXPORT_SYMBOL(ip_route_input_common); | ||
2376 | 2359 | ||
2377 | static int __mkroute_output(struct rtable **result, | 2360 | static int __mkroute_output(struct rtable **result, |
2378 | struct fib_result *res, | 2361 | struct fib_result *res, |
@@ -3056,7 +3039,7 @@ int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
3056 | continue; | 3039 | continue; |
3057 | if (rt_is_expired(rt)) | 3040 | if (rt_is_expired(rt)) |
3058 | continue; | 3041 | continue; |
3059 | skb_dst_set(skb, dst_clone(&rt->u.dst)); | 3042 | skb_dst_set_noref(skb, &rt->u.dst); |
3060 | if (rt_fill_info(net, skb, NETLINK_CB(cb->skb).pid, | 3043 | if (rt_fill_info(net, skb, NETLINK_CB(cb->skb).pid, |
3061 | cb->nlh->nlmsg_seq, RTM_NEWROUTE, | 3044 | cb->nlh->nlmsg_seq, RTM_NEWROUTE, |
3062 | 1, NLM_F_MULTI) <= 0) { | 3045 | 1, NLM_F_MULTI) <= 0) { |
@@ -3102,48 +3085,6 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write, | |||
3102 | return -EINVAL; | 3085 | return -EINVAL; |
3103 | } | 3086 | } |
3104 | 3087 | ||
3105 | static void rt_secret_reschedule(int old) | ||
3106 | { | ||
3107 | struct net *net; | ||
3108 | int new = ip_rt_secret_interval; | ||
3109 | int diff = new - old; | ||
3110 | |||
3111 | if (!diff) | ||
3112 | return; | ||
3113 | |||
3114 | rtnl_lock(); | ||
3115 | for_each_net(net) { | ||
3116 | int deleted = del_timer_sync(&net->ipv4.rt_secret_timer); | ||
3117 | long time; | ||
3118 | |||
3119 | if (!new) | ||
3120 | continue; | ||
3121 | |||
3122 | if (deleted) { | ||
3123 | time = net->ipv4.rt_secret_timer.expires - jiffies; | ||
3124 | |||
3125 | if (time <= 0 || (time += diff) <= 0) | ||
3126 | time = 0; | ||
3127 | } else | ||
3128 | time = new; | ||
3129 | |||
3130 | mod_timer(&net->ipv4.rt_secret_timer, jiffies + time); | ||
3131 | } | ||
3132 | rtnl_unlock(); | ||
3133 | } | ||
3134 | |||
3135 | static int ipv4_sysctl_rt_secret_interval(ctl_table *ctl, int write, | ||
3136 | void __user *buffer, size_t *lenp, | ||
3137 | loff_t *ppos) | ||
3138 | { | ||
3139 | int old = ip_rt_secret_interval; | ||
3140 | int ret = proc_dointvec_jiffies(ctl, write, buffer, lenp, ppos); | ||
3141 | |||
3142 | rt_secret_reschedule(old); | ||
3143 | |||
3144 | return ret; | ||
3145 | } | ||
3146 | |||
3147 | static ctl_table ipv4_route_table[] = { | 3088 | static ctl_table ipv4_route_table[] = { |
3148 | { | 3089 | { |
3149 | .procname = "gc_thresh", | 3090 | .procname = "gc_thresh", |
@@ -3252,13 +3193,6 @@ static ctl_table ipv4_route_table[] = { | |||
3252 | .mode = 0644, | 3193 | .mode = 0644, |
3253 | .proc_handler = proc_dointvec, | 3194 | .proc_handler = proc_dointvec, |
3254 | }, | 3195 | }, |
3255 | { | ||
3256 | .procname = "secret_interval", | ||
3257 | .data = &ip_rt_secret_interval, | ||
3258 | .maxlen = sizeof(int), | ||
3259 | .mode = 0644, | ||
3260 | .proc_handler = ipv4_sysctl_rt_secret_interval, | ||
3261 | }, | ||
3262 | { } | 3196 | { } |
3263 | }; | 3197 | }; |
3264 | 3198 | ||
@@ -3337,34 +3271,15 @@ static __net_initdata struct pernet_operations sysctl_route_ops = { | |||
3337 | }; | 3271 | }; |
3338 | #endif | 3272 | #endif |
3339 | 3273 | ||
3340 | 3274 | static __net_init int rt_genid_init(struct net *net) | |
3341 | static __net_init int rt_secret_timer_init(struct net *net) | ||
3342 | { | 3275 | { |
3343 | atomic_set(&net->ipv4.rt_genid, | 3276 | get_random_bytes(&net->ipv4.rt_genid, |
3344 | (int) ((num_physpages ^ (num_physpages>>8)) ^ | 3277 | sizeof(net->ipv4.rt_genid)); |
3345 | (jiffies ^ (jiffies >> 7)))); | ||
3346 | |||
3347 | net->ipv4.rt_secret_timer.function = rt_secret_rebuild; | ||
3348 | net->ipv4.rt_secret_timer.data = (unsigned long)net; | ||
3349 | init_timer_deferrable(&net->ipv4.rt_secret_timer); | ||
3350 | |||
3351 | if (ip_rt_secret_interval) { | ||
3352 | net->ipv4.rt_secret_timer.expires = | ||
3353 | jiffies + net_random() % ip_rt_secret_interval + | ||
3354 | ip_rt_secret_interval; | ||
3355 | add_timer(&net->ipv4.rt_secret_timer); | ||
3356 | } | ||
3357 | return 0; | 3278 | return 0; |
3358 | } | 3279 | } |
3359 | 3280 | ||
3360 | static __net_exit void rt_secret_timer_exit(struct net *net) | 3281 | static __net_initdata struct pernet_operations rt_genid_ops = { |
3361 | { | 3282 | .init = rt_genid_init, |
3362 | del_timer_sync(&net->ipv4.rt_secret_timer); | ||
3363 | } | ||
3364 | |||
3365 | static __net_initdata struct pernet_operations rt_secret_timer_ops = { | ||
3366 | .init = rt_secret_timer_init, | ||
3367 | .exit = rt_secret_timer_exit, | ||
3368 | }; | 3283 | }; |
3369 | 3284 | ||
3370 | 3285 | ||
@@ -3425,9 +3340,6 @@ int __init ip_rt_init(void) | |||
3425 | schedule_delayed_work(&expires_work, | 3340 | schedule_delayed_work(&expires_work, |
3426 | net_random() % ip_rt_gc_interval + ip_rt_gc_interval); | 3341 | net_random() % ip_rt_gc_interval + ip_rt_gc_interval); |
3427 | 3342 | ||
3428 | if (register_pernet_subsys(&rt_secret_timer_ops)) | ||
3429 | printk(KERN_ERR "Unable to setup rt_secret_timer\n"); | ||
3430 | |||
3431 | if (ip_rt_proc_init()) | 3343 | if (ip_rt_proc_init()) |
3432 | printk(KERN_ERR "Unable to create route proc files\n"); | 3344 | printk(KERN_ERR "Unable to create route proc files\n"); |
3433 | #ifdef CONFIG_XFRM | 3345 | #ifdef CONFIG_XFRM |
@@ -3439,6 +3351,7 @@ int __init ip_rt_init(void) | |||
3439 | #ifdef CONFIG_SYSCTL | 3351 | #ifdef CONFIG_SYSCTL |
3440 | register_pernet_subsys(&sysctl_route_ops); | 3352 | register_pernet_subsys(&sysctl_route_ops); |
3441 | #endif | 3353 | #endif |
3354 | register_pernet_subsys(&rt_genid_ops); | ||
3442 | return rc; | 3355 | return rc; |
3443 | } | 3356 | } |
3444 | 3357 | ||
@@ -3454,5 +3367,4 @@ void __init ip_static_sysctl_init(void) | |||
3454 | #endif | 3367 | #endif |
3455 | 3368 | ||
3456 | EXPORT_SYMBOL(__ip_select_ident); | 3369 | EXPORT_SYMBOL(__ip_select_ident); |
3457 | EXPORT_SYMBOL(ip_route_input); | ||
3458 | EXPORT_SYMBOL(ip_route_output_key); | 3370 | EXPORT_SYMBOL(ip_route_output_key); |
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 1cd5c15174b..d96c1da4b17 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c | |||
@@ -299,6 +299,13 @@ static struct ctl_table ipv4_table[] = { | |||
299 | .mode = 0644, | 299 | .mode = 0644, |
300 | .proc_handler = ipv4_local_port_range, | 300 | .proc_handler = ipv4_local_port_range, |
301 | }, | 301 | }, |
302 | { | ||
303 | .procname = "ip_local_reserved_ports", | ||
304 | .data = NULL, /* initialized in sysctl_ipv4_init */ | ||
305 | .maxlen = 65536, | ||
306 | .mode = 0644, | ||
307 | .proc_handler = proc_do_large_bitmap, | ||
308 | }, | ||
302 | #ifdef CONFIG_IP_MULTICAST | 309 | #ifdef CONFIG_IP_MULTICAST |
303 | { | 310 | { |
304 | .procname = "igmp_max_memberships", | 311 | .procname = "igmp_max_memberships", |
@@ -736,6 +743,16 @@ static __net_initdata struct pernet_operations ipv4_sysctl_ops = { | |||
736 | static __init int sysctl_ipv4_init(void) | 743 | static __init int sysctl_ipv4_init(void) |
737 | { | 744 | { |
738 | struct ctl_table_header *hdr; | 745 | struct ctl_table_header *hdr; |
746 | struct ctl_table *i; | ||
747 | |||
748 | for (i = ipv4_table; i->procname; i++) { | ||
749 | if (strcmp(i->procname, "ip_local_reserved_ports") == 0) { | ||
750 | i->data = sysctl_local_reserved_ports; | ||
751 | break; | ||
752 | } | ||
753 | } | ||
754 | if (!i->procname) | ||
755 | return -EINVAL; | ||
739 | 756 | ||
740 | hdr = register_sysctl_paths(net_ipv4_ctl_path, ipv4_table); | 757 | hdr = register_sysctl_paths(net_ipv4_ctl_path, ipv4_table); |
741 | if (hdr == NULL) | 758 | if (hdr == NULL) |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 296150b2a62..6596b4feedd 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -378,7 +378,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
378 | struct sock *sk = sock->sk; | 378 | struct sock *sk = sock->sk; |
379 | struct tcp_sock *tp = tcp_sk(sk); | 379 | struct tcp_sock *tp = tcp_sk(sk); |
380 | 380 | ||
381 | sock_poll_wait(file, sk->sk_sleep, wait); | 381 | sock_poll_wait(file, sk_sleep(sk), wait); |
382 | if (sk->sk_state == TCP_LISTEN) | 382 | if (sk->sk_state == TCP_LISTEN) |
383 | return inet_csk_listen_poll(sk); | 383 | return inet_csk_listen_poll(sk); |
384 | 384 | ||
@@ -2215,7 +2215,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, | |||
2215 | default: | 2215 | default: |
2216 | /* fallthru */ | 2216 | /* fallthru */ |
2217 | break; | 2217 | break; |
2218 | }; | 2218 | } |
2219 | 2219 | ||
2220 | if (optlen < sizeof(int)) | 2220 | if (optlen < sizeof(int)) |
2221 | return -EINVAL; | 2221 | return -EINVAL; |
@@ -2298,7 +2298,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, | |||
2298 | if (sock_flag(sk, SOCK_KEEPOPEN) && | 2298 | if (sock_flag(sk, SOCK_KEEPOPEN) && |
2299 | !((1 << sk->sk_state) & | 2299 | !((1 << sk->sk_state) & |
2300 | (TCPF_CLOSE | TCPF_LISTEN))) { | 2300 | (TCPF_CLOSE | TCPF_LISTEN))) { |
2301 | __u32 elapsed = tcp_time_stamp - tp->rcv_tstamp; | 2301 | u32 elapsed = keepalive_time_elapsed(tp); |
2302 | if (tp->keepalive_time > elapsed) | 2302 | if (tp->keepalive_time > elapsed) |
2303 | elapsed = tp->keepalive_time - elapsed; | 2303 | elapsed = tp->keepalive_time - elapsed; |
2304 | else | 2304 | else |
@@ -2721,7 +2721,7 @@ struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
2721 | struct tcphdr *th2; | 2721 | struct tcphdr *th2; |
2722 | unsigned int len; | 2722 | unsigned int len; |
2723 | unsigned int thlen; | 2723 | unsigned int thlen; |
2724 | unsigned int flags; | 2724 | __be32 flags; |
2725 | unsigned int mss = 1; | 2725 | unsigned int mss = 1; |
2726 | unsigned int hlen; | 2726 | unsigned int hlen; |
2727 | unsigned int off; | 2727 | unsigned int off; |
@@ -2771,10 +2771,10 @@ struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
2771 | 2771 | ||
2772 | found: | 2772 | found: |
2773 | flush = NAPI_GRO_CB(p)->flush; | 2773 | flush = NAPI_GRO_CB(p)->flush; |
2774 | flush |= flags & TCP_FLAG_CWR; | 2774 | flush |= (__force int)(flags & TCP_FLAG_CWR); |
2775 | flush |= (flags ^ tcp_flag_word(th2)) & | 2775 | flush |= (__force int)((flags ^ tcp_flag_word(th2)) & |
2776 | ~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH); | 2776 | ~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH)); |
2777 | flush |= th->ack_seq ^ th2->ack_seq; | 2777 | flush |= (__force int)(th->ack_seq ^ th2->ack_seq); |
2778 | for (i = sizeof(*th); i < thlen; i += 4) | 2778 | for (i = sizeof(*th); i < thlen; i += 4) |
2779 | flush |= *(u32 *)((u8 *)th + i) ^ | 2779 | flush |= *(u32 *)((u8 *)th + i) ^ |
2780 | *(u32 *)((u8 *)th2 + i); | 2780 | *(u32 *)((u8 *)th2 + i); |
@@ -2795,8 +2795,9 @@ found: | |||
2795 | 2795 | ||
2796 | out_check_final: | 2796 | out_check_final: |
2797 | flush = len < mss; | 2797 | flush = len < mss; |
2798 | flush |= flags & (TCP_FLAG_URG | TCP_FLAG_PSH | TCP_FLAG_RST | | 2798 | flush |= (__force int)(flags & (TCP_FLAG_URG | TCP_FLAG_PSH | |
2799 | TCP_FLAG_SYN | TCP_FLAG_FIN); | 2799 | TCP_FLAG_RST | TCP_FLAG_SYN | |
2800 | TCP_FLAG_FIN)); | ||
2800 | 2801 | ||
2801 | if (p && (!NAPI_GRO_CB(skb)->same_flow || flush)) | 2802 | if (p && (!NAPI_GRO_CB(skb)->same_flow || flush)) |
2802 | pp = head; | 2803 | pp = head; |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index f240f57b219..3e6dafcb107 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -3710,7 +3710,7 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) | |||
3710 | } | 3710 | } |
3711 | 3711 | ||
3712 | if ((flag & FLAG_FORWARD_PROGRESS) || !(flag & FLAG_NOT_DUP)) | 3712 | if ((flag & FLAG_FORWARD_PROGRESS) || !(flag & FLAG_NOT_DUP)) |
3713 | dst_confirm(sk->sk_dst_cache); | 3713 | dst_confirm(__sk_dst_get(sk)); |
3714 | 3714 | ||
3715 | return 1; | 3715 | return 1; |
3716 | 3716 | ||
@@ -3845,12 +3845,13 @@ void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx, | |||
3845 | /* 16-bit multiple */ | 3845 | /* 16-bit multiple */ |
3846 | opt_rx->cookie_plus = opsize; | 3846 | opt_rx->cookie_plus = opsize; |
3847 | *hvpp = ptr; | 3847 | *hvpp = ptr; |
3848 | break; | ||
3848 | default: | 3849 | default: |
3849 | /* ignore option */ | 3850 | /* ignore option */ |
3850 | break; | 3851 | break; |
3851 | }; | 3852 | } |
3852 | break; | 3853 | break; |
3853 | }; | 3854 | } |
3854 | 3855 | ||
3855 | ptr += opsize-2; | 3856 | ptr += opsize-2; |
3856 | length -= opsize; | 3857 | length -= opsize; |
@@ -4319,7 +4320,7 @@ static void tcp_ofo_queue(struct sock *sk) | |||
4319 | } | 4320 | } |
4320 | 4321 | ||
4321 | if (!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) { | 4322 | if (!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) { |
4322 | SOCK_DEBUG(sk, "ofo packet was already received \n"); | 4323 | SOCK_DEBUG(sk, "ofo packet was already received\n"); |
4323 | __skb_unlink(skb, &tp->out_of_order_queue); | 4324 | __skb_unlink(skb, &tp->out_of_order_queue); |
4324 | __kfree_skb(skb); | 4325 | __kfree_skb(skb); |
4325 | continue; | 4326 | continue; |
@@ -4367,6 +4368,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) | |||
4367 | if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) | 4368 | if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) |
4368 | goto drop; | 4369 | goto drop; |
4369 | 4370 | ||
4371 | skb_dst_drop(skb); | ||
4370 | __skb_pull(skb, th->doff * 4); | 4372 | __skb_pull(skb, th->doff * 4); |
4371 | 4373 | ||
4372 | TCP_ECN_accept_cwr(tp, skb); | 4374 | TCP_ECN_accept_cwr(tp, skb); |
@@ -5833,7 +5835,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
5833 | if (tp->snd_una == tp->write_seq) { | 5835 | if (tp->snd_una == tp->write_seq) { |
5834 | tcp_set_state(sk, TCP_FIN_WAIT2); | 5836 | tcp_set_state(sk, TCP_FIN_WAIT2); |
5835 | sk->sk_shutdown |= SEND_SHUTDOWN; | 5837 | sk->sk_shutdown |= SEND_SHUTDOWN; |
5836 | dst_confirm(sk->sk_dst_cache); | 5838 | dst_confirm(__sk_dst_get(sk)); |
5837 | 5839 | ||
5838 | if (!sock_flag(sk, SOCK_DEAD)) | 5840 | if (!sock_flag(sk, SOCK_DEAD)) |
5839 | /* Wake up lingering close() */ | 5841 | /* Wake up lingering close() */ |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 3c23e70885f..202cf09c4cd 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -519,26 +519,31 @@ out: | |||
519 | sock_put(sk); | 519 | sock_put(sk); |
520 | } | 520 | } |
521 | 521 | ||
522 | /* This routine computes an IPv4 TCP checksum. */ | 522 | static void __tcp_v4_send_check(struct sk_buff *skb, |
523 | void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb) | 523 | __be32 saddr, __be32 daddr) |
524 | { | 524 | { |
525 | struct inet_sock *inet = inet_sk(sk); | ||
526 | struct tcphdr *th = tcp_hdr(skb); | 525 | struct tcphdr *th = tcp_hdr(skb); |
527 | 526 | ||
528 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 527 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
529 | th->check = ~tcp_v4_check(len, inet->inet_saddr, | 528 | th->check = ~tcp_v4_check(skb->len, saddr, daddr, 0); |
530 | inet->inet_daddr, 0); | ||
531 | skb->csum_start = skb_transport_header(skb) - skb->head; | 529 | skb->csum_start = skb_transport_header(skb) - skb->head; |
532 | skb->csum_offset = offsetof(struct tcphdr, check); | 530 | skb->csum_offset = offsetof(struct tcphdr, check); |
533 | } else { | 531 | } else { |
534 | th->check = tcp_v4_check(len, inet->inet_saddr, | 532 | th->check = tcp_v4_check(skb->len, saddr, daddr, |
535 | inet->inet_daddr, | ||
536 | csum_partial(th, | 533 | csum_partial(th, |
537 | th->doff << 2, | 534 | th->doff << 2, |
538 | skb->csum)); | 535 | skb->csum)); |
539 | } | 536 | } |
540 | } | 537 | } |
541 | 538 | ||
539 | /* This routine computes an IPv4 TCP checksum. */ | ||
540 | void tcp_v4_send_check(struct sock *sk, struct sk_buff *skb) | ||
541 | { | ||
542 | struct inet_sock *inet = inet_sk(sk); | ||
543 | |||
544 | __tcp_v4_send_check(skb, inet->inet_saddr, inet->inet_daddr); | ||
545 | } | ||
546 | |||
542 | int tcp_v4_gso_send_check(struct sk_buff *skb) | 547 | int tcp_v4_gso_send_check(struct sk_buff *skb) |
543 | { | 548 | { |
544 | const struct iphdr *iph; | 549 | const struct iphdr *iph; |
@@ -551,10 +556,8 @@ int tcp_v4_gso_send_check(struct sk_buff *skb) | |||
551 | th = tcp_hdr(skb); | 556 | th = tcp_hdr(skb); |
552 | 557 | ||
553 | th->check = 0; | 558 | th->check = 0; |
554 | th->check = ~tcp_v4_check(skb->len, iph->saddr, iph->daddr, 0); | ||
555 | skb->csum_start = skb_transport_header(skb) - skb->head; | ||
556 | skb->csum_offset = offsetof(struct tcphdr, check); | ||
557 | skb->ip_summed = CHECKSUM_PARTIAL; | 559 | skb->ip_summed = CHECKSUM_PARTIAL; |
560 | __tcp_v4_send_check(skb, iph->saddr, iph->daddr); | ||
558 | return 0; | 561 | return 0; |
559 | } | 562 | } |
560 | 563 | ||
@@ -763,13 +766,7 @@ static int tcp_v4_send_synack(struct sock *sk, struct dst_entry *dst, | |||
763 | skb = tcp_make_synack(sk, dst, req, rvp); | 766 | skb = tcp_make_synack(sk, dst, req, rvp); |
764 | 767 | ||
765 | if (skb) { | 768 | if (skb) { |
766 | struct tcphdr *th = tcp_hdr(skb); | 769 | __tcp_v4_send_check(skb, ireq->loc_addr, ireq->rmt_addr); |
767 | |||
768 | th->check = tcp_v4_check(skb->len, | ||
769 | ireq->loc_addr, | ||
770 | ireq->rmt_addr, | ||
771 | csum_partial(th, skb->len, | ||
772 | skb->csum)); | ||
773 | 770 | ||
774 | err = ip_build_and_send_pkt(skb, sk, ireq->loc_addr, | 771 | err = ip_build_and_send_pkt(skb, sk, ireq->loc_addr, |
775 | ireq->rmt_addr, | 772 | ireq->rmt_addr, |
@@ -894,7 +891,7 @@ int tcp_v4_md5_do_add(struct sock *sk, __be32 addr, | |||
894 | kfree(newkey); | 891 | kfree(newkey); |
895 | return -ENOMEM; | 892 | return -ENOMEM; |
896 | } | 893 | } |
897 | sk->sk_route_caps &= ~NETIF_F_GSO_MASK; | 894 | sk_nocaps_add(sk, NETIF_F_GSO_MASK); |
898 | } | 895 | } |
899 | if (tcp_alloc_md5sig_pool(sk) == NULL) { | 896 | if (tcp_alloc_md5sig_pool(sk) == NULL) { |
900 | kfree(newkey); | 897 | kfree(newkey); |
@@ -1024,7 +1021,7 @@ static int tcp_v4_parse_md5_keys(struct sock *sk, char __user *optval, | |||
1024 | return -EINVAL; | 1021 | return -EINVAL; |
1025 | 1022 | ||
1026 | tp->md5sig_info = p; | 1023 | tp->md5sig_info = p; |
1027 | sk->sk_route_caps &= ~NETIF_F_GSO_MASK; | 1024 | sk_nocaps_add(sk, NETIF_F_GSO_MASK); |
1028 | } | 1025 | } |
1029 | 1026 | ||
1030 | newkey = kmemdup(cmd.tcpm_key, cmd.tcpm_keylen, sk->sk_allocation); | 1027 | newkey = kmemdup(cmd.tcpm_key, cmd.tcpm_keylen, sk->sk_allocation); |
@@ -1289,8 +1286,8 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1289 | goto drop_and_release; | 1286 | goto drop_and_release; |
1290 | 1287 | ||
1291 | /* Secret recipe starts with IP addresses */ | 1288 | /* Secret recipe starts with IP addresses */ |
1292 | *mess++ ^= daddr; | 1289 | *mess++ ^= (__force u32)daddr; |
1293 | *mess++ ^= saddr; | 1290 | *mess++ ^= (__force u32)saddr; |
1294 | 1291 | ||
1295 | /* plus variable length Initiator Cookie */ | 1292 | /* plus variable length Initiator Cookie */ |
1296 | c = (u8 *)mess; | 1293 | c = (u8 *)mess; |
@@ -1465,7 +1462,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1465 | if (newkey != NULL) | 1462 | if (newkey != NULL) |
1466 | tcp_v4_md5_do_add(newsk, newinet->inet_daddr, | 1463 | tcp_v4_md5_do_add(newsk, newinet->inet_daddr, |
1467 | newkey, key->keylen); | 1464 | newkey, key->keylen); |
1468 | newsk->sk_route_caps &= ~NETIF_F_GSO_MASK; | 1465 | sk_nocaps_add(newsk, NETIF_F_GSO_MASK); |
1469 | } | 1466 | } |
1470 | #endif | 1467 | #endif |
1471 | 1468 | ||
@@ -1675,6 +1672,8 @@ process: | |||
1675 | 1672 | ||
1676 | skb->dev = NULL; | 1673 | skb->dev = NULL; |
1677 | 1674 | ||
1675 | sock_rps_save_rxhash(sk, skb->rxhash); | ||
1676 | |||
1678 | bh_lock_sock_nested(sk); | 1677 | bh_lock_sock_nested(sk); |
1679 | ret = 0; | 1678 | ret = 0; |
1680 | if (!sock_owned_by_user(sk)) { | 1679 | if (!sock_owned_by_user(sk)) { |
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 5fabff9ac6d..794c2e122a4 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
@@ -672,6 +672,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, | |||
672 | if (req->retrans < inet_csk(sk)->icsk_accept_queue.rskq_defer_accept && | 672 | if (req->retrans < inet_csk(sk)->icsk_accept_queue.rskq_defer_accept && |
673 | TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) { | 673 | TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) { |
674 | inet_rsk(req)->acked = 1; | 674 | inet_rsk(req)->acked = 1; |
675 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPDEFERACCEPTDROP); | ||
675 | return NULL; | 676 | return NULL; |
676 | } | 677 | } |
677 | 678 | ||
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 0dda86e72ad..b4ed957f201 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -350,6 +350,7 @@ static inline void TCP_ECN_send(struct sock *sk, struct sk_buff *skb, | |||
350 | */ | 350 | */ |
351 | static void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags) | 351 | static void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags) |
352 | { | 352 | { |
353 | skb->ip_summed = CHECKSUM_PARTIAL; | ||
353 | skb->csum = 0; | 354 | skb->csum = 0; |
354 | 355 | ||
355 | TCP_SKB_CB(skb)->flags = flags; | 356 | TCP_SKB_CB(skb)->flags = flags; |
@@ -667,7 +668,6 @@ static unsigned tcp_synack_options(struct sock *sk, | |||
667 | u8 cookie_plus = (xvp != NULL && !xvp->cookie_out_never) ? | 668 | u8 cookie_plus = (xvp != NULL && !xvp->cookie_out_never) ? |
668 | xvp->cookie_plus : | 669 | xvp->cookie_plus : |
669 | 0; | 670 | 0; |
670 | bool doing_ts = ireq->tstamp_ok; | ||
671 | 671 | ||
672 | #ifdef CONFIG_TCP_MD5SIG | 672 | #ifdef CONFIG_TCP_MD5SIG |
673 | *md5 = tcp_rsk(req)->af_specific->md5_lookup(sk, req); | 673 | *md5 = tcp_rsk(req)->af_specific->md5_lookup(sk, req); |
@@ -680,7 +680,7 @@ static unsigned tcp_synack_options(struct sock *sk, | |||
680 | * rather than TS in order to fit in better with old, | 680 | * rather than TS in order to fit in better with old, |
681 | * buggy kernels, but that was deemed to be unnecessary. | 681 | * buggy kernels, but that was deemed to be unnecessary. |
682 | */ | 682 | */ |
683 | doing_ts &= !ireq->sack_ok; | 683 | ireq->tstamp_ok &= !ireq->sack_ok; |
684 | } | 684 | } |
685 | #else | 685 | #else |
686 | *md5 = NULL; | 686 | *md5 = NULL; |
@@ -695,7 +695,7 @@ static unsigned tcp_synack_options(struct sock *sk, | |||
695 | opts->options |= OPTION_WSCALE; | 695 | opts->options |= OPTION_WSCALE; |
696 | remaining -= TCPOLEN_WSCALE_ALIGNED; | 696 | remaining -= TCPOLEN_WSCALE_ALIGNED; |
697 | } | 697 | } |
698 | if (likely(doing_ts)) { | 698 | if (likely(ireq->tstamp_ok)) { |
699 | opts->options |= OPTION_TS; | 699 | opts->options |= OPTION_TS; |
700 | opts->tsval = TCP_SKB_CB(skb)->when; | 700 | opts->tsval = TCP_SKB_CB(skb)->when; |
701 | opts->tsecr = req->ts_recent; | 701 | opts->tsecr = req->ts_recent; |
@@ -703,7 +703,7 @@ static unsigned tcp_synack_options(struct sock *sk, | |||
703 | } | 703 | } |
704 | if (likely(ireq->sack_ok)) { | 704 | if (likely(ireq->sack_ok)) { |
705 | opts->options |= OPTION_SACK_ADVERTISE; | 705 | opts->options |= OPTION_SACK_ADVERTISE; |
706 | if (unlikely(!doing_ts)) | 706 | if (unlikely(!ireq->tstamp_ok)) |
707 | remaining -= TCPOLEN_SACKPERM_ALIGNED; | 707 | remaining -= TCPOLEN_SACKPERM_ALIGNED; |
708 | } | 708 | } |
709 | 709 | ||
@@ -711,7 +711,7 @@ static unsigned tcp_synack_options(struct sock *sk, | |||
711 | * If the <SYN> options fit, the same options should fit now! | 711 | * If the <SYN> options fit, the same options should fit now! |
712 | */ | 712 | */ |
713 | if (*md5 == NULL && | 713 | if (*md5 == NULL && |
714 | doing_ts && | 714 | ireq->tstamp_ok && |
715 | cookie_plus > TCPOLEN_COOKIE_BASE) { | 715 | cookie_plus > TCPOLEN_COOKIE_BASE) { |
716 | int need = cookie_plus; /* has TCPOLEN_COOKIE_BASE */ | 716 | int need = cookie_plus; /* has TCPOLEN_COOKIE_BASE */ |
717 | 717 | ||
@@ -860,7 +860,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
860 | th->urg_ptr = htons(tp->snd_up - tcb->seq); | 860 | th->urg_ptr = htons(tp->snd_up - tcb->seq); |
861 | th->urg = 1; | 861 | th->urg = 1; |
862 | } else if (after(tcb->seq + 0xFFFF, tp->snd_nxt)) { | 862 | } else if (after(tcb->seq + 0xFFFF, tp->snd_nxt)) { |
863 | th->urg_ptr = 0xFFFF; | 863 | th->urg_ptr = htons(0xFFFF); |
864 | th->urg = 1; | 864 | th->urg = 1; |
865 | } | 865 | } |
866 | } | 866 | } |
@@ -872,13 +872,13 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
872 | #ifdef CONFIG_TCP_MD5SIG | 872 | #ifdef CONFIG_TCP_MD5SIG |
873 | /* Calculate the MD5 hash, as we have all we need now */ | 873 | /* Calculate the MD5 hash, as we have all we need now */ |
874 | if (md5) { | 874 | if (md5) { |
875 | sk->sk_route_caps &= ~NETIF_F_GSO_MASK; | 875 | sk_nocaps_add(sk, NETIF_F_GSO_MASK); |
876 | tp->af_specific->calc_md5_hash(opts.hash_location, | 876 | tp->af_specific->calc_md5_hash(opts.hash_location, |
877 | md5, sk, NULL, skb); | 877 | md5, sk, NULL, skb); |
878 | } | 878 | } |
879 | #endif | 879 | #endif |
880 | 880 | ||
881 | icsk->icsk_af_ops->send_check(sk, skb->len, skb); | 881 | icsk->icsk_af_ops->send_check(sk, skb); |
882 | 882 | ||
883 | if (likely(tcb->flags & TCPCB_FLAG_ACK)) | 883 | if (likely(tcb->flags & TCPCB_FLAG_ACK)) |
884 | tcp_event_ack_sent(sk, tcp_skb_pcount(skb)); | 884 | tcp_event_ack_sent(sk, tcp_skb_pcount(skb)); |
@@ -887,9 +887,10 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
887 | tcp_event_data_sent(tp, skb, sk); | 887 | tcp_event_data_sent(tp, skb, sk); |
888 | 888 | ||
889 | if (after(tcb->end_seq, tp->snd_nxt) || tcb->seq == tcb->end_seq) | 889 | if (after(tcb->end_seq, tp->snd_nxt) || tcb->seq == tcb->end_seq) |
890 | TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); | 890 | TCP_ADD_STATS(sock_net(sk), TCP_MIB_OUTSEGS, |
891 | tcp_skb_pcount(skb)); | ||
891 | 892 | ||
892 | err = icsk->icsk_af_ops->queue_xmit(skb, 0); | 893 | err = icsk->icsk_af_ops->queue_xmit(skb); |
893 | if (likely(err <= 0)) | 894 | if (likely(err <= 0)) |
894 | return err; | 895 | return err; |
895 | 896 | ||
@@ -2484,7 +2485,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
2484 | *tail-- ^= TCP_SKB_CB(skb)->seq + 1; | 2485 | *tail-- ^= TCP_SKB_CB(skb)->seq + 1; |
2485 | 2486 | ||
2486 | /* recommended */ | 2487 | /* recommended */ |
2487 | *tail-- ^= ((th->dest << 16) | th->source); | 2488 | *tail-- ^= (((__force u32)th->dest << 16) | (__force u32)th->source); |
2488 | *tail-- ^= (u32)(unsigned long)cvp; /* per sockopt */ | 2489 | *tail-- ^= (u32)(unsigned long)cvp; /* per sockopt */ |
2489 | 2490 | ||
2490 | sha_transform((__u32 *)&xvp->cookie_bakery[0], | 2491 | sha_transform((__u32 *)&xvp->cookie_bakery[0], |
@@ -2502,7 +2503,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
2502 | th->window = htons(min(req->rcv_wnd, 65535U)); | 2503 | th->window = htons(min(req->rcv_wnd, 65535U)); |
2503 | tcp_options_write((__be32 *)(th + 1), tp, &opts); | 2504 | tcp_options_write((__be32 *)(th + 1), tp, &opts); |
2504 | th->doff = (tcp_header_size >> 2); | 2505 | th->doff = (tcp_header_size >> 2); |
2505 | TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); | 2506 | TCP_ADD_STATS(sock_net(sk), TCP_MIB_OUTSEGS, tcp_skb_pcount(skb)); |
2506 | 2507 | ||
2507 | #ifdef CONFIG_TCP_MD5SIG | 2508 | #ifdef CONFIG_TCP_MD5SIG |
2508 | /* Okay, we have all we need - do the md5 hash if needed */ | 2509 | /* Okay, we have all we need - do the md5 hash if needed */ |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 8a0ab2977f1..440a5c6004f 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -172,14 +172,14 @@ static int tcp_write_timeout(struct sock *sk) | |||
172 | 172 | ||
173 | if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) { | 173 | if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) { |
174 | if (icsk->icsk_retransmits) | 174 | if (icsk->icsk_retransmits) |
175 | dst_negative_advice(&sk->sk_dst_cache, sk); | 175 | dst_negative_advice(sk); |
176 | retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries; | 176 | retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries; |
177 | } else { | 177 | } else { |
178 | if (retransmits_timed_out(sk, sysctl_tcp_retries1)) { | 178 | if (retransmits_timed_out(sk, sysctl_tcp_retries1)) { |
179 | /* Black hole detection */ | 179 | /* Black hole detection */ |
180 | tcp_mtu_probing(icsk, sk); | 180 | tcp_mtu_probing(icsk, sk); |
181 | 181 | ||
182 | dst_negative_advice(&sk->sk_dst_cache, sk); | 182 | dst_negative_advice(sk); |
183 | } | 183 | } |
184 | 184 | ||
185 | retry_until = sysctl_tcp_retries2; | 185 | retry_until = sysctl_tcp_retries2; |
@@ -517,7 +517,7 @@ static void tcp_keepalive_timer (unsigned long data) | |||
517 | struct sock *sk = (struct sock *) data; | 517 | struct sock *sk = (struct sock *) data; |
518 | struct inet_connection_sock *icsk = inet_csk(sk); | 518 | struct inet_connection_sock *icsk = inet_csk(sk); |
519 | struct tcp_sock *tp = tcp_sk(sk); | 519 | struct tcp_sock *tp = tcp_sk(sk); |
520 | __u32 elapsed; | 520 | u32 elapsed; |
521 | 521 | ||
522 | /* Only process if socket is not in use. */ | 522 | /* Only process if socket is not in use. */ |
523 | bh_lock_sock(sk); | 523 | bh_lock_sock(sk); |
@@ -554,7 +554,7 @@ static void tcp_keepalive_timer (unsigned long data) | |||
554 | if (tp->packets_out || tcp_send_head(sk)) | 554 | if (tp->packets_out || tcp_send_head(sk)) |
555 | goto resched; | 555 | goto resched; |
556 | 556 | ||
557 | elapsed = tcp_time_stamp - tp->rcv_tstamp; | 557 | elapsed = keepalive_time_elapsed(tp); |
558 | 558 | ||
559 | if (elapsed >= keepalive_time_when(tp)) { | 559 | if (elapsed >= keepalive_time_when(tp)) { |
560 | if (icsk->icsk_probes_out >= keepalive_probes(tp)) { | 560 | if (icsk->icsk_probes_out >= keepalive_probes(tp)) { |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index c36522a0f11..9de6a698f91 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -233,7 +233,8 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum, | |||
233 | */ | 233 | */ |
234 | do { | 234 | do { |
235 | if (low <= snum && snum <= high && | 235 | if (low <= snum && snum <= high && |
236 | !test_bit(snum >> udptable->log, bitmap)) | 236 | !test_bit(snum >> udptable->log, bitmap) && |
237 | !inet_is_reserved_local_port(snum)) | ||
237 | goto found; | 238 | goto found; |
238 | snum += rand; | 239 | snum += rand; |
239 | } while (snum != first); | 240 | } while (snum != first); |
@@ -307,13 +308,13 @@ static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2) | |||
307 | static unsigned int udp4_portaddr_hash(struct net *net, __be32 saddr, | 308 | static unsigned int udp4_portaddr_hash(struct net *net, __be32 saddr, |
308 | unsigned int port) | 309 | unsigned int port) |
309 | { | 310 | { |
310 | return jhash_1word(saddr, net_hash_mix(net)) ^ port; | 311 | return jhash_1word((__force u32)saddr, net_hash_mix(net)) ^ port; |
311 | } | 312 | } |
312 | 313 | ||
313 | int udp_v4_get_port(struct sock *sk, unsigned short snum) | 314 | int udp_v4_get_port(struct sock *sk, unsigned short snum) |
314 | { | 315 | { |
315 | unsigned int hash2_nulladdr = | 316 | unsigned int hash2_nulladdr = |
316 | udp4_portaddr_hash(sock_net(sk), INADDR_ANY, snum); | 317 | udp4_portaddr_hash(sock_net(sk), htonl(INADDR_ANY), snum); |
317 | unsigned int hash2_partial = | 318 | unsigned int hash2_partial = |
318 | udp4_portaddr_hash(sock_net(sk), inet_sk(sk)->inet_rcv_saddr, 0); | 319 | udp4_portaddr_hash(sock_net(sk), inet_sk(sk)->inet_rcv_saddr, 0); |
319 | 320 | ||
@@ -466,14 +467,14 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr, | |||
466 | daddr, hnum, dif, | 467 | daddr, hnum, dif, |
467 | hslot2, slot2); | 468 | hslot2, slot2); |
468 | if (!result) { | 469 | if (!result) { |
469 | hash2 = udp4_portaddr_hash(net, INADDR_ANY, hnum); | 470 | hash2 = udp4_portaddr_hash(net, htonl(INADDR_ANY), hnum); |
470 | slot2 = hash2 & udptable->mask; | 471 | slot2 = hash2 & udptable->mask; |
471 | hslot2 = &udptable->hash2[slot2]; | 472 | hslot2 = &udptable->hash2[slot2]; |
472 | if (hslot->count < hslot2->count) | 473 | if (hslot->count < hslot2->count) |
473 | goto begin; | 474 | goto begin; |
474 | 475 | ||
475 | result = udp4_lib_lookup2(net, saddr, sport, | 476 | result = udp4_lib_lookup2(net, saddr, sport, |
476 | INADDR_ANY, hnum, dif, | 477 | htonl(INADDR_ANY), hnum, dif, |
477 | hslot2, slot2); | 478 | hslot2, slot2); |
478 | } | 479 | } |
479 | rcu_read_unlock(); | 480 | rcu_read_unlock(); |
@@ -1062,10 +1063,10 @@ static unsigned int first_packet_length(struct sock *sk) | |||
1062 | spin_unlock_bh(&rcvq->lock); | 1063 | spin_unlock_bh(&rcvq->lock); |
1063 | 1064 | ||
1064 | if (!skb_queue_empty(&list_kill)) { | 1065 | if (!skb_queue_empty(&list_kill)) { |
1065 | lock_sock(sk); | 1066 | lock_sock_bh(sk); |
1066 | __skb_queue_purge(&list_kill); | 1067 | __skb_queue_purge(&list_kill); |
1067 | sk_mem_reclaim_partial(sk); | 1068 | sk_mem_reclaim_partial(sk); |
1068 | release_sock(sk); | 1069 | unlock_sock_bh(sk); |
1069 | } | 1070 | } |
1070 | return res; | 1071 | return res; |
1071 | } | 1072 | } |
@@ -1196,10 +1197,10 @@ out: | |||
1196 | return err; | 1197 | return err; |
1197 | 1198 | ||
1198 | csum_copy_err: | 1199 | csum_copy_err: |
1199 | lock_sock(sk); | 1200 | lock_sock_bh(sk); |
1200 | if (!skb_kill_datagram(sk, skb, flags)) | 1201 | if (!skb_kill_datagram(sk, skb, flags)) |
1201 | UDP_INC_STATS_USER(sock_net(sk), UDP_MIB_INERRORS, is_udplite); | 1202 | UDP_INC_STATS_USER(sock_net(sk), UDP_MIB_INERRORS, is_udplite); |
1202 | release_sock(sk); | 1203 | unlock_sock_bh(sk); |
1203 | 1204 | ||
1204 | if (noblock) | 1205 | if (noblock) |
1205 | return -EAGAIN; | 1206 | return -EAGAIN; |
@@ -1217,6 +1218,7 @@ int udp_disconnect(struct sock *sk, int flags) | |||
1217 | sk->sk_state = TCP_CLOSE; | 1218 | sk->sk_state = TCP_CLOSE; |
1218 | inet->inet_daddr = 0; | 1219 | inet->inet_daddr = 0; |
1219 | inet->inet_dport = 0; | 1220 | inet->inet_dport = 0; |
1221 | sock_rps_save_rxhash(sk, 0); | ||
1220 | sk->sk_bound_dev_if = 0; | 1222 | sk->sk_bound_dev_if = 0; |
1221 | if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) | 1223 | if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) |
1222 | inet_reset_saddr(sk); | 1224 | inet_reset_saddr(sk); |
@@ -1258,8 +1260,12 @@ EXPORT_SYMBOL(udp_lib_unhash); | |||
1258 | 1260 | ||
1259 | static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | 1261 | static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) |
1260 | { | 1262 | { |
1261 | int rc = sock_queue_rcv_skb(sk, skb); | 1263 | int rc; |
1264 | |||
1265 | if (inet_sk(sk)->inet_daddr) | ||
1266 | sock_rps_save_rxhash(sk, skb->rxhash); | ||
1262 | 1267 | ||
1268 | rc = ip_queue_rcv_skb(sk, skb); | ||
1263 | if (rc < 0) { | 1269 | if (rc < 0) { |
1264 | int is_udplite = IS_UDPLITE(sk); | 1270 | int is_udplite = IS_UDPLITE(sk); |
1265 | 1271 | ||
@@ -1367,6 +1373,10 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
1367 | goto drop; | 1373 | goto drop; |
1368 | } | 1374 | } |
1369 | 1375 | ||
1376 | |||
1377 | if (sk_rcvqueues_full(sk, skb)) | ||
1378 | goto drop; | ||
1379 | |||
1370 | rc = 0; | 1380 | rc = 0; |
1371 | 1381 | ||
1372 | bh_lock_sock(sk); | 1382 | bh_lock_sock(sk); |
@@ -1615,9 +1625,9 @@ int udp_rcv(struct sk_buff *skb) | |||
1615 | 1625 | ||
1616 | void udp_destroy_sock(struct sock *sk) | 1626 | void udp_destroy_sock(struct sock *sk) |
1617 | { | 1627 | { |
1618 | lock_sock(sk); | 1628 | lock_sock_bh(sk); |
1619 | udp_flush_pending_frames(sk); | 1629 | udp_flush_pending_frames(sk); |
1620 | release_sock(sk); | 1630 | unlock_sock_bh(sk); |
1621 | } | 1631 | } |
1622 | 1632 | ||
1623 | /* | 1633 | /* |
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c index c791bb63203..ad8fbb871aa 100644 --- a/net/ipv4/xfrm4_input.c +++ b/net/ipv4/xfrm4_input.c | |||
@@ -27,8 +27,8 @@ static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb) | |||
27 | if (skb_dst(skb) == NULL) { | 27 | if (skb_dst(skb) == NULL) { |
28 | const struct iphdr *iph = ip_hdr(skb); | 28 | const struct iphdr *iph = ip_hdr(skb); |
29 | 29 | ||
30 | if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, | 30 | if (ip_route_input_noref(skb, iph->daddr, iph->saddr, |
31 | skb->dev)) | 31 | iph->tos, skb->dev)) |
32 | goto drop; | 32 | goto drop; |
33 | } | 33 | } |
34 | return dst_input(skb); | 34 | return dst_input(skb); |
@@ -61,7 +61,7 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async) | |||
61 | iph->tot_len = htons(skb->len); | 61 | iph->tot_len = htons(skb->len); |
62 | ip_send_check(iph); | 62 | ip_send_check(iph); |
63 | 63 | ||
64 | NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, skb->dev, NULL, | 64 | NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, skb->dev, NULL, |
65 | xfrm4_rcv_encap_finish); | 65 | xfrm4_rcv_encap_finish); |
66 | return 0; | 66 | return 0; |
67 | } | 67 | } |
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c index c908bd99bcb..571aa96a175 100644 --- a/net/ipv4/xfrm4_output.c +++ b/net/ipv4/xfrm4_output.c | |||
@@ -86,7 +86,7 @@ static int xfrm4_output_finish(struct sk_buff *skb) | |||
86 | 86 | ||
87 | int xfrm4_output(struct sk_buff *skb) | 87 | int xfrm4_output(struct sk_buff *skb) |
88 | { | 88 | { |
89 | return NF_HOOK_COND(PF_INET, NF_INET_POST_ROUTING, skb, | 89 | return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb, |
90 | NULL, skb_dst(skb)->dev, xfrm4_output_finish, | 90 | NULL, skb_dst(skb)->dev, xfrm4_output_finish, |
91 | !(IPCB(skb)->flags & IPSKB_REROUTED)); | 91 | !(IPCB(skb)->flags & IPSKB_REROUTED)); |
92 | } | 92 | } |
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index e4a1483fba7..1705476670e 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
@@ -59,27 +59,6 @@ static int xfrm4_get_saddr(struct net *net, | |||
59 | return 0; | 59 | return 0; |
60 | } | 60 | } |
61 | 61 | ||
62 | static struct dst_entry * | ||
63 | __xfrm4_find_bundle(struct flowi *fl, struct xfrm_policy *policy) | ||
64 | { | ||
65 | struct dst_entry *dst; | ||
66 | |||
67 | read_lock_bh(&policy->lock); | ||
68 | for (dst = policy->bundles; dst; dst = dst->next) { | ||
69 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; | ||
70 | if (xdst->u.rt.fl.oif == fl->oif && /*XXX*/ | ||
71 | xdst->u.rt.fl.fl4_dst == fl->fl4_dst && | ||
72 | xdst->u.rt.fl.fl4_src == fl->fl4_src && | ||
73 | xdst->u.rt.fl.fl4_tos == fl->fl4_tos && | ||
74 | xfrm_bundle_ok(policy, xdst, fl, AF_INET, 0)) { | ||
75 | dst_clone(dst); | ||
76 | break; | ||
77 | } | ||
78 | } | ||
79 | read_unlock_bh(&policy->lock); | ||
80 | return dst; | ||
81 | } | ||
82 | |||
83 | static int xfrm4_get_tos(struct flowi *fl) | 62 | static int xfrm4_get_tos(struct flowi *fl) |
84 | { | 63 | { |
85 | return fl->fl4_tos; | 64 | return fl->fl4_tos; |
@@ -259,7 +238,6 @@ static struct xfrm_policy_afinfo xfrm4_policy_afinfo = { | |||
259 | .dst_ops = &xfrm4_dst_ops, | 238 | .dst_ops = &xfrm4_dst_ops, |
260 | .dst_lookup = xfrm4_dst_lookup, | 239 | .dst_lookup = xfrm4_dst_lookup, |
261 | .get_saddr = xfrm4_get_saddr, | 240 | .get_saddr = xfrm4_get_saddr, |
262 | .find_bundle = __xfrm4_find_bundle, | ||
263 | .decode_session = _decode_session4, | 241 | .decode_session = _decode_session4, |
264 | .get_tos = xfrm4_get_tos, | 242 | .get_tos = xfrm4_get_tos, |
265 | .init_path = xfrm4_init_path, | 243 | .init_path = xfrm4_init_path, |