FLOW_ACTION_SAMPLE,
        FLOW_ACTION_POLICE,
        FLOW_ACTION_CT,
+       FLOW_ACTION_MPLS_PUSH,
+       FLOW_ACTION_MPLS_POP,
+       FLOW_ACTION_MPLS_MANGLE,
 };
 
 /* This is mirroring enum pedit_header_type definition for easy mapping between
                        int action;
                        u16 zone;
                } ct;
+               struct {                                /* FLOW_ACTION_MPLS_PUSH */
+                       u32             label;
+                       __be16          proto;
+                       u8              tc;
+                       u8              bos;
+                       u8              ttl;
+               } mpls_push;
+               struct {                                /* FLOW_ACTION_MPLS_POP */
+                       __be16          proto;
+               } mpls_pop;
+               struct {                                /* FLOW_ACTION_MPLS_MANGLE */
+                       u32             label;
+                       u8              tc;
+                       u8              bos;
+                       u8              ttl;
+               } mpls_mangle;
        };
 };
 
 
 };
 #define to_mpls(a) ((struct tcf_mpls *)a)
 
+static inline bool is_tcf_mpls(const struct tc_action *a)
+{
+#ifdef CONFIG_NET_CLS_ACT
+       if (a->ops && a->ops->id == TCA_ID_MPLS)
+               return true;
+#endif
+       return false;
+}
+
+static inline u32 tcf_mpls_action(const struct tc_action *a)
+{
+       u32 tcfm_action;
+
+       rcu_read_lock();
+       tcfm_action = rcu_dereference(to_mpls(a)->mpls_p)->tcfm_action;
+       rcu_read_unlock();
+
+       return tcfm_action;
+}
+
+static inline __be16 tcf_mpls_proto(const struct tc_action *a)
+{
+       __be16 tcfm_proto;
+
+       rcu_read_lock();
+       tcfm_proto = rcu_dereference(to_mpls(a)->mpls_p)->tcfm_proto;
+       rcu_read_unlock();
+
+       return tcfm_proto;
+}
+
+static inline u32 tcf_mpls_label(const struct tc_action *a)
+{
+       u32 tcfm_label;
+
+       rcu_read_lock();
+       tcfm_label = rcu_dereference(to_mpls(a)->mpls_p)->tcfm_label;
+       rcu_read_unlock();
+
+       return tcfm_label;
+}
+
+static inline u8 tcf_mpls_tc(const struct tc_action *a)
+{
+       u8 tcfm_tc;
+
+       rcu_read_lock();
+       tcfm_tc = rcu_dereference(to_mpls(a)->mpls_p)->tcfm_tc;
+       rcu_read_unlock();
+
+       return tcfm_tc;
+}
+
+static inline u8 tcf_mpls_bos(const struct tc_action *a)
+{
+       u8 tcfm_bos;
+
+       rcu_read_lock();
+       tcfm_bos = rcu_dereference(to_mpls(a)->mpls_p)->tcfm_bos;
+       rcu_read_unlock();
+
+       return tcfm_bos;
+}
+
+static inline u8 tcf_mpls_ttl(const struct tc_action *a)
+{
+       u8 tcfm_ttl;
+
+       rcu_read_lock();
+       tcfm_ttl = rcu_dereference(to_mpls(a)->mpls_p)->tcfm_ttl;
+       rcu_read_unlock();
+
+       return tcfm_ttl;
+}
+
 #endif /* __NET_TC_MPLS_H */
 
 #include <net/tc_act/tc_sample.h>
 #include <net/tc_act/tc_skbedit.h>
 #include <net/tc_act/tc_ct.h>
+#include <net/tc_act/tc_mpls.h>
 
 extern const struct nla_policy rtm_tca_policy[TCA_MAX + 1];
 
                        entry->id = FLOW_ACTION_CT;
                        entry->ct.action = tcf_ct_action(act);
                        entry->ct.zone = tcf_ct_zone(act);
+               } else if (is_tcf_mpls(act)) {
+                       switch (tcf_mpls_action(act)) {
+                       case TCA_MPLS_ACT_PUSH:
+                               entry->id = FLOW_ACTION_MPLS_PUSH;
+                               entry->mpls_push.proto = tcf_mpls_proto(act);
+                               entry->mpls_push.label = tcf_mpls_label(act);
+                               entry->mpls_push.tc = tcf_mpls_tc(act);
+                               entry->mpls_push.bos = tcf_mpls_bos(act);
+                               entry->mpls_push.ttl = tcf_mpls_ttl(act);
+                               break;
+                       case TCA_MPLS_ACT_POP:
+                               entry->id = FLOW_ACTION_MPLS_POP;
+                               entry->mpls_pop.proto = tcf_mpls_proto(act);
+                               break;
+                       case TCA_MPLS_ACT_MODIFY:
+                               entry->id = FLOW_ACTION_MPLS_MANGLE;
+                               entry->mpls_mangle.label = tcf_mpls_label(act);
+                               entry->mpls_mangle.tc = tcf_mpls_tc(act);
+                               entry->mpls_mangle.bos = tcf_mpls_bos(act);
+                               entry->mpls_mangle.ttl = tcf_mpls_ttl(act);
+                               break;
+                       default:
+                               goto err_out;
+                       }
                } else {
                        goto err_out;
                }