Commit 1397ed35f22d7c30d0b89ba74b6b7829220dfcfd
Committed by
David S. Miller
1 parent
5824d2d16d
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
ipv6: add flowinfo for tcp6 pkt_options for all cases
The current implementation of IPV6_FLOWINFO only gives a result if pktoptions is available (thanks to the ip6_datagram_recv_ctl function). It gives inconsistent results to user space, sometimes there is a result for getsockopt(IPV6_FLOWINFO), sometimes not. This patch add rcv_flowinfo to store it, and return it to the userspace in the same way than other pkt_options. Signed-off-by: Florent Fourcot <florent.fourcot@enst-bretagne.fr> Reviewed-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 3 changed files with 9 additions and 0 deletions Side-by-side Diff
include/linux/ipv6.h
net/ipv6/ipv6_sockglue.c
... | ... | @@ -1034,6 +1034,10 @@ |
1034 | 1034 | int hlim = np->mcast_hops; |
1035 | 1035 | put_cmsg(&msg, SOL_IPV6, IPV6_2292HOPLIMIT, sizeof(hlim), &hlim); |
1036 | 1036 | } |
1037 | + if (np->rxopt.bits.rxflow) { | |
1038 | + int flowinfo = np->rcv_flowinfo; | |
1039 | + put_cmsg(&msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo); | |
1040 | + } | |
1037 | 1041 | } |
1038 | 1042 | len -= msg.msg_controllen; |
1039 | 1043 | return put_user(len, optlen); |
net/ipv6/tcp_ipv6.c
... | ... | @@ -1136,6 +1136,7 @@ |
1136 | 1136 | newnp->mcast_oif = inet6_iif(skb); |
1137 | 1137 | newnp->mcast_hops = ipv6_hdr(skb)->hop_limit; |
1138 | 1138 | newnp->rcv_tclass = ipv6_get_dsfield(ipv6_hdr(skb)); |
1139 | + newnp->rcv_flowinfo = ip6_flowinfo(ipv6_hdr(skb)); | |
1139 | 1140 | |
1140 | 1141 | /* |
1141 | 1142 | * No need to charge this sock to the relevant IPv6 refcnt debug socks count |
... | ... | @@ -1216,6 +1217,7 @@ |
1216 | 1217 | newnp->mcast_oif = inet6_iif(skb); |
1217 | 1218 | newnp->mcast_hops = ipv6_hdr(skb)->hop_limit; |
1218 | 1219 | newnp->rcv_tclass = ipv6_get_dsfield(ipv6_hdr(skb)); |
1220 | + newnp->rcv_flowinfo = ip6_flowinfo(ipv6_hdr(skb)); | |
1219 | 1221 | |
1220 | 1222 | /* Clone native IPv6 options from listening socket (if any) |
1221 | 1223 | |
... | ... | @@ -1427,6 +1429,8 @@ |
1427 | 1429 | np->mcast_hops = ipv6_hdr(opt_skb)->hop_limit; |
1428 | 1430 | if (np->rxopt.bits.rxtclass) |
1429 | 1431 | np->rcv_tclass = ipv6_get_dsfield(ipv6_hdr(opt_skb)); |
1432 | + if (np->rxopt.bits.rxflow) | |
1433 | + np->rcv_flowinfo = ip6_flowinfo(ipv6_hdr(opt_skb)); | |
1430 | 1434 | if (ipv6_opt_accepted(sk, opt_skb)) { |
1431 | 1435 | skb_set_owner_r(opt_skb, sk); |
1432 | 1436 | opt_skb = xchg(&np->pktoptions, opt_skb); |