* [PATCH] ip6_tunnel, ip6_gre: fix setting of DSCP on encapsulated packets
@ 2017-05-18 1:11 I-Dawson, Peter A
2017-05-18 1:18 ` Stephen Hemminger
0 siblings, 1 reply; 3+ messages in thread
From: I-Dawson, Peter A @ 2017-05-18 1:11 UTC (permalink / raw)
To: netdev@vger.kernel.org
This fix addresses two problems in the way the DSCP field is formulated on the
encapsulating header of IPv6 tunnels.
This fix addresses Bug 195661. 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.
---
net/ipv6/ip6_gre.c | 18 ++++++++++--------
net/ipv6/ip6_tunnel.c | 28 +++++++++++++++++-----------
2 files changed, 27 insertions(+), 19 deletions(-)
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 8d128ba..42f51fe 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -537,11 +537,11 @@ static inline int ip6gre_xmit_ipv4(struct sk_buff *skb, struct net_device *dev)
memcpy(&fl6, &t->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;
+ if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) {
+ 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 +598,11 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device *dev)
memcpy(&fl6, &t->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);
+ if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) {
+ 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..4d45195 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1196,8 +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_make_flowlabel(net, skb, fl6->flowlabel, true, fl6));
+ ip6_flow_hdr(ipv6h, dsfield, ip6_make_flowlabel(net, skb, fl6->flowlabel, true, fl6));
ipv6h->hop_limit = hop_limit;
ipv6h->nexthdr = proto;
ipv6h->saddr = fl6->saddr;
@@ -1231,8 +1230,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 +1243,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;
@@ -1253,9 +1251,11 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6));
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;
+ if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) {
+ 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, &fl6, encap_limit, &mtu,
@@ -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_md) {
struct ip_tunnel_info *tun_info;
const struct ip_tunnel_key *key;
@@ -1315,6 +1315,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
fl6.flowi6_proto = IPPROTO_IPV6;
fl6.daddr = key->u.ipv6.dst;
fl6.flowlabel = key->label;
+ dsfield = ip6_tclass(key->label);
} else {
offset = ip6_tnl_parse_tlv_enc_lim(skb, skb_network_header(skb));
/* ip6_tnl_parse_tlv_enc_lim() might have reallocated skb->head */
@@ -1336,8 +1337,11 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6));
fl6.flowi6_proto = IPPROTO_IPV6;
- if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)
- fl6.flowlabel |= (*(__be32 *)ipv6h & IPV6_TCLASS_MASK);
+ if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) {
+ 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)
@@ -1351,6 +1355,8 @@ ip6ip6_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, ipv6_get_dsfield(ipv6h));
+
skb_set_inner_ipproto(skb, IPPROTO_IPV6);
err = ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu,
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH] ip6_tunnel, ip6_gre: fix setting of DSCP on encapsulated packets
2017-05-18 1:11 [PATCH] ip6_tunnel, ip6_gre: fix setting of DSCP on encapsulated packets I-Dawson, Peter A
@ 2017-05-18 1:18 ` Stephen Hemminger
[not found] ` <579256095bc540bab2668f55a6a2c25b@XCH15-07-02.nw.nos.boeing.com>
0 siblings, 1 reply; 3+ messages in thread
From: Stephen Hemminger @ 2017-05-18 1:18 UTC (permalink / raw)
To: I-Dawson, Peter A; +Cc: netdev@vger.kernel.org
On Thu, 18 May 2017 01:11:01 +0000
"I-Dawson, Peter A" <Peter.A.Dawson@boeing.com> wrote:
> This fix addresses two problems in the way the DSCP field is formulated on the
> encapsulating header of IPv6 tunnels.
> This fix addresses Bug 195661. 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.
> ---
> net/ipv6/ip6_gre.c | 18 ++++++++++--------
> net/ipv6/ip6_tunnel.c | 28 +++++++++++++++++-----------
> 2 files changed, 27 insertions(+), 19 deletions(-)
This patch looks correct, but has trivial style issues like using spaces
instead of tabs and other junk. Please run checkpatch.pl, look at the
results and resubmit.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2017-05-18 2:49 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-05-18 1:11 [PATCH] ip6_tunnel, ip6_gre: fix setting of DSCP on encapsulated packets I-Dawson, Peter A
2017-05-18 1:18 ` Stephen Hemminger
[not found] ` <579256095bc540bab2668f55a6a2c25b@XCH15-07-02.nw.nos.boeing.com>
2017-05-18 2:49 ` Peter Dawson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).