__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)
case OVS_ACTION_ATTR_OUTPUT:
if (nla_get_u32(a) >= DP_MAX_PORTS)
return -EINVAL;
- out_tnl_port = false;
break;
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.
*/
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:
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);
}
__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;
}
#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;
}