act_bpf.c (cc9b94029e9ef51787af908e9856b1eed314bc00) act_bpf.c (7bd509e311f408f7a5132fcdde2069af65fa05ae)
1/*
2 * Copyright (c) 2015 Jiri Pirko <jiri@resnulli.us>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */

--- 14 unchanged lines hidden (view full) ---

23
24#define BPF_TAB_MASK 15
25#define ACT_BPF_NAME_LEN 256
26
27struct tcf_bpf_cfg {
28 struct bpf_prog *filter;
29 struct sock_filter *bpf_ops;
30 const char *bpf_name;
1/*
2 * Copyright (c) 2015 Jiri Pirko <jiri@resnulli.us>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */

--- 14 unchanged lines hidden (view full) ---

23
24#define BPF_TAB_MASK 15
25#define ACT_BPF_NAME_LEN 256
26
27struct tcf_bpf_cfg {
28 struct bpf_prog *filter;
29 struct sock_filter *bpf_ops;
30 const char *bpf_name;
31 u32 bpf_fd;
32 u16 bpf_num_ops;
33 bool is_ebpf;
34};
35
31 u16 bpf_num_ops;
32 bool is_ebpf;
33};
34
36static int bpf_net_id;
35static unsigned int bpf_net_id;
37static struct tc_action_ops act_bpf_ops;
38
39static int tcf_bpf(struct sk_buff *skb, const struct tc_action *act,
40 struct tcf_result *res)
41{
42 bool at_ingress = skb_at_tc_ingress(skb);
43 struct tcf_bpf *prog = to_bpf(act);
44 struct bpf_prog *filter;

--- 68 unchanged lines hidden (view full) ---

113 memcpy(nla_data(nla), prog->bpf_ops, nla_len(nla));
114
115 return 0;
116}
117
118static int tcf_bpf_dump_ebpf_info(const struct tcf_bpf *prog,
119 struct sk_buff *skb)
120{
36static struct tc_action_ops act_bpf_ops;
37
38static int tcf_bpf(struct sk_buff *skb, const struct tc_action *act,
39 struct tcf_result *res)
40{
41 bool at_ingress = skb_at_tc_ingress(skb);
42 struct tcf_bpf *prog = to_bpf(act);
43 struct bpf_prog *filter;

--- 68 unchanged lines hidden (view full) ---

112 memcpy(nla_data(nla), prog->bpf_ops, nla_len(nla));
113
114 return 0;
115}
116
117static int tcf_bpf_dump_ebpf_info(const struct tcf_bpf *prog,
118 struct sk_buff *skb)
119{
121 if (nla_put_u32(skb, TCA_ACT_BPF_FD, prog->bpf_fd))
122 return -EMSGSIZE;
120 struct nlattr *nla;
123
124 if (prog->bpf_name &&
125 nla_put_string(skb, TCA_ACT_BPF_NAME, prog->bpf_name))
126 return -EMSGSIZE;
127
121
122 if (prog->bpf_name &&
123 nla_put_string(skb, TCA_ACT_BPF_NAME, prog->bpf_name))
124 return -EMSGSIZE;
125
126 nla = nla_reserve(skb, TCA_ACT_BPF_DIGEST,
127 sizeof(prog->filter->digest));
128 if (nla == NULL)
129 return -EMSGSIZE;
130
131 memcpy(nla_data(nla), prog->filter->digest, nla_len(nla));
132
128 return 0;
129}
130
131static int tcf_bpf_dump(struct sk_buff *skb, struct tc_action *act,
132 int bind, int ref)
133{
134 unsigned char *tp = skb_tail_pointer(skb);
135 struct tcf_bpf *prog = to_bpf(act);

--- 85 unchanged lines hidden (view full) ---

221
222 bpf_fd = nla_get_u32(tb[TCA_ACT_BPF_FD]);
223
224 fp = bpf_prog_get_type(bpf_fd, BPF_PROG_TYPE_SCHED_ACT);
225 if (IS_ERR(fp))
226 return PTR_ERR(fp);
227
228 if (tb[TCA_ACT_BPF_NAME]) {
133 return 0;
134}
135
136static int tcf_bpf_dump(struct sk_buff *skb, struct tc_action *act,
137 int bind, int ref)
138{
139 unsigned char *tp = skb_tail_pointer(skb);
140 struct tcf_bpf *prog = to_bpf(act);

--- 85 unchanged lines hidden (view full) ---

226
227 bpf_fd = nla_get_u32(tb[TCA_ACT_BPF_FD]);
228
229 fp = bpf_prog_get_type(bpf_fd, BPF_PROG_TYPE_SCHED_ACT);
230 if (IS_ERR(fp))
231 return PTR_ERR(fp);
232
233 if (tb[TCA_ACT_BPF_NAME]) {
229 name = kmemdup(nla_data(tb[TCA_ACT_BPF_NAME]),
230 nla_len(tb[TCA_ACT_BPF_NAME]),
231 GFP_KERNEL);
234 name = nla_memdup(tb[TCA_ACT_BPF_NAME], GFP_KERNEL);
232 if (!name) {
233 bpf_prog_put(fp);
234 return -ENOMEM;
235 }
236 }
237
235 if (!name) {
236 bpf_prog_put(fp);
237 return -ENOMEM;
238 }
239 }
240
238 cfg->bpf_fd = bpf_fd;
239 cfg->bpf_name = name;
240 cfg->filter = fp;
241 cfg->is_ebpf = true;
242
243 return 0;
244}
245
246static void tcf_bpf_cfg_cleanup(const struct tcf_bpf_cfg *cfg)

--- 82 unchanged lines hidden (view full) ---

329 if (res != ACT_P_CREATED)
330 tcf_bpf_prog_fill_cfg(prog, &old);
331
332 prog->bpf_ops = cfg.bpf_ops;
333 prog->bpf_name = cfg.bpf_name;
334
335 if (cfg.bpf_num_ops)
336 prog->bpf_num_ops = cfg.bpf_num_ops;
241 cfg->bpf_name = name;
242 cfg->filter = fp;
243 cfg->is_ebpf = true;
244
245 return 0;
246}
247
248static void tcf_bpf_cfg_cleanup(const struct tcf_bpf_cfg *cfg)

--- 82 unchanged lines hidden (view full) ---

331 if (res != ACT_P_CREATED)
332 tcf_bpf_prog_fill_cfg(prog, &old);
333
334 prog->bpf_ops = cfg.bpf_ops;
335 prog->bpf_name = cfg.bpf_name;
336
337 if (cfg.bpf_num_ops)
338 prog->bpf_num_ops = cfg.bpf_num_ops;
337 if (cfg.bpf_fd)
338 prog->bpf_fd = cfg.bpf_fd;
339
340 prog->tcf_action = parm->action;
341 rcu_assign_pointer(prog->filter, cfg.filter);
342
343 if (res == ACT_P_CREATED) {
344 tcf_hash_insert(tn, *act);
345 } else {
346 /* make sure the program being replaced is no longer executing */

--- 86 unchanged lines hidden ---
339
340 prog->tcf_action = parm->action;
341 rcu_assign_pointer(prog->filter, cfg.filter);
342
343 if (res == ACT_P_CREATED) {
344 tcf_hash_insert(tn, *act);
345 } else {
346 /* make sure the program being replaced is no longer executing */

--- 86 unchanged lines hidden ---