| @@ -47,6 +47,8 @@ static int tcf_skbedit(struct sk_buff *skb, const struct tc_action *a, · 46 unmodified lines |
| 47 | 47 | skb_set_queue_mapping(skb, d->queue_mapping); |
| 48 | 48 | if (d->flags & SKBEDIT_F_MARK) |
| 49 | 49 | skb->mark = d->mark; |
| 50 | + if (d->flags & SKBEDIT_F_PTYPE) |
| 51 | + skb->pkt_type = d->ptype; |
| 50 | 52 | |
| 51 | 53 | spin_unlock(&d->tcf_lock); |
| 52 | 54 | return d->tcf_action; |
| @@ -57,6 +59,7 @@ static const struct nla_policy skbedit_policy[TCA_SKBEDIT_MAX + 1] = { · 4 unmodified lines |
| 57 | 59 | [TCA_SKBEDIT_PRIORITY] = { .len = sizeof(u32) }, |
| 58 | 60 | [TCA_SKBEDIT_QUEUE_MAPPING] = { .len = sizeof(u16) }, |
| 59 | 61 | [TCA_SKBEDIT_MARK] = { .len = sizeof(u32) }, |
| 62 | + [TCA_SKBEDIT_PTYPE] = { .len = sizeof(u16) }, |
| 60 | 63 | }; |
| 61 | 64 | |
| 62 | 65 | static int tcf_skbedit_init(struct net *net, struct nlattr *nla, |
| @@ -68,7 +71,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, · 5 unmodified lines |
| 68 | 71 | struct tc_skbedit *parm; |
| 69 | 72 | struct tcf_skbedit *d; |
| 70 | 73 | u32 flags = 0, *priority = NULL, *mark = NULL; |
| 71 | | − u16 *queue_mapping = NULL; |
| 74 | + u16 *queue_mapping = NULL, *ptype = NULL; |
| 72 | 75 | bool exists = false; |
| 73 | 76 | int ret = 0, err; |
| 74 | 77 | |
| @@ -92,6 +95,13 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, · 17 unmodified lines |
| 92 | 95 | queue_mapping = nla_data(tb[TCA_SKBEDIT_QUEUE_MAPPING]); |
| 93 | 96 | } |
| 94 | 97 | |
| 98 | + if (tb[TCA_SKBEDIT_PTYPE] != NULL) { |
| 99 | + ptype = nla_data(tb[TCA_SKBEDIT_PTYPE]); |
| 100 | + if (!skb_pkt_type_ok(*ptype)) |
| 101 | + return -EINVAL; |
| 102 | + flags |= SKBEDIT_F_PTYPE; |
| 103 | + } |
| 104 | + |
| 95 | 105 | if (tb[TCA_SKBEDIT_MARK] != NULL) { |
| 96 | 106 | flags |= SKBEDIT_F_MARK; |
| 97 | 107 | mark = nla_data(tb[TCA_SKBEDIT_MARK]); |
| @@ -132,6 +142,8 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, · 34 unmodified lines |
| 132 | 142 | d->queue_mapping = *queue_mapping; |
| 133 | 143 | if (flags & SKBEDIT_F_MARK) |
| 134 | 144 | d->mark = *mark; |
| 145 | + if (flags & SKBEDIT_F_PTYPE) |
| 146 | + d->ptype = *ptype; |
| 135 | 147 | |
| 136 | 148 | d->tcf_action = parm->action; |
| 137 | 149 | |
| @@ -169,6 +181,10 @@ static int tcf_skbedit_dump(struct sk_buff *skb, struct tc_action *a, · 31 unmodified lines |
| 169 | 181 | nla_put(skb, TCA_SKBEDIT_MARK, sizeof(d->mark), |
| 170 | 182 | &d->mark)) |
| 171 | 183 | goto nla_put_failure; |
| 184 | + if ((d->flags & SKBEDIT_F_PTYPE) && |
| 185 | + nla_put(skb, TCA_SKBEDIT_PTYPE, sizeof(d->ptype), |
| 186 | + &d->ptype)) |
| 187 | + goto nla_put_failure; |
| 172 | 188 | |
| 173 | 189 | tcf_tm_dump(&t, &d->tcf_tm); |
| 174 | 190 | if (nla_put_64bit(skb, TCA_SKBEDIT_TM, sizeof(t), &t, TCA_SKBEDIT_PAD)) |