Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
[linux-2.6-microblaze.git] / net / sched / act_mpls.c
index e298ec3..f40bf97 100644 (file)
@@ -87,6 +87,23 @@ static int tcf_mpls_act(struct sk_buff *skb, const struct tc_action *a,
                                  skb->dev && skb->dev->type == ARPHRD_ETHER))
                        goto drop;
                break;
+       case TCA_MPLS_ACT_MAC_PUSH:
+               if (skb_vlan_tag_present(skb)) {
+                       if (__vlan_insert_inner_tag(skb, skb->vlan_proto,
+                                                   skb_vlan_tag_get(skb),
+                                                   ETH_HLEN) < 0)
+                               goto drop;
+
+                       skb->protocol = skb->vlan_proto;
+                       __vlan_hwaccel_clear_tag(skb);
+               }
+
+               new_lse = tcf_mpls_get_lse(NULL, p, mac_len ||
+                                          !eth_p_mpls(skb->protocol));
+
+               if (skb_mpls_push(skb, new_lse, p->tcfm_proto, 0, false))
+                       goto drop;
+               break;
        case TCA_MPLS_ACT_MODIFY:
                new_lse = tcf_mpls_get_lse(mpls_hdr(skb), p, false);
                if (skb_mpls_update_lse(skb, new_lse))
@@ -188,6 +205,7 @@ static int tcf_mpls_init(struct net *net, struct nlattr *nla,
                }
                break;
        case TCA_MPLS_ACT_PUSH:
+       case TCA_MPLS_ACT_MAC_PUSH:
                if (!tb[TCA_MPLS_LABEL]) {
                        NL_SET_ERR_MSG_MOD(extack, "Label is required for MPLS push");
                        return -EINVAL;