datapath: net: add ETH_P_802_3_MIN
[sliver-openvswitch.git] / datapath / tunnel.c
index 87f212a..057aaed 100644 (file)
@@ -65,7 +65,7 @@ void ovs_tnl_rcv(struct vport *vport, struct sk_buff *skb)
        skb_reset_mac_header(skb);
        eh = eth_hdr(skb);
 
-       if (likely(ntohs(eh->h_proto) >= 1536))
+       if (likely(ntohs(eh->h_proto) >= ETH_P_802_3_MIN))
                skb->protocol = eh->h_proto;
        else
                skb->protocol = htons(ETH_P_802_2);
@@ -221,7 +221,6 @@ u16 ovs_tnl_get_src_port(struct sk_buff *skb)
 int ovs_tnl_send(struct vport *vport, struct sk_buff *skb)
 {
        struct tnl_vport *tnl_vport = tnl_vport_priv(vport);
-       enum vport_err_type err = VPORT_E_TX_ERROR;
        struct rtable *rt;
        __be32 saddr;
        int sent_len = 0;
@@ -261,6 +260,7 @@ int ovs_tnl_send(struct vport *vport, struct sk_buff *skb)
                struct sk_buff *next_skb = skb->next;
                struct iphdr *iph;
                int frag_len;
+               int err;
 
                skb->next = NULL;
 
@@ -291,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)));
 
@@ -314,7 +322,7 @@ err_free_rt:
        ip_rt_put(rt);
 error_free:
        kfree_skb(skb);
-       ovs_vport_record_error(vport, err);
+       ovs_vport_record_error(vport, VPORT_E_TX_ERROR);
        return sent_len;
 }