Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

[IPV6]: Fix IPV6_UNICAST_HOPS getsockopt().

> Relevant standard (RFC 3493) notes:
>
> The IPV6_UNICAST_HOPS option may be used with getsockopt() to
> determine the hop limit value that the system will use for subsequent
> unicast packets sent via that socket.
>
> I don't reckon -1 could be the hop limit value.

-1 means un-initialized.

> IMHO, the value from
> case 1 (if socket is connected to some destination), otherwise case 2
> (if bound to a scope interface) or ultimately the default hop limit
> ought to be returned instead, as it will be most often correct, while
> the current behavior is always wrong, unless setsockopt() has been used
> first. I don't if some people may think doing a route lookup in
> getsockopt might be overly expensive, but at least the two other cases
> should be ok, particularly the last one.

The following patch seems to work for me, but this code has behaved this
way for a while, so don't know if it will break any existing apps.

Signed-off-by: Brian Haley <brian.haley@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Brian Haley and committed by
David S. Miller
befffe90 832e3ca6

+19 -4
+19 -4
net/ipv6/ipv6_sockglue.c
··· 978 978 break; 979 979 980 980 case IPV6_UNICAST_HOPS: 981 - val = np->hop_limit; 982 - break; 983 - 984 981 case IPV6_MULTICAST_HOPS: 985 - val = np->mcast_hops; 982 + { 983 + struct dst_entry *dst; 984 + 985 + if (optname == IPV6_UNICAST_HOPS) 986 + val = np->hop_limit; 987 + else 988 + val = np->mcast_hops; 989 + 990 + dst = sk_dst_get(sk); 991 + if (dst) { 992 + if (val < 0) 993 + val = dst_metric(dst, RTAX_HOPLIMIT); 994 + if (val < 0) 995 + val = ipv6_get_hoplimit(dst->dev); 996 + dst_release(dst); 997 + } 998 + if (val < 0) 999 + val = ipv6_devconf.hop_limit; 986 1000 break; 1001 + } 987 1002 988 1003 case IPV6_MULTICAST_LOOP: 989 1004 val = np->mc_loop;