diff options
Diffstat (limited to 'net/ipv6')
| -rw-r--r-- | net/ipv6/addrconf.c | 1 | ||||
| -rw-r--r-- | net/ipv6/icmp.c | 23 | ||||
| -rw-r--r-- | net/ipv6/ip6_output.c | 64 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6t_hbh.c | 8 | ||||
| -rw-r--r-- | net/ipv6/raw.c | 6 | ||||
| -rw-r--r-- | net/ipv6/route.c | 2 | ||||
| -rw-r--r-- | net/ipv6/sysctl_net_ipv6.c | 2 | ||||
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 3 |
8 files changed, 59 insertions, 50 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index e2d3b7580b76..7b6a584b62dd 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -1688,6 +1688,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev, | |||
| 1688 | .fc_dst_len = plen, | 1688 | .fc_dst_len = plen, |
| 1689 | .fc_flags = RTF_UP | flags, | 1689 | .fc_flags = RTF_UP | flags, |
| 1690 | .fc_nlinfo.nl_net = dev_net(dev), | 1690 | .fc_nlinfo.nl_net = dev_net(dev), |
| 1691 | .fc_protocol = RTPROT_KERNEL, | ||
| 1691 | }; | 1692 | }; |
| 1692 | 1693 | ||
| 1693 | ipv6_addr_copy(&cfg.fc_dst, pfx); | 1694 | ipv6_addr_copy(&cfg.fc_dst, pfx); |
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index abedf95fdf2d..b3157a0cc15d 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
| @@ -91,19 +91,22 @@ static struct inet6_protocol icmpv6_protocol = { | |||
| 91 | .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, | 91 | .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, |
| 92 | }; | 92 | }; |
| 93 | 93 | ||
| 94 | static __inline__ int icmpv6_xmit_lock(struct sock *sk) | 94 | static __inline__ struct sock *icmpv6_xmit_lock(struct net *net) |
| 95 | { | 95 | { |
| 96 | struct sock *sk; | ||
| 97 | |||
| 96 | local_bh_disable(); | 98 | local_bh_disable(); |
| 97 | 99 | ||
| 100 | sk = icmpv6_sk(net); | ||
| 98 | if (unlikely(!spin_trylock(&sk->sk_lock.slock))) { | 101 | if (unlikely(!spin_trylock(&sk->sk_lock.slock))) { |
| 99 | /* This can happen if the output path (f.e. SIT or | 102 | /* This can happen if the output path (f.e. SIT or |
| 100 | * ip6ip6 tunnel) signals dst_link_failure() for an | 103 | * ip6ip6 tunnel) signals dst_link_failure() for an |
| 101 | * outgoing ICMP6 packet. | 104 | * outgoing ICMP6 packet. |
| 102 | */ | 105 | */ |
| 103 | local_bh_enable(); | 106 | local_bh_enable(); |
| 104 | return 1; | 107 | return NULL; |
| 105 | } | 108 | } |
| 106 | return 0; | 109 | return sk; |
| 107 | } | 110 | } |
| 108 | 111 | ||
| 109 | static __inline__ void icmpv6_xmit_unlock(struct sock *sk) | 112 | static __inline__ void icmpv6_xmit_unlock(struct sock *sk) |
| @@ -392,11 +395,10 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, | |||
| 392 | fl.fl_icmp_code = code; | 395 | fl.fl_icmp_code = code; |
| 393 | security_skb_classify_flow(skb, &fl); | 396 | security_skb_classify_flow(skb, &fl); |
| 394 | 397 | ||
| 395 | sk = icmpv6_sk(net); | 398 | sk = icmpv6_xmit_lock(net); |
| 396 | np = inet6_sk(sk); | 399 | if (sk == NULL) |
| 397 | |||
| 398 | if (icmpv6_xmit_lock(sk)) | ||
| 399 | return; | 400 | return; |
| 401 | np = inet6_sk(sk); | ||
| 400 | 402 | ||
| 401 | if (!icmpv6_xrlim_allow(sk, type, &fl)) | 403 | if (!icmpv6_xrlim_allow(sk, type, &fl)) |
| 402 | goto out; | 404 | goto out; |
| @@ -539,11 +541,10 @@ static void icmpv6_echo_reply(struct sk_buff *skb) | |||
| 539 | fl.fl_icmp_type = ICMPV6_ECHO_REPLY; | 541 | fl.fl_icmp_type = ICMPV6_ECHO_REPLY; |
| 540 | security_skb_classify_flow(skb, &fl); | 542 | security_skb_classify_flow(skb, &fl); |
| 541 | 543 | ||
| 542 | sk = icmpv6_sk(net); | 544 | sk = icmpv6_xmit_lock(net); |
| 543 | np = inet6_sk(sk); | 545 | if (sk == NULL) |
| 544 | |||
| 545 | if (icmpv6_xmit_lock(sk)) | ||
| 546 | return; | 546 | return; |
| 547 | np = inet6_sk(sk); | ||
| 547 | 548 | ||
| 548 | if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) | 549 | if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) |
| 549 | fl.oif = np->mcast_oif; | 550 | fl.oif = np->mcast_oif; |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 0e844c2736a7..3df2c442d90b 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
| @@ -943,39 +943,39 @@ static int ip6_dst_lookup_tail(struct sock *sk, | |||
| 943 | } | 943 | } |
| 944 | 944 | ||
| 945 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD | 945 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD |
| 946 | /* | 946 | /* |
| 947 | * Here if the dst entry we've looked up | 947 | * Here if the dst entry we've looked up |
| 948 | * has a neighbour entry that is in the INCOMPLETE | 948 | * has a neighbour entry that is in the INCOMPLETE |
| 949 | * state and the src address from the flow is | 949 | * state and the src address from the flow is |
| 950 | * marked as OPTIMISTIC, we release the found | 950 | * marked as OPTIMISTIC, we release the found |
| 951 | * dst entry and replace it instead with the | 951 | * dst entry and replace it instead with the |
| 952 | * dst entry of the nexthop router | 952 | * dst entry of the nexthop router |
| 953 | */ | 953 | */ |
| 954 | if (!((*dst)->neighbour->nud_state & NUD_VALID)) { | 954 | if ((*dst)->neighbour && !((*dst)->neighbour->nud_state & NUD_VALID)) { |
| 955 | struct inet6_ifaddr *ifp; | 955 | struct inet6_ifaddr *ifp; |
| 956 | struct flowi fl_gw; | 956 | struct flowi fl_gw; |
| 957 | int redirect; | 957 | int redirect; |
| 958 | 958 | ||
| 959 | ifp = ipv6_get_ifaddr(net, &fl->fl6_src, | 959 | ifp = ipv6_get_ifaddr(net, &fl->fl6_src, |
| 960 | (*dst)->dev, 1); | 960 | (*dst)->dev, 1); |
| 961 | 961 | ||
| 962 | redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC); | 962 | redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC); |
| 963 | if (ifp) | 963 | if (ifp) |
| 964 | in6_ifa_put(ifp); | 964 | in6_ifa_put(ifp); |
| 965 | 965 | ||
| 966 | if (redirect) { | 966 | if (redirect) { |
| 967 | /* | 967 | /* |
| 968 | * We need to get the dst entry for the | 968 | * We need to get the dst entry for the |
| 969 | * default router instead | 969 | * default router instead |
| 970 | */ | 970 | */ |
| 971 | dst_release(*dst); | 971 | dst_release(*dst); |
| 972 | memcpy(&fl_gw, fl, sizeof(struct flowi)); | 972 | memcpy(&fl_gw, fl, sizeof(struct flowi)); |
| 973 | memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr)); | 973 | memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr)); |
| 974 | *dst = ip6_route_output(net, sk, &fl_gw); | 974 | *dst = ip6_route_output(net, sk, &fl_gw); |
| 975 | if ((err = (*dst)->error)) | 975 | if ((err = (*dst)->error)) |
| 976 | goto out_err_release; | 976 | goto out_err_release; |
| 977 | } | ||
| 978 | } | 977 | } |
| 978 | } | ||
| 979 | #endif | 979 | #endif |
| 980 | 980 | ||
| 981 | return 0; | 981 | return 0; |
diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c index 62e39ace0588..26654b26d7fa 100644 --- a/net/ipv6/netfilter/ip6t_hbh.c +++ b/net/ipv6/netfilter/ip6t_hbh.c | |||
| @@ -97,8 +97,6 @@ hbh_mt6(const struct sk_buff *skb, const struct net_device *in, | |||
| 97 | hdrlen -= 2; | 97 | hdrlen -= 2; |
| 98 | if (!(optinfo->flags & IP6T_OPTS_OPTS)) { | 98 | if (!(optinfo->flags & IP6T_OPTS_OPTS)) { |
| 99 | return ret; | 99 | return ret; |
| 100 | } else if (optinfo->flags & IP6T_OPTS_NSTRICT) { | ||
| 101 | pr_debug("Not strict - not implemented"); | ||
| 102 | } else { | 100 | } else { |
| 103 | pr_debug("Strict "); | 101 | pr_debug("Strict "); |
| 104 | pr_debug("#%d ", optinfo->optsnr); | 102 | pr_debug("#%d ", optinfo->optsnr); |
| @@ -177,6 +175,12 @@ hbh_mt6_check(const char *tablename, const void *entry, | |||
| 177 | pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags); | 175 | pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags); |
| 178 | return false; | 176 | return false; |
| 179 | } | 177 | } |
| 178 | |||
| 179 | if (optsinfo->flags & IP6T_OPTS_NSTRICT) { | ||
| 180 | pr_debug("ip6t_opts: Not strict - not implemented"); | ||
| 181 | return false; | ||
| 182 | } | ||
| 183 | |||
| 180 | return true; | 184 | return true; |
| 181 | } | 185 | } |
| 182 | 186 | ||
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 01d47674f7e5..e53e493606c5 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
| @@ -377,14 +377,14 @@ static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb) | |||
| 377 | skb_checksum_complete(skb)) { | 377 | skb_checksum_complete(skb)) { |
| 378 | atomic_inc(&sk->sk_drops); | 378 | atomic_inc(&sk->sk_drops); |
| 379 | kfree_skb(skb); | 379 | kfree_skb(skb); |
| 380 | return 0; | 380 | return NET_RX_DROP; |
| 381 | } | 381 | } |
| 382 | 382 | ||
| 383 | /* Charge it to the socket. */ | 383 | /* Charge it to the socket. */ |
| 384 | if (sock_queue_rcv_skb(sk,skb)<0) { | 384 | if (sock_queue_rcv_skb(sk,skb)<0) { |
| 385 | atomic_inc(&sk->sk_drops); | 385 | atomic_inc(&sk->sk_drops); |
| 386 | kfree_skb(skb); | 386 | kfree_skb(skb); |
| 387 | return 0; | 387 | return NET_RX_DROP; |
| 388 | } | 388 | } |
| 389 | 389 | ||
| 390 | return 0; | 390 | return 0; |
| @@ -429,7 +429,7 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb) | |||
| 429 | if (skb_checksum_complete(skb)) { | 429 | if (skb_checksum_complete(skb)) { |
| 430 | atomic_inc(&sk->sk_drops); | 430 | atomic_inc(&sk->sk_drops); |
| 431 | kfree_skb(skb); | 431 | kfree_skb(skb); |
| 432 | return 0; | 432 | return NET_RX_DROP; |
| 433 | } | 433 | } |
| 434 | } | 434 | } |
| 435 | 435 | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 9af6115f0f50..63442a1e741c 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -2688,6 +2688,8 @@ int __init ip6_route_init(void) | |||
| 2688 | if (ret) | 2688 | if (ret) |
| 2689 | goto out_kmem_cache; | 2689 | goto out_kmem_cache; |
| 2690 | 2690 | ||
| 2691 | ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep; | ||
| 2692 | |||
| 2691 | /* Registering of the loopback is done before this portion of code, | 2693 | /* Registering of the loopback is done before this portion of code, |
| 2692 | * the loopback reference in rt6_info will not be taken, do it | 2694 | * the loopback reference in rt6_info will not be taken, do it |
| 2693 | * manually for init_net */ | 2695 | * manually for init_net */ |
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index e6dfaeac6be3..587f8f60c489 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c | |||
| @@ -156,7 +156,7 @@ static struct ctl_table_header *ip6_base; | |||
| 156 | int ipv6_static_sysctl_register(void) | 156 | int ipv6_static_sysctl_register(void) |
| 157 | { | 157 | { |
| 158 | static struct ctl_table empty[1]; | 158 | static struct ctl_table empty[1]; |
| 159 | ip6_base = register_net_sysctl_rotable(net_ipv6_ctl_path, empty); | 159 | ip6_base = register_sysctl_paths(net_ipv6_ctl_path, empty); |
| 160 | if (ip6_base == NULL) | 160 | if (ip6_base == NULL) |
| 161 | return -ENOMEM; | 161 | return -ENOMEM; |
| 162 | return 0; | 162 | return 0; |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 5b90b369ccb2..10e22fd48222 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
| @@ -1050,7 +1050,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 | |||
| 1050 | struct tcphdr *th = tcp_hdr(skb), *t1; | 1050 | struct tcphdr *th = tcp_hdr(skb), *t1; |
| 1051 | struct sk_buff *buff; | 1051 | struct sk_buff *buff; |
| 1052 | struct flowi fl; | 1052 | struct flowi fl; |
| 1053 | struct net *net = dev_net(skb->dev); | 1053 | struct net *net = dev_net(skb->dst->dev); |
| 1054 | struct sock *ctl_sk = net->ipv6.tcp_sk; | 1054 | struct sock *ctl_sk = net->ipv6.tcp_sk; |
| 1055 | unsigned int tot_len = sizeof(struct tcphdr); | 1055 | unsigned int tot_len = sizeof(struct tcphdr); |
| 1056 | __be32 *topt; | 1056 | __be32 *topt; |
| @@ -2148,6 +2148,7 @@ static int tcpv6_net_init(struct net *net) | |||
| 2148 | static void tcpv6_net_exit(struct net *net) | 2148 | static void tcpv6_net_exit(struct net *net) |
| 2149 | { | 2149 | { |
| 2150 | inet_ctl_sock_destroy(net->ipv6.tcp_sk); | 2150 | inet_ctl_sock_destroy(net->ipv6.tcp_sk); |
| 2151 | inet_twsk_purge(net, &tcp_hashinfo, &tcp_death_row, AF_INET6); | ||
| 2151 | } | 2152 | } |
| 2152 | 2153 | ||
| 2153 | static struct pernet_operations tcpv6_net_ops = { | 2154 | static struct pernet_operations tcpv6_net_ops = { |
