Skip to content

Commit 513674b

Browse files
shligitdavem330
authored andcommitted
net: reevalulate autoflowlabel setting after sysctl setting
sysctl.ip6.auto_flowlabels is default 1. In our hosts, we set it to 2. If sockopt doesn't set autoflowlabel, outcome packets from the hosts are supposed to not include flowlabel. This is true for normal packet, but not for reset packet. The reason is ipv6_pinfo.autoflowlabel is set in sock creation. Later if we change sysctl.ip6.auto_flowlabels, the ipv6_pinfo.autoflowlabel isn't changed, so the sock will keep the old behavior in terms of auto flowlabel. Reset packet is suffering from this problem, because reset packet is sent from a special control socket, which is created at boot time. Since sysctl.ipv6.auto_flowlabels is 1 by default, the control socket will always have its ipv6_pinfo.autoflowlabel set, even after user set sysctl.ipv6.auto_flowlabels to 1, so reset packset will always have flowlabel. Normal sock created before sysctl setting suffers from the same issue. We can't even turn off autoflowlabel unless we kill all socks in the hosts. To fix this, if IPV6_AUTOFLOWLABEL sockopt is used, we use the autoflowlabel setting from user, otherwise we always call ip6_default_np_autolabel() which has the new settings of sysctl. Note, this changes behavior a little bit. Before commit 4224090 (ipv6: Implement different admin modes for automatic flow labels), the autoflowlabel behavior of a sock isn't sticky, eg, if sysctl changes, existing connection will change autoflowlabel behavior. After that commit, autoflowlabel behavior is sticky in the whole life of the sock. With this patch, the behavior isn't sticky again. Cc: Martin KaFai Lau <[email protected]> Cc: Eric Dumazet <[email protected]> Cc: Tom Herbert <[email protected]> Signed-off-by: Shaohua Li <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c48e747 commit 513674b

File tree

4 files changed

+13
-4
lines changed

4 files changed

+13
-4
lines changed

include/linux/ipv6.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,8 @@ struct ipv6_pinfo {
273273
* 100: prefer care-of address
274274
*/
275275
dontfrag:1,
276-
autoflowlabel:1;
276+
autoflowlabel:1,
277+
autoflowlabel_set:1;
277278
__u8 min_hopcount;
278279
__u8 tclass;
279280
__be32 rcv_flowinfo;

net/ipv6/af_inet6.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,6 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol,
210210
np->mcast_hops = IPV6_DEFAULT_MCASTHOPS;
211211
np->mc_loop = 1;
212212
np->pmtudisc = IPV6_PMTUDISC_WANT;
213-
np->autoflowlabel = ip6_default_np_autolabel(net);
214213
np->repflow = net->ipv6.sysctl.flowlabel_reflect;
215214
sk->sk_ipv6only = net->ipv6.sysctl.bindv6only;
216215

net/ipv6/ip6_output.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,14 @@ int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
166166
!(IP6CB(skb)->flags & IP6SKB_REROUTED));
167167
}
168168

169+
static bool ip6_autoflowlabel(struct net *net, const struct ipv6_pinfo *np)
170+
{
171+
if (!np->autoflowlabel_set)
172+
return ip6_default_np_autolabel(net);
173+
else
174+
return np->autoflowlabel;
175+
}
176+
169177
/*
170178
* xmit an sk_buff (used by TCP, SCTP and DCCP)
171179
* Note : socket lock is not held for SYNACK packets, but might be modified
@@ -230,7 +238,7 @@ int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
230238
hlimit = ip6_dst_hoplimit(dst);
231239

232240
ip6_flow_hdr(hdr, tclass, ip6_make_flowlabel(net, skb, fl6->flowlabel,
233-
np->autoflowlabel, fl6));
241+
ip6_autoflowlabel(net, np), fl6));
234242

235243
hdr->payload_len = htons(seg_len);
236244
hdr->nexthdr = proto;
@@ -1626,7 +1634,7 @@ struct sk_buff *__ip6_make_skb(struct sock *sk,
16261634

16271635
ip6_flow_hdr(hdr, v6_cork->tclass,
16281636
ip6_make_flowlabel(net, skb, fl6->flowlabel,
1629-
np->autoflowlabel, fl6));
1637+
ip6_autoflowlabel(net, np), fl6));
16301638
hdr->hop_limit = v6_cork->hop_limit;
16311639
hdr->nexthdr = proto;
16321640
hdr->saddr = fl6->saddr;

net/ipv6/ipv6_sockglue.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
886886
break;
887887
case IPV6_AUTOFLOWLABEL:
888888
np->autoflowlabel = valbool;
889+
np->autoflowlabel_set = 1;
889890
retv = 0;
890891
break;
891892
case IPV6_RECVFRAGSIZE:

0 commit comments

Comments
 (0)