Commit 08399efc authored by John W. Linville's avatar John W. Linville Committed by David S. Miller

geneve: ensure ECN info is handled properly in all tx/rx paths

Partially due to a pre-exising "thinko", the new metadata-based tx/rx
paths were handling ECN propagation differently than the traditional
tx/rx paths.  This patch removes the "thinko" (involving multiple
ip_hdr assignments) on the rx path and corrects the ECN handling on
both the rx and tx paths.
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
Reviewed-by: default avatarJesse Gross <jesse@nicira.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 29c68526
...@@ -126,6 +126,8 @@ static void geneve_rx(struct geneve_sock *gs, struct sk_buff *skb) ...@@ -126,6 +126,8 @@ static void geneve_rx(struct geneve_sock *gs, struct sk_buff *skb)
__be32 addr; __be32 addr;
int err; int err;
iph = ip_hdr(skb); /* outer IP header... */
if (gs->collect_md) { if (gs->collect_md) {
static u8 zero_vni[3]; static u8 zero_vni[3];
...@@ -133,7 +135,6 @@ static void geneve_rx(struct geneve_sock *gs, struct sk_buff *skb) ...@@ -133,7 +135,6 @@ static void geneve_rx(struct geneve_sock *gs, struct sk_buff *skb)
addr = 0; addr = 0;
} else { } else {
vni = gnvh->vni; vni = gnvh->vni;
iph = ip_hdr(skb); /* Still outer IP header... */
addr = iph->saddr; addr = iph->saddr;
} }
...@@ -178,7 +179,6 @@ static void geneve_rx(struct geneve_sock *gs, struct sk_buff *skb) ...@@ -178,7 +179,6 @@ static void geneve_rx(struct geneve_sock *gs, struct sk_buff *skb)
skb_reset_network_header(skb); skb_reset_network_header(skb);
iph = ip_hdr(skb); /* Now inner IP header... */
err = IP_ECN_decapsulate(iph, skb); err = IP_ECN_decapsulate(iph, skb);
if (unlikely(err)) { if (unlikely(err)) {
...@@ -626,6 +626,7 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -626,6 +626,7 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev)
struct geneve_sock *gs = geneve->sock; struct geneve_sock *gs = geneve->sock;
struct ip_tunnel_info *info = NULL; struct ip_tunnel_info *info = NULL;
struct rtable *rt = NULL; struct rtable *rt = NULL;
const struct iphdr *iip; /* interior IP header */
struct flowi4 fl4; struct flowi4 fl4;
__u8 tos, ttl; __u8 tos, ttl;
__be16 sport; __be16 sport;
...@@ -653,6 +654,8 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -653,6 +654,8 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev)
sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true); sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
skb_reset_mac_header(skb); skb_reset_mac_header(skb);
iip = ip_hdr(skb);
if (info) { if (info) {
const struct ip_tunnel_key *key = &info->key; const struct ip_tunnel_key *key = &info->key;
u8 *opts = NULL; u8 *opts = NULL;
...@@ -668,19 +671,16 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -668,19 +671,16 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev)
if (unlikely(err)) if (unlikely(err))
goto err; goto err;
tos = key->tos; tos = ip_tunnel_ecn_encap(key->tos, iip, skb);
ttl = key->ttl; ttl = key->ttl;
df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0; df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
} else { } else {
const struct iphdr *iip; /* interior IP header */
udp_csum = false; udp_csum = false;
err = geneve_build_skb(rt, skb, 0, geneve->vni, err = geneve_build_skb(rt, skb, 0, geneve->vni,
0, NULL, udp_csum); 0, NULL, udp_csum);
if (unlikely(err)) if (unlikely(err))
goto err; goto err;
iip = ip_hdr(skb);
tos = ip_tunnel_ecn_encap(fl4.flowi4_tos, iip, skb); tos = ip_tunnel_ecn_encap(fl4.flowi4_tos, iip, skb);
ttl = geneve->ttl; ttl = geneve->ttl;
if (!ttl && IN_MULTICAST(ntohl(fl4.daddr))) if (!ttl && IN_MULTICAST(ntohl(fl4.daddr)))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment