From: Pravin B Shelar Date: Fri, 19 Dec 2014 13:15:16 +0000 (-0800) Subject: datapath:compat: Fix build failure on old kernels. X-Git-Tag: v2.4.0~766 X-Git-Url: http://git.cascardo.eti.br/?p=cascardo%2Fovs.git;a=commitdiff_plain;h=15281870f986ccc5037dc2089b664b6d7b0eb522 datapath:compat: Fix build failure on old kernels. Reported by Travis. Signed-off-by: Pravin B Shelar --- diff --git a/datapath/linux/compat/gre.c b/datapath/linux/compat/gre.c index c7f255107..1cd885b6f 100644 --- a/datapath/linux/compat/gre.c +++ b/datapath/linux/compat/gre.c @@ -292,6 +292,11 @@ struct sk_buff *gre_handle_offloads(struct sk_buff *skb, bool gre_csum) skb_reset_inner_headers(skb); if (skb_is_gso(skb)) { + if (skb_is_encapsulated(skb)) { + err = -ENOSYS; + goto error; + } + if (gre_csum) OVS_GSO_CB(skb)->fix_segment = gre_csum_fix; else diff --git a/datapath/linux/compat/include/net/gre.h b/datapath/linux/compat/include/net/gre.h index 494702eff..af1d991c7 100644 --- a/datapath/linux/compat/include/net/gre.h +++ b/datapath/linux/compat/include/net/gre.h @@ -104,11 +104,11 @@ static inline int ip_gre_calc_hlen(__be16 o_flags) return addend; } #else + static inline struct sk_buff *rpl_gre_handle_offloads(struct sk_buff *skb, bool gre_csum) { - if ((ovs_skb_get_inner_protocol(skb) || skb->encapsulation) && - skb_is_gso(skb)) { + if (skb_is_gso(skb) && skb_is_encapsulated(skb)) { kfree_skb(skb); return ERR_PTR(-ENOSYS); } diff --git a/datapath/linux/compat/include/net/ip_tunnels.h b/datapath/linux/compat/include/net/ip_tunnels.h index d03be7564..8fb9527ef 100644 --- a/datapath/linux/compat/include/net/ip_tunnels.h +++ b/datapath/linux/compat/include/net/ip_tunnels.h @@ -75,4 +75,6 @@ int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto); #define TUNNEL_CRIT_OPT __cpu_to_be16(0x0400) #define TUNNEL_OPTIONS_PRESENT __cpu_to_be16(0x0800) +bool skb_is_encapsulated(struct sk_buff *skb); + #endif /* __NET_IP_TUNNELS_H */ diff --git a/datapath/linux/compat/include/net/vxlan.h b/datapath/linux/compat/include/net/vxlan.h index 84afe53f3..5fc4dea92 100644 --- a/datapath/linux/compat/include/net/vxlan.h +++ b/datapath/linux/compat/include/net/vxlan.h @@ -15,8 +15,7 @@ static inline int rpl_vxlan_xmit_skb(struct vxlan_sock *vs, __be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df, __be16 src_port, __be16 dst_port, __be32 vni) { - if ((ovs_skb_get_inner_protocol(skb) || skb->encapsulation) && - skb_is_gso(skb)) { + if (skb_is_gso(skb) && skb_is_encapsulated(skb)) { kfree_skb(skb); return -ENOSYS; } diff --git a/datapath/linux/compat/ip_tunnels_core.c b/datapath/linux/compat/ip_tunnels_core.c index 6cf38d04c..e71ba4e17 100644 --- a/datapath/linux/compat/ip_tunnels_core.c +++ b/datapath/linux/compat/ip_tunnels_core.c @@ -117,3 +117,12 @@ int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto) } #endif + +bool skb_is_encapsulated(struct sk_buff *skb) +{ + /* checking for inner protocol should be sufficient on newer kernel, but + * old kernel just set encapsulation bit. + */ + /* XXX: set inner protocol for all tunnel in OVS. */ + return ovs_skb_get_inner_protocol(skb) || skb_encapsulation(skb); +} diff --git a/datapath/linux/compat/vxlan.c b/datapath/linux/compat/vxlan.c index f13cc8957..ff040ac2f 100644 --- a/datapath/linux/compat/vxlan.c +++ b/datapath/linux/compat/vxlan.c @@ -169,6 +169,9 @@ static void vxlan_gso(struct sk_buff *skb) static int handle_offloads(struct sk_buff *skb) { if (skb_is_gso(skb)) { + if (skb_is_encapsulated(skb)) + return -ENOSYS; + OVS_GSO_CB(skb)->fix_segment = vxlan_gso; } else { if (skb->ip_summed != CHECKSUM_PARTIAL) diff --git a/datapath/vport-geneve.c b/datapath/vport-geneve.c index 7c085779a..200cc1469 100644 --- a/datapath/vport-geneve.c +++ b/datapath/vport-geneve.c @@ -326,22 +326,25 @@ static void geneve_fix_segment(struct sk_buff *skb) static int handle_offloads(struct sk_buff *skb) { - if (skb_is_gso(skb)) + if (skb_is_gso(skb)) { + if (skb_is_encapsulated(skb)) + return -ENOSYS; OVS_GSO_CB(skb)->fix_segment = geneve_fix_segment; - else if (skb->ip_summed != CHECKSUM_PARTIAL) + } else if (skb->ip_summed != CHECKSUM_PARTIAL) { skb->ip_summed = CHECKSUM_NONE; + } return 0; } #else static int handle_offloads(struct sk_buff *skb) { - if (skb->encapsulation && skb_is_gso(skb)) { - kfree_skb(skb); - return -ENOSYS; - } - if (skb_is_gso(skb)) { - int err = skb_unclone(skb, GFP_ATOMIC); + int err; + + if (skb_is_encapsulated(skb)) + return -ENOSYS; + + err = skb_unclone(skb, GFP_ATOMIC); if (unlikely(err)) return err; diff --git a/datapath/vport-lisp.c b/datapath/vport-lisp.c index 1eaeddb0e..a067e050c 100644 --- a/datapath/vport-lisp.c +++ b/datapath/vport-lisp.c @@ -408,23 +408,26 @@ static void lisp_fix_segment(struct sk_buff *skb) static int handle_offloads(struct sk_buff *skb) { - if (skb_is_gso(skb)) + if (skb_is_gso(skb)) { + if (skb_is_encapsulated(skb)) + return -ENOSYS; + OVS_GSO_CB(skb)->fix_segment = lisp_fix_segment; - else if (skb->ip_summed != CHECKSUM_PARTIAL) + } else if (skb->ip_summed != CHECKSUM_PARTIAL) { skb->ip_summed = CHECKSUM_NONE; + } return 0; } #else static int handle_offloads(struct sk_buff *skb) { - if ((ovs_skb_get_inner_protocol(skb) || skb->encapsulation) && - skb_is_gso(skb)) { - kfree_skb(skb); - return -ENOSYS; - } - if (skb_is_gso(skb)) { - int err = skb_unclone(skb, GFP_ATOMIC); + int err; + + if (skb_is_encapsulated(skb)) + return -ENOSYS; + + err = skb_unclone(skb, GFP_ATOMIC); if (unlikely(err)) return err;