Blame view

net/sched/act_skbedit.c 10.2 KB
9952f6918   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
ca9b0e27e   Alexander Duyck   pkt_action: add n...
2
3
4
  /*
   * Copyright (c) 2008, Intel Corporation.
   *
ca9b0e27e   Alexander Duyck   pkt_action: add n...
5
6
7
8
9
10
11
12
13
14
   * Author: Alexander Duyck <alexander.h.duyck@intel.com>
   */
  
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/kernel.h>
  #include <linux/skbuff.h>
  #include <linux/rtnetlink.h>
  #include <net/netlink.h>
  #include <net/pkt_sched.h>
e7e3728bd   Qiaobin Fu   net:sched: add ac...
15
16
17
  #include <net/ip.h>
  #include <net/ipv6.h>
  #include <net/dsfield.h>
ec7727bb2   Davide Caratti   net/sched: act_sk...
18
  #include <net/pkt_cls.h>
ca9b0e27e   Alexander Duyck   pkt_action: add n...
19
20
21
  
  #include <linux/tc_act/tc_skbedit.h>
  #include <net/tc_act/tc_skbedit.h>
c7d03a00b   Alexey Dobriyan   netns: make struc...
22
  static unsigned int skbedit_net_id;
a85a970af   WANG Cong   net_sched: move t...
23
  static struct tc_action_ops act_skbedit_ops;
ddf97ccdd   WANG Cong   net_sched: add ne...
24

45da1dac6   Jamal Hadi Salim   net: sched: act_s...
25
26
  static int tcf_skbedit_act(struct sk_buff *skb, const struct tc_action *a,
  			   struct tcf_result *res)
ca9b0e27e   Alexander Duyck   pkt_action: add n...
27
  {
a85a970af   WANG Cong   net_sched: move t...
28
  	struct tcf_skbedit *d = to_skbedit(a);
c749cdda9   Davide Caratti   net/sched: act_sk...
29
30
  	struct tcf_skbedit_params *params;
  	int action;
ca9b0e27e   Alexander Duyck   pkt_action: add n...
31

9c4a4e488   Jamal Hadi Salim   net sched: action...
32
  	tcf_lastuse_update(&d->tcf_tm);
6f3dfb0dc   Davide Caratti   net/sched: skbedi...
33
  	bstats_cpu_update(this_cpu_ptr(d->common.cpu_bstats), skb);
ca9b0e27e   Alexander Duyck   pkt_action: add n...
34

7fd4b288e   Paolo Abeni   tc/act: remove un...
35
  	params = rcu_dereference_bh(d->params);
c749cdda9   Davide Caratti   net/sched: act_sk...
36
37
38
39
40
  	action = READ_ONCE(d->tcf_action);
  
  	if (params->flags & SKBEDIT_F_PRIORITY)
  		skb->priority = params->priority;
  	if (params->flags & SKBEDIT_F_INHERITDSFIELD) {
e7e3728bd   Qiaobin Fu   net:sched: add ac...
41
  		int wlen = skb_network_offset(skb);
d7bf2ebeb   Toke Høiland-Jørgensen   sched: consistent...
42
  		switch (skb_protocol(skb, true)) {
e7e3728bd   Qiaobin Fu   net:sched: add ac...
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
  		case htons(ETH_P_IP):
  			wlen += sizeof(struct iphdr);
  			if (!pskb_may_pull(skb, wlen))
  				goto err;
  			skb->priority = ipv4_get_dsfield(ip_hdr(skb)) >> 2;
  			break;
  
  		case htons(ETH_P_IPV6):
  			wlen += sizeof(struct ipv6hdr);
  			if (!pskb_may_pull(skb, wlen))
  				goto err;
  			skb->priority = ipv6_get_dsfield(ipv6_hdr(skb)) >> 2;
  			break;
  		}
  	}
c749cdda9   Davide Caratti   net/sched: act_sk...
58
59
60
61
62
63
  	if (params->flags & SKBEDIT_F_QUEUE_MAPPING &&
  	    skb->dev->real_num_tx_queues > params->queue_mapping)
  		skb_set_queue_mapping(skb, params->queue_mapping);
  	if (params->flags & SKBEDIT_F_MARK) {
  		skb->mark &= ~params->mask;
  		skb->mark |= params->mark & params->mask;
4fe77d82e   Antonio Quartulli   skbedit: allow th...
64
  	}
c749cdda9   Davide Caratti   net/sched: act_sk...
65
66
  	if (params->flags & SKBEDIT_F_PTYPE)
  		skb->pkt_type = params->ptype;
c749cdda9   Davide Caratti   net/sched: act_sk...
67
  	return action;
7fd4b288e   Paolo Abeni   tc/act: remove un...
68

e7e3728bd   Qiaobin Fu   net:sched: add ac...
69
  err:
6f3dfb0dc   Davide Caratti   net/sched: skbedi...
70
  	qstats_drop_inc(this_cpu_ptr(d->common.cpu_qstats));
7fd4b288e   Paolo Abeni   tc/act: remove un...
71
  	return TC_ACT_SHOT;
ca9b0e27e   Alexander Duyck   pkt_action: add n...
72
  }
837cb17dd   Petr Machata   sched: act_skbedi...
73
  static void tcf_skbedit_stats_update(struct tc_action *a, u64 bytes,
4b61d3e8d   Po Liu   net: qos offload ...
74
75
  				     u64 packets, u64 drops,
  				     u64 lastuse, bool hw)
837cb17dd   Petr Machata   sched: act_skbedi...
76
77
78
  {
  	struct tcf_skbedit *d = to_skbedit(a);
  	struct tcf_t *tm = &d->tcf_tm;
4b61d3e8d   Po Liu   net: qos offload ...
79
  	tcf_action_update_stats(a, bytes, packets, drops, hw);
837cb17dd   Petr Machata   sched: act_skbedi...
80
81
  	tm->lastuse = max_t(u64, tm->lastuse, lastuse);
  }
ca9b0e27e   Alexander Duyck   pkt_action: add n...
82
83
84
85
  static const struct nla_policy skbedit_policy[TCA_SKBEDIT_MAX + 1] = {
  	[TCA_SKBEDIT_PARMS]		= { .len = sizeof(struct tc_skbedit) },
  	[TCA_SKBEDIT_PRIORITY]		= { .len = sizeof(u32) },
  	[TCA_SKBEDIT_QUEUE_MAPPING]	= { .len = sizeof(u16) },
1c55d62e7   jamal   pkt_sched: skbedi...
86
  	[TCA_SKBEDIT_MARK]		= { .len = sizeof(u32) },
ff202ee1e   Jamal Hadi Salim   net sched actions...
87
  	[TCA_SKBEDIT_PTYPE]		= { .len = sizeof(u16) },
4fe77d82e   Antonio Quartulli   skbedit: allow th...
88
  	[TCA_SKBEDIT_MASK]		= { .len = sizeof(u32) },
e7e3728bd   Qiaobin Fu   net:sched: add ac...
89
  	[TCA_SKBEDIT_FLAGS]		= { .len = sizeof(u64) },
ca9b0e27e   Alexander Duyck   pkt_action: add n...
90
  };
c1b52739e   Benjamin LaHaise   pkt_sched: namesp...
91
  static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
a85a970af   WANG Cong   net_sched: move t...
92
  			    struct nlattr *est, struct tc_action **a,
789871bb2   Vlad Buslov   net: sched: imple...
93
  			    int ovr, int bind, bool rtnl_held,
abbb0d336   Vlad Buslov   net: sched: exten...
94
  			    struct tcf_proto *tp, u32 act_flags,
789871bb2   Vlad Buslov   net: sched: imple...
95
  			    struct netlink_ext_ack *extack)
ca9b0e27e   Alexander Duyck   pkt_action: add n...
96
  {
ddf97ccdd   WANG Cong   net_sched: add ne...
97
  	struct tc_action_net *tn = net_generic(net, skbedit_net_id);
6d7a8df6d   Vlad Buslov   net: sched: act_s...
98
  	struct tcf_skbedit_params *params_new;
ca9b0e27e   Alexander Duyck   pkt_action: add n...
99
  	struct nlattr *tb[TCA_SKBEDIT_MAX + 1];
ec7727bb2   Davide Caratti   net/sched: act_sk...
100
  	struct tcf_chain *goto_ch = NULL;
ca9b0e27e   Alexander Duyck   pkt_action: add n...
101
102
  	struct tc_skbedit *parm;
  	struct tcf_skbedit *d;
4fe77d82e   Antonio Quartulli   skbedit: allow th...
103
  	u32 flags = 0, *priority = NULL, *mark = NULL, *mask = NULL;
ff202ee1e   Jamal Hadi Salim   net sched actions...
104
  	u16 *queue_mapping = NULL, *ptype = NULL;
b2313077e   WANG Cong   net_sched: make t...
105
106
  	bool exists = false;
  	int ret = 0, err;
7be8ef2cd   Dmytro Linkin   net: sched: use t...
107
  	u32 index;
ca9b0e27e   Alexander Duyck   pkt_action: add n...
108
109
110
  
  	if (nla == NULL)
  		return -EINVAL;
8cb081746   Johannes Berg   netlink: make val...
111
112
  	err = nla_parse_nested_deprecated(tb, TCA_SKBEDIT_MAX, nla,
  					  skbedit_policy, NULL);
ca9b0e27e   Alexander Duyck   pkt_action: add n...
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
  	if (err < 0)
  		return err;
  
  	if (tb[TCA_SKBEDIT_PARMS] == NULL)
  		return -EINVAL;
  
  	if (tb[TCA_SKBEDIT_PRIORITY] != NULL) {
  		flags |= SKBEDIT_F_PRIORITY;
  		priority = nla_data(tb[TCA_SKBEDIT_PRIORITY]);
  	}
  
  	if (tb[TCA_SKBEDIT_QUEUE_MAPPING] != NULL) {
  		flags |= SKBEDIT_F_QUEUE_MAPPING;
  		queue_mapping = nla_data(tb[TCA_SKBEDIT_QUEUE_MAPPING]);
  	}
1c55d62e7   jamal   pkt_sched: skbedi...
128

ff202ee1e   Jamal Hadi Salim   net sched actions...
129
130
131
132
133
134
  	if (tb[TCA_SKBEDIT_PTYPE] != NULL) {
  		ptype = nla_data(tb[TCA_SKBEDIT_PTYPE]);
  		if (!skb_pkt_type_ok(*ptype))
  			return -EINVAL;
  		flags |= SKBEDIT_F_PTYPE;
  	}
1c55d62e7   jamal   pkt_sched: skbedi...
135
136
137
138
  	if (tb[TCA_SKBEDIT_MARK] != NULL) {
  		flags |= SKBEDIT_F_MARK;
  		mark = nla_data(tb[TCA_SKBEDIT_MARK]);
  	}
4fe77d82e   Antonio Quartulli   skbedit: allow th...
139
140
141
142
  	if (tb[TCA_SKBEDIT_MASK] != NULL) {
  		flags |= SKBEDIT_F_MASK;
  		mask = nla_data(tb[TCA_SKBEDIT_MASK]);
  	}
e7e3728bd   Qiaobin Fu   net:sched: add ac...
143
144
145
146
147
148
  	if (tb[TCA_SKBEDIT_FLAGS] != NULL) {
  		u64 *pure_flags = nla_data(tb[TCA_SKBEDIT_FLAGS]);
  
  		if (*pure_flags & SKBEDIT_F_INHERITDSFIELD)
  			flags |= SKBEDIT_F_INHERITDSFIELD;
  	}
ca9b0e27e   Alexander Duyck   pkt_action: add n...
149
  	parm = nla_data(tb[TCA_SKBEDIT_PARMS]);
7be8ef2cd   Dmytro Linkin   net: sched: use t...
150
151
  	index = parm->index;
  	err = tcf_idr_check_alloc(tn, &index, a, bind);
0190c1d45   Vlad Buslov   net: sched: atomi...
152
153
154
  	if (err < 0)
  		return err;
  	exists = err;
5e1567aeb   Jamal Hadi Salim   net sched: skbedi...
155
156
157
158
  	if (exists && bind)
  		return 0;
  
  	if (!flags) {
af5d01842   Roman Mashak   net sched actions...
159
160
  		if (exists)
  			tcf_idr_release(*a, bind);
0190c1d45   Vlad Buslov   net: sched: atomi...
161
  		else
7be8ef2cd   Dmytro Linkin   net: sched: use t...
162
  			tcf_idr_cleanup(tn, index);
5e1567aeb   Jamal Hadi Salim   net sched: skbedi...
163
164
165
166
  		return -EINVAL;
  	}
  
  	if (!exists) {
7be8ef2cd   Dmytro Linkin   net: sched: use t...
167
  		ret = tcf_idr_create(tn, index, est, a,
e38226786   Vlad Buslov   net: sched: updat...
168
  				     &act_skbedit_ops, bind, true, 0);
0190c1d45   Vlad Buslov   net: sched: atomi...
169
  		if (ret) {
7be8ef2cd   Dmytro Linkin   net: sched: use t...
170
  			tcf_idr_cleanup(tn, index);
86062033f   WANG Cong   net_sched: act: h...
171
  			return ret;
0190c1d45   Vlad Buslov   net: sched: atomi...
172
  		}
ca9b0e27e   Alexander Duyck   pkt_action: add n...
173

a85a970af   WANG Cong   net_sched: move t...
174
  		d = to_skbedit(*a);
ca9b0e27e   Alexander Duyck   pkt_action: add n...
175
176
  		ret = ACT_P_CREATED;
  	} else {
a85a970af   WANG Cong   net_sched: move t...
177
  		d = to_skbedit(*a);
4e8ddd7f1   Vlad Buslov   net: sched: don't...
178
179
  		if (!ovr) {
  			tcf_idr_release(*a, bind);
ca9b0e27e   Alexander Duyck   pkt_action: add n...
180
  			return -EEXIST;
4e8ddd7f1   Vlad Buslov   net: sched: don't...
181
  		}
ca9b0e27e   Alexander Duyck   pkt_action: add n...
182
  	}
ec7727bb2   Davide Caratti   net/sched: act_sk...
183
184
185
  	err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch, extack);
  	if (err < 0)
  		goto release_idr;
ca9b0e27e   Alexander Duyck   pkt_action: add n...
186

c749cdda9   Davide Caratti   net/sched: act_sk...
187
188
  	params_new = kzalloc(sizeof(*params_new), GFP_KERNEL);
  	if (unlikely(!params_new)) {
ec7727bb2   Davide Caratti   net/sched: act_sk...
189
190
  		err = -ENOMEM;
  		goto put_chain;
c749cdda9   Davide Caratti   net/sched: act_sk...
191
192
193
  	}
  
  	params_new->flags = flags;
ca9b0e27e   Alexander Duyck   pkt_action: add n...
194
  	if (flags & SKBEDIT_F_PRIORITY)
c749cdda9   Davide Caratti   net/sched: act_sk...
195
  		params_new->priority = *priority;
ca9b0e27e   Alexander Duyck   pkt_action: add n...
196
  	if (flags & SKBEDIT_F_QUEUE_MAPPING)
c749cdda9   Davide Caratti   net/sched: act_sk...
197
  		params_new->queue_mapping = *queue_mapping;
1c55d62e7   jamal   pkt_sched: skbedi...
198
  	if (flags & SKBEDIT_F_MARK)
c749cdda9   Davide Caratti   net/sched: act_sk...
199
  		params_new->mark = *mark;
ff202ee1e   Jamal Hadi Salim   net sched actions...
200
  	if (flags & SKBEDIT_F_PTYPE)
c749cdda9   Davide Caratti   net/sched: act_sk...
201
  		params_new->ptype = *ptype;
4fe77d82e   Antonio Quartulli   skbedit: allow th...
202
  	/* default behaviour is to use all the bits */
c749cdda9   Davide Caratti   net/sched: act_sk...
203
  	params_new->mask = 0xffffffff;
4fe77d82e   Antonio Quartulli   skbedit: allow th...
204
  	if (flags & SKBEDIT_F_MASK)
c749cdda9   Davide Caratti   net/sched: act_sk...
205
  		params_new->mask = *mask;
1c55d62e7   jamal   pkt_sched: skbedi...
206

6d7a8df6d   Vlad Buslov   net: sched: act_s...
207
  	spin_lock_bh(&d->tcf_lock);
ec7727bb2   Davide Caratti   net/sched: act_sk...
208
  	goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch);
445d37493   Paul E. McKenney   net/sched: Replac...
209
210
  	params_new = rcu_replace_pointer(d->params, params_new,
  					 lockdep_is_held(&d->tcf_lock));
6d7a8df6d   Vlad Buslov   net: sched: act_s...
211
212
213
  	spin_unlock_bh(&d->tcf_lock);
  	if (params_new)
  		kfree_rcu(params_new, rcu);
ec7727bb2   Davide Caratti   net/sched: act_sk...
214
215
  	if (goto_ch)
  		tcf_chain_put_by_act(goto_ch);
ca9b0e27e   Alexander Duyck   pkt_action: add n...
216

ca9b0e27e   Alexander Duyck   pkt_action: add n...
217
  	return ret;
ec7727bb2   Davide Caratti   net/sched: act_sk...
218
219
220
221
222
223
  put_chain:
  	if (goto_ch)
  		tcf_chain_put_by_act(goto_ch);
  release_idr:
  	tcf_idr_release(*a, bind);
  	return err;
ca9b0e27e   Alexander Duyck   pkt_action: add n...
224
  }
cc7ec456f   Eric Dumazet   net_sched: cleanups
225
226
  static int tcf_skbedit_dump(struct sk_buff *skb, struct tc_action *a,
  			    int bind, int ref)
ca9b0e27e   Alexander Duyck   pkt_action: add n...
227
228
  {
  	unsigned char *b = skb_tail_pointer(skb);
a85a970af   WANG Cong   net_sched: move t...
229
  	struct tcf_skbedit *d = to_skbedit(a);
c749cdda9   Davide Caratti   net/sched: act_sk...
230
  	struct tcf_skbedit_params *params;
1c40be12f   Eric Dumazet   net sched: fix so...
231
232
  	struct tc_skbedit opt = {
  		.index   = d->tcf_index,
036bb4432   Vlad Buslov   net: sched: chang...
233
234
  		.refcnt  = refcount_read(&d->tcf_refcnt) - ref,
  		.bindcnt = atomic_read(&d->tcf_bindcnt) - bind,
1c40be12f   Eric Dumazet   net sched: fix so...
235
  	};
e7e3728bd   Qiaobin Fu   net:sched: add ac...
236
  	u64 pure_flags = 0;
c749cdda9   Davide Caratti   net/sched: act_sk...
237
  	struct tcf_t t;
6d7a8df6d   Vlad Buslov   net: sched: act_s...
238
239
240
241
  	spin_lock_bh(&d->tcf_lock);
  	params = rcu_dereference_protected(d->params,
  					   lockdep_is_held(&d->tcf_lock));
  	opt.action = d->tcf_action;
ca9b0e27e   Alexander Duyck   pkt_action: add n...
242

1b34ec43c   David S. Miller   pkt_sched: Stop u...
243
244
  	if (nla_put(skb, TCA_SKBEDIT_PARMS, sizeof(opt), &opt))
  		goto nla_put_failure;
c749cdda9   Davide Caratti   net/sched: act_sk...
245
246
  	if ((params->flags & SKBEDIT_F_PRIORITY) &&
  	    nla_put_u32(skb, TCA_SKBEDIT_PRIORITY, params->priority))
1b34ec43c   David S. Miller   pkt_sched: Stop u...
247
  		goto nla_put_failure;
c749cdda9   Davide Caratti   net/sched: act_sk...
248
249
  	if ((params->flags & SKBEDIT_F_QUEUE_MAPPING) &&
  	    nla_put_u16(skb, TCA_SKBEDIT_QUEUE_MAPPING, params->queue_mapping))
1b34ec43c   David S. Miller   pkt_sched: Stop u...
250
  		goto nla_put_failure;
c749cdda9   Davide Caratti   net/sched: act_sk...
251
252
  	if ((params->flags & SKBEDIT_F_MARK) &&
  	    nla_put_u32(skb, TCA_SKBEDIT_MARK, params->mark))
1b34ec43c   David S. Miller   pkt_sched: Stop u...
253
  		goto nla_put_failure;
c749cdda9   Davide Caratti   net/sched: act_sk...
254
255
  	if ((params->flags & SKBEDIT_F_PTYPE) &&
  	    nla_put_u16(skb, TCA_SKBEDIT_PTYPE, params->ptype))
ff202ee1e   Jamal Hadi Salim   net sched actions...
256
  		goto nla_put_failure;
c749cdda9   Davide Caratti   net/sched: act_sk...
257
258
  	if ((params->flags & SKBEDIT_F_MASK) &&
  	    nla_put_u32(skb, TCA_SKBEDIT_MASK, params->mask))
4fe77d82e   Antonio Quartulli   skbedit: allow th...
259
  		goto nla_put_failure;
c749cdda9   Davide Caratti   net/sched: act_sk...
260
  	if (params->flags & SKBEDIT_F_INHERITDSFIELD)
e7e3728bd   Qiaobin Fu   net:sched: add ac...
261
262
263
264
  		pure_flags |= SKBEDIT_F_INHERITDSFIELD;
  	if (pure_flags != 0 &&
  	    nla_put(skb, TCA_SKBEDIT_FLAGS, sizeof(pure_flags), &pure_flags))
  		goto nla_put_failure;
48d8ee169   Jamal Hadi Salim   net sched actions...
265
266
  
  	tcf_tm_dump(&t, &d->tcf_tm);
9854518ea   Nicolas Dichtel   sched: align nlat...
267
  	if (nla_put_64bit(skb, TCA_SKBEDIT_TM, sizeof(t), &t, TCA_SKBEDIT_PAD))
1b34ec43c   David S. Miller   pkt_sched: Stop u...
268
  		goto nla_put_failure;
6d7a8df6d   Vlad Buslov   net: sched: act_s...
269
  	spin_unlock_bh(&d->tcf_lock);
ca9b0e27e   Alexander Duyck   pkt_action: add n...
270
271
272
  	return skb->len;
  
  nla_put_failure:
6d7a8df6d   Vlad Buslov   net: sched: act_s...
273
  	spin_unlock_bh(&d->tcf_lock);
ca9b0e27e   Alexander Duyck   pkt_action: add n...
274
275
276
  	nlmsg_trim(skb, b);
  	return -1;
  }
c749cdda9   Davide Caratti   net/sched: act_sk...
277
278
279
280
281
282
283
284
285
  static void tcf_skbedit_cleanup(struct tc_action *a)
  {
  	struct tcf_skbedit *d = to_skbedit(a);
  	struct tcf_skbedit_params *params;
  
  	params = rcu_dereference_protected(d->params, 1);
  	if (params)
  		kfree_rcu(params, rcu);
  }
ddf97ccdd   WANG Cong   net_sched: add ne...
286
287
  static int tcf_skbedit_walker(struct net *net, struct sk_buff *skb,
  			      struct netlink_callback *cb, int type,
417801055   Alexander Aring   net: sched: act: ...
288
289
  			      const struct tc_action_ops *ops,
  			      struct netlink_ext_ack *extack)
ddf97ccdd   WANG Cong   net_sched: add ne...
290
291
  {
  	struct tc_action_net *tn = net_generic(net, skbedit_net_id);
b36201455   Alexander Aring   net: sched: act: ...
292
  	return tcf_generic_walker(tn, skb, cb, type, ops, extack);
ddf97ccdd   WANG Cong   net_sched: add ne...
293
  }
f061b48c1   Cong Wang   Revert "net: sche...
294
  static int tcf_skbedit_search(struct net *net, struct tc_action **a, u32 index)
ddf97ccdd   WANG Cong   net_sched: add ne...
295
296
  {
  	struct tc_action_net *tn = net_generic(net, skbedit_net_id);
65a206c01   Chris Mi   net/sched: Change...
297
  	return tcf_idr_search(tn, a, index);
ddf97ccdd   WANG Cong   net_sched: add ne...
298
  }
e1fea322f   Roman Mashak   net sched: update...
299
300
301
302
303
304
305
306
307
308
  static size_t tcf_skbedit_get_fill_size(const struct tc_action *act)
  {
  	return nla_total_size(sizeof(struct tc_skbedit))
  		+ nla_total_size(sizeof(u32)) /* TCA_SKBEDIT_PRIORITY */
  		+ nla_total_size(sizeof(u16)) /* TCA_SKBEDIT_QUEUE_MAPPING */
  		+ nla_total_size(sizeof(u32)) /* TCA_SKBEDIT_MARK */
  		+ nla_total_size(sizeof(u16)) /* TCA_SKBEDIT_PTYPE */
  		+ nla_total_size(sizeof(u32)) /* TCA_SKBEDIT_MASK */
  		+ nla_total_size_64bit(sizeof(u64)); /* TCA_SKBEDIT_FLAGS */
  }
ca9b0e27e   Alexander Duyck   pkt_action: add n...
309
310
  static struct tc_action_ops act_skbedit_ops = {
  	.kind		=	"skbedit",
eddd2cf19   Eli Cohen   net: Change TCA_A...
311
  	.id		=	TCA_ID_SKBEDIT,
ca9b0e27e   Alexander Duyck   pkt_action: add n...
312
  	.owner		=	THIS_MODULE,
45da1dac6   Jamal Hadi Salim   net: sched: act_s...
313
  	.act		=	tcf_skbedit_act,
837cb17dd   Petr Machata   sched: act_skbedi...
314
  	.stats_update	=	tcf_skbedit_stats_update,
ca9b0e27e   Alexander Duyck   pkt_action: add n...
315
  	.dump		=	tcf_skbedit_dump,
ca9b0e27e   Alexander Duyck   pkt_action: add n...
316
  	.init		=	tcf_skbedit_init,
c749cdda9   Davide Caratti   net/sched: act_sk...
317
  	.cleanup	=	tcf_skbedit_cleanup,
ddf97ccdd   WANG Cong   net_sched: add ne...
318
  	.walk		=	tcf_skbedit_walker,
e1fea322f   Roman Mashak   net sched: update...
319
  	.get_fill_size	=	tcf_skbedit_get_fill_size,
ddf97ccdd   WANG Cong   net_sched: add ne...
320
  	.lookup		=	tcf_skbedit_search,
a85a970af   WANG Cong   net_sched: move t...
321
  	.size		=	sizeof(struct tcf_skbedit),
ddf97ccdd   WANG Cong   net_sched: add ne...
322
323
324
325
326
  };
  
  static __net_init int skbedit_init_net(struct net *net)
  {
  	struct tc_action_net *tn = net_generic(net, skbedit_net_id);
981471bd3   Cong Wang   net_sched: fix a ...
327
  	return tc_action_net_init(net, tn, &act_skbedit_ops);
ddf97ccdd   WANG Cong   net_sched: add ne...
328
  }
039af9c66   Cong Wang   net_sched: switch...
329
  static void __net_exit skbedit_exit_net(struct list_head *net_list)
ddf97ccdd   WANG Cong   net_sched: add ne...
330
  {
039af9c66   Cong Wang   net_sched: switch...
331
  	tc_action_net_exit(net_list, skbedit_net_id);
ddf97ccdd   WANG Cong   net_sched: add ne...
332
333
334
335
  }
  
  static struct pernet_operations skbedit_net_ops = {
  	.init = skbedit_init_net,
039af9c66   Cong Wang   net_sched: switch...
336
  	.exit_batch = skbedit_exit_net,
ddf97ccdd   WANG Cong   net_sched: add ne...
337
338
  	.id   = &skbedit_net_id,
  	.size = sizeof(struct tc_action_net),
ca9b0e27e   Alexander Duyck   pkt_action: add n...
339
340
341
342
343
344
345
346
  };
  
  MODULE_AUTHOR("Alexander Duyck, <alexander.h.duyck@intel.com>");
  MODULE_DESCRIPTION("SKB Editing");
  MODULE_LICENSE("GPL");
  
  static int __init skbedit_init_module(void)
  {
ddf97ccdd   WANG Cong   net_sched: add ne...
347
  	return tcf_register_action(&act_skbedit_ops, &skbedit_net_ops);
ca9b0e27e   Alexander Duyck   pkt_action: add n...
348
349
350
351
  }
  
  static void __exit skbedit_cleanup_module(void)
  {
ddf97ccdd   WANG Cong   net_sched: add ne...
352
  	tcf_unregister_action(&act_skbedit_ops, &skbedit_net_ops);
ca9b0e27e   Alexander Duyck   pkt_action: add n...
353
354
355
356
  }
  
  module_init(skbedit_init_module);
  module_exit(skbedit_cleanup_module);