aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJarno Rajahalme <jarno.rajahalme@nsn.com>2013-03-25 21:03:38 +0200
committerJesse Gross <jesse@nicira.com>2013-03-26 18:26:57 -0700
commit32664c36ab505b219baea847f5430b7a86f80d0a (patch)
treed97a1bd3659d34ba0536ab4e3f511a0e139ecbb5
parentbe8b93b0bcfdd91a34f6aee575cd608d9c2bff9e (diff)
datapath: Fix IP ID setting.
Eliminate the extra call to ip_select_ident(), and place the __ip_select_ident() call where the ip_select_ident() call was. This fixes two problems: Before, the call to ip_select_ident() did always zero out the value set earlier by __ip_select_ident(). Also, when __ip_select_ident() was called before setting the iph->daddr, ident calculation was possibly based on uninitialized data (but as the result was masked by the later call to ip_select_ident() it was not visible). Signed-off-by: Jarno Rajahalme <jarno.rajahalme@nsn.com> Signed-off-by: Jesse Gross <jesse@nicira.com>
-rw-r--r--datapath/tunnel.c19
1 files changed, 9 insertions, 10 deletions
diff --git a/datapath/tunnel.c b/datapath/tunnel.c
index 1003bc70..34e02109 100644
--- a/datapath/tunnel.c
+++ b/datapath/tunnel.c
@@ -280,15 +280,6 @@ int ovs_tnl_send(struct vport *vport, struct sk_buff *skb)
/* Push Tunnel header. */
tnl_vport->tnl_ops->build_header(vport, skb, tunnel_hlen);
- /*
- * Allow our local IP stack to fragment the outer packet even
- * if the DF bit is set as a last resort. We also need to
- * force selection of an IP ID here because Linux will
- * otherwise leave it at 0 if the packet originally had DF set.
- */
- skb->local_df = 1;
- __ip_select_ident(ip_hdr(skb), skb_dst(skb), 0);
-
/* Push IP header. */
iph = ip_hdr(skb);
iph->version = 4;
@@ -300,7 +291,15 @@ int ovs_tnl_send(struct vport *vport, struct sk_buff *skb)
iph->ttl = OVS_CB(skb)->tun_key->ipv4_ttl;
iph->frag_off = OVS_CB(skb)->tun_key->tun_flags &
OVS_TNL_F_DONT_FRAGMENT ? htons(IP_DF) : 0;
- ip_select_ident(iph, &rt_dst(rt), NULL);
+ /*
+ * Allow our local IP stack to fragment the outer packet even
+ * if the DF bit is set as a last resort. We also need to
+ * force selection of an IP ID here with __ip_select_ident(),
+ * as ip_select_ident() assumes a proper ID is not needed when
+ * when the DF bit is set.
+ */
+ skb->local_df = 1;
+ __ip_select_ident(iph, skb_dst(skb), 0);
memset(IPCB(skb), 0, sizeof(*IPCB(skb)));