if (d->flags & SKBEDIT_F_QUEUE_MAPPING &&
            skb->dev->real_num_tx_queues > d->queue_mapping)
                skb_set_queue_mapping(skb, d->queue_mapping);
-       if (d->flags & SKBEDIT_F_MARK)
-               skb->mark = d->mark;
+       if (d->flags & SKBEDIT_F_MARK) {
+               skb->mark &= ~d->mask;
+               skb->mark |= d->mark & d->mask;
+       }
        if (d->flags & SKBEDIT_F_PTYPE)
                skb->pkt_type = d->ptype;
 
        [TCA_SKBEDIT_QUEUE_MAPPING]     = { .len = sizeof(u16) },
        [TCA_SKBEDIT_MARK]              = { .len = sizeof(u32) },
        [TCA_SKBEDIT_PTYPE]             = { .len = sizeof(u16) },
+       [TCA_SKBEDIT_MASK]              = { .len = sizeof(u32) },
 };
 
 static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
        struct nlattr *tb[TCA_SKBEDIT_MAX + 1];
        struct tc_skbedit *parm;
        struct tcf_skbedit *d;
-       u32 flags = 0, *priority = NULL, *mark = NULL;
+       u32 flags = 0, *priority = NULL, *mark = NULL, *mask = NULL;
        u16 *queue_mapping = NULL, *ptype = NULL;
        bool exists = false;
        int ret = 0, err;
                mark = nla_data(tb[TCA_SKBEDIT_MARK]);
        }
 
+       if (tb[TCA_SKBEDIT_MASK] != NULL) {
+               flags |= SKBEDIT_F_MASK;
+               mask = nla_data(tb[TCA_SKBEDIT_MASK]);
+       }
+
        parm = nla_data(tb[TCA_SKBEDIT_PARMS]);
 
        exists = tcf_hash_check(tn, parm->index, a, bind);
                d->mark = *mark;
        if (flags & SKBEDIT_F_PTYPE)
                d->ptype = *ptype;
+       /* default behaviour is to use all the bits */
+       d->mask = 0xffffffff;
+       if (flags & SKBEDIT_F_MASK)
+               d->mask = *mask;
 
        d->tcf_action = parm->action;
 
        if ((d->flags & SKBEDIT_F_PTYPE) &&
            nla_put_u16(skb, TCA_SKBEDIT_PTYPE, d->ptype))
                goto nla_put_failure;
+       if ((d->flags & SKBEDIT_F_MASK) &&
+           nla_put_u32(skb, TCA_SKBEDIT_MASK, d->mask))
+               goto nla_put_failure;
 
        tcf_tm_dump(&t, &d->tcf_tm);
        if (nla_put_64bit(skb, TCA_SKBEDIT_TM, sizeof(t), &t, TCA_SKBEDIT_PAD))