From 2eb9d75c723252c1fa8f0206e6a0df220e3c64c0 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 22 Jan 2008 22:10:42 -0800 Subject: [NET_SCHED]: mark classifier ops __read_mostly Additionally remove unnecessary NULL initilizations of the next pointer. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/sched/cls_basic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/sched/cls_basic.c') diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index 8dbcf2771a4..b31f9f97198 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c @@ -271,7 +271,7 @@ rtattr_failure: return -1; } -static struct tcf_proto_ops cls_basic_ops = { +static struct tcf_proto_ops cls_basic_ops __read_mostly = { .kind = "basic", .classify = basic_classify, .init = basic_init, -- cgit v1.2.3-70-g09d2 From add93b610a4e66d36d0cf0b2596c3d3bcfdaee39 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 22 Jan 2008 22:11:33 -0800 Subject: [NET_SCHED]: Convert classifiers from rtnetlink to new netlink API Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/net/pkt_cls.h | 10 +++--- include/net/sch_generic.h | 2 +- net/sched/cls_api.c | 65 +++++++++++++++++++++------------------ net/sched/cls_basic.c | 40 ++++++++++++------------ net/sched/cls_fw.c | 54 ++++++++++++++++---------------- net/sched/cls_route.c | 70 +++++++++++++++++++++--------------------- net/sched/cls_rsvp.h | 48 ++++++++++++++--------------- net/sched/cls_tcindex.c | 66 +++++++++++++++++++-------------------- net/sched/cls_u32.c | 78 +++++++++++++++++++++++------------------------ net/sched/em_meta.c | 56 +++++++++++++++++----------------- net/sched/em_text.c | 9 ++++-- net/sched/ematch.c | 74 ++++++++++++++++++++++---------------------- 12 files changed, 290 insertions(+), 282 deletions(-) (limited to 'net/sched/cls_basic.c') diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index 2eaf2048002..8716eb757d5 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -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, @@ -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); @@ -338,9 +338,9 @@ static inline int tcf_valid_offset(const struct sk_buff *skb, #include 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; } diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 8cacdff2459..ab502ec1c61 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -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); diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 9eeb3c6c82f..87be2b2fc29 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -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; @@ -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; @@ -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); @@ -160,6 +159,10 @@ replay: 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; @@ -202,7 +205,7 @@ replay: 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; @@ -217,14 +220,14 @@ replay: 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(); @@ -263,7 +266,7 @@ replay: *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); @@ -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; } @@ -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)); @@ -487,8 +490,9 @@ 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) @@ -496,8 +500,9 @@ int tcf_exts_validate(struct tcf_proto *tp, struct rtattr **tb, 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; @@ -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 @@ -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); @@ -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); diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index b31f9f97198..3953da33956 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c @@ -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); } @@ -164,23 +164,23 @@ errout: } 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; @@ -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; @@ -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; } diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index b45038770e7..db6e90a3784 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c @@ -188,37 +188,37 @@ out: static int fw_change_attrs(struct tcf_proto *tp, struct fw_filter *f, - struct rtattr **tb, struct rtattr **tca, unsigned long base) + struct nlattr **tb, struct nlattr **tca, unsigned long base) { struct fw_head *head = (struct fw_head *)tp->root; struct tcf_exts e; u32 mask; int err; - err = tcf_exts_validate(tp, tb, tca[TCA_RATE-1], &e, &fw_ext_map); + err = tcf_exts_validate(tp, tb, tca[TCA_RATE], &e, &fw_ext_map); if (err < 0) return err; err = -EINVAL; - if (tb[TCA_FW_CLASSID-1]) { - if (RTA_PAYLOAD(tb[TCA_FW_CLASSID-1]) != sizeof(u32)) + if (tb[TCA_FW_CLASSID]) { + if (nla_len(tb[TCA_FW_CLASSID]) != sizeof(u32)) goto errout; - f->res.classid = *(u32*)RTA_DATA(tb[TCA_FW_CLASSID-1]); + f->res.classid = *(u32*)nla_data(tb[TCA_FW_CLASSID]); tcf_bind_filter(tp, &f->res, base); } #ifdef CONFIG_NET_CLS_IND - if (tb[TCA_FW_INDEV-1]) { - err = tcf_change_indev(tp, f->indev, tb[TCA_FW_INDEV-1]); + if (tb[TCA_FW_INDEV]) { + err = tcf_change_indev(tp, f->indev, tb[TCA_FW_INDEV]); if (err < 0) goto errout; } #endif /* CONFIG_NET_CLS_IND */ - if (tb[TCA_FW_MASK-1]) { - if (RTA_PAYLOAD(tb[TCA_FW_MASK-1]) != sizeof(u32)) + if (tb[TCA_FW_MASK]) { + if (nla_len(tb[TCA_FW_MASK]) != sizeof(u32)) goto errout; - mask = *(u32*)RTA_DATA(tb[TCA_FW_MASK-1]); + mask = *(u32*)nla_data(tb[TCA_FW_MASK]); if (mask != head->mask) goto errout; } else if (head->mask != 0xFFFFFFFF) @@ -234,19 +234,19 @@ errout: static int fw_change(struct tcf_proto *tp, unsigned long base, u32 handle, - struct rtattr **tca, + struct nlattr **tca, unsigned long *arg) { struct fw_head *head = (struct fw_head*)tp->root; struct fw_filter *f = (struct fw_filter *) *arg; - struct rtattr *opt = tca[TCA_OPTIONS-1]; - struct rtattr *tb[TCA_FW_MAX]; + struct nlattr *opt = tca[TCA_OPTIONS]; + struct nlattr *tb[TCA_FW_MAX + 1]; int err; if (!opt) return handle ? -EINVAL : 0; - if (rtattr_parse_nested(tb, TCA_FW_MAX, opt) < 0) + if (nla_parse_nested(tb, TCA_FW_MAX, opt, NULL) < 0) return -EINVAL; if (f != NULL) { @@ -260,10 +260,10 @@ static int fw_change(struct tcf_proto *tp, unsigned long base, if (head == NULL) { u32 mask = 0xFFFFFFFF; - if (tb[TCA_FW_MASK-1]) { - if (RTA_PAYLOAD(tb[TCA_FW_MASK-1]) != sizeof(u32)) + if (tb[TCA_FW_MASK]) { + if (nla_len(tb[TCA_FW_MASK]) != sizeof(u32)) return -EINVAL; - mask = *(u32*)RTA_DATA(tb[TCA_FW_MASK-1]); + mask = *(u32*)nla_data(tb[TCA_FW_MASK]); } head = kzalloc(sizeof(struct fw_head), GFP_KERNEL); @@ -333,7 +333,7 @@ static int fw_dump(struct tcf_proto *tp, unsigned long fh, struct fw_head *head = (struct fw_head *)tp->root; struct fw_filter *f = (struct fw_filter*)fh; unsigned char *b = skb_tail_pointer(skb); - struct rtattr *rta; + struct nlattr *nla; if (f == NULL) return skb->len; @@ -343,29 +343,29 @@ static int fw_dump(struct tcf_proto *tp, unsigned long fh, if (!f->res.classid && !tcf_exts_is_available(&f->exts)) return skb->len; - 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_FW_CLASSID, 4, &f->res.classid); + NLA_PUT(skb, TCA_FW_CLASSID, 4, &f->res.classid); #ifdef CONFIG_NET_CLS_IND if (strlen(f->indev)) - RTA_PUT(skb, TCA_FW_INDEV, IFNAMSIZ, f->indev); + NLA_PUT(skb, TCA_FW_INDEV, IFNAMSIZ, f->indev); #endif /* CONFIG_NET_CLS_IND */ if (head->mask != 0xFFFFFFFF) - RTA_PUT(skb, TCA_FW_MASK, 4, &head->mask); + NLA_PUT(skb, TCA_FW_MASK, 4, &head->mask); if (tcf_exts_dump(skb, &f->exts, &fw_ext_map) < 0) - goto rtattr_failure; + goto nla_put_failure; - rta->rta_len = skb_tail_pointer(skb) - b; + nla->nla_len = skb_tail_pointer(skb) - b; if (tcf_exts_dump_stats(skb, &f->exts, &fw_ext_map) < 0) - goto rtattr_failure; + goto nla_put_failure; return skb->len; -rtattr_failure: +nla_put_failure: nlmsg_trim(skb, b); return -1; } diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c index e70edd0f7bc..b1aae84cbad 100644 --- a/net/sched/cls_route.c +++ b/net/sched/cls_route.c @@ -325,7 +325,7 @@ static int route4_delete(struct tcf_proto *tp, unsigned long arg) static int route4_set_parms(struct tcf_proto *tp, unsigned long base, struct route4_filter *f, u32 handle, struct route4_head *head, - struct rtattr **tb, struct rtattr *est, int new) + struct nlattr **tb, struct nlattr *est, int new) { int err; u32 id = 0, to = 0, nhandle = 0x8000; @@ -339,34 +339,34 @@ static int route4_set_parms(struct tcf_proto *tp, unsigned long base, return err; err = -EINVAL; - if (tb[TCA_ROUTE4_CLASSID-1]) - if (RTA_PAYLOAD(tb[TCA_ROUTE4_CLASSID-1]) < sizeof(u32)) + if (tb[TCA_ROUTE4_CLASSID]) + if (nla_len(tb[TCA_ROUTE4_CLASSID]) < sizeof(u32)) goto errout; - if (tb[TCA_ROUTE4_TO-1]) { + if (tb[TCA_ROUTE4_TO]) { if (new && handle & 0x8000) goto errout; - if (RTA_PAYLOAD(tb[TCA_ROUTE4_TO-1]) < sizeof(u32)) + if (nla_len(tb[TCA_ROUTE4_TO]) < sizeof(u32)) goto errout; - to = *(u32*)RTA_DATA(tb[TCA_ROUTE4_TO-1]); + to = *(u32*)nla_data(tb[TCA_ROUTE4_TO]); if (to > 0xFF) goto errout; nhandle = to; } - if (tb[TCA_ROUTE4_FROM-1]) { - if (tb[TCA_ROUTE4_IIF-1]) + if (tb[TCA_ROUTE4_FROM]) { + if (tb[TCA_ROUTE4_IIF]) goto errout; - if (RTA_PAYLOAD(tb[TCA_ROUTE4_FROM-1]) < sizeof(u32)) + if (nla_len(tb[TCA_ROUTE4_FROM]) < sizeof(u32)) goto errout; - id = *(u32*)RTA_DATA(tb[TCA_ROUTE4_FROM-1]); + id = *(u32*)nla_data(tb[TCA_ROUTE4_FROM]); if (id > 0xFF) goto errout; nhandle |= id << 16; - } else if (tb[TCA_ROUTE4_IIF-1]) { - if (RTA_PAYLOAD(tb[TCA_ROUTE4_IIF-1]) < sizeof(u32)) + } else if (tb[TCA_ROUTE4_IIF]) { + if (nla_len(tb[TCA_ROUTE4_IIF]) < sizeof(u32)) goto errout; - id = *(u32*)RTA_DATA(tb[TCA_ROUTE4_IIF-1]); + id = *(u32*)nla_data(tb[TCA_ROUTE4_IIF]); if (id > 0x7FFF) goto errout; nhandle |= (id | 0x8000) << 16; @@ -398,20 +398,20 @@ static int route4_set_parms(struct tcf_proto *tp, unsigned long base, } tcf_tree_lock(tp); - if (tb[TCA_ROUTE4_TO-1]) + if (tb[TCA_ROUTE4_TO]) f->id = to; - if (tb[TCA_ROUTE4_FROM-1]) + if (tb[TCA_ROUTE4_FROM]) f->id = to | id<<16; - else if (tb[TCA_ROUTE4_IIF-1]) + else if (tb[TCA_ROUTE4_IIF]) f->iif = id; f->handle = nhandle; f->bkt = b; tcf_tree_unlock(tp); - if (tb[TCA_ROUTE4_CLASSID-1]) { - f->res.classid = *(u32*)RTA_DATA(tb[TCA_ROUTE4_CLASSID-1]); + if (tb[TCA_ROUTE4_CLASSID]) { + f->res.classid = *(u32*)nla_data(tb[TCA_ROUTE4_CLASSID]); tcf_bind_filter(tp, &f->res, base); } @@ -425,14 +425,14 @@ errout: static int route4_change(struct tcf_proto *tp, unsigned long base, u32 handle, - struct rtattr **tca, + struct nlattr **tca, unsigned long *arg) { struct route4_head *head = tp->root; struct route4_filter *f, *f1, **fp; struct route4_bucket *b; - struct rtattr *opt = tca[TCA_OPTIONS-1]; - struct rtattr *tb[TCA_ROUTE4_MAX]; + struct nlattr *opt = tca[TCA_OPTIONS]; + struct nlattr *tb[TCA_ROUTE4_MAX + 1]; unsigned int h, th; u32 old_handle = 0; int err; @@ -440,7 +440,7 @@ static int route4_change(struct tcf_proto *tp, unsigned long base, if (opt == NULL) return handle ? -EINVAL : 0; - if (rtattr_parse_nested(tb, TCA_ROUTE4_MAX, opt) < 0) + if (nla_parse_nested(tb, TCA_ROUTE4_MAX, opt, NULL) < 0) return -EINVAL; if ((f = (struct route4_filter*)*arg) != NULL) { @@ -451,7 +451,7 @@ static int route4_change(struct tcf_proto *tp, unsigned long base, old_handle = f->handle; err = route4_set_parms(tp, base, f, handle, head, tb, - tca[TCA_RATE-1], 0); + tca[TCA_RATE], 0); if (err < 0) return err; @@ -474,7 +474,7 @@ static int route4_change(struct tcf_proto *tp, unsigned long base, goto errout; err = route4_set_parms(tp, base, f, handle, head, tb, - tca[TCA_RATE-1], 1); + tca[TCA_RATE], 1); if (err < 0) goto errout; @@ -550,7 +550,7 @@ static int route4_dump(struct tcf_proto *tp, unsigned long fh, { struct route4_filter *f = (struct route4_filter*)fh; unsigned char *b = skb_tail_pointer(skb); - struct rtattr *rta; + struct nlattr *nla; u32 id; if (f == NULL) @@ -558,34 +558,34 @@ static int route4_dump(struct tcf_proto *tp, unsigned long fh, 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->handle&0x8000)) { id = f->id&0xFF; - RTA_PUT(skb, TCA_ROUTE4_TO, sizeof(id), &id); + NLA_PUT(skb, TCA_ROUTE4_TO, sizeof(id), &id); } if (f->handle&0x80000000) { if ((f->handle>>16) != 0xFFFF) - RTA_PUT(skb, TCA_ROUTE4_IIF, sizeof(f->iif), &f->iif); + NLA_PUT(skb, TCA_ROUTE4_IIF, sizeof(f->iif), &f->iif); } else { id = f->id>>16; - RTA_PUT(skb, TCA_ROUTE4_FROM, sizeof(id), &id); + NLA_PUT(skb, TCA_ROUTE4_FROM, sizeof(id), &id); } if (f->res.classid) - RTA_PUT(skb, TCA_ROUTE4_CLASSID, 4, &f->res.classid); + NLA_PUT(skb, TCA_ROUTE4_CLASSID, 4, &f->res.classid); if (tcf_exts_dump(skb, &f->exts, &route_ext_map) < 0) - goto rtattr_failure; + goto nla_put_failure; - rta->rta_len = skb_tail_pointer(skb) - b; + nla->nla_len = skb_tail_pointer(skb) - b; if (tcf_exts_dump_stats(skb, &f->exts, &route_ext_map) < 0) - goto rtattr_failure; + goto nla_put_failure; return skb->len; -rtattr_failure: +nla_put_failure: nlmsg_trim(skb, b); return -1; } diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index 22f9ede70e8..2364c79d083 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h @@ -399,15 +399,15 @@ static u32 gen_tunnel(struct rsvp_head *data) static int rsvp_change(struct tcf_proto *tp, unsigned long base, u32 handle, - struct rtattr **tca, + struct nlattr **tca, unsigned long *arg) { struct rsvp_head *data = tp->root; struct rsvp_filter *f, **fp; struct rsvp_session *s, **sp; struct tc_rsvp_pinfo *pinfo = NULL; - struct rtattr *opt = tca[TCA_OPTIONS-1]; - struct rtattr *tb[TCA_RSVP_MAX]; + struct nlattr *opt = tca[TCA_OPTIONS-1]; + struct nlattr *tb[TCA_RSVP_MAX + 1]; struct tcf_exts e; unsigned h1, h2; __be32 *dst; @@ -416,7 +416,7 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base, if (opt == NULL) return handle ? -EINVAL : 0; - if (rtattr_parse_nested(tb, TCA_RSVP_MAX, opt) < 0) + if (nla_parse_nested(tb, TCA_RSVP_MAX, opt, NULL) < 0) return -EINVAL; err = tcf_exts_validate(tp, tb, tca[TCA_RATE-1], &e, &rsvp_ext_map); @@ -429,7 +429,7 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base, if (f->handle != handle && handle) goto errout2; if (tb[TCA_RSVP_CLASSID-1]) { - f->res.classid = *(u32*)RTA_DATA(tb[TCA_RSVP_CLASSID-1]); + f->res.classid = *(u32*)nla_data(tb[TCA_RSVP_CLASSID-1]); tcf_bind_filter(tp, &f->res, base); } @@ -452,30 +452,30 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base, h2 = 16; if (tb[TCA_RSVP_SRC-1]) { err = -EINVAL; - if (RTA_PAYLOAD(tb[TCA_RSVP_SRC-1]) != sizeof(f->src)) + if (nla_len(tb[TCA_RSVP_SRC-1]) != sizeof(f->src)) goto errout; - memcpy(f->src, RTA_DATA(tb[TCA_RSVP_SRC-1]), sizeof(f->src)); + memcpy(f->src, nla_data(tb[TCA_RSVP_SRC-1]), sizeof(f->src)); h2 = hash_src(f->src); } if (tb[TCA_RSVP_PINFO-1]) { err = -EINVAL; - if (RTA_PAYLOAD(tb[TCA_RSVP_PINFO-1]) < sizeof(struct tc_rsvp_pinfo)) + if (nla_len(tb[TCA_RSVP_PINFO-1]) < sizeof(struct tc_rsvp_pinfo)) goto errout; - pinfo = RTA_DATA(tb[TCA_RSVP_PINFO-1]); + pinfo = nla_data(tb[TCA_RSVP_PINFO-1]); f->spi = pinfo->spi; f->tunnelhdr = pinfo->tunnelhdr; } if (tb[TCA_RSVP_CLASSID-1]) { err = -EINVAL; - if (RTA_PAYLOAD(tb[TCA_RSVP_CLASSID-1]) != 4) + if (nla_len(tb[TCA_RSVP_CLASSID-1]) != 4) goto errout; - f->res.classid = *(u32*)RTA_DATA(tb[TCA_RSVP_CLASSID-1]); + f->res.classid = *(u32*)nla_data(tb[TCA_RSVP_CLASSID-1]); } err = -EINVAL; - if (RTA_PAYLOAD(tb[TCA_RSVP_DST-1]) != sizeof(f->src)) + if (nla_len(tb[TCA_RSVP_DST-1]) != sizeof(f->src)) goto errout; - dst = RTA_DATA(tb[TCA_RSVP_DST-1]); + dst = nla_data(tb[TCA_RSVP_DST-1]); h1 = hash_dst(dst, pinfo ? pinfo->protocol : 0, pinfo ? pinfo->tunnelid : 0); err = -ENOMEM; @@ -594,7 +594,7 @@ static int rsvp_dump(struct tcf_proto *tp, unsigned long fh, struct rsvp_filter *f = (struct rsvp_filter*)fh; struct rsvp_session *s; unsigned char *b = skb_tail_pointer(skb); - struct rtattr *rta; + struct nlattr *nla; struct tc_rsvp_pinfo pinfo; if (f == NULL) @@ -604,32 +604,32 @@ static int rsvp_dump(struct tcf_proto *tp, unsigned long fh, 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); - RTA_PUT(skb, TCA_RSVP_DST, sizeof(s->dst), &s->dst); + NLA_PUT(skb, TCA_RSVP_DST, sizeof(s->dst), &s->dst); pinfo.dpi = s->dpi; pinfo.spi = f->spi; pinfo.protocol = s->protocol; pinfo.tunnelid = s->tunnelid; pinfo.tunnelhdr = f->tunnelhdr; pinfo.pad = 0; - RTA_PUT(skb, TCA_RSVP_PINFO, sizeof(pinfo), &pinfo); + NLA_PUT(skb, TCA_RSVP_PINFO, sizeof(pinfo), &pinfo); if (f->res.classid) - RTA_PUT(skb, TCA_RSVP_CLASSID, 4, &f->res.classid); + NLA_PUT(skb, TCA_RSVP_CLASSID, 4, &f->res.classid); if (((f->handle>>8)&0xFF) != 16) - RTA_PUT(skb, TCA_RSVP_SRC, sizeof(f->src), f->src); + NLA_PUT(skb, TCA_RSVP_SRC, sizeof(f->src), f->src); if (tcf_exts_dump(skb, &f->exts, &rsvp_ext_map) < 0) - goto rtattr_failure; + goto nla_put_failure; - rta->rta_len = skb_tail_pointer(skb) - b; + nla->nla_len = skb_tail_pointer(skb) - b; if (tcf_exts_dump_stats(skb, &f->exts, &rsvp_ext_map) < 0) - goto rtattr_failure; + goto nla_put_failure; return skb->len; -rtattr_failure: +nla_put_failure: nlmsg_trim(skb, b); return -1; } diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index e36977b17fa..ed8023944fe 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c @@ -196,7 +196,7 @@ valid_perfect_hash(struct tcindex_data *p) static int tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle, struct tcindex_data *p, struct tcindex_filter_result *r, - struct rtattr **tb, struct rtattr *est) + struct nlattr **tb, struct nlattr *est) { int err, balloc = 0; struct tcindex_filter_result new_filter_result, *old_r = r; @@ -218,22 +218,22 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle, memset(&cr, 0, sizeof(cr)); err = -EINVAL; - if (tb[TCA_TCINDEX_HASH-1]) { - if (RTA_PAYLOAD(tb[TCA_TCINDEX_HASH-1]) < sizeof(u32)) + if (tb[TCA_TCINDEX_HASH]) { + if (nla_len(tb[TCA_TCINDEX_HASH]) < sizeof(u32)) goto errout; - cp.hash = *(u32 *) RTA_DATA(tb[TCA_TCINDEX_HASH-1]); + cp.hash = *(u32 *) nla_data(tb[TCA_TCINDEX_HASH]); } - if (tb[TCA_TCINDEX_MASK-1]) { - if (RTA_PAYLOAD(tb[TCA_TCINDEX_MASK-1]) < sizeof(u16)) + if (tb[TCA_TCINDEX_MASK]) { + if (nla_len(tb[TCA_TCINDEX_MASK]) < sizeof(u16)) goto errout; - cp.mask = *(u16 *) RTA_DATA(tb[TCA_TCINDEX_MASK-1]); + cp.mask = *(u16 *) nla_data(tb[TCA_TCINDEX_MASK]); } - if (tb[TCA_TCINDEX_SHIFT-1]) { - if (RTA_PAYLOAD(tb[TCA_TCINDEX_SHIFT-1]) < sizeof(int)) + if (tb[TCA_TCINDEX_SHIFT]) { + if (nla_len(tb[TCA_TCINDEX_SHIFT]) < sizeof(int)) goto errout; - cp.shift = *(int *) RTA_DATA(tb[TCA_TCINDEX_SHIFT-1]); + cp.shift = *(int *) nla_data(tb[TCA_TCINDEX_SHIFT]); } err = -EBUSY; @@ -248,11 +248,11 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle, goto errout; err = -EINVAL; - if (tb[TCA_TCINDEX_FALL_THROUGH-1]) { - if (RTA_PAYLOAD(tb[TCA_TCINDEX_FALL_THROUGH-1]) < sizeof(u32)) + if (tb[TCA_TCINDEX_FALL_THROUGH]) { + if (nla_len(tb[TCA_TCINDEX_FALL_THROUGH]) < sizeof(u32)) goto errout; cp.fall_through = - *(u32 *) RTA_DATA(tb[TCA_TCINDEX_FALL_THROUGH-1]); + *(u32 *) nla_data(tb[TCA_TCINDEX_FALL_THROUGH]); } if (!cp.hash) { @@ -304,8 +304,8 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle, goto errout_alloc; } - if (tb[TCA_TCINDEX_CLASSID-1]) { - cr.res.classid = *(u32 *) RTA_DATA(tb[TCA_TCINDEX_CLASSID-1]); + if (tb[TCA_TCINDEX_CLASSID]) { + cr.res.classid = *(u32 *) nla_data(tb[TCA_TCINDEX_CLASSID]); tcf_bind_filter(tp, &cr.res, base); } @@ -344,10 +344,10 @@ errout: static int tcindex_change(struct tcf_proto *tp, unsigned long base, u32 handle, - struct rtattr **tca, unsigned long *arg) + struct nlattr **tca, unsigned long *arg) { - struct rtattr *opt = tca[TCA_OPTIONS-1]; - struct rtattr *tb[TCA_TCINDEX_MAX]; + struct nlattr *opt = tca[TCA_OPTIONS]; + struct nlattr *tb[TCA_TCINDEX_MAX + 1]; struct tcindex_data *p = PRIV(tp); struct tcindex_filter_result *r = (struct tcindex_filter_result *) *arg; @@ -358,10 +358,10 @@ tcindex_change(struct tcf_proto *tp, unsigned long base, u32 handle, if (!opt) return 0; - if (rtattr_parse_nested(tb, TCA_TCINDEX_MAX, opt) < 0) + if (nla_parse_nested(tb, TCA_TCINDEX_MAX, opt, NULL) < 0) return -EINVAL; - return tcindex_set_parms(tp, base, handle, p, r, tb, tca[TCA_RATE-1]); + return tcindex_set_parms(tp, base, handle, p, r, tb, tca[TCA_RATE]); } @@ -435,21 +435,21 @@ static int tcindex_dump(struct tcf_proto *tp, unsigned long fh, struct tcindex_data *p = PRIV(tp); struct tcindex_filter_result *r = (struct tcindex_filter_result *) fh; unsigned char *b = skb_tail_pointer(skb); - struct rtattr *rta; + struct nlattr *nla; pr_debug("tcindex_dump(tp %p,fh 0x%lx,skb %p,t %p),p %p,r %p,b %p\n", tp, fh, skb, t, p, r, b); pr_debug("p->perfect %p p->h %p\n", p->perfect, p->h); - rta = (struct rtattr *) b; - RTA_PUT(skb, TCA_OPTIONS, 0, NULL); + nla = (struct nlattr *) b; + NLA_PUT(skb, TCA_OPTIONS, 0, NULL); if (!fh) { t->tcm_handle = ~0; /* whatever ... */ - RTA_PUT(skb, TCA_TCINDEX_HASH, sizeof(p->hash), &p->hash); - RTA_PUT(skb, TCA_TCINDEX_MASK, sizeof(p->mask), &p->mask); - RTA_PUT(skb, TCA_TCINDEX_SHIFT, sizeof(p->shift), &p->shift); - RTA_PUT(skb, TCA_TCINDEX_FALL_THROUGH, sizeof(p->fall_through), + NLA_PUT(skb, TCA_TCINDEX_HASH, sizeof(p->hash), &p->hash); + NLA_PUT(skb, TCA_TCINDEX_MASK, sizeof(p->mask), &p->mask); + NLA_PUT(skb, TCA_TCINDEX_SHIFT, sizeof(p->shift), &p->shift); + NLA_PUT(skb, TCA_TCINDEX_FALL_THROUGH, sizeof(p->fall_through), &p->fall_through); - rta->rta_len = skb_tail_pointer(skb) - b; + nla->nla_len = skb_tail_pointer(skb) - b; } else { if (p->perfect) { t->tcm_handle = r-p->perfect; @@ -468,19 +468,19 @@ static int tcindex_dump(struct tcf_proto *tp, unsigned long fh, } pr_debug("handle = %d\n", t->tcm_handle); if (r->res.class) - RTA_PUT(skb, TCA_TCINDEX_CLASSID, 4, &r->res.classid); + NLA_PUT(skb, TCA_TCINDEX_CLASSID, 4, &r->res.classid); if (tcf_exts_dump(skb, &r->exts, &tcindex_ext_map) < 0) - goto rtattr_failure; - rta->rta_len = skb_tail_pointer(skb) - b; + goto nla_put_failure; + nla->nla_len = skb_tail_pointer(skb) - b; if (tcf_exts_dump_stats(skb, &r->exts, &tcindex_ext_map) < 0) - goto rtattr_failure; + goto nla_put_failure; } return skb->len; -rtattr_failure: +nla_put_failure: nlmsg_trim(skb, b); return -1; } diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 7bf3cd4e731..aaf5049f951 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -462,8 +462,8 @@ static u32 gen_new_kid(struct tc_u_hnode *ht, u32 handle) static int u32_set_parms(struct tcf_proto *tp, unsigned long base, struct tc_u_hnode *ht, - struct tc_u_knode *n, struct rtattr **tb, - struct rtattr *est) + struct tc_u_knode *n, struct nlattr **tb, + struct nlattr *est) { int err; struct tcf_exts e; @@ -473,8 +473,8 @@ static int u32_set_parms(struct tcf_proto *tp, unsigned long base, return err; err = -EINVAL; - if (tb[TCA_U32_LINK-1]) { - u32 handle = *(u32*)RTA_DATA(tb[TCA_U32_LINK-1]); + if (tb[TCA_U32_LINK]) { + u32 handle = *(u32*)nla_data(tb[TCA_U32_LINK]); struct tc_u_hnode *ht_down = NULL; if (TC_U32_KEY(handle)) @@ -495,14 +495,14 @@ static int u32_set_parms(struct tcf_proto *tp, unsigned long base, if (ht_down) ht_down->refcnt--; } - if (tb[TCA_U32_CLASSID-1]) { - n->res.classid = *(u32*)RTA_DATA(tb[TCA_U32_CLASSID-1]); + if (tb[TCA_U32_CLASSID]) { + n->res.classid = *(u32*)nla_data(tb[TCA_U32_CLASSID]); tcf_bind_filter(tp, &n->res, base); } #ifdef CONFIG_NET_CLS_IND - if (tb[TCA_U32_INDEV-1]) { - err = tcf_change_indev(tp, n->indev, tb[TCA_U32_INDEV-1]); + if (tb[TCA_U32_INDEV]) { + err = tcf_change_indev(tp, n->indev, tb[TCA_U32_INDEV]); if (err < 0) goto errout; } @@ -516,33 +516,33 @@ errout: } static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, - struct rtattr **tca, + struct nlattr **tca, unsigned long *arg) { struct tc_u_common *tp_c = tp->data; struct tc_u_hnode *ht; struct tc_u_knode *n; struct tc_u32_sel *s; - struct rtattr *opt = tca[TCA_OPTIONS-1]; - struct rtattr *tb[TCA_U32_MAX]; + struct nlattr *opt = tca[TCA_OPTIONS]; + struct nlattr *tb[TCA_U32_MAX + 1]; u32 htid; int err; if (opt == NULL) return handle ? -EINVAL : 0; - if (rtattr_parse_nested(tb, TCA_U32_MAX, opt) < 0) + if (nla_parse_nested(tb, TCA_U32_MAX, opt, NULL) < 0) return -EINVAL; if ((n = (struct tc_u_knode*)*arg) != NULL) { if (TC_U32_KEY(n->handle) == 0) return -EINVAL; - return u32_set_parms(tp, base, n->ht_up, n, tb, tca[TCA_RATE-1]); + return u32_set_parms(tp, base, n->ht_up, n, tb, tca[TCA_RATE]); } - if (tb[TCA_U32_DIVISOR-1]) { - unsigned divisor = *(unsigned*)RTA_DATA(tb[TCA_U32_DIVISOR-1]); + if (tb[TCA_U32_DIVISOR]) { + unsigned divisor = *(unsigned*)nla_data(tb[TCA_U32_DIVISOR]); if (--divisor > 0x100) return -EINVAL; @@ -567,8 +567,8 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, return 0; } - if (tb[TCA_U32_HASH-1]) { - htid = *(unsigned*)RTA_DATA(tb[TCA_U32_HASH-1]); + if (tb[TCA_U32_HASH]) { + htid = *(unsigned*)nla_data(tb[TCA_U32_HASH]); if (TC_U32_HTID(htid) == TC_U32_ROOT) { ht = tp->root; htid = ht->handle; @@ -592,11 +592,11 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, } else handle = gen_new_kid(ht, htid); - if (tb[TCA_U32_SEL-1] == NULL || - RTA_PAYLOAD(tb[TCA_U32_SEL-1]) < sizeof(struct tc_u32_sel)) + if (tb[TCA_U32_SEL] == NULL || + nla_len(tb[TCA_U32_SEL]) < sizeof(struct tc_u32_sel)) return -EINVAL; - s = RTA_DATA(tb[TCA_U32_SEL-1]); + s = nla_data(tb[TCA_U32_SEL]); n = kzalloc(sizeof(*n) + s->nkeys*sizeof(struct tc_u32_key), GFP_KERNEL); if (n == NULL) @@ -616,23 +616,23 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, n->fshift = s->hmask ? ffs(ntohl(s->hmask)) - 1 : 0; #ifdef CONFIG_CLS_U32_MARK - if (tb[TCA_U32_MARK-1]) { + if (tb[TCA_U32_MARK]) { struct tc_u32_mark *mark; - if (RTA_PAYLOAD(tb[TCA_U32_MARK-1]) < sizeof(struct tc_u32_mark)) { + if (nla_len(tb[TCA_U32_MARK]) < sizeof(struct tc_u32_mark)) { #ifdef CONFIG_CLS_U32_PERF kfree(n->pf); #endif kfree(n); return -EINVAL; } - mark = RTA_DATA(tb[TCA_U32_MARK-1]); + mark = nla_data(tb[TCA_U32_MARK]); memcpy(&n->mark, mark, sizeof(struct tc_u32_mark)); n->mark.success = 0; } #endif - err = u32_set_parms(tp, base, ht, n, tb, tca[TCA_RATE-1]); + err = u32_set_parms(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) @@ -694,59 +694,59 @@ static int u32_dump(struct tcf_proto *tp, unsigned long fh, { struct tc_u_knode *n = (struct tc_u_knode*)fh; unsigned char *b = skb_tail_pointer(skb); - struct rtattr *rta; + struct nlattr *nla; if (n == NULL) return skb->len; t->tcm_handle = n->handle; - rta = (struct rtattr*)b; - RTA_PUT(skb, TCA_OPTIONS, 0, NULL); + nla = (struct nlattr*)b; + NLA_PUT(skb, TCA_OPTIONS, 0, NULL); if (TC_U32_KEY(n->handle) == 0) { struct tc_u_hnode *ht = (struct tc_u_hnode*)fh; u32 divisor = ht->divisor+1; - RTA_PUT(skb, TCA_U32_DIVISOR, 4, &divisor); + NLA_PUT(skb, TCA_U32_DIVISOR, 4, &divisor); } else { - RTA_PUT(skb, TCA_U32_SEL, + NLA_PUT(skb, TCA_U32_SEL, sizeof(n->sel) + n->sel.nkeys*sizeof(struct tc_u32_key), &n->sel); if (n->ht_up) { u32 htid = n->handle & 0xFFFFF000; - RTA_PUT(skb, TCA_U32_HASH, 4, &htid); + NLA_PUT(skb, TCA_U32_HASH, 4, &htid); } if (n->res.classid) - RTA_PUT(skb, TCA_U32_CLASSID, 4, &n->res.classid); + NLA_PUT(skb, TCA_U32_CLASSID, 4, &n->res.classid); if (n->ht_down) - RTA_PUT(skb, TCA_U32_LINK, 4, &n->ht_down->handle); + NLA_PUT(skb, TCA_U32_LINK, 4, &n->ht_down->handle); #ifdef CONFIG_CLS_U32_MARK if (n->mark.val || n->mark.mask) - RTA_PUT(skb, TCA_U32_MARK, sizeof(n->mark), &n->mark); + NLA_PUT(skb, TCA_U32_MARK, sizeof(n->mark), &n->mark); #endif if (tcf_exts_dump(skb, &n->exts, &u32_ext_map) < 0) - goto rtattr_failure; + goto nla_put_failure; #ifdef CONFIG_NET_CLS_IND if(strlen(n->indev)) - RTA_PUT(skb, TCA_U32_INDEV, IFNAMSIZ, n->indev); + NLA_PUT(skb, TCA_U32_INDEV, IFNAMSIZ, n->indev); #endif #ifdef CONFIG_CLS_U32_PERF - RTA_PUT(skb, TCA_U32_PCNT, + NLA_PUT(skb, TCA_U32_PCNT, sizeof(struct tc_u32_pcnt) + n->sel.nkeys*sizeof(u64), n->pf); #endif } - rta->rta_len = skb_tail_pointer(skb) - b; + nla->nla_len = skb_tail_pointer(skb) - b; if (TC_U32_KEY(n->handle)) if (tcf_exts_dump_stats(skb, &n->exts, &u32_ext_map) < 0) - goto rtattr_failure; + goto nla_put_failure; return skb->len; -rtattr_failure: +nla_put_failure: nlmsg_trim(skb, b); return -1; } diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index ceda8890ab0..92b6863e928 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -542,11 +542,11 @@ static int meta_var_compare(struct meta_obj *a, struct meta_obj *b) return r; } -static int meta_var_change(struct meta_value *dst, struct rtattr *rta) +static int meta_var_change(struct meta_value *dst, struct nlattr *nla) { - int len = RTA_PAYLOAD(rta); + int len = nla_len(nla); - dst->val = (unsigned long)kmemdup(RTA_DATA(rta), len, GFP_KERNEL); + dst->val = (unsigned long)kmemdup(nla_data(nla), len, GFP_KERNEL); if (dst->val == 0UL) return -ENOMEM; dst->len = len; @@ -570,10 +570,10 @@ static void meta_var_apply_extras(struct meta_value *v, static int meta_var_dump(struct sk_buff *skb, struct meta_value *v, int tlv) { if (v->val && v->len) - RTA_PUT(skb, tlv, v->len, (void *) v->val); + NLA_PUT(skb, tlv, v->len, (void *) v->val); return 0; -rtattr_failure: +nla_put_failure: return -1; } @@ -594,13 +594,13 @@ static int meta_int_compare(struct meta_obj *a, struct meta_obj *b) return 1; } -static int meta_int_change(struct meta_value *dst, struct rtattr *rta) +static int meta_int_change(struct meta_value *dst, struct nlattr *nla) { - if (RTA_PAYLOAD(rta) >= sizeof(unsigned long)) { - dst->val = *(unsigned long *) RTA_DATA(rta); + if (nla_len(nla) >= sizeof(unsigned long)) { + dst->val = *(unsigned long *) nla_data(nla); dst->len = sizeof(unsigned long); - } else if (RTA_PAYLOAD(rta) == sizeof(u32)) { - dst->val = *(u32 *) RTA_DATA(rta); + } else if (nla_len(nla) == sizeof(u32)) { + dst->val = *(u32 *) nla_data(nla); dst->len = sizeof(u32); } else return -EINVAL; @@ -621,15 +621,15 @@ static void meta_int_apply_extras(struct meta_value *v, static int meta_int_dump(struct sk_buff *skb, struct meta_value *v, int tlv) { if (v->len == sizeof(unsigned long)) - RTA_PUT(skb, tlv, sizeof(unsigned long), &v->val); + NLA_PUT(skb, tlv, sizeof(unsigned long), &v->val); else if (v->len == sizeof(u32)) { u32 d = v->val; - RTA_PUT(skb, tlv, sizeof(d), &d); + NLA_PUT(skb, tlv, sizeof(d), &d); } return 0; -rtattr_failure: +nla_put_failure: return -1; } @@ -641,7 +641,7 @@ struct meta_type_ops { void (*destroy)(struct meta_value *); int (*compare)(struct meta_obj *, struct meta_obj *); - int (*change)(struct meta_value *, struct rtattr *); + int (*change)(struct meta_value *, struct nlattr *); void (*apply_extras)(struct meta_value *, struct meta_obj *); int (*dump)(struct sk_buff *, struct meta_value *, int); }; @@ -729,13 +729,13 @@ static inline void meta_delete(struct meta_match *meta) kfree(meta); } -static inline int meta_change_data(struct meta_value *dst, struct rtattr *rta) +static inline int meta_change_data(struct meta_value *dst, struct nlattr *nla) { - if (rta) { - if (RTA_PAYLOAD(rta) == 0) + if (nla) { + if (nla_len(nla) == 0) return -EINVAL; - return meta_type_ops(dst)->change(dst, rta); + return meta_type_ops(dst)->change(dst, nla); } return 0; @@ -750,17 +750,17 @@ static int em_meta_change(struct tcf_proto *tp, void *data, int len, struct tcf_ematch *m) { int err = -EINVAL; - struct rtattr *tb[TCA_EM_META_MAX]; + struct nlattr *tb[TCA_EM_META_MAX + 1]; struct tcf_meta_hdr *hdr; struct meta_match *meta = NULL; - if (rtattr_parse(tb, TCA_EM_META_MAX, data, len) < 0) + if (nla_parse(tb, TCA_EM_META_MAX, data, len, NULL) < 0) goto errout; - if (tb[TCA_EM_META_HDR-1] == NULL || - RTA_PAYLOAD(tb[TCA_EM_META_HDR-1]) < sizeof(*hdr)) + if (tb[TCA_EM_META_HDR] == NULL || + nla_len(tb[TCA_EM_META_HDR]) < sizeof(*hdr)) goto errout; - hdr = RTA_DATA(tb[TCA_EM_META_HDR-1]); + hdr = nla_data(tb[TCA_EM_META_HDR]); if (TCF_META_TYPE(hdr->left.kind) != TCF_META_TYPE(hdr->right.kind) || TCF_META_TYPE(hdr->left.kind) > TCF_META_TYPE_MAX || @@ -781,8 +781,8 @@ static int em_meta_change(struct tcf_proto *tp, void *data, int len, goto errout; } - if (meta_change_data(&meta->lvalue, tb[TCA_EM_META_LVALUE-1]) < 0 || - meta_change_data(&meta->rvalue, tb[TCA_EM_META_RVALUE-1]) < 0) + if (meta_change_data(&meta->lvalue, tb[TCA_EM_META_LVALUE]) < 0 || + meta_change_data(&meta->rvalue, tb[TCA_EM_META_RVALUE]) < 0) goto errout; m->datalen = sizeof(*meta); @@ -811,16 +811,16 @@ static int em_meta_dump(struct sk_buff *skb, struct tcf_ematch *em) memcpy(&hdr.left, &meta->lvalue.hdr, sizeof(hdr.left)); memcpy(&hdr.right, &meta->rvalue.hdr, sizeof(hdr.right)); - RTA_PUT(skb, TCA_EM_META_HDR, sizeof(hdr), &hdr); + NLA_PUT(skb, TCA_EM_META_HDR, sizeof(hdr), &hdr); ops = meta_type_ops(&meta->lvalue); if (ops->dump(skb, &meta->lvalue, TCA_EM_META_LVALUE) < 0 || ops->dump(skb, &meta->rvalue, TCA_EM_META_RVALUE) < 0) - goto rtattr_failure; + goto nla_put_failure; return 0; -rtattr_failure: +nla_put_failure: return -1; } diff --git a/net/sched/em_text.c b/net/sched/em_text.c index d5cd86efb7d..853c5ead87f 100644 --- a/net/sched/em_text.c +++ b/net/sched/em_text.c @@ -118,11 +118,14 @@ static int em_text_dump(struct sk_buff *skb, struct tcf_ematch *m) conf.pattern_len = textsearch_get_pattern_len(tm->config); conf.pad = 0; - RTA_PUT_NOHDR(skb, sizeof(conf), &conf); - RTA_APPEND(skb, conf.pattern_len, textsearch_get_pattern(tm->config)); + if (nla_put_nohdr(skb, sizeof(conf), &conf) < 0) + goto nla_put_failure; + if (nla_append(skb, conf.pattern_len, + textsearch_get_pattern(tm->config)) < 0) + goto nla_put_failure; return 0; -rtattr_failure: +nla_put_failure: return -1; } diff --git a/net/sched/ematch.c b/net/sched/ematch.c index 27941cfc0ab..72d9b273524 100644 --- a/net/sched/ematch.c +++ b/net/sched/ematch.c @@ -183,11 +183,11 @@ static inline struct tcf_ematch * tcf_em_get_match(struct tcf_ematch_tree *tree, static int tcf_em_validate(struct tcf_proto *tp, struct tcf_ematch_tree_hdr *tree_hdr, - struct tcf_ematch *em, struct rtattr *rta, int idx) + struct tcf_ematch *em, struct nlattr *nla, int idx) { int err = -EINVAL; - struct tcf_ematch_hdr *em_hdr = RTA_DATA(rta); - int data_len = RTA_PAYLOAD(rta) - sizeof(*em_hdr); + struct tcf_ematch_hdr *em_hdr = nla_data(nla); + int data_len = nla_len(nla) - sizeof(*em_hdr); void *data = (void *) em_hdr + sizeof(*em_hdr); if (!TCF_EM_REL_VALID(em_hdr->flags)) @@ -286,11 +286,11 @@ errout: * tcf_em_tree_validate - validate ematch config TLV and build ematch tree * * @tp: classifier kind handle - * @rta: ematch tree configuration TLV + * @nla: ematch tree configuration TLV * @tree: destination ematch tree variable to store the resulting * ematch tree. * - * This function validates the given configuration TLV @rta and builds an + * This function validates the given configuration TLV @nla and builds an * ematch tree in @tree. The resulting tree must later be copied into * the private classifier data using tcf_em_tree_change(). You MUST NOT * provide the ematch tree variable of the private classifier data directly, @@ -298,45 +298,45 @@ errout: * * Returns a negative error code if the configuration TLV contains errors. */ -int tcf_em_tree_validate(struct tcf_proto *tp, struct rtattr *rta, +int tcf_em_tree_validate(struct tcf_proto *tp, struct nlattr *nla, struct tcf_ematch_tree *tree) { int idx, list_len, matches_len, err = -EINVAL; - struct rtattr *tb[TCA_EMATCH_TREE_MAX]; - struct rtattr *rt_match, *rt_hdr, *rt_list; + struct nlattr *tb[TCA_EMATCH_TREE_MAX + 1]; + struct nlattr *rt_match, *rt_hdr, *rt_list; struct tcf_ematch_tree_hdr *tree_hdr; struct tcf_ematch *em; - if (!rta) { + if (!nla) { memset(tree, 0, sizeof(*tree)); return 0; } - if (rtattr_parse_nested(tb, TCA_EMATCH_TREE_MAX, rta) < 0) + if (nla_parse_nested(tb, TCA_EMATCH_TREE_MAX, nla, NULL) < 0) goto errout; - rt_hdr = tb[TCA_EMATCH_TREE_HDR-1]; - rt_list = tb[TCA_EMATCH_TREE_LIST-1]; + rt_hdr = tb[TCA_EMATCH_TREE_HDR]; + rt_list = tb[TCA_EMATCH_TREE_LIST]; if (rt_hdr == NULL || rt_list == NULL) goto errout; - if (RTA_PAYLOAD(rt_hdr) < sizeof(*tree_hdr) || - RTA_PAYLOAD(rt_list) < sizeof(*rt_match)) + if (nla_len(rt_hdr) < sizeof(*tree_hdr) || + nla_len(rt_list) < sizeof(*rt_match)) goto errout; - tree_hdr = RTA_DATA(rt_hdr); + tree_hdr = nla_data(rt_hdr); memcpy(&tree->hdr, tree_hdr, sizeof(*tree_hdr)); - rt_match = RTA_DATA(rt_list); - list_len = RTA_PAYLOAD(rt_list); + rt_match = nla_data(rt_list); + list_len = nla_len(rt_list); matches_len = tree_hdr->nmatches * sizeof(*em); tree->matches = kzalloc(matches_len, GFP_KERNEL); if (tree->matches == NULL) goto errout; - /* We do not use rtattr_parse_nested here because the maximum + /* We do not use nla_parse_nested here because the maximum * number of attributes is unknown. This saves us the allocation * for a tb buffer which would serve no purpose at all. * @@ -344,16 +344,16 @@ int tcf_em_tree_validate(struct tcf_proto *tp, struct rtattr *rta, * provided, their type must be incremental from 1 to n. Even * if it does not serve any real purpose, a failure of sticking * to this policy will result in parsing failure. */ - for (idx = 0; RTA_OK(rt_match, list_len); idx++) { + for (idx = 0; nla_ok(rt_match, list_len); idx++) { err = -EINVAL; - if (rt_match->rta_type != (idx + 1)) + if (rt_match->nla_type != (idx + 1)) goto errout_abort; if (idx >= tree_hdr->nmatches) goto errout_abort; - if (RTA_PAYLOAD(rt_match) < sizeof(struct tcf_ematch_hdr)) + if (nla_len(rt_match) < sizeof(struct tcf_ematch_hdr)) goto errout_abort; em = tcf_em_get_match(tree, idx); @@ -362,7 +362,7 @@ int tcf_em_tree_validate(struct tcf_proto *tp, struct rtattr *rta, if (err < 0) goto errout_abort; - rt_match = RTA_NEXT(rt_match, list_len); + rt_match = nla_next(rt_match, &list_len); } /* Check if the number of matches provided by userspace actually @@ -434,18 +434,18 @@ int tcf_em_tree_dump(struct sk_buff *skb, struct tcf_ematch_tree *tree, int tlv) { int i; u8 *tail; - struct rtattr *top_start = (struct rtattr *)skb_tail_pointer(skb); - struct rtattr *list_start; + struct nlattr *top_start = (struct nlattr *)skb_tail_pointer(skb); + struct nlattr *list_start; - RTA_PUT(skb, tlv, 0, NULL); - RTA_PUT(skb, TCA_EMATCH_TREE_HDR, sizeof(tree->hdr), &tree->hdr); + NLA_PUT(skb, tlv, 0, NULL); + NLA_PUT(skb, TCA_EMATCH_TREE_HDR, sizeof(tree->hdr), &tree->hdr); - list_start = (struct rtattr *)skb_tail_pointer(skb); - RTA_PUT(skb, TCA_EMATCH_TREE_LIST, 0, NULL); + list_start = (struct nlattr *)skb_tail_pointer(skb); + NLA_PUT(skb, TCA_EMATCH_TREE_LIST, 0, NULL); tail = skb_tail_pointer(skb); for (i = 0; i < tree->hdr.nmatches; i++) { - struct rtattr *match_start = (struct rtattr *)tail; + struct nlattr *match_start = (struct nlattr *)tail; struct tcf_ematch *em = tcf_em_get_match(tree, i); struct tcf_ematch_hdr em_hdr = { .kind = em->ops ? em->ops->kind : TCF_EM_CONTAINER, @@ -453,27 +453,27 @@ int tcf_em_tree_dump(struct sk_buff *skb, struct tcf_ematch_tree *tree, int tlv) .flags = em->flags }; - RTA_PUT(skb, i+1, sizeof(em_hdr), &em_hdr); + NLA_PUT(skb, i+1, sizeof(em_hdr), &em_hdr); if (em->ops && em->ops->dump) { if (em->ops->dump(skb, em) < 0) - goto rtattr_failure; + goto nla_put_failure; } else if (tcf_em_is_container(em) || tcf_em_is_simple(em)) { u32 u = em->data; - RTA_PUT_NOHDR(skb, sizeof(u), &u); + nla_put_nohdr(skb, sizeof(u), &u); } else if (em->datalen > 0) - RTA_PUT_NOHDR(skb, em->datalen, (void *) em->data); + nla_put_nohdr(skb, em->datalen, (void *) em->data); tail = skb_tail_pointer(skb); - match_start->rta_len = tail - (u8 *)match_start; + match_start->nla_len = tail - (u8 *)match_start; } - list_start->rta_len = tail - (u8 *)list_start; - top_start->rta_len = tail - (u8 *)top_start; + list_start->nla_len = tail - (u8 *)list_start; + top_start->nla_len = tail - (u8 *)top_start; return 0; -rtattr_failure: +nla_put_failure: return -1; } EXPORT_SYMBOL(tcf_em_tree_dump); -- cgit v1.2.3-70-g09d2 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 ++++++++++++++++++----------- net/sched/act_gact.c | 7 ++++++- net/sched/act_ipt.c | 6 +++++- net/sched/act_mirred.c | 8 ++++++-- net/sched/act_nat.c | 8 ++++++-- net/sched/act_pedit.c | 8 ++++++-- net/sched/act_police.c | 6 +++++- net/sched/act_simple.c | 8 ++++++-- net/sched/cls_basic.c | 7 ++++--- net/sched/cls_fw.c | 5 +++-- net/sched/cls_route.c | 5 +++-- net/sched/cls_rsvp.h | 5 +++-- net/sched/cls_tcindex.c | 6 ++++-- net/sched/cls_u32.c | 5 +++-- net/sched/em_meta.c | 6 ++++-- net/sched/ematch.c | 6 ++++-- net/sched/sch_atm.c | 6 +++++- net/sched/sch_cbq.c | 14 +++++++++++--- net/sched/sch_dsmark.c | 14 ++++++++++++-- net/sched/sch_gred.c | 16 +++++++++++++--- net/sched/sch_hfsc.c | 7 ++++++- net/sched/sch_htb.c | 23 +++++++++++++++++++---- net/sched/sch_prio.c | 9 ++++++--- net/sched/sch_red.c | 7 ++++++- net/sched/sch_tbf.c | 10 +++++++--- 25 files changed, 171 insertions(+), 60 deletions(-) (limited to 'net/sched/cls_basic.c') diff --git a/net/sched/act_api.c b/net/sched/act_api.c index ea80f82dbb6..87818d7fb62 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) diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index 5402cf885f9..df214d47fc9 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c @@ -61,10 +61,15 @@ static int tcf_gact_init(struct nlattr *nla, struct nlattr *est, struct tcf_gact *gact; struct tcf_common *pc; int ret = 0; + int err; - if (nla == NULL || nla_parse_nested(tb, TCA_GACT_MAX, nla, NULL) < 0) + if (nla == NULL) return -EINVAL; + err = nla_parse_nested(tb, TCA_GACT_MAX, nla, NULL); + if (err < 0) + return err; + if (tb[TCA_GACT_PARMS] == NULL || nla_len(tb[TCA_GACT_PARMS]) < sizeof(*parm)) return -EINVAL; diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index fee5282637c..12693347d56 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c @@ -104,9 +104,13 @@ static int tcf_ipt_init(struct nlattr *nla, struct nlattr *est, u32 hook = 0; u32 index = 0; - if (nla == NULL || nla_parse_nested(tb, TCA_IPT_MAX, nla, NULL) < 0) + if (nla == NULL) return -EINVAL; + err = nla_parse_nested(tb, TCA_IPT_MAX, nla, NULL); + if (err < 0) + return err; + if (tb[TCA_IPT_HOOK] == NULL || nla_len(tb[TCA_IPT_HOOK]) < sizeof(u32)) return -EINVAL; diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index db943a8c738..6cb5e30dcf8 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -62,12 +62,16 @@ static int tcf_mirred_init(struct nlattr *nla, struct nlattr *est, struct tcf_mirred *m; struct tcf_common *pc; struct net_device *dev = NULL; - int ret = 0; + int ret = 0, err; int ok_push = 0; - if (nla == NULL || nla_parse_nested(tb, TCA_MIRRED_MAX, nla, NULL) < 0) + if (nla == NULL) return -EINVAL; + err = nla_parse_nested(tb, TCA_MIRRED_MAX, nla, NULL); + if (err < 0) + return err; + if (tb[TCA_MIRRED_PARMS] == NULL || nla_len(tb[TCA_MIRRED_PARMS]) < sizeof(*parm)) return -EINVAL; diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c index be007bb31b5..5a512d4dc37 100644 --- a/net/sched/act_nat.c +++ b/net/sched/act_nat.c @@ -45,13 +45,17 @@ static int tcf_nat_init(struct nlattr *nla, struct nlattr *est, { struct nlattr *tb[TCA_NAT_MAX + 1]; struct tc_nat *parm; - int ret = 0; + int ret = 0, err; struct tcf_nat *p; struct tcf_common *pc; - if (nla == NULL || nla_parse_nested(tb, TCA_NAT_MAX, nla, NULL) < 0) + if (nla == NULL) return -EINVAL; + err = nla_parse_nested(tb, TCA_NAT_MAX, nla, NULL); + if (err < 0) + return err; + if (tb[TCA_NAT_PARMS] == NULL || nla_len(tb[TCA_NAT_PARMS]) < sizeof(*parm)) return -EINVAL; diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 88d8a15a192..1b9ca45a78e 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c @@ -38,15 +38,19 @@ static int tcf_pedit_init(struct nlattr *nla, struct nlattr *est, { struct nlattr *tb[TCA_PEDIT_MAX + 1]; struct tc_pedit *parm; - int ret = 0; + int ret = 0, err; struct tcf_pedit *p; struct tcf_common *pc; struct tc_pedit_key *keys = NULL; int ksize; - if (nla == NULL || nla_parse_nested(tb, TCA_PEDIT_MAX, nla, NULL) < 0) + if (nla == NULL) return -EINVAL; + err = nla_parse_nested(tb, TCA_PEDIT_MAX, nla, NULL); + if (err < 0) + return err; + if (tb[TCA_PEDIT_PARMS] == NULL || nla_len(tb[TCA_PEDIT_PARMS]) < sizeof(*parm)) return -EINVAL; diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 3af5759aac2..c0fce9b9841 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -129,9 +129,13 @@ static int tcf_act_police_locate(struct nlattr *nla, struct nlattr *est, struct qdisc_rate_table *R_tab = NULL, *P_tab = NULL; int size; - if (nla == NULL || nla_parse_nested(tb, TCA_POLICE_MAX, nla, NULL) < 0) + if (nla == NULL) return -EINVAL; + err = nla_parse_nested(tb, TCA_POLICE_MAX, nla, NULL); + if (err < 0) + return err; + if (tb[TCA_POLICE_TBF] == NULL) return -EINVAL; size = nla_len(tb[TCA_POLICE_TBF]); diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c index d3226e24070..cedaadf18eb 100644 --- a/net/sched/act_simple.c +++ b/net/sched/act_simple.c @@ -93,11 +93,15 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est, struct tcf_common *pc; void *defdata; u32 datalen = 0; - int ret = 0; + int ret = 0, err; - if (nla == NULL || nla_parse_nested(tb, TCA_DEF_MAX, nla, NULL) < 0) + if (nla == NULL) return -EINVAL; + err = nla_parse_nested(tb, TCA_DEF_MAX, nla, NULL); + if (err < 0) + return err; + if (tb[TCA_DEF_PARMS] == NULL || nla_len(tb[TCA_DEF_PARMS]) < sizeof(*parm)) return -EINVAL; diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index 3953da33956..524b7885dc3 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c @@ -166,7 +166,7 @@ errout: static int basic_change(struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, unsigned long *arg) { - int err = -EINVAL; + int err; struct basic_head *head = (struct basic_head *) tp->root; struct nlattr *tb[TCA_BASIC_MAX + 1]; struct basic_filter *f = (struct basic_filter *) *arg; @@ -174,8 +174,9 @@ static int basic_change(struct tcf_proto *tp, unsigned long base, u32 handle, if (tca[TCA_OPTIONS] == NULL) return -EINVAL; - if (nla_parse_nested(tb, TCA_BASIC_MAX, tca[TCA_OPTIONS], NULL) < 0) - return -EINVAL; + err = nla_parse_nested(tb, TCA_BASIC_MAX, tca[TCA_OPTIONS], NULL); + if (err < 0) + return err; if (f != NULL) { if (handle && f->handle != handle) diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index db6e90a3784..a1a9f4d26b8 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c @@ -246,8 +246,9 @@ static int fw_change(struct tcf_proto *tp, unsigned long base, if (!opt) return handle ? -EINVAL : 0; - if (nla_parse_nested(tb, TCA_FW_MAX, opt, NULL) < 0) - return -EINVAL; + err = nla_parse_nested(tb, TCA_FW_MAX, opt, NULL); + if (err < 0) + return err; if (f != NULL) { if (f->id != handle && handle) diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c index b1aae84cbad..3aa8109aa3c 100644 --- a/net/sched/cls_route.c +++ b/net/sched/cls_route.c @@ -440,8 +440,9 @@ static int route4_change(struct tcf_proto *tp, unsigned long base, if (opt == NULL) return handle ? -EINVAL : 0; - if (nla_parse_nested(tb, TCA_ROUTE4_MAX, opt, NULL) < 0) - return -EINVAL; + err = nla_parse_nested(tb, TCA_ROUTE4_MAX, opt, NULL); + if (err < 0) + return err; if ((f = (struct route4_filter*)*arg) != NULL) { if (f->handle != handle && handle) diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index 2364c79d083..5747408a7d4 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h @@ -416,8 +416,9 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base, if (opt == NULL) return handle ? -EINVAL : 0; - if (nla_parse_nested(tb, TCA_RSVP_MAX, opt, NULL) < 0) - return -EINVAL; + err = nla_parse_nested(tb, TCA_RSVP_MAX, opt, NULL); + if (err < 0) + return err; err = tcf_exts_validate(tp, tb, tca[TCA_RATE-1], &e, &rsvp_ext_map); if (err < 0) diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index ed8023944fe..6b84d276e5a 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c @@ -350,6 +350,7 @@ tcindex_change(struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr *tb[TCA_TCINDEX_MAX + 1]; struct tcindex_data *p = PRIV(tp); struct tcindex_filter_result *r = (struct tcindex_filter_result *) *arg; + int err; pr_debug("tcindex_change(tp %p,handle 0x%08x,tca %p,arg %p),opt %p," "p %p,r %p,*arg 0x%lx\n", @@ -358,8 +359,9 @@ tcindex_change(struct tcf_proto *tp, unsigned long base, u32 handle, if (!opt) return 0; - if (nla_parse_nested(tb, TCA_TCINDEX_MAX, opt, NULL) < 0) - return -EINVAL; + err = nla_parse_nested(tb, TCA_TCINDEX_MAX, opt, NULL); + if (err < 0) + return err; return tcindex_set_parms(tp, base, handle, p, r, tb, tca[TCA_RATE]); } diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index aaf5049f951..3228cc4ae08 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -531,8 +531,9 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, if (opt == NULL) return handle ? -EINVAL : 0; - if (nla_parse_nested(tb, TCA_U32_MAX, opt, NULL) < 0) - return -EINVAL; + err = nla_parse_nested(tb, TCA_U32_MAX, opt, NULL); + if (err < 0) + return err; if ((n = (struct tc_u_knode*)*arg) != NULL) { if (TC_U32_KEY(n->handle) == 0) diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index 92b6863e928..dd5723670d3 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -749,14 +749,16 @@ static inline int meta_is_supported(struct meta_value *val) static int em_meta_change(struct tcf_proto *tp, void *data, int len, struct tcf_ematch *m) { - int err = -EINVAL; + int err; struct nlattr *tb[TCA_EM_META_MAX + 1]; struct tcf_meta_hdr *hdr; struct meta_match *meta = NULL; - if (nla_parse(tb, TCA_EM_META_MAX, data, len, NULL) < 0) + err = nla_parse(tb, TCA_EM_META_MAX, data, len, NULL); + if (err < 0) goto errout; + err = -EINVAL; if (tb[TCA_EM_META_HDR] == NULL || nla_len(tb[TCA_EM_META_HDR]) < sizeof(*hdr)) goto errout; diff --git a/net/sched/ematch.c b/net/sched/ematch.c index 72d9b273524..d2b480f01a4 100644 --- a/net/sched/ematch.c +++ b/net/sched/ematch.c @@ -301,7 +301,7 @@ errout: int tcf_em_tree_validate(struct tcf_proto *tp, struct nlattr *nla, struct tcf_ematch_tree *tree) { - int idx, list_len, matches_len, err = -EINVAL; + int idx, list_len, matches_len, err; struct nlattr *tb[TCA_EMATCH_TREE_MAX + 1]; struct nlattr *rt_match, *rt_hdr, *rt_list; struct tcf_ematch_tree_hdr *tree_hdr; @@ -312,9 +312,11 @@ int tcf_em_tree_validate(struct tcf_proto *tp, struct nlattr *nla, return 0; } - if (nla_parse_nested(tb, TCA_EMATCH_TREE_MAX, nla, NULL) < 0) + err = nla_parse_nested(tb, TCA_EMATCH_TREE_MAX, nla, NULL); + if (err < 0) goto errout; + err = -EINVAL; rt_hdr = tb[TCA_EMATCH_TREE_HDR]; rt_list = tb[TCA_EMATCH_TREE_LIST]; diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index e5873915378..aaa32a22726 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c @@ -223,8 +223,12 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, */ if (flow) return -EBUSY; - if (opt == NULL || nla_parse_nested(tb, TCA_ATM_MAX, opt, NULL)) + if (opt == NULL) return -EINVAL; + error = nla_parse_nested(tb, TCA_ATM_MAX, opt, NULL); + if (error < 0) + return error; + if (!tb[TCA_ATM_FD] || nla_len(tb[TCA_ATM_FD]) < sizeof(fd)) return -EINVAL; fd = *(int *)nla_data(tb[TCA_ATM_FD]); diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index 5c8667ef4ba..585f8a6ec7e 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c @@ -1382,9 +1382,13 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt) struct cbq_sched_data *q = qdisc_priv(sch); struct nlattr *tb[TCA_CBQ_MAX + 1]; struct tc_ratespec *r; + int err; + + err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, NULL); + if (err < 0) + return err; - if (nla_parse_nested(tb, TCA_CBQ_MAX, opt, NULL) < 0 || - tb[TCA_CBQ_RTAB] == NULL || tb[TCA_CBQ_RATE] == NULL || + if (tb[TCA_CBQ_RTAB] == NULL || tb[TCA_CBQ_RATE] == NULL || nla_len(tb[TCA_CBQ_RATE]) < sizeof(struct tc_ratespec)) return -EINVAL; @@ -1764,9 +1768,13 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t struct cbq_class *parent; struct qdisc_rate_table *rtab = NULL; - if (opt==NULL || nla_parse_nested(tb, TCA_CBQ_MAX, opt, NULL)) + if (opt == NULL) return -EINVAL; + err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, NULL); + if (err < 0) + return err; + if (tb[TCA_CBQ_OVL_STRATEGY] && nla_len(tb[TCA_CBQ_OVL_STRATEGY]) < sizeof(struct tc_cbq_ovl)) return -EINVAL; diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c index f183ab76887..f1d0a08aca7 100644 --- a/net/sched/sch_dsmark.c +++ b/net/sched/sch_dsmark.c @@ -116,9 +116,14 @@ static int dsmark_change(struct Qdisc *sch, u32 classid, u32 parent, goto errout; } - if (!opt || nla_parse_nested(tb, TCA_DSMARK_MAX, opt, NULL)) + if (!opt) goto errout; + err = nla_parse_nested(tb, TCA_DSMARK_MAX, opt, NULL); + if (err < 0) + return err; + + err = -EINVAL; if (tb[TCA_DSMARK_MASK]) { if (nla_len(tb[TCA_DSMARK_MASK]) < sizeof(u8)) goto errout; @@ -351,9 +356,14 @@ static int dsmark_init(struct Qdisc *sch, struct nlattr *opt) pr_debug("dsmark_init(sch %p,[qdisc %p],opt %p)\n", sch, p, opt); - if (!opt || nla_parse_nested(tb, TCA_DSMARK_MAX, opt, NULL) < 0) + if (!opt) + goto errout; + + err = nla_parse_nested(tb, TCA_DSMARK_MAX, opt, NULL); + if (err < 0) goto errout; + err = -EINVAL; if (nla_len(tb[TCA_DSMARK_INDICES]) < sizeof(u16)) goto errout; indices = nla_get_u16(tb[TCA_DSMARK_INDICES]); diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index 6b784838a53..365c7d8b17a 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c @@ -430,12 +430,16 @@ static int gred_change(struct Qdisc *sch, struct nlattr *opt) struct gred_sched *table = qdisc_priv(sch); struct tc_gred_qopt *ctl; struct nlattr *tb[TCA_GRED_MAX + 1]; - int err = -EINVAL, prio = GRED_DEF_PRIO; + int err, prio = GRED_DEF_PRIO; u8 *stab; - if (opt == NULL || nla_parse_nested(tb, TCA_GRED_MAX, opt, NULL)) + if (opt == NULL) return -EINVAL; + err = nla_parse_nested(tb, TCA_GRED_MAX, opt, NULL); + if (err < 0) + return err; + if (tb[TCA_GRED_PARMS] == NULL && tb[TCA_GRED_STAB] == NULL) return gred_change_table_def(sch, opt); @@ -445,6 +449,7 @@ static int gred_change(struct Qdisc *sch, struct nlattr *opt) nla_len(tb[TCA_GRED_STAB]) < 256) return -EINVAL; + err = -EINVAL; ctl = nla_data(tb[TCA_GRED_PARMS]); stab = nla_data(tb[TCA_GRED_STAB]); @@ -489,10 +494,15 @@ errout: static int gred_init(struct Qdisc *sch, struct nlattr *opt) { struct nlattr *tb[TCA_GRED_MAX + 1]; + int err; - if (opt == NULL || nla_parse_nested(tb, TCA_GRED_MAX, opt, NULL)) + if (opt == NULL) return -EINVAL; + err = nla_parse_nested(tb, TCA_GRED_MAX, opt, NULL); + if (err < 0) + return err; + if (tb[TCA_GRED_PARMS] || tb[TCA_GRED_STAB]) return -EINVAL; diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index 4e6a164d305..fcb4826158d 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c @@ -997,10 +997,15 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr *tb[TCA_HFSC_MAX + 1]; struct tc_service_curve *rsc = NULL, *fsc = NULL, *usc = NULL; u64 cur_time; + int err; - if (opt == NULL || nla_parse_nested(tb, TCA_HFSC_MAX, opt, NULL)) + if (opt == NULL) return -EINVAL; + err = nla_parse_nested(tb, TCA_HFSC_MAX, opt, NULL); + if (err < 0) + return err; + if (tb[TCA_HFSC_RSC]) { if (nla_len(tb[TCA_HFSC_RSC]) < sizeof(*rsc)) return -EINVAL; diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 3b3ff641b6d..512df9a0a24 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -997,9 +997,17 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt) struct htb_sched *q = qdisc_priv(sch); struct nlattr *tb[TCA_HTB_INIT + 1]; struct tc_htb_glob *gopt; + int err; int i; - if (!opt || nla_parse_nested(tb, TCA_HTB_INIT, opt, NULL) || - tb[TCA_HTB_INIT] == NULL || + + if (!opt) + return -EINVAL; + + err = nla_parse_nested(tb, TCA_HTB_INIT, opt, NULL); + if (err < 0) + return err; + + if (tb[TCA_HTB_INIT] == NULL || nla_len(tb[TCA_HTB_INIT]) < sizeof(*gopt)) { printk(KERN_ERR "HTB: hey probably you have bad tc tool ?\n"); return -EINVAL; @@ -1302,8 +1310,15 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, struct tc_htb_opt *hopt; /* extract all subattrs from opt attr */ - if (!opt || nla_parse_nested(tb, TCA_HTB_RTAB, opt, NULL) || - tb[TCA_HTB_PARMS] == NULL || + if (!opt) + goto failure; + + err = nla_parse_nested(tb, TCA_HTB_RTAB, opt, NULL); + if (err < 0) + goto failure; + + err = -EINVAL; + if (tb[TCA_HTB_PARMS] == NULL || nla_len(tb[TCA_HTB_PARMS]) < sizeof(*hopt)) goto failure; diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index a4f932df86e..4aa2b45dad0 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c @@ -229,11 +229,14 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt) struct prio_sched_data *q = qdisc_priv(sch); struct tc_prio_qopt *qopt; struct nlattr *tb[TCA_PRIO_MAX + 1]; + int err; int i; - if (nla_parse_nested_compat(tb, TCA_PRIO_MAX, opt, NULL, qopt, - sizeof(*qopt))) - return -EINVAL; + err = nla_parse_nested_compat(tb, TCA_PRIO_MAX, opt, NULL, qopt, + sizeof(*qopt)); + if (err < 0) + return err; + q->bands = qopt->bands; /* If we're multiqueue, make sure the number of incoming bands * matches the number of queues on the device we're associating with. diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c index 6ce8da5aca0..dcf6afc196f 100644 --- a/net/sched/sch_red.c +++ b/net/sched/sch_red.c @@ -207,10 +207,15 @@ static int red_change(struct Qdisc *sch, struct nlattr *opt) struct nlattr *tb[TCA_RED_MAX + 1]; struct tc_red_qopt *ctl; struct Qdisc *child = NULL; + int err; - if (opt == NULL || nla_parse_nested(tb, TCA_RED_MAX, opt, NULL)) + if (opt == NULL) return -EINVAL; + err = nla_parse_nested(tb, TCA_RED_MAX, opt, NULL); + if (err < 0) + return err; + if (tb[TCA_RED_PARMS] == NULL || nla_len(tb[TCA_RED_PARMS]) < sizeof(*ctl) || tb[TCA_RED_STAB] == NULL || diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index 6c4ad7e677b..f9b1543e3d7 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c @@ -272,7 +272,7 @@ static struct Qdisc *tbf_create_dflt_qdisc(struct Qdisc *sch, u32 limit) static int tbf_change(struct Qdisc* sch, struct nlattr *opt) { - int err = -EINVAL; + int err; struct tbf_sched_data *q = qdisc_priv(sch); struct nlattr *tb[TCA_TBF_PTAB + 1]; struct tc_tbf_qopt *qopt; @@ -281,8 +281,12 @@ static int tbf_change(struct Qdisc* sch, struct nlattr *opt) struct Qdisc *child = NULL; int max_size,n; - if (nla_parse_nested(tb, TCA_TBF_PTAB, opt, NULL) || - tb[TCA_TBF_PARMS] == NULL || + err = nla_parse_nested(tb, TCA_TBF_PTAB, opt, NULL); + if (err < 0) + return err; + + err = -EINVAL; + if (tb[TCA_TBF_PARMS] == NULL || nla_len(tb[TCA_TBF_PARMS]) < sizeof(*qopt)) goto done; -- cgit v1.2.3-70-g09d2 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 +++++++++++++++++++++++++++---------------------- net/sched/act_police.c | 13 ++++---- net/sched/cls_api.c | 14 ++++++--- net/sched/cls_basic.c | 12 +++---- net/sched/cls_fw.c | 9 +++--- net/sched/cls_route.c | 9 +++--- net/sched/cls_rsvp.h | 10 +++--- net/sched/cls_tcindex.c | 13 +++++--- net/sched/cls_u32.c | 13 ++++---- net/sched/ematch.c | 16 ++++++---- net/sched/sch_atm.c | 15 +++++---- net/sched/sch_cbq.c | 24 +++++++------- net/sched/sch_hfsc.c | 11 ++++--- net/sched/sch_htb.c | 32 +++++++++++-------- net/sched/sch_ingress.c | 12 +++---- net/sched/sch_tbf.c | 12 +++---- 16 files changed, 166 insertions(+), 133 deletions(-) (limited to 'net/sched/cls_basic.c') diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 87818d7fb62..36022605fc1 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) diff --git a/net/sched/act_police.c b/net/sched/act_police.c index c0fce9b9841..ee2f1b64dd7 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -54,7 +54,7 @@ static int tcf_act_police_walker(struct sk_buff *skb, struct netlink_callback *c { 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(&police_lock); @@ -69,18 +69,19 @@ static int tcf_act_police_walker(struct sk_buff *skb, struct netlink_callback *c continue; a->priv = p; a->order = index; - 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; if (type == RTM_DELACTION) err = tcf_action_dump_1(skb, a, 0, 1); else err = tcf_action_dump_1(skb, a, 0, 0); if (err < 0) { index--; - nlmsg_trim(skb, r); + nla_nest_cancel(skb, nest); goto done; } - r->nla_len = skb_tail_pointer(skb) - (u8 *)r; + nla_nest_end(skb, nest); n_i++; } } @@ -91,7 +92,7 @@ done: return n_i; nla_put_failure: - nlmsg_trim(skb, r); + nla_nest_cancel(skb, nest); goto done; } diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 92fa1559c21..5584e7cd4b9 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -544,18 +544,22 @@ 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 nlattr *p_rta = (struct nlattr *)skb_tail_pointer(skb); + struct nlattr *nest; if (exts->action->type != TCA_OLD_COMPAT) { - NLA_PUT(skb, map->action, 0, NULL); + nest = nla_nest_start(skb, map->action); + if (nest == NULL) + goto nla_put_failure; if (tcf_action_dump(skb, exts->action, 0, 0) < 0) goto nla_put_failure; - p_rta->nla_len = skb_tail_pointer(skb) - (u8 *)p_rta; + nla_nest_end(skb, nest); } else if (map->police) { - NLA_PUT(skb, map->police, 0, NULL); + nest = nla_nest_start(skb, map->police); + if (nest == NULL) + goto nla_put_failure; if (tcf_action_dump_old(skb, exts->action, 0, 0) < 0) goto nla_put_failure; - p_rta->nla_len = skb_tail_pointer(skb) - (u8 *)p_rta; + nla_nest_end(skb, nest); } } #endif diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index 524b7885dc3..6d08b429635 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c @@ -246,16 +246,16 @@ static int basic_dump(struct tcf_proto *tp, unsigned long fh, struct sk_buff *skb, struct tcmsg *t) { struct basic_filter *f = (struct basic_filter *) fh; - unsigned char *b = skb_tail_pointer(skb); - struct nlattr *nla; + struct nlattr *nest; if (f == NULL) return skb->len; t->tcm_handle = f->handle; - nla = (struct nlattr *) b; - NLA_PUT(skb, TCA_OPTIONS, 0, NULL); + nest = nla_nest_start(skb, TCA_OPTIONS); + if (nest == NULL) + goto nla_put_failure; if (f->res.classid) NLA_PUT(skb, TCA_BASIC_CLASSID, sizeof(u32), &f->res.classid); @@ -264,11 +264,11 @@ static int basic_dump(struct tcf_proto *tp, unsigned long fh, tcf_em_tree_dump(skb, &f->ematches, TCA_BASIC_EMATCHES) < 0) goto nla_put_failure; - nla->nla_len = skb_tail_pointer(skb) - b; + nla_nest_end(skb, nest); return skb->len; nla_put_failure: - nlmsg_trim(skb, b); + nla_nest_cancel(skb, nest); return -1; } diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index a1a9f4d26b8..e3dfbb3046c 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c @@ -334,7 +334,7 @@ static int fw_dump(struct tcf_proto *tp, unsigned long fh, struct fw_head *head = (struct fw_head *)tp->root; struct fw_filter *f = (struct fw_filter*)fh; unsigned char *b = skb_tail_pointer(skb); - struct nlattr *nla; + struct nlattr *nest; if (f == NULL) return skb->len; @@ -344,8 +344,9 @@ static int fw_dump(struct tcf_proto *tp, unsigned long fh, if (!f->res.classid && !tcf_exts_is_available(&f->exts)) return skb->len; - nla = (struct nlattr*)b; - NLA_PUT(skb, TCA_OPTIONS, 0, NULL); + nest = nla_nest_start(skb, TCA_OPTIONS); + if (nest == NULL) + goto nla_put_failure; if (f->res.classid) NLA_PUT(skb, TCA_FW_CLASSID, 4, &f->res.classid); @@ -359,7 +360,7 @@ static int fw_dump(struct tcf_proto *tp, unsigned long fh, if (tcf_exts_dump(skb, &f->exts, &fw_ext_map) < 0) goto nla_put_failure; - nla->nla_len = skb_tail_pointer(skb) - b; + nla_nest_end(skb, nest); if (tcf_exts_dump_stats(skb, &f->exts, &fw_ext_map) < 0) goto nla_put_failure; diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c index 3aa8109aa3c..1ce1f3623d6 100644 --- a/net/sched/cls_route.c +++ b/net/sched/cls_route.c @@ -551,7 +551,7 @@ static int route4_dump(struct tcf_proto *tp, unsigned long fh, { struct route4_filter *f = (struct route4_filter*)fh; unsigned char *b = skb_tail_pointer(skb); - struct nlattr *nla; + struct nlattr *nest; u32 id; if (f == NULL) @@ -559,8 +559,9 @@ static int route4_dump(struct tcf_proto *tp, unsigned long fh, t->tcm_handle = f->handle; - nla = (struct nlattr*)b; - NLA_PUT(skb, TCA_OPTIONS, 0, NULL); + nest = nla_nest_start(skb, TCA_OPTIONS); + if (nest == NULL) + goto nla_put_failure; if (!(f->handle&0x8000)) { id = f->id&0xFF; @@ -579,7 +580,7 @@ static int route4_dump(struct tcf_proto *tp, unsigned long fh, if (tcf_exts_dump(skb, &f->exts, &route_ext_map) < 0) goto nla_put_failure; - nla->nla_len = skb_tail_pointer(skb) - b; + nla_nest_end(skb, nest); if (tcf_exts_dump_stats(skb, &f->exts, &route_ext_map) < 0) goto nla_put_failure; diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index 5747408a7d4..77097e023f7 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h @@ -595,7 +595,7 @@ static int rsvp_dump(struct tcf_proto *tp, unsigned long fh, struct rsvp_filter *f = (struct rsvp_filter*)fh; struct rsvp_session *s; unsigned char *b = skb_tail_pointer(skb); - struct nlattr *nla; + struct nlattr *nest; struct tc_rsvp_pinfo pinfo; if (f == NULL) @@ -604,9 +604,9 @@ static int rsvp_dump(struct tcf_proto *tp, unsigned long fh, t->tcm_handle = f->handle; - - nla = (struct nlattr*)b; - NLA_PUT(skb, TCA_OPTIONS, 0, NULL); + nest = nla_nest_start(skb, TCA_OPTIONS); + if (nest == NULL) + goto nla_put_failure; NLA_PUT(skb, TCA_RSVP_DST, sizeof(s->dst), &s->dst); pinfo.dpi = s->dpi; @@ -624,7 +624,7 @@ static int rsvp_dump(struct tcf_proto *tp, unsigned long fh, if (tcf_exts_dump(skb, &f->exts, &rsvp_ext_map) < 0) goto nla_put_failure; - nla->nla_len = skb_tail_pointer(skb) - b; + nla_nest_end(skb, nest); if (tcf_exts_dump_stats(skb, &f->exts, &rsvp_ext_map) < 0) goto nla_put_failure; diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index 6b84d276e5a..cd350d38bda 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c @@ -437,13 +437,16 @@ static int tcindex_dump(struct tcf_proto *tp, unsigned long fh, struct tcindex_data *p = PRIV(tp); struct tcindex_filter_result *r = (struct tcindex_filter_result *) fh; unsigned char *b = skb_tail_pointer(skb); - struct nlattr *nla; + struct nlattr *nest; pr_debug("tcindex_dump(tp %p,fh 0x%lx,skb %p,t %p),p %p,r %p,b %p\n", tp, fh, skb, t, p, r, b); pr_debug("p->perfect %p p->h %p\n", p->perfect, p->h); - nla = (struct nlattr *) b; - NLA_PUT(skb, TCA_OPTIONS, 0, NULL); + + nest = nla_nest_start(skb, TCA_OPTIONS); + if (nest == NULL) + goto nla_put_failure; + if (!fh) { t->tcm_handle = ~0; /* whatever ... */ NLA_PUT(skb, TCA_TCINDEX_HASH, sizeof(p->hash), &p->hash); @@ -451,7 +454,7 @@ static int tcindex_dump(struct tcf_proto *tp, unsigned long fh, NLA_PUT(skb, TCA_TCINDEX_SHIFT, sizeof(p->shift), &p->shift); NLA_PUT(skb, TCA_TCINDEX_FALL_THROUGH, sizeof(p->fall_through), &p->fall_through); - nla->nla_len = skb_tail_pointer(skb) - b; + nla_nest_end(skb, nest); } else { if (p->perfect) { t->tcm_handle = r-p->perfect; @@ -474,7 +477,7 @@ static int tcindex_dump(struct tcf_proto *tp, unsigned long fh, if (tcf_exts_dump(skb, &r->exts, &tcindex_ext_map) < 0) goto nla_put_failure; - nla->nla_len = skb_tail_pointer(skb) - b; + nla_nest_end(skb, nest); if (tcf_exts_dump_stats(skb, &r->exts, &tcindex_ext_map) < 0) goto nla_put_failure; diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 3228cc4ae08..b51c2c324ab 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -694,16 +694,16 @@ static int u32_dump(struct tcf_proto *tp, unsigned long fh, struct sk_buff *skb, struct tcmsg *t) { struct tc_u_knode *n = (struct tc_u_knode*)fh; - unsigned char *b = skb_tail_pointer(skb); - struct nlattr *nla; + struct nlattr *nest; if (n == NULL) return skb->len; t->tcm_handle = n->handle; - nla = (struct nlattr*)b; - NLA_PUT(skb, TCA_OPTIONS, 0, NULL); + nest = nla_nest_start(skb, TCA_OPTIONS); + if (nest == NULL) + goto nla_put_failure; if (TC_U32_KEY(n->handle) == 0) { struct tc_u_hnode *ht = (struct tc_u_hnode*)fh; @@ -741,14 +741,15 @@ static int u32_dump(struct tcf_proto *tp, unsigned long fh, #endif } - nla->nla_len = skb_tail_pointer(skb) - b; + nla_nest_end(skb, nest); + if (TC_U32_KEY(n->handle)) if (tcf_exts_dump_stats(skb, &n->exts, &u32_ext_map) < 0) goto nla_put_failure; return skb->len; nla_put_failure: - nlmsg_trim(skb, b); + nla_nest_cancel(skb, nest); return -1; } diff --git a/net/sched/ematch.c b/net/sched/ematch.c index d2b480f01a4..daa9c4e7e81 100644 --- a/net/sched/ematch.c +++ b/net/sched/ematch.c @@ -436,14 +436,18 @@ int tcf_em_tree_dump(struct sk_buff *skb, struct tcf_ematch_tree *tree, int tlv) { int i; u8 *tail; - struct nlattr *top_start = (struct nlattr *)skb_tail_pointer(skb); + struct nlattr *top_start; struct nlattr *list_start; - NLA_PUT(skb, tlv, 0, NULL); + top_start = nla_nest_start(skb, tlv); + if (top_start == NULL) + goto nla_put_failure; + NLA_PUT(skb, TCA_EMATCH_TREE_HDR, sizeof(tree->hdr), &tree->hdr); - list_start = (struct nlattr *)skb_tail_pointer(skb); - NLA_PUT(skb, TCA_EMATCH_TREE_LIST, 0, NULL); + list_start = nla_nest_start(skb, TCA_EMATCH_TREE_LIST); + if (list_start == NULL) + goto nla_put_failure; tail = skb_tail_pointer(skb); for (i = 0; i < tree->hdr.nmatches; i++) { @@ -470,8 +474,8 @@ int tcf_em_tree_dump(struct sk_buff *skb, struct tcf_ematch_tree *tree, int tlv) match_start->nla_len = tail - (u8 *)match_start; } - list_start->nla_len = tail - (u8 *)list_start; - top_start->nla_len = tail - (u8 *)top_start; + nla_nest_end(skb, list_start); + nla_nest_end(skb, top_start); return 0; diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index aaa32a22726..19c00074ba1 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c @@ -605,8 +605,7 @@ static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl, { struct atm_qdisc_data *p = qdisc_priv(sch); struct atm_flow_data *flow = (struct atm_flow_data *)cl; - unsigned char *b = skb_tail_pointer(skb); - struct nlattr *nla; + struct nlattr *nest; pr_debug("atm_tc_dump_class(sch %p,[qdisc %p],flow %p,skb %p,tcm %p)\n", sch, p, flow, skb, tcm); @@ -614,8 +613,11 @@ static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl, return -EINVAL; tcm->tcm_handle = flow->classid; tcm->tcm_info = flow->q->handle; - nla = (struct nlattr *)b; - NLA_PUT(skb, TCA_OPTIONS, 0, NULL); + + nest = nla_nest_start(skb, TCA_OPTIONS); + if (nest == NULL) + goto nla_put_failure; + NLA_PUT(skb, TCA_ATM_HDR, flow->hdr_len, flow->hdr); if (flow->vcc) { struct sockaddr_atmpvc pvc; @@ -636,11 +638,12 @@ static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl, NLA_PUT(skb, TCA_ATM_EXCESS, sizeof(zero), &zero); } - nla->nla_len = skb_tail_pointer(skb) - b; + + nla_nest_end(skb, nest); return skb->len; nla_put_failure: - nlmsg_trim(skb, b); + nla_nest_cancel(skb, nest); return -1; } static int diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index 585f8a6ec7e..da0f6c0152d 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c @@ -1565,18 +1565,18 @@ static int cbq_dump_attr(struct sk_buff *skb, struct cbq_class *cl) static int cbq_dump(struct Qdisc *sch, struct sk_buff *skb) { struct cbq_sched_data *q = qdisc_priv(sch); - unsigned char *b = skb_tail_pointer(skb); - struct nlattr *nla; + struct nlattr *nest; - nla = (struct nlattr*)b; - NLA_PUT(skb, TCA_OPTIONS, 0, NULL); + nest = nla_nest_start(skb, TCA_OPTIONS); + if (nest == NULL) + goto nla_put_failure; if (cbq_dump_attr(skb, &q->link) < 0) goto nla_put_failure; - nla->nla_len = skb_tail_pointer(skb) - b; + nla_nest_end(skb, nest); return skb->len; nla_put_failure: - nlmsg_trim(skb, b); + nla_nest_cancel(skb, nest); return -1; } @@ -1594,8 +1594,7 @@ cbq_dump_class(struct Qdisc *sch, unsigned long arg, struct sk_buff *skb, struct tcmsg *tcm) { struct cbq_class *cl = (struct cbq_class*)arg; - unsigned char *b = skb_tail_pointer(skb); - struct nlattr *nla; + struct nlattr *nest; if (cl->tparent) tcm->tcm_parent = cl->tparent->classid; @@ -1604,15 +1603,16 @@ cbq_dump_class(struct Qdisc *sch, unsigned long arg, tcm->tcm_handle = cl->classid; tcm->tcm_info = cl->q->handle; - nla = (struct nlattr*)b; - NLA_PUT(skb, TCA_OPTIONS, 0, NULL); + nest = nla_nest_start(skb, TCA_OPTIONS); + if (nest == NULL) + goto nla_put_failure; if (cbq_dump_attr(skb, cl) < 0) goto nla_put_failure; - nla->nla_len = skb_tail_pointer(skb) - b; + nla_nest_end(skb, nest); return skb->len; nla_put_failure: - nlmsg_trim(skb, b); + nla_nest_cancel(skb, nest); return -1; } diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index fcb4826158d..10a2f35a27a 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c @@ -1343,22 +1343,23 @@ hfsc_dump_class(struct Qdisc *sch, unsigned long arg, struct sk_buff *skb, struct tcmsg *tcm) { struct hfsc_class *cl = (struct hfsc_class *)arg; - unsigned char *b = skb_tail_pointer(skb); - struct nlattr *nla = (struct nlattr *)b; + struct nlattr *nest; tcm->tcm_parent = cl->cl_parent ? cl->cl_parent->classid : TC_H_ROOT; tcm->tcm_handle = cl->classid; if (cl->level == 0) tcm->tcm_info = cl->qdisc->handle; - NLA_PUT(skb, TCA_OPTIONS, 0, NULL); + nest = nla_nest_start(skb, TCA_OPTIONS); + if (nest == NULL) + goto nla_put_failure; if (hfsc_dump_curves(skb, cl) < 0) goto nla_put_failure; - nla->nla_len = skb_tail_pointer(skb) - b; + nla_nest_end(skb, nest); return skb->len; nla_put_failure: - nlmsg_trim(skb, b); + nla_nest_cancel(skb, nest); return -1; } diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 512df9a0a24..69fac320f8b 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -1043,25 +1043,29 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt) static int htb_dump(struct Qdisc *sch, struct sk_buff *skb) { struct htb_sched *q = qdisc_priv(sch); - unsigned char *b = skb_tail_pointer(skb); - struct nlattr *nla; + struct nlattr *nest; struct tc_htb_glob gopt; + spin_lock_bh(&sch->dev->queue_lock); - gopt.direct_pkts = q->direct_pkts; + gopt.direct_pkts = q->direct_pkts; gopt.version = HTB_VER; gopt.rate2quantum = q->rate2quantum; gopt.defcls = q->defcls; gopt.debug = 0; - nla = (struct nlattr *)b; - NLA_PUT(skb, TCA_OPTIONS, 0, NULL); + + nest = nla_nest_start(skb, TCA_OPTIONS); + if (nest == NULL) + goto nla_put_failure; NLA_PUT(skb, TCA_HTB_INIT, sizeof(gopt), &gopt); - nla->nla_len = skb_tail_pointer(skb) - b; + nla_nest_end(skb, nest); + spin_unlock_bh(&sch->dev->queue_lock); return skb->len; + nla_put_failure: spin_unlock_bh(&sch->dev->queue_lock); - nlmsg_trim(skb, skb_tail_pointer(skb)); + nla_nest_cancel(skb, nest); return -1; } @@ -1069,8 +1073,7 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg, struct sk_buff *skb, struct tcmsg *tcm) { struct htb_class *cl = (struct htb_class *)arg; - unsigned char *b = skb_tail_pointer(skb); - struct nlattr *nla; + struct nlattr *nest; struct tc_htb_opt opt; spin_lock_bh(&sch->dev->queue_lock); @@ -1079,8 +1082,9 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg, if (!cl->level && cl->un.leaf.q) tcm->tcm_info = cl->un.leaf.q->handle; - nla = (struct nlattr *)b; - NLA_PUT(skb, TCA_OPTIONS, 0, NULL); + nest = nla_nest_start(skb, TCA_OPTIONS); + if (nest == NULL) + goto nla_put_failure; memset(&opt, 0, sizeof(opt)); @@ -1092,12 +1096,14 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg, opt.prio = cl->un.leaf.prio; opt.level = cl->level; NLA_PUT(skb, TCA_HTB_PARMS, sizeof(opt), &opt); - nla->nla_len = skb_tail_pointer(skb) - b; + + nla_nest_end(skb, nest); spin_unlock_bh(&sch->dev->queue_lock); return skb->len; + nla_put_failure: spin_unlock_bh(&sch->dev->queue_lock); - nlmsg_trim(skb, b); + nla_nest_cancel(skb, nest); return -1; } diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c index f6decbb5664..3f72d528273 100644 --- a/net/sched/sch_ingress.c +++ b/net/sched/sch_ingress.c @@ -183,16 +183,16 @@ static void ingress_destroy(struct Qdisc *sch) static int ingress_dump(struct Qdisc *sch, struct sk_buff *skb) { - unsigned char *b = skb_tail_pointer(skb); - struct nlattr *nla; + struct nlattr *nest; - nla = (struct nlattr *)b; - NLA_PUT(skb, TCA_OPTIONS, 0, NULL); - nla->nla_len = skb_tail_pointer(skb) - b; + nest = nla_nest_start(skb, TCA_OPTIONS); + if (nest == NULL) + goto nla_put_failure; + nla_nest_end(skb, nest); return skb->len; nla_put_failure: - nlmsg_trim(skb, b); + nla_nest_cancel(skb, nest); return -1; } diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index f9b1543e3d7..b7a185dc3de 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c @@ -375,12 +375,12 @@ static void tbf_destroy(struct Qdisc *sch) static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb) { struct tbf_sched_data *q = qdisc_priv(sch); - unsigned char *b = skb_tail_pointer(skb); - struct nlattr *nla; + struct nlattr *nest; struct tc_tbf_qopt opt; - nla = (struct nlattr*)b; - NLA_PUT(skb, TCA_OPTIONS, 0, NULL); + nest = nla_nest_start(skb, TCA_OPTIONS); + if (nest == NULL) + goto nla_put_failure; opt.limit = q->limit; opt.rate = q->R_tab->rate; @@ -391,12 +391,12 @@ static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb) opt.mtu = q->mtu; opt.buffer = q->buffer; NLA_PUT(skb, TCA_TBF_PARMS, sizeof(opt), &opt); - nla->nla_len = skb_tail_pointer(skb) - b; + nla_nest_end(skb, nest); return skb->len; nla_put_failure: - nlmsg_trim(skb, b); + nla_nest_cancel(skb, nest); return -1; } -- cgit v1.2.3-70-g09d2 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 +- net/sched/act_ipt.c | 4 ++-- net/sched/act_police.c | 5 ++--- net/sched/cls_basic.c | 2 +- net/sched/cls_fw.c | 4 ++-- net/sched/cls_route.c | 8 ++++---- net/sched/cls_rsvp.h | 2 +- net/sched/cls_tcindex.c | 11 +++++------ net/sched/cls_u32.c | 8 ++++---- net/sched/em_meta.c | 3 +-- net/sched/sch_atm.c | 8 +++----- 11 files changed, 26 insertions(+), 31 deletions(-) (limited to 'net/sched/cls_basic.c') diff --git a/net/sched/act_api.c b/net/sched/act_api.c index e33e43abe96..41fbd496aba 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; diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index ecda51da9c1..5dd701a7bc5 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c @@ -254,8 +254,8 @@ static int tcf_ipt_dump(struct sk_buff *skb, struct tc_action *a, int bind, int strcpy(t->u.user.name, ipt->tcfi_t->u.kernel.target->name); NLA_PUT(skb, TCA_IPT_TARG, ipt->tcfi_t->u.user.target_size, t); - NLA_PUT(skb, TCA_IPT_INDEX, 4, &ipt->tcf_index); - NLA_PUT(skb, TCA_IPT_HOOK, 4, &ipt->tcfi_hook); + NLA_PUT_U32(skb, TCA_IPT_INDEX, ipt->tcf_index); + NLA_PUT_U32(skb, TCA_IPT_HOOK, ipt->tcfi_hook); NLA_PUT(skb, TCA_IPT_CNT, sizeof(struct tc_cnt), &c); NLA_PUT_STRING(skb, TCA_IPT_TABLE, ipt->tcfi_tname); tm.install = jiffies_to_clock_t(jiffies - ipt->tcf_tm.install); diff --git a/net/sched/act_police.c b/net/sched/act_police.c index ee2f1b64dd7..79db6bb8a5f 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -339,10 +339,9 @@ tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) memset(&opt.peakrate, 0, sizeof(opt.peakrate)); NLA_PUT(skb, TCA_POLICE_TBF, sizeof(opt), &opt); if (police->tcfp_result) - NLA_PUT(skb, TCA_POLICE_RESULT, sizeof(int), - &police->tcfp_result); + NLA_PUT_U32(skb, TCA_POLICE_RESULT, police->tcfp_result); if (police->tcfp_ewma_rate) - NLA_PUT(skb, TCA_POLICE_AVRATE, 4, &police->tcfp_ewma_rate); + NLA_PUT_U32(skb, TCA_POLICE_AVRATE, police->tcfp_ewma_rate); return skb->len; nla_put_failure: diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index 6d08b429635..58444fedf06 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c @@ -258,7 +258,7 @@ static int basic_dump(struct tcf_proto *tp, unsigned long fh, goto nla_put_failure; if (f->res.classid) - NLA_PUT(skb, TCA_BASIC_CLASSID, sizeof(u32), &f->res.classid); + NLA_PUT_U32(skb, TCA_BASIC_CLASSID, 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) diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index 31074735d1b..61ebe25e5f7 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c @@ -349,13 +349,13 @@ static int fw_dump(struct tcf_proto *tp, unsigned long fh, goto nla_put_failure; if (f->res.classid) - NLA_PUT(skb, TCA_FW_CLASSID, 4, &f->res.classid); + NLA_PUT_U32(skb, TCA_FW_CLASSID, f->res.classid); #ifdef CONFIG_NET_CLS_IND if (strlen(f->indev)) NLA_PUT_STRING(skb, TCA_FW_INDEV, f->indev); #endif /* CONFIG_NET_CLS_IND */ if (head->mask != 0xFFFFFFFF) - NLA_PUT(skb, TCA_FW_MASK, 4, &head->mask); + NLA_PUT_U32(skb, TCA_FW_MASK, head->mask); if (tcf_exts_dump(skb, &f->exts, &fw_ext_map) < 0) goto nla_put_failure; diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c index 1ce1f3623d6..7752586e918 100644 --- a/net/sched/cls_route.c +++ b/net/sched/cls_route.c @@ -565,17 +565,17 @@ static int route4_dump(struct tcf_proto *tp, unsigned long fh, if (!(f->handle&0x8000)) { id = f->id&0xFF; - NLA_PUT(skb, TCA_ROUTE4_TO, sizeof(id), &id); + NLA_PUT_U32(skb, TCA_ROUTE4_TO, id); } if (f->handle&0x80000000) { if ((f->handle>>16) != 0xFFFF) - NLA_PUT(skb, TCA_ROUTE4_IIF, sizeof(f->iif), &f->iif); + NLA_PUT_U32(skb, TCA_ROUTE4_IIF, f->iif); } else { id = f->id>>16; - NLA_PUT(skb, TCA_ROUTE4_FROM, sizeof(id), &id); + NLA_PUT_U32(skb, TCA_ROUTE4_FROM, id); } if (f->res.classid) - NLA_PUT(skb, TCA_ROUTE4_CLASSID, 4, &f->res.classid); + NLA_PUT_U32(skb, TCA_ROUTE4_CLASSID, f->res.classid); if (tcf_exts_dump(skb, &f->exts, &route_ext_map) < 0) goto nla_put_failure; diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index 77097e023f7..838a3ff5a2c 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h @@ -617,7 +617,7 @@ static int rsvp_dump(struct tcf_proto *tp, unsigned long fh, pinfo.pad = 0; NLA_PUT(skb, TCA_RSVP_PINFO, sizeof(pinfo), &pinfo); if (f->res.classid) - NLA_PUT(skb, TCA_RSVP_CLASSID, 4, &f->res.classid); + NLA_PUT_U32(skb, TCA_RSVP_CLASSID, f->res.classid); if (((f->handle>>8)&0xFF) != 16) NLA_PUT(skb, TCA_RSVP_SRC, sizeof(f->src), f->src); diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index cd350d38bda..7d46df7eac0 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c @@ -449,11 +449,10 @@ static int tcindex_dump(struct tcf_proto *tp, unsigned long fh, if (!fh) { t->tcm_handle = ~0; /* whatever ... */ - NLA_PUT(skb, TCA_TCINDEX_HASH, sizeof(p->hash), &p->hash); - NLA_PUT(skb, TCA_TCINDEX_MASK, sizeof(p->mask), &p->mask); - NLA_PUT(skb, TCA_TCINDEX_SHIFT, sizeof(p->shift), &p->shift); - NLA_PUT(skb, TCA_TCINDEX_FALL_THROUGH, sizeof(p->fall_through), - &p->fall_through); + NLA_PUT_U32(skb, TCA_TCINDEX_HASH, p->hash); + NLA_PUT_U16(skb, TCA_TCINDEX_MASK, p->mask); + NLA_PUT_U32(skb, TCA_TCINDEX_SHIFT, p->shift); + NLA_PUT_U32(skb, TCA_TCINDEX_FALL_THROUGH, p->fall_through); nla_nest_end(skb, nest); } else { if (p->perfect) { @@ -473,7 +472,7 @@ static int tcindex_dump(struct tcf_proto *tp, unsigned long fh, } pr_debug("handle = %d\n", t->tcm_handle); if (r->res.class) - NLA_PUT(skb, TCA_TCINDEX_CLASSID, 4, &r->res.classid); + NLA_PUT_U32(skb, TCA_TCINDEX_CLASSID, r->res.classid); if (tcf_exts_dump(skb, &r->exts, &tcindex_ext_map) < 0) goto nla_put_failure; diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 7a1502553b3..326711eb593 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -708,19 +708,19 @@ static int u32_dump(struct tcf_proto *tp, unsigned long fh, if (TC_U32_KEY(n->handle) == 0) { struct tc_u_hnode *ht = (struct tc_u_hnode*)fh; u32 divisor = ht->divisor+1; - NLA_PUT(skb, TCA_U32_DIVISOR, 4, &divisor); + NLA_PUT_U32(skb, TCA_U32_DIVISOR, divisor); } else { NLA_PUT(skb, TCA_U32_SEL, sizeof(n->sel) + n->sel.nkeys*sizeof(struct tc_u32_key), &n->sel); if (n->ht_up) { u32 htid = n->handle & 0xFFFFF000; - NLA_PUT(skb, TCA_U32_HASH, 4, &htid); + NLA_PUT_U32(skb, TCA_U32_HASH, htid); } if (n->res.classid) - NLA_PUT(skb, TCA_U32_CLASSID, 4, &n->res.classid); + NLA_PUT_U32(skb, TCA_U32_CLASSID, n->res.classid); if (n->ht_down) - NLA_PUT(skb, TCA_U32_LINK, 4, &n->ht_down->handle); + NLA_PUT_U32(skb, TCA_U32_LINK, n->ht_down->handle); #ifdef CONFIG_CLS_U32_MARK if (n->mark.val || n->mark.mask) diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index dd5723670d3..63ae6a230c4 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -623,8 +623,7 @@ static int meta_int_dump(struct sk_buff *skb, struct meta_value *v, int tlv) if (v->len == sizeof(unsigned long)) NLA_PUT(skb, tlv, sizeof(unsigned long), &v->val); else if (v->len == sizeof(u32)) { - u32 d = v->val; - NLA_PUT(skb, tlv, sizeof(d), &d); + NLA_PUT_U32(skb, tlv, v->val); } return 0; diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index 19c00074ba1..4d876598d7d 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c @@ -629,14 +629,12 @@ static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl, pvc.sap_addr.vci = flow->vcc->vci; NLA_PUT(skb, TCA_ATM_ADDR, sizeof(pvc), &pvc); state = ATM_VF2VS(flow->vcc->flags); - NLA_PUT(skb, TCA_ATM_STATE, sizeof(state), &state); + NLA_PUT_U32(skb, TCA_ATM_STATE, state); } if (flow->excess) - NLA_PUT(skb, TCA_ATM_EXCESS, sizeof(u32), &flow->classid); + NLA_PUT_U32(skb, TCA_ATM_EXCESS, flow->classid); else { - static u32 zero; - - NLA_PUT(skb, TCA_ATM_EXCESS, sizeof(zero), &zero); + NLA_PUT_U32(skb, TCA_ATM_EXCESS, 0); } nla_nest_end(skb, nest); -- cgit v1.2.3-70-g09d2 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 +- net/sched/act_ipt.c | 4 ++-- net/sched/act_police.c | 5 ++--- net/sched/cls_basic.c | 2 +- net/sched/cls_fw.c | 6 +++--- net/sched/cls_route.c | 8 ++++---- net/sched/cls_rsvp.h | 4 ++-- net/sched/cls_tcindex.c | 11 +++++------ net/sched/cls_u32.c | 8 ++++---- net/sched/em_meta.c | 2 +- net/sched/sch_atm.c | 4 ++-- 11 files changed, 27 insertions(+), 29 deletions(-) (limited to 'net/sched/cls_basic.c') diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 41fbd496aba..0b8eb235bc1 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); diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index 5dd701a7bc5..7ab2419b44e 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c @@ -123,7 +123,7 @@ static int tcf_ipt_init(struct nlattr *nla, struct nlattr *est, if (tb[TCA_IPT_INDEX] != NULL && nla_len(tb[TCA_IPT_INDEX]) >= sizeof(u32)) - index = *(u32 *)nla_data(tb[TCA_IPT_INDEX]); + index = nla_get_u32(tb[TCA_IPT_INDEX]); pc = tcf_hash_check(index, a, bind, &ipt_hash_info); if (!pc) { @@ -140,7 +140,7 @@ static int tcf_ipt_init(struct nlattr *nla, struct nlattr *est, } ipt = to_ipt(pc); - hook = *(u32 *)nla_data(tb[TCA_IPT_HOOK]); + hook = nla_get_u32(tb[TCA_IPT_HOOK]); err = -ENOMEM; tname = kmalloc(IFNAMSIZ, GFP_KERNEL); diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 79db6bb8a5f..62de806af3a 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -203,7 +203,7 @@ override: } if (tb[TCA_POLICE_RESULT]) - police->tcfp_result = *(u32*)nla_data(tb[TCA_POLICE_RESULT]); + police->tcfp_result = nla_get_u32(tb[TCA_POLICE_RESULT]); police->tcfp_toks = police->tcfp_burst = parm->burst; police->tcfp_mtu = parm->mtu; if (police->tcfp_mtu == 0) { @@ -216,8 +216,7 @@ override: police->tcf_action = parm->action; if (tb[TCA_POLICE_AVRATE]) - police->tcfp_ewma_rate = - *(u32*)nla_data(tb[TCA_POLICE_AVRATE]); + police->tcfp_ewma_rate = nla_get_u32(tb[TCA_POLICE_AVRATE]); if (est) gen_replace_estimator(&police->tcf_bstats, &police->tcf_rate_est, diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index 58444fedf06..0c872a76c4b 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c @@ -150,7 +150,7 @@ static inline int basic_set_parms(struct tcf_proto *tp, struct basic_filter *f, goto errout; if (tb[TCA_BASIC_CLASSID]) { - f->res.classid = *(u32*)nla_data(tb[TCA_BASIC_CLASSID]); + f->res.classid = nla_get_u32(tb[TCA_BASIC_CLASSID]); tcf_bind_filter(tp, &f->res, base); } diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index 61ebe25e5f7..b75696d67ec 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c @@ -203,7 +203,7 @@ fw_change_attrs(struct tcf_proto *tp, struct fw_filter *f, if (tb[TCA_FW_CLASSID]) { if (nla_len(tb[TCA_FW_CLASSID]) != sizeof(u32)) goto errout; - f->res.classid = *(u32*)nla_data(tb[TCA_FW_CLASSID]); + f->res.classid = nla_get_u32(tb[TCA_FW_CLASSID]); tcf_bind_filter(tp, &f->res, base); } @@ -218,7 +218,7 @@ fw_change_attrs(struct tcf_proto *tp, struct fw_filter *f, if (tb[TCA_FW_MASK]) { if (nla_len(tb[TCA_FW_MASK]) != sizeof(u32)) goto errout; - mask = *(u32*)nla_data(tb[TCA_FW_MASK]); + mask = nla_get_u32(tb[TCA_FW_MASK]); if (mask != head->mask) goto errout; } else if (head->mask != 0xFFFFFFFF) @@ -264,7 +264,7 @@ static int fw_change(struct tcf_proto *tp, unsigned long base, if (tb[TCA_FW_MASK]) { if (nla_len(tb[TCA_FW_MASK]) != sizeof(u32)) return -EINVAL; - mask = *(u32*)nla_data(tb[TCA_FW_MASK]); + mask = nla_get_u32(tb[TCA_FW_MASK]); } head = kzalloc(sizeof(struct fw_head), GFP_KERNEL); diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c index 7752586e918..ae97238c57a 100644 --- a/net/sched/cls_route.c +++ b/net/sched/cls_route.c @@ -348,7 +348,7 @@ static int route4_set_parms(struct tcf_proto *tp, unsigned long base, goto errout; if (nla_len(tb[TCA_ROUTE4_TO]) < sizeof(u32)) goto errout; - to = *(u32*)nla_data(tb[TCA_ROUTE4_TO]); + to = nla_get_u32(tb[TCA_ROUTE4_TO]); if (to > 0xFF) goto errout; nhandle = to; @@ -359,14 +359,14 @@ static int route4_set_parms(struct tcf_proto *tp, unsigned long base, goto errout; if (nla_len(tb[TCA_ROUTE4_FROM]) < sizeof(u32)) goto errout; - id = *(u32*)nla_data(tb[TCA_ROUTE4_FROM]); + id = nla_get_u32(tb[TCA_ROUTE4_FROM]); if (id > 0xFF) goto errout; nhandle |= id << 16; } else if (tb[TCA_ROUTE4_IIF]) { if (nla_len(tb[TCA_ROUTE4_IIF]) < sizeof(u32)) goto errout; - id = *(u32*)nla_data(tb[TCA_ROUTE4_IIF]); + id = nla_get_u32(tb[TCA_ROUTE4_IIF]); if (id > 0x7FFF) goto errout; nhandle |= (id | 0x8000) << 16; @@ -411,7 +411,7 @@ static int route4_set_parms(struct tcf_proto *tp, unsigned long base, tcf_tree_unlock(tp); if (tb[TCA_ROUTE4_CLASSID]) { - f->res.classid = *(u32*)nla_data(tb[TCA_ROUTE4_CLASSID]); + f->res.classid = nla_get_u32(tb[TCA_ROUTE4_CLASSID]); tcf_bind_filter(tp, &f->res, base); } diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index 838a3ff5a2c..61286a0f7a3 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h @@ -430,7 +430,7 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base, if (f->handle != handle && handle) goto errout2; if (tb[TCA_RSVP_CLASSID-1]) { - f->res.classid = *(u32*)nla_data(tb[TCA_RSVP_CLASSID-1]); + f->res.classid = nla_get_u32(tb[TCA_RSVP_CLASSID-1]); tcf_bind_filter(tp, &f->res, base); } @@ -470,7 +470,7 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base, err = -EINVAL; if (nla_len(tb[TCA_RSVP_CLASSID-1]) != 4) goto errout; - f->res.classid = *(u32*)nla_data(tb[TCA_RSVP_CLASSID-1]); + f->res.classid = nla_get_u32(tb[TCA_RSVP_CLASSID-1]); } err = -EINVAL; diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index 7d46df7eac0..28098564b4d 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c @@ -221,19 +221,19 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle, if (tb[TCA_TCINDEX_HASH]) { if (nla_len(tb[TCA_TCINDEX_HASH]) < sizeof(u32)) goto errout; - cp.hash = *(u32 *) nla_data(tb[TCA_TCINDEX_HASH]); + cp.hash = nla_get_u32(tb[TCA_TCINDEX_HASH]); } if (tb[TCA_TCINDEX_MASK]) { if (nla_len(tb[TCA_TCINDEX_MASK]) < sizeof(u16)) goto errout; - cp.mask = *(u16 *) nla_data(tb[TCA_TCINDEX_MASK]); + cp.mask = nla_get_u16(tb[TCA_TCINDEX_MASK]); } if (tb[TCA_TCINDEX_SHIFT]) { if (nla_len(tb[TCA_TCINDEX_SHIFT]) < sizeof(int)) goto errout; - cp.shift = *(int *) nla_data(tb[TCA_TCINDEX_SHIFT]); + cp.shift = nla_get_u32(tb[TCA_TCINDEX_SHIFT]); } err = -EBUSY; @@ -251,8 +251,7 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle, if (tb[TCA_TCINDEX_FALL_THROUGH]) { if (nla_len(tb[TCA_TCINDEX_FALL_THROUGH]) < sizeof(u32)) goto errout; - cp.fall_through = - *(u32 *) nla_data(tb[TCA_TCINDEX_FALL_THROUGH]); + cp.fall_through = nla_get_u32(tb[TCA_TCINDEX_FALL_THROUGH]); } if (!cp.hash) { @@ -305,7 +304,7 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle, } if (tb[TCA_TCINDEX_CLASSID]) { - cr.res.classid = *(u32 *) nla_data(tb[TCA_TCINDEX_CLASSID]); + cr.res.classid = nla_get_u32(tb[TCA_TCINDEX_CLASSID]); tcf_bind_filter(tp, &cr.res, base); } diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 326711eb593..a4e72e8a882 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -474,7 +474,7 @@ static int u32_set_parms(struct tcf_proto *tp, unsigned long base, err = -EINVAL; if (tb[TCA_U32_LINK]) { - u32 handle = *(u32*)nla_data(tb[TCA_U32_LINK]); + u32 handle = nla_get_u32(tb[TCA_U32_LINK]); struct tc_u_hnode *ht_down = NULL; if (TC_U32_KEY(handle)) @@ -496,7 +496,7 @@ static int u32_set_parms(struct tcf_proto *tp, unsigned long base, ht_down->refcnt--; } if (tb[TCA_U32_CLASSID]) { - n->res.classid = *(u32*)nla_data(tb[TCA_U32_CLASSID]); + n->res.classid = nla_get_u32(tb[TCA_U32_CLASSID]); tcf_bind_filter(tp, &n->res, base); } @@ -543,7 +543,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, } if (tb[TCA_U32_DIVISOR]) { - unsigned divisor = *(unsigned*)nla_data(tb[TCA_U32_DIVISOR]); + unsigned divisor = nla_get_u32(tb[TCA_U32_DIVISOR]); if (--divisor > 0x100) return -EINVAL; @@ -569,7 +569,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, } if (tb[TCA_U32_HASH]) { - htid = *(unsigned*)nla_data(tb[TCA_U32_HASH]); + htid = nla_get_u32(tb[TCA_U32_HASH]); if (TC_U32_HTID(htid) == TC_U32_ROOT) { ht = tp->root; htid = ht->handle; diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index 63ae6a230c4..d9f487d813c 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -600,7 +600,7 @@ static int meta_int_change(struct meta_value *dst, struct nlattr *nla) dst->val = *(unsigned long *) nla_data(nla); dst->len = sizeof(unsigned long); } else if (nla_len(nla) == sizeof(u32)) { - dst->val = *(u32 *) nla_data(nla); + dst->val = nla_get_u32(nla); dst->len = sizeof(u32); } else return -EINVAL; diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index 4d876598d7d..0c71f2eb96b 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c @@ -231,7 +231,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, if (!tb[TCA_ATM_FD] || nla_len(tb[TCA_ATM_FD]) < sizeof(fd)) return -EINVAL; - fd = *(int *)nla_data(tb[TCA_ATM_FD]); + fd = nla_get_u32(tb[TCA_ATM_FD]); pr_debug("atm_tc_change: fd %d\n", fd); if (tb[TCA_ATM_HDR]) { hdr_len = nla_len(tb[TCA_ATM_HDR]); @@ -246,7 +246,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, if (nla_len(tb[TCA_ATM_EXCESS]) != sizeof(u32)) return -EINVAL; excess = (struct atm_flow_data *) - atm_tc_get(sch, *(u32 *)nla_data(tb[TCA_ATM_EXCESS])); + atm_tc_get(sch, nla_get_u32(tb[TCA_ATM_EXCESS])); if (!excess) return -ENOENT; } -- cgit v1.2.3-70-g09d2 From 6fa8c0144b770dac941cf2c15053b6e24f046c8a Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 23 Jan 2008 20:36:12 -0800 Subject: [NET_SCHED]: Use nla_policy for attribute validation in classifiers Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/sched/cls_basic.c | 12 +++++++----- net/sched/cls_fw.c | 17 ++++++++--------- net/sched/cls_route.c | 19 ++++++++----------- net/sched/cls_rsvp.h | 26 +++++++++++--------------- net/sched/cls_tcindex.c | 31 +++++++++++++------------------ net/sched/cls_u32.c | 22 ++++++++++++---------- 6 files changed, 59 insertions(+), 68 deletions(-) (limited to 'net/sched/cls_basic.c') diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index 0c872a76c4b..bfb4342ea88 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c @@ -129,6 +129,11 @@ static int basic_delete(struct tcf_proto *tp, unsigned long arg) return -ENOENT; } +static const struct nla_policy basic_policy[TCA_BASIC_MAX + 1] = { + [TCA_BASIC_CLASSID] = { .type = NLA_U32 }, + [TCA_BASIC_EMATCHES] = { .type = NLA_NESTED }, +}; + static inline int basic_set_parms(struct tcf_proto *tp, struct basic_filter *f, unsigned long base, struct nlattr **tb, struct nlattr *est) @@ -137,10 +142,6 @@ static inline int basic_set_parms(struct tcf_proto *tp, struct basic_filter *f, struct tcf_exts e; struct tcf_ematch_tree t; - 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; @@ -174,7 +175,8 @@ static int basic_change(struct tcf_proto *tp, unsigned long base, u32 handle, if (tca[TCA_OPTIONS] == NULL) return -EINVAL; - err = nla_parse_nested(tb, TCA_BASIC_MAX, tca[TCA_OPTIONS], NULL); + err = nla_parse_nested(tb, TCA_BASIC_MAX, tca[TCA_OPTIONS], + basic_policy); if (err < 0) return err; diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index b75696d67ec..436a6e7c438 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c @@ -186,6 +186,12 @@ out: return -EINVAL; } +static const struct nla_policy fw_policy[TCA_FW_MAX + 1] = { + [TCA_FW_CLASSID] = { .type = NLA_U32 }, + [TCA_FW_INDEV] = { .type = NLA_STRING, .len = IFNAMSIZ }, + [TCA_FW_MASK] = { .type = NLA_U32 }, +}; + static int fw_change_attrs(struct tcf_proto *tp, struct fw_filter *f, struct nlattr **tb, struct nlattr **tca, unsigned long base) @@ -201,8 +207,6 @@ fw_change_attrs(struct tcf_proto *tp, struct fw_filter *f, err = -EINVAL; if (tb[TCA_FW_CLASSID]) { - if (nla_len(tb[TCA_FW_CLASSID]) != sizeof(u32)) - goto errout; f->res.classid = nla_get_u32(tb[TCA_FW_CLASSID]); tcf_bind_filter(tp, &f->res, base); } @@ -216,8 +220,6 @@ fw_change_attrs(struct tcf_proto *tp, struct fw_filter *f, #endif /* CONFIG_NET_CLS_IND */ if (tb[TCA_FW_MASK]) { - if (nla_len(tb[TCA_FW_MASK]) != sizeof(u32)) - goto errout; mask = nla_get_u32(tb[TCA_FW_MASK]); if (mask != head->mask) goto errout; @@ -246,7 +248,7 @@ static int fw_change(struct tcf_proto *tp, unsigned long base, if (!opt) return handle ? -EINVAL : 0; - err = nla_parse_nested(tb, TCA_FW_MAX, opt, NULL); + err = nla_parse_nested(tb, TCA_FW_MAX, opt, fw_policy); if (err < 0) return err; @@ -261,11 +263,8 @@ static int fw_change(struct tcf_proto *tp, unsigned long base, if (head == NULL) { u32 mask = 0xFFFFFFFF; - if (tb[TCA_FW_MASK]) { - if (nla_len(tb[TCA_FW_MASK]) != sizeof(u32)) - return -EINVAL; + if (tb[TCA_FW_MASK]) mask = nla_get_u32(tb[TCA_FW_MASK]); - } head = kzalloc(sizeof(struct fw_head), GFP_KERNEL); if (head == NULL) diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c index ae97238c57a..f7e7d3955d2 100644 --- a/net/sched/cls_route.c +++ b/net/sched/cls_route.c @@ -323,6 +323,13 @@ static int route4_delete(struct tcf_proto *tp, unsigned long arg) return 0; } +static const struct nla_policy route4_policy[TCA_ROUTE4_MAX + 1] = { + [TCA_ROUTE4_CLASSID] = { .type = NLA_U32 }, + [TCA_ROUTE4_TO] = { .type = NLA_U32 }, + [TCA_ROUTE4_FROM] = { .type = NLA_U32 }, + [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, struct nlattr **tb, struct nlattr *est, int new) @@ -339,15 +346,9 @@ static int route4_set_parms(struct tcf_proto *tp, unsigned long base, return err; err = -EINVAL; - if (tb[TCA_ROUTE4_CLASSID]) - if (nla_len(tb[TCA_ROUTE4_CLASSID]) < sizeof(u32)) - goto errout; - if (tb[TCA_ROUTE4_TO]) { if (new && handle & 0x8000) goto errout; - if (nla_len(tb[TCA_ROUTE4_TO]) < sizeof(u32)) - goto errout; to = nla_get_u32(tb[TCA_ROUTE4_TO]); if (to > 0xFF) goto errout; @@ -357,15 +358,11 @@ static int route4_set_parms(struct tcf_proto *tp, unsigned long base, if (tb[TCA_ROUTE4_FROM]) { if (tb[TCA_ROUTE4_IIF]) goto errout; - if (nla_len(tb[TCA_ROUTE4_FROM]) < sizeof(u32)) - goto errout; id = nla_get_u32(tb[TCA_ROUTE4_FROM]); if (id > 0xFF) goto errout; nhandle |= id << 16; } else if (tb[TCA_ROUTE4_IIF]) { - if (nla_len(tb[TCA_ROUTE4_IIF]) < sizeof(u32)) - goto errout; id = nla_get_u32(tb[TCA_ROUTE4_IIF]); if (id > 0x7FFF) goto errout; @@ -440,7 +437,7 @@ static int route4_change(struct tcf_proto *tp, unsigned long base, if (opt == NULL) return handle ? -EINVAL : 0; - err = nla_parse_nested(tb, TCA_ROUTE4_MAX, opt, NULL); + err = nla_parse_nested(tb, TCA_ROUTE4_MAX, opt, route4_policy); if (err < 0) return err; diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index 61286a0f7a3..7034ea4530e 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h @@ -397,6 +397,15 @@ static u32 gen_tunnel(struct rsvp_head *data) return 0; } +static const struct nla_policy rsvp_policy[TCA_RSVP_MAX + 1] = { + [TCA_RSVP_CLASSID] = { .type = NLA_U32 }, + [TCA_RSVP_DST] = { .type = NLA_BINARY, + .len = RSVP_DST_LEN * sizeof(u32) }, + [TCA_RSVP_SRC] = { .type = NLA_BINARY, + .len = RSVP_DST_LEN * sizeof(u32) }, + [TCA_RSVP_PINFO] = { .len = sizeof(struct tc_rsvp_pinfo) }, +}; + static int rsvp_change(struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, @@ -416,7 +425,7 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base, if (opt == NULL) return handle ? -EINVAL : 0; - err = nla_parse_nested(tb, TCA_RSVP_MAX, opt, NULL); + err = nla_parse_nested(tb, TCA_RSVP_MAX, opt, rsvp_policy); if (err < 0) return err; @@ -452,30 +461,17 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base, h2 = 16; if (tb[TCA_RSVP_SRC-1]) { - err = -EINVAL; - if (nla_len(tb[TCA_RSVP_SRC-1]) != sizeof(f->src)) - goto errout; memcpy(f->src, nla_data(tb[TCA_RSVP_SRC-1]), sizeof(f->src)); h2 = hash_src(f->src); } if (tb[TCA_RSVP_PINFO-1]) { - err = -EINVAL; - if (nla_len(tb[TCA_RSVP_PINFO-1]) < sizeof(struct tc_rsvp_pinfo)) - goto errout; pinfo = nla_data(tb[TCA_RSVP_PINFO-1]); f->spi = pinfo->spi; f->tunnelhdr = pinfo->tunnelhdr; } - if (tb[TCA_RSVP_CLASSID-1]) { - err = -EINVAL; - if (nla_len(tb[TCA_RSVP_CLASSID-1]) != 4) - goto errout; + if (tb[TCA_RSVP_CLASSID-1]) f->res.classid = nla_get_u32(tb[TCA_RSVP_CLASSID-1]); - } - err = -EINVAL; - if (nla_len(tb[TCA_RSVP_DST-1]) != sizeof(f->src)) - goto errout; dst = nla_data(tb[TCA_RSVP_DST-1]); h1 = hash_dst(dst, pinfo ? pinfo->protocol : 0, pinfo ? pinfo->tunnelid : 0); diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index 28098564b4d..ee60b2d1705 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c @@ -193,6 +193,14 @@ valid_perfect_hash(struct tcindex_data *p) return p->hash > (p->mask >> p->shift); } +static const struct nla_policy tcindex_policy[TCA_TCINDEX_MAX + 1] = { + [TCA_TCINDEX_HASH] = { .type = NLA_U32 }, + [TCA_TCINDEX_MASK] = { .type = NLA_U16 }, + [TCA_TCINDEX_SHIFT] = { .type = NLA_U32 }, + [TCA_TCINDEX_FALL_THROUGH] = { .type = NLA_U32 }, + [TCA_TCINDEX_CLASSID] = { .type = NLA_U32 }, +}; + static int tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle, struct tcindex_data *p, struct tcindex_filter_result *r, @@ -217,24 +225,14 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle, else memset(&cr, 0, sizeof(cr)); - err = -EINVAL; - if (tb[TCA_TCINDEX_HASH]) { - if (nla_len(tb[TCA_TCINDEX_HASH]) < sizeof(u32)) - goto errout; + if (tb[TCA_TCINDEX_HASH]) cp.hash = nla_get_u32(tb[TCA_TCINDEX_HASH]); - } - if (tb[TCA_TCINDEX_MASK]) { - if (nla_len(tb[TCA_TCINDEX_MASK]) < sizeof(u16)) - goto errout; + if (tb[TCA_TCINDEX_MASK]) cp.mask = nla_get_u16(tb[TCA_TCINDEX_MASK]); - } - if (tb[TCA_TCINDEX_SHIFT]) { - if (nla_len(tb[TCA_TCINDEX_SHIFT]) < sizeof(int)) - goto errout; + if (tb[TCA_TCINDEX_SHIFT]) cp.shift = nla_get_u32(tb[TCA_TCINDEX_SHIFT]); - } err = -EBUSY; /* Hash already allocated, make sure that we still meet the @@ -248,11 +246,8 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle, goto errout; err = -EINVAL; - if (tb[TCA_TCINDEX_FALL_THROUGH]) { - if (nla_len(tb[TCA_TCINDEX_FALL_THROUGH]) < sizeof(u32)) - goto errout; + if (tb[TCA_TCINDEX_FALL_THROUGH]) cp.fall_through = nla_get_u32(tb[TCA_TCINDEX_FALL_THROUGH]); - } if (!cp.hash) { /* Hash not specified, use perfect hash if the upper limit @@ -358,7 +353,7 @@ tcindex_change(struct tcf_proto *tp, unsigned long base, u32 handle, if (!opt) return 0; - err = nla_parse_nested(tb, TCA_TCINDEX_MAX, opt, NULL); + err = nla_parse_nested(tb, TCA_TCINDEX_MAX, opt, tcindex_policy); if (err < 0) return err; diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index a4e72e8a882..e8a77568912 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -460,6 +460,16 @@ static u32 gen_new_kid(struct tc_u_hnode *ht, u32 handle) return handle|(i>0xFFF ? 0xFFF : i); } +static const struct nla_policy u32_policy[TCA_U32_MAX + 1] = { + [TCA_U32_CLASSID] = { .type = NLA_U32 }, + [TCA_U32_HASH] = { .type = NLA_U32 }, + [TCA_U32_LINK] = { .type = NLA_U32 }, + [TCA_U32_DIVISOR] = { .type = NLA_U32 }, + [TCA_U32_SEL] = { .len = sizeof(struct tc_u32_sel) }, + [TCA_U32_INDEV] = { .type = NLA_STRING, .len = IFNAMSIZ }, + [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, struct tc_u_knode *n, struct nlattr **tb, @@ -531,7 +541,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, if (opt == NULL) return handle ? -EINVAL : 0; - err = nla_parse_nested(tb, TCA_U32_MAX, opt, NULL); + err = nla_parse_nested(tb, TCA_U32_MAX, opt, u32_policy); if (err < 0) return err; @@ -593,8 +603,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, } else handle = gen_new_kid(ht, htid); - if (tb[TCA_U32_SEL] == NULL || - nla_len(tb[TCA_U32_SEL]) < sizeof(struct tc_u32_sel)) + if (tb[TCA_U32_SEL] == NULL) return -EINVAL; s = nla_data(tb[TCA_U32_SEL]); @@ -620,13 +629,6 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, if (tb[TCA_U32_MARK]) { struct tc_u32_mark *mark; - if (nla_len(tb[TCA_U32_MARK]) < sizeof(struct tc_u32_mark)) { -#ifdef CONFIG_CLS_U32_PERF - kfree(n->pf); -#endif - kfree(n); - return -EINVAL; - } mark = nla_data(tb[TCA_U32_MARK]); memcpy(&n->mark, mark, sizeof(struct tc_u32_mark)); n->mark.success = 0; -- cgit v1.2.3-70-g09d2