svn commit: r205511 - in stable/8: . contrib/top lib lib/libusb
sbin/ipfw sys/conf sys/net sys/netgraph sys/netinet
sys/netinet/ipfw sys/netinet/ipfw/test
tools/regression/lib/msun tools/regression...
Luigi Rizzo
luigi at FreeBSD.org
Tue Mar 23 09:59:00 UTC 2010
Author: luigi
Date: Tue Mar 23 09:58:59 2010
New Revision: 205511
URL: http://svn.freebsd.org/changeset/base/205511
Log:
MFC of a large number of ipfw and dummynet fixes and enhancements
done in CURRENT over the last 4 months.
HEAD and RELENG_8 are almost in sync now for ipfw, dummynet
the pfil hooks and related components.
Among the most noticeable changes:
- r200855 more efficient lookup of skipto rules, and remove O(N)
blocks from critical sections in the kernel;
- r204591 large restructuring of the dummynet module, with support
for multiple scheduling algorithms (4 available so far)
See the original commit logs for details.
Changes in the kernel/userland ABI should be harmless because the
kernel is able to understand previous requests from RELENG_8 and
RELENG_7. For this reason, this changeset would be applicable
to RELENG_7 as well, but i am not sure if it is worthwhile.
Added:
stable/8/sys/netinet/ipfw/dn_heap.c
- copied unchanged from r205419, user/luigi/ipfw3-r8/sys/netinet/ipfw/dn_heap.c
stable/8/sys/netinet/ipfw/dn_heap.h
- copied unchanged from r205419, user/luigi/ipfw3-r8/sys/netinet/ipfw/dn_heap.h
stable/8/sys/netinet/ipfw/dn_sched.h
- copied unchanged from r205419, user/luigi/ipfw3-r8/sys/netinet/ipfw/dn_sched.h
stable/8/sys/netinet/ipfw/dn_sched_fifo.c
- copied unchanged from r205419, user/luigi/ipfw3-r8/sys/netinet/ipfw/dn_sched_fifo.c
stable/8/sys/netinet/ipfw/dn_sched_qfq.c
- copied unchanged from r205419, user/luigi/ipfw3-r8/sys/netinet/ipfw/dn_sched_qfq.c
stable/8/sys/netinet/ipfw/dn_sched_rr.c
- copied unchanged from r205419, user/luigi/ipfw3-r8/sys/netinet/ipfw/dn_sched_rr.c
stable/8/sys/netinet/ipfw/dn_sched_wf2q.c
- copied unchanged from r205419, user/luigi/ipfw3-r8/sys/netinet/ipfw/dn_sched_wf2q.c
stable/8/sys/netinet/ipfw/dummynet.txt
- copied unchanged from r205419, user/luigi/ipfw3-r8/sys/netinet/ipfw/dummynet.txt
stable/8/sys/netinet/ipfw/ip_dn_glue.c
- copied unchanged from r205419, user/luigi/ipfw3-r8/sys/netinet/ipfw/ip_dn_glue.c
stable/8/sys/netinet/ipfw/ip_dn_io.c
- copied unchanged from r205419, user/luigi/ipfw3-r8/sys/netinet/ipfw/ip_dn_io.c
stable/8/sys/netinet/ipfw/ip_dn_private.h
- copied unchanged from r205419, user/luigi/ipfw3-r8/sys/netinet/ipfw/ip_dn_private.h
stable/8/sys/netinet/ipfw/ip_fw_dynamic.c
- copied unchanged from r205419, user/luigi/ipfw3-r8/sys/netinet/ipfw/ip_fw_dynamic.c
stable/8/sys/netinet/ipfw/ip_fw_log.c
- copied unchanged from r205419, user/luigi/ipfw3-r8/sys/netinet/ipfw/ip_fw_log.c
stable/8/sys/netinet/ipfw/ip_fw_private.h
- copied unchanged from r205419, user/luigi/ipfw3-r8/sys/netinet/ipfw/ip_fw_private.h
stable/8/sys/netinet/ipfw/ip_fw_sockopt.c
- copied unchanged from r205419, user/luigi/ipfw3-r8/sys/netinet/ipfw/ip_fw_sockopt.c
stable/8/sys/netinet/ipfw/ip_fw_table.c
- copied unchanged from r205419, user/luigi/ipfw3-r8/sys/netinet/ipfw/ip_fw_table.c
stable/8/sys/netinet/ipfw/test/
- copied from r205419, user/luigi/ipfw3-r8/sys/netinet/ipfw/test/
Modified:
stable/8/sbin/ipfw/Makefile
stable/8/sbin/ipfw/altq.c
stable/8/sbin/ipfw/dummynet.c
stable/8/sbin/ipfw/ipfw.8
stable/8/sbin/ipfw/ipfw2.c
stable/8/sbin/ipfw/ipfw2.h
stable/8/sbin/ipfw/main.c
stable/8/sys/conf/files
stable/8/sys/net/if_bridge.c
stable/8/sys/net/if_ethersubr.c
stable/8/sys/net/radix.c
stable/8/sys/net/radix.h
stable/8/sys/net/route.c
stable/8/sys/netgraph/ng_ipfw.c
stable/8/sys/netgraph/ng_ipfw.h
stable/8/sys/netinet/in.h
stable/8/sys/netinet/ip_divert.c
stable/8/sys/netinet/ip_divert.h
stable/8/sys/netinet/ip_dummynet.h
stable/8/sys/netinet/ip_fw.h
stable/8/sys/netinet/ip_var.h
stable/8/sys/netinet/ipfw/ip_dummynet.c
stable/8/sys/netinet/ipfw/ip_fw2.c
stable/8/sys/netinet/ipfw/ip_fw_nat.c
stable/8/sys/netinet/ipfw/ip_fw_pfil.c
stable/8/sys/netinet/raw_ip.c
Directory Properties:
stable/8/ (props changed)
stable/8/Makefile.inc1 (props changed)
stable/8/ObsoleteFiles.inc (props changed)
stable/8/UPDATING (props changed)
stable/8/bin/ (props changed)
stable/8/bin/chmod/ (props changed)
stable/8/bin/cp/ (props changed)
stable/8/bin/csh/ (props changed)
stable/8/bin/getfacl/ (props changed)
stable/8/bin/kill/ (props changed)
stable/8/bin/ls/ (props changed)
stable/8/bin/mv/ (props changed)
stable/8/bin/pax/ (props changed)
stable/8/bin/pkill/ (props changed)
stable/8/bin/ps/ (props changed)
stable/8/bin/setfacl/ (props changed)
stable/8/bin/sh/ (props changed)
stable/8/cddl/compat/opensolaris/ (props changed)
stable/8/cddl/contrib/opensolaris/ (props changed)
stable/8/cddl/contrib/opensolaris/cmd/zdb/ (props changed)
stable/8/cddl/contrib/opensolaris/cmd/zfs/ (props changed)
stable/8/cddl/contrib/opensolaris/lib/libzfs/ (props changed)
stable/8/cddl/lib/libnvpair/ (props changed)
stable/8/contrib/bind9/ (props changed)
stable/8/contrib/bsnmp/ (props changed)
stable/8/contrib/bzip2/ (props changed)
stable/8/contrib/cpio/ (props changed)
stable/8/contrib/csup/ (props changed)
stable/8/contrib/ee/ (props changed)
stable/8/contrib/expat/ (props changed)
stable/8/contrib/file/ (props changed)
stable/8/contrib/gcc/ (props changed)
stable/8/contrib/gdb/ (props changed)
stable/8/contrib/gdtoa/ (props changed)
stable/8/contrib/groff/ (props changed)
stable/8/contrib/less/ (props changed)
stable/8/contrib/libpcap/ (props changed)
stable/8/contrib/ncurses/ (props changed)
stable/8/contrib/netcat/ (props changed)
stable/8/contrib/ntp/ (props changed)
stable/8/contrib/one-true-awk/ (props changed)
stable/8/contrib/openbsm/ (props changed)
stable/8/contrib/openpam/ (props changed)
stable/8/contrib/pf/ (props changed)
stable/8/contrib/sendmail/ (props changed)
stable/8/contrib/tcpdump/ (props changed)
stable/8/contrib/tcsh/ (props changed)
stable/8/contrib/top/ (props changed)
stable/8/contrib/top/install-sh (props changed)
stable/8/contrib/traceroute/ (props changed)
stable/8/contrib/wpa/ (props changed)
stable/8/crypto/heimdal/ (props changed)
stable/8/crypto/openssh/ (props changed)
stable/8/crypto/openssl/ (props changed)
stable/8/etc/ (props changed)
stable/8/games/factor/ (props changed)
stable/8/games/fortune/ (props changed)
stable/8/games/fortune/datfiles/ (props changed)
stable/8/games/grdc/ (props changed)
stable/8/gnu/usr.bin/gdb/kgdb/ (props changed)
stable/8/gnu/usr.bin/groff/ (props changed)
stable/8/gnu/usr.bin/patch/ (props changed)
stable/8/include/ (props changed)
stable/8/kerberos5/lib/libgssapi_krb5/ (props changed)
stable/8/kerberos5/lib/libgssapi_spnego/ (props changed)
stable/8/kerberos5/usr.bin/kdestroy/ (props changed)
stable/8/kerberos5/usr.bin/kpasswd/ (props changed)
stable/8/lib/Makefile (props changed)
stable/8/lib/bind/ (props changed)
stable/8/lib/csu/ (props changed)
stable/8/lib/libarchive/ (props changed)
stable/8/lib/libbluetooth/ (props changed)
stable/8/lib/libc/ (props changed)
stable/8/lib/libc/stdtime/ (props changed)
stable/8/lib/libc_r/ (props changed)
stable/8/lib/libdevinfo/ (props changed)
stable/8/lib/libdisk/ (props changed)
stable/8/lib/libelf/ (props changed)
stable/8/lib/libexpat/ (props changed)
stable/8/lib/libfetch/ (props changed)
stable/8/lib/libgpib/ (props changed)
stable/8/lib/libgssapi/ (props changed)
stable/8/lib/libjail/ (props changed)
stable/8/lib/libkse/ (props changed)
stable/8/lib/libkvm/ (props changed)
stable/8/lib/libpmc/ (props changed)
stable/8/lib/libradius/ (props changed)
stable/8/lib/librpcsec_gss/ (props changed)
stable/8/lib/libsm/ (props changed)
stable/8/lib/libstand/ (props changed)
stable/8/lib/libtacplus/ (props changed)
stable/8/lib/libthr/ (props changed)
stable/8/lib/libufs/ (props changed)
stable/8/lib/libusb/ (props changed)
stable/8/lib/libusb/usb.h (props changed)
stable/8/lib/libutil/ (props changed)
stable/8/lib/msun/ (props changed)
stable/8/libexec/rtld-elf/ (props changed)
stable/8/release/ (props changed)
stable/8/release/picobsd/ (props changed)
stable/8/release/picobsd/floppy.tree/sbin/ (props changed)
stable/8/release/picobsd/qemu/ (props changed)
stable/8/sbin/ (props changed)
stable/8/sbin/atacontrol/ (props changed)
stable/8/sbin/bsdlabel/ (props changed)
stable/8/sbin/camcontrol/ (props changed)
stable/8/sbin/ddb/ (props changed)
stable/8/sbin/devfs/ (props changed)
stable/8/sbin/dhclient/ (props changed)
stable/8/sbin/dump/ (props changed)
stable/8/sbin/dumpfs/ (props changed)
stable/8/sbin/fsck/ (props changed)
stable/8/sbin/fsck_ffs/ (props changed)
stable/8/sbin/geom/ (props changed)
stable/8/sbin/geom/class/stripe/ (props changed)
stable/8/sbin/ggate/ (props changed)
stable/8/sbin/growfs/ (props changed)
stable/8/sbin/ifconfig/ (props changed)
stable/8/sbin/ipfw/ (props changed)
stable/8/sbin/iscontrol/ (props changed)
stable/8/sbin/mdconfig/ (props changed)
stable/8/sbin/mksnap_ffs/ (props changed)
stable/8/sbin/mount/ (props changed)
stable/8/sbin/mount_cd9660/ (props changed)
stable/8/sbin/mount_msdosfs/ (props changed)
stable/8/sbin/mount_nfs/ (props changed)
stable/8/sbin/natd/ (props changed)
stable/8/sbin/newfs/ (props changed)
stable/8/sbin/restore/ (props changed)
stable/8/sbin/routed/ (props changed)
stable/8/sbin/sysctl/ (props changed)
stable/8/sbin/tunefs/ (props changed)
stable/8/sbin/umount/ (props changed)
stable/8/secure/usr.bin/bdes/ (props changed)
stable/8/share/examples/ (props changed)
stable/8/share/man/man3/ (props changed)
stable/8/share/man/man4/ (props changed)
stable/8/share/man/man5/ (props changed)
stable/8/share/man/man7/ (props changed)
stable/8/share/man/man8/ (props changed)
stable/8/share/man/man9/ (props changed)
stable/8/share/misc/ (props changed)
stable/8/share/mk/ (props changed)
stable/8/share/timedef/ (props changed)
stable/8/share/zoneinfo/ (props changed)
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/xen/xenpci/ (props changed)
stable/8/sys/net/ (props changed)
stable/8/sys/netinet/ipfw/ (props changed)
stable/8/tools/ (props changed)
stable/8/tools/kerneldoc/subsys/ (props changed)
stable/8/tools/regression/acltools/ (props changed)
stable/8/tools/regression/aio/aiotest/ (props changed)
stable/8/tools/regression/bin/sh/ (props changed)
stable/8/tools/regression/fifo/ (props changed)
stable/8/tools/regression/geom/ (props changed)
stable/8/tools/regression/lib/libc/ (props changed)
stable/8/tools/regression/lib/msun/test-conj.t (props changed)
stable/8/tools/regression/mqueue/mqtest1/ (props changed)
stable/8/tools/regression/mqueue/mqtest2/ (props changed)
stable/8/tools/regression/mqueue/mqtest3/ (props changed)
stable/8/tools/regression/mqueue/mqtest4/ (props changed)
stable/8/tools/regression/mqueue/mqtest5/ (props changed)
stable/8/tools/regression/poll/ (props changed)
stable/8/tools/regression/posixsem/ (props changed)
stable/8/tools/regression/priv/ (props changed)
stable/8/tools/regression/usr.bin/pkill/pgrep-_g.t (props changed)
stable/8/tools/regression/usr.bin/pkill/pgrep-_s.t (props changed)
stable/8/tools/regression/usr.bin/pkill/pkill-_g.t (props changed)
stable/8/tools/tools/ath/ (props changed)
stable/8/tools/tools/ath/common/dumpregs.h (props changed)
stable/8/tools/tools/ath/common/dumpregs_5210.c (props changed)
stable/8/tools/tools/ath/common/dumpregs_5211.c (props changed)
stable/8/tools/tools/ath/common/dumpregs_5212.c (props changed)
stable/8/tools/tools/ath/common/dumpregs_5416.c (props changed)
stable/8/tools/tools/termcap/termcap.pl (props changed)
stable/8/tools/tools/vimage/ (props changed)
stable/8/usr.bin/awk/ (props changed)
stable/8/usr.bin/calendar/ (props changed)
stable/8/usr.bin/catman/ (props changed)
stable/8/usr.bin/comm/ (props changed)
stable/8/usr.bin/csup/ (props changed)
stable/8/usr.bin/fetch/ (props changed)
stable/8/usr.bin/find/ (props changed)
stable/8/usr.bin/finger/ (props changed)
stable/8/usr.bin/fstat/ (props changed)
stable/8/usr.bin/gcore/ (props changed)
stable/8/usr.bin/gzip/ (props changed)
stable/8/usr.bin/hexdump/ (props changed)
stable/8/usr.bin/kdump/ (props changed)
stable/8/usr.bin/locale/ (props changed)
stable/8/usr.bin/look/ (props changed)
stable/8/usr.bin/makewhatis/ (props changed)
stable/8/usr.bin/netstat/ (props changed)
stable/8/usr.bin/perror/ (props changed)
stable/8/usr.bin/procstat/ (props changed)
stable/8/usr.bin/systat/ (props changed)
stable/8/usr.bin/tftp/ (props changed)
stable/8/usr.bin/truss/ (props changed)
stable/8/usr.bin/unifdef/ (props changed)
stable/8/usr.bin/uniq/ (props changed)
stable/8/usr.bin/vmstat/ (props changed)
stable/8/usr.bin/w/ (props changed)
stable/8/usr.bin/whois/ (props changed)
stable/8/usr.bin/xlint/ (props changed)
stable/8/usr.sbin/ (props changed)
stable/8/usr.sbin/Makefile (props changed)
stable/8/usr.sbin/acpi/ (props changed)
stable/8/usr.sbin/arp/ (props changed)
stable/8/usr.sbin/bsnmpd/ (props changed)
stable/8/usr.sbin/burncd/ (props changed)
stable/8/usr.sbin/cdcontrol/ (props changed)
stable/8/usr.sbin/cpucontrol/ (props changed)
stable/8/usr.sbin/crashinfo/ (props changed)
stable/8/usr.sbin/cron/ (props changed)
stable/8/usr.sbin/diskinfo/ (props changed)
stable/8/usr.sbin/dumpcis/cardinfo.h (props changed)
stable/8/usr.sbin/dumpcis/cis.h (props changed)
stable/8/usr.sbin/faithd/ (props changed)
stable/8/usr.sbin/freebsd-update/ (props changed)
stable/8/usr.sbin/inetd/ (props changed)
stable/8/usr.sbin/iostat/ (props changed)
stable/8/usr.sbin/jail/ (props changed)
stable/8/usr.sbin/jls/ (props changed)
stable/8/usr.sbin/lpr/ (props changed)
stable/8/usr.sbin/makefs/ffs/ffs_bswap.c (props changed)
stable/8/usr.sbin/makefs/ffs/ffs_subr.c (props changed)
stable/8/usr.sbin/makefs/ffs/ufs_bswap.h (props changed)
stable/8/usr.sbin/makefs/getid.c (props changed)
stable/8/usr.sbin/mergemaster/ (props changed)
stable/8/usr.sbin/mfiutil/mfiutil.8 (props changed)
stable/8/usr.sbin/mptutil/ (props changed)
stable/8/usr.sbin/ndp/ (props changed)
stable/8/usr.sbin/newsyslog/ (props changed)
stable/8/usr.sbin/ntp/ (props changed)
stable/8/usr.sbin/pmcstat/ (props changed)
stable/8/usr.sbin/powerd/ (props changed)
stable/8/usr.sbin/ppp/ (props changed)
stable/8/usr.sbin/pstat/ (props changed)
stable/8/usr.sbin/rpc.umntall/ (props changed)
stable/8/usr.sbin/rtsold/ (props changed)
stable/8/usr.sbin/service/ (props changed)
stable/8/usr.sbin/sysinstall/ (props changed)
stable/8/usr.sbin/syslogd/ (props changed)
stable/8/usr.sbin/traceroute/ (props changed)
stable/8/usr.sbin/traceroute6/ (props changed)
stable/8/usr.sbin/usbconfig/ (props changed)
stable/8/usr.sbin/wpa/ (props changed)
stable/8/usr.sbin/ypserv/ (props changed)
stable/8/usr.sbin/zic/ (props changed)
Modified: stable/8/sbin/ipfw/Makefile
==============================================================================
--- stable/8/sbin/ipfw/Makefile Tue Mar 23 06:42:52 2010 (r205510)
+++ stable/8/sbin/ipfw/Makefile Tue Mar 23 09:58:59 2010 (r205511)
@@ -3,6 +3,7 @@
PROG= ipfw
SRCS= ipfw2.c dummynet.c ipv6.c main.c nat.c altq.c
WARNS?= 2
+DPADD= ${LIBUTIL}
LDADD= -lutil
MAN= ipfw.8
Modified: stable/8/sbin/ipfw/altq.c
==============================================================================
--- stable/8/sbin/ipfw/altq.c Tue Mar 23 06:42:52 2010 (r205510)
+++ stable/8/sbin/ipfw/altq.c Tue Mar 23 09:58:59 2010 (r205511)
@@ -39,6 +39,7 @@
#include <net/if.h> /* IFNAMSIZ */
#include <net/pfvar.h>
+#include <netinet/in.h> /* in_addr */
#include <netinet/ip_fw.h>
/*
Modified: stable/8/sbin/ipfw/dummynet.c
==============================================================================
--- stable/8/sbin/ipfw/dummynet.c Tue Mar 23 06:42:52 2010 (r205510)
+++ stable/8/sbin/ipfw/dummynet.c Tue Mar 23 09:58:59 2010 (r205511)
@@ -1,10 +1,5 @@
/*
- * Copyright (c) 2002-2003 Luigi Rizzo
- * Copyright (c) 1996 Alex Nash, Paul Traina, Poul-Henning Kamp
- * Copyright (c) 1994 Ugen J.S.Antsilevich
- *
- * Idea and grammar partially left from:
- * Copyright (c) 1993 Daniel Boulet
+ * Copyright (c) 2002-2003,2010 Luigi Rizzo
*
* Redistribution and use in source forms, with and without modification,
* are permitted provided that this entire comment appears intact.
@@ -15,8 +10,6 @@
*
* This software is provided ``AS IS'' without any warranties of any kind.
*
- * NEW command line interface for IP firewall facility
- *
* $FreeBSD$
*
* dummynet support
@@ -24,7 +17,6 @@
#include <sys/types.h>
#include <sys/socket.h>
-#include <sys/queue.h>
/* XXX there are several sysctl leftover here */
#include <sys/sysctl.h>
@@ -46,6 +38,7 @@
#include <netinet/ip_dummynet.h>
#include <arpa/inet.h> /* inet_ntoa */
+
static struct _s_x dummynet_params[] = {
{ "plr", TOK_PLR },
{ "noerror", TOK_NOERROR },
@@ -56,27 +49,59 @@ static struct _s_x dummynet_params[] = {
{ "src-port", TOK_SRCPORT },
{ "proto", TOK_PROTO },
{ "weight", TOK_WEIGHT },
+ { "lmax", TOK_LMAX },
+ { "maxlen", TOK_LMAX },
{ "all", TOK_ALL },
- { "mask", TOK_MASK },
+ { "mask", TOK_MASK }, /* alias for both */
+ { "sched_mask", TOK_SCHED_MASK },
+ { "flow_mask", TOK_FLOW_MASK },
{ "droptail", TOK_DROPTAIL },
{ "red", TOK_RED },
{ "gred", TOK_GRED },
{ "bw", TOK_BW },
{ "bandwidth", TOK_BW },
{ "delay", TOK_DELAY },
+ { "link", TOK_LINK },
{ "pipe", TOK_PIPE },
{ "queue", TOK_QUEUE },
+ { "flowset", TOK_FLOWSET },
+ { "sched", TOK_SCHED },
+ { "pri", TOK_PRI },
+ { "priority", TOK_PRI },
+ { "type", TOK_TYPE },
{ "flow-id", TOK_FLOWID},
{ "dst-ipv6", TOK_DSTIP6},
{ "dst-ip6", TOK_DSTIP6},
{ "src-ipv6", TOK_SRCIP6},
{ "src-ip6", TOK_SRCIP6},
- { "profile", TOK_PIPE_PROFILE},
+ { "profile", TOK_PROFILE},
{ "burst", TOK_BURST},
{ "dummynet-params", TOK_NULL },
{ NULL, 0 } /* terminator */
};
+#define O_NEXT(p, len) ((void *)((char *)p + len))
+
+static void
+oid_fill(struct dn_id *oid, int len, int type, uintptr_t id)
+{
+ oid->len = len;
+ oid->type = type;
+ oid->subtype = 0;
+ oid->id = id;
+}
+
+/* make room in the buffer and move the pointer forward */
+static void *
+o_next(struct dn_id **o, int len, int type)
+{
+ struct dn_id *ret = *o;
+ oid_fill(ret, len, type, 0);
+ *o = O_NEXT(*o, len);
+ return ret;
+}
+
+#if 0
static int
sort_q(void *arg, const void *pa, const void *pb)
{
@@ -108,117 +133,84 @@ sort_q(void *arg, const void *pa, const
res = 1;
return (int)(rev ? res : -res);
}
+#endif
+/* print a mask and header for the subsequent list of flows */
static void
-list_queues(struct dn_flow_set *fs, struct dn_flow_queue *q)
+print_mask(struct ipfw_flow_id *id)
+{
+ if (!IS_IP6_FLOW_ID(id)) {
+ printf(" "
+ "mask: %s 0x%02x 0x%08x/0x%04x -> 0x%08x/0x%04x\n",
+ id->extra ? "queue," : "",
+ id->proto,
+ id->src_ip, id->src_port,
+ id->dst_ip, id->dst_port);
+
+ printf("BKT Prot ___Source IP/port____ "
+ "____Dest. IP/port____ "
+ "Tot_pkt/bytes Pkt/Byte Drp\n");
+ } else {
+ char buf[255];
+ printf("\n mask: %sproto: 0x%02x, flow_id: 0x%08x, ",
+ id->extra ? "queue," : "",
+ id->proto, id->flow_id6);
+ inet_ntop(AF_INET6, &(id->src_ip6), buf, sizeof(buf));
+ printf("%s/0x%04x -> ", buf, id->src_port);
+ inet_ntop(AF_INET6, &(id->dst_ip6), buf, sizeof(buf));
+ printf("%s/0x%04x\n", buf, id->dst_port);
+
+ printf("BKT ___Prot___ _flow-id_ "
+ "______________Source IPv6/port_______________ "
+ "_______________Dest. IPv6/port_______________ "
+ "Tot_pkt/bytes Pkt/Byte Drp\n");
+ }
+}
+
+static void
+list_flow(struct dn_flow *ni)
{
- int l;
- int index_printed, indexes = 0;
char buff[255];
struct protoent *pe;
+ struct in_addr ina;
+ struct ipfw_flow_id *id = &ni->fid;
- if (fs->rq_elements == 0)
- return;
-
- if (co.do_sort != 0)
- qsort_r(q, fs->rq_elements, sizeof *q, NULL, sort_q);
-
- /* Print IPv4 flows */
- index_printed = 0;
- for (l = 0; l < fs->rq_elements; l++) {
- struct in_addr ina;
-
+ pe = getprotobynumber(id->proto);
/* XXX: Should check for IPv4 flows */
- if (IS_IP6_FLOW_ID(&(q[l].id)))
- continue;
-
- if (!index_printed) {
- index_printed = 1;
- if (indexes > 0) /* currently a no-op */
- printf("\n");
- indexes++;
- printf(" "
- "mask: 0x%02x 0x%08x/0x%04x -> 0x%08x/0x%04x\n",
- fs->flow_mask.proto,
- fs->flow_mask.src_ip, fs->flow_mask.src_port,
- fs->flow_mask.dst_ip, fs->flow_mask.dst_port);
-
- printf("BKT Prot ___Source IP/port____ "
- "____Dest. IP/port____ "
- "Tot_pkt/bytes Pkt/Byte Drp\n");
- }
-
- printf("%3d ", q[l].hash_slot);
- pe = getprotobynumber(q[l].id.proto);
+ printf("%3u%c", (ni->oid.id) & 0xff,
+ id->extra ? '*' : ' ');
+ if (!IS_IP6_FLOW_ID(id)) {
if (pe)
printf("%-4s ", pe->p_name);
else
- printf("%4u ", q[l].id.proto);
- ina.s_addr = htonl(q[l].id.src_ip);
+ printf("%4u ", id->proto);
+ ina.s_addr = htonl(id->src_ip);
printf("%15s/%-5d ",
- inet_ntoa(ina), q[l].id.src_port);
- ina.s_addr = htonl(q[l].id.dst_ip);
+ inet_ntoa(ina), id->src_port);
+ ina.s_addr = htonl(id->dst_ip);
printf("%15s/%-5d ",
- inet_ntoa(ina), q[l].id.dst_port);
- printf("%4llu %8llu %2u %4u %3u\n",
- align_uint64(&q[l].tot_pkts),
- align_uint64(&q[l].tot_bytes),
- q[l].len, q[l].len_bytes, q[l].drops);
- if (co.verbose)
- printf(" S %20llu F %20llu\n",
- align_uint64(&q[l].S), align_uint64(&q[l].F));
- }
-
- /* Print IPv6 flows */
- index_printed = 0;
- for (l = 0; l < fs->rq_elements; l++) {
- if (!IS_IP6_FLOW_ID(&(q[l].id)))
- continue;
-
- if (!index_printed) {
- index_printed = 1;
- if (indexes > 0)
- printf("\n");
- indexes++;
- printf("\n mask: proto: 0x%02x, flow_id: 0x%08x, ",
- fs->flow_mask.proto, fs->flow_mask.flow_id6);
- inet_ntop(AF_INET6, &(fs->flow_mask.src_ip6),
- buff, sizeof(buff));
- printf("%s/0x%04x -> ", buff, fs->flow_mask.src_port);
- inet_ntop( AF_INET6, &(fs->flow_mask.dst_ip6),
- buff, sizeof(buff) );
- printf("%s/0x%04x\n", buff, fs->flow_mask.dst_port);
-
- printf("BKT ___Prot___ _flow-id_ "
- "______________Source IPv6/port_______________ "
- "_______________Dest. IPv6/port_______________ "
- "Tot_pkt/bytes Pkt/Byte Drp\n");
- }
- printf("%3d ", q[l].hash_slot);
- pe = getprotobynumber(q[l].id.proto);
+ inet_ntoa(ina), id->dst_port);
+ } else {
+ /* Print IPv6 flows */
if (pe != NULL)
printf("%9s ", pe->p_name);
else
- printf("%9u ", q[l].id.proto);
- printf("%7d %39s/%-5d ", q[l].id.flow_id6,
- inet_ntop(AF_INET6, &(q[l].id.src_ip6), buff, sizeof(buff)),
- q[l].id.src_port);
+ printf("%9u ", id->proto);
+ printf("%7d %39s/%-5d ", id->flow_id6,
+ inet_ntop(AF_INET6, &(id->src_ip6), buff, sizeof(buff)),
+ id->src_port);
printf(" %39s/%-5d ",
- inet_ntop(AF_INET6, &(q[l].id.dst_ip6), buff, sizeof(buff)),
- q[l].id.dst_port);
- printf(" %4llu %8llu %2u %4u %3u\n",
- align_uint64(&q[l].tot_pkts),
- align_uint64(&q[l].tot_bytes),
- q[l].len, q[l].len_bytes, q[l].drops);
- if (co.verbose)
- printf(" S %20llu F %20llu\n",
- align_uint64(&q[l].S),
- align_uint64(&q[l].F));
+ inet_ntop(AF_INET6, &(id->dst_ip6), buff, sizeof(buff)),
+ id->dst_port);
}
+ printf("%4llu %8llu %2u %4u %3u\n",
+ align_uint64(&ni->tot_pkts),
+ align_uint64(&ni->tot_bytes),
+ ni->length, ni->len_bytes, ni->drops);
}
static void
-print_flowset_parms(struct dn_flow_set *fs, char *prefix)
+print_flowset_parms(struct dn_fs *fs, char *prefix)
{
int l;
char qs[30];
@@ -226,7 +218,7 @@ print_flowset_parms(struct dn_flow_set *
char red[90]; /* Display RED parameters */
l = fs->qsize;
- if (fs->flags_fs & DN_QSIZE_IS_BYTES) {
+ if (fs->flags & DN_QSIZE_BYTES) {
if (l >= 8192)
sprintf(qs, "%d KB", l / 1024);
else
@@ -237,23 +229,34 @@ print_flowset_parms(struct dn_flow_set *
sprintf(plr, "plr %f", 1.0 * fs->plr / (double)(0x7fffffff));
else
plr[0] = '\0';
- if (fs->flags_fs & DN_IS_RED) /* RED parameters */
+
+ if (fs->flags & DN_IS_RED) /* RED parameters */
sprintf(red,
"\n\t %cRED w_q %f min_th %d max_th %d max_p %f",
- (fs->flags_fs & DN_IS_GENTLE_RED) ? 'G' : ' ',
+ (fs->flags & DN_IS_GENTLE_RED) ? 'G' : ' ',
1.0 * fs->w_q / (double)(1 << SCALE_RED),
- SCALE_VAL(fs->min_th),
- SCALE_VAL(fs->max_th),
+ fs->min_th,
+ fs->max_th,
1.0 * fs->max_p / (double)(1 << SCALE_RED));
else
sprintf(red, "droptail");
- printf("%s %s%s %d queues (%d buckets) %s\n",
- prefix, qs, plr, fs->rq_elements, fs->rq_size, red);
+ if (prefix[0]) {
+ printf("%s %s%s %d queues (%d buckets) %s\n",
+ prefix, qs, plr, fs->oid.id, fs->buckets, red);
+ prefix[0] = '\0';
+ } else {
+ printf("q%05d %s%s %d flows (%d buckets) sched %d "
+ "weight %d lmax %d pri %d %s\n",
+ fs->fs_nr, qs, plr, fs->oid.id, fs->buckets,
+ fs->sched_nr, fs->par[0], fs->par[1], fs->par[2], red);
+ if (fs->flags & DN_HAVE_MASK)
+ print_mask(&fs->flow_mask);
+ }
}
static void
-print_extra_delay_parms(struct dn_pipe *p)
+print_extra_delay_parms(struct dn_profile *p)
{
double loss;
if (p->samples_no <= 0)
@@ -265,105 +268,126 @@ print_extra_delay_parms(struct dn_pipe *
p->name, loss, p->samples_no);
}
-void
-ipfw_list_pipes(void *data, uint nbytes, int ac, char *av[])
+static void
+flush_buf(char *buf)
{
- int rulenum;
- void *next = data;
- struct dn_pipe *p = (struct dn_pipe *) data;
- struct dn_flow_set *fs;
- struct dn_flow_queue *q;
- int l;
-
- if (ac > 0)
- rulenum = strtoul(*av++, NULL, 10);
- else
- rulenum = 0;
- for (; nbytes >= sizeof *p; p = (struct dn_pipe *)next) {
- double b = p->bandwidth;
- char buf[30];
- char prefix[80];
- char burst[5 + 7];
-
- if (SLIST_NEXT(p, next) != (struct dn_pipe *)DN_IS_PIPE)
- break; /* done with pipes, now queues */
-
- /*
- * compute length, as pipe have variable size
- */
- l = sizeof(*p) + p->fs.rq_elements * sizeof(*q);
- next = (char *)p + l;
- nbytes -= l;
-
- if ((rulenum != 0 && rulenum != p->pipe_nr) || co.do_pipe == 2)
- continue;
-
- /*
- * Print rate (or clocking interface)
- */
- if (p->if_name[0] != '\0')
- sprintf(buf, "%s", p->if_name);
- else if (b == 0)
- sprintf(buf, "unlimited");
- else if (b >= 1000000)
- sprintf(buf, "%7.3f Mbit/s", b/1000000);
- else if (b >= 1000)
- sprintf(buf, "%7.3f Kbit/s", b/1000);
- else
- sprintf(buf, "%7.3f bit/s ", b);
-
- sprintf(prefix, "%05d: %s %4d ms ",
- p->pipe_nr, buf, p->delay);
-
- print_flowset_parms(&(p->fs), prefix);
-
- if (humanize_number(burst, sizeof(burst), p->burst,
- "Byte", HN_AUTOSCALE, 0) < 0 || co.verbose)
- printf("\t burst: %ju Byte\n", p->burst);
- else
- printf("\t burst: %s\n", burst);
-
- print_extra_delay_parms(p);
-
- q = (struct dn_flow_queue *)(p+1);
- list_queues(&(p->fs), q);
- }
- for (fs = next; nbytes >= sizeof *fs; fs = next) {
- char prefix[80];
+ if (buf[0])
+ printf("%s\n", buf);
+ buf[0] = '\0';
+}
+
+/*
+ * generic list routine. We expect objects in a specific order, i.e.
+ * PIPES AND SCHEDULERS:
+ * link; scheduler; internal flowset if any; instances
+ * we can tell a pipe from the number.
+ *
+ * FLOWSETS:
+ * flowset; queues;
+ * link i (int queue); scheduler i; si(i) { flowsets() : queues }
+ */
+static void
+list_pipes(struct dn_id *oid, struct dn_id *end)
+{
+ char buf[160]; /* pending buffer */
+ buf[0] = '\0';
- if (SLIST_NEXT(fs, next) != (struct dn_flow_set *)DN_IS_QUEUE)
- break;
- l = sizeof(*fs) + fs->rq_elements * sizeof(*q);
- next = (char *)fs + l;
- nbytes -= l;
+ for (; oid != end; oid = O_NEXT(oid, oid->len)) {
+ if (oid->len < sizeof(*oid))
+ errx(1, "invalid oid len %d\n", oid->len);
+
+ switch (oid->type) {
+ default:
+ flush_buf(buf);
+ printf("unrecognized object %d size %d\n", oid->type, oid->len);
+ break;
+ case DN_TEXT: /* list of attached flowsets */
+ {
+ int i, l;
+ struct {
+ struct dn_id id;
+ uint32_t p[0];
+ } *d = (void *)oid;
+ l = (oid->len - sizeof(*oid))/sizeof(d->p[0]);
+ if (l == 0)
+ break;
+ printf(" Children flowsets: ");
+ for (i = 0; i < l; i++)
+ printf("%u ", d->p[i]);
+ printf("\n");
+ break;
+ }
+ case DN_CMD_GET:
+ if (co.verbose)
+ printf("answer for cmd %d, len %d\n", oid->type, oid->id);
+ break;
+ case DN_SCH: {
+ struct dn_sch *s = (struct dn_sch *)oid;
+ flush_buf(buf);
+ printf(" sched %d type %s flags 0x%x %d buckets %d active\n",
+ s->sched_nr,
+ s->name, s->flags, s->buckets, s->oid.id);
+ if (s->flags & DN_HAVE_MASK)
+ print_mask(&s->sched_mask);
+ }
+ break;
- if (rulenum != 0 && ((rulenum != fs->fs_nr && co.do_pipe == 2) ||
- (rulenum != fs->parent_nr && co.do_pipe == 1))) {
- continue;
- }
+ case DN_FLOW:
+ list_flow((struct dn_flow *)oid);
+ break;
+
+ case DN_LINK: {
+ struct dn_link *p = (struct dn_link *)oid;
+ double b = p->bandwidth;
+ char bwbuf[30];
+ char burst[5 + 7];
+
+ /* This starts a new object so flush buffer */
+ flush_buf(buf);
+ /* data rate */
+ if (b == 0)
+ sprintf(bwbuf, "unlimited ");
+ else if (b >= 1000000)
+ sprintf(bwbuf, "%7.3f Mbit/s", b/1000000);
+ else if (b >= 1000)
+ sprintf(bwbuf, "%7.3f Kbit/s", b/1000);
+ else
+ sprintf(bwbuf, "%7.3f bit/s ", b);
+
+ if (humanize_number(burst, sizeof(burst), p->burst,
+ "", HN_AUTOSCALE, 0) < 0 || co.verbose)
+ sprintf(burst, "%d", (int)p->burst);
+ sprintf(buf, "%05d: %s %4d ms burst %s",
+ p->link_nr % DN_MAX_ID, bwbuf, p->delay, burst);
+ }
+ break;
- q = (struct dn_flow_queue *)(fs+1);
- sprintf(prefix, "q%05d: weight %d pipe %d ",
- fs->fs_nr, fs->weight, fs->parent_nr);
- print_flowset_parms(fs, prefix);
- list_queues(fs, q);
+ case DN_FS:
+ print_flowset_parms((struct dn_fs *)oid, buf);
+ break;
+ case DN_PROFILE:
+ flush_buf(buf);
+ print_extra_delay_parms((struct dn_profile *)oid);
}
+ flush_buf(buf); // XXX does it really go here ?
+ }
}
/*
- * Delete pipe or queue i
+ * Delete pipe, queue or scheduler i
*/
int
-ipfw_delete_pipe(int pipe_or_queue, int i)
+ipfw_delete_pipe(int do_pipe, int i)
{
- struct dn_pipe p;
-
- memset(&p, 0, sizeof p);
- if (pipe_or_queue == 1)
- p.pipe_nr = i; /* pipe */
- else
- p.fs.fs_nr = i; /* queue */
- i = do_cmd(IP_DUMMYNET_DEL, &p, sizeof p);
+ struct {
+ struct dn_id oid;
+ uintptr_t a[1]; /* add more if we want a list */
+ } cmd;
+ oid_fill((void *)&cmd, sizeof(cmd), DN_CMD_DELETE, DN_API_VERSION);
+ cmd.oid.subtype = (do_pipe == 1) ? DN_LINK :
+ ( (do_pipe == 2) ? DN_FS : DN_SCH);
+ cmd.a[0] = i;
+ i = do_cmd(IP_DUMMYNET3, &cmd, cmd.oid.len);
if (i) {
i = 1;
warn("rule %u: setsockopt(IP_DUMMYNET_DEL)", i);
@@ -400,7 +424,7 @@ ipfw_delete_pipe(int pipe_or_queue, int
* The empirical curve may have both vertical and horizontal lines.
* Vertical lines represent constant delay for a range of
* probabilities; horizontal lines correspond to a discontinuty
- * in the delay distribution: the pipe will use the largest delay
+ * in the delay distribution: the link will use the largest delay
* for a given probability.
*
* To pass the curve to dummynet, we must store the parameters
@@ -490,9 +514,12 @@ static void
read_bandwidth(char *arg, int *bandwidth, char *if_name, int namelen)
{
if (*bandwidth != -1)
- warn("duplicate token, override bandwidth value!");
+ warnx("duplicate token, override bandwidth value!");
if (arg[0] >= 'a' && arg[0] <= 'z') {
+ if (!if_name) {
+ errx(1, "no if support");
+ }
if (namelen >= IFNAMSIZ)
warn("interface name truncated");
namelen--;
@@ -508,7 +535,7 @@ read_bandwidth(char *arg, int *bandwidth
if (*end == 'K' || *end == 'k') {
end++;
bw *= 1000;
- } else if (*end == 'M') {
+ } else if (*end == 'M' || *end == 'm') {
end++;
bw *= 1000000;
}
@@ -521,7 +548,8 @@ read_bandwidth(char *arg, int *bandwidth
errx(EX_DATAERR, "bandwidth too large");
*bandwidth = bw;
- if_name[0] = '\0';
+ if (if_name)
+ if_name[0] = '\0';
}
}
@@ -551,7 +579,8 @@ compare_points(const void *vp1, const vo
#define ED_EFMT(s) EX_DATAERR,"error in %s at line %d: "#s,filename,lineno
static void
-load_extra_delays(const char *filename, struct dn_pipe *p)
+load_extra_delays(const char *filename, struct dn_profile *p,
+ struct dn_link *link)
{
char line[ED_MAX_LINE_LEN];
FILE *f;
@@ -566,6 +595,9 @@ load_extra_delays(const char *filename,
struct point points[ED_MAX_SAMPLES_NO];
int points_no = 0;
+ /* XXX link never NULL? */
+ p->link_nr = link->link_nr;
+
profile_name[0] = '\0';
f = fopen(filename, "r");
if (f == NULL)
@@ -606,7 +638,8 @@ load_extra_delays(const char *filename,
ED_MAX_SAMPLES_NO);
do_points = 0;
} else if (!strcasecmp(name, ED_TOK_BW)) {
- read_bandwidth(arg, &p->bandwidth, p->if_name, sizeof(p->if_name));
+ char buf[IFNAMSIZ];
+ read_bandwidth(arg, &link->bandwidth, buf, sizeof(buf));
} else if (!strcasecmp(name, ED_TOK_LOSS)) {
if (loss != -1.0)
errx(ED_EFMT("duplicated token: %s"), name);
@@ -676,17 +709,17 @@ load_extra_delays(const char *filename,
double y2 = points[i+1].prob * samples;
double x2 = points[i+1].delay;
- int index = y1;
+ int ix = y1;
int stop = y2;
if (x1 == x2) {
- for (; index<stop; ++index)
- p->samples[index] = x1;
+ for (; ix<stop; ++ix)
+ p->samples[ix] = x1;
} else {
double m = (y2-y1)/(x2-x1);
double c = y1 - m*x1;
- for (; index<stop ; ++index)
- p->samples[index] = (index - c)/m;
+ for (; ix<stop ; ++ix)
+ p->samples[ix] = (ix - c)/m;
}
}
p->samples_no = samples;
@@ -694,27 +727,120 @@ load_extra_delays(const char *filename,
strncpy(p->name, profile_name, sizeof(p->name));
}
+/*
+ * configuration of pipes, schedulers, flowsets.
+ * When we configure a new scheduler, an empty pipe is created, so:
+ *
+ * do_pipe = 1 -> "pipe N config ..." only for backward compatibility
+ * sched N+Delta type fifo sched_mask ...
+ * pipe N+Delta <parameters>
+ * flowset N+Delta pipe N+Delta (no parameters)
+ * sched N type wf2q+ sched_mask ...
+ * pipe N <parameters>
+ *
+ * do_pipe = 2 -> flowset N config
+ * flowset N parameters
+ *
+ * do_pipe = 3 -> sched N config
+ * sched N parameters (default no pipe)
+ * optional Pipe N config ...
+ * pipe ==>
+ */
void
ipfw_config_pipe(int ac, char **av)
{
- int samples[ED_MAX_SAMPLES_NO];
- struct dn_pipe p;
- int i;
+ int i, j;
char *end;
void *par = NULL;
-
- memset(&p, 0, sizeof p);
- p.bandwidth = -1;
+ struct dn_id *buf, *base;
+ struct dn_sch *sch = NULL;
+ struct dn_link *p = NULL;
+ struct dn_fs *fs = NULL;
+ struct dn_profile *pf = NULL;
+ struct ipfw_flow_id *mask = NULL;
+ int lmax;
+ uint32_t _foo = 0, *flags = &_foo , *buckets = &_foo;
+
+ /*
+ * allocate space for 1 header,
+ * 1 scheduler, 1 link, 1 flowset, 1 profile
+ */
+ lmax = sizeof(struct dn_id); /* command header */
+ lmax += sizeof(struct dn_sch) + sizeof(struct dn_link) +
+ sizeof(struct dn_fs) + sizeof(struct dn_profile);
av++; ac--;
/* Pipe number */
if (ac && isdigit(**av)) {
i = atoi(*av); av++; ac--;
- if (co.do_pipe == 1)
- p.pipe_nr = i;
- else
- p.fs.fs_nr = i;
+ } else
+ i = -1;
+ if (i <= 0)
+ errx(EX_USAGE, "need a pipe/flowset/sched number");
+ base = buf = safe_calloc(1, lmax);
+ /* all commands start with a 'CONFIGURE' and a version */
+ o_next(&buf, sizeof(struct dn_id), DN_CMD_CONFIG);
+ base->id = DN_API_VERSION;
+
+ switch (co.do_pipe) {
+ case 1: /* "pipe N config ..." */
+ /* Allocate space for the WF2Q+ scheduler, its link
+ * and the FIFO flowset. Set the number, but leave
+ * the scheduler subtype and other parameters to 0
+ * so the kernel will use appropriate defaults.
+ * XXX todo: add a flag to record if a parameter
+ * is actually configured.
+ * If we do a 'pipe config' mask -> sched_mask.
+ * The FIFO scheduler and link are derived from the
+ * WF2Q+ one in the kernel.
+ */
+ sch = o_next(&buf, sizeof(*sch), DN_SCH);
+ p = o_next(&buf, sizeof(*p), DN_LINK);
+ fs = o_next(&buf, sizeof(*fs), DN_FS);
+
+ sch->sched_nr = i;
+ sch->oid.subtype = 0; /* defaults to WF2Q+ */
+ mask = &sch->sched_mask;
+ flags = &sch->flags;
+ buckets = &sch->buckets;
+ *flags |= DN_PIPE_CMD;
+
+ p->link_nr = i;
+
+ /* This flowset is only for the FIFO scheduler */
+ fs->fs_nr = i + 2*DN_MAX_ID;
+ fs->sched_nr = i + DN_MAX_ID;
+ break;
+
+ case 2: /* "queue N config ... " */
+ fs = o_next(&buf, sizeof(*fs), DN_FS);
+ fs->fs_nr = i;
+ mask = &fs->flow_mask;
+ flags = &fs->flags;
+ buckets = &fs->buckets;
+ break;
+
+ case 3: /* "sched N config ..." */
+ sch = o_next(&buf, sizeof(*sch), DN_SCH);
+ fs = o_next(&buf, sizeof(*fs), DN_FS);
+ sch->sched_nr = i;
+ mask = &sch->sched_mask;
+ flags = &sch->flags;
+ buckets = &sch->buckets;
+ /* fs is used only with !MULTIQUEUE schedulers */
+ fs->fs_nr = i + DN_MAX_ID;
+ fs->sched_nr = i;
+ break;
}
+ /* set to -1 those fields for which we want to reuse existing
+ * values from the kernel.
+ * Also, *_nr and subtype = 0 mean reuse the value from the kernel.
+ * XXX todo: support reuse of the mask.
+ */
+ if (p)
+ p->bandwidth = -1;
+ for (j = 0; j < sizeof(fs->par)/sizeof(fs->par[0]); j++)
+ fs->par[j] = -1;
while (ac > 0) {
double d;
int tok = match_token(dummynet_params, *av);
@@ -722,41 +848,48 @@ ipfw_config_pipe(int ac, char **av)
switch(tok) {
case TOK_NOERROR:
- p.fs.flags_fs |= DN_NOERROR;
+ NEED(fs, "noerror is only for pipes");
+ fs->flags |= DN_NOERROR;
break;
case TOK_PLR:
+ NEED(fs, "plr is only for pipes");
NEED1("plr needs argument 0..1\n");
d = strtod(av[0], NULL);
if (d > 1)
d = 1;
else if (d < 0)
d = 0;
- p.fs.plr = (int)(d*0x7fffffff);
+ fs->plr = (int)(d*0x7fffffff);
ac--; av++;
break;
case TOK_QUEUE:
+ NEED(fs, "queue is only for pipes or flowsets");
NEED1("queue needs queue size\n");
end = NULL;
- p.fs.qsize = strtoul(av[0], &end, 0);
+ fs->qsize = strtoul(av[0], &end, 0);
if (*end == 'K' || *end == 'k') {
- p.fs.flags_fs |= DN_QSIZE_IS_BYTES;
- p.fs.qsize *= 1024;
+ fs->flags |= DN_QSIZE_BYTES;
+ fs->qsize *= 1024;
} else if (*end == 'B' ||
_substrcmp2(end, "by", "bytes") == 0) {
- p.fs.flags_fs |= DN_QSIZE_IS_BYTES;
+ fs->flags |= DN_QSIZE_BYTES;
}
ac--; av++;
break;
case TOK_BUCKETS:
+ NEED(fs, "buckets is only for pipes or flowsets");
NEED1("buckets needs argument\n");
- p.fs.rq_size = strtoul(av[0], NULL, 0);
+ *buckets = strtoul(av[0], NULL, 0);
ac--; av++;
break;
+ case TOK_FLOW_MASK:
+ case TOK_SCHED_MASK:
case TOK_MASK:
+ NEED(mask, "tok_mask");
NEED1("mask needs mask specifier\n");
/*
* per-flow queue, mask is dst_ip, dst_port,
@@ -764,7 +897,7 @@ ipfw_config_pipe(int ac, char **av)
*/
par = NULL;
- bzero(&p.fs.flow_mask, sizeof(p.fs.flow_mask));
+ bzero(mask, sizeof(*mask));
end = NULL;
while (ac >= 1) {
@@ -780,44 +913,55 @@ ipfw_config_pipe(int ac, char **av)
case TOK_ALL:
/*
* special case, all bits significant
+ * except 'extra' (the queue number)
*/
- p.fs.flow_mask.dst_ip = ~0;
- p.fs.flow_mask.src_ip = ~0;
- p.fs.flow_mask.dst_port = ~0;
- p.fs.flow_mask.src_port = ~0;
- p.fs.flow_mask.proto = ~0;
- n2mask(&(p.fs.flow_mask.dst_ip6), 128);
- n2mask(&(p.fs.flow_mask.src_ip6), 128);
- p.fs.flow_mask.flow_id6 = ~0;
- p.fs.flags_fs |= DN_HAVE_FLOW_MASK;
+ mask->dst_ip = ~0;
+ mask->src_ip = ~0;
+ mask->dst_port = ~0;
+ mask->src_port = ~0;
+ mask->proto = ~0;
+ n2mask(&mask->dst_ip6, 128);
+ n2mask(&mask->src_ip6, 128);
+ mask->flow_id6 = ~0;
+ *flags |= DN_HAVE_MASK;
+ goto end_mask;
+
+ case TOK_QUEUE:
+ mask->extra = ~0;
+ *flags |= DN_HAVE_MASK;
goto end_mask;
case TOK_DSTIP:
- p32 = &p.fs.flow_mask.dst_ip;
+ mask->addr_type = 4;
+ p32 = &mask->dst_ip;
break;
case TOK_SRCIP:
- p32 = &p.fs.flow_mask.src_ip;
+ mask->addr_type = 4;
+ p32 = &mask->src_ip;
break;
case TOK_DSTIP6:
- pa6 = &(p.fs.flow_mask.dst_ip6);
+ mask->addr_type = 6;
+ pa6 = &mask->dst_ip6;
break;
case TOK_SRCIP6:
- pa6 = &(p.fs.flow_mask.src_ip6);
+ mask->addr_type = 6;
+ pa6 = &mask->src_ip6;
break;
case TOK_FLOWID:
- p20 = &p.fs.flow_mask.flow_id6;
+ mask->addr_type = 6;
+ p20 = &mask->flow_id6;
break;
case TOK_DSTPORT:
- p16 = &p.fs.flow_mask.dst_port;
+ p16 = &mask->dst_port;
break;
case TOK_SRCPORT:
- p16 = &p.fs.flow_mask.src_port;
+ p16 = &mask->src_port;
break;
case TOK_PROTO:
@@ -857,10 +1001,10 @@ ipfw_config_pipe(int ac, char **av)
if (a > 0xFF)
errx(EX_DATAERR,
"proto mask must be 8 bit");
- p.fs.flow_mask.proto = (uint8_t)a;
+ mask->proto = (uint8_t)a;
}
if (a != 0)
- p.fs.flags_fs |= DN_HAVE_FLOW_MASK;
+ *flags |= DN_HAVE_MASK;
ac--; av++;
} /* end while, config masks */
end_mask:
@@ -869,9 +1013,9 @@ end_mask:
case TOK_RED:
case TOK_GRED:
NEED1("red/gred needs w_q/min_th/max_th/max_p\n");
- p.fs.flags_fs |= DN_IS_RED;
+ fs->flags |= DN_IS_RED;
if (tok == TOK_GRED)
- p.fs.flags_fs |= DN_IS_GENTLE_RED;
+ fs->flags |= DN_IS_GENTLE_RED;
/*
* the format for parameters is w_q/min_th/max_th/max_p
*/
@@ -879,82 +1023,108 @@ end_mask:
double w_q = strtod(end, NULL);
if (w_q > 1 || w_q <= 0)
errx(EX_DATAERR, "0 < w_q <= 1");
- p.fs.w_q = (int) (w_q * (1 << SCALE_RED));
+ fs->w_q = (int) (w_q * (1 << SCALE_RED));
}
if ((end = strsep(&av[0], "/"))) {
- p.fs.min_th = strtoul(end, &end, 0);
+ fs->min_th = strtoul(end, &end, 0);
if (*end == 'K' || *end == 'k')
- p.fs.min_th *= 1024;
+ fs->min_th *= 1024;
}
if ((end = strsep(&av[0], "/"))) {
- p.fs.max_th = strtoul(end, &end, 0);
+ fs->max_th = strtoul(end, &end, 0);
if (*end == 'K' || *end == 'k')
- p.fs.max_th *= 1024;
+ fs->max_th *= 1024;
}
if ((end = strsep(&av[0], "/"))) {
double max_p = strtod(end, NULL);
if (max_p > 1 || max_p <= 0)
errx(EX_DATAERR, "0 < max_p <= 1");
- p.fs.max_p = (int)(max_p * (1 << SCALE_RED));
+ fs->max_p = (int)(max_p * (1 << SCALE_RED));
}
ac--; av++;
break;
case TOK_DROPTAIL:
- p.fs.flags_fs &= ~(DN_IS_RED|DN_IS_GENTLE_RED);
+ NEED(fs, "droptail is only for flowsets");
+ fs->flags &= ~(DN_IS_RED|DN_IS_GENTLE_RED);
break;
case TOK_BW:
+ NEED(p, "bw is only for links");
NEED1("bw needs bandwidth or interface\n");
- if (co.do_pipe != 1)
- errx(EX_DATAERR, "bandwidth only valid for pipes");
- read_bandwidth(av[0], &p.bandwidth, p.if_name, sizeof(p.if_name));
+ read_bandwidth(av[0], &p->bandwidth, NULL, 0);
ac--; av++;
break;
case TOK_DELAY:
- if (co.do_pipe != 1)
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list