From: Jarno Rajahalme Date: Mon, 25 Mar 2013 19:03:38 +0000 (+0200) Subject: datapath: Fix IP ID setting. X-Git-Tag: sliver-openvswitch-1.10.90-1~10^2~31 X-Git-Url: http://git.onelab.eu/?p=sliver-openvswitch.git;a=commitdiff_plain;h=0e4c4682f4058e9f51e980ee8c138756a32da45f 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 Signed-off-by: Jesse Gross --- diff --git a/datapath/tunnel.c b/datapath/tunnel.c index 8d5a6d47c..fca016c64 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)));