pkt_sched: namespace aware act_mirred

Eric Dumazet pointed out that act_mirred needs to find the current net_ns,
and struct net pointer is not provided in the call chain.  His original
patch made use of current->nsproxy->net_ns to find the network namespace,
but this fails to work correctly for userspace code that makes use of
netlink sockets in different network namespaces.  Instead, pass the
"struct net *" down along the call chain to where it is needed.

This version removes the ifb changes as Eric has submitted that patch
separately, but is otherwise identical to the previous version.

Signed-off-by: Benjamin LaHaise <bcrl@kvack.org>
Tested-by: Eric Dumazet <eric.dumazet@gmail.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Benjamin LaHaise 2013-01-14 05:15:39 +00:00 коммит произвёл David S. Miller
Родитель 6059283378
Коммит c1b52739e4
22 изменённых файлов: 94 добавлений и 72 удалений

Просмотреть файл

@ -91,7 +91,9 @@ struct tc_action_ops {
int (*dump)(struct sk_buff *, struct tc_action *, int, int);
int (*cleanup)(struct tc_action *, int bind);
int (*lookup)(struct tc_action *, u32);
int (*init)(struct nlattr *, struct nlattr *, struct tc_action *, int , int);
int (*init)(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action *act, int ovr,
int bind);
int (*walk)(struct sk_buff *, struct netlink_callback *, int, struct tc_action *);
};
@ -116,8 +118,12 @@ extern int tcf_register_action(struct tc_action_ops *a);
extern int tcf_unregister_action(struct tc_action_ops *a);
extern void tcf_action_destroy(struct tc_action *a, int bind);
extern int tcf_action_exec(struct sk_buff *skb, const struct tc_action *a, struct tcf_result *res);
extern struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est, char *n, int ovr, int bind);
extern struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est, char *n, int ovr, int bind);
extern struct tc_action *tcf_action_init(struct net *net, struct nlattr *nla,
struct nlattr *est, char *n, int ovr,
int bind);
extern struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla,
struct nlattr *est, char *n, int ovr,
int bind);
extern int tcf_action_dump(struct sk_buff *skb, struct tc_action *a, int, int);
extern int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int);
extern int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int);

Просмотреть файл

@ -126,8 +126,9 @@ tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
return 0;
}
extern int tcf_exts_validate(struct tcf_proto *tp, struct nlattr **tb,
struct nlattr *rate_tlv, struct tcf_exts *exts,
extern int tcf_exts_validate(struct net *net, struct tcf_proto *tp,
struct nlattr **tb, struct nlattr *rate_tlv,
struct tcf_exts *exts,
const struct tcf_ext_map *map);
extern void tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts);
extern void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,

Просмотреть файл

@ -195,7 +195,7 @@ struct tcf_proto_ops {
unsigned long (*get)(struct tcf_proto*, u32 handle);
void (*put)(struct tcf_proto*, unsigned long);
int (*change)(struct sk_buff *,
int (*change)(struct net *net, struct sk_buff *,
struct tcf_proto*, unsigned long,
u32 handle, struct nlattr **,
unsigned long *);

Просмотреть файл

@ -485,8 +485,9 @@ errout:
return err;
}
struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est,
char *name, int ovr, int bind)
struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla,
struct nlattr *est, char *name, int ovr,
int bind)
{
struct tc_action *a;
struct tc_action_ops *a_o;
@ -542,9 +543,9 @@ struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est,
/* backward compatibility for policer */
if (name == NULL)
err = a_o->init(tb[TCA_ACT_OPTIONS], est, a, ovr, bind);
err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, a, ovr, bind);
else
err = a_o->init(nla, est, a, ovr, bind);
err = a_o->init(net, nla, est, a, ovr, bind);
if (err < 0)
goto err_free;
@ -566,8 +567,9 @@ err_out:
return ERR_PTR(err);
}
struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est,
char *name, int ovr, int bind)
struct tc_action *tcf_action_init(struct net *net, struct nlattr *nla,
struct nlattr *est, char *name, int ovr,
int bind)
{
struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
struct tc_action *head = NULL, *act, *act_prev = NULL;
@ -579,7 +581,7 @@ struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est,
return ERR_PTR(err);
for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
act = tcf_action_init_1(tb[i], est, name, ovr, bind);
act = tcf_action_init_1(net, tb[i], est, name, ovr, bind);
if (IS_ERR(act))
goto err;
act->order = i;
@ -960,7 +962,7 @@ tcf_action_add(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
struct tc_action *a;
u32 seq = n->nlmsg_seq;
act = tcf_action_init(nla, NULL, NULL, ovr, 0);
act = tcf_action_init(net, nla, NULL, NULL, ovr, 0);
if (act == NULL)
goto done;
if (IS_ERR(act)) {

Просмотреть файл

@ -51,7 +51,7 @@ static const struct nla_policy csum_policy[TCA_CSUM_MAX + 1] = {
[TCA_CSUM_PARMS] = { .len = sizeof(struct tc_csum), },
};
static int tcf_csum_init(struct nlattr *nla, struct nlattr *est,
static int tcf_csum_init(struct net *n, struct nlattr *nla, struct nlattr *est,
struct tc_action *a, int ovr, int bind)
{
struct nlattr *tb[TCA_CSUM_MAX + 1];

Просмотреть файл

@ -58,8 +58,9 @@ static const struct nla_policy gact_policy[TCA_GACT_MAX + 1] = {
[TCA_GACT_PROB] = { .len = sizeof(struct tc_gact_p) },
};
static int tcf_gact_init(struct nlattr *nla, struct nlattr *est,
struct tc_action *a, int ovr, int bind)
static int tcf_gact_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action *a,
int ovr, int bind)
{
struct nlattr *tb[TCA_GACT_MAX + 1];
struct tc_gact *parm;

Просмотреть файл

@ -102,7 +102,7 @@ static const struct nla_policy ipt_policy[TCA_IPT_MAX + 1] = {
[TCA_IPT_TARG] = { .len = sizeof(struct xt_entry_target) },
};
static int tcf_ipt_init(struct nlattr *nla, struct nlattr *est,
static int tcf_ipt_init(struct net *net, struct nlattr *nla, struct nlattr *est,
struct tc_action *a, int ovr, int bind)
{
struct nlattr *tb[TCA_IPT_MAX + 1];

Просмотреть файл

@ -62,8 +62,9 @@ static const struct nla_policy mirred_policy[TCA_MIRRED_MAX + 1] = {
[TCA_MIRRED_PARMS] = { .len = sizeof(struct tc_mirred) },
};
static int tcf_mirred_init(struct nlattr *nla, struct nlattr *est,
struct tc_action *a, int ovr, int bind)
static int tcf_mirred_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action *a, int ovr,
int bind)
{
struct nlattr *tb[TCA_MIRRED_MAX + 1];
struct tc_mirred *parm;
@ -88,7 +89,7 @@ static int tcf_mirred_init(struct nlattr *nla, struct nlattr *est,
return -EINVAL;
}
if (parm->ifindex) {
dev = __dev_get_by_index(&init_net, parm->ifindex);
dev = __dev_get_by_index(net, parm->ifindex);
if (dev == NULL)
return -ENODEV;
switch (dev->type) {

Просмотреть файл

@ -44,7 +44,7 @@ static const struct nla_policy nat_policy[TCA_NAT_MAX + 1] = {
[TCA_NAT_PARMS] = { .len = sizeof(struct tc_nat) },
};
static int tcf_nat_init(struct nlattr *nla, struct nlattr *est,
static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est,
struct tc_action *a, int ovr, int bind)
{
struct nlattr *tb[TCA_NAT_MAX + 1];

Просмотреть файл

@ -38,8 +38,9 @@ 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 nlattr *nla, struct nlattr *est,
struct tc_action *a, int ovr, int bind)
static int tcf_pedit_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action *a,
int ovr, int bind)
{
struct nlattr *tb[TCA_PEDIT_MAX + 1];
struct tc_pedit *parm;

Просмотреть файл

@ -130,8 +130,9 @@ static const struct nla_policy police_policy[TCA_POLICE_MAX + 1] = {
[TCA_POLICE_RESULT] = { .type = NLA_U32 },
};
static int tcf_act_police_locate(struct nlattr *nla, struct nlattr *est,
struct tc_action *a, int ovr, int bind)
static int tcf_act_police_locate(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action *a,
int ovr, int bind)
{
unsigned int h;
int ret = 0, err;

Просмотреть файл

@ -95,8 +95,9 @@ static const struct nla_policy simple_policy[TCA_DEF_MAX + 1] = {
[TCA_DEF_DATA] = { .type = NLA_STRING, .len = SIMP_MAX_DATA },
};
static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
struct tc_action *a, int ovr, int bind)
static int tcf_simp_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action *a,
int ovr, int bind)
{
struct nlattr *tb[TCA_DEF_MAX + 1];
struct tc_defact *parm;

Просмотреть файл

@ -67,8 +67,9 @@ static const struct nla_policy skbedit_policy[TCA_SKBEDIT_MAX + 1] = {
[TCA_SKBEDIT_MARK] = { .len = sizeof(u32) },
};
static int tcf_skbedit_init(struct nlattr *nla, struct nlattr *est,
struct tc_action *a, int ovr, int bind)
static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action *a,
int ovr, int bind)
{
struct nlattr *tb[TCA_SKBEDIT_MAX + 1];
struct tc_skbedit *parm;

Просмотреть файл

@ -321,7 +321,7 @@ replay:
}
}
err = tp->ops->change(skb, tp, cl, t->tcm_handle, tca, &fh);
err = tp->ops->change(net, skb, tp, cl, t->tcm_handle, tca, &fh);
if (err == 0) {
if (tp_created) {
spin_lock_bh(root_lock);
@ -508,7 +508,7 @@ void tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts)
}
EXPORT_SYMBOL(tcf_exts_destroy);
int tcf_exts_validate(struct tcf_proto *tp, struct nlattr **tb,
int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
struct nlattr *rate_tlv, struct tcf_exts *exts,
const struct tcf_ext_map *map)
{
@ -519,7 +519,7 @@ int tcf_exts_validate(struct tcf_proto *tp, struct nlattr **tb,
struct tc_action *act;
if (map->police && tb[map->police]) {
act = tcf_action_init_1(tb[map->police], rate_tlv,
act = tcf_action_init_1(net, tb[map->police], rate_tlv,
"police", TCA_ACT_NOREPLACE,
TCA_ACT_BIND);
if (IS_ERR(act))
@ -528,8 +528,9 @@ int tcf_exts_validate(struct tcf_proto *tp, struct nlattr **tb,
act->type = TCA_OLD_COMPAT;
exts->action = act;
} else if (map->action && tb[map->action]) {
act = tcf_action_init(tb[map->action], rate_tlv, NULL,
TCA_ACT_NOREPLACE, TCA_ACT_BIND);
act = tcf_action_init(net, tb[map->action], rate_tlv,
NULL, TCA_ACT_NOREPLACE,
TCA_ACT_BIND);
if (IS_ERR(act))
return PTR_ERR(act);

Просмотреть файл

@ -132,15 +132,16 @@ static const struct nla_policy basic_policy[TCA_BASIC_MAX + 1] = {
[TCA_BASIC_EMATCHES] = { .type = NLA_NESTED },
};
static int basic_set_parms(struct tcf_proto *tp, struct basic_filter *f,
unsigned long base, struct nlattr **tb,
static int basic_set_parms(struct net *net, struct tcf_proto *tp,
struct basic_filter *f, unsigned long base,
struct nlattr **tb,
struct nlattr *est)
{
int err = -EINVAL;
struct tcf_exts e;
struct tcf_ematch_tree t;
err = tcf_exts_validate(tp, tb, est, &e, &basic_ext_map);
err = tcf_exts_validate(net, tp, tb, est, &e, &basic_ext_map);
if (err < 0)
return err;
@ -162,7 +163,7 @@ errout:
return err;
}
static int basic_change(struct sk_buff *in_skb,
static int basic_change(struct net *net, struct sk_buff *in_skb,
struct tcf_proto *tp, unsigned long base, u32 handle,
struct nlattr **tca, unsigned long *arg)
{
@ -182,7 +183,7 @@ static int basic_change(struct sk_buff *in_skb,
if (f != NULL) {
if (handle && f->handle != handle)
return -EINVAL;
return basic_set_parms(tp, f, base, tb, tca[TCA_RATE]);
return basic_set_parms(net, tp, f, base, tb, tca[TCA_RATE]);
}
err = -ENOBUFS;
@ -208,7 +209,7 @@ static int basic_change(struct sk_buff *in_skb,
f->handle = head->hgenerator;
}
err = basic_set_parms(tp, f, base, tb, tca[TCA_RATE]);
err = basic_set_parms(net, tp, f, base, tb, tca[TCA_RATE]);
if (err < 0)
goto errout;

Просмотреть файл

@ -178,7 +178,7 @@ static const struct nla_policy cgroup_policy[TCA_CGROUP_MAX + 1] = {
[TCA_CGROUP_EMATCHES] = { .type = NLA_NESTED },
};
static int cls_cgroup_change(struct sk_buff *in_skb,
static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
struct tcf_proto *tp, unsigned long base,
u32 handle, struct nlattr **tca,
unsigned long *arg)
@ -215,7 +215,8 @@ static int cls_cgroup_change(struct sk_buff *in_skb,
if (err < 0)
return err;
err = tcf_exts_validate(tp, tb, tca[TCA_RATE], &e, &cgroup_ext_map);
err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e,
&cgroup_ext_map);
if (err < 0)
return err;

Просмотреть файл

@ -351,7 +351,7 @@ static const struct nla_policy flow_policy[TCA_FLOW_MAX + 1] = {
[TCA_FLOW_PERTURB] = { .type = NLA_U32 },
};
static int flow_change(struct sk_buff *in_skb,
static int flow_change(struct net *net, struct sk_buff *in_skb,
struct tcf_proto *tp, unsigned long base,
u32 handle, struct nlattr **tca,
unsigned long *arg)
@ -397,7 +397,7 @@ static int flow_change(struct sk_buff *in_skb,
return -EOPNOTSUPP;
}
err = tcf_exts_validate(tp, tb, tca[TCA_RATE], &e, &flow_ext_map);
err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, &flow_ext_map);
if (err < 0)
return err;

Просмотреть файл

@ -192,7 +192,7 @@ static const struct nla_policy fw_policy[TCA_FW_MAX + 1] = {
};
static int
fw_change_attrs(struct tcf_proto *tp, struct fw_filter *f,
fw_change_attrs(struct net *net, struct tcf_proto *tp, struct fw_filter *f,
struct nlattr **tb, struct nlattr **tca, unsigned long base)
{
struct fw_head *head = (struct fw_head *)tp->root;
@ -200,7 +200,7 @@ fw_change_attrs(struct tcf_proto *tp, struct fw_filter *f,
u32 mask;
int err;
err = tcf_exts_validate(tp, tb, tca[TCA_RATE], &e, &fw_ext_map);
err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, &fw_ext_map);
if (err < 0)
return err;
@ -233,7 +233,7 @@ errout:
return err;
}
static int fw_change(struct sk_buff *in_skb,
static int fw_change(struct net *net, struct sk_buff *in_skb,
struct tcf_proto *tp, unsigned long base,
u32 handle,
struct nlattr **tca,
@ -255,7 +255,7 @@ static int fw_change(struct sk_buff *in_skb,
if (f != NULL) {
if (f->id != handle && handle)
return -EINVAL;
return fw_change_attrs(tp, f, tb, tca, base);
return fw_change_attrs(net, tp, f, tb, tca, base);
}
if (!handle)
@ -282,7 +282,7 @@ static int fw_change(struct sk_buff *in_skb,
f->id = handle;
err = fw_change_attrs(tp, f, tb, tca, base);
err = fw_change_attrs(net, tp, f, tb, tca, base);
if (err < 0)
goto errout;

Просмотреть файл

@ -335,8 +335,9 @@ static const struct nla_policy route4_policy[TCA_ROUTE4_MAX + 1] = {
[TCA_ROUTE4_IIF] = { .type = NLA_U32 },
};
static int route4_set_parms(struct tcf_proto *tp, unsigned long base,
struct route4_filter *f, u32 handle, struct route4_head *head,
static int route4_set_parms(struct net *net, struct tcf_proto *tp,
unsigned long base, struct route4_filter *f,
u32 handle, struct route4_head *head,
struct nlattr **tb, struct nlattr *est, int new)
{
int err;
@ -346,7 +347,7 @@ static int route4_set_parms(struct tcf_proto *tp, unsigned long base,
struct route4_bucket *b;
struct tcf_exts e;
err = tcf_exts_validate(tp, tb, est, &e, &route_ext_map);
err = tcf_exts_validate(net, tp, tb, est, &e, &route_ext_map);
if (err < 0)
return err;
@ -427,7 +428,7 @@ errout:
return err;
}
static int route4_change(struct sk_buff *in_skb,
static int route4_change(struct net *net, struct sk_buff *in_skb,
struct tcf_proto *tp, unsigned long base,
u32 handle,
struct nlattr **tca,
@ -457,7 +458,7 @@ static int route4_change(struct sk_buff *in_skb,
if (f->bkt)
old_handle = f->handle;
err = route4_set_parms(tp, base, f, handle, head, tb,
err = route4_set_parms(net, tp, base, f, handle, head, tb,
tca[TCA_RATE], 0);
if (err < 0)
return err;
@ -480,7 +481,7 @@ static int route4_change(struct sk_buff *in_skb,
if (f == NULL)
goto errout;
err = route4_set_parms(tp, base, f, handle, head, tb,
err = route4_set_parms(net, tp, base, f, handle, head, tb,
tca[TCA_RATE], 1);
if (err < 0)
goto errout;

Просмотреть файл

@ -416,7 +416,7 @@ static const struct nla_policy rsvp_policy[TCA_RSVP_MAX + 1] = {
[TCA_RSVP_PINFO] = { .len = sizeof(struct tc_rsvp_pinfo) },
};
static int rsvp_change(struct sk_buff *in_skb,
static int rsvp_change(struct net *net, struct sk_buff *in_skb,
struct tcf_proto *tp, unsigned long base,
u32 handle,
struct nlattr **tca,
@ -440,7 +440,7 @@ static int rsvp_change(struct sk_buff *in_skb,
if (err < 0)
return err;
err = tcf_exts_validate(tp, tb, tca[TCA_RATE], &e, &rsvp_ext_map);
err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, &rsvp_ext_map);
if (err < 0)
return err;

Просмотреть файл

@ -197,9 +197,10 @@ static const struct nla_policy tcindex_policy[TCA_TCINDEX_MAX + 1] = {
};
static int
tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle,
struct tcindex_data *p, struct tcindex_filter_result *r,
struct nlattr **tb, struct nlattr *est)
tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
u32 handle, struct tcindex_data *p,
struct tcindex_filter_result *r, struct nlattr **tb,
struct nlattr *est)
{
int err, balloc = 0;
struct tcindex_filter_result new_filter_result, *old_r = r;
@ -208,7 +209,7 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle,
struct tcindex_filter *f = NULL; /* make gcc behave */
struct tcf_exts e;
err = tcf_exts_validate(tp, tb, est, &e, &tcindex_ext_map);
err = tcf_exts_validate(net, tp, tb, est, &e, &tcindex_ext_map);
if (err < 0)
return err;
@ -332,7 +333,7 @@ errout:
}
static int
tcindex_change(struct sk_buff *in_skb,
tcindex_change(struct net *net, struct sk_buff *in_skb,
struct tcf_proto *tp, unsigned long base, u32 handle,
struct nlattr **tca, unsigned long *arg)
{
@ -353,7 +354,8 @@ tcindex_change(struct sk_buff *in_skb,
if (err < 0)
return err;
return tcindex_set_parms(tp, base, handle, p, r, tb, tca[TCA_RATE]);
return tcindex_set_parms(net, tp, base, handle, p, r, tb,
tca[TCA_RATE]);
}

Просмотреть файл

@ -488,15 +488,15 @@ static const struct nla_policy u32_policy[TCA_U32_MAX + 1] = {
[TCA_U32_MARK] = { .len = sizeof(struct tc_u32_mark) },
};
static int u32_set_parms(struct tcf_proto *tp, unsigned long base,
struct tc_u_hnode *ht,
static int u32_set_parms(struct net *net, struct tcf_proto *tp,
unsigned long base, struct tc_u_hnode *ht,
struct tc_u_knode *n, struct nlattr **tb,
struct nlattr *est)
{
int err;
struct tcf_exts e;
err = tcf_exts_validate(tp, tb, est, &e, &u32_ext_map);
err = tcf_exts_validate(net, tp, tb, est, &e, &u32_ext_map);
if (err < 0)
return err;
@ -544,7 +544,7 @@ errout:
return err;
}
static int u32_change(struct sk_buff *in_skb,
static int u32_change(struct net *net, struct sk_buff *in_skb,
struct tcf_proto *tp, unsigned long base, u32 handle,
struct nlattr **tca,
unsigned long *arg)
@ -570,7 +570,8 @@ static int u32_change(struct sk_buff *in_skb,
if (TC_U32_KEY(n->handle) == 0)
return -EINVAL;
return u32_set_parms(tp, base, n->ht_up, n, tb, tca[TCA_RATE]);
return u32_set_parms(net, tp, base, n->ht_up, n, tb,
tca[TCA_RATE]);
}
if (tb[TCA_U32_DIVISOR]) {
@ -656,7 +657,7 @@ static int u32_change(struct sk_buff *in_skb,
}
#endif
err = u32_set_parms(tp, base, ht, n, tb, tca[TCA_RATE]);
err = u32_set_parms(net, tp, base, ht, n, tb, tca[TCA_RATE]);
if (err == 0) {
struct tc_u_knode **ins;
for (ins = &ht->ht[TC_U32_HASH(handle)]; *ins; ins = &(*ins)->next)