1 /* $NetBSD: qop_fifoq.c,v 1.4 2001/08/22 08:52:37 itojun Exp $ */
2 /* $KAME: qop_fifoq.c,v 1.6 2001/12/03 08:20:55 kjc Exp $ */
4 * Copyright (C) 1999-2000
5 * Sony Computer Science Laboratories, Inc. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/param.h>
30 #include <sys/socket.h>
31 #include <sys/sockio.h>
32 #include <sys/ioctl.h>
33 #include <sys/fcntl.h>
35 #include <netinet/in.h>
36 #include <arpa/inet.h>
48 #include <altq/altq.h>
49 #include <altq/altq_fifoq.h>
51 #include "qop_fifoq.h"
53 static int fifoq_attach(struct ifinfo
*);
54 static int fifoq_detach(struct ifinfo
*);
55 static int fifoq_enable(struct ifinfo
*);
56 static int fifoq_disable(struct ifinfo
*);
58 #define FIFOQ_DEVICE "/dev/altq/fifoq"
60 static int fifoq_fd
= -1;
61 static int fifoq_refcount
= 0;
63 static struct qdisc_ops fifoq_qdisc
= {
72 NULL
, /* modify class */
73 NULL
, /* delete class */
74 NULL
, /* add filter */
75 NULL
/* delete filter */
81 #define EQUAL(s1, s2) (strcmp((s1), (s2)) == 0)
84 fifoq_interface_parser(const char *ifname
, int argc
, char **argv
)
86 u_int bandwidth
= 100000000; /* 100Mbps */
94 if (EQUAL(*argv
, "bandwidth")) {
97 bandwidth
= atobps(*argv
);
98 } else if (EQUAL(*argv
, "tbrsize")) {
101 tbrsize
= atobytes(*argv
);
102 } else if (EQUAL(*argv
, "qlimit")) {
105 qlimit
= (int)strtol(*argv
, NULL
, 0);
106 } else if (EQUAL(*argv
, "fifoq")) {
109 LOG(LOG_ERR
, 0, "Unknown keyword '%s'", *argv
);
115 if (qcmd_tbr_register(ifname
, bandwidth
, tbrsize
) != 0)
118 if (qcmd_fifoq_add_if(ifname
, bandwidth
, qlimit
) != 0)
127 qcmd_fifoq_add_if(const char *ifname
, u_int bandwidth
, int qlimit
)
131 error
= qop_fifoq_add_if(NULL
, ifname
, bandwidth
, qlimit
);
133 LOG(LOG_ERR
, errno
, "%s: can't add fifoq on interface '%s'",
134 qoperror(error
), ifname
);
142 qop_fifoq_add_if(struct ifinfo
**rp
, const char *ifname
,
143 u_int bandwidth
, int qlimit
)
145 struct ifinfo
*ifinfo
= NULL
;
146 struct fifoq_ifinfo
*fifoq_ifinfo
;
149 if ((fifoq_ifinfo
= calloc(1, sizeof(*fifoq_ifinfo
))) == NULL
)
150 return (QOPERR_NOMEM
);
151 fifoq_ifinfo
->qlimit
= qlimit
;
153 error
= qop_add_if(&ifinfo
, ifname
, bandwidth
,
154 &fifoq_qdisc
, fifoq_ifinfo
);
166 * system call interfaces for qdisc_ops
169 fifoq_attach(struct ifinfo
*ifinfo
)
171 struct fifoq_interface iface
;
172 struct fifoq_ifinfo
*fifoq_ifinfo
;
173 struct fifoq_conf conf
;
176 (fifoq_fd
= open(FIFOQ_DEVICE
, O_RDWR
)) < 0 &&
177 (fifoq_fd
= open_module(FIFOQ_DEVICE
, O_RDWR
)) < 0) {
178 LOG(LOG_ERR
, errno
, "FIFOQ open");
179 return (QOPERR_SYSCALL
);
183 memset(&iface
, 0, sizeof(iface
));
184 strncpy(iface
.fifoq_ifname
, ifinfo
->ifname
, IFNAMSIZ
);
186 if (ioctl(fifoq_fd
, FIFOQ_IF_ATTACH
, &iface
) < 0)
187 return (QOPERR_SYSCALL
);
189 /* set fifoq parameters */
190 fifoq_ifinfo
= (struct fifoq_ifinfo
*)ifinfo
->private;
191 if (fifoq_ifinfo
->qlimit
> 0) {
192 memset(&conf
, 0, sizeof(conf
));
193 strncpy(conf
.iface
.fifoq_ifname
, ifinfo
->ifname
, IFNAMSIZ
);
194 conf
.fifoq_limit
= fifoq_ifinfo
->qlimit
;
195 if (ioctl(fifoq_fd
, FIFOQ_CONFIG
, &conf
) < 0)
196 return (QOPERR_SYSCALL
);
199 LOG(LOG_INFO
, 0, "fifoq attached to %s", iface
.fifoq_ifname
);
205 fifoq_detach(struct ifinfo
*ifinfo
)
207 struct fifoq_interface iface
;
209 memset(&iface
, 0, sizeof(iface
));
210 strncpy(iface
.fifoq_ifname
, ifinfo
->ifname
, IFNAMSIZ
);
212 if (ioctl(fifoq_fd
, FIFOQ_IF_DETACH
, &iface
) < 0)
213 return (QOPERR_SYSCALL
);
215 if (--fifoq_refcount
== 0) {
223 fifoq_enable(struct ifinfo
*ifinfo
)
225 struct fifoq_interface iface
;
227 memset(&iface
, 0, sizeof(iface
));
228 strncpy(iface
.fifoq_ifname
, ifinfo
->ifname
, IFNAMSIZ
);
230 if (ioctl(fifoq_fd
, FIFOQ_ENABLE
, &iface
) < 0)
231 return (QOPERR_SYSCALL
);
236 fifoq_disable(struct ifinfo
*ifinfo
)
238 struct fifoq_interface iface
;
240 memset(&iface
, 0, sizeof(iface
));
241 strncpy(iface
.fifoq_ifname
, ifinfo
->ifname
, IFNAMSIZ
);
243 if (ioctl(fifoq_fd
, FIFOQ_DISABLE
, &iface
) < 0)
244 return (QOPERR_SYSCALL
);