Re: [PATCH v3] ip6_tunnel: Correct tos value in collect_md mode
On Sat, 17 Jun 2017 11:38:05 +0800 Haishuang Yan <yanhaishu...@cmss.chinamobile.com> wrote: > Same as ip_gre, geneve and vxlan, use key->tos as traffic class value. > > CC: Peter Dawson <peted...@gmail.com> > Fixes: 0e9a709560db ("ip6_tunnel, ip6_gre: fix setting of DSCP on > encapsulated packets”) > Signed-off-by: Haishuang Yan <yanhaishu...@cmss.chinamobile.com> > > --- > Changes since v3: > * Add fixes information > * Remove obsoleted RT_TOS mask > --- > net/ipv6/ip6_tunnel.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c > index ef99d59..9d65918 100644 > --- a/net/ipv6/ip6_tunnel.c > +++ b/net/ipv6/ip6_tunnel.c > @@ -1249,7 +1249,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device > *dev, __u8 dsfield, > fl6.flowi6_proto = IPPROTO_IPIP; > fl6.daddr = key->u.ipv6.dst; > fl6.flowlabel = key->label; > - dsfield = ip6_tclass(key->label); > + dsfield = key->tos; > } else { > if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) > encap_limit = t->parms.encap_limit; > @@ -1320,7 +1320,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device > *dev, __u8 dsfield, > fl6.flowi6_proto = IPPROTO_IPV6; > fl6.daddr = key->u.ipv6.dst; > fl6.flowlabel = key->label; > - dsfield = ip6_tclass(key->label); > + dsfield = key->tos; > } else { > offset = ip6_tnl_parse_tlv_enc_lim(skb, > skb_network_header(skb)); > /* ip6_tnl_parse_tlv_enc_lim() might have reallocated skb->head > */ Acked-by: Peter Dawson <peter.a.daw...@boeing.com>
Re: [PATCH v3] ip6_tunnel: Correct tos value in collect_md mode
On Sat, 17 Jun 2017 11:38:05 +0800 Haishuang Yan wrote: > Same as ip_gre, geneve and vxlan, use key->tos as traffic class value. > > CC: Peter Dawson > Fixes: 0e9a709560db ("ip6_tunnel, ip6_gre: fix setting of DSCP on > encapsulated packets”) > Signed-off-by: Haishuang Yan > > --- > Changes since v3: > * Add fixes information > * Remove obsoleted RT_TOS mask > --- > net/ipv6/ip6_tunnel.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c > index ef99d59..9d65918 100644 > --- a/net/ipv6/ip6_tunnel.c > +++ b/net/ipv6/ip6_tunnel.c > @@ -1249,7 +1249,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device > *dev, __u8 dsfield, > fl6.flowi6_proto = IPPROTO_IPIP; > fl6.daddr = key->u.ipv6.dst; > fl6.flowlabel = key->label; > - dsfield = ip6_tclass(key->label); > + dsfield = key->tos; > } else { > if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) > encap_limit = t->parms.encap_limit; > @@ -1320,7 +1320,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device > *dev, __u8 dsfield, > fl6.flowi6_proto = IPPROTO_IPV6; > fl6.daddr = key->u.ipv6.dst; > fl6.flowlabel = key->label; > - dsfield = ip6_tclass(key->label); > + dsfield = key->tos; > } else { > offset = ip6_tnl_parse_tlv_enc_lim(skb, > skb_network_header(skb)); > /* ip6_tnl_parse_tlv_enc_lim() might have reallocated skb->head > */ Acked-by: Peter Dawson
Re: [PATCH v2] ip6_tunnel: Correct tos value in collect_md mode
On Thu, 15 Jun 2017 10:30:29 +0800 Haishuang Yan <yanhaishu...@cmss.chinamobile.com> wrote: > Same as ip_gre, geneve and vxlan, use key->tos as tos value. > > CC: Peter Dawson <peted...@gmail.com> > Fixes: 0e9a709560db ("ip6_tunnel, ip6_gre: fix setting of DSCP on > encapsulated packets”) > Suggested-by: Daniel Borkmann <dan...@iogearbox.net> > Signed-off-by: Haishuang Yan <yanhaishu...@cmss.chinamobile.com> > > --- > Changes since v2: > * Add fixes information > * mask key->tos with RT_TOS() suggested by Daniel > --- > net/ipv6/ip6_tunnel.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c > index ef99d59..6400726 100644 > --- a/net/ipv6/ip6_tunnel.c > +++ b/net/ipv6/ip6_tunnel.c > @@ -1249,7 +1249,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device > *dev, __u8 dsfield, > fl6.flowi6_proto = IPPROTO_IPIP; > fl6.daddr = key->u.ipv6.dst; > fl6.flowlabel = key->label; > - dsfield = ip6_tclass(key->label); > + dsfield = RT_TOS(key->tos); > } else { > if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) > encap_limit = t->parms.encap_limit; > @@ -1320,7 +1320,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device > *dev, __u8 dsfield, > fl6.flowi6_proto = IPPROTO_IPV6; > fl6.daddr = key->u.ipv6.dst; > fl6.flowlabel = key->label; > - dsfield = ip6_tclass(key->label); > + dsfield = RT_TOS(key->tos); > } else { > offset = ip6_tnl_parse_tlv_enc_lim(skb, > skb_network_header(skb)); > /* ip6_tnl_parse_tlv_enc_lim() might have reallocated skb->head > */ I don't think it is correct to apply RT_TOS Here is my understanding based on the RFCs. IPv4/6 Header:0 |0 1 2 3 |0 1 2 3 |0 1 2 3 |0 1 2 3 | RFC2460(IPv6) |Version | Traffic Class || RFC2474(IPv6) |Version | DSCP|ECN|| RFC2474(IPv4) |Version | IHL |DSCP |ECN| RFC1349(IPv4) |Version | IHL | PREC | TOS |X| RFC791 (IPv4) |Version | IHL | TOS| u8 key->tos stores the full 8bits of Traffic class from an IPv6 header and; u8 key->tos stores the full 8bits of TOS(RFC791) from an IPv4 header u8 ip6_tclass will return the full 8bits of Traffic Class from an IPv6 flowlabel RT_TOS will return the RFC1349 4bit TOS field. Applying RT_TOS to a key->tos will result in lost information and the inclusion of 1 bit of ECN if the original field was a DSCP+ECN. Based on this understanding of the RFCs (but not years of experience) and since RFC1349 has been obsoleted by RFC2474 I think the use of RT_TOS should be deprecated. This being said, dsfield = ip6_tclass(key->label) = key->tos isn't fully correct either because the result will contain the ECN bits as well as the DSCP. I agree that code should be consistent, but not where there is a potential issue.
Re: [PATCH v2] ip6_tunnel: Correct tos value in collect_md mode
On Thu, 15 Jun 2017 10:30:29 +0800 Haishuang Yan wrote: > Same as ip_gre, geneve and vxlan, use key->tos as tos value. > > CC: Peter Dawson > Fixes: 0e9a709560db ("ip6_tunnel, ip6_gre: fix setting of DSCP on > encapsulated packets”) > Suggested-by: Daniel Borkmann > Signed-off-by: Haishuang Yan > > --- > Changes since v2: > * Add fixes information > * mask key->tos with RT_TOS() suggested by Daniel > --- > net/ipv6/ip6_tunnel.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c > index ef99d59..6400726 100644 > --- a/net/ipv6/ip6_tunnel.c > +++ b/net/ipv6/ip6_tunnel.c > @@ -1249,7 +1249,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device > *dev, __u8 dsfield, > fl6.flowi6_proto = IPPROTO_IPIP; > fl6.daddr = key->u.ipv6.dst; > fl6.flowlabel = key->label; > - dsfield = ip6_tclass(key->label); > + dsfield = RT_TOS(key->tos); > } else { > if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) > encap_limit = t->parms.encap_limit; > @@ -1320,7 +1320,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device > *dev, __u8 dsfield, > fl6.flowi6_proto = IPPROTO_IPV6; > fl6.daddr = key->u.ipv6.dst; > fl6.flowlabel = key->label; > - dsfield = ip6_tclass(key->label); > + dsfield = RT_TOS(key->tos); > } else { > offset = ip6_tnl_parse_tlv_enc_lim(skb, > skb_network_header(skb)); > /* ip6_tnl_parse_tlv_enc_lim() might have reallocated skb->head > */ I don't think it is correct to apply RT_TOS Here is my understanding based on the RFCs. IPv4/6 Header:0 |0 1 2 3 |0 1 2 3 |0 1 2 3 |0 1 2 3 | RFC2460(IPv6) |Version | Traffic Class || RFC2474(IPv6) |Version | DSCP|ECN|| RFC2474(IPv4) |Version | IHL |DSCP |ECN| RFC1349(IPv4) |Version | IHL | PREC | TOS |X| RFC791 (IPv4) |Version | IHL | TOS| u8 key->tos stores the full 8bits of Traffic class from an IPv6 header and; u8 key->tos stores the full 8bits of TOS(RFC791) from an IPv4 header u8 ip6_tclass will return the full 8bits of Traffic Class from an IPv6 flowlabel RT_TOS will return the RFC1349 4bit TOS field. Applying RT_TOS to a key->tos will result in lost information and the inclusion of 1 bit of ECN if the original field was a DSCP+ECN. Based on this understanding of the RFCs (but not years of experience) and since RFC1349 has been obsoleted by RFC2474 I think the use of RT_TOS should be deprecated. This being said, dsfield = ip6_tclass(key->label) = key->tos isn't fully correct either because the result will contain the ECN bits as well as the DSCP. I agree that code should be consistent, but not where there is a potential issue.
Re: [PATCH] ip6_tunnel: Correct tos value in collect_md mode
On Wed, 14 Jun 2017 10:54:31 +0800 严海双wrote: > > Changes since v2: > > * mask key->tos with RT_TOS() suggested by Daniel Can you help me understand the rationale for this change? Is there are bug introduced by dsfield = ip6_tclass(key->label); ? The RT_TOS masks out 4bits of the 8bit tos field in accordance with RFC1349 (obsoleted by RFC2474). IPv6 does not have a TOS field. So it dosen't make sense to apply a TOS value to the outer header of an IPv6 tunnel.
Re: [PATCH] ip6_tunnel: Correct tos value in collect_md mode
On Wed, 14 Jun 2017 10:54:31 +0800 严海双 wrote: > > Changes since v2: > > * mask key->tos with RT_TOS() suggested by Daniel Can you help me understand the rationale for this change? Is there are bug introduced by dsfield = ip6_tclass(key->label); ? The RT_TOS masks out 4bits of the 8bit tos field in accordance with RFC1349 (obsoleted by RFC2474). IPv6 does not have a TOS field. So it dosen't make sense to apply a TOS value to the outer header of an IPv6 tunnel.
[PATCH net,v2] ip6_tunnel, ip6_gre: fix setting of DSCP on encapsulated packets
This fix addresses two problems in the way the DSCP field is formulated on the encapsulating header of IPv6 tunnels. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=195661 1) The IPv6 tunneling code was manipulating the DSCP field of the encapsulating packet using the 32b flowlabel. Since the flowlabel is only the lower 20b it was incorrect to assume that the upper 12b containing the DSCP and ECN fields would remain intact when formulating the encapsulating header. This fix handles the 'inherit' and 'fixed-value' DSCP cases explicitly using the extant dsfield u8 variable. 2) The use of INET_ECN_encapsulate(0, dsfield) in ip6_tnl_xmit was incorrect and resulted in the DSCP value always being set to 0. Commit 90427ef5d2a4 ("ipv6: fix flow labels when the traffic class is non-0") caused the regression by masking out the flowlabel which exposed the incorrect handling of the DSCP portion of the flowlabel in ip6_tunnel and ip6_gre. Fixes: 90427ef5d2a4 ("ipv6: fix flow labels when the traffic class is non-0") Signed-off-by: Peter Dawson <peter.a.daw...@boeing.com> --- net/ipv6/ip6_gre.c| 13 +++-- net/ipv6/ip6_tunnel.c | 21 + 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 8d128ba..0c5b4caa 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -537,11 +537,10 @@ static inline int ip6gre_xmit_ipv4(struct sk_buff *skb, struct net_device *dev) memcpy(, >fl.u.ip6, sizeof(fl6)); - dsfield = ipv4_get_dsfield(iph); - if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) - fl6.flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT) - & IPV6_TCLASS_MASK; + dsfield = ipv4_get_dsfield(iph); + else + dsfield = ip6_tclass(t->parms.flowinfo); if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK) fl6.flowi6_mark = skb->mark; else @@ -598,9 +597,11 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device *dev) memcpy(, >fl.u.ip6, sizeof(fl6)); - dsfield = ipv6_get_dsfield(ipv6h); if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) - fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_TCLASS_MASK); + dsfield = ipv6_get_dsfield(ipv6h); + else + dsfield = ip6_tclass(t->parms.flowinfo); + if (t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL) fl6.flowlabel |= ip6_flowlabel(ipv6h); if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK) diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 6eb2ae5..7ae6c50 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -1196,7 +1196,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, skb_push(skb, sizeof(struct ipv6hdr)); skb_reset_network_header(skb); ipv6h = ipv6_hdr(skb); - ip6_flow_hdr(ipv6h, INET_ECN_encapsulate(0, dsfield), + ip6_flow_hdr(ipv6h, dsfield, ip6_make_flowlabel(net, skb, fl6->flowlabel, true, fl6)); ipv6h->hop_limit = hop_limit; ipv6h->nexthdr = proto; @@ -1231,8 +1231,6 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) if (tproto != IPPROTO_IPIP && tproto != 0) return -1; - dsfield = ipv4_get_dsfield(iph); - if (t->parms.collect_md) { struct ip_tunnel_info *tun_info; const struct ip_tunnel_key *key; @@ -1246,6 +1244,7 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) fl6.flowi6_proto = IPPROTO_IPIP; fl6.daddr = key->u.ipv6.dst; fl6.flowlabel = key->label; + dsfield = ip6_tclass(key->label); } else { if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) encap_limit = t->parms.encap_limit; @@ -1254,8 +1253,9 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) fl6.flowi6_proto = IPPROTO_IPIP; if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) - fl6.flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT) -& IPV6_TCLASS_MASK; + dsfield = ipv4_get_dsfield(iph); + else + dsfield = ip6_tclass(t->parms.flowinfo); if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK) fl6.flowi6_mark = skb->mark; else @@ -1267,6 +1267,8 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6)) return -1; + dsfield = INET_ECN_encapsulate(dsf
[PATCH net,v2] ip6_tunnel, ip6_gre: fix setting of DSCP on encapsulated packets
This fix addresses two problems in the way the DSCP field is formulated on the encapsulating header of IPv6 tunnels. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=195661 1) The IPv6 tunneling code was manipulating the DSCP field of the encapsulating packet using the 32b flowlabel. Since the flowlabel is only the lower 20b it was incorrect to assume that the upper 12b containing the DSCP and ECN fields would remain intact when formulating the encapsulating header. This fix handles the 'inherit' and 'fixed-value' DSCP cases explicitly using the extant dsfield u8 variable. 2) The use of INET_ECN_encapsulate(0, dsfield) in ip6_tnl_xmit was incorrect and resulted in the DSCP value always being set to 0. Commit 90427ef5d2a4 ("ipv6: fix flow labels when the traffic class is non-0") caused the regression by masking out the flowlabel which exposed the incorrect handling of the DSCP portion of the flowlabel in ip6_tunnel and ip6_gre. Fixes: 90427ef5d2a4 ("ipv6: fix flow labels when the traffic class is non-0") Signed-off-by: Peter Dawson --- net/ipv6/ip6_gre.c| 13 +++-- net/ipv6/ip6_tunnel.c | 21 + 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 8d128ba..0c5b4caa 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -537,11 +537,10 @@ static inline int ip6gre_xmit_ipv4(struct sk_buff *skb, struct net_device *dev) memcpy(, >fl.u.ip6, sizeof(fl6)); - dsfield = ipv4_get_dsfield(iph); - if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) - fl6.flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT) - & IPV6_TCLASS_MASK; + dsfield = ipv4_get_dsfield(iph); + else + dsfield = ip6_tclass(t->parms.flowinfo); if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK) fl6.flowi6_mark = skb->mark; else @@ -598,9 +597,11 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device *dev) memcpy(, >fl.u.ip6, sizeof(fl6)); - dsfield = ipv6_get_dsfield(ipv6h); if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) - fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_TCLASS_MASK); + dsfield = ipv6_get_dsfield(ipv6h); + else + dsfield = ip6_tclass(t->parms.flowinfo); + if (t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL) fl6.flowlabel |= ip6_flowlabel(ipv6h); if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK) diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 6eb2ae5..7ae6c50 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -1196,7 +1196,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, skb_push(skb, sizeof(struct ipv6hdr)); skb_reset_network_header(skb); ipv6h = ipv6_hdr(skb); - ip6_flow_hdr(ipv6h, INET_ECN_encapsulate(0, dsfield), + ip6_flow_hdr(ipv6h, dsfield, ip6_make_flowlabel(net, skb, fl6->flowlabel, true, fl6)); ipv6h->hop_limit = hop_limit; ipv6h->nexthdr = proto; @@ -1231,8 +1231,6 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) if (tproto != IPPROTO_IPIP && tproto != 0) return -1; - dsfield = ipv4_get_dsfield(iph); - if (t->parms.collect_md) { struct ip_tunnel_info *tun_info; const struct ip_tunnel_key *key; @@ -1246,6 +1244,7 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) fl6.flowi6_proto = IPPROTO_IPIP; fl6.daddr = key->u.ipv6.dst; fl6.flowlabel = key->label; + dsfield = ip6_tclass(key->label); } else { if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) encap_limit = t->parms.encap_limit; @@ -1254,8 +1253,9 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) fl6.flowi6_proto = IPPROTO_IPIP; if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) - fl6.flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT) -& IPV6_TCLASS_MASK; + dsfield = ipv4_get_dsfield(iph); + else + dsfield = ip6_tclass(t->parms.flowinfo); if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK) fl6.flowi6_mark = skb->mark; else @@ -1267,6 +1267,8 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6)) return -1; + dsfield = INET_ECN_encapsulate(dsfield, ipv4_get_dsfield(iph)); + skb_s
Re: [PATCH net] ip6_tunnel, ip6_gre: fix setting of DSCP on encapsulated packets
On Thu, 25 May 2017 15:49:14 -0400 (EDT) David Miller <da...@davemloft.net> wrote: > Still not correct, you need to use a "Fixes: " tag of the form: > > Fixes: 90427ef5d2a4 ("ipv6: fix flow labels when the traffic class is non-0") > > And it must appear of the first line of tags, before signoffs and acks, > with no empty lines in between. Here is my proposed commit message in full. Note that the "Fixes" line extends to 78 chars. Is this OK? Thanks This fix addresses two problems in the way the DSCP field is formulated on the encapsulating header of IPv6 tunnels. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=195661 1) The IPv6 tunneling code was manipulating the DSCP field of the encapsulating packet using the 32b flowlabel. Since the flowlabel is only the lower 20b it was incorrect to assume that the upper 12b containing the DSCP and ECN fields would remain intact when formulating the encapsulating header. This fix handles the 'inherit' and 'fixed-value' DSCP cases explicitly using the extant dsfield u8 variable. 2) The use of INET_ECN_encapsulate(0, dsfield) in ip6_tnl_xmit was incorrect and resulted in the DSCP value always being set to 0. Commit 90427ef5d2a4 caused the regression by masking out the flowlabel which exposed the incorrect the handling of the DSCP portion of the flowlabel in ip6_tunnel and ip6_gre. Fixes: 90427ef5d2a4 ("ipv6: fix flow labels when the traffic class is non-0") Signed-off-by: Peter Dawson <peter.a.daw...@boeing.com>
Re: [PATCH net] ip6_tunnel, ip6_gre: fix setting of DSCP on encapsulated packets
On Thu, 25 May 2017 15:49:14 -0400 (EDT) David Miller wrote: > Still not correct, you need to use a "Fixes: " tag of the form: > > Fixes: 90427ef5d2a4 ("ipv6: fix flow labels when the traffic class is non-0") > > And it must appear of the first line of tags, before signoffs and acks, > with no empty lines in between. Here is my proposed commit message in full. Note that the "Fixes" line extends to 78 chars. Is this OK? Thanks This fix addresses two problems in the way the DSCP field is formulated on the encapsulating header of IPv6 tunnels. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=195661 1) The IPv6 tunneling code was manipulating the DSCP field of the encapsulating packet using the 32b flowlabel. Since the flowlabel is only the lower 20b it was incorrect to assume that the upper 12b containing the DSCP and ECN fields would remain intact when formulating the encapsulating header. This fix handles the 'inherit' and 'fixed-value' DSCP cases explicitly using the extant dsfield u8 variable. 2) The use of INET_ECN_encapsulate(0, dsfield) in ip6_tnl_xmit was incorrect and resulted in the DSCP value always being set to 0. Commit 90427ef5d2a4 caused the regression by masking out the flowlabel which exposed the incorrect the handling of the DSCP portion of the flowlabel in ip6_tunnel and ip6_gre. Fixes: 90427ef5d2a4 ("ipv6: fix flow labels when the traffic class is non-0") Signed-off-by: Peter Dawson
Re: [PATCH net] ip6_tunnel, ip6_gre: fix setting of DSCP on encapsulated packets
On Thu, 25 May 2017 12:11:17 -0400 (EDT) David Millerwrote: > > Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=195661 > > This is not the correct way to use the Fixes: tag. > > You should specify the commit that introduced the regression > between 4.9.x and 4.10.x, and that you are fixing here. Thanks for your review Dave. I'll resubmit the patch with the following detail and just reference the bugzilla in the main body of the commit comment. Commit 90427ef5d2a4 ("ipv6: fix flow labels when the traffic class is non-0") caused the regression by masking out the flowlabel which exposed the incorrect the handling of the DSCP portion of the flowlabel in ip6_tunnel and ip6_gre.
Re: [PATCH net] ip6_tunnel, ip6_gre: fix setting of DSCP on encapsulated packets
On Thu, 25 May 2017 12:11:17 -0400 (EDT) David Miller wrote: > > Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=195661 > > This is not the correct way to use the Fixes: tag. > > You should specify the commit that introduced the regression > between 4.9.x and 4.10.x, and that you are fixing here. Thanks for your review Dave. I'll resubmit the patch with the following detail and just reference the bugzilla in the main body of the commit comment. Commit 90427ef5d2a4 ("ipv6: fix flow labels when the traffic class is non-0") caused the regression by masking out the flowlabel which exposed the incorrect the handling of the DSCP portion of the flowlabel in ip6_tunnel and ip6_gre.
[PATCH net] ip6_tunnel, ip6_gre: fix setting of DSCP on encapsulated packets
This fix addresses two problems in the way the DSCP field is formulated on the encapsulating header of IPv6 tunnels. 1) The IPv6 tunneling code was manipulating the DSCP field of the encapsulating packet using the 32b flowlabel. Since the flowlabel is only the lower 20b it was incorrect to assume that the upper 12b containing the DSCP and ECN fields would remain intact when formulating the encapsulating header. This fix handles the 'inherit' and 'fixed-value' DSCP cases explicitly using the extant dsfield u8 variable. 2) The use of INET_ECN_encapsulate(0, dsfield) in ip6_tnl_xmit was incorrect and resulted in the DSCP value always being set to 0. Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=195661 Signed-off-by: Peter Dawson <peter.a.daw...@boeing.com> --- net/ipv6/ip6_gre.c| 13 +++-- net/ipv6/ip6_tunnel.c | 21 + 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 8d128ba..0c5b4caa 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -537,11 +537,10 @@ static inline int ip6gre_xmit_ipv4(struct sk_buff *skb, struct net_device *dev) memcpy(, >fl.u.ip6, sizeof(fl6)); - dsfield = ipv4_get_dsfield(iph); - if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) - fl6.flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT) - & IPV6_TCLASS_MASK; + dsfield = ipv4_get_dsfield(iph); + else + dsfield = ip6_tclass(t->parms.flowinfo); if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK) fl6.flowi6_mark = skb->mark; else @@ -598,9 +597,11 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device *dev) memcpy(, >fl.u.ip6, sizeof(fl6)); - dsfield = ipv6_get_dsfield(ipv6h); if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) - fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_TCLASS_MASK); + dsfield = ipv6_get_dsfield(ipv6h); + else + dsfield = ip6_tclass(t->parms.flowinfo); + if (t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL) fl6.flowlabel |= ip6_flowlabel(ipv6h); if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK) diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 6eb2ae5..7ae6c50 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -1196,7 +1196,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, skb_push(skb, sizeof(struct ipv6hdr)); skb_reset_network_header(skb); ipv6h = ipv6_hdr(skb); - ip6_flow_hdr(ipv6h, INET_ECN_encapsulate(0, dsfield), + ip6_flow_hdr(ipv6h, dsfield, ip6_make_flowlabel(net, skb, fl6->flowlabel, true, fl6)); ipv6h->hop_limit = hop_limit; ipv6h->nexthdr = proto; @@ -1231,8 +1231,6 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) if (tproto != IPPROTO_IPIP && tproto != 0) return -1; - dsfield = ipv4_get_dsfield(iph); - if (t->parms.collect_md) { struct ip_tunnel_info *tun_info; const struct ip_tunnel_key *key; @@ -1246,6 +1244,7 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) fl6.flowi6_proto = IPPROTO_IPIP; fl6.daddr = key->u.ipv6.dst; fl6.flowlabel = key->label; + dsfield = ip6_tclass(key->label); } else { if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) encap_limit = t->parms.encap_limit; @@ -1254,8 +1253,9 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) fl6.flowi6_proto = IPPROTO_IPIP; if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) - fl6.flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT) -& IPV6_TCLASS_MASK; + dsfield = ipv4_get_dsfield(iph); + else + dsfield = ip6_tclass(t->parms.flowinfo); if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK) fl6.flowi6_mark = skb->mark; else @@ -1267,6 +1267,8 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6)) return -1; + dsfield = INET_ECN_encapsulate(dsfield, ipv4_get_dsfield(iph)); + skb_set_inner_ipproto(skb, IPPROTO_IPIP); err = ip6_tnl_xmit(skb, dev, dsfield, , encap_limit, , @@ -1300,8 +1302,6 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) ip6_tnl_addr_conflict(t, ipv6h)) return -1; - dsfield = ipv6_get_dsfield(ipv6h);
[PATCH net] ip6_tunnel, ip6_gre: fix setting of DSCP on encapsulated packets
This fix addresses two problems in the way the DSCP field is formulated on the encapsulating header of IPv6 tunnels. 1) The IPv6 tunneling code was manipulating the DSCP field of the encapsulating packet using the 32b flowlabel. Since the flowlabel is only the lower 20b it was incorrect to assume that the upper 12b containing the DSCP and ECN fields would remain intact when formulating the encapsulating header. This fix handles the 'inherit' and 'fixed-value' DSCP cases explicitly using the extant dsfield u8 variable. 2) The use of INET_ECN_encapsulate(0, dsfield) in ip6_tnl_xmit was incorrect and resulted in the DSCP value always being set to 0. Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=195661 Signed-off-by: Peter Dawson --- net/ipv6/ip6_gre.c| 13 +++-- net/ipv6/ip6_tunnel.c | 21 + 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 8d128ba..0c5b4caa 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -537,11 +537,10 @@ static inline int ip6gre_xmit_ipv4(struct sk_buff *skb, struct net_device *dev) memcpy(, >fl.u.ip6, sizeof(fl6)); - dsfield = ipv4_get_dsfield(iph); - if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) - fl6.flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT) - & IPV6_TCLASS_MASK; + dsfield = ipv4_get_dsfield(iph); + else + dsfield = ip6_tclass(t->parms.flowinfo); if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK) fl6.flowi6_mark = skb->mark; else @@ -598,9 +597,11 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device *dev) memcpy(, >fl.u.ip6, sizeof(fl6)); - dsfield = ipv6_get_dsfield(ipv6h); if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) - fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_TCLASS_MASK); + dsfield = ipv6_get_dsfield(ipv6h); + else + dsfield = ip6_tclass(t->parms.flowinfo); + if (t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL) fl6.flowlabel |= ip6_flowlabel(ipv6h); if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK) diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 6eb2ae5..7ae6c50 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -1196,7 +1196,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, skb_push(skb, sizeof(struct ipv6hdr)); skb_reset_network_header(skb); ipv6h = ipv6_hdr(skb); - ip6_flow_hdr(ipv6h, INET_ECN_encapsulate(0, dsfield), + ip6_flow_hdr(ipv6h, dsfield, ip6_make_flowlabel(net, skb, fl6->flowlabel, true, fl6)); ipv6h->hop_limit = hop_limit; ipv6h->nexthdr = proto; @@ -1231,8 +1231,6 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) if (tproto != IPPROTO_IPIP && tproto != 0) return -1; - dsfield = ipv4_get_dsfield(iph); - if (t->parms.collect_md) { struct ip_tunnel_info *tun_info; const struct ip_tunnel_key *key; @@ -1246,6 +1244,7 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) fl6.flowi6_proto = IPPROTO_IPIP; fl6.daddr = key->u.ipv6.dst; fl6.flowlabel = key->label; + dsfield = ip6_tclass(key->label); } else { if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) encap_limit = t->parms.encap_limit; @@ -1254,8 +1253,9 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) fl6.flowi6_proto = IPPROTO_IPIP; if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) - fl6.flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT) -& IPV6_TCLASS_MASK; + dsfield = ipv4_get_dsfield(iph); + else + dsfield = ip6_tclass(t->parms.flowinfo); if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK) fl6.flowi6_mark = skb->mark; else @@ -1267,6 +1267,8 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6)) return -1; + dsfield = INET_ECN_encapsulate(dsfield, ipv4_get_dsfield(iph)); + skb_set_inner_ipproto(skb, IPPROTO_IPIP); err = ip6_tnl_xmit(skb, dev, dsfield, , encap_limit, , @@ -1300,8 +1302,6 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) ip6_tnl_addr_conflict(t, ipv6h)) return -1; - dsfield = ipv6_get_dsfield(ipv6h); - if (t->parms.collect