From b854272b3c732316676e9128f7b9e6f1e1ff88b0 Mon Sep 17 00:00:00 2001 From: "Denis V. Lunev" Date: Sat, 1 Dec 2007 00:21:31 +1100 Subject: [NET]: Modify all rtnetlink methods to only work in the initial namespace (v2) Before I can enable rtnetlink to work in all network namespaces I need to be certain that something won't break. So this patch deliberately disables all of the rtnletlink methods in everything except the initial network namespace. After the methods have been audited this extra check can be disabled. Changes from v1: - added IPv6 addrlabel protection Signed-off-by: Denis V. Lunev Signed-off-by: Eric W. Biederman Signed-off-by: David S. Miller Signed-off-by: Herbert Xu --- net/sched/act_api.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'net/sched/act_api.c') diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 72cdb0fade20..852829139c67 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include #include @@ -924,10 +926,14 @@ done: static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg) { + struct net *net = skb->sk->sk_net; struct rtattr **tca = arg; u32 pid = skb ? NETLINK_CB(skb).pid : 0; int ret = 0, ovr = 0; + if (net != &init_net) + return -EINVAL; + if (tca[TCA_ACT_TAB-1] == NULL) { printk("tc_ctl_action: received NO action attribs\n"); return -EINVAL; @@ -997,6 +1003,7 @@ find_dump_kind(struct nlmsghdr *n) static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) { + struct net *net = skb->sk->sk_net; struct nlmsghdr *nlh; unsigned char *b = skb_tail_pointer(skb); struct rtattr *x; @@ -1006,6 +1013,9 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh); struct rtattr *kind = find_dump_kind(cb->nlh); + if (net != &init_net) + return 0; + if (kind == NULL) { printk("tc_dump_action: action bad kind\n"); return 0; -- cgit v1.2.3 From 97c53cacf00d1f5aa04adabfebcc806ca8b22b10 Mon Sep 17 00:00:00 2001 From: "Denis V. Lunev" Date: Mon, 19 Nov 2007 22:26:51 -0800 Subject: [NET]: Make rtnetlink infrastructure network namespace aware (v3) After this patch none of the netlink callback support anything except the initial network namespace but the rtnetlink infrastructure now handles multiple network namespaces. Changes from v2: - IPv6 addrlabel processing Changes from v1: - no need for special rtnl_unlock handling - fixed IPv6 ndisc Signed-off-by: Denis V. Lunev Signed-off-by: Eric W. Biederman Signed-off-by: David S. Miller --- net/sched/act_api.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'net/sched/act_api.c') diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 852829139c67..81506474a4f7 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -660,7 +660,7 @@ act_get_notify(u32 pid, struct nlmsghdr *n, struct tc_action *a, int event) return -EINVAL; } - return rtnl_unicast(skb, pid); + return rtnl_unicast(skb, &init_net, pid); } static struct tc_action * @@ -781,7 +781,7 @@ static int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid) nlh->nlmsg_flags |= NLM_F_ROOT; module_put(a->ops->owner); kfree(a); - err = rtnetlink_send(skb, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO); + err = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO); if (err > 0) return 0; @@ -844,7 +844,7 @@ tca_action_gd(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int event) /* now do the delete */ tcf_action_destroy(head, 0); - ret = rtnetlink_send(skb, pid, RTNLGRP_TC, + ret = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO); if (ret > 0) return 0; @@ -888,7 +888,7 @@ static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event, nlh->nlmsg_len = skb_tail_pointer(skb) - b; NETLINK_CB(skb).dst_group = RTNLGRP_TC; - err = rtnetlink_send(skb, pid, RTNLGRP_TC, flags&NLM_F_ECHO); + err = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, flags&NLM_F_ECHO); if (err > 0) err = 0; return err; -- cgit v1.2.3 From 62e3ba1b558e5f393ef746880613fb8222e64d03 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 22 Jan 2008 22:10:23 -0800 Subject: [NET_SCHED]: Move EXPORT_SYMBOL next to exported symbol Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/sched/act_api.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'net/sched/act_api.c') diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 81506474a4f7..3825508fdcd1 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -263,6 +263,7 @@ int tcf_register_action(struct tc_action_ops *act) write_unlock(&act_mod_lock); return 0; } +EXPORT_SYMBOL(tcf_register_action); int tcf_unregister_action(struct tc_action_ops *act) { @@ -281,6 +282,7 @@ int tcf_unregister_action(struct tc_action_ops *act) write_unlock(&act_mod_lock); return err; } +EXPORT_SYMBOL(tcf_unregister_action); /* lookup by name */ static struct tc_action_ops *tc_lookup_action_n(char *kind) @@ -377,6 +379,7 @@ repeat: exec_done: return ret; } +EXPORT_SYMBOL(tcf_action_exec); void tcf_action_destroy(struct tc_action *act, int bind) { @@ -430,6 +433,7 @@ rtattr_failure: nlmsg_trim(skb, b); return -1; } +EXPORT_SYMBOL(tcf_action_dump_1); int tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref) @@ -1077,8 +1081,3 @@ static int __init tc_action_init(void) } subsys_initcall(tc_action_init); - -EXPORT_SYMBOL(tcf_register_action); -EXPORT_SYMBOL(tcf_unregister_action); -EXPORT_SYMBOL(tcf_action_exec); -EXPORT_SYMBOL(tcf_action_dump_1); -- cgit v1.2.3 From 1e90474c377e92db7262a8968a45c1dd980ca9e5 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 22 Jan 2008 22:11:17 -0800 Subject: [NET_SCHED]: Convert packet schedulers from rtnetlink to new netlink API Convert packet schedulers to use the netlink API. Unfortunately a gradual conversion is not possible without breaking compilation in the middle or adding lots of casts, so this patch converts them all in one step. The patch has been mostly generated automatically with some minor edits to at least allow seperate conversion of classifiers and actions. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/sched/act_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/sched/act_api.c') diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 3825508fdcd1..11f3097a6912 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -227,7 +227,7 @@ struct tcf_common *tcf_hash_create(u32 index, struct rtattr *est, struct tc_acti p->tcfc_tm.lastuse = jiffies; if (est) gen_new_estimator(&p->tcfc_bstats, &p->tcfc_rate_est, - &p->tcfc_lock, est); + &p->tcfc_lock, (struct nlattr *)est); a->priv = (void *) p; return p; } -- cgit v1.2.3 From 7ba699c604ab811972eee2e041fd6b07659a2e6e Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 22 Jan 2008 22:11:50 -0800 Subject: [NET_SCHED]: Convert actions from rtnetlink to new netlink API Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/sched/act_api.c | 214 ++++++++++++++++++++++++++-------------------------- 1 file changed, 109 insertions(+), 105 deletions(-) (limited to 'net/sched/act_api.c') diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 11f3097a6912..ebd21d2cb5f1 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -68,7 +68,7 @@ static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb, { struct tcf_common *p; int err = 0, index = -1,i = 0, s_i = 0, n_i = 0; - struct rtattr *r ; + struct nlattr *r ; read_lock_bh(hinfo->lock); @@ -83,15 +83,15 @@ static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb, continue; a->priv = p; a->order = n_i; - r = (struct rtattr *)skb_tail_pointer(skb); - RTA_PUT(skb, a->order, 0, NULL); + r = (struct nlattr *)skb_tail_pointer(skb); + NLA_PUT(skb, a->order, 0, NULL); err = tcf_action_dump_1(skb, a, 0, 0); if (err < 0) { index--; nlmsg_trim(skb, r); goto done; } - r->rta_len = skb_tail_pointer(skb) - (u8 *)r; + r->nla_len = skb_tail_pointer(skb) - (u8 *)r; n_i++; if (n_i >= TCA_ACT_MAX_PRIO) goto done; @@ -103,7 +103,7 @@ done: cb->args[0] += n_i; return n_i; -rtattr_failure: +nla_put_failure: nlmsg_trim(skb, r); goto done; } @@ -112,12 +112,12 @@ static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a, struct tcf_hashinfo *hinfo) { struct tcf_common *p, *s_p; - struct rtattr *r ; + struct nlattr *r ; int i= 0, n_i = 0; - r = (struct rtattr *)skb_tail_pointer(skb); - RTA_PUT(skb, a->order, 0, NULL); - RTA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind); + r = (struct nlattr *)skb_tail_pointer(skb); + NLA_PUT(skb, a->order, 0, NULL); + NLA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind); for (i = 0; i < (hinfo->hmask + 1); i++) { p = hinfo->htab[tcf_hash(i, hinfo->hmask)]; @@ -129,11 +129,11 @@ static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a, p = s_p; } } - RTA_PUT(skb, TCA_FCNT, 4, &n_i); - r->rta_len = skb_tail_pointer(skb) - (u8 *)r; + NLA_PUT(skb, TCA_FCNT, 4, &n_i); + r->nla_len = skb_tail_pointer(skb) - (u8 *)r; return n_i; -rtattr_failure: +nla_put_failure: nlmsg_trim(skb, r); return -EINVAL; } @@ -211,7 +211,7 @@ 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 rtattr *est, struct tc_action *a, int size, int bind, u32 *idx_gen, struct tcf_hashinfo *hinfo) +struct tcf_common *tcf_hash_create(u32 index, struct nlattr *est, struct tc_action *a, int size, int bind, u32 *idx_gen, struct tcf_hashinfo *hinfo) { struct tcf_common *p = kzalloc(size, GFP_KERNEL); @@ -227,7 +227,7 @@ struct tcf_common *tcf_hash_create(u32 index, struct rtattr *est, struct tc_acti p->tcfc_tm.lastuse = jiffies; if (est) gen_new_estimator(&p->tcfc_bstats, &p->tcfc_rate_est, - &p->tcfc_lock, (struct nlattr *)est); + &p->tcfc_lock, est); a->priv = (void *) p; return p; } @@ -305,15 +305,15 @@ static struct tc_action_ops *tc_lookup_action_n(char *kind) return a; } -/* lookup by rtattr */ -static struct tc_action_ops *tc_lookup_action(struct rtattr *kind) +/* lookup by nlattr */ +static struct tc_action_ops *tc_lookup_action(struct nlattr *kind) { struct tc_action_ops *a = NULL; if (kind) { read_lock(&act_mod_lock); for (a = act_base; a; a = a->next) { - if (rtattr_strcmp(kind, a->kind) == 0) { + if (nla_strcmp(kind, a->kind) == 0) { if (!try_module_get(a->owner)) { read_unlock(&act_mod_lock); return NULL; @@ -414,22 +414,22 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref) { int err = -EINVAL; unsigned char *b = skb_tail_pointer(skb); - struct rtattr *r; + struct nlattr *r; if (a->ops == NULL || a->ops->dump == NULL) return err; - RTA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind); + NLA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind); if (tcf_action_copy_stats(skb, a, 0)) - goto rtattr_failure; - r = (struct rtattr *)skb_tail_pointer(skb); - RTA_PUT(skb, TCA_OPTIONS, 0, NULL); + goto nla_put_failure; + r = (struct nlattr *)skb_tail_pointer(skb); + NLA_PUT(skb, TCA_OPTIONS, 0, NULL); if ((err = tcf_action_dump_old(skb, a, bind, ref)) > 0) { - r->rta_len = skb_tail_pointer(skb) - (u8 *)r; + r->nla_len = skb_tail_pointer(skb) - (u8 *)r; return err; } -rtattr_failure: +nla_put_failure: nlmsg_trim(skb, b); return -1; } @@ -441,45 +441,45 @@ tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref) struct tc_action *a; int err = -EINVAL; unsigned char *b = skb_tail_pointer(skb); - struct rtattr *r ; + struct nlattr *r ; while ((a = act) != NULL) { - r = (struct rtattr *)skb_tail_pointer(skb); + r = (struct nlattr *)skb_tail_pointer(skb); act = a->next; - RTA_PUT(skb, a->order, 0, NULL); + NLA_PUT(skb, a->order, 0, NULL); err = tcf_action_dump_1(skb, a, bind, ref); if (err < 0) goto errout; - r->rta_len = skb_tail_pointer(skb) - (u8 *)r; + r->nla_len = skb_tail_pointer(skb) - (u8 *)r; } return 0; -rtattr_failure: +nla_put_failure: err = -EINVAL; errout: nlmsg_trim(skb, b); return err; } -struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est, +struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est, char *name, int ovr, int bind, int *err) { struct tc_action *a; struct tc_action_ops *a_o; char act_name[IFNAMSIZ]; - struct rtattr *tb[TCA_ACT_MAX+1]; - struct rtattr *kind; + struct nlattr *tb[TCA_ACT_MAX+1]; + struct nlattr *kind; *err = -EINVAL; if (name == NULL) { - if (rtattr_parse_nested(tb, TCA_ACT_MAX, rta) < 0) + if (nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL) < 0) goto err_out; - kind = tb[TCA_ACT_KIND-1]; + kind = tb[TCA_ACT_KIND]; if (kind == NULL) goto err_out; - if (rtattr_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ) + if (nla_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ) goto err_out; } else { if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ) @@ -517,9 +517,9 @@ struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est, /* backward compatibility for policer */ if (name == NULL) - *err = a_o->init(tb[TCA_ACT_OPTIONS-1], est, a, ovr, bind); + *err = a_o->init(tb[TCA_ACT_OPTIONS], est, a, ovr, bind); else - *err = a_o->init(rta, est, a, ovr, bind); + *err = a_o->init(nla, est, a, ovr, bind); if (*err < 0) goto err_free; @@ -542,23 +542,23 @@ err_out: return NULL; } -struct tc_action *tcf_action_init(struct rtattr *rta, struct rtattr *est, +struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est, char *name, int ovr, int bind, int *err) { - struct rtattr *tb[TCA_ACT_MAX_PRIO+1]; + struct nlattr *tb[TCA_ACT_MAX_PRIO+1]; struct tc_action *head = NULL, *act, *act_prev = NULL; int i; - if (rtattr_parse_nested(tb, TCA_ACT_MAX_PRIO, rta) < 0) { + if (nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL) < 0) { *err = -EINVAL; return head; } - for (i=0; i < TCA_ACT_MAX_PRIO && tb[i]; i++) { + for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) { act = tcf_action_init_1(tb[i], est, name, ovr, bind, err); if (act == NULL) goto err; - act->order = i+1; + act->order = i; if (head == NULL) head = act; @@ -625,7 +625,7 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq, struct tcamsg *t; struct nlmsghdr *nlh; unsigned char *b = skb_tail_pointer(skb); - struct rtattr *x; + struct nlattr *x; nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags); @@ -634,18 +634,18 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq, t->tca__pad1 = 0; t->tca__pad2 = 0; - x = (struct rtattr *)skb_tail_pointer(skb); - RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); + x = (struct nlattr *)skb_tail_pointer(skb); + NLA_PUT(skb, TCA_ACT_TAB, 0, NULL); if (tcf_action_dump(skb, a, bind, ref) < 0) - goto rtattr_failure; + goto nla_put_failure; - x->rta_len = skb_tail_pointer(skb) - (u8 *)x; + x->nla_len = skb_tail_pointer(skb) - (u8 *)x; nlh->nlmsg_len = skb_tail_pointer(skb) - b; return skb->len; -rtattr_failure: +nla_put_failure: nlmsg_failure: nlmsg_trim(skb, b); return -1; @@ -668,20 +668,20 @@ act_get_notify(u32 pid, struct nlmsghdr *n, struct tc_action *a, int event) } static struct tc_action * -tcf_action_get_1(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int *err) +tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int *err) { - struct rtattr *tb[TCA_ACT_MAX+1]; + struct nlattr *tb[TCA_ACT_MAX+1]; struct tc_action *a; int index; *err = -EINVAL; - if (rtattr_parse_nested(tb, TCA_ACT_MAX, rta) < 0) + if (nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL) < 0) return NULL; - if (tb[TCA_ACT_INDEX - 1] == NULL || - RTA_PAYLOAD(tb[TCA_ACT_INDEX - 1]) < sizeof(index)) + if (tb[TCA_ACT_INDEX] == NULL || + nla_len(tb[TCA_ACT_INDEX]) < sizeof(index)) return NULL; - index = *(int *)RTA_DATA(tb[TCA_ACT_INDEX - 1]); + index = *(int *)nla_data(tb[TCA_ACT_INDEX]); *err = -ENOMEM; a = kzalloc(sizeof(struct tc_action), GFP_KERNEL); @@ -689,7 +689,7 @@ tcf_action_get_1(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int *err) return NULL; *err = -EINVAL; - a->ops = tc_lookup_action(tb[TCA_ACT_KIND - 1]); + a->ops = tc_lookup_action(tb[TCA_ACT_KIND]); if (a->ops == NULL) goto err_free; if (a->ops->lookup == NULL) @@ -731,16 +731,16 @@ static struct tc_action *create_a(int i) return act; } -static int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid) +static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid) { struct sk_buff *skb; unsigned char *b; struct nlmsghdr *nlh; struct tcamsg *t; struct netlink_callback dcb; - struct rtattr *x; - struct rtattr *tb[TCA_ACT_MAX+1]; - struct rtattr *kind; + struct nlattr *x; + struct nlattr *tb[TCA_ACT_MAX+1]; + struct nlattr *kind; struct tc_action *a = create_a(0); int err = -EINVAL; @@ -758,10 +758,10 @@ static int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid) b = skb_tail_pointer(skb); - if (rtattr_parse_nested(tb, TCA_ACT_MAX, rta) < 0) + if (nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL) < 0) goto err_out; - kind = tb[TCA_ACT_KIND-1]; + kind = tb[TCA_ACT_KIND]; a->ops = tc_lookup_action(kind); if (a->ops == NULL) goto err_out; @@ -772,14 +772,14 @@ static int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid) t->tca__pad1 = 0; t->tca__pad2 = 0; - x = (struct rtattr *)skb_tail_pointer(skb); - RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); + x = (struct nlattr *)skb_tail_pointer(skb); + NLA_PUT(skb, TCA_ACT_TAB, 0, NULL); err = a->ops->walk(skb, &dcb, RTM_DELACTION, a); if (err < 0) - goto rtattr_failure; + goto nla_put_failure; - x->rta_len = skb_tail_pointer(skb) - (u8 *)x; + x->nla_len = skb_tail_pointer(skb) - (u8 *)x; nlh->nlmsg_len = skb_tail_pointer(skb) - b; nlh->nlmsg_flags |= NLM_F_ROOT; @@ -791,7 +791,7 @@ static int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid) return err; -rtattr_failure: +nla_put_failure: nlmsg_failure: module_put(a->ops->owner); err_out: @@ -801,13 +801,13 @@ err_out: } static int -tca_action_gd(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int event) +tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event) { int i, ret = 0; - struct rtattr *tb[TCA_ACT_MAX_PRIO+1]; + struct nlattr *tb[TCA_ACT_MAX_PRIO+1]; struct tc_action *head = NULL, *act, *act_prev = NULL; - if (rtattr_parse_nested(tb, TCA_ACT_MAX_PRIO, rta) < 0) + if (nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL) < 0) return -EINVAL; if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) { @@ -815,11 +815,11 @@ tca_action_gd(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int event) return tca_action_flush(tb[0], n, pid); } - for (i=0; i < TCA_ACT_MAX_PRIO && tb[i]; i++) { + for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) { act = tcf_action_get_1(tb[i], n, pid, &ret); if (act == NULL) goto err; - act->order = i+1; + act->order = i; if (head == NULL) head = act; @@ -865,7 +865,7 @@ static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event, struct tcamsg *t; struct nlmsghdr *nlh; struct sk_buff *skb; - struct rtattr *x; + struct nlattr *x; unsigned char *b; int err = 0; @@ -881,13 +881,13 @@ static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event, t->tca__pad1 = 0; t->tca__pad2 = 0; - x = (struct rtattr *)skb_tail_pointer(skb); - RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); + x = (struct nlattr *)skb_tail_pointer(skb); + NLA_PUT(skb, TCA_ACT_TAB, 0, NULL); if (tcf_action_dump(skb, a, 0, 0) < 0) - goto rtattr_failure; + goto nla_put_failure; - x->rta_len = skb_tail_pointer(skb) - (u8 *)x; + x->nla_len = skb_tail_pointer(skb) - (u8 *)x; nlh->nlmsg_len = skb_tail_pointer(skb) - b; NETLINK_CB(skb).dst_group = RTNLGRP_TC; @@ -897,7 +897,7 @@ static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event, err = 0; return err; -rtattr_failure: +nla_put_failure: nlmsg_failure: kfree_skb(skb); return -1; @@ -905,14 +905,14 @@ nlmsg_failure: static int -tcf_action_add(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int ovr) +tcf_action_add(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int ovr) { int ret = 0; struct tc_action *act; struct tc_action *a; u32 seq = n->nlmsg_seq; - act = tcf_action_init(rta, NULL, NULL, ovr, 0, &ret); + act = tcf_action_init(nla, NULL, NULL, ovr, 0, &ret); if (act == NULL) goto done; @@ -931,14 +931,18 @@ done: static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg) { struct net *net = skb->sk->sk_net; - struct rtattr **tca = arg; + struct nlattr *tca[TCA_ACT_MAX + 1]; u32 pid = skb ? NETLINK_CB(skb).pid : 0; int ret = 0, ovr = 0; if (net != &init_net) return -EINVAL; - if (tca[TCA_ACT_TAB-1] == NULL) { + ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL); + if (ret < 0) + return ret; + + if (tca[TCA_ACT_TAB] == NULL) { printk("tc_ctl_action: received NO action attribs\n"); return -EINVAL; } @@ -956,15 +960,15 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg) if (n->nlmsg_flags&NLM_F_REPLACE) ovr = 1; replay: - ret = tcf_action_add(tca[TCA_ACT_TAB-1], n, pid, ovr); + ret = tcf_action_add(tca[TCA_ACT_TAB], n, pid, ovr); if (ret == -EAGAIN) goto replay; break; case RTM_DELACTION: - ret = tca_action_gd(tca[TCA_ACT_TAB-1], n, pid, RTM_DELACTION); + ret = tca_action_gd(tca[TCA_ACT_TAB], n, pid, RTM_DELACTION); break; case RTM_GETACTION: - ret = tca_action_gd(tca[TCA_ACT_TAB-1], n, pid, RTM_GETACTION); + ret = tca_action_gd(tca[TCA_ACT_TAB], n, pid, RTM_GETACTION); break; default: BUG(); @@ -973,33 +977,33 @@ replay: return ret; } -static struct rtattr * +static struct nlattr * find_dump_kind(struct nlmsghdr *n) { - struct rtattr *tb1, *tb2[TCA_ACT_MAX+1]; - struct rtattr *tb[TCA_ACT_MAX_PRIO + 1]; - struct rtattr *rta[TCAA_MAX + 1]; - struct rtattr *kind; + struct nlattr *tb1, *tb2[TCA_ACT_MAX+1]; + struct nlattr *tb[TCA_ACT_MAX_PRIO + 1]; + struct nlattr *nla[TCAA_MAX + 1]; + struct nlattr *kind; int min_len = NLMSG_LENGTH(sizeof(struct tcamsg)); int attrlen = n->nlmsg_len - NLMSG_ALIGN(min_len); - struct rtattr *attr = (void *) n + NLMSG_ALIGN(min_len); + struct nlattr *attr = (void *) n + NLMSG_ALIGN(min_len); - if (rtattr_parse(rta, TCAA_MAX, attr, attrlen) < 0) + if (nla_parse(nla, TCAA_MAX, attr, attrlen, NULL) < 0) return NULL; - tb1 = rta[TCA_ACT_TAB - 1]; + tb1 = nla[TCA_ACT_TAB]; if (tb1 == NULL) return NULL; - if (rtattr_parse(tb, TCA_ACT_MAX_PRIO, RTA_DATA(tb1), - NLMSG_ALIGN(RTA_PAYLOAD(tb1))) < 0) + if (nla_parse(tb, TCA_ACT_MAX_PRIO, nla_data(tb1), + NLMSG_ALIGN(nla_len(tb1)), NULL) < 0) return NULL; if (tb[0] == NULL) return NULL; - if (rtattr_parse(tb2, TCA_ACT_MAX, RTA_DATA(tb[0]), - RTA_PAYLOAD(tb[0])) < 0) + if (nla_parse(tb2, TCA_ACT_MAX, nla_data(tb[0]), + nla_len(tb[0]), NULL) < 0) return NULL; - kind = tb2[TCA_ACT_KIND-1]; + kind = tb2[TCA_ACT_KIND]; return kind; } @@ -1010,12 +1014,12 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) struct net *net = skb->sk->sk_net; struct nlmsghdr *nlh; unsigned char *b = skb_tail_pointer(skb); - struct rtattr *x; + struct nlattr *x; struct tc_action_ops *a_o; struct tc_action a; int ret = 0; struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh); - struct rtattr *kind = find_dump_kind(cb->nlh); + struct nlattr *kind = find_dump_kind(cb->nlh); if (net != &init_net) return 0; @@ -1035,7 +1039,7 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) if (a_o->walk == NULL) { printk("tc_dump_action: %s !capable of dumping table\n", a_o->kind); - goto rtattr_failure; + goto nla_put_failure; } nlh = NLMSG_PUT(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, @@ -1045,15 +1049,15 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) t->tca__pad1 = 0; t->tca__pad2 = 0; - x = (struct rtattr *)skb_tail_pointer(skb); - RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); + x = (struct nlattr *)skb_tail_pointer(skb); + NLA_PUT(skb, TCA_ACT_TAB, 0, NULL); ret = a_o->walk(skb, cb, RTM_GETACTION, &a); if (ret < 0) - goto rtattr_failure; + goto nla_put_failure; if (ret > 0) { - x->rta_len = skb_tail_pointer(skb) - (u8 *)x; + x->nla_len = skb_tail_pointer(skb) - (u8 *)x; ret = skb->len; } else nlmsg_trim(skb, x); @@ -1064,7 +1068,7 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) module_put(a_o->owner); return skb->len; -rtattr_failure: +nla_put_failure: nlmsg_failure: module_put(a_o->owner); nlmsg_trim(skb, b); -- cgit v1.2.3 From 6d834e04e596d6803cf1074a07fd67e7b5662f1b Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 23 Jan 2008 20:32:42 -0800 Subject: [NET_SCHED]: act_api: fix netlink API conversion bug Fix two invalid attribute accesses, indices start at 1 with the new netlink API. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/sched/act_api.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'net/sched/act_api.c') diff --git a/net/sched/act_api.c b/net/sched/act_api.c index ebd21d2cb5f1..ae077ed208af 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -997,11 +997,11 @@ find_dump_kind(struct nlmsghdr *n) if (nla_parse(tb, TCA_ACT_MAX_PRIO, nla_data(tb1), NLMSG_ALIGN(nla_len(tb1)), NULL) < 0) return NULL; - if (tb[0] == NULL) - return NULL; - if (nla_parse(tb2, TCA_ACT_MAX, nla_data(tb[0]), - nla_len(tb[0]), NULL) < 0) + if (tb[1] == NULL) + return NULL; + if (nla_parse(tb2, TCA_ACT_MAX, nla_data(tb[1]), + nla_len(tb[1]), NULL) < 0) return NULL; kind = tb2[TCA_ACT_KIND]; -- cgit v1.2.3 From c96c9471dd86ba24dc3826bf5688b99d3caf3ace Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 23 Jan 2008 20:32:58 -0800 Subject: [NET_SCHED]: act_api: use nlmsg_parse Convert open-coded nlmsg_parse to use the real function. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/sched/act_api.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'net/sched/act_api.c') diff --git a/net/sched/act_api.c b/net/sched/act_api.c index ae077ed208af..2fe0345ddcb1 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -984,11 +984,8 @@ find_dump_kind(struct nlmsghdr *n) struct nlattr *tb[TCA_ACT_MAX_PRIO + 1]; struct nlattr *nla[TCAA_MAX + 1]; struct nlattr *kind; - int min_len = NLMSG_LENGTH(sizeof(struct tcamsg)); - int attrlen = n->nlmsg_len - NLMSG_ALIGN(min_len); - struct nlattr *attr = (void *) n + NLMSG_ALIGN(min_len); - if (nla_parse(nla, TCAA_MAX, attr, attrlen, NULL) < 0) + if (nlmsg_parse(n, sizeof(struct tcamsg), nla, TCAA_MAX, NULL) < 0) return NULL; tb1 = nla[TCA_ACT_TAB]; if (tb1 == NULL) -- cgit v1.2.3 From ab27cfb85c5778400740ad0c401bde65616774eb Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 23 Jan 2008 20:33:13 -0800 Subject: [NET_SCHED]: act_api: use PTR_ERR in tcf_action_init/tcf_action_get Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/sched/act_api.c | 71 +++++++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 32 deletions(-) (limited to 'net/sched/act_api.c') diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 2fe0345ddcb1..ea80f82dbb6a 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -463,15 +464,16 @@ errout: } struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est, - char *name, int ovr, int bind, int *err) + char *name, int ovr, int bind) { struct tc_action *a; struct tc_action_ops *a_o; char act_name[IFNAMSIZ]; struct nlattr *tb[TCA_ACT_MAX+1]; struct nlattr *kind; + int err; - *err = -EINVAL; + err = -EINVAL; if (name == NULL) { if (nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL) < 0) @@ -502,36 +504,35 @@ struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est, * indicate this using -EAGAIN. */ if (a_o != NULL) { - *err = -EAGAIN; + err = -EAGAIN; goto err_mod; } #endif - *err = -ENOENT; + err = -ENOENT; goto err_out; } - *err = -ENOMEM; + err = -ENOMEM; a = kzalloc(sizeof(*a), GFP_KERNEL); if (a == NULL) goto err_mod; /* backward compatibility for policer */ if (name == NULL) - *err = a_o->init(tb[TCA_ACT_OPTIONS], est, a, ovr, bind); + err = a_o->init(tb[TCA_ACT_OPTIONS], est, a, ovr, bind); else - *err = a_o->init(nla, est, a, ovr, bind); - if (*err < 0) + err = a_o->init(nla, est, a, ovr, bind); + if (err < 0) goto err_free; /* module count goes up only when brand new policy is created if it exists and is only bound to in a_o->init() then ACT_P_CREATED is not returned (a zero is). */ - if (*err != ACT_P_CREATED) + if (err != ACT_P_CREATED) module_put(a_o->owner); a->ops = a_o; - *err = 0; return a; err_free: @@ -539,24 +540,22 @@ err_free: err_mod: module_put(a_o->owner); err_out: - return NULL; + return ERR_PTR(err); } struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est, - char *name, int ovr, int bind, int *err) + char *name, int ovr, int bind) { struct nlattr *tb[TCA_ACT_MAX_PRIO+1]; struct tc_action *head = NULL, *act, *act_prev = NULL; int i; - if (nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL) < 0) { - *err = -EINVAL; - return head; - } + if (nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL) < 0) + return ERR_PTR(-EINVAL); for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) { - act = tcf_action_init_1(tb[i], est, name, ovr, bind, err); - if (act == NULL) + act = tcf_action_init_1(tb[i], est, name, ovr, bind); + if (IS_ERR(act)) goto err; act->order = i; @@ -571,7 +570,7 @@ struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est, err: if (head != NULL) tcf_action_destroy(head, bind); - return NULL; + return act; } int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a, @@ -668,44 +667,46 @@ act_get_notify(u32 pid, struct nlmsghdr *n, struct tc_action *a, int event) } static struct tc_action * -tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int *err) +tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 pid) { struct nlattr *tb[TCA_ACT_MAX+1]; struct tc_action *a; int index; + int err; - *err = -EINVAL; + err = -EINVAL; if (nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL) < 0) - return NULL; + goto err_out; if (tb[TCA_ACT_INDEX] == NULL || nla_len(tb[TCA_ACT_INDEX]) < sizeof(index)) - return NULL; + goto err_out; index = *(int *)nla_data(tb[TCA_ACT_INDEX]); - *err = -ENOMEM; + err = -ENOMEM; a = kzalloc(sizeof(struct tc_action), GFP_KERNEL); if (a == NULL) - return NULL; + goto err_out; - *err = -EINVAL; + err = -EINVAL; a->ops = tc_lookup_action(tb[TCA_ACT_KIND]); if (a->ops == NULL) goto err_free; if (a->ops->lookup == NULL) goto err_mod; - *err = -ENOENT; + err = -ENOENT; if (a->ops->lookup(a, index) == 0) goto err_mod; module_put(a->ops->owner); - *err = 0; return a; + err_mod: module_put(a->ops->owner); err_free: kfree(a); - return NULL; +err_out: + return ERR_PTR(err); } static void cleanup_a(struct tc_action *act) @@ -816,9 +817,11 @@ tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event) } for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) { - act = tcf_action_get_1(tb[i], n, pid, &ret); - if (act == NULL) + act = tcf_action_get_1(tb[i], n, pid); + if (IS_ERR(act)) { + ret = PTR_ERR(act); goto err; + } act->order = i; if (head == NULL) @@ -912,9 +915,13 @@ tcf_action_add(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int ovr) struct tc_action *a; u32 seq = n->nlmsg_seq; - act = tcf_action_init(nla, NULL, NULL, ovr, 0, &ret); + act = tcf_action_init(nla, NULL, NULL, ovr, 0); if (act == NULL) goto done; + if (IS_ERR(act)) { + ret = PTR_ERR(act); + goto done; + } /* dump then free all the actions after update; inserted policy * stays intact -- cgit v1.2.3 From cee63723b358e594225e812d6e14a2a0abfd5c88 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 23 Jan 2008 20:33:32 -0800 Subject: [NET_SCHED]: Propagate nla_parse return value nla_parse() returns more detailed errno codes, propagate them back on error. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/sched/act_api.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) (limited to 'net/sched/act_api.c') diff --git a/net/sched/act_api.c b/net/sched/act_api.c index ea80f82dbb6a..87818d7fb623 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -473,17 +473,18 @@ struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est, struct nlattr *kind; int err; - err = -EINVAL; - if (name == NULL) { - if (nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL) < 0) + err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL); + if (err < 0) goto err_out; + err = -EINVAL; kind = tb[TCA_ACT_KIND]; if (kind == NULL) goto err_out; if (nla_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ) goto err_out; } else { + err = -EINVAL; if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ) goto err_out; } @@ -548,10 +549,12 @@ struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est, { struct nlattr *tb[TCA_ACT_MAX_PRIO+1]; struct tc_action *head = NULL, *act, *act_prev = NULL; + int err; int i; - if (nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL) < 0) - return ERR_PTR(-EINVAL); + err = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL); + if (err < 0) + 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); @@ -674,10 +677,11 @@ tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 pid) int index; int err; - err = -EINVAL; - if (nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL) < 0) + err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL); + if (err < 0) goto err_out; + err = -EINVAL; if (tb[TCA_ACT_INDEX] == NULL || nla_len(tb[TCA_ACT_INDEX]) < sizeof(index)) goto err_out; @@ -759,9 +763,11 @@ static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid) b = skb_tail_pointer(skb); - if (nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL) < 0) + err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL); + if (err < 0) goto err_out; + err = -EINVAL; kind = tb[TCA_ACT_KIND]; a->ops = tc_lookup_action(kind); if (a->ops == NULL) @@ -804,12 +810,13 @@ err_out: static int tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event) { - int i, ret = 0; + int i, ret; struct nlattr *tb[TCA_ACT_MAX_PRIO+1]; struct tc_action *head = NULL, *act, *act_prev = NULL; - if (nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL) < 0) - return -EINVAL; + ret = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL); + if (ret < 0) + return ret; if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) { if (tb[0] != NULL && tb[1] == NULL) -- cgit v1.2.3 From 4b3550ef530cfc153fa91f0b37cbda448bad11c6 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 23 Jan 2008 20:34:11 -0800 Subject: [NET_SCHED]: Use nla_nest_start/nla_nest_end Use nla_nest_start/nla_nest_end for dumping nested attributes. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/sched/act_api.c | 84 +++++++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 38 deletions(-) (limited to 'net/sched/act_api.c') diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 87818d7fb623..36022605fc16 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -69,7 +69,7 @@ static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb, { struct tcf_common *p; int err = 0, index = -1,i = 0, s_i = 0, n_i = 0; - struct nlattr *r ; + struct nlattr *nest; read_lock_bh(hinfo->lock); @@ -84,15 +84,17 @@ static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb, continue; a->priv = p; a->order = n_i; - r = (struct nlattr *)skb_tail_pointer(skb); - NLA_PUT(skb, a->order, 0, NULL); + + nest = nla_nest_start(skb, a->order); + if (nest == NULL) + goto nla_put_failure; err = tcf_action_dump_1(skb, a, 0, 0); if (err < 0) { index--; - nlmsg_trim(skb, r); + nlmsg_trim(skb, nest); goto done; } - r->nla_len = skb_tail_pointer(skb) - (u8 *)r; + nla_nest_end(skb, nest); n_i++; if (n_i >= TCA_ACT_MAX_PRIO) goto done; @@ -105,7 +107,7 @@ done: return n_i; nla_put_failure: - nlmsg_trim(skb, r); + nla_nest_cancel(skb, nest); goto done; } @@ -113,11 +115,12 @@ static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a, struct tcf_hashinfo *hinfo) { struct tcf_common *p, *s_p; - struct nlattr *r ; + struct nlattr *nest; int i= 0, n_i = 0; - r = (struct nlattr *)skb_tail_pointer(skb); - NLA_PUT(skb, a->order, 0, NULL); + nest = nla_nest_start(skb, a->order); + if (nest == NULL) + goto nla_put_failure; NLA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind); for (i = 0; i < (hinfo->hmask + 1); i++) { p = hinfo->htab[tcf_hash(i, hinfo->hmask)]; @@ -131,11 +134,11 @@ static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a, } } NLA_PUT(skb, TCA_FCNT, 4, &n_i); - r->nla_len = skb_tail_pointer(skb) - (u8 *)r; + nla_nest_end(skb, nest); return n_i; nla_put_failure: - nlmsg_trim(skb, r); + nla_nest_cancel(skb, nest); return -EINVAL; } @@ -415,7 +418,7 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref) { int err = -EINVAL; unsigned char *b = skb_tail_pointer(skb); - struct nlattr *r; + struct nlattr *nest; if (a->ops == NULL || a->ops->dump == NULL) return err; @@ -423,10 +426,11 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref) NLA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind); if (tcf_action_copy_stats(skb, a, 0)) goto nla_put_failure; - r = (struct nlattr *)skb_tail_pointer(skb); - NLA_PUT(skb, TCA_OPTIONS, 0, NULL); + nest = nla_nest_start(skb, TCA_OPTIONS); + if (nest == NULL) + goto nla_put_failure; if ((err = tcf_action_dump_old(skb, a, bind, ref)) > 0) { - r->nla_len = skb_tail_pointer(skb) - (u8 *)r; + nla_nest_end(skb, nest); return err; } @@ -441,17 +445,17 @@ tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref) { struct tc_action *a; int err = -EINVAL; - unsigned char *b = skb_tail_pointer(skb); - struct nlattr *r ; + struct nlattr *nest; while ((a = act) != NULL) { - r = (struct nlattr *)skb_tail_pointer(skb); act = a->next; - NLA_PUT(skb, a->order, 0, NULL); + nest = nla_nest_start(skb, a->order); + if (nest == NULL) + goto nla_put_failure; err = tcf_action_dump_1(skb, a, bind, ref); if (err < 0) goto errout; - r->nla_len = skb_tail_pointer(skb) - (u8 *)r; + nla_nest_end(skb, nest); } return 0; @@ -459,7 +463,7 @@ tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref) nla_put_failure: err = -EINVAL; errout: - nlmsg_trim(skb, b); + nla_nest_cancel(skb, nest); return err; } @@ -627,7 +631,7 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq, struct tcamsg *t; struct nlmsghdr *nlh; unsigned char *b = skb_tail_pointer(skb); - struct nlattr *x; + struct nlattr *nest; nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags); @@ -636,13 +640,14 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq, t->tca__pad1 = 0; t->tca__pad2 = 0; - x = (struct nlattr *)skb_tail_pointer(skb); - NLA_PUT(skb, TCA_ACT_TAB, 0, NULL); + nest = nla_nest_start(skb, TCA_ACT_TAB); + if (nest == NULL) + goto nla_put_failure; if (tcf_action_dump(skb, a, bind, ref) < 0) goto nla_put_failure; - x->nla_len = skb_tail_pointer(skb) - (u8 *)x; + nla_nest_end(skb, nest); nlh->nlmsg_len = skb_tail_pointer(skb) - b; return skb->len; @@ -743,7 +748,7 @@ static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid) struct nlmsghdr *nlh; struct tcamsg *t; struct netlink_callback dcb; - struct nlattr *x; + struct nlattr *nest; struct nlattr *tb[TCA_ACT_MAX+1]; struct nlattr *kind; struct tc_action *a = create_a(0); @@ -779,14 +784,15 @@ static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid) t->tca__pad1 = 0; t->tca__pad2 = 0; - x = (struct nlattr *)skb_tail_pointer(skb); - NLA_PUT(skb, TCA_ACT_TAB, 0, NULL); + nest = nla_nest_start(skb, TCA_ACT_TAB); + if (nest == NULL) + goto nla_put_failure; err = a->ops->walk(skb, &dcb, RTM_DELACTION, a); if (err < 0) goto nla_put_failure; - x->nla_len = skb_tail_pointer(skb) - (u8 *)x; + nla_nest_end(skb, nest); nlh->nlmsg_len = skb_tail_pointer(skb) - b; nlh->nlmsg_flags |= NLM_F_ROOT; @@ -875,7 +881,7 @@ static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event, struct tcamsg *t; struct nlmsghdr *nlh; struct sk_buff *skb; - struct nlattr *x; + struct nlattr *nest; unsigned char *b; int err = 0; @@ -891,13 +897,14 @@ static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event, t->tca__pad1 = 0; t->tca__pad2 = 0; - x = (struct nlattr *)skb_tail_pointer(skb); - NLA_PUT(skb, TCA_ACT_TAB, 0, NULL); + nest = nla_nest_start(skb, TCA_ACT_TAB); + if (nest == NULL) + goto nla_put_failure; if (tcf_action_dump(skb, a, 0, 0) < 0) goto nla_put_failure; - x->nla_len = skb_tail_pointer(skb) - (u8 *)x; + nla_nest_end(skb, nest); nlh->nlmsg_len = skb_tail_pointer(skb) - b; NETLINK_CB(skb).dst_group = RTNLGRP_TC; @@ -1025,7 +1032,7 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) struct net *net = skb->sk->sk_net; struct nlmsghdr *nlh; unsigned char *b = skb_tail_pointer(skb); - struct nlattr *x; + struct nlattr *nest; struct tc_action_ops *a_o; struct tc_action a; int ret = 0; @@ -1060,18 +1067,19 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) t->tca__pad1 = 0; t->tca__pad2 = 0; - x = (struct nlattr *)skb_tail_pointer(skb); - NLA_PUT(skb, TCA_ACT_TAB, 0, NULL); + nest = nla_nest_start(skb, TCA_ACT_TAB); + if (nest == NULL) + goto nla_put_failure; ret = a_o->walk(skb, cb, RTM_GETACTION, &a); if (ret < 0) goto nla_put_failure; if (ret > 0) { - x->nla_len = skb_tail_pointer(skb) - (u8 *)x; + nla_nest_end(skb, nest); ret = skb->len; } else - nlmsg_trim(skb, x); + nla_nest_cancel(skb, nest); nlh->nlmsg_len = skb_tail_pointer(skb) - b; if (NETLINK_CB(cb->skb).pid && ret) -- cgit v1.2.3 From 57e1c487a4f5754cb77abeb00adb21faa88c484f Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 23 Jan 2008 20:34:28 -0800 Subject: [NET_SCHED]: Use NLA_PUT_STRING for string dumping Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/sched/act_api.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net/sched/act_api.c') diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 36022605fc16..e33e43abe969 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -121,7 +121,7 @@ static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a, nest = nla_nest_start(skb, a->order); if (nest == NULL) goto nla_put_failure; - NLA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind); + NLA_PUT_STRING(skb, TCA_KIND, a->ops->kind); for (i = 0; i < (hinfo->hmask + 1); i++) { p = hinfo->htab[tcf_hash(i, hinfo->hmask)]; @@ -423,7 +423,7 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref) if (a->ops == NULL || a->ops->dump == NULL) return err; - NLA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind); + NLA_PUT_STRING(skb, TCA_KIND, a->ops->kind); if (tcf_action_copy_stats(skb, a, 0)) goto nla_put_failure; nest = nla_nest_start(skb, TCA_OPTIONS); -- cgit v1.2.3 From 24beeab539c6f42c4a93e2ff7c3b5f272e60da45 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 23 Jan 2008 20:34:48 -0800 Subject: [NET_SCHED]: Use typeful attribute construction helpers Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/sched/act_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/sched/act_api.c') diff --git a/net/sched/act_api.c b/net/sched/act_api.c index e33e43abe969..41fbd496abac 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -133,7 +133,7 @@ static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a, p = s_p; } } - NLA_PUT(skb, TCA_FCNT, 4, &n_i); + NLA_PUT_U32(skb, TCA_FCNT, n_i); nla_nest_end(skb, nest); return n_i; -- cgit v1.2.3 From 1587bac49f8491b5006a78f8d726111b71757941 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 23 Jan 2008 20:35:03 -0800 Subject: [NET_SCHED]: Use typeful attribute parsing helpers Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/sched/act_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/sched/act_api.c') diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 41fbd496abac..0b8eb235bc13 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -690,7 +690,7 @@ tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 pid) if (tb[TCA_ACT_INDEX] == NULL || nla_len(tb[TCA_ACT_INDEX]) < sizeof(index)) goto err_out; - index = *(int *)nla_data(tb[TCA_ACT_INDEX]); + index = nla_get_u32(tb[TCA_ACT_INDEX]); err = -ENOMEM; a = kzalloc(sizeof(struct tc_action), GFP_KERNEL); -- cgit v1.2.3