diff options
Diffstat (limited to 'net/ipv4')
58 files changed, 1282 insertions, 1006 deletions
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 0c94a1ac2946..8e3a1fd938ab 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 f71357422380..551ce564b035 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 80769f1f9fab..f094b75810db 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 c97cd9ff697e..3a92a76ae41d 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 90e3d6379a42..382bc768ed56 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 ca2d07b1c706..76daeb5ff564 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 c98f115fb0fd..79d057a939ba 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 ac4dec132735..d65e9215bcd7 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 15d3eeda92f5..5fff865a4fa7 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 8da6429269dd..70eb3507c406 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 2b79377b468d..d3e160a88219 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 af10942b326c..56cdf68a074c 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 fe381d12ecdd..32618e11076d 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 f8ab7a380d4a..d930dc5e4d85 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 4c09a31fd140..ba9836c488ed 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 d1bcc9f21d4f..9a4a6c96cb0d 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 1e64dabbd232..ce231780a2b1 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 067ce9e043dc..b9d84e800cf4 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 0b27b14dcc9d..7fd636711037 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 ec19a890c9a0..45889103b3e2 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * overflow. | 22 | * overflow. |
| 23 | * Carlos Picoto : PIMv1 Support | 23 | * Carlos Picoto : PIMv1 Support |
| 24 | * Pavlin Ivanov Radoslavov: PIMv2 Registers must checksum only PIM header | 24 | * Pavlin Ivanov Radoslavov: PIMv2 Registers must checksum only PIM header |
| 25 | * Relax this requrement to work with older peers. | 25 | * Relax this requirement to work with older peers. |
| 26 | * | 26 | * |
| 27 | */ | 27 | */ |
| 28 | 28 | ||
| @@ -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 82fb43c5c59e..07de855e2175 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 f07d77f65751..1ac01b128621 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 b0d5b1d0a769..e1be7dd1171b 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 e2787048aa0a..a4e5fc5df4bf 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 b29c66df8d1f..63958f3394a5 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 ab828400ed71..f91c94b9a790 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 ea5cea2415c1..4bf3dc49ad1e 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 ee128efa1c8d..5234f4f3499a 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 650b54042b01..d2ed9dc74ebc 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 7c29582d4ec8..f43867d1697f 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 698e5e78685b..18a0656505a0 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 a0e8bcf04159..f5f4a888e4ec 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 0dbe697f164f..446e0f467a17 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 3b216be3bc9f..db8bff0fb86d 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 0104c0b399de..14a2aa8b8a14 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 2a1e56b71908..af6e9c778345 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 55392466daa4..c37641e819f2 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 2bb1f87051c4..5a03c02af999 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 2fb7b76da94f..244f7cb08d68 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 7e8e6fc75413..5045196d853c 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 26de2c1f7fab..98ed78281aee 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 4d85b6e55f29..1679e2c0963d 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 c39c9cf6bee6..beb25819c9c9 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 b096e81500ae..7274a43c7a12 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 4f1f337f4337..3dc9914c1dce 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 cc6f097fbd5f..2c7a1639388a 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 cb562fdd9b9a..560acc677ce4 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 1cd5c15174b8..d96c1da4b17c 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 296150b2a62f..6596b4feeddc 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 f240f57b2199..3e6dafcb1071 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 3c23e70885f4..202cf09c4cd4 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 5fabff9ac6d6..794c2e122a41 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 0dda86e72ad8..b4ed957f201a 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 8a0ab2977f1f..440a5c6004f6 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 c36522a0f113..baeec29fe0f1 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 | /* |
| @@ -1676,8 +1686,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, | |||
| 1676 | return -ENOPROTOOPT; | 1686 | return -ENOPROTOOPT; |
| 1677 | if (val != 0 && val < 8) /* Illegal coverage: use default (8) */ | 1687 | if (val != 0 && val < 8) /* Illegal coverage: use default (8) */ |
| 1678 | val = 8; | 1688 | val = 8; |
| 1679 | else if (val > USHORT_MAX) | 1689 | else if (val > USHRT_MAX) |
| 1680 | val = USHORT_MAX; | 1690 | val = USHRT_MAX; |
| 1681 | up->pcslen = val; | 1691 | up->pcslen = val; |
| 1682 | up->pcflag |= UDPLITE_SEND_CC; | 1692 | up->pcflag |= UDPLITE_SEND_CC; |
| 1683 | break; | 1693 | break; |
| @@ -1690,8 +1700,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, | |||
| 1690 | return -ENOPROTOOPT; | 1700 | return -ENOPROTOOPT; |
| 1691 | if (val != 0 && val < 8) /* Avoid silly minimal values. */ | 1701 | if (val != 0 && val < 8) /* Avoid silly minimal values. */ |
| 1692 | val = 8; | 1702 | val = 8; |
| 1693 | else if (val > USHORT_MAX) | 1703 | else if (val > USHRT_MAX) |
| 1694 | val = USHORT_MAX; | 1704 | val = USHRT_MAX; |
| 1695 | up->pcrlen = val; | 1705 | up->pcrlen = val; |
| 1696 | up->pcflag |= UDPLITE_RECV_CC; | 1706 | up->pcflag |= UDPLITE_RECV_CC; |
| 1697 | break; | 1707 | break; |
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c index c791bb63203f..ad8fbb871aa0 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 c908bd99bcba..571aa96a175c 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 e4a1483fba77..1705476670ef 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, |
