X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=net%2Fsched%2Fact_police.c;h=38015b49394755d06cd1cfa56306ea358c968a49;hb=e5a4a72d4f88f4389e9340d383ca67031d1b8536;hp=3af5759aac26a569bd0b6456be083aa4008c6037;hpb=7ba699c604ab811972eee2e041fd6b07659a2e6e;p=linux-2.6 diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 3af5759aac..38015b4939 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; } @@ -115,9 +116,16 @@ static void tcf_police_destroy(struct tcf_police *p) return; } } - BUG_TRAP(0); + WARN_ON(1); } +static const struct nla_policy police_policy[TCA_POLICE_MAX + 1] = { + [TCA_POLICE_RATE] = { .len = TC_RTAB_SIZE }, + [TCA_POLICE_PEAKRATE] = { .len = TC_RTAB_SIZE }, + [TCA_POLICE_AVRATE] = { .type = NLA_U32 }, + [TCA_POLICE_RESULT] = { .type = NLA_U32 }, +}; + static int tcf_act_police_locate(struct nlattr *nla, struct nlattr *est, struct tc_action *a, int ovr, int bind) { @@ -129,9 +137,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, police_policy); + if (err < 0) + return err; + if (tb[TCA_POLICE_TBF] == NULL) return -EINVAL; size = nla_len(tb[TCA_POLICE_TBF]); @@ -139,13 +151,6 @@ static int tcf_act_police_locate(struct nlattr *nla, struct nlattr *est, return -EINVAL; parm = nla_data(tb[TCA_POLICE_TBF]); - if (tb[TCA_POLICE_RESULT] != NULL && - nla_len(tb[TCA_POLICE_RESULT]) != sizeof(u32)) - return -EINVAL; - if (tb[TCA_POLICE_RESULT] != NULL && - nla_len(tb[TCA_POLICE_RESULT]) != sizeof(u32)) - return -EINVAL; - if (parm->index) { struct tcf_common *pc; @@ -198,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) { @@ -211,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, @@ -268,7 +272,7 @@ static int tcf_act_police(struct sk_buff *skb, struct tc_action *a, spin_lock(&police->tcf_lock); - police->tcf_bstats.bytes += skb->len; + police->tcf_bstats.bytes += qdisc_pkt_len(skb); police->tcf_bstats.packets++; if (police->tcfp_ewma_rate && @@ -278,7 +282,7 @@ static int tcf_act_police(struct sk_buff *skb, struct tc_action *a, return police->tcf_action; } - if (skb->len <= police->tcfp_mtu) { + if (qdisc_pkt_len(skb) <= police->tcfp_mtu) { if (police->tcfp_R_tab == NULL) { spin_unlock(&police->tcf_lock); return police->tcfp_result; @@ -291,12 +295,12 @@ static int tcf_act_police(struct sk_buff *skb, struct tc_action *a, ptoks = toks + police->tcfp_ptoks; if (ptoks > (long)L2T_P(police, police->tcfp_mtu)) ptoks = (long)L2T_P(police, police->tcfp_mtu); - ptoks -= L2T_P(police, skb->len); + ptoks -= L2T_P(police, qdisc_pkt_len(skb)); } toks += police->tcfp_toks; if (toks > (long)police->tcfp_burst) toks = police->tcfp_burst; - toks -= L2T(police, skb->len); + toks -= L2T(police, qdisc_pkt_len(skb)); if ((toks|ptoks) >= 0) { police->tcfp_t_c = now; police->tcfp_toks = toks; @@ -334,10 +338,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: