Skip to content

Commit

Permalink
[NET_SCHED]: Convert classifiers from rtnetlink to new netlink API
Browse files Browse the repository at this point in the history
Signed-off-by: Patrick McHardy <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
kaber authored and davem330 committed Jan 28, 2008
1 parent 1e90474 commit add93b6
Show file tree
Hide file tree
Showing 12 changed files with 290 additions and 282 deletions.
10 changes: 5 additions & 5 deletions include/net/pkt_cls.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
return 0;
}

extern int tcf_exts_validate(struct tcf_proto *tp, struct rtattr **tb,
struct rtattr *rate_tlv, struct tcf_exts *exts,
extern int tcf_exts_validate(struct tcf_proto *tp, struct nlattr **tb,
struct nlattr *rate_tlv, struct tcf_exts *exts,
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,
Expand Down Expand Up @@ -247,7 +247,7 @@ struct tcf_ematch_ops

extern int tcf_em_register(struct tcf_ematch_ops *);
extern int tcf_em_unregister(struct tcf_ematch_ops *);
extern int tcf_em_tree_validate(struct tcf_proto *, struct rtattr *,
extern int tcf_em_tree_validate(struct tcf_proto *, struct nlattr *,
struct tcf_ematch_tree *);
extern void tcf_em_tree_destroy(struct tcf_proto *, struct tcf_ematch_tree *);
extern int tcf_em_tree_dump(struct sk_buff *, struct tcf_ematch_tree *, int);
Expand Down Expand Up @@ -338,9 +338,9 @@ static inline int tcf_valid_offset(const struct sk_buff *skb,
#include <net/net_namespace.h>

static inline int
tcf_change_indev(struct tcf_proto *tp, char *indev, struct rtattr *indev_tlv)
tcf_change_indev(struct tcf_proto *tp, char *indev, struct nlattr *indev_tlv)
{
if (rtattr_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ)
if (nla_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ)
return -EINVAL;
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion include/net/sch_generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ struct tcf_proto_ops
unsigned long (*get)(struct tcf_proto*, u32 handle);
void (*put)(struct tcf_proto*, unsigned long);
int (*change)(struct tcf_proto*, unsigned long,
u32 handle, struct rtattr **,
u32 handle, struct nlattr **,
unsigned long *);
int (*delete)(struct tcf_proto*, unsigned long);
void (*walk)(struct tcf_proto*, struct tcf_walker *arg);
Expand Down
65 changes: 35 additions & 30 deletions net/sched/cls_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ static DEFINE_RWLOCK(cls_mod_lock);

/* Find classifier type by string name */

static struct tcf_proto_ops *tcf_proto_lookup_ops(struct rtattr *kind)
static struct tcf_proto_ops *tcf_proto_lookup_ops(struct nlattr *kind)
{
struct tcf_proto_ops *t = NULL;

if (kind) {
read_lock(&cls_mod_lock);
for (t = tcf_proto_base; t; t = t->next) {
if (rtattr_strcmp(kind, t->kind) == 0) {
if (nla_strcmp(kind, t->kind) == 0) {
if (!try_module_get(t->owner))
t = NULL;
break;
Expand Down Expand Up @@ -118,7 +118,7 @@ static inline u32 tcf_auto_prio(struct tcf_proto *tp)
static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
{
struct net *net = skb->sk->sk_net;
struct rtattr **tca;
struct nlattr *tca[TCA_MAX + 1];
struct tcmsg *t;
u32 protocol;
u32 prio;
Expand All @@ -138,7 +138,6 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
return -EINVAL;

replay:
tca = arg;
t = NLMSG_DATA(n);
protocol = TC_H_MIN(t->tcm_info);
prio = TC_H_MAJ(t->tcm_info);
Expand All @@ -160,6 +159,10 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
if (dev == NULL)
return -ENODEV;

err = nlmsg_parse(n, sizeof(*t), tca, TCA_MAX, NULL);
if (err < 0)
return err;

/* Find qdisc */
if (!parent) {
q = dev->qdisc_sleeping;
Expand Down Expand Up @@ -202,7 +205,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
if (tp == NULL) {
/* Proto-tcf does not exist, create new one */

if (tca[TCA_KIND-1] == NULL || !protocol)
if (tca[TCA_KIND] == NULL || !protocol)
goto errout;

err = -ENOENT;
Expand All @@ -217,14 +220,14 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
if (tp == NULL)
goto errout;
err = -EINVAL;
tp_ops = tcf_proto_lookup_ops(tca[TCA_KIND-1]);
tp_ops = tcf_proto_lookup_ops(tca[TCA_KIND]);
if (tp_ops == NULL) {
#ifdef CONFIG_KMOD
struct rtattr *kind = tca[TCA_KIND-1];
struct nlattr *kind = tca[TCA_KIND];
char name[IFNAMSIZ];

if (kind != NULL &&
rtattr_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) {
nla_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) {
rtnl_unlock();
request_module("cls_%s", name);
rtnl_lock();
Expand Down Expand Up @@ -263,7 +266,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
*back = tp;
qdisc_unlock_tree(dev);

} else if (tca[TCA_KIND-1] && rtattr_strcmp(tca[TCA_KIND-1], tp->ops->kind))
} else if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], tp->ops->kind))
goto errout;

fh = tp->ops->get(tp, t->tcm_handle);
Expand Down Expand Up @@ -333,18 +336,18 @@ static int tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp,
tcm->tcm_ifindex = tp->q->dev->ifindex;
tcm->tcm_parent = tp->classid;
tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol);
RTA_PUT(skb, TCA_KIND, IFNAMSIZ, tp->ops->kind);
NLA_PUT(skb, TCA_KIND, IFNAMSIZ, tp->ops->kind);
tcm->tcm_handle = fh;
if (RTM_DELTFILTER != event) {
tcm->tcm_handle = 0;
if (tp->ops->dump && tp->ops->dump(tp, fh, skb, tcm) < 0)
goto rtattr_failure;
goto nla_put_failure;
}
nlh->nlmsg_len = skb_tail_pointer(skb) - b;
return skb->len;

nlmsg_failure:
rtattr_failure:
nla_put_failure:
nlmsg_trim(skb, b);
return -1;
}
Expand Down Expand Up @@ -476,8 +479,8 @@ 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 rtattr **tb,
struct rtattr *rate_tlv, struct tcf_exts *exts,
int tcf_exts_validate(struct tcf_proto *tp, struct nlattr **tb,
struct nlattr *rate_tlv, struct tcf_exts *exts,
struct tcf_ext_map *map)
{
memset(exts, 0, sizeof(*exts));
Expand All @@ -487,17 +490,19 @@ int tcf_exts_validate(struct tcf_proto *tp, struct rtattr **tb,
int err;
struct tc_action *act;

if (map->police && tb[map->police-1]) {
act = tcf_action_init_1(tb[map->police-1], rate_tlv,
if (map->police && tb[map->police]) {
act = tcf_action_init_1((struct rtattr *)tb[map->police],
(struct rtattr *)rate_tlv,
"police", TCA_ACT_NOREPLACE,
TCA_ACT_BIND, &err);
if (act == NULL)
return err;

act->type = TCA_OLD_COMPAT;
exts->action = act;
} else if (map->action && tb[map->action-1]) {
act = tcf_action_init(tb[map->action-1], rate_tlv, NULL,
} else if (map->action && tb[map->action]) {
act = tcf_action_init((struct rtattr *)tb[map->action],
(struct rtattr *)rate_tlv, NULL,
TCA_ACT_NOREPLACE, TCA_ACT_BIND, &err);
if (act == NULL)
return err;
Expand All @@ -506,8 +511,8 @@ int tcf_exts_validate(struct tcf_proto *tp, struct rtattr **tb,
}
}
#else
if ((map->action && tb[map->action-1]) ||
(map->police && tb[map->police-1]))
if ((map->action && tb[map->action]) ||
(map->police && tb[map->police]))
return -EOPNOTSUPP;
#endif

Expand Down Expand Up @@ -541,23 +546,23 @@ int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts,
* to work with both old and new modes of entering
* tc data even if iproute2 was newer - jhs
*/
struct rtattr *p_rta = (struct rtattr *)skb_tail_pointer(skb);
struct nlattr *p_rta = (struct nlattr *)skb_tail_pointer(skb);

if (exts->action->type != TCA_OLD_COMPAT) {
RTA_PUT(skb, map->action, 0, NULL);
NLA_PUT(skb, map->action, 0, NULL);
if (tcf_action_dump(skb, exts->action, 0, 0) < 0)
goto rtattr_failure;
p_rta->rta_len = skb_tail_pointer(skb) - (u8 *)p_rta;
goto nla_put_failure;
p_rta->nla_len = skb_tail_pointer(skb) - (u8 *)p_rta;
} else if (map->police) {
RTA_PUT(skb, map->police, 0, NULL);
NLA_PUT(skb, map->police, 0, NULL);
if (tcf_action_dump_old(skb, exts->action, 0, 0) < 0)
goto rtattr_failure;
p_rta->rta_len = skb_tail_pointer(skb) - (u8 *)p_rta;
goto nla_put_failure;
p_rta->nla_len = skb_tail_pointer(skb) - (u8 *)p_rta;
}
}
#endif
return 0;
rtattr_failure: __attribute__ ((unused))
nla_put_failure: __attribute__ ((unused))
return -1;
}
EXPORT_SYMBOL(tcf_exts_dump);
Expand All @@ -569,10 +574,10 @@ int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts,
#ifdef CONFIG_NET_CLS_ACT
if (exts->action)
if (tcf_action_copy_stats(skb, exts->action, 1) < 0)
goto rtattr_failure;
goto nla_put_failure;
#endif
return 0;
rtattr_failure: __attribute__ ((unused))
nla_put_failure: __attribute__ ((unused))
return -1;
}
EXPORT_SYMBOL(tcf_exts_dump_stats);
Expand Down
40 changes: 20 additions & 20 deletions net/sched/cls_basic.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,27 +130,27 @@ static int basic_delete(struct tcf_proto *tp, unsigned long arg)
}

static inline int basic_set_parms(struct tcf_proto *tp, struct basic_filter *f,
unsigned long base, struct rtattr **tb,
struct rtattr *est)
unsigned long base, struct nlattr **tb,
struct nlattr *est)
{
int err = -EINVAL;
struct tcf_exts e;
struct tcf_ematch_tree t;

if (tb[TCA_BASIC_CLASSID-1])
if (RTA_PAYLOAD(tb[TCA_BASIC_CLASSID-1]) < sizeof(u32))
if (tb[TCA_BASIC_CLASSID])
if (nla_len(tb[TCA_BASIC_CLASSID]) < sizeof(u32))
return err;

err = tcf_exts_validate(tp, tb, est, &e, &basic_ext_map);
if (err < 0)
return err;

err = tcf_em_tree_validate(tp, tb[TCA_BASIC_EMATCHES-1], &t);
err = tcf_em_tree_validate(tp, tb[TCA_BASIC_EMATCHES], &t);
if (err < 0)
goto errout;

if (tb[TCA_BASIC_CLASSID-1]) {
f->res.classid = *(u32*)RTA_DATA(tb[TCA_BASIC_CLASSID-1]);
if (tb[TCA_BASIC_CLASSID]) {
f->res.classid = *(u32*)nla_data(tb[TCA_BASIC_CLASSID]);
tcf_bind_filter(tp, &f->res, base);
}

Expand All @@ -164,23 +164,23 @@ static inline int basic_set_parms(struct tcf_proto *tp, struct basic_filter *f,
}

static int basic_change(struct tcf_proto *tp, unsigned long base, u32 handle,
struct rtattr **tca, unsigned long *arg)
struct nlattr **tca, unsigned long *arg)
{
int err = -EINVAL;
struct basic_head *head = (struct basic_head *) tp->root;
struct rtattr *tb[TCA_BASIC_MAX];
struct nlattr *tb[TCA_BASIC_MAX + 1];
struct basic_filter *f = (struct basic_filter *) *arg;

if (tca[TCA_OPTIONS-1] == NULL)
if (tca[TCA_OPTIONS] == NULL)
return -EINVAL;

if (rtattr_parse_nested(tb, TCA_BASIC_MAX, tca[TCA_OPTIONS-1]) < 0)
if (nla_parse_nested(tb, TCA_BASIC_MAX, tca[TCA_OPTIONS], NULL) < 0)
return -EINVAL;

if (f != NULL) {
if (handle && f->handle != handle)
return -EINVAL;
return basic_set_parms(tp, f, base, tb, tca[TCA_RATE-1]);
return basic_set_parms(tp, f, base, tb, tca[TCA_RATE]);
}

err = -ENOBUFS;
Expand All @@ -206,7 +206,7 @@ static int basic_change(struct tcf_proto *tp, unsigned long base, u32 handle,
f->handle = head->hgenerator;
}

err = basic_set_parms(tp, f, base, tb, tca[TCA_RATE-1]);
err = basic_set_parms(tp, f, base, tb, tca[TCA_RATE]);
if (err < 0)
goto errout;

Expand Down Expand Up @@ -246,27 +246,27 @@ static int basic_dump(struct tcf_proto *tp, unsigned long fh,
{
struct basic_filter *f = (struct basic_filter *) fh;
unsigned char *b = skb_tail_pointer(skb);
struct rtattr *rta;
struct nlattr *nla;

if (f == NULL)
return skb->len;

t->tcm_handle = f->handle;

rta = (struct rtattr *) b;
RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
nla = (struct nlattr *) b;
NLA_PUT(skb, TCA_OPTIONS, 0, NULL);

if (f->res.classid)
RTA_PUT(skb, TCA_BASIC_CLASSID, sizeof(u32), &f->res.classid);
NLA_PUT(skb, TCA_BASIC_CLASSID, sizeof(u32), &f->res.classid);

if (tcf_exts_dump(skb, &f->exts, &basic_ext_map) < 0 ||
tcf_em_tree_dump(skb, &f->ematches, TCA_BASIC_EMATCHES) < 0)
goto rtattr_failure;
goto nla_put_failure;

rta->rta_len = skb_tail_pointer(skb) - b;
nla->nla_len = skb_tail_pointer(skb) - b;
return skb->len;

rtattr_failure:
nla_put_failure:
nlmsg_trim(skb, b);
return -1;
}
Expand Down
Loading

0 comments on commit add93b6

Please sign in to comment.