summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenjiro Cho <kjc@cvs.openbsd.org>2004-04-27 02:56:21 +0000
committerKenjiro Cho <kjc@cvs.openbsd.org>2004-04-27 02:56:21 +0000
commit6cbc4b315919eff5d4f1122a1dc5a306f3094362 (patch)
tree56a9b8a09215e828793a6b5d75357dd1e84a4e81
parentfb770dbcf2089bb051cb5aaf01b6f08969cf3539 (diff)
make separate functions to enable/disable altq, and call them when we
reload rules. this fixes an altq problem that, if you reload pf rules not containing queues while running altq, the interface shaper is not properly removed. make pf_altq_running local to pf_ioctl.c since it is no longer used in altq_subr.c. ok henning@
-rw-r--r--sys/altq/altq_subr.c25
-rw-r--r--sys/altq/altq_var.h4
-rw-r--r--sys/net/pf_ioctl.c105
3 files changed, 74 insertions, 60 deletions
diff --git a/sys/altq/altq_subr.c b/sys/altq/altq_subr.c
index 6599c79b680..88785dca41c 100644
--- a/sys/altq/altq_subr.c
+++ b/sys/altq/altq_subr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: altq_subr.c,v 1.16 2004/01/14 08:42:23 kjc Exp $ */
+/* $OpenBSD: altq_subr.c,v 1.17 2004/04/27 02:56:20 kjc Exp $ */
/* $KAME: altq_subr.c,v 1.11 2002/01/11 08:11:49 kjc Exp $ */
/*
@@ -70,8 +70,6 @@ int (*altq_input)(struct mbuf *, int) = NULL;
static int tbr_timer = 0; /* token bucket regulator timer */
static struct callout tbr_callout = CALLOUT_INITIALIZER;
-int pfaltq_running; /* keep track of running state */
-
/*
* alternate queueing support routines
*/
@@ -380,9 +378,7 @@ tbr_get(ifq, profile)
int
altq_pfattach(struct pf_altq *a)
{
- struct ifnet *ifp;
- struct tb_profile tb;
- int s, error = 0;
+ int error = 0;
switch (a->scheduler) {
case ALTQT_NONE:
@@ -406,23 +402,6 @@ altq_pfattach(struct pf_altq *a)
error = ENXIO;
}
- ifp = ifunit(a->ifname);
-
- /* if the state is running, enable altq */
- if (error == 0 && pfaltq_running &&
- ifp != NULL && ifp->if_snd.altq_type != ALTQT_NONE &&
- !ALTQ_IS_ENABLED(&ifp->if_snd))
- error = altq_enable(&ifp->if_snd);
-
- /* if altq is already enabled, reset set tokenbucket regulator */
- if (error == 0 && ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
- tb.rate = a->ifbandwidth;
- tb.depth = a->tbrsize;
- s = splimp();
- error = tbr_set(&ifp->if_snd, &tb);
- splx(s);
- }
-
return (error);
}
diff --git a/sys/altq/altq_var.h b/sys/altq/altq_var.h
index 20e88412ea8..e71b47f502d 100644
--- a/sys/altq/altq_var.h
+++ b/sys/altq/altq_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: altq_var.h,v 1.13 2004/01/14 08:42:23 kjc Exp $ */
+/* $OpenBSD: altq_var.h,v 1.14 2004/04/27 02:56:20 kjc Exp $ */
/* $KAME: altq_var.h,v 1.8 2001/02/09 09:44:41 kjc Exp $ */
/*
@@ -92,8 +92,6 @@ typedef void (timeout_t)(void *);
#define m_pktlen(m) ((m)->m_pkthdr.len)
-extern int pfaltq_running;
-
struct ifnet; struct mbuf;
struct pf_altq; struct pf_qstats;
diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c
index bc8d3ab4650..dad8d232430 100644
--- a/sys/net/pf_ioctl.c
+++ b/sys/net/pf_ioctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_ioctl.c,v 1.115 2004/04/26 02:01:47 mcbride Exp $ */
+/* $OpenBSD: pf_ioctl.c,v 1.116 2004/04/27 02:56:20 kjc Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -96,6 +96,8 @@ int pfioctl(dev_t, u_long, caddr_t, int, struct proc *);
int pf_begin_altq(u_int32_t *);
int pf_rollback_altq(u_int32_t);
int pf_commit_altq(u_int32_t);
+int pf_enable_altq(struct pf_altq *);
+int pf_disable_altq(struct pf_altq *);
#endif /* ALTQ */
int pf_begin_rules(u_int32_t *, int, char *, char *);
int pf_rollback_rules(u_int32_t, int, char *, char *);
@@ -104,6 +106,9 @@ int pf_commit_rules(u_int32_t, int, char *, char *);
extern struct timeout pf_expire_to;
struct pf_rule pf_default_rule;
+#ifdef ALTQ
+static int pf_altq_running;
+#endif
#define TAGID_MAX 50000
TAILQ_HEAD(pf_tags, pf_tagname) pf_tags = TAILQ_HEAD_INITIALIZER(pf_tags),
@@ -699,7 +704,9 @@ pf_commit_altq(u_int32_t ticket)
if (altq->qname[0] == 0) {
/* attach the discipline */
error = altq_pfattach(altq);
- if (error) {
+ if (error == 0 && pf_altq_running)
+ error = pf_enable_altq(altq);
+ if (error == 0) {
splx(s);
return (error);
}
@@ -711,6 +718,8 @@ pf_commit_altq(u_int32_t ticket)
TAILQ_REMOVE(pf_altqs_inactive, altq, entries);
if (altq->qname[0] == 0) {
/* detach and destroy the discipline */
+ if (pf_altq_running)
+ error = pf_disable_altq(altq);
err = altq_pfdetach(altq);
if (err != 0 && error == 0)
error = err;
@@ -726,6 +735,61 @@ pf_commit_altq(u_int32_t ticket)
altqs_inactive_open = 0;
return (error);
}
+
+int
+pf_enable_altq(struct pf_altq *altq)
+{
+ struct ifnet *ifp;
+ struct tb_profile tb;
+ int s, error = 0;
+
+ if ((ifp = ifunit(altq->ifname)) == NULL)
+ return (EINVAL);
+
+ if (ifp->if_snd.altq_type != ALTQT_NONE)
+ error = altq_enable(&ifp->if_snd);
+
+ /* set tokenbucket regulator */
+ if (error == 0 && ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
+ tb.rate = altq->ifbandwidth;
+ tb.depth = altq->tbrsize;
+ s = splimp();
+ error = tbr_set(&ifp->if_snd, &tb);
+ splx(s);
+ }
+
+ return (error);
+}
+
+int
+pf_disable_altq(struct pf_altq *altq)
+{
+ struct ifnet *ifp;
+ struct tb_profile tb;
+ int s, error;
+
+ if ((ifp = ifunit(altq->ifname)) == NULL)
+ return (EINVAL);
+
+ /*
+ * when the discipline is no longer referenced, it was overridden
+ * by a new one. if so, just return.
+ */
+ if (altq->altq_disc != ifp->if_snd.altq_disc)
+ return (0);
+
+ error = altq_disable(&ifp->if_snd);
+
+ if (error == 0) {
+ /* clear tokenbucket regulator */
+ tb.rate = 0;
+ s = splimp();
+ error = tbr_set(&ifp->if_snd, &tb);
+ splx(s);
+ }
+
+ return (error);
+}
#endif /* ALTQ */
int
@@ -1698,31 +1762,18 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
#ifdef ALTQ
case DIOCSTARTALTQ: {
struct pf_altq *altq;
- struct ifnet *ifp;
- struct tb_profile tb;
/* enable all altq interfaces on active list */
s = splsoftnet();
TAILQ_FOREACH(altq, pf_altqs_active, entries) {
if (altq->qname[0] == 0) {
- if ((ifp = ifunit(altq->ifname)) == NULL) {
- error = EINVAL;
- break;
- }
- if (ifp->if_snd.altq_type != ALTQT_NONE)
- error = altq_enable(&ifp->if_snd);
- if (error != 0)
- break;
- /* set tokenbucket regulator */
- tb.rate = altq->ifbandwidth;
- tb.depth = altq->tbrsize;
- error = tbr_set(&ifp->if_snd, &tb);
+ error = pf_enable_altq(altq);
if (error != 0)
break;
}
}
if (error == 0)
- pfaltq_running = 1;
+ pf_altq_running = 1;
splx(s);
DPFPRINTF(PF_DEBUG_MISC, ("altq: started\n"));
break;
@@ -1730,32 +1781,18 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
case DIOCSTOPALTQ: {
struct pf_altq *altq;
- struct ifnet *ifp;
- struct tb_profile tb;
- int err;
/* disable all altq interfaces on active list */
s = splsoftnet();
TAILQ_FOREACH(altq, pf_altqs_active, entries) {
if (altq->qname[0] == 0) {
- if ((ifp = ifunit(altq->ifname)) == NULL) {
- error = EINVAL;
+ error = pf_disable_altq(altq);
+ if (error != 0)
break;
- }
- if (ifp->if_snd.altq_type != ALTQT_NONE) {
- err = altq_disable(&ifp->if_snd);
- if (err != 0 && error == 0)
- error = err;
- }
- /* clear tokenbucket regulator */
- tb.rate = 0;
- err = tbr_set(&ifp->if_snd, &tb);
- if (err != 0 && error == 0)
- error = err;
}
}
if (error == 0)
- pfaltq_running = 0;
+ pf_altq_running = 0;
splx(s);
DPFPRINTF(PF_DEBUG_MISC, ("altq: stopped\n"));
break;