summaryrefslogtreecommitdiffstats
path: root/net/sched/cls_rsvp.h
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-06-13 16:29:25 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-06-13 16:29:25 +0000
commitdb7d4daea91e105e3859cf461d7e53b9b77454b2 (patch)
tree9bb65b95440af09e8aca63abe56970dd3360cc57 /net/sched/cls_rsvp.h
parent9c1c01ead627bdda9211c9abd5b758d6c687d8ac (diff)
Merge with Linux 2.2.8.
Diffstat (limited to 'net/sched/cls_rsvp.h')
-rw-r--r--net/sched/cls_rsvp.h81
1 files changed, 56 insertions, 25 deletions
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
index 4168f541f..48142c6e7 100644
--- a/net/sched/cls_rsvp.h
+++ b/net/sched/cls_rsvp.h
@@ -120,6 +120,18 @@ 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 int rsvp_classify(struct sk_buff *skb, struct tcf_proto *tp,
struct tcf_result *res)
{
@@ -137,7 +149,7 @@ static int rsvp_classify(struct sk_buff *skb, struct tcf_proto *tp,
struct iphdr *nhptr = skb->nh.iph;
#endif
-#ifndef __i386__
+#if !defined( __i386__) && !defined(__mc68000__)
if ((unsigned long)nhptr & 3)
return -1;
#endif
@@ -181,25 +193,26 @@ restart:
&& src[2] == f->src[2]
#endif
) {
+ *res = f->res;
+
+ RSVP_POLICE();
+
matched:
- if (f->tunnelhdr == 0) {
- *res = f->res;
-#ifdef CONFIG_NET_CLS_POLICE
- if (f->police)
- return tcf_police(skb, f->police);
-#endif
+ if (f->tunnelhdr == 0)
return 0;
- } else {
- tunnelid = f->res.classid;
- nhptr = (void*)(xprt + f->tunnelhdr - sizeof(*nhptr));
- goto restart;
- }
+
+ tunnelid = f->res.classid;
+ nhptr = (void*)(xprt + f->tunnelhdr - sizeof(*nhptr));
+ goto restart;
}
}
/* And wildcard bucket... */
- if ((f = s->ht[16]) != NULL)
+ for (f = s->ht[16]; f; f = f->next) {
+ *res = f->res;
+ RSVP_POLICE();
goto matched;
+ }
return -1;
}
}
@@ -260,7 +273,6 @@ static void rsvp_destroy(struct tcf_proto *tp)
struct rsvp_session *s;
while ((s = sht[h1]) != NULL) {
-
sht[h1] = s->next;
for (h2=0; h2<=16; h2++) {
@@ -270,7 +282,7 @@ static void rsvp_destroy(struct tcf_proto *tp)
unsigned long cl;
s->ht[h2] = f->next;
- if ((cl = xchg(&f->res.class, 0)) != 0)
+ if ((cl = cls_set_class(&f->res.class, 0)) != 0)
tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
#ifdef CONFIG_NET_CLS_POLICE
tcf_police_release(f->police);
@@ -297,8 +309,11 @@ static int rsvp_delete(struct tcf_proto *tp, unsigned long arg)
if (*fp == f) {
unsigned long cl;
+
*fp = f->next;
- if ((cl = xchg(&f->res.class, 0)) != 0)
+ synchronize_bh();
+
+ if ((cl = cls_set_class(&f->res.class, 0)) != 0)
tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
#ifdef CONFIG_NET_CLS_POLICE
@@ -318,11 +333,13 @@ static int rsvp_delete(struct tcf_proto *tp, unsigned long arg)
*sp; sp = &(*sp)->next) {
if (*sp == s) {
*sp = s->next;
+ synchronize_bh();
+
kfree(s);
return 0;
}
}
-
+
return 0;
}
}
@@ -399,7 +416,8 @@ static u32 gen_tunnel(struct rsvp_head *data)
return 0;
}
-static int rsvp_change(struct tcf_proto *tp, u32 handle,
+static int rsvp_change(struct tcf_proto *tp, unsigned long base,
+ u32 handle,
struct rtattr **tca,
unsigned long *arg)
{
@@ -425,17 +443,21 @@ static int rsvp_change(struct tcf_proto *tp, u32 handle,
if (f->handle != handle && handle)
return -EINVAL;
if (tb[TCA_RSVP_CLASSID-1]) {
- unsigned long cl = xchg(&f->res.class, 0);
+ unsigned long cl;
+
+ f->res.classid = *(u32*)RTA_DATA(tb[TCA_RSVP_CLASSID-1]);
+ cl = cls_set_class(&f->res.class, tp->q->ops->cl_ops->bind_tcf(tp->q, base, f->res.classid));
if (cl)
tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
- f->res.classid = *(u32*)RTA_DATA(tb[TCA_RSVP_CLASSID-1]);
- f->res.class = tp->q->ops->cl_ops->bind_tcf(tp->q, f->res.classid);
}
#ifdef CONFIG_NET_CLS_POLICE
if (tb[TCA_RSVP_POLICE-1]) {
- struct tcf_police *police = tcf_police_locate(tb[TCA_RSVP_POLICE-1]);
+ struct tcf_police *police = tcf_police_locate(tb[TCA_RSVP_POLICE-1], tca[TCA_RATE-1]);
- tcf_police_release(xchg(&f->police, police));
+ police = xchg(&f->police, police);
+ synchronize_bh();
+
+ tcf_police_release(police);
}
#endif
return 0;
@@ -514,17 +536,19 @@ insert:
f->sess = s;
if (f->tunnelhdr == 0)
- f->res.class = tp->q->ops->cl_ops->bind_tcf(tp->q, f->res.classid);
+ cls_set_class(&f->res.class, tp->q->ops->cl_ops->bind_tcf(tp->q, base, f->res.classid));
#ifdef CONFIG_NET_CLS_POLICE
if (tb[TCA_RSVP_POLICE-1])
- f->police = tcf_police_locate(tb[TCA_RSVP_POLICE-1]);
+ f->police = tcf_police_locate(tb[TCA_RSVP_POLICE-1], tca[TCA_RATE-1]);
#endif
for (fp = &s->ht[h2]; *fp; fp = &(*fp)->next)
if (((*fp)->spi.mask&f->spi.mask) != f->spi.mask)
break;
f->next = *fp;
+ wmb();
*fp = f;
+
*arg = (unsigned long)f;
return 0;
}
@@ -546,7 +570,9 @@ insert:
break;
}
s->next = *sp;
+ wmb();
*sp = s;
+
goto insert;
errout:
@@ -631,6 +657,11 @@ static int rsvp_dump(struct tcf_proto *tp, unsigned long fh,
#endif
rta->rta_len = skb->tail - b;
+#ifdef CONFIG_NET_CLS_POLICE
+ if (f->police) {
+ RTA_PUT(skb, TCA_STATS, sizeof(struct tc_stats), &f->police->stats);
+ }
+#endif
return skb->len;
rtattr_failure: