summaryrefslogtreecommitdiff
path: root/net/sched/act_bpf.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/act_bpf.c')
-rw-r--r--net/sched/act_bpf.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c
index 09d46e195e33..06d8f78b7368 100644
--- a/net/sched/act_bpf.c
+++ b/net/sched/act_bpf.c
@@ -389,6 +389,31 @@ static void tcf_bpf_cleanup(struct tc_action *act)
tcf_bpf_cfg_cleanup(&tmp);
}
+static size_t tcf_bpf_get_fill_size(const struct tc_action *act)
+{
+ struct tcf_bpf *prog = to_bpf(act);
+ size_t size = nla_total_size(sizeof(struct tc_act_bpf));
+
+ /* bpf_ops and bpf_num_ops are published as separate stores under
+ * tcf_lock, so take it here as tcf_bpf_dump() does.
+ */
+ spin_lock_bh(&prog->tcf_lock);
+ if (tcf_bpf_is_ebpf(prog)) {
+ /* TCA_ACT_BPF_NAME */
+ size += nla_total_size(ACT_BPF_NAME_LEN + 1);
+ size += nla_total_size(sizeof(u32)); /* TCA_ACT_BPF_ID */
+ size += nla_total_size(BPF_TAG_SIZE); /* TCA_ACT_BPF_TAG */
+ } else {
+ size += nla_total_size(sizeof(u16)); /* TCA_ACT_BPF_OPS_LEN */
+ /* TCA_ACT_BPF_OPS */
+ size += nla_total_size(prog->bpf_num_ops *
+ sizeof(struct sock_filter));
+ }
+ spin_unlock_bh(&prog->tcf_lock);
+
+ return size;
+}
+
static struct tc_action_ops act_bpf_ops __read_mostly = {
.kind = "bpf",
.id = TCA_ID_BPF,
@@ -397,6 +422,7 @@ static struct tc_action_ops act_bpf_ops __read_mostly = {
.dump = tcf_bpf_dump,
.cleanup = tcf_bpf_cleanup,
.init = tcf_bpf_init,
+ .get_fill_size = tcf_bpf_get_fill_size,
.size = sizeof(struct tcf_bpf),
};
MODULE_ALIAS_NET_ACT("bpf");