]> git.proxmox.com Git - mirror_ovs.git/commitdiff
datapath: Fix MPLS action validation.
authorPravin B Shelar <pshelar@nicira.com>
Fri, 19 Dec 2014 09:55:45 +0000 (01:55 -0800)
committerPravin B Shelar <pshelar@nicira.com>
Fri, 19 Dec 2014 20:27:38 +0000 (12:27 -0800)
Linux stack do not allow GSO for packet with multiple
encapsulations.  Therefore there was check in MPLS action
validation to detect such case, But it is better to add
such check at run time to detect such cases.
Removing this check also fixes bug in action copy to no skip
multiple set actions.

Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Reported-by: Srinivas Neginhal <sneginha@vmware.com>
Acked-by: Jarno Rajahalme <jrajahalme@nicira.com>
Bug #1367702

datapath/flow_netlink.c
datapath/linux/compat/include/net/gre.h
datapath/linux/compat/include/net/vxlan.h
datapath/vport-lisp.c

index 4aae3056b7567bb8a78f9b763b92cf414c7dd991..c611e71a7401d9e2149772348575ed33f0a5b110 100644 (file)
@@ -1764,7 +1764,6 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr,
                                  __be16 eth_type, __be16 vlan_tci, bool log)
 {
        const struct nlattr *a;
-       bool out_tnl_port = false;
        int rem, err;
 
        if (depth >= SAMPLE_ACTION_DEPTH)
@@ -1807,7 +1806,6 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr,
                case OVS_ACTION_ATTR_OUTPUT:
                        if (nla_get_u32(a) >= DP_MAX_PORTS)
                                return -EINVAL;
-                       out_tnl_port = false;
 
                        break;
 
@@ -1843,14 +1841,9 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr,
                case OVS_ACTION_ATTR_PUSH_MPLS: {
                        const struct ovs_action_push_mpls *mpls = nla_data(a);
 
-                       /* Networking stack do not allow simultaneous Tunnel
-                        * and MPLS GSO.
-                        */
-                       if (out_tnl_port)
-                               return -EINVAL;
-
                        if (!eth_p_mpls(mpls->mpls_ethertype))
                                return -EINVAL;
+
                        /* Prohibit push MPLS other than to a white list
                         * for packets that have a known tag order.
                         */
@@ -1884,11 +1877,9 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr,
 
                case OVS_ACTION_ATTR_SET:
                        err = validate_set(a, key, sfa,
-                                          &out_tnl_port, eth_type, log);
+                                          &skip_copy, eth_type, log);
                        if (err)
                                return err;
-
-                       skip_copy = out_tnl_port;
                        break;
 
                case OVS_ACTION_ATTR_SAMPLE:
index b4bf2f150e32c8811b428196edbc859232a658b1..494702effe89188715f1f20f6f1b18a43a53e307 100644 (file)
@@ -107,7 +107,8 @@ static inline int ip_gre_calc_hlen(__be16 o_flags)
 static inline struct sk_buff *rpl_gre_handle_offloads(struct sk_buff *skb,
                                                  bool gre_csum)
 {
-       if (skb->encapsulation && skb_is_gso(skb)) {
+       if ((ovs_skb_get_inner_protocol(skb) || skb->encapsulation) &&
+           skb_is_gso(skb)) {
                kfree_skb(skb);
                return ERR_PTR(-ENOSYS);
        }
index 099d8241c182641da26c54d0c22e1e9f363fb1ac..84afe53f34315f7729f139020b7d9c326109c31f 100644 (file)
@@ -15,7 +15,8 @@ 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 (skb->encapsulation && skb_is_gso(skb)) {
+       if ((ovs_skb_get_inner_protocol(skb) || skb->encapsulation) &&
+            skb_is_gso(skb)) {
                kfree_skb(skb);
                return -ENOSYS;
        }
index f3d450f5e18d812595f0bcf0779fd90da33c9129..1eaeddb0e9fb30cc986653cefbaee4e9dff44f20 100644 (file)
@@ -417,7 +417,8 @@ static int handle_offloads(struct sk_buff *skb)
 #else
 static int handle_offloads(struct sk_buff *skb)
 {
-       if (skb->encapsulation && skb_is_gso(skb)) {
+       if ((ovs_skb_get_inner_protocol(skb) || skb->encapsulation) &&
+           skb_is_gso(skb)) {
                kfree_skb(skb);
                return -ENOSYS;
        }