From d8b883c348e5efda3dfafad3a4eae37ce3dfc917 Mon Sep 17 00:00:00 2001 From: Dave Taht Date: Fri, 12 Jun 2015 19:16:28 -0700 Subject: [PATCH] nuke my copy of iproute2 --- net/iproute2/Makefile | 93 - net/iproute2/files/15-teql | 23 - net/iproute2/patches/001-config.patch | 7 - net/iproute2/patches/004-darwin_fixes.patch | 59 - net/iproute2/patches/006-no_sctp.patch | 18 - net/iproute2/patches/007-no_arpd.patch | 11 - net/iproute2/patches/010-type_fixes.patch | 396 --- .../patches/100-allow_pfifo_fast.patch | 9 - net/iproute2/patches/110-extra-ccopts.patch | 11 - net/iproute2/patches/120-libnetlink-pic.patch | 11 - .../patches/130-missing_include.patch | 10 - net/iproute2/patches/200-add-tc_esfq.patch | 249 -- .../patches/210-add-act_connmark.patch | 87 - net/iproute2/patches/300-ip_tiny.patch | 101 - .../600-Add-alternate-queue-models.patch | 2143 ----------------- .../601-iproute2-add-fq_pie-support.patch | 488 ---- ...ible-buffer-overflow-when-print-clas.patch | 61 - ...x-compilation-warning-on-32bits-arch.patch | 35 - .../patches/900-drop_FAILED_POLICY.patch | 54 - .../910-sanitize_headers_for_musl.patch | 10 - 20 files changed, 3876 deletions(-) delete mode 100644 net/iproute2/Makefile delete mode 100644 net/iproute2/files/15-teql delete mode 100644 net/iproute2/patches/001-config.patch delete mode 100644 net/iproute2/patches/004-darwin_fixes.patch delete mode 100644 net/iproute2/patches/006-no_sctp.patch delete mode 100644 net/iproute2/patches/007-no_arpd.patch delete mode 100644 net/iproute2/patches/010-type_fixes.patch delete mode 100644 net/iproute2/patches/100-allow_pfifo_fast.patch delete mode 100644 net/iproute2/patches/110-extra-ccopts.patch delete mode 100644 net/iproute2/patches/120-libnetlink-pic.patch delete mode 100644 net/iproute2/patches/130-missing_include.patch delete mode 100644 net/iproute2/patches/200-add-tc_esfq.patch delete mode 100644 net/iproute2/patches/210-add-act_connmark.patch delete mode 100644 net/iproute2/patches/300-ip_tiny.patch delete mode 100644 net/iproute2/patches/600-Add-alternate-queue-models.patch delete mode 100644 net/iproute2/patches/601-iproute2-add-fq_pie-support.patch delete mode 100644 net/iproute2/patches/800-tc-util-Fix-possible-buffer-overflow-when-print-clas.patch delete mode 100644 net/iproute2/patches/801-tc-fix-compilation-warning-on-32bits-arch.patch delete mode 100644 net/iproute2/patches/900-drop_FAILED_POLICY.patch delete mode 100644 net/iproute2/patches/910-sanitize_headers_for_musl.patch diff --git a/net/iproute2/Makefile b/net/iproute2/Makefile deleted file mode 100644 index fb08e02..0000000 --- a/net/iproute2/Makefile +++ /dev/null @@ -1,93 +0,0 @@ -# -# Copyright (C) 2006-2015 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=tc-adv -PKG_VERSION:=4.1.0-git -PKG_RELEASE:=1 - -PKG_SOURCE_PROTO:=git -PKG_SOURCE_URL:=git://github.com/dtaht/tc-adv -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_SOURCE_VERSION:=4167c76d7f0601b34f46ed15e139b573fdeb6efe -PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) - -PKG_BUILD_PARALLEL:=1 -PKG_LICENSE:=GPL-2.0 - -# PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) - -include $(INCLUDE_DIR)/package.mk - -define Package/tc-adv/Default - TITLE:=Advanced bufferbloat qdisc tc control utility ($(2)) - SECTION:=net - CATEGORY:=Network - URL:=http://www.linuxfoundation.org/collaborate/workgroups/networking/iproute2 - SUBMENU:=Routing and Redirection - MAINTAINER:=Russell Senior - DEPENDS:= +libnl-tiny - VARIANT:=$(1) -endef - -define Package/tc-adv -$(call Package/tc-adv/Default) - TITLE:=Traffic control utility with support for cake and fq_pie - DEPENDS:=+kmod-sched-core +kmod-sched-cake +kmod-sched-fq_pie -endef - -ifeq ($(BUILD_VARIANT),tiny) - IP_CONFIG_TINY:=y -endif - -define Build/Configure - $(SED) "s,-I/usr/include/db3,," $(PKG_BUILD_DIR)/Makefile - $(SED) "s,^KERNEL_INCLUDE.*,KERNEL_INCLUDE=$(LINUX_DIR)/include," \ - $(PKG_BUILD_DIR)/Makefile - $(SED) "s,^LIBC_INCLUDE.*,LIBC_INCLUDE=$(STAGING_DIR)/include," \ - $(PKG_BUILD_DIR)/Makefile - echo "static const char SNAPSHOT[] = \"$(PKG_VERSION)-$(PKG_RELEASE)-openwrt\";" \ - > $(PKG_BUILD_DIR)/include/SNAPSHOT.h -endef - -ifdef CONFIG_USE_GLIBC - TARGET_CFLAGS += -DHAVE_SETNS -endif -ifdef CONFIG_USE_MUSL - TARGET_CFLAGS += -DHAVE_SETNS -endif - -TARGET_CFLAGS += -ffunction-sections -fdata-sections - -MAKE_FLAGS += \ - EXTRA_CCOPTS="$(TARGET_CFLAGS) -I../include -I$(STAGING_DIR)/usr/include/libnl-tiny" \ - KERNEL_INCLUDE="$(LINUX_DIR)/include" \ - SHARED_LIBS="" \ - LDFLAGS="-Wl,--gc-sections" \ - IP_CONFIG_TINY=$(IP_CONFIG_TINY) \ - FPIC="$(FPIC)" - -define Build/Compile - +$(MAKE_VARS) $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) $(MAKE_FLAGS) -endef - -define Build/InstallDev - $(INSTALL_DIR) $(1)/usr/include - $(CP) $(PKG_BUILD_DIR)/include/libnetlink.h $(1)/usr/include/ - $(INSTALL_DIR) $(1)/usr/lib - $(CP) $(PKG_BUILD_DIR)/lib/libnetlink.a $(1)/usr/lib/ -endef - -define Package/tc-adv/install - $(INSTALL_DIR) $(1)/usr/sbin - $(INSTALL_BIN) $(PKG_BUILD_DIR)/tc/tc $(1)/usr/sbin/ - $(INSTALL_DIR) $(1)/etc/hotplug.d/iface - $(INSTALL_BIN) ./files/15-teql $(1)/etc/hotplug.d/iface/ -endef - -$(eval $(call BuildPackage,tc-adv)) diff --git a/net/iproute2/files/15-teql b/net/iproute2/files/15-teql deleted file mode 100644 index a0c0e50..0000000 --- a/net/iproute2/files/15-teql +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh - -. /lib/functions.sh - -if [ "$ACTION" != "ifup" ]; then - exit -fi - -config_load network - -config_get teql $INTERFACE teql - -if [ "$teql" != "" ]; then - logger Adding device $DEVICE to TEQL master $teql - insmod sch_teql - tc qdisc add dev $DEVICE root $teql - - # The kernel doesn't let us bring it up until it has at least one - # slave. So bring it up now, if it isn't already. - if ! cat /sys/class/net/$teql/carrier &>/dev/null; then - ifup $teql & - fi -fi diff --git a/net/iproute2/patches/001-config.patch b/net/iproute2/patches/001-config.patch deleted file mode 100644 index ece8652..0000000 --- a/net/iproute2/patches/001-config.patch +++ /dev/null @@ -1,7 +0,0 @@ ---- /dev/null -+++ b/Config -@@ -0,0 +1,4 @@ -+# Fixed config to disable ATM support even if present on host system -+TC_CONFIG_ATM:=n -+TC_CONFIG_ACTION_GACT=y -+TC_CONFIG_ACTION_PROB=y diff --git a/net/iproute2/patches/004-darwin_fixes.patch b/net/iproute2/patches/004-darwin_fixes.patch deleted file mode 100644 index e1a5e97..0000000 --- a/net/iproute2/patches/004-darwin_fixes.patch +++ /dev/null @@ -1,59 +0,0 @@ ---- a/netem/maketable.c -+++ b/netem/maketable.c -@@ -10,7 +10,9 @@ - #include - #include - #include -+#if !defined(__APPLE__) && !defined(__FreeBSD__) - #include -+#endif - #include - #include - #include ---- a/netem/normal.c -+++ b/netem/normal.c -@@ -8,8 +8,12 @@ - #include - #include - -+#if !defined(__APPLE__) && !defined(__FreeBSD__) - #include - #include -+#else -+#define NETEM_DIST_SCALE 8192 -+#endif - - #define TABLESIZE 16384 - #define TABLEFACTOR NETEM_DIST_SCALE ---- a/netem/pareto.c -+++ b/netem/pareto.c -@@ -7,8 +7,12 @@ - #include - #include - -+#if !defined(__APPLE__) && !defined(__FreeBSD__) - #include - #include -+#else -+#define NETEM_DIST_SCALE 8192 -+#endif - - static const double a=3.0; - #define TABLESIZE 16384 ---- a/netem/paretonormal.c -+++ b/netem/paretonormal.c -@@ -15,10 +15,13 @@ - #include - #include - #include -+#if !defined(__APPLE__) && !defined(__FreeBSD__) - #include -- - #include - #include -+#else -+#define NETEM_DIST_SCALE 8192 -+#endif - - #define TABLESIZE 16384 - #define TABLEFACTOR NETEM_DIST_SCALE diff --git a/net/iproute2/patches/006-no_sctp.patch b/net/iproute2/patches/006-no_sctp.patch deleted file mode 100644 index 4aa9884..0000000 --- a/net/iproute2/patches/006-no_sctp.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- a/ip/ipxfrm.c -+++ b/ip/ipxfrm.c -@@ -467,7 +467,6 @@ void xfrm_selector_print(struct xfrm_sel - switch (sel->proto) { - case IPPROTO_TCP: - case IPPROTO_UDP: -- case IPPROTO_SCTP: - case IPPROTO_DCCP: - default: /* XXX */ - if (sel->sport_mask) -@@ -1337,7 +1336,6 @@ static int xfrm_selector_upspec_parse(st - switch (sel->proto) { - case IPPROTO_TCP: - case IPPROTO_UDP: -- case IPPROTO_SCTP: - case IPPROTO_DCCP: - break; - default: diff --git a/net/iproute2/patches/007-no_arpd.patch b/net/iproute2/patches/007-no_arpd.patch deleted file mode 100644 index 6a7e24e..0000000 --- a/net/iproute2/patches/007-no_arpd.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/misc/Makefile -+++ b/misc/Makefile -@@ -1,7 +1,7 @@ - SSOBJ=ss.o ssfilter.o - LNSTATOBJ=lnstat.o lnstat_util.o - --TARGETS=ss nstat ifstat rtacct arpd lnstat -+TARGETS=ss nstat ifstat rtacct lnstat - - include ../Config - diff --git a/net/iproute2/patches/010-type_fixes.patch b/net/iproute2/patches/010-type_fixes.patch deleted file mode 100644 index e0055fc..0000000 --- a/net/iproute2/patches/010-type_fixes.patch +++ /dev/null @@ -1,396 +0,0 @@ ---- a/include/iptables_common.h -+++ b/include/iptables_common.h -@@ -2,6 +2,8 @@ - #define _IPTABLES_COMMON_H - /* Shared definitions between ipv4 and ipv6. */ - -+#include -+ - enum exittype { - OTHER_PROBLEM = 1, - PARAMETER_PROBLEM, -@@ -43,9 +45,9 @@ extern char *lib_dir; - extern void init_extensions(void); - #endif - --#define __be32 u_int32_t --#define __le32 u_int32_t --#define __be16 u_int16_t --#define __le16 u_int16_t -+#define __be32 uint32_t -+#define __le32 uint32_t -+#define __be16 uint16_t -+#define __le16 uint16_t - - #endif /*_IPTABLES_COMMON_H*/ ---- a/include/netinet/tcp.h -+++ /dev/null -@@ -1,231 +0,0 @@ --/* -- * Copyright (c) 1982, 1986, 1993 -- * The Regents of the University of California. All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions -- * are met: -- * 1. Redistributions of source code must retain the above copyright -- * notice, this list of conditions and the following disclaimer. -- * 2. Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * 4. Neither the name of the University nor the names of its contributors -- * may be used to endorse or promote products derived from this software -- * without specific prior written permission. -- * -- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -- * SUCH DAMAGE. -- * -- * @(#)tcp.h 8.1 (Berkeley) 6/10/93 -- */ -- --#ifndef _NETINET_TCP_H --#define _NETINET_TCP_H 1 -- --#include -- --/* -- * User-settable options (used with setsockopt). -- */ --#define TCP_NODELAY 1 /* Don't delay send to coalesce packets */ --#define TCP_MAXSEG 2 /* Set maximum segment size */ --#define TCP_CORK 3 /* Control sending of partial frames */ --#define TCP_KEEPIDLE 4 /* Start keeplives after this period */ --#define TCP_KEEPINTVL 5 /* Interval between keepalives */ --#define TCP_KEEPCNT 6 /* Number of keepalives before death */ --#define TCP_SYNCNT 7 /* Number of SYN retransmits */ --#define TCP_LINGER2 8 /* Life time of orphaned FIN-WAIT-2 state */ --#define TCP_DEFER_ACCEPT 9 /* Wake up listener only when data arrive */ --#define TCP_WINDOW_CLAMP 10 /* Bound advertised window */ --#define TCP_INFO 11 /* Information about this connection. */ --#define TCP_QUICKACK 12 /* Bock/reenable quick ACKs. */ --#define TCP_CONGESTION 13 /* Congestion control algorithm. */ -- --#ifdef __USE_MISC --# include -- --# ifdef __FAVOR_BSD --typedef u_int32_t tcp_seq; --/* -- * TCP header. -- * Per RFC 793, September, 1981. -- */ --struct tcphdr -- { -- u_int16_t th_sport; /* source port */ -- u_int16_t th_dport; /* destination port */ -- tcp_seq th_seq; /* sequence number */ -- tcp_seq th_ack; /* acknowledgement number */ --# if __BYTE_ORDER == __LITTLE_ENDIAN -- u_int8_t th_x2:4; /* (unused) */ -- u_int8_t th_off:4; /* data offset */ --# endif --# if __BYTE_ORDER == __BIG_ENDIAN -- u_int8_t th_off:4; /* data offset */ -- u_int8_t th_x2:4; /* (unused) */ --# endif -- u_int8_t th_flags; --# define TH_FIN 0x01 --# define TH_SYN 0x02 --# define TH_RST 0x04 --# define TH_PUSH 0x08 --# define TH_ACK 0x10 --# define TH_URG 0x20 -- u_int16_t th_win; /* window */ -- u_int16_t th_sum; /* checksum */ -- u_int16_t th_urp; /* urgent pointer */ --}; -- --# else /* !__FAVOR_BSD */ --struct tcphdr -- { -- u_int16_t source; -- u_int16_t dest; -- u_int32_t seq; -- u_int32_t ack_seq; --# if __BYTE_ORDER == __LITTLE_ENDIAN -- u_int16_t res1:4; -- u_int16_t doff:4; -- u_int16_t fin:1; -- u_int16_t syn:1; -- u_int16_t rst:1; -- u_int16_t psh:1; -- u_int16_t ack:1; -- u_int16_t urg:1; -- u_int16_t res2:2; --# elif __BYTE_ORDER == __BIG_ENDIAN -- u_int16_t doff:4; -- u_int16_t res1:4; -- u_int16_t res2:2; -- u_int16_t urg:1; -- u_int16_t ack:1; -- u_int16_t psh:1; -- u_int16_t rst:1; -- u_int16_t syn:1; -- u_int16_t fin:1; --# else --# error "Adjust your defines" --# endif -- u_int16_t window; -- u_int16_t check; -- u_int16_t urg_ptr; --}; --# endif /* __FAVOR_BSD */ -- --enum --{ -- TCP_ESTABLISHED = 1, -- TCP_SYN_SENT, -- TCP_SYN_RECV, -- TCP_FIN_WAIT1, -- TCP_FIN_WAIT2, -- TCP_TIME_WAIT, -- TCP_CLOSE, -- TCP_CLOSE_WAIT, -- TCP_LAST_ACK, -- TCP_LISTEN, -- TCP_CLOSING /* now a valid state */ --}; -- --# define TCPOPT_EOL 0 --# define TCPOPT_NOP 1 --# define TCPOPT_MAXSEG 2 --# define TCPOLEN_MAXSEG 4 --# define TCPOPT_WINDOW 3 --# define TCPOLEN_WINDOW 3 --# define TCPOPT_SACK_PERMITTED 4 /* Experimental */ --# define TCPOLEN_SACK_PERMITTED 2 --# define TCPOPT_SACK 5 /* Experimental */ --# define TCPOPT_TIMESTAMP 8 --# define TCPOLEN_TIMESTAMP 10 --# define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */ -- --# define TCPOPT_TSTAMP_HDR \ -- (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP) -- --/* -- * Default maximum segment size for TCP. -- * With an IP MSS of 576, this is 536, -- * but 512 is probably more convenient. -- * This should be defined as MIN(512, IP_MSS - sizeof (struct tcpiphdr)). -- */ --# define TCP_MSS 512 -- --# define TCP_MAXWIN 65535 /* largest value for (unscaled) window */ -- --# define TCP_MAX_WINSHIFT 14 /* maximum window shift */ -- --# define SOL_TCP 6 /* TCP level */ -- -- --# define TCPI_OPT_TIMESTAMPS 1 --# define TCPI_OPT_SACK 2 --# define TCPI_OPT_WSCALE 4 --# define TCPI_OPT_ECN 8 --# define TCPI_OPT_ECN_SEEN 16 -- --/* Values for tcpi_state. */ --enum tcp_ca_state --{ -- TCP_CA_Open = 0, -- TCP_CA_Disorder = 1, -- TCP_CA_CWR = 2, -- TCP_CA_Recovery = 3, -- TCP_CA_Loss = 4 --}; -- --struct tcp_info --{ -- u_int8_t tcpi_state; -- u_int8_t tcpi_ca_state; -- u_int8_t tcpi_retransmits; -- u_int8_t tcpi_probes; -- u_int8_t tcpi_backoff; -- u_int8_t tcpi_options; -- u_int8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4; -- -- u_int32_t tcpi_rto; -- u_int32_t tcpi_ato; -- u_int32_t tcpi_snd_mss; -- u_int32_t tcpi_rcv_mss; -- -- u_int32_t tcpi_unacked; -- u_int32_t tcpi_sacked; -- u_int32_t tcpi_lost; -- u_int32_t tcpi_retrans; -- u_int32_t tcpi_fackets; -- -- /* Times. */ -- u_int32_t tcpi_last_data_sent; -- u_int32_t tcpi_last_ack_sent; /* Not remembered, sorry. */ -- u_int32_t tcpi_last_data_recv; -- u_int32_t tcpi_last_ack_recv; -- -- /* Metrics. */ -- u_int32_t tcpi_pmtu; -- u_int32_t tcpi_rcv_ssthresh; -- u_int32_t tcpi_rtt; -- u_int32_t tcpi_rttvar; -- u_int32_t tcpi_snd_ssthresh; -- u_int32_t tcpi_snd_cwnd; -- u_int32_t tcpi_advmss; -- u_int32_t tcpi_reordering; -- u_int32_t tcpi_rcv_rtt; -- u_int32_t tcpi_rcv_space; -- u_int32_t tcpi_total_retrans; -- --}; -- --#endif /* Misc. */ -- --#endif /* netinet/tcp.h */ ---- a/include/iptables.h -+++ b/include/iptables.h -@@ -20,7 +20,7 @@ struct ipt_get_revision - { - char name[IPT_FUNCTION_MAXNAMELEN-1]; - -- u_int8_t revision; -+ uint8_t revision; - }; - #endif /* IPT_SO_GET_REVISION_MATCH Old kernel source */ - -@@ -39,7 +39,7 @@ struct iptables_match - ipt_chainlabel name; - - /* Revision of match (0 by default). */ -- u_int8_t revision; -+ uint8_t revision; - - const char *version; - -@@ -92,7 +92,7 @@ struct iptables_target - ipt_chainlabel name; - - /* Revision of target (0 by default). */ -- u_int8_t revision; -+ uint8_t revision; - - const char *version; - -@@ -153,7 +153,7 @@ extern char *mask_to_dotted(const struct - - extern void parse_hostnetworkmask(const char *name, struct in_addr **addrpp, - struct in_addr *maskp, unsigned int *naddrs); --extern u_int16_t parse_protocol(const char *s); -+extern uint16_t parse_protocol(const char *s); - - extern int do_command(int argc, char *argv[], char **table, - iptc_handle_t *handle); ---- a/lib/dnet_ntop.c -+++ b/lib/dnet_ntop.c -@@ -1,24 +1,25 @@ - #include - #include -+#include - #include - #include - - #include "utils.h" - --static __inline__ u_int16_t dn_ntohs(u_int16_t addr) -+static __inline__ uint16_t dn_ntohs(uint16_t addr) - { - union { -- u_int8_t byte[2]; -- u_int16_t word; -+ uint8_t byte[2]; -+ uint16_t word; - } u; - - u.word = addr; -- return ((u_int16_t)u.byte[0]) | (((u_int16_t)u.byte[1]) << 8); -+ return ((uint16_t)u.byte[0]) | (((uint16_t)u.byte[1]) << 8); - } - --static __inline__ int do_digit(char *str, u_int16_t *addr, u_int16_t scale, size_t *pos, size_t len, int *started) -+static __inline__ int do_digit(char *str, uint16_t *addr, uint16_t scale, size_t *pos, size_t len, int *started) - { -- u_int16_t tmp = *addr / scale; -+ uint16_t tmp = *addr / scale; - - if (*pos == len) - return 1; -@@ -36,7 +37,7 @@ static __inline__ int do_digit(char *str - - static const char *dnet_ntop1(const struct dn_naddr *dna, char *str, size_t len) - { -- u_int16_t addr, area; -+ uint16_t addr, area; - size_t pos = 0; - int started = 0; - ---- a/lib/dnet_pton.c -+++ b/lib/dnet_pton.c -@@ -1,23 +1,24 @@ - #include - #include -+#include - #include - #include - - #include "utils.h" - --static __inline__ u_int16_t dn_htons(u_int16_t addr) -+static __inline__ uint16_t dn_htons(uint16_t addr) - { - union { -- u_int8_t byte[2]; -- u_int16_t word; -+ uint8_t byte[2]; -+ uint16_t word; - } u; - - u.word = addr; -- return ((u_int16_t)u.byte[0]) | (((u_int16_t)u.byte[1]) << 8); -+ return ((uint16_t)u.byte[0]) | (((uint16_t)u.byte[1]) << 8); - } - - --static int dnet_num(const char *src, u_int16_t * dst) -+static int dnet_num(const char *src, uint16_t * dst) - { - int rv = 0; - int tmp; -@@ -38,9 +39,9 @@ static int dnet_num(const char *src, u_i - - static int dnet_pton1(const char *src, struct dn_naddr *dna) - { -- u_int16_t addr; -- u_int16_t area = 0; -- u_int16_t node = 0; -+ uint16_t addr; -+ uint16_t area = 0; -+ uint16_t node = 0; - int pos; - - pos = dnet_num(src, &area); ---- a/include/libiptc/ipt_kernel_headers.h -+++ b/include/libiptc/ipt_kernel_headers.h -@@ -5,7 +5,7 @@ - - #include - --#if defined(__GLIBC__) && __GLIBC__ == 2 -+#if 1 - #include - #include - #include diff --git a/net/iproute2/patches/100-allow_pfifo_fast.patch b/net/iproute2/patches/100-allow_pfifo_fast.patch deleted file mode 100644 index ce958a9..0000000 --- a/net/iproute2/patches/100-allow_pfifo_fast.patch +++ /dev/null @@ -1,9 +0,0 @@ ---- a/tc/q_fifo.c -+++ b/tc/q_fifo.c -@@ -98,5 +98,6 @@ struct qdisc_util pfifo_head_drop_qdisc_ - extern int prio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt); - struct qdisc_util pfifo_fast_qdisc_util = { - .id = "pfifo_fast", -+ .parse_qopt = fifo_parse_opt, - .print_qopt = prio_print_opt, - }; diff --git a/net/iproute2/patches/110-extra-ccopts.patch b/net/iproute2/patches/110-extra-ccopts.patch deleted file mode 100644 index 0e36230..0000000 --- a/net/iproute2/patches/110-extra-ccopts.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/Makefile -+++ b/Makefile -@@ -29,7 +29,7 @@ ADDLIB+=ipx_ntop.o ipx_pton.o - CC = gcc - HOSTCC = gcc - DEFINES += -D_GNU_SOURCE --CCOPTS = -O2 -+CCOPTS = -O2 $(EXTRA_CCOPTS) - WFLAGS := -Wall -Wstrict-prototypes -Wmissing-prototypes - WFLAGS += -Wmissing-declarations -Wold-style-definition -Wformat=2 - diff --git a/net/iproute2/patches/120-libnetlink-pic.patch b/net/iproute2/patches/120-libnetlink-pic.patch deleted file mode 100644 index 19ccd1a..0000000 --- a/net/iproute2/patches/120-libnetlink-pic.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/lib/Makefile -+++ b/lib/Makefile -@@ -4,7 +4,7 @@ ifeq ($(IP_CONFIG_SETNS),y) - CFLAGS += -DHAVE_SETNS - endif - --CFLAGS += -fPIC -+CFLAGS += $(FPIC) - - UTILOBJ=utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o inet_proto.o namespace.o \ - names.o diff --git a/net/iproute2/patches/130-missing_include.patch b/net/iproute2/patches/130-missing_include.patch deleted file mode 100644 index 8856963..0000000 --- a/net/iproute2/patches/130-missing_include.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/lib/namespace.c -+++ b/lib/namespace.c -@@ -9,6 +9,7 @@ - - #include - #include -+#include - - #include "utils.h" - #include "namespace.h" diff --git a/net/iproute2/patches/200-add-tc_esfq.patch b/net/iproute2/patches/200-add-tc_esfq.patch deleted file mode 100644 index 6c148ea..0000000 --- a/net/iproute2/patches/200-add-tc_esfq.patch +++ /dev/null @@ -1,249 +0,0 @@ ---- a/tc/Makefile -+++ b/tc/Makefile -@@ -13,6 +13,7 @@ SHARED_LIBS ?= y - TCMODULES := - TCMODULES += q_fifo.o - TCMODULES += q_sfq.o -+TCMODULES += q_esfq.o - TCMODULES += q_red.o - TCMODULES += q_prio.o - TCMODULES += q_tbf.o ---- a/include/linux/pkt_sched.h -+++ b/include/linux/pkt_sched.h -@@ -226,6 +226,33 @@ struct tc_sfq_xstats { - __s32 allot; - }; - -+/* ESFQ section */ -+ -+enum -+{ -+ /* traditional */ -+ TCA_SFQ_HASH_CLASSIC, -+ TCA_SFQ_HASH_DST, -+ TCA_SFQ_HASH_SRC, -+ TCA_SFQ_HASH_FWMARK, -+ /* conntrack */ -+ TCA_SFQ_HASH_CTORIGDST, -+ TCA_SFQ_HASH_CTORIGSRC, -+ TCA_SFQ_HASH_CTREPLDST, -+ TCA_SFQ_HASH_CTREPLSRC, -+ TCA_SFQ_HASH_CTNATCHG, -+}; -+ -+struct tc_esfq_qopt -+{ -+ unsigned quantum; /* Bytes per round allocated to flow */ -+ int perturb_period; /* Period of hash perturbation */ -+ __u32 limit; /* Maximal packets in queue */ -+ unsigned divisor; /* Hash divisor */ -+ unsigned flows; /* Maximal number of flows */ -+ unsigned hash_kind; /* Hash function to use for flow identification */ -+}; -+ - /* RED section */ - - enum { ---- /dev/null -+++ b/tc/q_esfq.c -@@ -0,0 +1,200 @@ -+/* -+ * q_esfq.c ESFQ. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ * -+ * Authors: Alexey Kuznetsov, -+ * -+ * Changes: Alexander Atanasov, -+ * Alexander Clouter, -+ * Corey Hickey, -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "utils.h" -+#include "tc_util.h" -+ -+static void explain(void) -+{ -+ fprintf(stderr, "Usage: ... esfq [ perturb SECS ] [ quantum BYTES ] [ depth FLOWS ]\n\t[ divisor HASHBITS ] [ limit PKTS ] [ hash HASHTYPE]\n"); -+ fprintf(stderr,"Where: \n"); -+ fprintf(stderr,"HASHTYPE := { classic | src | dst | ctorigdst | ctorigsrc | ctrepldst | ctreplsrc | ctnatchg }\n"); -+} -+ -+#define usage() return(-1) -+ -+static int esfq_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) -+{ -+ int ok=0; -+ struct tc_esfq_qopt opt; -+ -+ memset(&opt, 0, sizeof(opt)); -+ -+ opt.hash_kind= TCA_SFQ_HASH_CLASSIC; -+ -+ while (argc > 0) { -+ if (strcmp(*argv, "quantum") == 0) { -+ NEXT_ARG(); -+ if (get_size(&opt.quantum, *argv)) { -+ fprintf(stderr, "Illegal \"quantum\"\n"); -+ return -1; -+ } -+ ok++; -+ } else if (strcmp(*argv, "perturb") == 0) { -+ NEXT_ARG(); -+ if (get_integer(&opt.perturb_period, *argv, 0)) { -+ fprintf(stderr, "Illegal \"perturb\"\n"); -+ return -1; -+ } -+ ok++; -+ } else if (strcmp(*argv, "depth") == 0) { -+ NEXT_ARG(); -+ if (get_integer((int *) &opt.flows, *argv, 0)) { -+ fprintf(stderr, "Illegal \"depth\"\n"); -+ return -1; -+ } -+ ok++; -+ } else if (strcmp(*argv, "divisor") == 0) { -+ NEXT_ARG(); -+ if (get_integer((int *) &opt.divisor, *argv, 0)) { -+ fprintf(stderr, "Illegal \"divisor\"\n"); -+ return -1; -+ } -+ if(opt.divisor >= 14) { -+ fprintf(stderr, "Illegal \"divisor\": must be < 14\n"); -+ return -1; -+ } -+ opt.divisor=pow(2,opt.divisor); -+ ok++; -+ } else if (strcmp(*argv, "limit") == 0) { -+ NEXT_ARG(); -+ if (get_integer((int *) &opt.limit, *argv, 0)) { -+ fprintf(stderr, "Illegal \"limit\"\n"); -+ return -1; -+ } -+ ok++; -+ } else if (strcmp(*argv, "hash") == 0) { -+ NEXT_ARG(); -+ if(strcmp(*argv, "classic") == 0) { -+ opt.hash_kind= TCA_SFQ_HASH_CLASSIC; -+ } else -+ if(strcmp(*argv, "dst") == 0) { -+ opt.hash_kind= TCA_SFQ_HASH_DST; -+ } else -+ if(strcmp(*argv, "src") == 0) { -+ opt.hash_kind= TCA_SFQ_HASH_SRC; -+ } else -+ if(strcmp(*argv, "ctorigsrc") == 0) { -+ opt.hash_kind= TCA_SFQ_HASH_CTORIGSRC; -+ } else -+ if(strcmp(*argv, "ctorigdst") == 0) { -+ opt.hash_kind= TCA_SFQ_HASH_CTORIGDST; -+ } else -+ if(strcmp(*argv, "ctreplsrc") == 0) { -+ opt.hash_kind= TCA_SFQ_HASH_CTREPLSRC; -+ } else -+ if(strcmp(*argv, "ctrepldst") == 0) { -+ opt.hash_kind= TCA_SFQ_HASH_CTREPLDST; -+ } else -+ if(strcmp(*argv, "ctnatchg") == 0) { -+ opt.hash_kind= TCA_SFQ_HASH_CTNATCHG; -+ } else { -+ fprintf(stderr, "Illegal \"hash\"\n"); -+ explain(); -+ return -1; -+ } -+ ok++; -+ } else if (strcmp(*argv, "help") == 0) { -+ explain(); -+ return -1; -+ } else { -+ fprintf(stderr, "What is \"%s\"?\n", *argv); -+ explain(); -+ return -1; -+ } -+ argc--; argv++; -+ } -+ -+ if (ok) -+ addattr_l(n, 1024, TCA_OPTIONS, &opt, sizeof(opt)); -+ return 0; -+} -+ -+static int esfq_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -+{ -+ struct tc_esfq_qopt *qopt; -+ SPRINT_BUF(b1); -+ -+ if (opt == NULL) -+ return 0; -+ -+ if (RTA_PAYLOAD(opt) < sizeof(*qopt)) -+ return -1; -+ qopt = RTA_DATA(opt); -+ fprintf(f, "quantum %s ", sprint_size(qopt->quantum, b1)); -+ if (show_details) { -+ fprintf(f, "limit %up flows %u/%u ", -+ qopt->limit, qopt->flows, qopt->divisor); -+ } -+ if (qopt->perturb_period) -+ fprintf(f, "perturb %dsec ", qopt->perturb_period); -+ -+ fprintf(f,"hash: "); -+ switch(qopt->hash_kind) -+ { -+ case TCA_SFQ_HASH_CLASSIC: -+ fprintf(f,"classic"); -+ break; -+ case TCA_SFQ_HASH_DST: -+ fprintf(f,"dst"); -+ break; -+ case TCA_SFQ_HASH_SRC: -+ fprintf(f,"src"); -+ break; -+ case TCA_SFQ_HASH_CTORIGSRC: -+ fprintf(f,"ctorigsrc"); -+ break; -+ case TCA_SFQ_HASH_CTORIGDST: -+ fprintf(f,"ctorigdst"); -+ break; -+ case TCA_SFQ_HASH_CTREPLSRC: -+ fprintf(f,"ctreplsrc"); -+ break; -+ case TCA_SFQ_HASH_CTREPLDST: -+ fprintf(f,"ctrepldst"); -+ break; -+ case TCA_SFQ_HASH_CTNATCHG: -+ fprintf(f,"ctnatchg"); -+ break; -+ default: -+ fprintf(f,"Unknown"); -+ } -+ return 0; -+} -+ -+static int esfq_print_xstats(struct qdisc_util *qu, FILE *f, struct rtattr *xstats) -+{ -+ return 0; -+} -+ -+ -+struct qdisc_util esfq_qdisc_util = { -+ .id = "esfq", -+ .parse_qopt = esfq_parse_opt, -+ .print_qopt = esfq_print_opt, -+ .print_xstats = esfq_print_xstats, -+}; diff --git a/net/iproute2/patches/210-add-act_connmark.patch b/net/iproute2/patches/210-add-act_connmark.patch deleted file mode 100644 index 10167ae..0000000 --- a/net/iproute2/patches/210-add-act_connmark.patch +++ /dev/null @@ -1,87 +0,0 @@ ---- a/tc/Makefile -+++ b/tc/Makefile -@@ -44,6 +44,7 @@ TCMODULES += m_mirred.o - TCMODULES += m_nat.o - TCMODULES += m_pedit.o - TCMODULES += m_skbedit.o -+TCMODULES += m_connmark.o - TCMODULES += m_csum.o - TCMODULES += m_simple.o - TCMODULES += m_vlan.o ---- /dev/null -+++ b/tc/m_connmark.c -@@ -0,0 +1,74 @@ -+/* -+ * m_connmark.c Connection tracking marking import -+ * -+ * Copyright (c) 2011 Felix Fietkau -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple -+ * Place - Suite 330, Boston, MA 02111-1307 USA. -+ */ -+ -+#include -+#include -+#include -+#include -+#include "utils.h" -+#include "tc_util.h" -+ -+static void -+explain(void) -+{ -+ fprintf(stderr, "Usage: ... connmark\n"); -+} -+ -+static void -+usage(void) -+{ -+ explain(); -+ exit(-1); -+} -+ -+static int -+parse_connmark(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, -+ struct nlmsghdr *n) -+{ -+ int argc = *argc_p; -+ char **argv = *argv_p; -+ -+ if (matches(*argv, "connmark") != 0) -+ return -1; -+ -+ NEXT_ARG(); -+ -+ if (matches(*argv, "help") == 0) -+ usage(); -+ -+ *argc_p = argc; -+ *argv_p = argv; -+ return 0; -+} -+ -+static int print_connmark(struct action_util *au, FILE *f, struct rtattr *arg) -+{ -+ if (arg == NULL) -+ return -1; -+ -+ fprintf(f, " connmark"); -+ -+ return 0; -+} -+ -+struct action_util connmark_action_util = { -+ .id = "connmark", -+ .parse_aopt = parse_connmark, -+ .print_aopt = print_connmark, -+}; diff --git a/net/iproute2/patches/300-ip_tiny.patch b/net/iproute2/patches/300-ip_tiny.patch deleted file mode 100644 index 14518dc..0000000 --- a/net/iproute2/patches/300-ip_tiny.patch +++ /dev/null @@ -1,101 +0,0 @@ ---- a/ip/Makefile -+++ b/ip/Makefile -@@ -16,6 +16,13 @@ ifeq ($(IP_CONFIG_SETNS),y) - CFLAGS += -DHAVE_SETNS - endif - -+STATIC_SYM_FILTER:= -+ifeq ($(IP_CONFIG_TINY),y) -+ STATIC_SYM_FILTER:=iplink_can.c iplink_ipoib.c iplink_vxlan.c -+ CFLAGS += -DIPROUTE2_TINY -+endif -+STATIC_SYM_SOURCES:=$(filter-out $(STATIC_SYM_FILTER),$(wildcard *.c)) -+ - ALLOBJ=$(IPOBJ) $(RTMONOBJ) - SCRIPTS=ifcfg rtpr routel routef - TARGETS=ip rtmon -@@ -43,7 +50,7 @@ else - - ip: static-syms.o - static-syms.o: static-syms.h --static-syms.h: $(wildcard *.c) -+static-syms.h: $(STATIC_SYM_SOURCES) - files="$^" ; \ - for s in `grep -B 3 '\ -Date: Sat, 2 May 2015 01:27:50 -0700 -Subject: [PATCH 1/2] Add cake and alternate codel models - ---- - include/linux/pkt_sched.h | 34 +++++ - tc/Makefile | 8 ++ - tc/q_cake.c | 333 ++++++++++++++++++++++++++++++++++++++++++++++ - tc/q_cake0.c | 301 +++++++++++++++++++++++++++++++++++++++++ - tc/q_cake2.c | 296 +++++++++++++++++++++++++++++++++++++++++ - tc/q_efq_codel.c | 232 ++++++++++++++++++++++++++++++++ - tc/q_nfq_codel.c | 232 ++++++++++++++++++++++++++++++++ - tc/q_ns2_codel.c | 188 ++++++++++++++++++++++++++ - tc/q_ns4_codel.c | 188 ++++++++++++++++++++++++++ - tc/q_pfq_codel.c | 232 ++++++++++++++++++++++++++++++++ - 10 files changed, 2044 insertions(+) - create mode 100644 tc/q_cake.c - create mode 100644 tc/q_cake0.c - create mode 100644 tc/q_cake2.c - create mode 100644 tc/q_efq_codel.c - create mode 100644 tc/q_nfq_codel.c - create mode 100644 tc/q_ns2_codel.c - create mode 100644 tc/q_ns4_codel.c - create mode 100644 tc/q_pfq_codel.c - -diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h -index 534b847..a1d7b67 100644 ---- a/include/linux/pkt_sched.h -+++ b/include/linux/pkt_sched.h -@@ -845,4 +845,38 @@ struct tc_pie_xstats { - __u32 maxq; /* maximum queue size */ - __u32 ecn_mark; /* packets marked with ecn*/ - }; -+ -+/* CAKE */ -+enum { -+ TCA_CAKE_UNSPEC, -+ TCA_CAKE_BASE_RATE, -+ TCA_CAKE_DIFFSERV_MODE, -+ TCA_CAKE_ATM, -+ TCA_CAKE_FLOW_MODE, -+ __TCA_CAKE_MAX -+}; -+#define TCA_CAKE_MAX (__TCA_CAKE_MAX - 1) -+ -+struct tc_cake_xstats { -+ __u16 type; /* constant magic 0xCAFE */ -+ __u16 class_cnt; -+ struct { -+ __u32 rate; -+ __u32 target_us; -+ __u32 packets; -+ __u32 interval_us; -+ __u64 bytes; -+ __u32 dropped; -+ __u32 ecn_marked; -+ __u32 way_indirect_hits; -+ __u32 way_misses; -+ __u32 way_collisions; -+ __u32 backlog_bytes; -+ __u32 peak_delay; /* delay to fat flows */ -+ __u32 avge_delay; -+ __u32 base_delay; /* delay to sparse flows */ -+ __u32 dummy2; -+ } cls[8]; -+}; -+ - #endif -diff --git a/tc/Makefile b/tc/Makefile -index 96e8493..69b83c7 100644 ---- a/tc/Makefile -+++ b/tc/Makefile -@@ -60,8 +60,16 @@ TCMODULES += em_meta.o - TCMODULES += q_mqprio.o - TCMODULES += q_codel.o - TCMODULES += q_fq_codel.o -+TCMODULES += q_nfq_codel.o -+TCMODULES += q_efq_codel.o -+TCMODULES += q_pfq_codel.o -+TCMODULES += q_ns2_codel.o -+TCMODULES += q_ns4_codel.o - TCMODULES += q_fq.o - TCMODULES += q_pie.o -+TCMODULES += q_cake.o -+TCMODULES += q_cake0.o -+TCMODULES += q_cake2.o - TCMODULES += q_hhf.o - TCMODULES += e_bpf.o - -diff --git a/tc/q_cake.c b/tc/q_cake.c -new file mode 100644 -index 0000000..d9415d3 ---- /dev/null -+++ b/tc/q_cake.c -@@ -0,0 +1,333 @@ -+/* -+ * Common Applications Kept Enhanced -- CAKE -+ * -+ * Copyright (C) 2014-2015 Jonathan Morton -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions, and the following disclaimer, -+ * without modification. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. The names of the authors may not be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * Alternatively, provided that this notice is retained in full, this -+ * software may be distributed under the terms of the GNU General -+ * Public License ("GPL") version 2, in which case the provisions of the -+ * GPL apply INSTEAD OF those given above. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "utils.h" -+#include "tc_util.h" -+ -+static void explain(void) -+{ -+ fprintf(stderr, "Usage: ... cake [ bandwidth RATE | unlimited ]\n" -+ " [ besteffort | precedence | diffserv8 | diffserv4 ]\n" -+ " [ flowblind | srchost | dsthost | hosts | flows ]\n" -+ " [ atm ]\n"); -+} -+ -+static int cake_parse_opt(struct qdisc_util *qu, int argc, char **argv, -+ struct nlmsghdr *n) -+{ -+ int unlimited = 0; -+ unsigned bandwidth = 0; -+ unsigned diffserv = 0; -+ int flowmode = -1; -+ int atm = -1; -+ struct rtattr *tail; -+ -+ while (argc > 0) { -+ if (strcmp(*argv, "bandwidth") == 0) { -+ NEXT_ARG(); -+ if (get_rate(&bandwidth, *argv)) { -+ fprintf(stderr, "Illegal \"bandwidth\"\n"); -+ return -1; -+ } -+ unlimited = 0; -+ } else if (strcmp(*argv, "unlimited") == 0) { -+ bandwidth = 0; -+ unlimited = 1; -+ -+ } else if (strcmp(*argv, "besteffort") == 0) { -+ diffserv = 1; -+ } else if (strcmp(*argv, "precedence") == 0) { -+ diffserv = 2; -+ } else if (strcmp(*argv, "diffserv8") == 0) { -+ diffserv = 3; -+ } else if (strcmp(*argv, "diffserv4") == 0) { -+ diffserv = 4; -+ } else if (strcmp(*argv, "diffserv") == 0) { -+ diffserv = 4; -+ -+ } else if (strcmp(*argv, "flowblind") == 0) { -+ flowmode = 0; -+ } else if (strcmp(*argv, "srchost") == 0) { -+ flowmode = 1; -+ } else if (strcmp(*argv, "dsthost") == 0) { -+ flowmode = 2; -+ } else if (strcmp(*argv, "hosts") == 0) { -+ flowmode = 3; -+ } else if (strcmp(*argv, "flows") == 0) { -+ flowmode = 4; -+ -+ } else if (strcmp(*argv, "atm") == 0) { -+ atm = 1; -+ } else if (strcmp(*argv, "noatm") == 0) { -+ atm = 0; -+ -+ } else if (strcmp(*argv, "help") == 0) { -+ explain(); -+ return -1; -+ } else { -+ fprintf(stderr, "What is \"%s\"?\n", *argv); -+ explain(); -+ return -1; -+ } -+ argc--; argv++; -+ } -+ -+ tail = NLMSG_TAIL(n); -+ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); -+ if (bandwidth || unlimited) -+ addattr_l(n, 1024, TCA_CAKE_BASE_RATE, &bandwidth, sizeof(bandwidth)); -+ if (diffserv) -+ addattr_l(n, 1024, TCA_CAKE_DIFFSERV_MODE, &diffserv, sizeof(diffserv)); -+ if (atm != -1) -+ addattr_l(n, 1024, TCA_CAKE_ATM, &atm, sizeof(atm)); -+ if (flowmode != -1) -+ addattr_l(n, 1024, TCA_CAKE_FLOW_MODE, &flowmode, sizeof(flowmode)); -+ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; -+ return 0; -+} -+ -+static int cake_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -+{ -+ struct rtattr *tb[TCA_CAKE_MAX + 1]; -+ unsigned bandwidth = 0; -+ unsigned diffserv = 0; -+ unsigned flowmode = 0; -+ int atm = -1; -+ SPRINT_BUF(b1); -+ -+ if (opt == NULL) -+ return 0; -+ -+ parse_rtattr_nested(tb, TCA_CAKE_MAX, opt); -+ -+ if (tb[TCA_CAKE_BASE_RATE] && -+ RTA_PAYLOAD(tb[TCA_CAKE_BASE_RATE]) >= sizeof(__u32)) { -+ bandwidth = rta_getattr_u32(tb[TCA_CAKE_BASE_RATE]); -+ if(bandwidth) -+ fprintf(f, "bandwidth %s ", sprint_rate(bandwidth, b1)); -+ else -+ fprintf(f, "unlimited "); -+ } -+ if (tb[TCA_CAKE_DIFFSERV_MODE] && -+ RTA_PAYLOAD(tb[TCA_CAKE_DIFFSERV_MODE]) >= sizeof(__u32)) { -+ diffserv = rta_getattr_u32(tb[TCA_CAKE_DIFFSERV_MODE]); -+ switch(diffserv) { -+ case 1: -+ fprintf(f, "besteffort "); -+ break; -+ case 2: -+ fprintf(f, "precedence "); -+ break; -+ case 3: -+ fprintf(f, "diffserv8 "); -+ break; -+ case 4: -+ fprintf(f, "diffserv4 "); -+ break; -+ default: -+ fprintf(f, "(?diffserv?) "); -+ break; -+ }; -+ } -+ if (tb[TCA_CAKE_FLOW_MODE] && -+ RTA_PAYLOAD(tb[TCA_CAKE_FLOW_MODE]) >= sizeof(__u32)) { -+ flowmode = rta_getattr_u32(tb[TCA_CAKE_FLOW_MODE]); -+ switch(flowmode) { -+ case 0: -+ fprintf(f, "flowblind "); -+ break; -+ case 1: -+ fprintf(f, "srchost "); -+ break; -+ case 2: -+ fprintf(f, "dsthost "); -+ break; -+ case 3: -+ fprintf(f, "hosts "); -+ break; -+ case 4: -+ fprintf(f, "flows "); -+ break; -+ default: -+ fprintf(f, "(?flowmode?) "); -+ break; -+ }; -+ } -+ if (tb[TCA_CAKE_ATM] && -+ RTA_PAYLOAD(tb[TCA_CAKE_ATM]) >= sizeof(__u32)) { -+ atm = rta_getattr_u32(tb[TCA_CAKE_ATM]); -+ if (atm) -+ fprintf(f, "atm "); -+ } -+ -+ return 0; -+} -+ -+static int cake_print_xstats(struct qdisc_util *qu, FILE *f, -+ struct rtattr *xstats) -+{ -+ /* fq_codel stats format borrowed */ -+ struct tc_fq_codel_xstats *st; -+ struct tc_cake_xstats *stc; -+ SPRINT_BUF(b1); -+ -+ if (xstats == NULL) -+ return 0; -+ -+ if (RTA_PAYLOAD(xstats) < sizeof(st->type)) -+ return -1; -+ -+ st = RTA_DATA(xstats); -+ stc = RTA_DATA(xstats); -+ -+ if (st->type == TCA_FQ_CODEL_XSTATS_QDISC && RTA_PAYLOAD(xstats) >= sizeof(*st)) { -+ fprintf(f, " maxpacket %u drop_overlimit %u new_flow_count %u ecn_mark %u", -+ st->qdisc_stats.maxpacket, -+ st->qdisc_stats.drop_overlimit, -+ st->qdisc_stats.new_flow_count, -+ st->qdisc_stats.ecn_mark); -+ fprintf(f, "\n new_flows_len %u old_flows_len %u", -+ st->qdisc_stats.new_flows_len, -+ st->qdisc_stats.old_flows_len); -+ } else if (st->type == TCA_FQ_CODEL_XSTATS_CLASS && RTA_PAYLOAD(xstats) >= sizeof(*st)) { -+ fprintf(f, " deficit %d count %u lastcount %u ldelay %s", -+ st->class_stats.deficit, -+ st->class_stats.count, -+ st->class_stats.lastcount, -+ sprint_time(st->class_stats.ldelay, b1)); -+ if (st->class_stats.dropping) { -+ fprintf(f, " dropping"); -+ if (st->class_stats.drop_next < 0) -+ fprintf(f, " drop_next -%s", -+ sprint_time(-st->class_stats.drop_next, b1)); -+ else -+ fprintf(f, " drop_next %s", -+ sprint_time(st->class_stats.drop_next, b1)); -+ } -+ } else if (stc->type == 0xCAFE && RTA_PAYLOAD(xstats) >= sizeof(*stc)) { -+ int i; -+ -+ fprintf(f, " "); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, " Class %u ", i); -+ fprintf(f, "\n"); -+ -+ fprintf(f, " rate "); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%12s", sprint_rate(stc->cls[i].rate, b1)); -+ fprintf(f, "\n"); -+ -+ fprintf(f, " target"); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%12s", sprint_time(stc->cls[i].target_us, b1)); -+ fprintf(f, "\n"); -+ -+ fprintf(f, "interval"); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%12s", sprint_time(stc->cls[i].interval_us, b1)); -+ fprintf(f, "\n"); -+ -+ fprintf(f, "Pk delay"); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%12s", sprint_time(stc->cls[i].peak_delay, b1)); -+ fprintf(f, "\n"); -+ -+ fprintf(f, "Av delay"); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%12s", sprint_time(stc->cls[i].avge_delay, b1)); -+ fprintf(f, "\n"); -+ -+ fprintf(f, "Sp delay"); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%12s", sprint_time(stc->cls[i].base_delay, b1)); -+ fprintf(f, "\n"); -+ -+ fprintf(f, " pkts "); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%12u", stc->cls[i].packets); -+ fprintf(f, "\n"); -+ -+ fprintf(f, "way inds"); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%12u", stc->cls[i].way_indirect_hits); -+ fprintf(f, "\n"); -+ -+ fprintf(f, "way miss"); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%12u", stc->cls[i].way_misses); -+ fprintf(f, "\n"); -+ -+ fprintf(f, "way cols"); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%12u", stc->cls[i].way_collisions); -+ fprintf(f, "\n"); -+ -+ fprintf(f, " bytes "); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%12llu", stc->cls[i].bytes); -+ fprintf(f, "\n"); -+ -+ fprintf(f, " drops "); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%12u", stc->cls[i].dropped); -+ fprintf(f, "\n"); -+ -+ fprintf(f, " marks "); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%12u", stc->cls[i].ecn_marked); -+ } else { -+ return -1; -+ } -+ return 0; -+} -+ -+struct qdisc_util cake_qdisc_util = { -+ .id = "cake", -+ .parse_qopt = cake_parse_opt, -+ .print_qopt = cake_print_opt, -+ .print_xstats = cake_print_xstats, -+}; -diff --git a/tc/q_cake0.c b/tc/q_cake0.c -new file mode 100644 -index 0000000..9fb63ed ---- /dev/null -+++ b/tc/q_cake0.c -@@ -0,0 +1,301 @@ -+/* -+ * Common Applications Kept Enhanced -- CAKE -+ * -+ * Copyright (C) 2014 Jonathan Morton -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions, and the following disclaimer, -+ * without modification. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. The names of the authors may not be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * Alternatively, provided that this notice is retained in full, this -+ * software may be distributed under the terms of the GNU General -+ * Public License ("GPL") version 2, in which case the provisions of the -+ * GPL apply INSTEAD OF those given above. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "utils.h" -+#include "tc_util.h" -+ -+static void explain(void) -+{ -+ fprintf(stderr, "Usage: ... cake0 [ bandwidth RATE | unlimited ]\n" -+ " [ besteffort | precedence | diffserv ]\n" -+ " [ flowblind | srchost | dsthost | hosts | flows ]\n" -+ " [ atm ]\n"); -+} -+ -+static int cake_parse_opt(struct qdisc_util *qu, int argc, char **argv, -+ struct nlmsghdr *n) -+{ -+ int unlimited = 0; -+ unsigned bandwidth = 0; -+ unsigned diffserv = 0; -+ int flowmode = -1; -+ int atm = -1; -+ struct rtattr *tail; -+ -+ while (argc > 0) { -+ if (strcmp(*argv, "bandwidth") == 0) { -+ NEXT_ARG(); -+ if (get_rate(&bandwidth, *argv)) { -+ fprintf(stderr, "Illegal \"bandwidth\"\n"); -+ return -1; -+ } -+ unlimited = 0; -+ } else if (strcmp(*argv, "unlimited") == 0) { -+ bandwidth = 0; -+ unlimited = 1; -+ -+ } else if (strcmp(*argv, "besteffort") == 0) { -+ diffserv = 1; -+ } else if (strcmp(*argv, "precedence") == 0) { -+ diffserv = 2; -+ } else if (strcmp(*argv, "diffserv") == 0) { -+ diffserv = 3; -+ -+ } else if (strcmp(*argv, "flowblind") == 0) { -+ flowmode = 0; -+ } else if (strcmp(*argv, "srchost") == 0) { -+ flowmode = 1; -+ } else if (strcmp(*argv, "dsthost") == 0) { -+ flowmode = 2; -+ } else if (strcmp(*argv, "hosts") == 0) { -+ flowmode = 3; -+ } else if (strcmp(*argv, "flows") == 0) { -+ flowmode = 4; -+ -+ } else if (strcmp(*argv, "atm") == 0) { -+ atm = 1; -+ } else if (strcmp(*argv, "noatm") == 0) { -+ atm = 0; -+ -+ } else if (strcmp(*argv, "help") == 0) { -+ explain(); -+ return -1; -+ } else { -+ fprintf(stderr, "What is \"%s\"?\n", *argv); -+ explain(); -+ return -1; -+ } -+ argc--; argv++; -+ } -+ -+ tail = NLMSG_TAIL(n); -+ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); -+ if (bandwidth || unlimited) -+ addattr_l(n, 1024, TCA_CAKE_BASE_RATE, &bandwidth, sizeof(bandwidth)); -+ if (diffserv) -+ addattr_l(n, 1024, TCA_CAKE_DIFFSERV_MODE, &diffserv, sizeof(diffserv)); -+ if (atm != -1) -+ addattr_l(n, 1024, TCA_CAKE_ATM, &atm, sizeof(atm)); -+ if (flowmode != -1) -+ addattr_l(n, 1024, TCA_CAKE_FLOW_MODE, &flowmode, sizeof(flowmode)); -+ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; -+ return 0; -+} -+ -+static int cake_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -+{ -+ struct rtattr *tb[TCA_CAKE_MAX + 1]; -+ unsigned bandwidth = 0; -+ unsigned diffserv = 0; -+ unsigned flowmode = 0; -+ int atm = -1; -+ SPRINT_BUF(b1); -+ -+ if (opt == NULL) -+ return 0; -+ -+ parse_rtattr_nested(tb, TCA_CAKE_MAX, opt); -+ -+ if (tb[TCA_CAKE_BASE_RATE] && -+ RTA_PAYLOAD(tb[TCA_CAKE_BASE_RATE]) >= sizeof(__u32)) { -+ bandwidth = rta_getattr_u32(tb[TCA_CAKE_BASE_RATE]); -+ if(bandwidth) -+ fprintf(f, "bandwidth %s ", sprint_rate(bandwidth, b1)); -+ else -+ fprintf(f, "unlimited"); -+ } -+ if (tb[TCA_CAKE_DIFFSERV_MODE] && -+ RTA_PAYLOAD(tb[TCA_CAKE_DIFFSERV_MODE]) >= sizeof(__u32)) { -+ diffserv = rta_getattr_u32(tb[TCA_CAKE_DIFFSERV_MODE]); -+ switch(diffserv) { -+ case 1: -+ fprintf(f, "besteffort "); -+ break; -+ case 2: -+ fprintf(f, "precedence "); -+ break; -+ case 3: -+ fprintf(f, "diffserv "); -+ break; -+ default: -+ fprintf(f, "(?diffserv?) "); -+ break; -+ }; -+ } -+ if (tb[TCA_CAKE_FLOW_MODE] && -+ RTA_PAYLOAD(tb[TCA_CAKE_FLOW_MODE]) >= sizeof(__u32)) { -+ flowmode = rta_getattr_u32(tb[TCA_CAKE_FLOW_MODE]); -+ switch(flowmode) { -+ case 0: -+ fprintf(f, "flowblind "); -+ break; -+ case 1: -+ fprintf(f, "srchost "); -+ break; -+ case 2: -+ fprintf(f, "dsthost "); -+ break; -+ case 3: -+ fprintf(f, "hosts "); -+ break; -+ case 4: -+ fprintf(f, "flows "); -+ break; -+ default: -+ fprintf(f, "(?flowmode?) "); -+ break; -+ }; -+ } -+ if (tb[TCA_CAKE_ATM] && -+ RTA_PAYLOAD(tb[TCA_CAKE_ATM]) >= sizeof(__u32)) { -+ atm = rta_getattr_u32(tb[TCA_CAKE_ATM]); -+ if (atm) -+ fprintf(f, "atm "); -+ } -+ -+ return 0; -+} -+ -+static int cake_print_xstats(struct qdisc_util *qu, FILE *f, -+ struct rtattr *xstats) -+{ -+ /* fq_codel stats format borrowed */ -+ struct tc_fq_codel_xstats *st; -+ struct tc_cake_xstats *stc; -+ SPRINT_BUF(b1); -+ -+ if (xstats == NULL) -+ return 0; -+ -+ if (RTA_PAYLOAD(xstats) < sizeof(st->type)) -+ return -1; -+ -+ st = RTA_DATA(xstats); -+ stc = RTA_DATA(xstats); -+ -+ if (st->type == TCA_FQ_CODEL_XSTATS_QDISC && RTA_PAYLOAD(xstats) >= sizeof(*st)) { -+ fprintf(f, " maxpacket %u drop_overlimit %u new_flow_count %u ecn_mark %u", -+ st->qdisc_stats.maxpacket, -+ st->qdisc_stats.drop_overlimit, -+ st->qdisc_stats.new_flow_count, -+ st->qdisc_stats.ecn_mark); -+ fprintf(f, "\n new_flows_len %u old_flows_len %u", -+ st->qdisc_stats.new_flows_len, -+ st->qdisc_stats.old_flows_len); -+ } else if (st->type == TCA_FQ_CODEL_XSTATS_CLASS && RTA_PAYLOAD(xstats) >= sizeof(*st)) { -+ fprintf(f, " deficit %d count %u lastcount %u ldelay %s", -+ st->class_stats.deficit, -+ st->class_stats.count, -+ st->class_stats.lastcount, -+ sprint_time(st->class_stats.ldelay, b1)); -+ if (st->class_stats.dropping) { -+ fprintf(f, " dropping"); -+ if (st->class_stats.drop_next < 0) -+ fprintf(f, " drop_next -%s", -+ sprint_time(-st->class_stats.drop_next, b1)); -+ else -+ fprintf(f, " drop_next %s", -+ sprint_time(st->class_stats.drop_next, b1)); -+ } -+ } else if (stc->type == 0xCAFE && RTA_PAYLOAD(xstats) >= sizeof(*stc)) { -+ int i; -+ -+ fprintf(f, " "); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, " Class %u ", i); -+ fprintf(f, "\n"); -+ -+ fprintf(f, " rate "); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%10s", sprint_rate(stc->cls[i].rate, b1)); -+ fprintf(f, "\n"); -+ -+ fprintf(f, " target"); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%10s", sprint_time(stc->cls[i].target_us, b1)); -+ fprintf(f, "\n"); -+ -+ fprintf(f, "interval"); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%10s", sprint_time(stc->cls[i].interval_us, b1)); -+ fprintf(f, "\n"); -+ -+ fprintf(f, " delay "); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%10s", sprint_time(stc->cls[i].peak_delay, b1)); -+ fprintf(f, "\n"); -+ -+ fprintf(f, " pkts "); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%10u", stc->cls[i].packets); -+ fprintf(f, "\n"); -+ -+ fprintf(f, " bytes "); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%10llu", stc->cls[i].bytes); -+ fprintf(f, "\n"); -+ -+ fprintf(f, " drops "); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%10u", stc->cls[i].dropped); -+ fprintf(f, "\n"); -+ -+ fprintf(f, " marks "); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%10u", stc->cls[i].ecn_marked); -+ } else { -+ return -1; -+ } -+ return 0; -+} -+ -+struct qdisc_util cake0_qdisc_util = { -+ .id = "cake0", -+ .parse_qopt = cake_parse_opt, -+ .print_qopt = cake_print_opt, -+ .print_xstats = cake_print_xstats, -+}; -diff --git a/tc/q_cake2.c b/tc/q_cake2.c -new file mode 100644 -index 0000000..a4d3f7c ---- /dev/null -+++ b/tc/q_cake2.c -@@ -0,0 +1,296 @@ -+/* -+ * Common Applications Kept Enhanced -- CAKE -+ * -+ * Copyright (C) 2014 Jonathan Morton -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions, and the following disclaimer, -+ * without modification. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. The names of the authors may not be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * Alternatively, provided that this notice is retained in full, this -+ * software may be distributed under the terms of the GNU General -+ * Public License ("GPL") version 2, in which case the provisions of the -+ * GPL apply INSTEAD OF those given above. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "utils.h" -+#include "tc_util.h" -+ -+static void explain(void) -+{ -+ fprintf(stderr, "Usage: ... cake2 [ bandwidth RATE | unlimited ]\n" -+ " [ besteffort | precedence | diffserv ]\n" -+ " [ flowblind | srchost | dsthost | hosts | flows ]\n" -+ " [ atm ]\n"); -+} -+ -+static int cake_parse_opt(struct qdisc_util *qu, int argc, char **argv, -+ struct nlmsghdr *n) -+{ -+ int unlimited = 0; -+ unsigned bandwidth = 0; -+ unsigned diffserv = 0; -+ int flowmode = -1; -+ int atm = -1; -+ struct rtattr *tail; -+ -+ while (argc > 0) { -+ if (strcmp(*argv, "bandwidth") == 0) { -+ NEXT_ARG(); -+ if (get_rate(&bandwidth, *argv)) { -+ fprintf(stderr, "Illegal \"bandwidth\"\n"); -+ return -1; -+ } -+ unlimited = 0; -+ } else if (strcmp(*argv, "unlimited") == 0) { -+ bandwidth = 0; -+ unlimited = 1; -+ -+ } else if (strcmp(*argv, "besteffort") == 0) { -+ diffserv = 1; -+ } else if (strcmp(*argv, "precedence") == 0) { -+ diffserv = 2; -+ } else if (strcmp(*argv, "diffserv") == 0) { -+ diffserv = 3; -+ -+ } else if (strcmp(*argv, "flowblind") == 0) { -+ flowmode = 0; -+ } else if (strcmp(*argv, "srchost") == 0) { -+ flowmode = 1; -+ } else if (strcmp(*argv, "dsthost") == 0) { -+ flowmode = 2; -+ } else if (strcmp(*argv, "hosts") == 0) { -+ flowmode = 3; -+ } else if (strcmp(*argv, "flows") == 0) { -+ flowmode = 4; -+ -+ } else if (strcmp(*argv, "atm") == 0) { -+ atm = 1; -+ } else if (strcmp(*argv, "noatm") == 0) { -+ atm = 0; -+ -+ } else if (strcmp(*argv, "help") == 0) { -+ explain(); -+ return -1; -+ } else { -+ fprintf(stderr, "What is \"%s\"?\n", *argv); -+ explain(); -+ return -1; -+ } -+ argc--; argv++; -+ } -+ -+ tail = NLMSG_TAIL(n); -+ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); -+ if (bandwidth || unlimited) -+ addattr_l(n, 1024, TCA_CAKE_BASE_RATE, &bandwidth, sizeof(bandwidth)); -+ if (diffserv) -+ addattr_l(n, 1024, TCA_CAKE_DIFFSERV_MODE, &diffserv, sizeof(diffserv)); -+ if (atm != -1) -+ addattr_l(n, 1024, TCA_CAKE_ATM, &atm, sizeof(atm)); -+ if (flowmode != -1) -+ addattr_l(n, 1024, TCA_CAKE_FLOW_MODE, &flowmode, sizeof(flowmode)); -+ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; -+ return 0; -+} -+ -+static int cake_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -+{ -+ struct rtattr *tb[TCA_CAKE_MAX + 1]; -+ unsigned bandwidth = 0; -+ unsigned diffserv = 0; -+ unsigned flowmode = 0; -+ int atm = -1; -+ SPRINT_BUF(b1); -+ -+ if (opt == NULL) -+ return 0; -+ -+ parse_rtattr_nested(tb, TCA_CAKE_MAX, opt); -+ -+ if (tb[TCA_CAKE_BASE_RATE] && -+ RTA_PAYLOAD(tb[TCA_CAKE_BASE_RATE]) >= sizeof(__u32)) { -+ bandwidth = rta_getattr_u32(tb[TCA_CAKE_BASE_RATE]); -+ if(bandwidth) -+ fprintf(f, "bandwidth %s ", sprint_rate(bandwidth, b1)); -+ else -+ fprintf(f, "unlimited"); -+ } -+ if (tb[TCA_CAKE_DIFFSERV_MODE] && -+ RTA_PAYLOAD(tb[TCA_CAKE_DIFFSERV_MODE]) >= sizeof(__u32)) { -+ diffserv = rta_getattr_u32(tb[TCA_CAKE_DIFFSERV_MODE]); -+ switch(diffserv) { -+ case 1: -+ fprintf(f, "besteffort "); -+ break; -+ case 2: -+ fprintf(f, "precedence "); -+ break; -+ case 3: -+ fprintf(f, "diffserv "); -+ break; -+ default: -+ fprintf(f, "(?diffserv?) "); -+ break; -+ }; -+ } -+ if (tb[TCA_CAKE_FLOW_MODE] && -+ RTA_PAYLOAD(tb[TCA_CAKE_FLOW_MODE]) >= sizeof(__u32)) { -+ flowmode = rta_getattr_u32(tb[TCA_CAKE_FLOW_MODE]); -+ switch(flowmode) { -+ case 0: -+ fprintf(f, "flowblind "); -+ break; -+ case 1: -+ fprintf(f, "srchost "); -+ break; -+ case 2: -+ fprintf(f, "dsthost "); -+ break; -+ case 3: -+ fprintf(f, "hosts "); -+ break; -+ case 4: -+ fprintf(f, "flows "); -+ break; -+ default: -+ fprintf(f, "(?flowmode?) "); -+ break; -+ }; -+ } -+ if (tb[TCA_CAKE_ATM] && -+ RTA_PAYLOAD(tb[TCA_CAKE_ATM]) >= sizeof(__u32)) { -+ atm = rta_getattr_u32(tb[TCA_CAKE_ATM]); -+ if (atm) -+ fprintf(f, "atm "); -+ } -+ -+ return 0; -+} -+ -+static int cake_print_xstats(struct qdisc_util *qu, FILE *f, -+ struct rtattr *xstats) -+{ -+ /* fq_codel stats format borrowed */ -+ struct tc_fq_codel_xstats *st; -+ struct tc_cake_xstats *stc; -+ SPRINT_BUF(b1); -+ -+ if (xstats == NULL) -+ return 0; -+ -+ if (RTA_PAYLOAD(xstats) < sizeof(st->type)) -+ return -1; -+ -+ st = RTA_DATA(xstats); -+ stc = RTA_DATA(xstats); -+ -+ if (st->type == TCA_FQ_CODEL_XSTATS_QDISC && RTA_PAYLOAD(xstats) >= sizeof(*st)) { -+ fprintf(f, " maxpacket %u drop_overlimit %u new_flow_count %u ecn_mark %u", -+ st->qdisc_stats.maxpacket, -+ st->qdisc_stats.drop_overlimit, -+ st->qdisc_stats.new_flow_count, -+ st->qdisc_stats.ecn_mark); -+ fprintf(f, "\n new_flows_len %u old_flows_len %u", -+ st->qdisc_stats.new_flows_len, -+ st->qdisc_stats.old_flows_len); -+ } else if (st->type == TCA_FQ_CODEL_XSTATS_CLASS && RTA_PAYLOAD(xstats) >= sizeof(*st)) { -+ fprintf(f, " deficit %d count %u lastcount %u ldelay %s", -+ st->class_stats.deficit, -+ st->class_stats.count, -+ st->class_stats.lastcount, -+ sprint_time(st->class_stats.ldelay, b1)); -+ if (st->class_stats.dropping) { -+ fprintf(f, " dropping"); -+ if (st->class_stats.drop_next < 0) -+ fprintf(f, " drop_next -%s", -+ sprint_time(-st->class_stats.drop_next, b1)); -+ else -+ fprintf(f, " drop_next %s", -+ sprint_time(st->class_stats.drop_next, b1)); -+ } -+ } else if (stc->type == 0xCAFE && RTA_PAYLOAD(xstats) >= sizeof(*stc)) { -+ int i; -+ -+ fprintf(f, " "); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, " Class %u ", i); -+ fprintf(f, "\n"); -+ -+ fprintf(f, " rate "); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%10s", sprint_rate(stc->cls[i].rate, b1)); -+ fprintf(f, "\n"); -+ -+ fprintf(f, " target"); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%10s", sprint_time(stc->cls[i].target_us, b1)); -+ fprintf(f, "\n"); -+ -+ fprintf(f, "interval"); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%10s", sprint_time(stc->cls[i].interval_us, b1)); -+ fprintf(f, "\n"); -+ -+ fprintf(f, " pkts "); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%10u", stc->cls[i].packets); -+ fprintf(f, "\n"); -+ -+ fprintf(f, " bytes "); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%10llu", stc->cls[i].bytes); -+ fprintf(f, "\n"); -+ -+ fprintf(f, " drops "); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%10u", stc->cls[i].dropped); -+ fprintf(f, "\n"); -+ -+ fprintf(f, " marks "); -+ for(i=0; i < stc->class_cnt; i++) -+ fprintf(f, "%10u", stc->cls[i].ecn_marked); -+ } else { -+ return -1; -+ } -+ return 0; -+} -+ -+struct qdisc_util cake2_qdisc_util = { -+ .id = "cake2", -+ .parse_qopt = cake_parse_opt, -+ .print_qopt = cake_print_opt, -+ .print_xstats = cake_print_xstats, -+}; -diff --git a/tc/q_efq_codel.c b/tc/q_efq_codel.c -new file mode 100644 -index 0000000..b80e5e4 ---- /dev/null -+++ b/tc/q_efq_codel.c -@@ -0,0 +1,232 @@ -+/* -+ * Fair Queue Codel -+ * -+ * Copyright (C) 2012 Eric Dumazet -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions, and the following disclaimer, -+ * without modification. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. The names of the authors may not be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * Alternatively, provided that this notice is retained in full, this -+ * software may be distributed under the terms of the GNU General -+ * Public License ("GPL") version 2, in which case the provisions of the -+ * GPL apply INSTEAD OF those given above. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "utils.h" -+#include "tc_util.h" -+ -+static void explain(void) -+{ -+ fprintf(stderr, "Usage: ... efq_codel [ limit PACKETS ] [ flows NUMBER ]\n"); -+ fprintf(stderr, " [ target TIME] [ interval TIME ]\n"); -+ fprintf(stderr, " [ quantum BYTES ] [ [no]ecn ]\n"); -+} -+ -+static int fq_codel_parse_opt(struct qdisc_util *qu, int argc, char **argv, -+ struct nlmsghdr *n) -+{ -+ unsigned limit = 0; -+ unsigned flows = 0; -+ unsigned target = 0; -+ unsigned interval = 0; -+ unsigned quantum = 0; -+ int ecn = -1; -+ struct rtattr *tail; -+ -+ while (argc > 0) { -+ if (strcmp(*argv, "limit") == 0) { -+ NEXT_ARG(); -+ if (get_unsigned(&limit, *argv, 0)) { -+ fprintf(stderr, "Illegal \"limit\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "flows") == 0) { -+ NEXT_ARG(); -+ if (get_unsigned(&flows, *argv, 0)) { -+ fprintf(stderr, "Illegal \"flows\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "quantum") == 0) { -+ NEXT_ARG(); -+ if (get_unsigned(&quantum, *argv, 0)) { -+ fprintf(stderr, "Illegal \"quantum\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "target") == 0) { -+ NEXT_ARG(); -+ if (get_time(&target, *argv)) { -+ fprintf(stderr, "Illegal \"target\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "interval") == 0) { -+ NEXT_ARG(); -+ if (get_time(&interval, *argv)) { -+ fprintf(stderr, "Illegal \"interval\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "ecn") == 0) { -+ ecn = 1; -+ } else if (strcmp(*argv, "noecn") == 0) { -+ ecn = 0; -+ } else if (strcmp(*argv, "help") == 0) { -+ explain(); -+ return -1; -+ } else { -+ fprintf(stderr, "What is \"%s\"?\n", *argv); -+ explain(); -+ return -1; -+ } -+ argc--; argv++; -+ } -+ -+ tail = NLMSG_TAIL(n); -+ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); -+ if (limit) -+ addattr_l(n, 1024, TCA_FQ_CODEL_LIMIT, &limit, sizeof(limit)); -+ if (flows) -+ addattr_l(n, 1024, TCA_FQ_CODEL_FLOWS, &flows, sizeof(flows)); -+ if (quantum) -+ addattr_l(n, 1024, TCA_FQ_CODEL_QUANTUM, &quantum, sizeof(quantum)); -+ if (interval) -+ addattr_l(n, 1024, TCA_FQ_CODEL_INTERVAL, &interval, sizeof(interval)); -+ if (target) -+ addattr_l(n, 1024, TCA_FQ_CODEL_TARGET, &target, sizeof(target)); -+ if (ecn != -1) -+ addattr_l(n, 1024, TCA_FQ_CODEL_ECN, &ecn, sizeof(ecn)); -+ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; -+ return 0; -+} -+ -+static int fq_codel_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -+{ -+ struct rtattr *tb[TCA_FQ_CODEL_MAX + 1]; -+ unsigned limit; -+ unsigned flows; -+ unsigned interval; -+ unsigned target; -+ unsigned ecn; -+ unsigned quantum; -+ SPRINT_BUF(b1); -+ -+ if (opt == NULL) -+ return 0; -+ -+ parse_rtattr_nested(tb, TCA_FQ_CODEL_MAX, opt); -+ -+ if (tb[TCA_FQ_CODEL_LIMIT] && -+ RTA_PAYLOAD(tb[TCA_FQ_CODEL_LIMIT]) >= sizeof(__u32)) { -+ limit = rta_getattr_u32(tb[TCA_FQ_CODEL_LIMIT]); -+ fprintf(f, "limit %up ", limit); -+ } -+ if (tb[TCA_FQ_CODEL_FLOWS] && -+ RTA_PAYLOAD(tb[TCA_FQ_CODEL_FLOWS]) >= sizeof(__u32)) { -+ flows = rta_getattr_u32(tb[TCA_FQ_CODEL_FLOWS]); -+ fprintf(f, "flows %u ", flows); -+ } -+ if (tb[TCA_FQ_CODEL_QUANTUM] && -+ RTA_PAYLOAD(tb[TCA_FQ_CODEL_QUANTUM]) >= sizeof(__u32)) { -+ quantum = rta_getattr_u32(tb[TCA_FQ_CODEL_QUANTUM]); -+ fprintf(f, "quantum %u ", quantum); -+ } -+ if (tb[TCA_FQ_CODEL_TARGET] && -+ RTA_PAYLOAD(tb[TCA_FQ_CODEL_TARGET]) >= sizeof(__u32)) { -+ target = rta_getattr_u32(tb[TCA_FQ_CODEL_TARGET]); -+ fprintf(f, "target %s ", sprint_time(target, b1)); -+ } -+ if (tb[TCA_FQ_CODEL_INTERVAL] && -+ RTA_PAYLOAD(tb[TCA_FQ_CODEL_INTERVAL]) >= sizeof(__u32)) { -+ interval = rta_getattr_u32(tb[TCA_FQ_CODEL_INTERVAL]); -+ fprintf(f, "interval %s ", sprint_time(interval, b1)); -+ } -+ if (tb[TCA_FQ_CODEL_ECN] && -+ RTA_PAYLOAD(tb[TCA_FQ_CODEL_ECN]) >= sizeof(__u32)) { -+ ecn = rta_getattr_u32(tb[TCA_FQ_CODEL_ECN]); -+ if (ecn) -+ fprintf(f, "ecn "); -+ } -+ -+ return 0; -+} -+ -+static int fq_codel_print_xstats(struct qdisc_util *qu, FILE *f, -+ struct rtattr *xstats) -+{ -+ struct tc_fq_codel_xstats *st; -+ SPRINT_BUF(b1); -+ -+ if (xstats == NULL) -+ return 0; -+ -+ if (RTA_PAYLOAD(xstats) < sizeof(*st)) -+ return -1; -+ -+ st = RTA_DATA(xstats); -+ if (st->type == TCA_FQ_CODEL_XSTATS_QDISC) { -+ fprintf(f, " maxpacket %u drop_overlimit %u new_flow_count %u ecn_mark %u", -+ st->qdisc_stats.maxpacket, -+ st->qdisc_stats.drop_overlimit, -+ st->qdisc_stats.new_flow_count, -+ st->qdisc_stats.ecn_mark); -+ fprintf(f, "\n new_flows_len %u old_flows_len %u", -+ st->qdisc_stats.new_flows_len, -+ st->qdisc_stats.old_flows_len); -+ } -+ if (st->type == TCA_FQ_CODEL_XSTATS_CLASS) { -+ fprintf(f, " deficit %d count %u lastcount %u ldelay %s", -+ st->class_stats.deficit, -+ st->class_stats.count, -+ st->class_stats.lastcount, -+ sprint_time(st->class_stats.ldelay, b1)); -+ if (st->class_stats.dropping) { -+ fprintf(f, " dropping"); -+ if (st->class_stats.drop_next < 0) -+ fprintf(f, " drop_next -%s", -+ sprint_time(-st->class_stats.drop_next, b1)); -+ else -+ fprintf(f, " drop_next %s", -+ sprint_time(st->class_stats.drop_next, b1)); -+ } -+ } -+ return 0; -+ -+} -+ -+struct qdisc_util efq_codel_qdisc_util = { -+ .id = "efq_codel", -+ .parse_qopt = fq_codel_parse_opt, -+ .print_qopt = fq_codel_print_opt, -+ .print_xstats = fq_codel_print_xstats, -+}; -diff --git a/tc/q_nfq_codel.c b/tc/q_nfq_codel.c -new file mode 100644 -index 0000000..ef24909 ---- /dev/null -+++ b/tc/q_nfq_codel.c -@@ -0,0 +1,232 @@ -+/* -+ * Fair Queue Codel -+ * -+ * Copyright (C) 2012 Eric Dumazet -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions, and the following disclaimer, -+ * without modification. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. The names of the authors may not be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * Alternatively, provided that this notice is retained in full, this -+ * software may be distributed under the terms of the GNU General -+ * Public License ("GPL") version 2, in which case the provisions of the -+ * GPL apply INSTEAD OF those given above. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "utils.h" -+#include "tc_util.h" -+ -+static void explain(void) -+{ -+ fprintf(stderr, "Usage: ... nfq_codel [ limit PACKETS ] [ flows NUMBER ]\n"); -+ fprintf(stderr, " [ target TIME] [ interval TIME ]\n"); -+ fprintf(stderr, " [ quantum BYTES ] [ [no]ecn ]\n"); -+} -+ -+static int fq_codel_parse_opt(struct qdisc_util *qu, int argc, char **argv, -+ struct nlmsghdr *n) -+{ -+ unsigned limit = 0; -+ unsigned flows = 0; -+ unsigned target = 0; -+ unsigned interval = 0; -+ unsigned quantum = 0; -+ int ecn = -1; -+ struct rtattr *tail; -+ -+ while (argc > 0) { -+ if (strcmp(*argv, "limit") == 0) { -+ NEXT_ARG(); -+ if (get_unsigned(&limit, *argv, 0)) { -+ fprintf(stderr, "Illegal \"limit\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "flows") == 0) { -+ NEXT_ARG(); -+ if (get_unsigned(&flows, *argv, 0)) { -+ fprintf(stderr, "Illegal \"flows\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "quantum") == 0) { -+ NEXT_ARG(); -+ if (get_unsigned(&quantum, *argv, 0)) { -+ fprintf(stderr, "Illegal \"quantum\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "target") == 0) { -+ NEXT_ARG(); -+ if (get_time(&target, *argv)) { -+ fprintf(stderr, "Illegal \"target\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "interval") == 0) { -+ NEXT_ARG(); -+ if (get_time(&interval, *argv)) { -+ fprintf(stderr, "Illegal \"interval\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "ecn") == 0) { -+ ecn = 1; -+ } else if (strcmp(*argv, "noecn") == 0) { -+ ecn = 0; -+ } else if (strcmp(*argv, "help") == 0) { -+ explain(); -+ return -1; -+ } else { -+ fprintf(stderr, "What is \"%s\"?\n", *argv); -+ explain(); -+ return -1; -+ } -+ argc--; argv++; -+ } -+ -+ tail = NLMSG_TAIL(n); -+ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); -+ if (limit) -+ addattr_l(n, 1024, TCA_FQ_CODEL_LIMIT, &limit, sizeof(limit)); -+ if (flows) -+ addattr_l(n, 1024, TCA_FQ_CODEL_FLOWS, &flows, sizeof(flows)); -+ if (quantum) -+ addattr_l(n, 1024, TCA_FQ_CODEL_QUANTUM, &quantum, sizeof(quantum)); -+ if (interval) -+ addattr_l(n, 1024, TCA_FQ_CODEL_INTERVAL, &interval, sizeof(interval)); -+ if (target) -+ addattr_l(n, 1024, TCA_FQ_CODEL_TARGET, &target, sizeof(target)); -+ if (ecn != -1) -+ addattr_l(n, 1024, TCA_FQ_CODEL_ECN, &ecn, sizeof(ecn)); -+ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; -+ return 0; -+} -+ -+static int fq_codel_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -+{ -+ struct rtattr *tb[TCA_FQ_CODEL_MAX + 1]; -+ unsigned limit; -+ unsigned flows; -+ unsigned interval; -+ unsigned target; -+ unsigned ecn; -+ unsigned quantum; -+ SPRINT_BUF(b1); -+ -+ if (opt == NULL) -+ return 0; -+ -+ parse_rtattr_nested(tb, TCA_FQ_CODEL_MAX, opt); -+ -+ if (tb[TCA_FQ_CODEL_LIMIT] && -+ RTA_PAYLOAD(tb[TCA_FQ_CODEL_LIMIT]) >= sizeof(__u32)) { -+ limit = rta_getattr_u32(tb[TCA_FQ_CODEL_LIMIT]); -+ fprintf(f, "limit %up ", limit); -+ } -+ if (tb[TCA_FQ_CODEL_FLOWS] && -+ RTA_PAYLOAD(tb[TCA_FQ_CODEL_FLOWS]) >= sizeof(__u32)) { -+ flows = rta_getattr_u32(tb[TCA_FQ_CODEL_FLOWS]); -+ fprintf(f, "flows %u ", flows); -+ } -+ if (tb[TCA_FQ_CODEL_QUANTUM] && -+ RTA_PAYLOAD(tb[TCA_FQ_CODEL_QUANTUM]) >= sizeof(__u32)) { -+ quantum = rta_getattr_u32(tb[TCA_FQ_CODEL_QUANTUM]); -+ fprintf(f, "quantum %u ", quantum); -+ } -+ if (tb[TCA_FQ_CODEL_TARGET] && -+ RTA_PAYLOAD(tb[TCA_FQ_CODEL_TARGET]) >= sizeof(__u32)) { -+ target = rta_getattr_u32(tb[TCA_FQ_CODEL_TARGET]); -+ fprintf(f, "target %s ", sprint_time(target, b1)); -+ } -+ if (tb[TCA_FQ_CODEL_INTERVAL] && -+ RTA_PAYLOAD(tb[TCA_FQ_CODEL_INTERVAL]) >= sizeof(__u32)) { -+ interval = rta_getattr_u32(tb[TCA_FQ_CODEL_INTERVAL]); -+ fprintf(f, "interval %s ", sprint_time(interval, b1)); -+ } -+ if (tb[TCA_FQ_CODEL_ECN] && -+ RTA_PAYLOAD(tb[TCA_FQ_CODEL_ECN]) >= sizeof(__u32)) { -+ ecn = rta_getattr_u32(tb[TCA_FQ_CODEL_ECN]); -+ if (ecn) -+ fprintf(f, "ecn "); -+ } -+ -+ return 0; -+} -+ -+static int fq_codel_print_xstats(struct qdisc_util *qu, FILE *f, -+ struct rtattr *xstats) -+{ -+ struct tc_fq_codel_xstats *st; -+ SPRINT_BUF(b1); -+ -+ if (xstats == NULL) -+ return 0; -+ -+ if (RTA_PAYLOAD(xstats) < sizeof(*st)) -+ return -1; -+ -+ st = RTA_DATA(xstats); -+ if (st->type == TCA_FQ_CODEL_XSTATS_QDISC) { -+ fprintf(f, " maxpacket %u drop_overlimit %u new_flow_count %u ecn_mark %u", -+ st->qdisc_stats.maxpacket, -+ st->qdisc_stats.drop_overlimit, -+ st->qdisc_stats.new_flow_count, -+ st->qdisc_stats.ecn_mark); -+ fprintf(f, "\n new_flows_len %u old_flows_len %u", -+ st->qdisc_stats.new_flows_len, -+ st->qdisc_stats.old_flows_len); -+ } -+ if (st->type == TCA_FQ_CODEL_XSTATS_CLASS) { -+ fprintf(f, " deficit %d count %u lastcount %u ldelay %s", -+ st->class_stats.deficit, -+ st->class_stats.count, -+ st->class_stats.lastcount, -+ sprint_time(st->class_stats.ldelay, b1)); -+ if (st->class_stats.dropping) { -+ fprintf(f, " dropping"); -+ if (st->class_stats.drop_next < 0) -+ fprintf(f, " drop_next -%s", -+ sprint_time(-st->class_stats.drop_next, b1)); -+ else -+ fprintf(f, " drop_next %s", -+ sprint_time(st->class_stats.drop_next, b1)); -+ } -+ } -+ return 0; -+ -+} -+ -+struct qdisc_util nfq_codel_qdisc_util = { -+ .id = "nfq_codel", -+ .parse_qopt = fq_codel_parse_opt, -+ .print_qopt = fq_codel_print_opt, -+ .print_xstats = fq_codel_print_xstats, -+}; -diff --git a/tc/q_ns2_codel.c b/tc/q_ns2_codel.c -new file mode 100644 -index 0000000..223a971 ---- /dev/null -+++ b/tc/q_ns2_codel.c -@@ -0,0 +1,188 @@ -+/* -+ * Codel - The Controlled-Delay Active Queue Management algorithm -+ * -+ * Copyright (C) 2011-2012 Kathleen Nichols -+ * Copyright (C) 2011-2012 Van Jacobson -+ * Copyright (C) 2012 Michael D. Taht -+ * Copyright (C) 2012 Eric Dumazet -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions, and the following disclaimer, -+ * without modification. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. The names of the authors may not be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * Alternatively, provided that this notice is retained in full, this -+ * software may be distributed under the terms of the GNU General -+ * Public License ("GPL") version 2, in which case the provisions of the -+ * GPL apply INSTEAD OF those given above. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "utils.h" -+#include "tc_util.h" -+ -+static void explain(void) -+{ -+ fprintf(stderr, "Usage: ... ns2_codel [ limit PACKETS ] [ target TIME]\n"); -+ fprintf(stderr, " [ interval TIME ] [ ecn | noecn ]\n"); -+} -+ -+static int codel_parse_opt(struct qdisc_util *qu, int argc, char **argv, -+ struct nlmsghdr *n) -+{ -+ unsigned limit = 0; -+ unsigned target = 0; -+ unsigned interval = 0; -+ int ecn = -1; -+ struct rtattr *tail; -+ -+ while (argc > 0) { -+ if (strcmp(*argv, "limit") == 0) { -+ NEXT_ARG(); -+ if (get_unsigned(&limit, *argv, 0)) { -+ fprintf(stderr, "Illegal \"limit\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "target") == 0) { -+ NEXT_ARG(); -+ if (get_time(&target, *argv)) { -+ fprintf(stderr, "Illegal \"target\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "interval") == 0) { -+ NEXT_ARG(); -+ if (get_time(&interval, *argv)) { -+ fprintf(stderr, "Illegal \"interval\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "ecn") == 0) { -+ ecn = 1; -+ } else if (strcmp(*argv, "noecn") == 0) { -+ ecn = 0; -+ } else if (strcmp(*argv, "help") == 0) { -+ explain(); -+ return -1; -+ } else { -+ fprintf(stderr, "What is \"%s\"?\n", *argv); -+ explain(); -+ return -1; -+ } -+ argc--; argv++; -+ } -+ -+ tail = NLMSG_TAIL(n); -+ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); -+ if (limit) -+ addattr_l(n, 1024, TCA_CODEL_LIMIT, &limit, sizeof(limit)); -+ if (interval) -+ addattr_l(n, 1024, TCA_CODEL_INTERVAL, &interval, sizeof(interval)); -+ if (target) -+ addattr_l(n, 1024, TCA_CODEL_TARGET, &target, sizeof(target)); -+ if (ecn != -1) -+ addattr_l(n, 1024, TCA_CODEL_ECN, &ecn, sizeof(ecn)); -+ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; -+ return 0; -+} -+ -+static int codel_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -+{ -+ struct rtattr *tb[TCA_CODEL_MAX + 1]; -+ unsigned limit; -+ unsigned interval; -+ unsigned target; -+ unsigned ecn; -+ SPRINT_BUF(b1); -+ -+ if (opt == NULL) -+ return 0; -+ -+ parse_rtattr_nested(tb, TCA_CODEL_MAX, opt); -+ -+ if (tb[TCA_CODEL_LIMIT] && -+ RTA_PAYLOAD(tb[TCA_CODEL_LIMIT]) >= sizeof(__u32)) { -+ limit = rta_getattr_u32(tb[TCA_CODEL_LIMIT]); -+ fprintf(f, "limit %up ", limit); -+ } -+ if (tb[TCA_CODEL_TARGET] && -+ RTA_PAYLOAD(tb[TCA_CODEL_TARGET]) >= sizeof(__u32)) { -+ target = rta_getattr_u32(tb[TCA_CODEL_TARGET]); -+ fprintf(f, "target %s ", sprint_time(target, b1)); -+ } -+ if (tb[TCA_CODEL_INTERVAL] && -+ RTA_PAYLOAD(tb[TCA_CODEL_INTERVAL]) >= sizeof(__u32)) { -+ interval = rta_getattr_u32(tb[TCA_CODEL_INTERVAL]); -+ fprintf(f, "interval %s ", sprint_time(interval, b1)); -+ } -+ if (tb[TCA_CODEL_ECN] && -+ RTA_PAYLOAD(tb[TCA_CODEL_ECN]) >= sizeof(__u32)) { -+ ecn = rta_getattr_u32(tb[TCA_CODEL_ECN]); -+ if (ecn) -+ fprintf(f, "ecn "); -+ } -+ -+ return 0; -+} -+ -+static int codel_print_xstats(struct qdisc_util *qu, FILE *f, -+ struct rtattr *xstats) -+{ -+ struct tc_codel_xstats *st; -+ SPRINT_BUF(b1); -+ -+ if (xstats == NULL) -+ return 0; -+ -+ if (RTA_PAYLOAD(xstats) < sizeof(*st)) -+ return -1; -+ -+ st = RTA_DATA(xstats); -+ fprintf(f, " count %u lastcount %u ldelay %s", -+ st->count, st->lastcount, sprint_time(st->ldelay, b1)); -+ if (st->dropping) -+ fprintf(f, " dropping"); -+ if (st->drop_next < 0) -+ fprintf(f, " drop_next -%s", sprint_time(-st->drop_next, b1)); -+ else -+ fprintf(f, " drop_next %s", sprint_time(st->drop_next, b1)); -+ fprintf(f, "\n maxpacket %u ecn_mark %u drop_overlimit %u", -+ st->maxpacket, st->ecn_mark, st->drop_overlimit); -+ return 0; -+ -+} -+ -+struct qdisc_util ns2_codel_qdisc_util = { -+ .id = "ns2_codel", -+ .parse_qopt = codel_parse_opt, -+ .print_qopt = codel_print_opt, -+ .print_xstats = codel_print_xstats, -+}; -diff --git a/tc/q_ns4_codel.c b/tc/q_ns4_codel.c -new file mode 100644 -index 0000000..0aaa349 ---- /dev/null -+++ b/tc/q_ns4_codel.c -@@ -0,0 +1,188 @@ -+/* -+ * Codel - The Controlled-Delay Active Queue Management algorithm -+ * -+ * Copyright (C) 2011-2012 Kathleen Nichols -+ * Copyright (C) 2011-2012 Van Jacobson -+ * Copyright (C) 2012 Michael D. Taht -+ * Copyright (C) 2012 Eric Dumazet -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions, and the following disclaimer, -+ * without modification. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. The names of the authors may not be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * Alternatively, provided that this notice is retained in full, this -+ * software may be distributed under the terms of the GNU General -+ * Public License ("GPL") version 2, in which case the provisions of the -+ * GPL apply INSTEAD OF those given above. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "utils.h" -+#include "tc_util.h" -+ -+static void explain(void) -+{ -+ fprintf(stderr, "Usage: ... ns4_codel [ limit PACKETS ] [ target TIME]\n"); -+ fprintf(stderr, " [ interval TIME ] [ ecn | noecn ]\n"); -+} -+ -+static int codel_parse_opt(struct qdisc_util *qu, int argc, char **argv, -+ struct nlmsghdr *n) -+{ -+ unsigned limit = 0; -+ unsigned target = 0; -+ unsigned interval = 0; -+ int ecn = -1; -+ struct rtattr *tail; -+ -+ while (argc > 0) { -+ if (strcmp(*argv, "limit") == 0) { -+ NEXT_ARG(); -+ if (get_unsigned(&limit, *argv, 0)) { -+ fprintf(stderr, "Illegal \"limit\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "target") == 0) { -+ NEXT_ARG(); -+ if (get_time(&target, *argv)) { -+ fprintf(stderr, "Illegal \"target\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "interval") == 0) { -+ NEXT_ARG(); -+ if (get_time(&interval, *argv)) { -+ fprintf(stderr, "Illegal \"interval\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "ecn") == 0) { -+ ecn = 1; -+ } else if (strcmp(*argv, "noecn") == 0) { -+ ecn = 0; -+ } else if (strcmp(*argv, "help") == 0) { -+ explain(); -+ return -1; -+ } else { -+ fprintf(stderr, "What is \"%s\"?\n", *argv); -+ explain(); -+ return -1; -+ } -+ argc--; argv++; -+ } -+ -+ tail = NLMSG_TAIL(n); -+ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); -+ if (limit) -+ addattr_l(n, 1024, TCA_CODEL_LIMIT, &limit, sizeof(limit)); -+ if (interval) -+ addattr_l(n, 1024, TCA_CODEL_INTERVAL, &interval, sizeof(interval)); -+ if (target) -+ addattr_l(n, 1024, TCA_CODEL_TARGET, &target, sizeof(target)); -+ if (ecn != -1) -+ addattr_l(n, 1024, TCA_CODEL_ECN, &ecn, sizeof(ecn)); -+ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; -+ return 0; -+} -+ -+static int codel_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -+{ -+ struct rtattr *tb[TCA_CODEL_MAX + 1]; -+ unsigned limit; -+ unsigned interval; -+ unsigned target; -+ unsigned ecn; -+ SPRINT_BUF(b1); -+ -+ if (opt == NULL) -+ return 0; -+ -+ parse_rtattr_nested(tb, TCA_CODEL_MAX, opt); -+ -+ if (tb[TCA_CODEL_LIMIT] && -+ RTA_PAYLOAD(tb[TCA_CODEL_LIMIT]) >= sizeof(__u32)) { -+ limit = rta_getattr_u32(tb[TCA_CODEL_LIMIT]); -+ fprintf(f, "limit %up ", limit); -+ } -+ if (tb[TCA_CODEL_TARGET] && -+ RTA_PAYLOAD(tb[TCA_CODEL_TARGET]) >= sizeof(__u32)) { -+ target = rta_getattr_u32(tb[TCA_CODEL_TARGET]); -+ fprintf(f, "target %s ", sprint_time(target, b1)); -+ } -+ if (tb[TCA_CODEL_INTERVAL] && -+ RTA_PAYLOAD(tb[TCA_CODEL_INTERVAL]) >= sizeof(__u32)) { -+ interval = rta_getattr_u32(tb[TCA_CODEL_INTERVAL]); -+ fprintf(f, "interval %s ", sprint_time(interval, b1)); -+ } -+ if (tb[TCA_CODEL_ECN] && -+ RTA_PAYLOAD(tb[TCA_CODEL_ECN]) >= sizeof(__u32)) { -+ ecn = rta_getattr_u32(tb[TCA_CODEL_ECN]); -+ if (ecn) -+ fprintf(f, "ecn "); -+ } -+ -+ return 0; -+} -+ -+static int codel_print_xstats(struct qdisc_util *qu, FILE *f, -+ struct rtattr *xstats) -+{ -+ struct tc_codel_xstats *st; -+ SPRINT_BUF(b1); -+ -+ if (xstats == NULL) -+ return 0; -+ -+ if (RTA_PAYLOAD(xstats) < sizeof(*st)) -+ return -1; -+ -+ st = RTA_DATA(xstats); -+ fprintf(f, " count %u lastcount %u ldelay %s", -+ st->count, st->lastcount, sprint_time(st->ldelay, b1)); -+ if (st->dropping) -+ fprintf(f, " dropping"); -+ if (st->drop_next < 0) -+ fprintf(f, " drop_next -%s", sprint_time(-st->drop_next, b1)); -+ else -+ fprintf(f, " drop_next %s", sprint_time(st->drop_next, b1)); -+ fprintf(f, "\n maxpacket %u ecn_mark %u drop_overlimit %u", -+ st->maxpacket, st->ecn_mark, st->drop_overlimit); -+ return 0; -+ -+} -+ -+struct qdisc_util ns4_codel_qdisc_util = { -+ .id = "ns4_codel", -+ .parse_qopt = codel_parse_opt, -+ .print_qopt = codel_print_opt, -+ .print_xstats = codel_print_xstats, -+}; -diff --git a/tc/q_pfq_codel.c b/tc/q_pfq_codel.c -new file mode 100644 -index 0000000..52c5160 ---- /dev/null -+++ b/tc/q_pfq_codel.c -@@ -0,0 +1,232 @@ -+/* -+ * Fair Queue Codel -+ * -+ * Copyright (C) 2012 Eric Dumazet -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions, and the following disclaimer, -+ * without modification. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. The names of the authors may not be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * Alternatively, provided that this notice is retained in full, this -+ * software may be distributed under the terms of the GNU General -+ * Public License ("GPL") version 2, in which case the provisions of the -+ * GPL apply INSTEAD OF those given above. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "utils.h" -+#include "tc_util.h" -+ -+static void explain(void) -+{ -+ fprintf(stderr, "Usage: ... pfq_codel [ limit PACKETS ] [ flows NUMBER ]\n"); -+ fprintf(stderr, " [ target TIME] [ interval TIME ]\n"); -+ fprintf(stderr, " [ quantum BYTES ] [ [no]ecn ]\n"); -+} -+ -+static int fq_codel_parse_opt(struct qdisc_util *qu, int argc, char **argv, -+ struct nlmsghdr *n) -+{ -+ unsigned limit = 0; -+ unsigned flows = 0; -+ unsigned target = 0; -+ unsigned interval = 0; -+ unsigned quantum = 0; -+ int ecn = -1; -+ struct rtattr *tail; -+ -+ while (argc > 0) { -+ if (strcmp(*argv, "limit") == 0) { -+ NEXT_ARG(); -+ if (get_unsigned(&limit, *argv, 0)) { -+ fprintf(stderr, "Illegal \"limit\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "flows") == 0) { -+ NEXT_ARG(); -+ if (get_unsigned(&flows, *argv, 0)) { -+ fprintf(stderr, "Illegal \"flows\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "quantum") == 0) { -+ NEXT_ARG(); -+ if (get_unsigned(&quantum, *argv, 0)) { -+ fprintf(stderr, "Illegal \"quantum\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "target") == 0) { -+ NEXT_ARG(); -+ if (get_time(&target, *argv)) { -+ fprintf(stderr, "Illegal \"target\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "interval") == 0) { -+ NEXT_ARG(); -+ if (get_time(&interval, *argv)) { -+ fprintf(stderr, "Illegal \"interval\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "ecn") == 0) { -+ ecn = 1; -+ } else if (strcmp(*argv, "noecn") == 0) { -+ ecn = 0; -+ } else if (strcmp(*argv, "help") == 0) { -+ explain(); -+ return -1; -+ } else { -+ fprintf(stderr, "What is \"%s\"?\n", *argv); -+ explain(); -+ return -1; -+ } -+ argc--; argv++; -+ } -+ -+ tail = NLMSG_TAIL(n); -+ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); -+ if (limit) -+ addattr_l(n, 1024, TCA_FQ_CODEL_LIMIT, &limit, sizeof(limit)); -+ if (flows) -+ addattr_l(n, 1024, TCA_FQ_CODEL_FLOWS, &flows, sizeof(flows)); -+ if (quantum) -+ addattr_l(n, 1024, TCA_FQ_CODEL_QUANTUM, &quantum, sizeof(quantum)); -+ if (interval) -+ addattr_l(n, 1024, TCA_FQ_CODEL_INTERVAL, &interval, sizeof(interval)); -+ if (target) -+ addattr_l(n, 1024, TCA_FQ_CODEL_TARGET, &target, sizeof(target)); -+ if (ecn != -1) -+ addattr_l(n, 1024, TCA_FQ_CODEL_ECN, &ecn, sizeof(ecn)); -+ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; -+ return 0; -+} -+ -+static int fq_codel_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -+{ -+ struct rtattr *tb[TCA_FQ_CODEL_MAX + 1]; -+ unsigned limit; -+ unsigned flows; -+ unsigned interval; -+ unsigned target; -+ unsigned ecn; -+ unsigned quantum; -+ SPRINT_BUF(b1); -+ -+ if (opt == NULL) -+ return 0; -+ -+ parse_rtattr_nested(tb, TCA_FQ_CODEL_MAX, opt); -+ -+ if (tb[TCA_FQ_CODEL_LIMIT] && -+ RTA_PAYLOAD(tb[TCA_FQ_CODEL_LIMIT]) >= sizeof(__u32)) { -+ limit = rta_getattr_u32(tb[TCA_FQ_CODEL_LIMIT]); -+ fprintf(f, "limit %up ", limit); -+ } -+ if (tb[TCA_FQ_CODEL_FLOWS] && -+ RTA_PAYLOAD(tb[TCA_FQ_CODEL_FLOWS]) >= sizeof(__u32)) { -+ flows = rta_getattr_u32(tb[TCA_FQ_CODEL_FLOWS]); -+ fprintf(f, "flows %u ", flows); -+ } -+ if (tb[TCA_FQ_CODEL_QUANTUM] && -+ RTA_PAYLOAD(tb[TCA_FQ_CODEL_QUANTUM]) >= sizeof(__u32)) { -+ quantum = rta_getattr_u32(tb[TCA_FQ_CODEL_QUANTUM]); -+ fprintf(f, "quantum %u ", quantum); -+ } -+ if (tb[TCA_FQ_CODEL_TARGET] && -+ RTA_PAYLOAD(tb[TCA_FQ_CODEL_TARGET]) >= sizeof(__u32)) { -+ target = rta_getattr_u32(tb[TCA_FQ_CODEL_TARGET]); -+ fprintf(f, "target %s ", sprint_time(target, b1)); -+ } -+ if (tb[TCA_FQ_CODEL_INTERVAL] && -+ RTA_PAYLOAD(tb[TCA_FQ_CODEL_INTERVAL]) >= sizeof(__u32)) { -+ interval = rta_getattr_u32(tb[TCA_FQ_CODEL_INTERVAL]); -+ fprintf(f, "interval %s ", sprint_time(interval, b1)); -+ } -+ if (tb[TCA_FQ_CODEL_ECN] && -+ RTA_PAYLOAD(tb[TCA_FQ_CODEL_ECN]) >= sizeof(__u32)) { -+ ecn = rta_getattr_u32(tb[TCA_FQ_CODEL_ECN]); -+ if (ecn) -+ fprintf(f, "ecn "); -+ } -+ -+ return 0; -+} -+ -+static int fq_codel_print_xstats(struct qdisc_util *qu, FILE *f, -+ struct rtattr *xstats) -+{ -+ struct tc_fq_codel_xstats *st; -+ SPRINT_BUF(b1); -+ -+ if (xstats == NULL) -+ return 0; -+ -+ if (RTA_PAYLOAD(xstats) < sizeof(*st)) -+ return -1; -+ -+ st = RTA_DATA(xstats); -+ if (st->type == TCA_FQ_CODEL_XSTATS_QDISC) { -+ fprintf(f, " maxpacket %u drop_overlimit %u new_flow_count %u ecn_mark %u", -+ st->qdisc_stats.maxpacket, -+ st->qdisc_stats.drop_overlimit, -+ st->qdisc_stats.new_flow_count, -+ st->qdisc_stats.ecn_mark); -+ fprintf(f, "\n new_flows_len %u old_flows_len %u", -+ st->qdisc_stats.new_flows_len, -+ st->qdisc_stats.old_flows_len); -+ } -+ if (st->type == TCA_FQ_CODEL_XSTATS_CLASS) { -+ fprintf(f, " deficit %d count %u lastcount %u ldelay %s", -+ st->class_stats.deficit, -+ st->class_stats.count, -+ st->class_stats.lastcount, -+ sprint_time(st->class_stats.ldelay, b1)); -+ if (st->class_stats.dropping) { -+ fprintf(f, " dropping"); -+ if (st->class_stats.drop_next < 0) -+ fprintf(f, " drop_next -%s", -+ sprint_time(-st->class_stats.drop_next, b1)); -+ else -+ fprintf(f, " drop_next %s", -+ sprint_time(st->class_stats.drop_next, b1)); -+ } -+ } -+ return 0; -+ -+} -+ -+struct qdisc_util pfq_codel_qdisc_util = { -+ .id = "pfq_codel", -+ .parse_qopt = fq_codel_parse_opt, -+ .print_qopt = fq_codel_print_opt, -+ .print_xstats = fq_codel_print_xstats, -+}; --- -2.1.4 - diff --git a/net/iproute2/patches/601-iproute2-add-fq_pie-support.patch b/net/iproute2/patches/601-iproute2-add-fq_pie-support.patch deleted file mode 100644 index d792a6c..0000000 --- a/net/iproute2/patches/601-iproute2-add-fq_pie-support.patch +++ /dev/null @@ -1,488 +0,0 @@ -From 57129ca50caa256bf4ef4a5e60c7205f37156915 Mon Sep 17 00:00:00 2001 -From: Dave Taht -Date: Sat, 2 May 2015 01:05:20 -0700 -Subject: [PATCH 2/2] iproute2: add fq_pie support - ---- - include/linux/pkt_sched.h | 46 ++++++ - tc/Makefile | 1 + - tc/q_fq_pie.c | 398 ++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 445 insertions(+) - create mode 100644 tc/q_fq_pie.c - -diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h -index a1d7b67..582f19a 100644 ---- a/include/linux/pkt_sched.h -+++ b/include/linux/pkt_sched.h -@@ -821,6 +821,52 @@ struct tc_hhf_xstats { - __u32 hh_cur_count; /* number of current heavy-hitters */ - }; - -+/* FQ_PIE */ -+enum { -+ TCA_FQ_PIE_UNSPEC, -+ TCA_FQ_PIE_TARGET, -+ TCA_FQ_PIE_TUPDATE, -+ TCA_FQ_PIE_ALPHA, -+ TCA_FQ_PIE_BETA, -+ TCA_FQ_PIE_ECN, -+ TCA_FQ_PIE_BYTEMODE, -+ TCA_FQ_PIE_PLIMIT, /* limit of total number of packets in queue */ -+ TCA_FQ_PIE_FLOW_PLIMIT, /* limit of packets per flow */ -+ TCA_FQ_PIE_QUANTUM, /* RR quantum */ -+ TCA_FQ_PIE_INITIAL_QUANTUM, /* RR quantum for new flow */ -+ TCA_FQ_PIE_RATE_ENABLE, /* enable/disable rate limiting */ -+ TCA_FQ_PIE_FLOW_DEFAULT_RATE, /* obsolete, do not use */ -+ TCA_FQ_PIE_FLOW_MAX_RATE, /* per flow max rate */ -+ TCA_FQ_PIE_BUCKETS_LOG, /* log2(number of buckets) */ -+ TCA_FQ_PIE_FLOW_REFILL_DELAY, /* flow credit refill delay in usec */ -+ __TCA_FQ_PIE_MAX -+}; -+ -+#define TCA_FQ_PIE_MAX (__TCA_FQ_PIE_MAX - 1) -+ -+struct tc_fq_pie_qd_stats { -+ __u32 prob; /* current probability */ -+ __u32 delay; /* current delay in ms */ -+ __u32 avg_dq_rate; /* current average dq_rate in bits/pie_time */ -+ __u32 packets_in; /* total number of packets enqueued */ -+ __u32 dropped; /* packets dropped due to pie_action */ -+ __u32 overlimit; /* dropped due to lack of space in queue */ -+ __u32 maxq; /* maximum queue size */ -+ __u32 ecn_mark; /* packets marked with ecn*/ -+ __u64 gc_flows; -+ __u64 highprio_packets; -+ __u64 tcp_retrans; -+ __u64 throttled; -+ __u64 flows_plimit; -+ __u64 pkts_too_long; -+ __u64 allocation_errors; -+ __s64 time_next_delayed_flow; -+ __u32 flows; -+ __u32 inactive_flows; -+ __u32 throttled_flows; -+ __u32 pad; -+}; -+ - /* PIE */ - enum { - TCA_PIE_UNSPEC, -diff --git a/tc/Makefile b/tc/Makefile -index 69b83c7..45af89c 100644 ---- a/tc/Makefile -+++ b/tc/Makefile -@@ -66,6 +66,7 @@ TCMODULES += q_pfq_codel.o - TCMODULES += q_ns2_codel.o - TCMODULES += q_ns4_codel.o - TCMODULES += q_fq.o -+TCMODULES += q_fq_pie.o - TCMODULES += q_pie.o - TCMODULES += q_cake.o - TCMODULES += q_cake0.o -diff --git a/tc/q_fq_pie.c b/tc/q_fq_pie.c -new file mode 100644 -index 0000000..647be59 ---- /dev/null -+++ b/tc/q_fq_pie.c -@@ -0,0 +1,398 @@ -+/* -+ * Fair Queue Pie -+ * -+ * Copyright (C) 2014 Hironori Okano -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions, and the following disclaimer, -+ * without modification. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. The names of the authors may not be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * Alternatively, provided that this notice is retained in full, this -+ * software may be distributed under the terms of the GNU General -+ * Public License ("GPL") version 2, in which case the provisions of the -+ * GPL apply INSTEAD OF those given above. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "utils.h" -+#include "tc_util.h" -+ -+#define ALPHA_MAX 32 -+#define ALPHA_MIN 0 -+#define BETA_MAX 32 -+#define BETA_MIN 0 -+ -+static void explain(void) -+{ -+ fprintf(stderr, "Usage: ... pie [ limit PACKETS ][ target TIME us]\n"); -+ fprintf(stderr, " [ tupdate TIME us][ alpha ALPHA ]"); -+ fprintf(stderr, "[beta BETA ][bytemode | nobytemode][ecn | noecn ]\n"); -+ -+ fprintf(stderr, "Usage: ... fq [ limit PACKETS ] [ flow_limit PACKETS ]\n"); -+ fprintf(stderr, " [ quantum BYTES ] [ initial_quantum BYTES ]\n"); -+ fprintf(stderr, " [ maxrate RATE ] [ buckets NUMBER ]\n"); -+ fprintf(stderr, " [ [no]pacing ]\n"); -+} -+ -+static unsigned int ilog2(unsigned int val) -+{ -+ unsigned int res = 0; -+ -+ val--; -+ while (val) { -+ res++; -+ val >>= 1; -+ } -+ return res; -+} -+ -+static int fq_pie_parse_opt(struct qdisc_util *qu, int argc, char **argv, -+ struct nlmsghdr *n) -+{ -+ unsigned int limit = 0; -+ unsigned int target = 0; -+ unsigned int tupdate = 0; -+ unsigned int alpha = 0; -+ unsigned int beta = 0; -+ int ecn = -1; -+ int bytemode = -1; -+ unsigned int plimit; -+ unsigned int flow_plimit; -+ unsigned int quantum; -+ unsigned int initial_quantum; -+ unsigned int buckets = 0; -+ unsigned int maxrate; -+ unsigned int defrate; -+ bool set_plimit = false; -+ bool set_flow_plimit = false; -+ bool set_quantum = false; -+ bool set_initial_quantum = false; -+ bool set_maxrate = false; -+ bool set_defrate = false; -+ int pacing = -1; -+ struct rtattr *tail; -+ -+ while (argc > 0) { -+ if (strcmp(*argv, "limit") == 0) { -+ NEXT_ARG(); -+ if (get_unsigned(&plimit, *argv, 0)) { -+ fprintf(stderr, "Illegal \"limit\"\n"); -+ return -1; -+ } -+ set_plimit = true; -+ } else if (strcmp(*argv, "target") == 0) { -+ NEXT_ARG(); -+ if (get_time(&target, *argv)) { -+ fprintf(stderr, "Illegal \"target\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "tupdate") == 0) { -+ NEXT_ARG(); -+ if (get_time(&tupdate, *argv)) { -+ fprintf(stderr, "Illegal \"tupdate\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "alpha") == 0) { -+ NEXT_ARG(); -+ if (get_unsigned(&alpha, *argv, 0) || -+ (alpha > ALPHA_MAX) || (alpha < ALPHA_MIN)) { -+ fprintf(stderr, "Illegal \"alpha\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "beta") == 0) { -+ NEXT_ARG(); -+ if (get_unsigned(&beta, *argv, 0) || -+ (beta > BETA_MAX) || (beta < BETA_MIN)) { -+ fprintf(stderr, "Illegal \"beta\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "ecn") == 0) { -+ ecn = 1; -+ } else if (strcmp(*argv, "noecn") == 0) { -+ ecn = 0; -+ } else if (strcmp(*argv, "bytemode") == 0) { -+ bytemode = 1; -+ } else if (strcmp(*argv, "nobytemode") == 0) { -+ bytemode = 0; -+ } else if (strcmp(*argv, "flow_limit") == 0) { -+ NEXT_ARG(); -+ if (get_unsigned(&flow_plimit, *argv, 0)) { -+ fprintf(stderr, "Illegal \"flow_limit\"\n"); -+ return -1; -+ } -+ set_flow_plimit = true; -+ } else if (strcmp(*argv, "buckets") == 0) { -+ NEXT_ARG(); -+ if (get_unsigned(&buckets, *argv, 0)) { -+ fprintf(stderr, "Illegal \"buckets\"\n"); -+ return -1; -+ } -+ } else if (strcmp(*argv, "maxrate") == 0) { -+ NEXT_ARG(); -+ if (get_rate(&maxrate, *argv)) { -+ fprintf(stderr, "Illegal \"maxrate\"\n"); -+ return -1; -+ } -+ set_maxrate = true; -+ } else if (strcmp(*argv, "defrate") == 0) { -+ NEXT_ARG(); -+ if (get_rate(&defrate, *argv)) { -+ fprintf(stderr, "Illegal \"defrate\"\n"); -+ return -1; -+ } -+ set_defrate = true; -+ } else if (strcmp(*argv, "quantum") == 0) { -+ NEXT_ARG(); -+ if (get_unsigned(&quantum, *argv, 0)) { -+ fprintf(stderr, "Illegal \"quantum\"\n"); -+ return -1; -+ } -+ set_quantum = true; -+ } else if (strcmp(*argv, "initial_quantum") == 0) { -+ NEXT_ARG(); -+ if (get_unsigned(&initial_quantum, *argv, 0)) { -+ fprintf(stderr, "Illegal \"initial_quantum\"\n"); -+ return -1; -+ } -+ set_initial_quantum = true; -+ } else if (strcmp(*argv, "pacing") == 0) { -+ pacing = 1; -+ } else if (strcmp(*argv, "nopacing") == 0) { -+ pacing = 0; -+ } else if (strcmp(*argv, "help") == 0) { -+ explain(); -+ return -1; -+ } else { -+ fprintf(stderr, "What is \"%s\"?\n", *argv); -+ explain(); -+ return -1; -+ } -+ argc--; argv++; -+ } -+ -+ tail = NLMSG_TAIL(n); -+ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); -+ if (buckets) { -+ unsigned int log = ilog2(buckets); -+ -+ addattr_l(n, 1024, TCA_FQ_PIE_BUCKETS_LOG, -+ &log, sizeof(log)); -+ } -+ if (target) -+ addattr_l(n, 1024, TCA_FQ_PIE_TARGET, &target, sizeof(target)); -+ if (tupdate) -+ addattr_l(n, 1024, TCA_FQ_PIE_TUPDATE, &tupdate, sizeof(tupdate)); -+ if (alpha) -+ addattr_l(n, 1024, TCA_FQ_PIE_ALPHA, &alpha, sizeof(alpha)); -+ if (beta) -+ addattr_l(n, 1024, TCA_FQ_PIE_BETA, &beta, sizeof(beta)); -+ if (ecn != -1) -+ addattr_l(n, 1024, TCA_FQ_PIE_ECN, &ecn, sizeof(ecn)); -+ if (bytemode != -1) -+ addattr_l(n, 1024, TCA_FQ_PIE_BYTEMODE, &bytemode, -+ sizeof(bytemode)); -+ if (set_plimit) -+ addattr_l(n, 1024, TCA_FQ_PIE_PLIMIT, -+ &plimit, sizeof(plimit)); -+ if (set_flow_plimit) -+ addattr_l(n, 1024, TCA_FQ_PIE_FLOW_PLIMIT, -+ &flow_plimit, sizeof(flow_plimit)); -+ if (set_quantum) -+ addattr_l(n, 1024, TCA_FQ_PIE_QUANTUM, &quantum, sizeof(quantum)); -+ if (set_initial_quantum) -+ addattr_l(n, 1024, TCA_FQ_PIE_INITIAL_QUANTUM, -+ &initial_quantum, sizeof(initial_quantum)); -+ if (pacing != -1) -+ addattr_l(n, 1024, TCA_FQ_PIE_RATE_ENABLE, -+ &pacing, sizeof(pacing)); -+ if (set_maxrate) -+ addattr_l(n, 1024, TCA_FQ_PIE_FLOW_MAX_RATE, -+ &maxrate, sizeof(maxrate)); -+ if (set_defrate) -+ addattr_l(n, 1024, TCA_FQ_PIE_FLOW_DEFAULT_RATE, -+ &defrate, sizeof(defrate)); -+ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; -+ return 0; -+} -+ -+static int fq_pie_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -+{ -+ struct rtattr *tb[TCA_FQ_PIE_MAX + 1]; -+ unsigned int target; -+ unsigned int tupdate; -+ unsigned int alpha; -+ unsigned int beta; -+ unsigned ecn; -+ unsigned bytemode; -+ unsigned int plimit, flow_plimit; -+ unsigned int buckets_log; -+ int pacing; -+ unsigned int rate, quantum; -+ SPRINT_BUF(b1); -+ -+ if (opt == NULL) -+ return 0; -+ -+ parse_rtattr_nested(tb, TCA_FQ_PIE_MAX, opt); -+ if (tb[TCA_FQ_PIE_TARGET] && -+ RTA_PAYLOAD(tb[TCA_FQ_PIE_TARGET]) >= sizeof(__u32)) { -+ target = rta_getattr_u32(tb[TCA_FQ_PIE_TARGET]); -+ fprintf(f, "target %s ", sprint_time(target, b1)); -+ } -+ if (tb[TCA_FQ_PIE_TUPDATE] && -+ RTA_PAYLOAD(tb[TCA_FQ_PIE_TUPDATE]) >= sizeof(__u32)) { -+ tupdate = rta_getattr_u32(tb[TCA_FQ_PIE_TUPDATE]); -+ fprintf(f, "tupdate %s ", sprint_time(tupdate, b1)); -+ } -+ if (tb[TCA_FQ_PIE_ALPHA] && -+ RTA_PAYLOAD(tb[TCA_FQ_PIE_ALPHA]) >= sizeof(__u32)) { -+ alpha = rta_getattr_u32(tb[TCA_FQ_PIE_ALPHA]); -+ fprintf(f, "alpha %u ", alpha); -+ } -+ if (tb[TCA_FQ_PIE_BETA] && -+ RTA_PAYLOAD(tb[TCA_FQ_PIE_BETA]) >= sizeof(__u32)) { -+ beta = rta_getattr_u32(tb[TCA_FQ_PIE_BETA]); -+ fprintf(f, "beta %u ", beta); -+ } -+ -+ if (tb[TCA_FQ_PIE_ECN] && RTA_PAYLOAD(tb[TCA_FQ_PIE_ECN]) >= sizeof(__u32)) { -+ ecn = rta_getattr_u32(tb[TCA_FQ_PIE_ECN]); -+ if (ecn) -+ fprintf(f, "ecn "); -+ } -+ -+ if (tb[TCA_FQ_PIE_BYTEMODE] && -+ RTA_PAYLOAD(tb[TCA_FQ_PIE_BYTEMODE]) >= sizeof(__u32)) { -+ bytemode = rta_getattr_u32(tb[TCA_FQ_PIE_BYTEMODE]); -+ if (bytemode) -+ fprintf(f, "bytemode "); -+ } -+ if (tb[TCA_FQ_PIE_PLIMIT] && -+ RTA_PAYLOAD(tb[TCA_FQ_PIE_PLIMIT]) >= sizeof(__u32)) { -+ plimit = rta_getattr_u32(tb[TCA_FQ_PIE_PLIMIT]); -+ fprintf(f, "limit %up ", plimit); -+ } -+ if (tb[TCA_FQ_PIE_FLOW_PLIMIT] && -+ RTA_PAYLOAD(tb[TCA_FQ_PIE_FLOW_PLIMIT]) >= sizeof(__u32)) { -+ flow_plimit = rta_getattr_u32(tb[TCA_FQ_PIE_FLOW_PLIMIT]); -+ fprintf(f, "flow_limit %up ", flow_plimit); -+ } -+ if (tb[TCA_FQ_PIE_BUCKETS_LOG] && -+ RTA_PAYLOAD(tb[TCA_FQ_PIE_BUCKETS_LOG]) >= sizeof(__u32)) { -+ buckets_log = rta_getattr_u32(tb[TCA_FQ_PIE_BUCKETS_LOG]); -+ fprintf(f, "buckets %u ", 1U << buckets_log); -+ } -+ if (tb[TCA_FQ_PIE_RATE_ENABLE] && -+ RTA_PAYLOAD(tb[TCA_FQ_PIE_RATE_ENABLE]) >= sizeof(int)) { -+ pacing = rta_getattr_u32(tb[TCA_FQ_PIE_RATE_ENABLE]); -+ if (pacing == 0) -+ fprintf(f, "nopacing "); -+ } -+ if (tb[TCA_FQ_PIE_QUANTUM] && -+ RTA_PAYLOAD(tb[TCA_FQ_PIE_QUANTUM]) >= sizeof(__u32)) { -+ quantum = rta_getattr_u32(tb[TCA_FQ_PIE_QUANTUM]); -+ fprintf(f, "quantum %u ", quantum); -+ } -+ if (tb[TCA_FQ_PIE_INITIAL_QUANTUM] && -+ RTA_PAYLOAD(tb[TCA_FQ_PIE_INITIAL_QUANTUM]) >= sizeof(__u32)) { -+ quantum = rta_getattr_u32(tb[TCA_FQ_PIE_INITIAL_QUANTUM]); -+ fprintf(f, "initial_quantum %u ", quantum); -+ } -+ if (tb[TCA_FQ_PIE_FLOW_MAX_RATE] && -+ RTA_PAYLOAD(tb[TCA_FQ_PIE_FLOW_MAX_RATE]) >= sizeof(__u32)) { -+ rate = rta_getattr_u32(tb[TCA_FQ_PIE_FLOW_MAX_RATE]); -+ -+ if (rate != ~0U) -+ fprintf(f, "maxrate %s ", sprint_rate(rate, b1)); -+ } -+ if (tb[TCA_FQ_PIE_FLOW_DEFAULT_RATE] && -+ RTA_PAYLOAD(tb[TCA_FQ_PIE_FLOW_DEFAULT_RATE]) >= sizeof(__u32)) { -+ rate = rta_getattr_u32(tb[TCA_FQ_PIE_FLOW_DEFAULT_RATE]); -+ -+ if (rate != 0) -+ fprintf(f, "defrate %s ", sprint_rate(rate, b1)); -+ } -+ -+ return 0; -+} -+ -+static int fq_pie_print_xstats(struct qdisc_util *qu, FILE *f, -+ struct rtattr *xstats) -+{ -+ struct tc_fq_pie_qd_stats *st; -+ -+ if (xstats == NULL) -+ return 0; -+ -+ if (RTA_PAYLOAD(xstats) < sizeof(*st)) -+ return -1; -+ -+ st = RTA_DATA(xstats); -+ fprintf(f, "prob %f delay %uus avg_dq_rate %u", -+ (double)st->prob / (double)0xffffffff, st->delay, -+ st->avg_dq_rate); -+ fprintf(f, "pkts_in %u overlimit %u dropped %u maxq %u ecn_mark %u", -+ st->packets_in, st->overlimit, st->dropped, st->maxq, -+ st->ecn_mark); -+ fprintf(f, " %u flows (%u inactive, %u throttled)", -+ st->flows, st->inactive_flows, st->throttled_flows); -+ -+ if (st->time_next_delayed_flow > 0) -+ fprintf(f, ", next packet delay %llu ns", st->time_next_delayed_flow); -+ -+ fprintf(f, "\n %llu gc, %llu highprio", -+ st->gc_flows, st->highprio_packets); -+ -+ if (st->tcp_retrans) -+ fprintf(f, ", %llu retrans", st->tcp_retrans); -+ -+ fprintf(f, ", %llu throttled", st->throttled); -+ -+ if (st->flows_plimit) -+ fprintf(f, ", %llu flows_plimit", st->flows_plimit); -+ -+ if (st->pkts_too_long || st->allocation_errors) -+ fprintf(f, "\n %llu too long pkts, %llu alloc errors\n", -+ st->pkts_too_long, st->allocation_errors); -+ -+ return 0; -+} -+ -+struct qdisc_util fq_pie_qdisc_util = { -+ .id = "fq_pie", -+ .parse_qopt = fq_pie_parse_opt, -+ .print_qopt = fq_pie_print_opt, -+ .print_xstats = fq_pie_print_xstats, -+}; --- -2.1.4 - diff --git a/net/iproute2/patches/800-tc-util-Fix-possible-buffer-overflow-when-print-clas.patch b/net/iproute2/patches/800-tc-util-Fix-possible-buffer-overflow-when-print-clas.patch deleted file mode 100644 index b45068d..0000000 --- a/net/iproute2/patches/800-tc-util-Fix-possible-buffer-overflow-when-print-clas.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 46679bbbe89699016d31486de7599590d02a5054 Mon Sep 17 00:00:00 2001 -From: Vadim Kochan -Date: Mon, 20 Apr 2015 08:33:32 +0300 -Subject: [PATCH 32/38] tc util: Fix possible buffer overflow when print class - id - -Use correct handle buffer length. - -Signed-off-by: Vadim Kochan ---- - tc/tc_util.c | 19 ++++++++++--------- - 1 file changed, 10 insertions(+), 9 deletions(-) - -diff --git a/tc/tc_util.c b/tc/tc_util.c -index 1d3153d..dc2b70f 100644 ---- a/tc/tc_util.c -+++ b/tc/tc_util.c -@@ -128,30 +128,31 @@ ok: - return 0; - } - --int print_tc_classid(char *buf, int len, __u32 h) -+int print_tc_classid(char *buf, int blen, __u32 h) - { -- char handle[40] = {}; -+ SPRINT_BUF(handle) = {}; -+ int hlen = SPRINT_BSIZE - 1; - - if (h == TC_H_ROOT) - sprintf(handle, "root"); - else if (h == TC_H_UNSPEC) -- snprintf(handle, len, "none"); -+ snprintf(handle, hlen, "none"); - else if (TC_H_MAJ(h) == 0) -- snprintf(handle, len, ":%x", TC_H_MIN(h)); -+ snprintf(handle, hlen, ":%x", TC_H_MIN(h)); - else if (TC_H_MIN(h) == 0) -- snprintf(handle, len, "%x:", TC_H_MAJ(h) >> 16); -+ snprintf(handle, hlen, "%x:", TC_H_MAJ(h) >> 16); - else -- snprintf(handle, len, "%x:%x", TC_H_MAJ(h) >> 16, TC_H_MIN(h)); -+ snprintf(handle, hlen, "%x:%x", TC_H_MAJ(h) >> 16, TC_H_MIN(h)); - - if (use_names) { - char clname[IDNAME_MAX] = {}; - - if (id_to_name(cls_names, h, clname)) -- snprintf(buf, len, "%s#%s", clname, handle); -+ snprintf(buf, blen, "%s#%s", clname, handle); - else -- snprintf(buf, len, "%s", handle); -+ snprintf(buf, blen, "%s", handle); - } else { -- snprintf(buf, len, "%s", handle); -+ snprintf(buf, blen, "%s", handle); - } - - return 0; --- -1.9.1 - diff --git a/net/iproute2/patches/801-tc-fix-compilation-warning-on-32bits-arch.patch b/net/iproute2/patches/801-tc-fix-compilation-warning-on-32bits-arch.patch deleted file mode 100644 index 29fed6e..0000000 --- a/net/iproute2/patches/801-tc-fix-compilation-warning-on-32bits-arch.patch +++ /dev/null @@ -1,35 +0,0 @@ -From afa5158f02024ea9ac71a4bb262670bba17aebcd Mon Sep 17 00:00:00 2001 -From: Nicolas Dichtel -Date: Wed, 22 Apr 2015 10:27:05 +0200 -Subject: [PATCH 33/38] tc: fix compilation warning on 32bits arch -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The warning was: -m_simple.c: In function ‘parse_simple’: -m_simple.c:142:4: warning: format ‘%ld’ expects argument of type ‘long int’, but argument 3 has type ‘size_t’ [-Wformat] - -Useful to be able to compile with -Werror. - -Signed-off-by: Nicolas Dichtel ---- - tc/m_simple.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tc/m_simple.c b/tc/m_simple.c -index 866552f..1ad5526 100644 ---- a/tc/m_simple.c -+++ b/tc/m_simple.c -@@ -138,7 +138,7 @@ parse_simple(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, - } - - if (strlen(simpdata) > (SIMP_MAX_DATA - 1)) { -- fprintf(stderr, "simple: Illegal string len %ld <%s> \n", -+ fprintf(stderr, "simple: Illegal string len %zu <%s> \n", - strlen(simpdata), simpdata); - return -1; - } --- -1.9.1 - diff --git a/net/iproute2/patches/900-drop_FAILED_POLICY.patch b/net/iproute2/patches/900-drop_FAILED_POLICY.patch deleted file mode 100644 index f5d2dfe..0000000 --- a/net/iproute2/patches/900-drop_FAILED_POLICY.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 4e7dbf76227e8c7be7897dc81def3011f637864d Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Thu, 30 May 2013 11:54:04 +0200 -Subject: [PATCH] add support for dropping with FAILED_POLICY - ---- - include/linux/fib_rules.h | 4 ++++ - include/linux/rtnetlink.h | 1 + - ip/rtm_map.c | 4 ++++ - 3 files changed, 9 insertions(+) - ---- a/include/linux/fib_rules.h -+++ b/include/linux/fib_rules.h -@@ -64,6 +64,10 @@ enum { - FR_ACT_BLACKHOLE, /* Drop without notification */ - FR_ACT_UNREACHABLE, /* Drop with ENETUNREACH */ - FR_ACT_PROHIBIT, /* Drop with EACCES */ -+ FR_ACT_RES8, -+ FR_ACT_RES9, -+ FR_ACT_RES10, -+ FR_ACT_FAILED_POLICY, /* Drop with EPERM */ - __FR_ACT_MAX, - }; - ---- a/include/linux/rtnetlink.h -+++ b/include/linux/rtnetlink.h -@@ -208,6 +208,7 @@ enum { - RTN_THROW, /* Not in this table */ - RTN_NAT, /* Translate this address */ - RTN_XRESOLVE, /* Use external resolver */ -+ RTN_FAILED_POLICY, /* Source address failed policy */ - __RTN_MAX - }; - ---- a/ip/rtm_map.c -+++ b/ip/rtm_map.c -@@ -49,6 +49,8 @@ char *rtnl_rtntype_n2a(int id, char *buf - return "nat"; - case RTN_XRESOLVE: - return "xresolve"; -+ case RTN_FAILED_POLICY: -+ return "failed_policy"; - default: - snprintf(buf, len, "%d", id); - return buf; -@@ -84,6 +86,8 @@ int rtnl_rtntype_a2n(int *id, char *arg) - res = RTN_UNICAST; - else if (strcmp(arg, "throw") == 0) - res = RTN_THROW; -+ else if (strcmp(arg, "failed_policy") == 0) -+ res = RTN_FAILED_POLICY; - else { - res = strtoul(arg, &end, 0); - if (!end || end == arg || *end || res > 255) diff --git a/net/iproute2/patches/910-sanitize_headers_for_musl.patch b/net/iproute2/patches/910-sanitize_headers_for_musl.patch deleted file mode 100644 index ca1125d..0000000 --- a/net/iproute2/patches/910-sanitize_headers_for_musl.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/include/linux/if_bridge.h -+++ b/include/linux/if_bridge.h -@@ -15,7 +15,6 @@ - - #include - #include --#include - - #define SYSFS_BRIDGE_ATTR "bridge" - #define SYSFS_BRIDGE_FDB "brforward"