diff options
author | Thomas Graf <tgraf@suug.ch> | 2005-01-09 21:31:20 -0800 |
---|---|---|
committer | David S. Miller <davem@nuts.davemloft.net> | 2005-01-09 21:31:20 -0800 |
commit | bd6781a99e25e4d0f701025d47f781e1bec3b84d (patch) | |
tree | c2d172a7630421d7ea350622dcea92cb374dd6db /net | |
parent | cb589a66945276f1c366870ded953f213cdf9a57 (diff) | |
download | history-bd6781a99e25e4d0f701025d47f781e1bec3b84d.tar.gz |
[PKT_SCHED]: rsvp: use tcf_exts API
Transforms tcindex to use tcf_exts API and thus adds support for
actions. Needs more work to allow changing parameters for
existing filters.
Signed-off-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/sched/cls_rsvp.h | 102 |
1 files changed, 49 insertions, 53 deletions
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index 95f691c5c8b5ac..7b74ad5ccd0829 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h @@ -95,9 +95,7 @@ struct rsvp_filter u8 tunnelhdr; struct tcf_result res; -#ifdef CONFIG_NET_CLS_POLICE - struct tcf_police *police; -#endif + struct tcf_exts exts; u32 handle; struct rsvp_session *sess; @@ -120,18 +118,20 @@ static __inline__ unsigned hash_src(u32 *src) return h & 0xF; } -#ifdef CONFIG_NET_CLS_POLICE -#define RSVP_POLICE() \ -if (f->police) { \ - int pol_res = tcf_police(skb, f->police); \ - if (pol_res < 0) continue; \ - if (pol_res) return pol_res; \ -} -#else -#define RSVP_POLICE() -#endif - +static struct tcf_ext_map rsvp_ext_map = { + .police = TCA_RSVP_POLICE, + .action = TCA_RSVP_ACT +}; +#define RSVP_APPLY_RESULT() \ + do { \ + int r = tcf_exts_exec(skb, &f->exts, res); \ + if (r < 0) \ + continue; \ + else if (r > 0) \ + return r; \ + } while(0) + static int rsvp_classify(struct sk_buff *skb, struct tcf_proto *tp, struct tcf_result *res) { @@ -189,8 +189,7 @@ restart: #endif ) { *res = f->res; - - RSVP_POLICE(); + RSVP_APPLY_RESULT(); matched: if (f->tunnelhdr == 0) @@ -205,7 +204,7 @@ matched: /* And wildcard bucket... */ for (f = s->ht[16]; f; f = f->next) { *res = f->res; - RSVP_POLICE(); + RSVP_APPLY_RESULT(); goto matched; } return -1; @@ -251,6 +250,14 @@ static int rsvp_init(struct tcf_proto *tp) return -ENOBUFS; } +static inline void +rsvp_delete_filter(struct tcf_proto *tp, struct rsvp_filter *f) +{ + tcf_unbind_filter(tp, &f->res); + tcf_exts_destroy(tp, &f->exts); + kfree(f); +} + static void rsvp_destroy(struct tcf_proto *tp) { struct rsvp_head *data = xchg(&tp->root, NULL); @@ -273,11 +280,7 @@ static void rsvp_destroy(struct tcf_proto *tp) while ((f = s->ht[h2]) != NULL) { s->ht[h2] = f->next; - tcf_unbind_filter(tp, &f->res); -#ifdef CONFIG_NET_CLS_POLICE - tcf_police_release(f->police,TCA_ACT_UNBIND); -#endif - kfree(f); + rsvp_delete_filter(tp, f); } } kfree(s); @@ -299,12 +302,7 @@ static int rsvp_delete(struct tcf_proto *tp, unsigned long arg) tcf_tree_lock(tp); *fp = f->next; tcf_tree_unlock(tp); - tcf_unbind_filter(tp, &f->res); -#ifdef CONFIG_NET_CLS_POLICE - tcf_police_release(f->police,TCA_ACT_UNBIND); -#endif - - kfree(f); + rsvp_delete_filter(tp, f); /* Strip tree */ @@ -412,6 +410,7 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base, struct tc_rsvp_pinfo *pinfo = NULL; struct rtattr *opt = tca[TCA_OPTIONS-1]; struct rtattr *tb[TCA_RSVP_MAX]; + struct tcf_exts e; unsigned h1, h2; u32 *dst; int err; @@ -419,38 +418,38 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base, if (opt == NULL) return handle ? -EINVAL : 0; - if (rtattr_parse(tb, TCA_RSVP_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)) < 0) + if (rtattr_parse_nested(tb, TCA_RSVP_MAX, opt) < 0) return -EINVAL; + err = tcf_exts_validate(tp, tb, tca[TCA_RATE-1], &e, &rsvp_ext_map); + if (err < 0) + return err; + if ((f = (struct rsvp_filter*)*arg) != NULL) { /* Node exists: adjust only classid */ if (f->handle != handle && handle) - return -EINVAL; + goto errout2; if (tb[TCA_RSVP_CLASSID-1]) { f->res.classid = *(u32*)RTA_DATA(tb[TCA_RSVP_CLASSID-1]); tcf_bind_filter(tp, &f->res, base); } -#ifdef CONFIG_NET_CLS_POLICE - if (tb[TCA_RSVP_POLICE-1]) { - err = tcf_change_police(tp, &f->police, - tb[TCA_RSVP_POLICE-1], tca[TCA_RATE-1]); - if (err < 0) - return err; - } -#endif + + tcf_exts_change(tp, &f->exts, &e); return 0; } /* Now more serious part... */ + err = -EINVAL; if (handle) - return -EINVAL; + goto errout2; if (tb[TCA_RSVP_DST-1] == NULL) - return -EINVAL; + goto errout2; + err = -ENOBUFS; f = kmalloc(sizeof(struct rsvp_filter), GFP_KERNEL); if (f == NULL) - return -ENOBUFS; + goto errout2; memset(f, 0, sizeof(*f)); h2 = 16; @@ -516,10 +515,8 @@ insert: f->sess = s; if (f->tunnelhdr == 0) tcf_bind_filter(tp, &f->res, base); -#ifdef CONFIG_NET_CLS_POLICE - if (tb[TCA_RSVP_POLICE-1]) - tcf_change_police(tp, &f->police, tb[TCA_RSVP_POLICE-1], tca[TCA_RATE-1]); -#endif + + tcf_exts_change(tp, &f->exts, &e); for (fp = &s->ht[h2]; *fp; fp = &(*fp)->next) if (((*fp)->spi.mask&f->spi.mask) != f->spi.mask) @@ -560,6 +557,8 @@ insert: errout: if (f) kfree(f); +errout2: + tcf_exts_destroy(tp, &e); return err; } @@ -624,17 +623,14 @@ static int rsvp_dump(struct tcf_proto *tp, unsigned long fh, RTA_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); -#ifdef CONFIG_NET_CLS_POLICE - if (tcf_dump_police(skb, f->police, TCA_RSVP_POLICE) < 0) + + if (tcf_exts_dump(skb, &f->exts, &rsvp_ext_map) < 0) goto rtattr_failure; -#endif rta->rta_len = skb->tail - b; -#ifdef CONFIG_NET_CLS_POLICE - if (f->police) - if (tcf_police_dump_stats(skb, f->police) < 0) - goto rtattr_failure; -#endif + + if (tcf_exts_dump_stats(skb, &f->exts, &rsvp_ext_map) < 0) + goto rtattr_failure; return skb->len; rtattr_failure: |