diff options
author | Julian Anastasov <ja@ssi.bg> | 2017-02-06 16:14:16 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-02-07 13:07:47 -0500 |
commit | 0dec879f636f11b0ffda1cb5fd96a1754c59ead3 (patch) | |
tree | fcc479052e78ceb30f8f3b95a881cf986f0564dd /net/ipv6/raw.c | |
parent | 63fca65d08632fbec9d9b655f671cf08aa1aeeb8 (diff) |
net: use dst_confirm_neigh for UDP, RAW, ICMP, L2TP
When same struct dst_entry can be used for many different
neighbours we can not use it for pending confirmations.
The datagram protocols can use MSG_CONFIRM to confirm the
neighbour. When used with MSG_PROBE we do not reach the
code where neighbour is confirmed, so we have to do the
same slow lookup by using the dst_confirm_neigh() helper.
When MSG_PROBE is not used, ip_append_data/ip6_append_data
will set the skb flag dst_pending_confirm.
Reported-by: YueHaibing <yuehaibing@huawei.com>
Fixes: 5110effee8fd ("net: Do delayed neigh confirmation.")
Fixes: f2bb4bedf35d ("ipv4: Cache output routes in fib_info nexthops.")
Signed-off-by: Julian Anastasov <ja@ssi.bg>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/raw.c')
-rw-r--r-- | net/ipv6/raw.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index ea89073c8247..f174e76e6505 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -654,6 +654,9 @@ static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length, | |||
654 | 654 | ||
655 | skb->ip_summed = CHECKSUM_NONE; | 655 | skb->ip_summed = CHECKSUM_NONE; |
656 | 656 | ||
657 | if (flags & MSG_CONFIRM) | ||
658 | skb_set_dst_pending_confirm(skb, 1); | ||
659 | |||
657 | skb->transport_header = skb->network_header; | 660 | skb->transport_header = skb->network_header; |
658 | err = memcpy_from_msg(iph, msg, length); | 661 | err = memcpy_from_msg(iph, msg, length); |
659 | if (err) | 662 | if (err) |
@@ -934,7 +937,8 @@ out: | |||
934 | txopt_put(opt_to_free); | 937 | txopt_put(opt_to_free); |
935 | return err < 0 ? err : len; | 938 | return err < 0 ? err : len; |
936 | do_confirm: | 939 | do_confirm: |
937 | dst_confirm(dst); | 940 | if (msg->msg_flags & MSG_PROBE) |
941 | dst_confirm_neigh(dst, &fl6.daddr); | ||
938 | if (!(msg->msg_flags & MSG_PROBE) || len) | 942 | if (!(msg->msg_flags & MSG_PROBE) || len) |
939 | goto back_from_confirm; | 943 | goto back_from_confirm; |
940 | err = 0; | 944 | err = 0; |