1 /* $NetBSD: qop_blue.c,v 1.4 2001/08/22 08:52:37 itojun Exp $ */
2 /* $KAME: qop_blue.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_blue.h>
53 static int blue_attach(struct ifinfo
*);
54 static int blue_detach(struct ifinfo
*);
55 static int blue_enable(struct ifinfo
*);
56 static int blue_disable(struct ifinfo
*);
58 #define BLUE_DEVICE "/dev/altq/blue"
60 static int blue_fd
= -1;
61 static int blue_refcount
= 0;
63 static struct qdisc_ops blue_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 blue_interface_parser(const char *ifname
, int argc
, char **argv
)
86 u_int bandwidth
= 100000000; /* 100Mbps */
93 int packet_size
= 1000;
99 if (EQUAL(*argv
, "bandwidth")) {
102 bandwidth
= atobps(*argv
);
103 } else if (EQUAL(*argv
, "tbrsize")) {
106 tbrsize
= atobytes(*argv
);
107 } else if (EQUAL(*argv
, "packetsize")) {
110 packet_size
= atobytes(*argv
);
111 } else if (EQUAL(*argv
, "qlimit")) {
114 qlimit
= (int)strtol(*argv
, NULL
, 0);
115 } else if (EQUAL(*argv
, "maxpmark")) {
118 max_pmark
= (int)strtol(*argv
, NULL
, 0);
119 } else if (EQUAL(*argv
, "holdtime")) {
122 hold_time
= (int)strtol(*argv
, NULL
, 0);
123 } else if (EQUAL(*argv
, "blue")) {
125 } else if (EQUAL(*argv
, "ecn")) {
128 LOG(LOG_ERR
, 0, "Unknown keyword '%s'", *argv
);
134 if (qcmd_tbr_register(ifname
, bandwidth
, tbrsize
) != 0)
137 pkttime
= packet_size
* 8 * 1000 / (bandwidth
/ 1000);
139 if (qcmd_blue_add_if(ifname
, bandwidth
, max_pmark
, hold_time
,
140 qlimit
, pkttime
, flags
) != 0)
149 qcmd_blue_add_if(const char *ifname
, u_int bandwidth
, int max_pmark
,
150 int hold_time
, int qlimit
, int pkttime
, int flags
)
154 error
= qop_blue_add_if(NULL
, ifname
, bandwidth
, max_pmark
, hold_time
,
155 qlimit
, pkttime
, flags
);
157 LOG(LOG_ERR
, errno
, "%s: can't add blue on interface '%s'",
158 qoperror(error
), ifname
);
166 qop_blue_add_if(struct ifinfo
**rp
, const char *ifname
, u_int bandwidth
,
167 int max_pmark
, int hold_time
, int qlimit
,
168 int pkttime
, int flags
)
170 struct ifinfo
*ifinfo
= NULL
;
171 struct blue_ifinfo
*blue_ifinfo
;
174 if ((blue_ifinfo
= calloc(1, sizeof(*blue_ifinfo
))) == NULL
)
175 return (QOPERR_NOMEM
);
176 blue_ifinfo
->max_pmark
= max_pmark
;
177 blue_ifinfo
->hold_time
= hold_time
;
178 blue_ifinfo
->qlimit
= qlimit
;
179 blue_ifinfo
->pkttime
= pkttime
;
180 blue_ifinfo
->flags
= flags
;
182 error
= qop_add_if(&ifinfo
, ifname
, bandwidth
,
183 &blue_qdisc
, blue_ifinfo
);
195 * system call interfaces for qdisc_ops
198 blue_attach(struct ifinfo
*ifinfo
)
200 struct blue_interface iface
;
201 struct blue_ifinfo
*blue_ifinfo
;
202 struct blue_conf conf
;
205 (blue_fd
= open(BLUE_DEVICE
, O_RDWR
)) < 0 &&
206 (blue_fd
= open_module(BLUE_DEVICE
, O_RDWR
)) < 0) {
207 LOG(LOG_ERR
, errno
, "BLUE open");
208 return (QOPERR_SYSCALL
);
212 memset(&iface
, 0, sizeof(iface
));
213 strncpy(iface
.blue_ifname
, ifinfo
->ifname
, IFNAMSIZ
);
215 if (ioctl(blue_fd
, BLUE_IF_ATTACH
, &iface
) < 0)
216 return (QOPERR_SYSCALL
);
218 /* set blue parameters */
219 blue_ifinfo
= (struct blue_ifinfo
*)ifinfo
->private;
220 memset(&conf
, 0, sizeof(conf
));
221 strncpy(conf
.iface
.blue_ifname
, ifinfo
->ifname
, IFNAMSIZ
);
222 conf
.blue_max_pmark
= blue_ifinfo
->max_pmark
;
223 conf
.blue_hold_time
= blue_ifinfo
->hold_time
;
224 conf
.blue_limit
= blue_ifinfo
->qlimit
;
225 conf
.blue_pkttime
= blue_ifinfo
->pkttime
;
226 conf
.blue_flags
= blue_ifinfo
->flags
;
227 if (ioctl(blue_fd
, BLUE_CONFIG
, &conf
) < 0)
228 return (QOPERR_SYSCALL
);
231 LOG(LOG_INFO
, 0, "blue attached to %s", iface
.blue_ifname
);
237 blue_detach(struct ifinfo
*ifinfo
)
239 struct blue_interface iface
;
241 memset(&iface
, 0, sizeof(iface
));
242 strncpy(iface
.blue_ifname
, ifinfo
->ifname
, IFNAMSIZ
);
244 if (ioctl(blue_fd
, BLUE_IF_DETACH
, &iface
) < 0)
245 return (QOPERR_SYSCALL
);
247 if (--blue_refcount
== 0) {
255 blue_enable(struct ifinfo
*ifinfo
)
257 struct blue_interface iface
;
259 memset(&iface
, 0, sizeof(iface
));
260 strncpy(iface
.blue_ifname
, ifinfo
->ifname
, IFNAMSIZ
);
262 if (ioctl(blue_fd
, BLUE_ENABLE
, &iface
) < 0)
263 return (QOPERR_SYSCALL
);
268 blue_disable(struct ifinfo
*ifinfo
)
270 struct blue_interface iface
;
272 memset(&iface
, 0, sizeof(iface
));
273 strncpy(iface
.blue_ifname
, ifinfo
->ifname
, IFNAMSIZ
);
275 if (ioctl(blue_fd
, BLUE_DISABLE
, &iface
) < 0)
276 return (QOPERR_SYSCALL
);