Commit e0d8c1b7 authored by Wei Wang's avatar Wei Wang Committed by David S. Miller

ipv6: pass up EMSGSIZE msg for UDP socket in Ipv6

In ipv4,  when  the machine receives a ICMP_FRAG_NEEDED message,  the
connected UDP socket will get EMSGSIZE message on its next read from the
socket.
However, this is not the case for ipv6.
This fix modifies the udp err handler in Ipv6 for ICMP6_PKT_TOOBIG to
make it similar to ipv4 behavior. That is when the machine gets an
ICMP6_PKT_TOOBIG message, the connected UDP socket will get EMSGSIZE
message on its next read from the socket.
Signed-off-by: default avatarWei Wang <weiwan@google.com>
Acked-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 68f22793
...@@ -548,6 +548,7 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -548,6 +548,7 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
const struct in6_addr *daddr = &hdr->daddr; const struct in6_addr *daddr = &hdr->daddr;
struct udphdr *uh = (struct udphdr *)(skb->data+offset); struct udphdr *uh = (struct udphdr *)(skb->data+offset);
struct sock *sk; struct sock *sk;
int harderr;
int err; int err;
struct net *net = dev_net(skb->dev); struct net *net = dev_net(skb->dev);
...@@ -559,26 +560,27 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -559,26 +560,27 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
return; return;
} }
harderr = icmpv6_err_convert(type, code, &err);
np = inet6_sk(sk);
if (type == ICMPV6_PKT_TOOBIG) { if (type == ICMPV6_PKT_TOOBIG) {
if (!ip6_sk_accept_pmtu(sk)) if (!ip6_sk_accept_pmtu(sk))
goto out; goto out;
ip6_sk_update_pmtu(skb, sk, info); ip6_sk_update_pmtu(skb, sk, info);
if (np->pmtudisc != IPV6_PMTUDISC_DONT)
harderr = 1;
} }
if (type == NDISC_REDIRECT) { if (type == NDISC_REDIRECT) {
ip6_sk_redirect(skb, sk); ip6_sk_redirect(skb, sk);
goto out; goto out;
} }
np = inet6_sk(sk); if (!np->recverr) {
if (!harderr || sk->sk_state != TCP_ESTABLISHED)
if (!icmpv6_err_convert(type, code, &err) && !np->recverr)
goto out; goto out;
} else {
if (sk->sk_state != TCP_ESTABLISHED && !np->recverr)
goto out;
if (np->recverr)
ipv6_icmp_error(sk, skb, err, uh->dest, ntohl(info), (u8 *)(uh+1)); ipv6_icmp_error(sk, skb, err, uh->dest, ntohl(info), (u8 *)(uh+1));
}
sk->sk_err = err; sk->sk_err = err;
sk->sk_error_report(sk); sk->sk_error_report(sk);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment