aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrconf.c1
-rw-r--r--net/ipv6/icmp.c23
-rw-r--r--net/ipv6/ip6_output.c64
-rw-r--r--net/ipv6/netfilter/ip6t_hbh.c8
-rw-r--r--net/ipv6/raw.c6
-rw-r--r--net/ipv6/route.c2
-rw-r--r--net/ipv6/sysctl_net_ipv6.c2
-rw-r--r--net/ipv6/tcp_ipv6.c3
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
94static __inline__ int icmpv6_xmit_lock(struct sock *sk) 94static __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
109static __inline__ void icmpv6_xmit_unlock(struct sock *sk) 112static __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;
156int ipv6_static_sysctl_register(void) 156int 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)
2148static void tcpv6_net_exit(struct net *net) 2148static 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
2153static struct pernet_operations tcpv6_net_ops = { 2154static struct pernet_operations tcpv6_net_ops = {