summaryrefslogtreecommitdiff
path: root/sys/net/pf_ioctl.c
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 /sys/net/pf_ioctl.c
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@
Diffstat (limited to 'sys/net/pf_ioctl.c')
-rw-r--r--sys/net/pf_ioctl.c105
1 files changed, 71 insertions, 34 deletions
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;