aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/ip6_output.c')
-rw-r--r--net/ipv6/ip6_output.c66
1 files changed, 41 insertions, 25 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index e6f931997996..ef02b26ccf81 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -321,6 +321,27 @@ static inline int ip6_forward_finish(struct sk_buff *skb)
321 return dst_output(skb); 321 return dst_output(skb);
322} 322}
323 323
324static unsigned int ip6_dst_mtu_forward(const struct dst_entry *dst)
325{
326 unsigned int mtu;
327 struct inet6_dev *idev;
328
329 if (dst_metric_locked(dst, RTAX_MTU)) {
330 mtu = dst_metric_raw(dst, RTAX_MTU);
331 if (mtu)
332 return mtu;
333 }
334
335 mtu = IPV6_MIN_MTU;
336 rcu_read_lock();
337 idev = __in6_dev_get(dst->dev);
338 if (idev)
339 mtu = idev->cnf.mtu6;
340 rcu_read_unlock();
341
342 return mtu;
343}
344
324int ip6_forward(struct sk_buff *skb) 345int ip6_forward(struct sk_buff *skb)
325{ 346{
326 struct dst_entry *dst = skb_dst(skb); 347 struct dst_entry *dst = skb_dst(skb);
@@ -336,7 +357,8 @@ int ip6_forward(struct sk_buff *skb)
336 goto drop; 357 goto drop;
337 358
338 if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) { 359 if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) {
339 IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); 360 IP6_INC_STATS_BH(net, ip6_dst_idev(dst),
361 IPSTATS_MIB_INDISCARDS);
340 goto drop; 362 goto drop;
341 } 363 }
342 364
@@ -370,8 +392,8 @@ int ip6_forward(struct sk_buff *skb)
370 /* Force OUTPUT device used as source address */ 392 /* Force OUTPUT device used as source address */
371 skb->dev = dst->dev; 393 skb->dev = dst->dev;
372 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 0); 394 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 0);
373 IP6_INC_STATS_BH(net, 395 IP6_INC_STATS_BH(net, ip6_dst_idev(dst),
374 ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS); 396 IPSTATS_MIB_INHDRERRORS);
375 397
376 kfree_skb(skb); 398 kfree_skb(skb);
377 return -ETIMEDOUT; 399 return -ETIMEDOUT;
@@ -384,14 +406,15 @@ int ip6_forward(struct sk_buff *skb)
384 if (proxied > 0) 406 if (proxied > 0)
385 return ip6_input(skb); 407 return ip6_input(skb);
386 else if (proxied < 0) { 408 else if (proxied < 0) {
387 IP6_INC_STATS(net, ip6_dst_idev(dst), 409 IP6_INC_STATS_BH(net, ip6_dst_idev(dst),
388 IPSTATS_MIB_INDISCARDS); 410 IPSTATS_MIB_INDISCARDS);
389 goto drop; 411 goto drop;
390 } 412 }
391 } 413 }
392 414
393 if (!xfrm6_route_forward(skb)) { 415 if (!xfrm6_route_forward(skb)) {
394 IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); 416 IP6_INC_STATS_BH(net, ip6_dst_idev(dst),
417 IPSTATS_MIB_INDISCARDS);
395 goto drop; 418 goto drop;
396 } 419 }
397 dst = skb_dst(skb); 420 dst = skb_dst(skb);
@@ -439,7 +462,7 @@ int ip6_forward(struct sk_buff *skb)
439 } 462 }
440 } 463 }
441 464
442 mtu = dst_mtu(dst); 465 mtu = ip6_dst_mtu_forward(dst);
443 if (mtu < IPV6_MIN_MTU) 466 if (mtu < IPV6_MIN_MTU)
444 mtu = IPV6_MIN_MTU; 467 mtu = IPV6_MIN_MTU;
445 468
@@ -448,16 +471,17 @@ int ip6_forward(struct sk_buff *skb)
448 /* Again, force OUTPUT device used as source address */ 471 /* Again, force OUTPUT device used as source address */
449 skb->dev = dst->dev; 472 skb->dev = dst->dev;
450 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); 473 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
451 IP6_INC_STATS_BH(net, 474 IP6_INC_STATS_BH(net, ip6_dst_idev(dst),
452 ip6_dst_idev(dst), IPSTATS_MIB_INTOOBIGERRORS); 475 IPSTATS_MIB_INTOOBIGERRORS);
453 IP6_INC_STATS_BH(net, 476 IP6_INC_STATS_BH(net, ip6_dst_idev(dst),
454 ip6_dst_idev(dst), IPSTATS_MIB_FRAGFAILS); 477 IPSTATS_MIB_FRAGFAILS);
455 kfree_skb(skb); 478 kfree_skb(skb);
456 return -EMSGSIZE; 479 return -EMSGSIZE;
457 } 480 }
458 481
459 if (skb_cow(skb, dst->dev->hard_header_len)) { 482 if (skb_cow(skb, dst->dev->hard_header_len)) {
460 IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTDISCARDS); 483 IP6_INC_STATS_BH(net, ip6_dst_idev(dst),
484 IPSTATS_MIB_OUTDISCARDS);
461 goto drop; 485 goto drop;
462 } 486 }
463 487
@@ -938,7 +962,6 @@ EXPORT_SYMBOL_GPL(ip6_dst_lookup);
938 * @sk: socket which provides route info 962 * @sk: socket which provides route info
939 * @fl6: flow to lookup 963 * @fl6: flow to lookup
940 * @final_dst: final destination address for ipsec lookup 964 * @final_dst: final destination address for ipsec lookup
941 * @can_sleep: we are in a sleepable context
942 * 965 *
943 * This function performs a route lookup on the given flow. 966 * This function performs a route lookup on the given flow.
944 * 967 *
@@ -946,8 +969,7 @@ EXPORT_SYMBOL_GPL(ip6_dst_lookup);
946 * error code. 969 * error code.
947 */ 970 */
948struct dst_entry *ip6_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6, 971struct dst_entry *ip6_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
949 const struct in6_addr *final_dst, 972 const struct in6_addr *final_dst)
950 bool can_sleep)
951{ 973{
952 struct dst_entry *dst = NULL; 974 struct dst_entry *dst = NULL;
953 int err; 975 int err;
@@ -957,8 +979,6 @@ struct dst_entry *ip6_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
957 return ERR_PTR(err); 979 return ERR_PTR(err);
958 if (final_dst) 980 if (final_dst)
959 fl6->daddr = *final_dst; 981 fl6->daddr = *final_dst;
960 if (can_sleep)
961 fl6->flowi6_flags |= FLOWI_FLAG_CAN_SLEEP;
962 982
963 return xfrm_lookup(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0); 983 return xfrm_lookup(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0);
964} 984}
@@ -969,7 +989,6 @@ EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow);
969 * @sk: socket which provides the dst cache and route info 989 * @sk: socket which provides the dst cache and route info
970 * @fl6: flow to lookup 990 * @fl6: flow to lookup
971 * @final_dst: final destination address for ipsec lookup 991 * @final_dst: final destination address for ipsec lookup
972 * @can_sleep: we are in a sleepable context
973 * 992 *
974 * This function performs a route lookup on the given flow with the 993 * This function performs a route lookup on the given flow with the
975 * possibility of using the cached route in the socket if it is valid. 994 * possibility of using the cached route in the socket if it is valid.
@@ -980,8 +999,7 @@ EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow);
980 * error code. 999 * error code.
981 */ 1000 */
982struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6, 1001struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
983 const struct in6_addr *final_dst, 1002 const struct in6_addr *final_dst)
984 bool can_sleep)
985{ 1003{
986 struct dst_entry *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie); 1004 struct dst_entry *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie);
987 int err; 1005 int err;
@@ -993,8 +1011,6 @@ struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
993 return ERR_PTR(err); 1011 return ERR_PTR(err);
994 if (final_dst) 1012 if (final_dst)
995 fl6->daddr = *final_dst; 1013 fl6->daddr = *final_dst;
996 if (can_sleep)
997 fl6->flowi6_flags |= FLOWI_FLAG_CAN_SLEEP;
998 1014
999 return xfrm_lookup(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0); 1015 return xfrm_lookup(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0);
1000} 1016}
@@ -1162,10 +1178,10 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1162 np->cork.hop_limit = hlimit; 1178 np->cork.hop_limit = hlimit;
1163 np->cork.tclass = tclass; 1179 np->cork.tclass = tclass;
1164 if (rt->dst.flags & DST_XFRM_TUNNEL) 1180 if (rt->dst.flags & DST_XFRM_TUNNEL)
1165 mtu = np->pmtudisc == IPV6_PMTUDISC_PROBE ? 1181 mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
1166 rt->dst.dev->mtu : dst_mtu(&rt->dst); 1182 rt->dst.dev->mtu : dst_mtu(&rt->dst);
1167 else 1183 else
1168 mtu = np->pmtudisc == IPV6_PMTUDISC_PROBE ? 1184 mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
1169 rt->dst.dev->mtu : dst_mtu(rt->dst.path); 1185 rt->dst.dev->mtu : dst_mtu(rt->dst.path);
1170 if (np->frag_size < mtu) { 1186 if (np->frag_size < mtu) {
1171 if (np->frag_size) 1187 if (np->frag_size)
@@ -1285,7 +1301,7 @@ alloc_new_skb:
1285 if (skb == NULL || skb_prev == NULL) 1301 if (skb == NULL || skb_prev == NULL)
1286 ip6_append_data_mtu(&mtu, &maxfraglen, 1302 ip6_append_data_mtu(&mtu, &maxfraglen,
1287 fragheaderlen, skb, rt, 1303 fragheaderlen, skb, rt,
1288 np->pmtudisc == 1304 np->pmtudisc >=
1289 IPV6_PMTUDISC_PROBE); 1305 IPV6_PMTUDISC_PROBE);
1290 1306
1291 skb_prev = skb; 1307 skb_prev = skb;