diff --git a/include/net/act_api.h b/include/net/act_api.h index 8ed9746656403f5df04ac4fc072638646b65b935..152316b3f59a8ddada9748416cf70cca5ba58b31 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -103,10 +103,10 @@ int tcf_hash_release(struct tcf_common *p, int bind, struct tcf_hashinfo *hinfo); u32 tcf_hash_new_index(struct tcf_hashinfo *hinfo); struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a, - int bind, struct tcf_hashinfo *hinfo); + int bind); struct tcf_common *tcf_hash_create(u32 index, struct nlattr *est, struct tc_action *a, int size, - int bind, struct tcf_hashinfo *hinfo); + int bind); void tcf_hash_insert(struct tcf_common *p, struct tcf_hashinfo *hinfo); int tcf_register_action(struct tc_action_ops *a); diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 35f89e9ce49c2f9300c38a03ca0348e726331d29..b94825322d4df5466db333b851502f7b76b6fa8d 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -62,8 +62,9 @@ int tcf_hash_release(struct tcf_common *p, int bind, EXPORT_SYMBOL(tcf_hash_release); static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb, - struct tc_action *a, struct tcf_hashinfo *hinfo) + struct tc_action *a) { + struct tcf_hashinfo *hinfo = a->ops->hinfo; struct hlist_head *head; struct tcf_common *p; int err = 0, index = -1, i = 0, s_i = 0, n_i = 0; @@ -109,9 +110,9 @@ static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb, goto done; } -static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a, - struct tcf_hashinfo *hinfo) +static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a) { + struct tcf_hashinfo *hinfo = a->ops->hinfo; struct hlist_head *head; struct hlist_node *n; struct tcf_common *p; @@ -145,12 +146,10 @@ static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a, static int tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb, int type, struct tc_action *a) { - struct tcf_hashinfo *hinfo = a->ops->hinfo; - if (type == RTM_DELACTION) { - return tcf_del_walker(skb, a, hinfo); + return tcf_del_walker(skb, a); } else if (type == RTM_GETACTION) { - return tcf_dump_walker(skb, cb, a, hinfo); + return tcf_dump_walker(skb, cb, a); } else { WARN(1, "tcf_generic_walker: unknown action %d\n", type); return -EINVAL; @@ -199,9 +198,9 @@ static int tcf_hash_search(struct tc_action *a, u32 index) return 0; } -struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a, int bind, - struct tcf_hashinfo *hinfo) +struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a, int bind) { + struct tcf_hashinfo *hinfo = a->ops->hinfo; struct tcf_common *p = NULL; if (index && (p = tcf_hash_lookup(index, hinfo)) != NULL) { if (bind) @@ -214,9 +213,9 @@ struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a, int bind, EXPORT_SYMBOL(tcf_hash_check); struct tcf_common *tcf_hash_create(u32 index, struct nlattr *est, - struct tc_action *a, int size, int bind, - struct tcf_hashinfo *hinfo) + struct tc_action *a, int size, int bind) { + struct tcf_hashinfo *hinfo = a->ops->hinfo; struct tcf_common *p = kzalloc(size, GFP_KERNEL); if (unlikely(!p)) @@ -495,6 +494,7 @@ struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla, if (a == NULL) goto err_mod; + a->ops = a_o; INIT_LIST_HEAD(&a->list); /* backward compatibility for policer */ if (name == NULL) @@ -510,7 +510,6 @@ struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla, */ if (err != ACT_P_CREATED) module_put(a_o->owner); - a->ops = a_o; return a; diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index 9d5c1d343fe2953a9be476d5ae57002c3b158a0c..2210187c45c2772a9f21dae081af50eeabcf6366 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c @@ -63,17 +63,16 @@ static int tcf_csum_init(struct net *n, struct nlattr *nla, struct nlattr *est, return -EINVAL; parm = nla_data(tb[TCA_CSUM_PARMS]); - pc = tcf_hash_check(parm->index, a, bind, &csum_hash_info); + pc = tcf_hash_check(parm->index, a, bind); if (!pc) { - pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind, - &csum_hash_info); + pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind); if (IS_ERR(pc)) return PTR_ERR(pc); ret = ACT_P_CREATED; } else { if (bind)/* dont override defaults */ return 0; - tcf_hash_release(pc, bind, &csum_hash_info); + tcf_hash_release(pc, bind, a->ops->hinfo); if (!ovr) return -EEXIST; } @@ -85,7 +84,7 @@ static int tcf_csum_init(struct net *n, struct nlattr *nla, struct nlattr *est, spin_unlock_bh(&p->tcf_lock); if (ret == ACT_P_CREATED) - tcf_hash_insert(pc, &csum_hash_info); + tcf_hash_insert(pc, a->ops->hinfo); return ret; } diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index 72c49de506164685795fd5329102f1016118b02f..a0eed30d58111ab49e11f9cc97c4dc0d30e93c9e 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c @@ -86,17 +86,16 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla, } #endif - pc = tcf_hash_check(parm->index, a, bind, &gact_hash_info); + pc = tcf_hash_check(parm->index, a, bind); if (!pc) { - pc = tcf_hash_create(parm->index, est, a, sizeof(*gact), - bind, &gact_hash_info); + pc = tcf_hash_create(parm->index, est, a, sizeof(*gact), bind); if (IS_ERR(pc)) return PTR_ERR(pc); ret = ACT_P_CREATED; } else { if (bind)/* dont override defaults */ return 0; - tcf_hash_release(pc, bind, &gact_hash_info); + tcf_hash_release(pc, bind, a->ops->hinfo); if (!ovr) return -EEXIST; } @@ -114,7 +113,7 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla, #endif spin_unlock_bh(&gact->tcf_lock); if (ret == ACT_P_CREATED) - tcf_hash_insert(pc, &gact_hash_info); + tcf_hash_insert(pc, a->ops->hinfo); return ret; } @@ -123,7 +122,7 @@ static int tcf_gact_cleanup(struct tc_action *a, int bind) struct tcf_gact *gact = a->priv; if (gact) - return tcf_hash_release(&gact->common, bind, &gact_hash_info); + return tcf_hash_release(&gact->common, bind, a->ops->hinfo); return 0; } diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index 67d701e0a2bd3702faacfa7e2db811303f721418..0a6d621740273ffddec7dffc1837f483be8bb0e2 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c @@ -125,10 +125,9 @@ static int tcf_ipt_init(struct net *net, struct nlattr *nla, struct nlattr *est, if (tb[TCA_IPT_INDEX] != NULL) index = nla_get_u32(tb[TCA_IPT_INDEX]); - pc = tcf_hash_check(index, a, bind, &ipt_hash_info); + pc = tcf_hash_check(index, a, bind); if (!pc) { - pc = tcf_hash_create(index, est, a, sizeof(*ipt), bind, - &ipt_hash_info); + pc = tcf_hash_create(index, est, a, sizeof(*ipt), bind); if (IS_ERR(pc)) return PTR_ERR(pc); ret = ACT_P_CREATED; @@ -171,7 +170,7 @@ static int tcf_ipt_init(struct net *net, struct nlattr *nla, struct nlattr *est, ipt->tcfi_hook = hook; spin_unlock_bh(&ipt->tcf_lock); if (ret == ACT_P_CREATED) - tcf_hash_insert(pc, &ipt_hash_info); + tcf_hash_insert(pc, a->ops->hinfo); return ret; err3: diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 376234ee8514455b92618f3f6066046627f0d2b9..0b2c6d39d39671f9f96f57528e35588816a62e88 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -101,12 +101,11 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, dev = NULL; } - pc = tcf_hash_check(parm->index, a, bind, &mirred_hash_info); + pc = tcf_hash_check(parm->index, a, bind); if (!pc) { if (dev == NULL) return -EINVAL; - pc = tcf_hash_create(parm->index, est, a, sizeof(*m), bind, - &mirred_hash_info); + pc = tcf_hash_create(parm->index, est, a, sizeof(*m), bind); if (IS_ERR(pc)) return PTR_ERR(pc); ret = ACT_P_CREATED; @@ -132,7 +131,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, spin_unlock_bh(&m->tcf_lock); if (ret == ACT_P_CREATED) { list_add(&m->tcfm_list, &mirred_list); - tcf_hash_insert(pc, &mirred_hash_info); + tcf_hash_insert(pc, a->ops->hinfo); } return ret; diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c index 46e1aa36b1470d28d2e833b68ebff45a96536ffa..81f0404bb33555244faf74504af4a8becf00d65a 100644 --- a/net/sched/act_nat.c +++ b/net/sched/act_nat.c @@ -57,17 +57,16 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est, return -EINVAL; parm = nla_data(tb[TCA_NAT_PARMS]); - pc = tcf_hash_check(parm->index, a, bind, &nat_hash_info); + pc = tcf_hash_check(parm->index, a, bind); if (!pc) { - pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind, - &nat_hash_info); + pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind); if (IS_ERR(pc)) return PTR_ERR(pc); ret = ACT_P_CREATED; } else { if (bind) return 0; - tcf_hash_release(pc, bind, &nat_hash_info); + tcf_hash_release(pc, bind, a->ops->hinfo); if (!ovr) return -EEXIST; } @@ -83,7 +82,7 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est, spin_unlock_bh(&p->tcf_lock); if (ret == ACT_P_CREATED) - tcf_hash_insert(pc, &nat_hash_info); + tcf_hash_insert(pc, a->ops->hinfo); return ret; } diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 109265d7c14b2da982c0bf5bafc6af482c41aa91..be3f0f6875bb1b594f35685336d41d1a3fe62515 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c @@ -57,12 +57,11 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, if (nla_len(tb[TCA_PEDIT_PARMS]) < sizeof(*parm) + ksize) return -EINVAL; - pc = tcf_hash_check(parm->index, a, bind, &pedit_hash_info); + pc = tcf_hash_check(parm->index, a, bind); if (!pc) { if (!parm->nkeys) return -EINVAL; - pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind, - &pedit_hash_info); + pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind); if (IS_ERR(pc)) return PTR_ERR(pc); p = to_pedit(pc); @@ -77,7 +76,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, ret = ACT_P_CREATED; } else { p = to_pedit(pc); - tcf_hash_release(pc, bind, &pedit_hash_info); + tcf_hash_release(pc, bind, a->ops->hinfo); if (bind) return 0; if (!ovr) @@ -101,7 +100,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, memcpy(p->tcfp_keys, parm->keys, ksize); spin_unlock_bh(&p->tcf_lock); if (ret == ACT_P_CREATED) - tcf_hash_insert(pc, &pedit_hash_info); + tcf_hash_insert(pc, a->ops->hinfo); return ret; } diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 85437ba5c64b1baf55a88eca8e40106f2284f929..c7093896cf1406b5505f4e9575d1849739d185a5 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -59,17 +59,18 @@ struct tc_police_compat { static int tcf_act_police_walker(struct sk_buff *skb, struct netlink_callback *cb, int type, struct tc_action *a) { + struct tcf_hashinfo *hinfo = a->ops->hinfo; struct hlist_head *head; struct tcf_common *p; int err = 0, index = -1, i = 0, s_i = 0, n_i = 0; struct nlattr *nest; - spin_lock_bh(&police_hash_info.lock); + spin_lock_bh(&hinfo->lock); s_i = cb->args[0]; for (i = 0; i < (POL_TAB_MASK + 1); i++) { - head = &police_hash_info.htab[tcf_hash(i, POL_TAB_MASK)]; + head = &hinfo->htab[tcf_hash(i, POL_TAB_MASK)]; hlist_for_each_entry_rcu(p, head, tcfc_head) { index++; @@ -94,7 +95,7 @@ static int tcf_act_police_walker(struct sk_buff *skb, struct netlink_callback *c } } done: - spin_unlock_bh(&police_hash_info.lock); + spin_unlock_bh(&hinfo->lock); if (n_i) cb->args[0] += n_i; return n_i; @@ -121,6 +122,7 @@ static int tcf_act_police_locate(struct net *net, struct nlattr *nla, struct tc_police *parm; struct tcf_police *police; struct qdisc_rate_table *R_tab = NULL, *P_tab = NULL; + struct tcf_hashinfo *hinfo = a->ops->hinfo; int size; if (nla == NULL) @@ -140,7 +142,7 @@ static int tcf_act_police_locate(struct net *net, struct nlattr *nla, if (parm->index) { struct tcf_common *pc; - pc = tcf_hash_lookup(parm->index, &police_hash_info); + pc = tcf_hash_lookup(parm->index, hinfo); if (pc != NULL) { a->priv = pc; police = to_police(pc); @@ -236,11 +238,11 @@ static int tcf_act_police_locate(struct net *net, struct nlattr *nla, police->tcfp_t_c = ktime_to_ns(ktime_get()); police->tcf_index = parm->index ? parm->index : - tcf_hash_new_index(&police_hash_info); + tcf_hash_new_index(a->ops->hinfo); h = tcf_hash(police->tcf_index, POL_TAB_MASK); - spin_lock_bh(&police_hash_info.lock); - hlist_add_head(&police->tcf_head, &police_hash_info.htab[h]); - spin_unlock_bh(&police_hash_info.lock); + spin_lock_bh(&hinfo->lock); + hlist_add_head(&police->tcf_head, &hinfo->htab[h]); + spin_unlock_bh(&hinfo->lock); a->priv = police; return ret; diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c index 92236daaac8d1a93a7145dfc33f2a4327ba1db67..8ef2f1fcbfba20d9dcf853f21e1101b0ff363108 100644 --- a/net/sched/act_simple.c +++ b/net/sched/act_simple.c @@ -114,10 +114,9 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, parm = nla_data(tb[TCA_DEF_PARMS]); defdata = nla_data(tb[TCA_DEF_DATA]); - pc = tcf_hash_check(parm->index, a, bind, &simp_hash_info); + pc = tcf_hash_check(parm->index, a, bind); if (!pc) { - pc = tcf_hash_create(parm->index, est, a, sizeof(*d), bind, - &simp_hash_info); + pc = tcf_hash_create(parm->index, est, a, sizeof(*d), bind); if (IS_ERR(pc)) return PTR_ERR(pc); @@ -145,7 +144,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, } if (ret == ACT_P_CREATED) - tcf_hash_insert(pc, &simp_hash_info); + tcf_hash_insert(pc, a->ops->hinfo); return ret; } diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c index c36b5209bc15ab419deb89560d86bd24c9ec0a45..98725080b5aa73a1d402a704a5a316eead4410a8 100644 --- a/net/sched/act_skbedit.c +++ b/net/sched/act_skbedit.c @@ -100,10 +100,9 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, parm = nla_data(tb[TCA_SKBEDIT_PARMS]); - pc = tcf_hash_check(parm->index, a, bind, &skbedit_hash_info); + pc = tcf_hash_check(parm->index, a, bind); if (!pc) { - pc = tcf_hash_create(parm->index, est, a, sizeof(*d), bind, - &skbedit_hash_info); + pc = tcf_hash_create(parm->index, est, a, sizeof(*d), bind); if (IS_ERR(pc)) return PTR_ERR(pc); @@ -113,7 +112,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, d = to_skbedit(pc); if (bind) return 0; - tcf_hash_release(pc, bind, &skbedit_hash_info); + tcf_hash_release(pc, bind, a->ops->hinfo); if (!ovr) return -EEXIST; } @@ -133,7 +132,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, spin_unlock_bh(&d->tcf_lock); if (ret == ACT_P_CREATED) - tcf_hash_insert(pc, &skbedit_hash_info); + tcf_hash_insert(pc, a->ops->hinfo); return ret; }