aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/inet6_connection_sock.c3
-rw-r--r--net/ipv6/ip6_fib.c3
-rw-r--r--net/ipv6/ip6_gre.c10
-rw-r--r--net/ipv6/ip6_offload.c6
-rw-r--r--net/ipv6/ip6_output.c10
-rw-r--r--net/ipv6/ip6_tunnel.c10
-rw-r--r--net/ipv6/ip6_vti.c8
-rw-r--r--net/ipv6/ip6mr.c4
-rw-r--r--net/ipv6/ndisc.c7
-rw-r--r--net/ipv6/netfilter.c6
-rw-r--r--net/ipv6/netfilter/ip6t_rpfilter.c1
-rw-r--r--net/ipv6/route.c45
-rw-r--r--net/ipv6/sit.c22
-rw-r--r--net/ipv6/tcpv6_offload.c2
-rw-r--r--net/ipv6/xfrm6_output.c24
-rw-r--r--net/ipv6/xfrm6_protocol.c11
16 files changed, 107 insertions, 65 deletions
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index c9138189415a..d4ade34ab375 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -224,9 +224,8 @@ static struct dst_entry *inet6_csk_route_socket(struct sock *sk,
224 return dst; 224 return dst;
225} 225}
226 226
227int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) 227int inet6_csk_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl_unused)
228{ 228{
229 struct sock *sk = skb->sk;
230 struct ipv6_pinfo *np = inet6_sk(sk); 229 struct ipv6_pinfo *np = inet6_sk(sk);
231 struct flowi6 fl6; 230 struct flowi6 fl6;
232 struct dst_entry *dst; 231 struct dst_entry *dst;
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 34e0ded5c14b..87891f5f57b5 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -1459,7 +1459,7 @@ static int fib6_walk_continue(struct fib6_walker_t *w)
1459 1459
1460 if (w->skip) { 1460 if (w->skip) {
1461 w->skip--; 1461 w->skip--;
1462 continue; 1462 goto skip;
1463 } 1463 }
1464 1464
1465 err = w->func(w); 1465 err = w->func(w);
@@ -1469,6 +1469,7 @@ static int fib6_walk_continue(struct fib6_walker_t *w)
1469 w->count++; 1469 w->count++;
1470 continue; 1470 continue;
1471 } 1471 }
1472skip:
1472 w->state = FWS_U; 1473 w->state = FWS_U;
1473 case FWS_U: 1474 case FWS_U:
1474 if (fn == w->root) 1475 if (fn == w->root)
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index c98338b81d30..9d921462b57f 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -1559,6 +1559,15 @@ static int ip6gre_changelink(struct net_device *dev, struct nlattr *tb[],
1559 return 0; 1559 return 0;
1560} 1560}
1561 1561
1562static void ip6gre_dellink(struct net_device *dev, struct list_head *head)
1563{
1564 struct net *net = dev_net(dev);
1565 struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
1566
1567 if (dev != ign->fb_tunnel_dev)
1568 unregister_netdevice_queue(dev, head);
1569}
1570
1562static size_t ip6gre_get_size(const struct net_device *dev) 1571static size_t ip6gre_get_size(const struct net_device *dev)
1563{ 1572{
1564 return 1573 return
@@ -1636,6 +1645,7 @@ static struct rtnl_link_ops ip6gre_link_ops __read_mostly = {
1636 .validate = ip6gre_tunnel_validate, 1645 .validate = ip6gre_tunnel_validate,
1637 .newlink = ip6gre_newlink, 1646 .newlink = ip6gre_newlink,
1638 .changelink = ip6gre_changelink, 1647 .changelink = ip6gre_changelink,
1648 .dellink = ip6gre_dellink,
1639 .get_size = ip6gre_get_size, 1649 .get_size = ip6gre_get_size,
1640 .fill_info = ip6gre_fill_info, 1650 .fill_info = ip6gre_fill_info,
1641}; 1651};
diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c
index 59f95affceb0..b2f091566f88 100644
--- a/net/ipv6/ip6_offload.c
+++ b/net/ipv6/ip6_offload.c
@@ -196,7 +196,6 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
196 unsigned int off; 196 unsigned int off;
197 u16 flush = 1; 197 u16 flush = 1;
198 int proto; 198 int proto;
199 __wsum csum;
200 199
201 off = skb_gro_offset(skb); 200 off = skb_gro_offset(skb);
202 hlen = off + sizeof(*iph); 201 hlen = off + sizeof(*iph);
@@ -264,13 +263,10 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
264 263
265 NAPI_GRO_CB(skb)->flush |= flush; 264 NAPI_GRO_CB(skb)->flush |= flush;
266 265
267 csum = skb->csum; 266 skb_gro_postpull_rcsum(skb, iph, nlen);
268 skb_postpull_rcsum(skb, iph, skb_network_header_len(skb));
269 267
270 pp = ops->callbacks.gro_receive(head, skb); 268 pp = ops->callbacks.gro_receive(head, skb);
271 269
272 skb->csum = csum;
273
274out_unlock: 270out_unlock:
275 rcu_read_unlock(); 271 rcu_read_unlock();
276 272
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 3284d61577c0..fbf11562b54c 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -132,7 +132,7 @@ static int ip6_finish_output(struct sk_buff *skb)
132 return ip6_finish_output2(skb); 132 return ip6_finish_output2(skb);
133} 133}
134 134
135int ip6_output(struct sk_buff *skb) 135int ip6_output(struct sock *sk, struct sk_buff *skb)
136{ 136{
137 struct net_device *dev = skb_dst(skb)->dev; 137 struct net_device *dev = skb_dst(skb)->dev;
138 struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); 138 struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
@@ -344,12 +344,16 @@ static unsigned int ip6_dst_mtu_forward(const struct dst_entry *dst)
344 344
345static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu) 345static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu)
346{ 346{
347 if (skb->len <= mtu || skb->local_df) 347 if (skb->len <= mtu)
348 return false; 348 return false;
349 349
350 /* ipv6 conntrack defrag sets max_frag_size + local_df */
350 if (IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu) 351 if (IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu)
351 return true; 352 return true;
352 353
354 if (skb->local_df)
355 return false;
356
353 if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu) 357 if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu)
354 return false; 358 return false;
355 359
@@ -1225,7 +1229,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1225 unsigned int maxnonfragsize, headersize; 1229 unsigned int maxnonfragsize, headersize;
1226 1230
1227 headersize = sizeof(struct ipv6hdr) + 1231 headersize = sizeof(struct ipv6hdr) +
1228 (opt ? opt->tot_len : 0) + 1232 (opt ? opt->opt_flen + opt->opt_nflen : 0) +
1229 (dst_allfrag(&rt->dst) ? 1233 (dst_allfrag(&rt->dst) ?
1230 sizeof(struct frag_hdr) : 0) + 1234 sizeof(struct frag_hdr) : 0) +
1231 rt->rt6i_nfheader_len; 1235 rt->rt6i_nfheader_len;
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index e1df691d78be..f6a66bb4114d 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1340,8 +1340,8 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1340 int err = 0; 1340 int err = 0;
1341 struct ip6_tnl_parm p; 1341 struct ip6_tnl_parm p;
1342 struct __ip6_tnl_parm p1; 1342 struct __ip6_tnl_parm p1;
1343 struct ip6_tnl *t = NULL; 1343 struct ip6_tnl *t = netdev_priv(dev);
1344 struct net *net = dev_net(dev); 1344 struct net *net = t->net;
1345 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); 1345 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
1346 1346
1347 switch (cmd) { 1347 switch (cmd) {
@@ -1353,11 +1353,11 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1353 } 1353 }
1354 ip6_tnl_parm_from_user(&p1, &p); 1354 ip6_tnl_parm_from_user(&p1, &p);
1355 t = ip6_tnl_locate(net, &p1, 0); 1355 t = ip6_tnl_locate(net, &p1, 0);
1356 if (t == NULL)
1357 t = netdev_priv(dev);
1356 } else { 1358 } else {
1357 memset(&p, 0, sizeof(p)); 1359 memset(&p, 0, sizeof(p));
1358 } 1360 }
1359 if (t == NULL)
1360 t = netdev_priv(dev);
1361 ip6_tnl_parm_to_user(&p, &t->parms); 1361 ip6_tnl_parm_to_user(&p, &t->parms);
1362 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof (p))) { 1362 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof (p))) {
1363 err = -EFAULT; 1363 err = -EFAULT;
@@ -1557,7 +1557,7 @@ static int ip6_tnl_validate(struct nlattr *tb[], struct nlattr *data[])
1557{ 1557{
1558 u8 proto; 1558 u8 proto;
1559 1559
1560 if (!data) 1560 if (!data || !data[IFLA_IPTUN_PROTO])
1561 return 0; 1561 return 0;
1562 1562
1563 proto = nla_get_u8(data[IFLA_IPTUN_PROTO]); 1563 proto = nla_get_u8(data[IFLA_IPTUN_PROTO]);
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index b7c0f827140b..6cc9f9371cc5 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -511,6 +511,7 @@ static int vti6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
511 u8 type, u8 code, int offset, __be32 info) 511 u8 type, u8 code, int offset, __be32 info)
512{ 512{
513 __be32 spi; 513 __be32 spi;
514 __u32 mark;
514 struct xfrm_state *x; 515 struct xfrm_state *x;
515 struct ip6_tnl *t; 516 struct ip6_tnl *t;
516 struct ip_esp_hdr *esph; 517 struct ip_esp_hdr *esph;
@@ -524,6 +525,8 @@ static int vti6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
524 if (!t) 525 if (!t)
525 return -1; 526 return -1;
526 527
528 mark = be32_to_cpu(t->parms.o_key);
529
527 switch (protocol) { 530 switch (protocol) {
528 case IPPROTO_ESP: 531 case IPPROTO_ESP:
529 esph = (struct ip_esp_hdr *)(skb->data + offset); 532 esph = (struct ip_esp_hdr *)(skb->data + offset);
@@ -545,7 +548,7 @@ static int vti6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
545 type != NDISC_REDIRECT) 548 type != NDISC_REDIRECT)
546 return 0; 549 return 0;
547 550
548 x = xfrm_state_lookup(net, skb->mark, (const xfrm_address_t *)&iph->daddr, 551 x = xfrm_state_lookup(net, mark, (const xfrm_address_t *)&iph->daddr,
549 spi, protocol, AF_INET6); 552 spi, protocol, AF_INET6);
550 if (!x) 553 if (!x)
551 return 0; 554 return 0;
@@ -1097,7 +1100,6 @@ static int __init vti6_tunnel_init(void)
1097 1100
1098 err = xfrm6_protocol_register(&vti_esp6_protocol, IPPROTO_ESP); 1101 err = xfrm6_protocol_register(&vti_esp6_protocol, IPPROTO_ESP);
1099 if (err < 0) { 1102 if (err < 0) {
1100 unregister_pernet_device(&vti6_net_ops);
1101 pr_err("%s: can't register vti6 protocol\n", __func__); 1103 pr_err("%s: can't register vti6 protocol\n", __func__);
1102 1104
1103 goto out; 1105 goto out;
@@ -1106,7 +1108,6 @@ static int __init vti6_tunnel_init(void)
1106 err = xfrm6_protocol_register(&vti_ah6_protocol, IPPROTO_AH); 1108 err = xfrm6_protocol_register(&vti_ah6_protocol, IPPROTO_AH);
1107 if (err < 0) { 1109 if (err < 0) {
1108 xfrm6_protocol_deregister(&vti_esp6_protocol, IPPROTO_ESP); 1110 xfrm6_protocol_deregister(&vti_esp6_protocol, IPPROTO_ESP);
1109 unregister_pernet_device(&vti6_net_ops);
1110 pr_err("%s: can't register vti6 protocol\n", __func__); 1111 pr_err("%s: can't register vti6 protocol\n", __func__);
1111 1112
1112 goto out; 1113 goto out;
@@ -1116,7 +1117,6 @@ static int __init vti6_tunnel_init(void)
1116 if (err < 0) { 1117 if (err < 0) {
1117 xfrm6_protocol_deregister(&vti_ah6_protocol, IPPROTO_AH); 1118 xfrm6_protocol_deregister(&vti_ah6_protocol, IPPROTO_AH);
1118 xfrm6_protocol_deregister(&vti_esp6_protocol, IPPROTO_ESP); 1119 xfrm6_protocol_deregister(&vti_esp6_protocol, IPPROTO_ESP);
1119 unregister_pernet_device(&vti6_net_ops);
1120 pr_err("%s: can't register vti6 protocol\n", __func__); 1120 pr_err("%s: can't register vti6 protocol\n", __func__);
1121 1121
1122 goto out; 1122 goto out;
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 8737400af0a0..8250474ab7dc 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -700,7 +700,7 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb,
700 struct mr6_table *mrt; 700 struct mr6_table *mrt;
701 struct flowi6 fl6 = { 701 struct flowi6 fl6 = {
702 .flowi6_oif = dev->ifindex, 702 .flowi6_oif = dev->ifindex,
703 .flowi6_iif = skb->skb_iif, 703 .flowi6_iif = skb->skb_iif ? : LOOPBACK_IFINDEX,
704 .flowi6_mark = skb->mark, 704 .flowi6_mark = skb->mark,
705 }; 705 };
706 int err; 706 int err;
@@ -1633,7 +1633,7 @@ struct sock *mroute6_socket(struct net *net, struct sk_buff *skb)
1633{ 1633{
1634 struct mr6_table *mrt; 1634 struct mr6_table *mrt;
1635 struct flowi6 fl6 = { 1635 struct flowi6 fl6 = {
1636 .flowi6_iif = skb->skb_iif, 1636 .flowi6_iif = skb->skb_iif ? : LOOPBACK_IFINDEX,
1637 .flowi6_oif = skb->dev->ifindex, 1637 .flowi6_oif = skb->dev->ifindex,
1638 .flowi6_mark = skb->mark, 1638 .flowi6_mark = skb->mark,
1639 }; 1639 };
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 09a22f4f36c9..ca8d4ea48a5d 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -851,7 +851,7 @@ out:
851static void ndisc_recv_na(struct sk_buff *skb) 851static void ndisc_recv_na(struct sk_buff *skb)
852{ 852{
853 struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb); 853 struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb);
854 const struct in6_addr *saddr = &ipv6_hdr(skb)->saddr; 854 struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
855 const struct in6_addr *daddr = &ipv6_hdr(skb)->daddr; 855 const struct in6_addr *daddr = &ipv6_hdr(skb)->daddr;
856 u8 *lladdr = NULL; 856 u8 *lladdr = NULL;
857 u32 ndoptlen = skb_tail_pointer(skb) - (skb_transport_header(skb) + 857 u32 ndoptlen = skb_tail_pointer(skb) - (skb_transport_header(skb) +
@@ -944,10 +944,7 @@ static void ndisc_recv_na(struct sk_buff *skb)
944 /* 944 /*
945 * Change: router to host 945 * Change: router to host
946 */ 946 */
947 struct rt6_info *rt; 947 rt6_clean_tohost(dev_net(dev), saddr);
948 rt = rt6_get_dflt_router(saddr, dev);
949 if (rt)
950 ip6_del_rt(rt);
951 } 948 }
952 949
953out: 950out:
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index 95f3f1da0d7f..d38e6a8d8b9f 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -30,13 +30,15 @@ int ip6_route_me_harder(struct sk_buff *skb)
30 .daddr = iph->daddr, 30 .daddr = iph->daddr,
31 .saddr = iph->saddr, 31 .saddr = iph->saddr,
32 }; 32 };
33 int err;
33 34
34 dst = ip6_route_output(net, skb->sk, &fl6); 35 dst = ip6_route_output(net, skb->sk, &fl6);
35 if (dst->error) { 36 err = dst->error;
37 if (err) {
36 IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); 38 IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
37 LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n"); 39 LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n");
38 dst_release(dst); 40 dst_release(dst);
39 return dst->error; 41 return err;
40 } 42 }
41 43
42 /* Drop old route. */ 44 /* Drop old route. */
diff --git a/net/ipv6/netfilter/ip6t_rpfilter.c b/net/ipv6/netfilter/ip6t_rpfilter.c
index e0983f3648a6..790e0c6b19e1 100644
--- a/net/ipv6/netfilter/ip6t_rpfilter.c
+++ b/net/ipv6/netfilter/ip6t_rpfilter.c
@@ -33,6 +33,7 @@ static bool rpfilter_lookup_reverse6(const struct sk_buff *skb,
33 struct ipv6hdr *iph = ipv6_hdr(skb); 33 struct ipv6hdr *iph = ipv6_hdr(skb);
34 bool ret = false; 34 bool ret = false;
35 struct flowi6 fl6 = { 35 struct flowi6 fl6 = {
36 .flowi6_iif = LOOPBACK_IFINDEX,
36 .flowlabel = (* (__be32 *) iph) & IPV6_FLOWINFO_MASK, 37 .flowlabel = (* (__be32 *) iph) & IPV6_FLOWINFO_MASK,
37 .flowi6_proto = iph->nexthdr, 38 .flowi6_proto = iph->nexthdr,
38 .daddr = iph->saddr, 39 .daddr = iph->saddr,
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 5015c50a5ba7..6ebdb7b6744c 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -84,9 +84,9 @@ static void ip6_dst_ifdown(struct dst_entry *,
84static int ip6_dst_gc(struct dst_ops *ops); 84static int ip6_dst_gc(struct dst_ops *ops);
85 85
86static int ip6_pkt_discard(struct sk_buff *skb); 86static int ip6_pkt_discard(struct sk_buff *skb);
87static int ip6_pkt_discard_out(struct sk_buff *skb); 87static int ip6_pkt_discard_out(struct sock *sk, struct sk_buff *skb);
88static int ip6_pkt_prohibit(struct sk_buff *skb); 88static int ip6_pkt_prohibit(struct sk_buff *skb);
89static int ip6_pkt_prohibit_out(struct sk_buff *skb); 89static int ip6_pkt_prohibit_out(struct sock *sk, struct sk_buff *skb);
90static void ip6_link_failure(struct sk_buff *skb); 90static void ip6_link_failure(struct sk_buff *skb);
91static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, 91static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
92 struct sk_buff *skb, u32 mtu); 92 struct sk_buff *skb, u32 mtu);
@@ -290,7 +290,7 @@ static const struct rt6_info ip6_blk_hole_entry_template = {
290 .obsolete = DST_OBSOLETE_FORCE_CHK, 290 .obsolete = DST_OBSOLETE_FORCE_CHK,
291 .error = -EINVAL, 291 .error = -EINVAL,
292 .input = dst_discard, 292 .input = dst_discard,
293 .output = dst_discard, 293 .output = dst_discard_sk,
294 }, 294 },
295 .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), 295 .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
296 .rt6i_protocol = RTPROT_KERNEL, 296 .rt6i_protocol = RTPROT_KERNEL,
@@ -1058,7 +1058,7 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
1058 1058
1059 new->__use = 1; 1059 new->__use = 1;
1060 new->input = dst_discard; 1060 new->input = dst_discard;
1061 new->output = dst_discard; 1061 new->output = dst_discard_sk;
1062 1062
1063 if (dst_metrics_read_only(&ort->dst)) 1063 if (dst_metrics_read_only(&ort->dst))
1064 new->_metrics = ort->dst._metrics; 1064 new->_metrics = ort->dst._metrics;
@@ -1273,6 +1273,7 @@ void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark)
1273 struct flowi6 fl6; 1273 struct flowi6 fl6;
1274 1274
1275 memset(&fl6, 0, sizeof(fl6)); 1275 memset(&fl6, 0, sizeof(fl6));
1276 fl6.flowi6_iif = LOOPBACK_IFINDEX;
1276 fl6.flowi6_oif = oif; 1277 fl6.flowi6_oif = oif;
1277 fl6.flowi6_mark = mark; 1278 fl6.flowi6_mark = mark;
1278 fl6.daddr = iph->daddr; 1279 fl6.daddr = iph->daddr;
@@ -1294,6 +1295,7 @@ void ip6_redirect_no_header(struct sk_buff *skb, struct net *net, int oif,
1294 struct flowi6 fl6; 1295 struct flowi6 fl6;
1295 1296
1296 memset(&fl6, 0, sizeof(fl6)); 1297 memset(&fl6, 0, sizeof(fl6));
1298 fl6.flowi6_iif = LOOPBACK_IFINDEX;
1297 fl6.flowi6_oif = oif; 1299 fl6.flowi6_oif = oif;
1298 fl6.flowi6_mark = mark; 1300 fl6.flowi6_mark = mark;
1299 fl6.daddr = msg->dest; 1301 fl6.daddr = msg->dest;
@@ -1338,7 +1340,7 @@ static unsigned int ip6_mtu(const struct dst_entry *dst)
1338 unsigned int mtu = dst_metric_raw(dst, RTAX_MTU); 1340 unsigned int mtu = dst_metric_raw(dst, RTAX_MTU);
1339 1341
1340 if (mtu) 1342 if (mtu)
1341 return mtu; 1343 goto out;
1342 1344
1343 mtu = IPV6_MIN_MTU; 1345 mtu = IPV6_MIN_MTU;
1344 1346
@@ -1348,7 +1350,8 @@ static unsigned int ip6_mtu(const struct dst_entry *dst)
1348 mtu = idev->cnf.mtu6; 1350 mtu = idev->cnf.mtu6;
1349 rcu_read_unlock(); 1351 rcu_read_unlock();
1350 1352
1351 return mtu; 1353out:
1354 return min_t(unsigned int, mtu, IP6_MAX_MTU);
1352} 1355}
1353 1356
1354static struct dst_entry *icmp6_dst_gc_list; 1357static struct dst_entry *icmp6_dst_gc_list;
@@ -1576,7 +1579,7 @@ int ip6_route_add(struct fib6_config *cfg)
1576 switch (cfg->fc_type) { 1579 switch (cfg->fc_type) {
1577 case RTN_BLACKHOLE: 1580 case RTN_BLACKHOLE:
1578 rt->dst.error = -EINVAL; 1581 rt->dst.error = -EINVAL;
1579 rt->dst.output = dst_discard; 1582 rt->dst.output = dst_discard_sk;
1580 rt->dst.input = dst_discard; 1583 rt->dst.input = dst_discard;
1581 break; 1584 break;
1582 case RTN_PROHIBIT: 1585 case RTN_PROHIBIT:
@@ -2128,7 +2131,7 @@ static int ip6_pkt_discard(struct sk_buff *skb)
2128 return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_INNOROUTES); 2131 return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_INNOROUTES);
2129} 2132}
2130 2133
2131static int ip6_pkt_discard_out(struct sk_buff *skb) 2134static int ip6_pkt_discard_out(struct sock *sk, struct sk_buff *skb)
2132{ 2135{
2133 skb->dev = skb_dst(skb)->dev; 2136 skb->dev = skb_dst(skb)->dev;
2134 return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES); 2137 return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES);
@@ -2139,7 +2142,7 @@ static int ip6_pkt_prohibit(struct sk_buff *skb)
2139 return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES); 2142 return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES);
2140} 2143}
2141 2144
2142static int ip6_pkt_prohibit_out(struct sk_buff *skb) 2145static int ip6_pkt_prohibit_out(struct sock *sk, struct sk_buff *skb)
2143{ 2146{
2144 skb->dev = skb_dst(skb)->dev; 2147 skb->dev = skb_dst(skb)->dev;
2145 return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); 2148 return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
@@ -2231,6 +2234,27 @@ void rt6_remove_prefsrc(struct inet6_ifaddr *ifp)
2231 fib6_clean_all(net, fib6_remove_prefsrc, &adni); 2234 fib6_clean_all(net, fib6_remove_prefsrc, &adni);
2232} 2235}
2233 2236
2237#define RTF_RA_ROUTER (RTF_ADDRCONF | RTF_DEFAULT | RTF_GATEWAY)
2238#define RTF_CACHE_GATEWAY (RTF_GATEWAY | RTF_CACHE)
2239
2240/* Remove routers and update dst entries when gateway turn into host. */
2241static int fib6_clean_tohost(struct rt6_info *rt, void *arg)
2242{
2243 struct in6_addr *gateway = (struct in6_addr *)arg;
2244
2245 if ((((rt->rt6i_flags & RTF_RA_ROUTER) == RTF_RA_ROUTER) ||
2246 ((rt->rt6i_flags & RTF_CACHE_GATEWAY) == RTF_CACHE_GATEWAY)) &&
2247 ipv6_addr_equal(gateway, &rt->rt6i_gateway)) {
2248 return -1;
2249 }
2250 return 0;
2251}
2252
2253void rt6_clean_tohost(struct net *net, struct in6_addr *gateway)
2254{
2255 fib6_clean_all(net, fib6_clean_tohost, gateway);
2256}
2257
2234struct arg_dev_net { 2258struct arg_dev_net {
2235 struct net_device *dev; 2259 struct net_device *dev;
2236 struct net *net; 2260 struct net *net;
@@ -2706,6 +2730,9 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh)
2706 if (tb[RTA_OIF]) 2730 if (tb[RTA_OIF])
2707 oif = nla_get_u32(tb[RTA_OIF]); 2731 oif = nla_get_u32(tb[RTA_OIF]);
2708 2732
2733 if (tb[RTA_MARK])
2734 fl6.flowi6_mark = nla_get_u32(tb[RTA_MARK]);
2735
2709 if (iif) { 2736 if (iif) {
2710 struct net_device *dev; 2737 struct net_device *dev;
2711 int flags = 0; 2738 int flags = 0;
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 1693c8d885f0..e5a453ca302e 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -974,8 +974,9 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
974 goto out; 974 goto out;
975 } 975 }
976 976
977 err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, IPPROTO_IPV6, tos, 977 err = iptunnel_xmit(skb->sk, rt, skb, fl4.saddr, fl4.daddr,
978 ttl, df, !net_eq(tunnel->net, dev_net(dev))); 978 IPPROTO_IPV6, tos, ttl, df,
979 !net_eq(tunnel->net, dev_net(dev)));
979 iptunnel_xmit_stats(err, &dev->stats, dev->tstats); 980 iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
980 return NETDEV_TX_OK; 981 return NETDEV_TX_OK;
981 982
@@ -1126,8 +1127,8 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
1126 int err = 0; 1127 int err = 0;
1127 struct ip_tunnel_parm p; 1128 struct ip_tunnel_parm p;
1128 struct ip_tunnel_prl prl; 1129 struct ip_tunnel_prl prl;
1129 struct ip_tunnel *t; 1130 struct ip_tunnel *t = netdev_priv(dev);
1130 struct net *net = dev_net(dev); 1131 struct net *net = t->net;
1131 struct sit_net *sitn = net_generic(net, sit_net_id); 1132 struct sit_net *sitn = net_generic(net, sit_net_id);
1132#ifdef CONFIG_IPV6_SIT_6RD 1133#ifdef CONFIG_IPV6_SIT_6RD
1133 struct ip_tunnel_6rd ip6rd; 1134 struct ip_tunnel_6rd ip6rd;
@@ -1138,16 +1139,15 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
1138#ifdef CONFIG_IPV6_SIT_6RD 1139#ifdef CONFIG_IPV6_SIT_6RD
1139 case SIOCGET6RD: 1140 case SIOCGET6RD:
1140#endif 1141#endif
1141 t = NULL;
1142 if (dev == sitn->fb_tunnel_dev) { 1142 if (dev == sitn->fb_tunnel_dev) {
1143 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) { 1143 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) {
1144 err = -EFAULT; 1144 err = -EFAULT;
1145 break; 1145 break;
1146 } 1146 }
1147 t = ipip6_tunnel_locate(net, &p, 0); 1147 t = ipip6_tunnel_locate(net, &p, 0);
1148 if (t == NULL)
1149 t = netdev_priv(dev);
1148 } 1150 }
1149 if (t == NULL)
1150 t = netdev_priv(dev);
1151 1151
1152 err = -EFAULT; 1152 err = -EFAULT;
1153 if (cmd == SIOCGETTUNNEL) { 1153 if (cmd == SIOCGETTUNNEL) {
@@ -1243,9 +1243,6 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
1243 err = -EINVAL; 1243 err = -EINVAL;
1244 if (dev == sitn->fb_tunnel_dev) 1244 if (dev == sitn->fb_tunnel_dev)
1245 goto done; 1245 goto done;
1246 err = -ENOENT;
1247 if (!(t = netdev_priv(dev)))
1248 goto done;
1249 err = ipip6_tunnel_get_prl(t, ifr->ifr_ifru.ifru_data); 1246 err = ipip6_tunnel_get_prl(t, ifr->ifr_ifru.ifru_data);
1250 break; 1247 break;
1251 1248
@@ -1261,9 +1258,6 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
1261 err = -EFAULT; 1258 err = -EFAULT;
1262 if (copy_from_user(&prl, ifr->ifr_ifru.ifru_data, sizeof(prl))) 1259 if (copy_from_user(&prl, ifr->ifr_ifru.ifru_data, sizeof(prl)))
1263 goto done; 1260 goto done;
1264 err = -ENOENT;
1265 if (!(t = netdev_priv(dev)))
1266 goto done;
1267 1261
1268 switch (cmd) { 1262 switch (cmd) {
1269 case SIOCDELPRL: 1263 case SIOCDELPRL:
@@ -1291,8 +1285,6 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
1291 sizeof(ip6rd))) 1285 sizeof(ip6rd)))
1292 goto done; 1286 goto done;
1293 1287
1294 t = netdev_priv(dev);
1295
1296 if (cmd != SIOCDEL6RD) { 1288 if (cmd != SIOCDEL6RD) {
1297 err = ipip6_tunnel_update_6rd(t, &ip6rd); 1289 err = ipip6_tunnel_update_6rd(t, &ip6rd);
1298 if (err < 0) 1290 if (err < 0)
diff --git a/net/ipv6/tcpv6_offload.c b/net/ipv6/tcpv6_offload.c
index 0d78132ff18a..8517d3cd1aed 100644
--- a/net/ipv6/tcpv6_offload.c
+++ b/net/ipv6/tcpv6_offload.c
@@ -42,7 +42,7 @@ static struct sk_buff **tcp6_gro_receive(struct sk_buff **head,
42 if (NAPI_GRO_CB(skb)->flush) 42 if (NAPI_GRO_CB(skb)->flush)
43 goto skip_csum; 43 goto skip_csum;
44 44
45 wsum = skb->csum; 45 wsum = NAPI_GRO_CB(skb)->csum;
46 46
47 switch (skb->ip_summed) { 47 switch (skb->ip_summed) {
48 case CHECKSUM_NONE: 48 case CHECKSUM_NONE:
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index 6cd625e37706..b930d080c66f 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -114,12 +114,6 @@ int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb)
114 if (err) 114 if (err)
115 return err; 115 return err;
116 116
117 memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
118#ifdef CONFIG_NETFILTER
119 IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
120#endif
121
122 skb->protocol = htons(ETH_P_IPV6);
123 skb->local_df = 1; 117 skb->local_df = 1;
124 118
125 return x->outer_mode->output2(x, skb); 119 return x->outer_mode->output2(x, skb);
@@ -128,11 +122,13 @@ EXPORT_SYMBOL(xfrm6_prepare_output);
128 122
129int xfrm6_output_finish(struct sk_buff *skb) 123int xfrm6_output_finish(struct sk_buff *skb)
130{ 124{
125 memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
126 skb->protocol = htons(ETH_P_IPV6);
127
131#ifdef CONFIG_NETFILTER 128#ifdef CONFIG_NETFILTER
132 IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED; 129 IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
133#endif 130#endif
134 131
135 skb->protocol = htons(ETH_P_IPV6);
136 return xfrm_output(skb); 132 return xfrm_output(skb);
137} 133}
138 134
@@ -142,6 +138,13 @@ static int __xfrm6_output(struct sk_buff *skb)
142 struct xfrm_state *x = dst->xfrm; 138 struct xfrm_state *x = dst->xfrm;
143 int mtu; 139 int mtu;
144 140
141#ifdef CONFIG_NETFILTER
142 if (!x) {
143 IP6CB(skb)->flags |= IP6SKB_REROUTED;
144 return dst_output(skb);
145 }
146#endif
147
145 if (skb->protocol == htons(ETH_P_IPV6)) 148 if (skb->protocol == htons(ETH_P_IPV6))
146 mtu = ip6_skb_dst_mtu(skb); 149 mtu = ip6_skb_dst_mtu(skb);
147 else 150 else
@@ -163,8 +166,9 @@ static int __xfrm6_output(struct sk_buff *skb)
163 return x->outer_mode->afinfo->output_finish(skb); 166 return x->outer_mode->afinfo->output_finish(skb);
164} 167}
165 168
166int xfrm6_output(struct sk_buff *skb) 169int xfrm6_output(struct sock *sk, struct sk_buff *skb)
167{ 170{
168 return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL, 171 return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb,
169 skb_dst(skb)->dev, __xfrm6_output); 172 NULL, skb_dst(skb)->dev, __xfrm6_output,
173 !(IP6CB(skb)->flags & IP6SKB_REROUTED));
170} 174}
diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c
index 6ab989c486f7..54d13f8dbbae 100644
--- a/net/ipv6/xfrm6_protocol.c
+++ b/net/ipv6/xfrm6_protocol.c
@@ -50,6 +50,10 @@ int xfrm6_rcv_cb(struct sk_buff *skb, u8 protocol, int err)
50{ 50{
51 int ret; 51 int ret;
52 struct xfrm6_protocol *handler; 52 struct xfrm6_protocol *handler;
53 struct xfrm6_protocol __rcu **head = proto_handlers(protocol);
54
55 if (!head)
56 return 0;
53 57
54 for_each_protocol_rcu(*proto_handlers(protocol), handler) 58 for_each_protocol_rcu(*proto_handlers(protocol), handler)
55 if ((ret = handler->cb_handler(skb, err)) <= 0) 59 if ((ret = handler->cb_handler(skb, err)) <= 0)
@@ -184,10 +188,12 @@ int xfrm6_protocol_register(struct xfrm6_protocol *handler,
184 struct xfrm6_protocol __rcu **pprev; 188 struct xfrm6_protocol __rcu **pprev;
185 struct xfrm6_protocol *t; 189 struct xfrm6_protocol *t;
186 bool add_netproto = false; 190 bool add_netproto = false;
187
188 int ret = -EEXIST; 191 int ret = -EEXIST;
189 int priority = handler->priority; 192 int priority = handler->priority;
190 193
194 if (!proto_handlers(protocol) || !netproto(protocol))
195 return -EINVAL;
196
191 mutex_lock(&xfrm6_protocol_mutex); 197 mutex_lock(&xfrm6_protocol_mutex);
192 198
193 if (!rcu_dereference_protected(*proto_handlers(protocol), 199 if (!rcu_dereference_protected(*proto_handlers(protocol),
@@ -230,6 +236,9 @@ int xfrm6_protocol_deregister(struct xfrm6_protocol *handler,
230 struct xfrm6_protocol *t; 236 struct xfrm6_protocol *t;
231 int ret = -ENOENT; 237 int ret = -ENOENT;
232 238
239 if (!proto_handlers(protocol) || !netproto(protocol))
240 return -EINVAL;
241
233 mutex_lock(&xfrm6_protocol_mutex); 242 mutex_lock(&xfrm6_protocol_mutex);
234 243
235 for (pprev = proto_handlers(protocol); 244 for (pprev = proto_handlers(protocol);