diff options
Diffstat (limited to 'net/sched/act_connmark.c')
-rw-r--r-- | net/sched/act_connmark.c | 54 |
1 files changed, 48 insertions, 6 deletions
diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c index bb41699c6..c0ed93ce2 100644 --- a/net/sched/act_connmark.c +++ b/net/sched/act_connmark.c @@ -30,6 +30,8 @@ #define CONNMARK_TAB_MASK 3 +static int connmark_net_id; + static int tcf_connmark(struct sk_buff *skb, const struct tc_action *a, struct tcf_result *res) { @@ -97,6 +99,7 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla, struct nlattr *est, struct tc_action *a, int ovr, int bind) { + struct tc_action_net *tn = net_generic(net, connmark_net_id); struct nlattr *tb[TCA_CONNMARK_MAX + 1]; struct tcf_connmark_info *ci; struct tc_connmark *parm; @@ -111,9 +114,9 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla, parm = nla_data(tb[TCA_CONNMARK_PARMS]); - if (!tcf_hash_check(parm->index, a, bind)) { - ret = tcf_hash_create(parm->index, est, a, sizeof(*ci), - bind, false); + if (!tcf_hash_check(tn, parm->index, a, bind)) { + ret = tcf_hash_create(tn, parm->index, est, a, + sizeof(*ci), bind, false); if (ret) return ret; @@ -122,7 +125,7 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla, ci->net = net; ci->zone = parm->zone; - tcf_hash_insert(a); + tcf_hash_insert(tn, a); ret = ACT_P_CREATED; } else { ci = to_connmark(a); @@ -169,6 +172,22 @@ nla_put_failure: return -1; } +static int tcf_connmark_walker(struct net *net, struct sk_buff *skb, + struct netlink_callback *cb, int type, + struct tc_action *a) +{ + struct tc_action_net *tn = net_generic(net, connmark_net_id); + + return tcf_generic_walker(tn, skb, cb, type, a); +} + +static int tcf_connmark_search(struct net *net, struct tc_action *a, u32 index) +{ + struct tc_action_net *tn = net_generic(net, connmark_net_id); + + return tcf_hash_search(tn, a, index); +} + static struct tc_action_ops act_connmark_ops = { .kind = "connmark", .type = TCA_ACT_CONNMARK, @@ -176,16 +195,39 @@ static struct tc_action_ops act_connmark_ops = { .act = tcf_connmark, .dump = tcf_connmark_dump, .init = tcf_connmark_init, + .walk = tcf_connmark_walker, + .lookup = tcf_connmark_search, +}; + +static __net_init int connmark_init_net(struct net *net) +{ + struct tc_action_net *tn = net_generic(net, connmark_net_id); + + return tc_action_net_init(tn, &act_connmark_ops, CONNMARK_TAB_MASK); +} + +static void __net_exit connmark_exit_net(struct net *net) +{ + struct tc_action_net *tn = net_generic(net, connmark_net_id); + + tc_action_net_exit(tn); +} + +static struct pernet_operations connmark_net_ops = { + .init = connmark_init_net, + .exit = connmark_exit_net, + .id = &connmark_net_id, + .size = sizeof(struct tc_action_net), }; static int __init connmark_init_module(void) { - return tcf_register_action(&act_connmark_ops, CONNMARK_TAB_MASK); + return tcf_register_action(&act_connmark_ops, &connmark_net_ops); } static void __exit connmark_cleanup_module(void) { - tcf_unregister_action(&act_connmark_ops); + tcf_unregister_action(&act_connmark_ops, &connmark_net_ops); } module_init(connmark_init_module); |