Release 4.7 net/sched/act_pedit.c
/*
* net/sched/act_pedit.c Generic packet editor
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Authors: Jamal Hadi Salim (2002-4)
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/skbuff.h>
#include <linux/rtnetlink.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <net/netlink.h>
#include <net/pkt_sched.h>
#include <linux/tc_act/tc_pedit.h>
#include <net/tc_act/tc_pedit.h>
#define PEDIT_TAB_MASK 15
static int pedit_net_id;
static const struct nla_policy pedit_policy[TCA_PEDIT_MAX + 1] = {
[TCA_PEDIT_PARMS] = { .len = sizeof(struct tc_pedit) },
};
static int tcf_pedit_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, pedit_net_id);
struct nlattr *tb[TCA_PEDIT_MAX + 1];
struct tc_pedit *parm;
int ret = 0, err;
struct tcf_pedit *p;
struct tc_pedit_key *keys = NULL;
int ksize;
if (nla == NULL)
return -EINVAL;
err = nla_parse_nested(tb, TCA_PEDIT_MAX, nla, pedit_policy);
if (err < 0)
return err;
if (tb[TCA_PEDIT_PARMS] == NULL)
return -EINVAL;
parm = nla_data(tb[TCA_PEDIT_PARMS]);
ksize = parm->nkeys * sizeof(struct tc_pedit_key);
if (nla_len(tb[TCA_PEDIT_PARMS]) < sizeof(*parm) + ksize)
return -EINVAL;
if (!tcf_hash_check(tn, parm->index, a, bind)) {
if (!parm->nkeys)
return -EINVAL;
ret = tcf_hash_create(tn, parm->index, est, a,
sizeof(*p), bind, false);
if (ret)
return ret;
p = to_pedit(a);
keys = kmalloc(ksize, GFP_KERNEL);
if (keys == NULL) {
tcf_hash_cleanup(a, est);
return -ENOMEM;
}
ret = ACT_P_CREATED;
} else {
if (bind)
return 0;
tcf_hash_release(a, bind);
if (!ovr)
return -EEXIST;
p = to_pedit(a);
if (p->tcfp_nkeys && p->tcfp_nkeys != parm->nkeys) {
keys = kmalloc(ksize, GFP_KERNEL);
if (keys == NULL)
return -ENOMEM;
}
}
spin_lock_bh(&p->tcf_lock);
p->tcfp_flags = parm->flags;
p->tcf_action = parm->action;
if (keys) {
kfree(p->tcfp_keys);
p->tcfp_keys = keys;
p->tcfp_nkeys = parm->nkeys;
}
memcpy(p->tcfp_keys, parm->keys, ksize);
spin_unlock_bh(&p->tcf_lock);
if (ret == ACT_P_CREATED)
tcf_hash_insert(tn, a);
return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
patrick mchardy | patrick mchardy | 194 | 45.54% | 6 | 37.50% |
jamal hadi salim | jamal hadi salim | 165 | 38.73% | 2 | 12.50% |
americo wang | americo wang | 43 | 10.09% | 4 | 25.00% |
david s. miller | david s. miller | 16 | 3.76% | 1 | 6.25% |
benjamin lahaise | benjamin lahaise | 5 | 1.17% | 1 | 6.25% |
eric dumazet | eric dumazet | 2 | 0.47% | 1 | 6.25% |
hiroaki shimoda | hiroaki shimoda | 1 | 0.23% | 1 | 6.25% |
| Total | 426 | 100.00% | 16 | 100.00% |
static void tcf_pedit_cleanup(struct tc_action *a, int bind)
{
struct tcf_pedit *p = a->priv;
struct tc_pedit_key *keys = p->tcfp_keys;
kfree(keys);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jamal hadi salim | jamal hadi salim | 17 | 45.95% | 1 | 16.67% |
patrick mchardy | patrick mchardy | 16 | 43.24% | 3 | 50.00% |
david s. miller | david s. miller | 3 | 8.11% | 1 | 16.67% |
americo wang | americo wang | 1 | 2.70% | 1 | 16.67% |
| Total | 37 | 100.00% | 6 | 100.00% |
static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a,
struct tcf_result *res)
{
struct tcf_pedit *p = a->priv;
int i;
unsigned int off;
if (skb_unclone(skb, GFP_ATOMIC))
return p->tcf_action;
off = skb_network_offset(skb);
spin_lock(&p->tcf_lock);
p->tcf_tm.lastuse = jiffies;
if (p->tcfp_nkeys > 0) {
struct tc_pedit_key *tkey = p->tcfp_keys;
for (i = p->tcfp_nkeys; i > 0; i--, tkey++) {
u32 *ptr, _data;
int offset = tkey->off;
if (tkey->offmask) {
char *d, _d;
d = skb_header_pointer(skb, off + tkey->at, 1,
&_d);
if (!d)
goto bad;
offset += (*d & tkey->offmask) >> tkey->shift;
}
if (offset % 4) {
pr_info("tc filter pedit"
" offset must be on 32 bit boundaries\n");
goto bad;
}
if (offset > 0 && offset > skb->len) {
pr_info("tc filter pedit"
" offset %d can't exceed pkt length %d\n",
offset, skb->len);
goto bad;
}
ptr = skb_header_pointer(skb, off + offset, 4, &_data);
if (!ptr)
goto bad;
/* just do it, baby */
*ptr = ((*ptr & tkey->mask) ^ tkey->val);
if (ptr == &_data)
skb_store_bits(skb, off + offset, ptr, 4);
}
goto done;
} else
WARN(1, "pedit BUG: index %d\n", p->tcf_index);
bad:
p->tcf_qstats.overlimits++;
done:
bstats_update(&p->tcf_bstats, skb);
spin_unlock(&p->tcf_lock);
return p->tcf_action;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jamal hadi salim | jamal hadi salim | 225 | 66.18% | 2 | 13.33% |
changli gao | changli gao | 73 | 21.47% | 1 | 6.67% |
david s. miller | david s. miller | 13 | 3.82% | 1 | 6.67% |
patrick mchardy | patrick mchardy | 11 | 3.24% | 4 | 26.67% |
stephen hemminger | stephen hemminger | 8 | 2.35% | 1 | 6.67% |
eric dumazet | eric dumazet | 5 | 1.47% | 2 | 13.33% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 2 | 0.59% | 1 | 6.67% |
pravin b shelar | pravin b shelar | 1 | 0.29% | 1 | 6.67% |
lucas de marchi | lucas de marchi | 1 | 0.29% | 1 | 6.67% |
jussi kivilinna | jussi kivilinna | 1 | 0.29% | 1 | 6.67% |
| Total | 340 | 100.00% | 15 | 100.00% |
static int tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a,
int bind, int ref)
{
unsigned char *b = skb_tail_pointer(skb);
struct tcf_pedit *p = a->priv;
struct tc_pedit *opt;
struct tcf_t t;
int s;
s = sizeof(*opt) + p->tcfp_nkeys * sizeof(struct tc_pedit_key);
/* netlink spinlocks held above us - must use ATOMIC */
opt = kzalloc(s, GFP_ATOMIC);
if (unlikely(!opt))
return -ENOBUFS;
memcpy(opt->keys, p->tcfp_keys,
p->tcfp_nkeys * sizeof(struct tc_pedit_key));
opt->index = p->tcf_index;
opt->nkeys = p->tcfp_nkeys;
opt->flags = p->tcfp_flags;
opt->action = p->tcf_action;
opt->refcnt = p->tcf_refcnt - ref;
opt->bindcnt = p->tcf_bindcnt - bind;
if (nla_put(skb, TCA_PEDIT_PARMS, s, opt))
goto nla_put_failure;
t.install = jiffies_to_clock_t(jiffies - p->tcf_tm.install);
t.lastuse = jiffies_to_clock_t(jiffies - p->tcf_tm.lastuse);
t.expires = jiffies_to_clock_t(p->tcf_tm.expires);
if (nla_put_64bit(skb, TCA_PEDIT_TM, sizeof(t), &t, TCA_PEDIT_PAD))
goto nla_put_failure;
kfree(opt);
return skb->len;
nla_put_failure:
nlmsg_trim(skb, b);
kfree(opt);
return -1;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jamal hadi salim | jamal hadi salim | 207 | 75.27% | 1 | 8.33% |
david s. miller | david s. miller | 36 | 13.09% | 2 | 16.67% |
patrick mchardy | patrick mchardy | 24 | 8.73% | 5 | 41.67% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 4 | 1.45% | 2 | 16.67% |
nicolas dichtel | nicolas dichtel | 3 | 1.09% | 1 | 8.33% |
panagiotis issaris* | panagiotis issaris* | 1 | 0.36% | 1 | 8.33% |
| Total | 275 | 100.00% | 12 | 100.00% |
static int tcf_pedit_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, pedit_net_id);
return tcf_generic_walker(tn, skb, cb, type, a);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
americo wang | americo wang | 55 | 100.00% | 1 | 100.00% |
| Total | 55 | 100.00% | 1 | 100.00% |
static int tcf_pedit_search(struct net *net, struct tc_action *a, u32 index)
{
struct tc_action_net *tn = net_generic(net, pedit_net_id);
return tcf_hash_search(tn, a, index);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
americo wang | americo wang | 41 | 100.00% | 1 | 100.00% |
| Total | 41 | 100.00% | 1 | 100.00% |
static struct tc_action_ops act_pedit_ops = {
.kind = "pedit",
.type = TCA_ACT_PEDIT,
.owner = THIS_MODULE,
.act = tcf_pedit,
.dump = tcf_pedit_dump,
.cleanup = tcf_pedit_cleanup,
.init = tcf_pedit_init,
.walk = tcf_pedit_walker,
.lookup = tcf_pedit_search,
};
static __net_init int pedit_init_net(struct net *net)
{
struct tc_action_net *tn = net_generic(net, pedit_net_id);
return tc_action_net_init(tn, &act_pedit_ops, PEDIT_TAB_MASK);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
americo wang | americo wang | 35 | 100.00% | 1 | 100.00% |
| Total | 35 | 100.00% | 1 | 100.00% |
static void __net_exit pedit_exit_net(struct net *net)
{
struct tc_action_net *tn = net_generic(net, pedit_net_id);
tc_action_net_exit(tn);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
americo wang | americo wang | 29 | 100.00% | 1 | 100.00% |
| Total | 29 | 100.00% | 1 | 100.00% |
static struct pernet_operations pedit_net_ops = {
.init = pedit_init_net,
.exit = pedit_exit_net,
.id = &pedit_net_id,
.size = sizeof(struct tc_action_net),
};
MODULE_AUTHOR("Jamal Hadi Salim(2002-4)");
MODULE_DESCRIPTION("Generic Packet Editor actions");
MODULE_LICENSE("GPL");
static int __init pedit_init_module(void)
{
return tcf_register_action(&act_pedit_ops, &pedit_net_ops);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jamal hadi salim | jamal hadi salim | 16 | 84.21% | 1 | 33.33% |
americo wang | americo wang | 3 | 15.79% | 2 | 66.67% |
| Total | 19 | 100.00% | 3 | 100.00% |
static void __exit pedit_cleanup_module(void)
{
tcf_unregister_action(&act_pedit_ops, &pedit_net_ops);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jamal hadi salim | jamal hadi salim | 15 | 83.33% | 1 | 50.00% |
americo wang | americo wang | 3 | 16.67% | 1 | 50.00% |
| Total | 18 | 100.00% | 2 | 100.00% |
module_init(pedit_init_module);
module_exit(pedit_cleanup_module);
Overall Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jamal hadi salim | jamal hadi salim | 748 | 51.23% | 5 | 12.50% |
patrick mchardy | patrick mchardy | 272 | 18.63% | 10 | 25.00% |
americo wang | americo wang | 256 | 17.53% | 6 | 15.00% |
changli gao | changli gao | 73 | 5.00% | 1 | 2.50% |
david s. miller | david s. miller | 70 | 4.79% | 2 | 5.00% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 9 | 0.62% | 3 | 7.50% |
stephen hemminger | stephen hemminger | 8 | 0.55% | 1 | 2.50% |
eric dumazet | eric dumazet | 7 | 0.48% | 3 | 7.50% |
benjamin lahaise | benjamin lahaise | 5 | 0.34% | 1 | 2.50% |
nicolas dichtel | nicolas dichtel | 3 | 0.21% | 1 | 2.50% |
tejun heo | tejun heo | 3 | 0.21% | 1 | 2.50% |
hiroaki shimoda | hiroaki shimoda | 1 | 0.07% | 1 | 2.50% |
lucas de marchi | lucas de marchi | 1 | 0.07% | 1 | 2.50% |
jiri pirko | jiri pirko | 1 | 0.07% | 1 | 2.50% |
pravin b shelar | pravin b shelar | 1 | 0.07% | 1 | 2.50% |
panagiotis issaris* | panagiotis issaris* | 1 | 0.07% | 1 | 2.50% |
jussi kivilinna | jussi kivilinna | 1 | 0.07% | 1 | 2.50% |
| Total | 1460 | 100.00% | 40 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.