aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2011-01-06 15:37:12 -0800
committerDmitry Shmidt <dimitrysh@google.com>2011-01-06 15:37:12 -0800
commit1a441f49ec87ef74b978d7ae17da2a9b2ca6e811 (patch)
treea0fe569be05241e141f7bf03c5b42bd548c096d9
parent722fcc24bc9c1d1066e01ba8890c20602d5c8413 (diff)
downloadiproute2-1a441f49ec87ef74b978d7ae17da2a9b2ca6e811.tar.gz
Change-Id: I8a85cc051aea35e4562c7fea46c148ed2757efc6 Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
-rwxr-xr-xconfigure33
-rw-r--r--doc/ip-cref.tex15
-rw-r--r--examples/gaiconf134
-rw-r--r--include/SNAPSHOT.h2
-rw-r--r--include/linux/can/netlink.h17
-rw-r--r--include/linux/fib_rules.h17
-rw-r--r--include/linux/gen_stats.h15
-rw-r--r--include/linux/genetlink.h1
-rw-r--r--include/linux/if.h18
-rw-r--r--include/linux/if_addr.h9
-rw-r--r--include/linux/if_addrlabel.h6
-rw-r--r--include/linux/if_arp.h4
-rw-r--r--include/linux/if_ether.h1
-rw-r--r--include/linux/if_link.h195
-rw-r--r--include/linux/if_tun.h94
-rw-r--r--include/linux/if_tunnel.h18
-rw-r--r--include/linux/if_vlan.h1
-rw-r--r--include/linux/neighbour.h18
-rw-r--r--include/linux/netdevice.h4
-rw-r--r--include/linux/netfilter/x_tables.h51
-rw-r--r--include/linux/netfilter/xt_tcpudp.h6
-rw-r--r--include/linux/netfilter_ipv4/ip_tables.h15
-rw-r--r--include/linux/netlink.h15
-rw-r--r--include/linux/pkt_cls.h84
-rw-r--r--include/linux/pkt_sched.h111
-rw-r--r--include/linux/rtnetlink.h66
-rw-r--r--include/linux/tc_act/tc_gact.h9
-rw-r--r--include/linux/tc_act/tc_ipt.h3
-rw-r--r--include/linux/tc_act/tc_mirred.h6
-rw-r--r--include/linux/tc_act/tc_nat.h6
-rw-r--r--include/linux/tc_act/tc_pedit.h9
-rw-r--r--include/linux/tc_act/tc_skbedit.h2
-rw-r--r--include/linux/tc_ematch/tc_em_cmp.h6
-rw-r--r--include/linux/tc_ematch/tc_em_meta.h15
-rw-r--r--include/linux/tc_ematch/tc_em_nbyte.h3
-rw-r--r--include/linux/xfrm.h47
-rw-r--r--ip/Android.mk2
-rw-r--r--ip/Makefile5
-rw-r--r--ip/ip.c9
-rw-r--r--ip/ip_common.h2
-rw-r--r--ip/ipaddress.c112
-rw-r--r--ip/ipaddrlabel.c2
-rw-r--r--ip/iplink.c83
-rw-r--r--ip/iplink_can.c19
-rw-r--r--ip/iplink_macvlan.c93
-rw-r--r--ip/iplink_vlan.c11
-rw-r--r--ip/iproute.c40
-rw-r--r--ip/iprule.c37
-rw-r--r--ip/iptunnel.c64
-rw-r--r--ip/iptuntap.c323
-rw-r--r--ip/ipxfrm.c42
-rw-r--r--ip/tunnel.c20
-rw-r--r--ip/tunnel.h2
-rw-r--r--ip/xfrm.h1
-rw-r--r--ip/xfrm_policy.c34
-rw-r--r--ip/xfrm_state.c73
-rw-r--r--lib/dnet_ntop.c8
-rw-r--r--lib/dnet_pton.c5
-rw-r--r--lib/libnetlink.c2
-rw-r--r--lib/ll_map.c6
-rw-r--r--lib/ll_types.c36
-rw-r--r--man/man8/ip.8199
-rw-r--r--man/man8/tc-drr.894
-rw-r--r--man/man8/tc-prio.82
-rw-r--r--man/man8/tc-sfq.83
-rw-r--r--man/man8/tc.81
-rw-r--r--misc/ss.c134
-rw-r--r--netem/Makefile4
-rw-r--r--tc/Makefile40
-rw-r--r--tc/emp_ematch.l30
-rw-r--r--tc/f_fw.c2
-rw-r--r--tc/f_route.c2
-rw-r--r--tc/f_rsvp.c2
-rw-r--r--tc/f_tcindex.c4
-rw-r--r--tc/f_u32.c48
-rw-r--r--tc/m_action.c4
-rw-r--r--tc/m_ematch.c12
-rw-r--r--tc/m_mirred.c5
-rw-r--r--tc/m_skbedit.c29
-rw-r--r--tc/m_xt.c5
-rw-r--r--tc/m_xt_old.c5
-rw-r--r--tc/q_atm.c2
-rw-r--r--tc/q_cbq.c3
-rw-r--r--tc/q_drr.c1
-rw-r--r--tc/q_dsmark.c3
-rw-r--r--tc/q_fifo.c10
-rw-r--r--tc/q_gred.c7
-rw-r--r--tc/q_htb.c2
-rw-r--r--tc/q_ingress.c2
-rw-r--r--tc/q_multiq.c2
-rw-r--r--tc/q_netem.c2
-rw-r--r--tc/q_prio.c4
-rw-r--r--tc/q_red.c16
-rw-r--r--tc/q_rr.c3
-rw-r--r--tc/q_sfq.c2
-rw-r--r--tc/q_tbf.c8
96 files changed, 2135 insertions, 644 deletions
diff --git a/configure b/configure
index a903bb0c..600fa96c 100755
--- a/configure
+++ b/configure
@@ -3,7 +3,9 @@
#
INCLUDE=${1:-"$PWD/include"}
-function check_atm
+TABLES=
+
+check_atm()
{
cat >/tmp/atmtest.c <<EOF
#include <atm.h>
@@ -24,7 +26,7 @@ fi
rm -f /tmp/atmtest.c /tmp/atmtest
}
-function check_xt
+check_xt()
{
#check if we have xtables from iptables >= 1.4.5.
cat >/tmp/ipttest.c <<EOF
@@ -55,7 +57,7 @@ fi
rm -f /tmp/ipttest.c /tmp/ipttest
}
-function check_xt_old
+check_xt_old()
{
# bail if previous XT checks has already succeded.
if grep TC_CONFIG_XT Config > /dev/null
@@ -94,7 +96,7 @@ fi
rm -f /tmp/ipttest.c /tmp/ipttest
}
-function check_xt_old_internal_h
+check_xt_old_internal_h()
{
# bail if previous XT checks has already succeded.
if grep TC_CONFIG_XT Config > /dev/null
@@ -134,14 +136,33 @@ fi
rm -f /tmp/ipttest.c /tmp/ipttest
}
-function check_ipt
+check_ipt()
{
if ! grep TC_CONFIG_XT Config > /dev/null
then
echo "using iptables"
+ TABLES="iptables"
+ else
+ TABLES="xtables"
fi
}
+check_ipt_lib_dir()
+{
+ IPT_LIB_DIR=""
+ for dir in /lib /usr/lib /usr/local/lib
+ do
+ for file in $dir/$TABLES/lib*t_*so ; do
+ if [ -f $file ]; then
+ echo $dir/$TABLES
+ echo "IPT_LIB_DIR:=$dir/$TABLES" >> Config
+ return
+ fi
+ done
+ done
+ echo "not found!"
+}
+
echo "# Generated config based on" $INCLUDE >Config
echo "TC schedulers"
@@ -155,3 +176,5 @@ check_xt_old
check_xt_old_internal_h
check_ipt
+echo -n "iptables modules directory: "
+check_ipt_lib_dir
diff --git a/doc/ip-cref.tex b/doc/ip-cref.tex
index 6ea44025..056e3bf5 100644
--- a/doc/ip-cref.tex
+++ b/doc/ip-cref.tex
@@ -1336,6 +1336,13 @@ peers are allowed to send to us.
MSS (``Maximal Segment Size'') for same connection. The default is
zero, meaning to use the values specified in~\cite{RFC2414}.
++\item \verb|initrwnd NUMBER|
+
++--- [2.6.33+ only] Initial receive window size for connections to
++ this destination. The actual window size is this value multiplied
++ by the MSS (''Maximal Segment Size'') of the connection. The default
++ value is zero, meaning to use Slow Start value.
+
\item \verb|nexthop NEXTHOP|
--- the nexthop of a multipath route. \verb|NEXTHOP| is a complex value
@@ -1390,14 +1397,6 @@ database.
even if it does not match any interface prefix. One application of this
option may be found in~\cite{IP-TUNNELS}.
-\item \verb|equalize|
-
---- allow packet by packet randomization on multipath routes.
-Without this modifier, the route will be frozen to one selected
-nexthop, so that load splitting will only occur on per-flow base.
-\verb|equalize| only works if the kernel is patched.
-
-
\end{itemize}
diff --git a/examples/gaiconf b/examples/gaiconf
new file mode 100644
index 00000000..d75292b9
--- /dev/null
+++ b/examples/gaiconf
@@ -0,0 +1,134 @@
+#!/bin/sh
+
+#
+# Setup address label from /etc/gai.conf
+#
+# Written by YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>, 2010.
+#
+
+IP=ip
+DEFAULT_GAICONF=/etc/gai.conf
+verbose=
+debug=
+
+function run ()
+{
+ if [ x"$verbose" != x"" ]; then
+ echo "$@"
+ fi
+ if [ x"$debug" = x"" ]; then
+ "$@"
+ fi
+}
+
+function do_load_config ()
+{
+ file=$1; shift
+ flush=1
+ cat $file | while read command prefix label; do
+ if [ x"$command" = x"#label" ]; then
+ if [ ${flush} = 1 ]; then
+ run ${IP} -6 addrlabel flush
+ flush=0
+ fi
+ run ${IP} -6 addrlabel add prefix $prefix label $label
+ fi
+ done
+}
+
+function do_list_config ()
+{
+ ${IP} -6 addrlabel list | while read p pfx l lbl; do
+ echo label ${pfx} ${lbl}
+ done
+}
+
+function help ()
+{
+ echo "Usage: $0 [-v] {--list | --config [ ${DEFAULT_GAICONF} ] | --default}"
+ exit 1
+}
+
+TEMP=`getopt -o c::dlv -l config::,default,list,verbose -n gaiconf -- "$@"`
+
+if [ $? != 0 ]; then
+ echo "Terminating..." >&2
+ exit 1
+fi
+
+TEMPFILE=`mktemp`
+
+eval set -- "$TEMP"
+
+while true ; do
+ case "$1" in
+ -c|--config)
+ if [ x"$cmd" != x"" ]; then
+ help
+ fi
+ case "$2" in
+ "") gai_conf="${DEFAULT_GAICONF}"
+ shift 2
+ ;;
+ *) gai_conf="$2"
+ shift 2
+ esac
+ cmd=config
+ ;;
+ -d|--default)
+ if [ x"$cmd" != x"" ]; then
+ help
+ fi
+ gai_conf=${TEMPFILE}
+ cmd=config
+ ;;
+ -l|--list)
+ if [ x"$cmd" != x"" ]; then
+ help
+ fi
+ cmd=list
+ shift
+ ;;
+ -v)
+ verbose=1
+ shift
+ ;;
+ --)
+ shift;
+ break
+ ;;
+ *)
+ echo "Internal error!" >&2
+ exit 1
+ ;;
+ esac
+done
+
+case "$cmd" in
+ config)
+ if [ x"$gai_conf" = x"${TEMPFILE}" ]; then
+ sed -e 's/^[[:space:]]*//' <<END_OF_DEFAULT >${TEMPFILE}
+ label ::1/128 0
+ label ::/0 1
+ label 2002::/16 2
+ label ::/96 3
+ label ::ffff:0:0/96 4
+ label fec0::/10 5
+ label fc00::/7 6
+ label 2001:0::/32 7
+END_OF_DEFAULT
+ fi
+ do_load_config "$gai_conf"
+ ;;
+ list)
+ do_list_config
+ ;;
+ *)
+ help
+ ;;
+esac
+
+rm -f "${TEMPFILE}"
+
+exit 0
+
diff --git a/include/SNAPSHOT.h b/include/SNAPSHOT.h
index 4696bfe8..de41b1b3 100644
--- a/include/SNAPSHOT.h
+++ b/include/SNAPSHOT.h
@@ -1 +1 @@
-static const char SNAPSHOT[] = "091226";
+static const char SNAPSHOT[] = "100804";
diff --git a/include/linux/can/netlink.h b/include/linux/can/netlink.h
index 9ecbb787..3250de93 100644
--- a/include/linux/can/netlink.h
+++ b/include/linux/can/netlink.h
@@ -70,6 +70,14 @@ enum can_state {
};
/*
+ * CAN bus error counters
+ */
+struct can_berr_counter {
+ __u16 txerr;
+ __u16 rxerr;
+};
+
+/*
* CAN controller mode
*/
struct can_ctrlmode {
@@ -77,9 +85,11 @@ struct can_ctrlmode {
__u32 flags;
};
-#define CAN_CTRLMODE_LOOPBACK 0x1 /* Loopback mode */
-#define CAN_CTRLMODE_LISTENONLY 0x2 /* Listen-only mode */
-#define CAN_CTRLMODE_3_SAMPLES 0x4 /* Triple sampling mode */
+#define CAN_CTRLMODE_LOOPBACK 0x01 /* Loopback mode */
+#define CAN_CTRLMODE_LISTENONLY 0x02 /* Listen-only mode */
+#define CAN_CTRLMODE_3_SAMPLES 0x04 /* Triple sampling mode */
+#define CAN_CTRLMODE_ONE_SHOT 0x08 /* One-Shot mode */
+#define CAN_CTRLMODE_BERR_REPORTING 0x10 /* Bus-error reporting */
/*
* CAN device statistics
@@ -105,6 +115,7 @@ enum {
IFLA_CAN_CTRLMODE,
IFLA_CAN_RESTART_MS,
IFLA_CAN_RESTART,
+ IFLA_CAN_BERR_COUNTER,
__IFLA_CAN_MAX
};
diff --git a/include/linux/fib_rules.h b/include/linux/fib_rules.h
index 87b606b6..51da65b6 100644
--- a/include/linux/fib_rules.h
+++ b/include/linux/fib_rules.h
@@ -8,13 +8,14 @@
#define FIB_RULE_PERMANENT 0x00000001
#define FIB_RULE_INVERT 0x00000002
#define FIB_RULE_UNRESOLVED 0x00000004
-#define FIB_RULE_DEV_DETACHED 0x00000008
+#define FIB_RULE_IIF_DETACHED 0x00000008
+#define FIB_RULE_DEV_DETACHED FIB_RULE_IIF_DETACHED
+#define FIB_RULE_OIF_DETACHED 0x00000010
/* try to find source address in routing lookups */
#define FIB_RULE_FIND_SADDR 0x00010000
-struct fib_rule_hdr
-{
+struct fib_rule_hdr {
__u8 family;
__u8 dst_len;
__u8 src_len;
@@ -28,12 +29,12 @@ struct fib_rule_hdr
__u32 flags;
};
-enum
-{
+enum {
FRA_UNSPEC,
FRA_DST, /* destination address */
FRA_SRC, /* source address */
- FRA_IFNAME, /* interface name */
+ FRA_IIFNAME, /* interface name */
+#define FRA_IFNAME FRA_IIFNAME
FRA_GOTO, /* target to jump to (FR_ACT_GOTO) */
FRA_UNUSED2,
FRA_PRIORITY, /* priority/preference */
@@ -47,13 +48,13 @@ enum
FRA_UNUSED8,
FRA_TABLE, /* Extended table id */
FRA_FWMASK, /* mask for netfilter mark */
+ FRA_OIFNAME,
__FRA_MAX
};
#define FRA_MAX (__FRA_MAX - 1)
-enum
-{
+enum {
FR_ACT_UNSPEC,
FR_ACT_TO_TBL, /* Pass to fixed table */
FR_ACT_GOTO, /* Jump to another rule */
diff --git a/include/linux/gen_stats.h b/include/linux/gen_stats.h
index 710e9010..552c8a0a 100644
--- a/include/linux/gen_stats.h
+++ b/include/linux/gen_stats.h
@@ -18,13 +18,11 @@ enum {
* @bytes: number of seen bytes
* @packets: number of seen packets
*/
-struct gnet_stats_basic
-{
+struct gnet_stats_basic {
__u64 bytes;
__u32 packets;
};
-struct gnet_stats_basic_packed
-{
+struct gnet_stats_basic_packed {
__u64 bytes;
__u32 packets;
} __attribute__ ((packed));
@@ -34,8 +32,7 @@ struct gnet_stats_basic_packed
* @bps: current byte rate
* @pps: current packet rate
*/
-struct gnet_stats_rate_est
-{
+struct gnet_stats_rate_est {
__u32 bps;
__u32 pps;
};
@@ -48,8 +45,7 @@ struct gnet_stats_rate_est
* @requeues: number of requeues
* @overlimits: number of enqueues over the limit
*/
-struct gnet_stats_queue
-{
+struct gnet_stats_queue {
__u32 qlen;
__u32 backlog;
__u32 drops;
@@ -62,8 +58,7 @@ struct gnet_stats_queue
* @interval: sampling period
* @ewma_log: the log of measurement window weight
*/
-struct gnet_estimator
-{
+struct gnet_estimator {
signed char interval;
unsigned char ewma_log;
};
diff --git a/include/linux/genetlink.h b/include/linux/genetlink.h
index b834ef6d..55ce7bbb 100644
--- a/include/linux/genetlink.h
+++ b/include/linux/genetlink.h
@@ -80,4 +80,5 @@ enum {
#define CTRL_ATTR_MCAST_GRP_MAX (__CTRL_ATTR_MCAST_GRP_MAX - 1)
+
#endif /* __LINUX_GENERIC_NETLINK_H */
diff --git a/include/linux/if.h b/include/linux/if.h
index 010a0d29..a272e379 100644
--- a/include/linux/if.h
+++ b/include/linux/if.h
@@ -70,6 +70,9 @@
#define IFF_XMIT_DST_RELEASE 0x400 /* dev_hard_start_xmit() is allowed to
* release skb->dst
*/
+#define IFF_DONT_BRIDGE 0x800 /* disallow bridging this ether dev */
+#define IFF_IN_NETPOLL 0x1000 /* whether we are processing netpoll */
+#define IFF_DISABLE_NETPOLL 0x2000 /* disable netpoll at run-time */
#define IF_GET_IFACE 0x0001 /* for querying only */
#define IF_GET_PROTO 0x0002
@@ -125,8 +128,7 @@ enum {
* being very small might be worth keeping for clean configuration.
*/
-struct ifmap
-{
+struct ifmap {
unsigned long mem_start;
unsigned long mem_end;
unsigned short base_addr;
@@ -136,8 +138,7 @@ struct ifmap
/* 3 bytes spare */
};
-struct if_settings
-{
+struct if_settings {
unsigned int type; /* Type of physical device or protocol */
unsigned int size; /* Size of the data allocated by the caller */
union {
@@ -161,8 +162,7 @@ struct if_settings
* remainder may be interface specific.
*/
-struct ifreq
-{
+struct ifreq {
#define IFHWADDRLEN 6
union
{
@@ -211,11 +211,9 @@ struct ifreq
* must know all networks accessible).
*/
-struct ifconf
-{
+struct ifconf {
int ifc_len; /* size of buffer */
- union
- {
+ union {
char *ifcu_buf;
struct ifreq *ifcu_req;
} ifc_ifcu;
diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h
index 41b0193d..58b39f47 100644
--- a/include/linux/if_addr.h
+++ b/include/linux/if_addr.h
@@ -4,8 +4,7 @@
#include <linux/types.h>
#include <linux/netlink.h>
-struct ifaddrmsg
-{
+struct ifaddrmsg {
__u8 ifa_family;
__u8 ifa_prefixlen; /* The prefix length */
__u8 ifa_flags; /* Flags */
@@ -20,8 +19,7 @@ struct ifaddrmsg
* but for point-to-point IFA_ADDRESS is DESTINATION address,
* local address is supplied in IFA_LOCAL attribute.
*/
-enum
-{
+enum {
IFA_UNSPEC,
IFA_ADDRESS,
IFA_LOCAL,
@@ -47,8 +45,7 @@ enum
#define IFA_F_TENTATIVE 0x40
#define IFA_F_PERMANENT 0x80
-struct ifa_cacheinfo
-{
+struct ifa_cacheinfo {
__u32 ifa_prefered;
__u32 ifa_valid;
__u32 cstamp; /* created timestamp, hundredths of seconds */
diff --git a/include/linux/if_addrlabel.h b/include/linux/if_addrlabel.h
index 89571f65..54580c29 100644
--- a/include/linux/if_addrlabel.h
+++ b/include/linux/if_addrlabel.h
@@ -12,8 +12,7 @@
#include <linux/types.h>
-struct ifaddrlblmsg
-{
+struct ifaddrlblmsg {
__u8 ifal_family; /* Address family */
__u8 __ifal_reserved; /* Reserved */
__u8 ifal_prefixlen; /* Prefix length */
@@ -22,8 +21,7 @@ struct ifaddrlblmsg
__u32 ifal_seq; /* sequence number */
};
-enum
-{
+enum {
IFAL_ADDRESS = 1,
IFAL_LABEL = 2,
__IFAL_MAX
diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h
index 57a8f38e..1f9fc5db 100644
--- a/include/linux/if_arp.h
+++ b/include/linux/if_arp.h
@@ -90,6 +90,7 @@
#define ARPHRD_PHONET 820 /* PhoNet media type */
#define ARPHRD_PHONET_PIPE 821 /* PhoNet pipe header */
+#define ARPHRD_CAIF 822 /* CAIF media type */
#define ARPHRD_VOID 0xFFFF /* Void type, nothing is known */
#define ARPHRD_NONE 0xFFFE /* zero header length */
@@ -133,8 +134,7 @@ struct arpreq_old {
* This structure defines an ethernet arp header.
*/
-struct arphdr
-{
+struct arphdr {
__be16 ar_hrd; /* format of hardware address */
__be16 ar_pro; /* format of protocol address */
unsigned char ar_hln; /* length of hardware address */
diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
index 893f72e6..7e275c44 100644
--- a/include/linux/if_ether.h
+++ b/include/linux/if_ether.h
@@ -109,6 +109,7 @@
#define ETH_P_TRAILER 0x001C /* Trailer switch tagging */
#define ETH_P_PHONET 0x00F5 /* Nokia Phonet frames */
#define ETH_P_IEEE802154 0x00F6 /* IEEE802.15.4 frame */
+#define ETH_P_CAIF 0x00F7 /* ST-Ericsson CAIF protocol */
/*
* This is an Ethernet frame header.
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index b0b9e8a6..01bcaa67 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -5,8 +5,7 @@
#include <linux/netlink.h>
/* The struct should be in sync with struct net_device_stats */
-struct rtnl_link_stats
-{
+struct rtnl_link_stats {
__u32 rx_packets; /* total packets received */
__u32 tx_packets; /* total packets transmitted */
__u32 rx_bytes; /* total bytes received */
@@ -38,9 +37,40 @@ struct rtnl_link_stats
__u32 tx_compressed;
};
+struct rtnl_link_stats64 {
+ __u64 rx_packets; /* total packets received */
+ __u64 tx_packets; /* total packets transmitted */
+ __u64 rx_bytes; /* total bytes received */
+ __u64 tx_bytes; /* total bytes transmitted */
+ __u64 rx_errors; /* bad packets received */
+ __u64 tx_errors; /* packet transmit problems */
+ __u64 rx_dropped; /* no space in linux buffers */
+ __u64 tx_dropped; /* no space available in linux */
+ __u64 multicast; /* multicast packets received */
+ __u64 collisions;
+
+ /* detailed rx_errors: */
+ __u64 rx_length_errors;
+ __u64 rx_over_errors; /* receiver ring buff overflow */
+ __u64 rx_crc_errors; /* recved pkt with crc error */
+ __u64 rx_frame_errors; /* recv'd frame alignment error */
+ __u64 rx_fifo_errors; /* recv'r fifo overrun */
+ __u64 rx_missed_errors; /* receiver missed packet */
+
+ /* detailed tx_errors */
+ __u64 tx_aborted_errors;
+ __u64 tx_carrier_errors;
+ __u64 tx_fifo_errors;
+ __u64 tx_heartbeat_errors;
+ __u64 tx_window_errors;
+
+ /* for cslip etc */
+ __u64 rx_compressed;
+ __u64 tx_compressed;
+};
+
/* The struct should be in sync with struct ifmap */
-struct rtnl_link_ifmap
-{
+struct rtnl_link_ifmap {
__u64 mem_start;
__u64 mem_end;
__u64 base_addr;
@@ -49,8 +79,7 @@ struct rtnl_link_ifmap
__u8 port;
};
-enum
-{
+enum {
IFLA_UNSPEC,
IFLA_ADDRESS,
IFLA_BROADCAST,
@@ -81,6 +110,11 @@ enum
#define IFLA_LINKINFO IFLA_LINKINFO
IFLA_NET_NS_PID,
IFLA_IFALIAS,
+ IFLA_NUM_VF, /* Number of VFs if device is SR-IOV PF */
+ IFLA_VFINFO_LIST,
+ IFLA_STATS64,
+ IFLA_VF_PORTS,
+ IFLA_PORT_SELF,
__IFLA_MAX
};
@@ -121,8 +155,7 @@ enum
*/
/* Subtype attributes for IFLA_PROTINFO */
-enum
-{
+enum {
IFLA_INET6_UNSPEC,
IFLA_INET6_FLAGS, /* link flags */
IFLA_INET6_CONF, /* sysctl parameters */
@@ -135,16 +168,14 @@ enum
#define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1)
-struct ifla_cacheinfo
-{
+struct ifla_cacheinfo {
__u32 max_reasm_len;
__u32 tstamp; /* ipv6InterfaceTable updated timestamp */
__u32 reachable_time;
__u32 retrans_time;
};
-enum
-{
+enum {
IFLA_INFO_UNSPEC,
IFLA_INFO_KIND,
IFLA_INFO_DATA,
@@ -156,8 +187,7 @@ enum
/* VLAN section */
-enum
-{
+enum {
IFLA_VLAN_UNSPEC,
IFLA_VLAN_ID,
IFLA_VLAN_FLAGS,
@@ -173,8 +203,7 @@ struct ifla_vlan_flags {
__u32 mask;
};
-enum
-{
+enum {
IFLA_VLAN_QOS_UNSPEC,
IFLA_VLAN_QOS_MAPPING,
__IFLA_VLAN_QOS_MAX
@@ -182,10 +211,140 @@ enum
#define IFLA_VLAN_QOS_MAX (__IFLA_VLAN_QOS_MAX - 1)
-struct ifla_vlan_qos_mapping
-{
+struct ifla_vlan_qos_mapping {
__u32 from;
__u32 to;
};
+/* MACVLAN section */
+enum {
+ IFLA_MACVLAN_UNSPEC,
+ IFLA_MACVLAN_MODE,
+ __IFLA_MACVLAN_MAX,
+};
+
+#define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1)
+
+enum macvlan_mode {
+ MACVLAN_MODE_PRIVATE = 1, /* don't talk to other macvlans */
+ MACVLAN_MODE_VEPA = 2, /* talk to other ports through ext bridge */
+ MACVLAN_MODE_BRIDGE = 4, /* talk to bridge ports directly */
+};
+
+/* SR-IOV virtual function managment section */
+
+enum {
+ IFLA_VF_INFO_UNSPEC,
+ IFLA_VF_INFO,
+ __IFLA_VF_INFO_MAX,
+};
+
+#define IFLA_VF_INFO_MAX (__IFLA_VF_INFO_MAX - 1)
+
+enum {
+ IFLA_VF_UNSPEC,
+ IFLA_VF_MAC, /* Hardware queue specific attributes */
+ IFLA_VF_VLAN,
+ IFLA_VF_TX_RATE, /* TX Bandwidth Allocation */
+ __IFLA_VF_MAX,
+};
+
+#define IFLA_VF_MAX (__IFLA_VF_MAX - 1)
+
+struct ifla_vf_mac {
+ __u32 vf;
+ __u8 mac[32]; /* MAX_ADDR_LEN */
+};
+
+struct ifla_vf_vlan {
+ __u32 vf;
+ __u32 vlan; /* 0 - 4095, 0 disables VLAN filter */
+ __u32 qos;
+};
+
+struct ifla_vf_tx_rate {
+ __u32 vf;
+ __u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */
+};
+
+struct ifla_vf_info {
+ __u32 vf;
+ __u8 mac[32];
+ __u32 vlan;
+ __u32 qos;
+ __u32 tx_rate;
+};
+
+/* VF ports management section
+ *
+ * Nested layout of set/get msg is:
+ *
+ * [IFLA_NUM_VF]
+ * [IFLA_VF_PORTS]
+ * [IFLA_VF_PORT]
+ * [IFLA_PORT_*], ...
+ * [IFLA_VF_PORT]
+ * [IFLA_PORT_*], ...
+ * ...
+ * [IFLA_PORT_SELF]
+ * [IFLA_PORT_*], ...
+ */
+
+enum {
+ IFLA_VF_PORT_UNSPEC,
+ IFLA_VF_PORT, /* nest */
+ __IFLA_VF_PORT_MAX,
+};
+
+#define IFLA_VF_PORT_MAX (__IFLA_VF_PORT_MAX - 1)
+
+enum {
+ IFLA_PORT_UNSPEC,
+ IFLA_PORT_VF, /* __u32 */
+ IFLA_PORT_PROFILE, /* string */
+ IFLA_PORT_VSI_TYPE, /* 802.1Qbg (pre-)standard VDP */
+ IFLA_PORT_INSTANCE_UUID, /* binary UUID */
+ IFLA_PORT_HOST_UUID, /* binary UUID */
+ IFLA_PORT_REQUEST, /* __u8 */
+ IFLA_PORT_RESPONSE, /* __u16, output only */
+ __IFLA_PORT_MAX,
+};
+
+#define IFLA_PORT_MAX (__IFLA_PORT_MAX - 1)
+
+#define PORT_PROFILE_MAX 40
+#define PORT_UUID_MAX 16
+#define PORT_SELF_VF -1
+
+enum {
+ PORT_REQUEST_PREASSOCIATE = 0,
+ PORT_REQUEST_PREASSOCIATE_RR,
+ PORT_REQUEST_ASSOCIATE,
+ PORT_REQUEST_DISASSOCIATE,
+};
+
+enum {
+ PORT_VDP_RESPONSE_SUCCESS = 0,
+ PORT_VDP_RESPONSE_INVALID_FORMAT,
+ PORT_VDP_RESPONSE_INSUFFICIENT_RESOURCES,
+ PORT_VDP_RESPONSE_UNUSED_VTID,
+ PORT_VDP_RESPONSE_VTID_VIOLATION,
+ PORT_VDP_RESPONSE_VTID_VERSION_VIOALTION,
+ PORT_VDP_RESPONSE_OUT_OF_SYNC,
+ /* 0x08-0xFF reserved for future VDP use */
+ PORT_PROFILE_RESPONSE_SUCCESS = 0x100,
+ PORT_PROFILE_RESPONSE_INPROGRESS,
+ PORT_PROFILE_RESPONSE_INVALID,
+ PORT_PROFILE_RESPONSE_BADSTATE,
+ PORT_PROFILE_RESPONSE_INSUFFICIENT_RESOURCES,
+ PORT_PROFILE_RESPONSE_ERROR,
+};
+
+struct ifla_port_vsi {
+ __u8 vsi_mgr_id;
+ __u8 vsi_type_id[3];
+ __u8 vsi_type_version;
+ __u8 pad[3];
+};
+
#endif /* _LINUX_IF_LINK_H */
diff --git a/include/linux/if_tun.h b/include/linux/if_tun.h
new file mode 100644
index 00000000..4054c1ac
--- /dev/null
+++ b/include/linux/if_tun.h
@@ -0,0 +1,94 @@
+/*
+ * Universal TUN/TAP device driver.
+ * Copyright (C) 1999-2000 Maxim Krasnyansky <max_mk@yahoo.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that 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.
+ */
+
+#ifndef __IF_TUN_H
+#define __IF_TUN_H
+
+#include <linux/types.h>
+#include <linux/if_ether.h>
+#include <linux/filter.h>
+
+/* Read queue size */
+#define TUN_READQ_SIZE 500
+
+/* TUN device flags */
+#define TUN_TUN_DEV 0x0001
+#define TUN_TAP_DEV 0x0002
+#define TUN_TYPE_MASK 0x000f
+
+#define TUN_FASYNC 0x0010
+#define TUN_NOCHECKSUM 0x0020
+#define TUN_NO_PI 0x0040
+#define TUN_ONE_QUEUE 0x0080
+#define TUN_PERSIST 0x0100
+#define TUN_VNET_HDR 0x0200
+
+/* Ioctl defines */
+#define TUNSETNOCSUM _IOW('T', 200, int)
+#define TUNSETDEBUG _IOW('T', 201, int)
+#define TUNSETIFF _IOW('T', 202, int)
+#define TUNSETPERSIST _IOW('T', 203, int)
+#define TUNSETOWNER _IOW('T', 204, int)
+#define TUNSETLINK _IOW('T', 205, int)
+#define TUNSETGROUP _IOW('T', 206, int)
+#define TUNGETFEATURES _IOR('T', 207, unsigned int)
+#define TUNSETOFFLOAD _IOW('T', 208, unsigned int)
+#define TUNSETTXFILTER _IOW('T', 209, unsigned int)
+#define TUNGETIFF _IOR('T', 210, unsigned int)
+#define TUNGETSNDBUF _IOR('T', 211, int)
+#define TUNSETSNDBUF _IOW('T', 212, int)
+#define TUNATTACHFILTER _IOW('T', 213, struct sock_fprog)
+#define TUNDETACHFILTER _IOW('T', 214, struct sock_fprog)
+#define TUNGETVNETHDRSZ _IOR('T', 215, int)
+#define TUNSETVNETHDRSZ _IOW('T', 216, int)
+
+/* TUNSETIFF ifr flags */
+#define IFF_TUN 0x0001
+#define IFF_TAP 0x0002
+#define IFF_NO_PI 0x1000
+#define IFF_ONE_QUEUE 0x2000
+#define IFF_VNET_HDR 0x4000
+#define IFF_TUN_EXCL 0x8000
+
+/* Features for GSO (TUNSETOFFLOAD). */
+#define TUN_F_CSUM 0x01 /* You can hand me unchecksummed packets. */
+#define TUN_F_TSO4 0x02 /* I can handle TSO for IPv4 packets */
+#define TUN_F_TSO6 0x04 /* I can handle TSO for IPv6 packets */
+#define TUN_F_TSO_ECN 0x08 /* I can handle TSO with ECN bits. */
+#define TUN_F_UFO 0x10 /* I can handle UFO packets */
+
+/* Protocol info prepended to the packets (when IFF_NO_PI is not set) */
+#define TUN_PKT_STRIP 0x0001
+struct tun_pi {
+ __u16 flags;
+ __be16 proto;
+};
+
+/*
+ * Filter spec (used for SETXXFILTER ioctls)
+ * This stuff is applicable only to the TAP (Ethernet) devices.
+ * If the count is zero the filter is disabled and the driver accepts
+ * all packets (promisc mode).
+ * If the filter is enabled in order to accept broadcast packets
+ * broadcast addr must be explicitly included in the addr list.
+ */
+#define TUN_FLT_ALLMULTI 0x0001 /* Accept all multicast packets */
+struct tun_filter {
+ __u16 flags; /* TUN_FLT_ flags see above */
+ __u16 count; /* Number of addresses */
+ __u8 addr[0][ETH_ALEN];
+};
+
+#endif /* __IF_TUN_H */
diff --git a/include/linux/if_tunnel.h b/include/linux/if_tunnel.h
index 3036cec1..8c819b8b 100644
--- a/include/linux/if_tunnel.h
+++ b/include/linux/if_tunnel.h
@@ -2,6 +2,7 @@
#define _IF_TUNNEL_H_
#include <linux/types.h>
+#include <asm/byteorder.h>
#define SIOCGETTUNNEL (SIOCDEVPRIVATE + 0)
@@ -12,6 +13,10 @@
#define SIOCADDPRL (SIOCDEVPRIVATE + 5)
#define SIOCDELPRL (SIOCDEVPRIVATE + 6)
#define SIOCCHGPRL (SIOCDEVPRIVATE + 7)
+#define SIOCGET6RD (SIOCDEVPRIVATE + 8)
+#define SIOCADD6RD (SIOCDEVPRIVATE + 9)
+#define SIOCDEL6RD (SIOCDEVPRIVATE + 10)
+#define SIOCCHG6RD (SIOCDEVPRIVATE + 11)
#define GRE_CSUM __cpu_to_be16(0x8000)
#define GRE_ROUTING __cpu_to_be16(0x4000)
@@ -22,8 +27,7 @@
#define GRE_FLAGS __cpu_to_be16(0x00F8)
#define GRE_VERSION __cpu_to_be16(0x0007)
-struct ip_tunnel_parm
-{
+struct ip_tunnel_parm {
char name[IFNAMSIZ];
int link;
__be16 i_flags;
@@ -48,8 +52,14 @@ struct ip_tunnel_prl {
/* PRL flags */
#define PRL_DEFAULT 0x0001
-enum
-{
+struct ip_tunnel_6rd {
+ struct in6_addr prefix;
+ __be32 relay_prefix;
+ __u16 prefixlen;
+ __u16 relay_prefixlen;
+};
+
+enum {
IFLA_GRE_UNSPEC,
IFLA_GRE_LINK,
IFLA_GRE_IFLAGS,
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 2dc4a57d..329b3546 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -33,6 +33,7 @@ enum vlan_ioctl_cmds {
enum vlan_flags {
VLAN_FLAG_REORDER_HDR = 0x1,
VLAN_FLAG_GVRP = 0x2,
+ VLAN_FLAG_LOOSE_BINDING = 0x4,
};
enum vlan_name_types {
diff --git a/include/linux/neighbour.h b/include/linux/neighbour.h
index 12c9de13..a7003b7a 100644
--- a/include/linux/neighbour.h
+++ b/include/linux/neighbour.h
@@ -4,8 +4,7 @@
#include <linux/types.h>
#include <linux/netlink.h>
-struct ndmsg
-{
+struct ndmsg {
__u8 ndm_family;
__u8 ndm_pad1;
__u16 ndm_pad2;
@@ -15,8 +14,7 @@ struct ndmsg
__u8 ndm_type;
};
-enum
-{
+enum {
NDA_UNSPEC,
NDA_DST,
NDA_LLADDR,
@@ -56,8 +54,7 @@ enum
NUD_PERMANENT is also cannot be deleted by garbage collectors.
*/
-struct nda_cacheinfo
-{
+struct nda_cacheinfo {
__u32 ndm_confirmed;
__u32 ndm_used;
__u32 ndm_updated;
@@ -89,8 +86,7 @@ struct nda_cacheinfo
* device.
****/
-struct ndt_stats
-{
+struct ndt_stats {
__u64 ndts_allocs;
__u64 ndts_destroys;
__u64 ndts_hash_grows;
@@ -124,15 +120,13 @@ enum {
};
#define NDTPA_MAX (__NDTPA_MAX - 1)
-struct ndtmsg
-{
+struct ndtmsg {
__u8 ndtm_family;
__u8 ndtm_pad1;
__u16 ndtm_pad2;
};
-struct ndt_config
-{
+struct ndt_config {
__u16 ndtc_key_len;
__u16 ndtc_entry_size;
__u32 ndtc_entries;
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 260f0109..3dbf0cc4 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -28,6 +28,7 @@
#include <linux/if.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
+#include <linux/if_link.h>
#define MAX_ADDR_LEN 32 /* Largest hardware address length */
@@ -38,8 +39,7 @@
* with byte counters.
*/
-struct net_device_stats
-{
+struct net_device_stats {
unsigned long rx_packets; /* total packets received */
unsigned long tx_packets; /* total packets transmitted */
unsigned long rx_bytes; /* total bytes received */
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 2794d971..fa2d9578 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -1,20 +1,19 @@
#ifndef _X_TABLES_H
#define _X_TABLES_H
-
+#include <linux/kernel.h>
#include <linux/types.h>
#define XT_FUNCTION_MAXNAMELEN 30
+#define XT_EXTENSION_MAXNAMELEN 29
#define XT_TABLE_MAXNAMELEN 32
-struct xt_entry_match
-{
+struct xt_entry_match {
union {
struct {
__u16 match_size;
/* Used by userspace */
- char name[XT_FUNCTION_MAXNAMELEN-1];
-
+ char name[XT_EXTENSION_MAXNAMELEN];
__u8 revision;
} user;
struct {
@@ -31,15 +30,13 @@ struct xt_entry_match
unsigned char data[0];
};
-struct xt_entry_target
-{
+struct xt_entry_target {
union {
struct {
__u16 target_size;
/* Used by userspace */
- char name[XT_FUNCTION_MAXNAMELEN-1];
-
+ char name[XT_EXTENSION_MAXNAMELEN];
__u8 revision;
} user;
struct {
@@ -64,18 +61,15 @@ struct xt_entry_target
}, \
}
-struct xt_standard_target
-{
+struct xt_standard_target {
struct xt_entry_target target;
int verdict;
};
/* The argument to IPT_SO_GET_REVISION_*. Returns highest revision
* kernel supports, if >= revision. */
-struct xt_get_revision
-{
- char name[XT_FUNCTION_MAXNAMELEN-1];
-
+struct xt_get_revision {
+ char name[XT_EXTENSION_MAXNAMELEN];
__u8 revision;
};
@@ -90,16 +84,14 @@ struct xt_get_revision
* ip6t_entry and arpt_entry. This sucks, and it is a hack. It will be my
* personal pleasure to remove it -HW
*/
-struct _xt_align
-{
+struct _xt_align {
__u8 u8;
__u16 u16;
__u32 u32;
__u64 u64;
};
-#define XT_ALIGN(s) (((s) + (__alignof__(struct _xt_align)-1)) \
- & ~(__alignof__(struct _xt_align)-1))
+#define XT_ALIGN(s) __ALIGN_KERNEL((s), __alignof__(struct _xt_align))
/* Standard return verdict, or do jump. */
#define XT_STANDARD_TARGET ""
@@ -109,14 +101,12 @@ struct _xt_align
#define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0)
#define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
-struct xt_counters
-{
+struct xt_counters {
__u64 pcnt, bcnt; /* Packet and byte counters */
};
/* The argument to IPT_SO_ADD_COUNTERS. */
-struct xt_counters_info
-{
+struct xt_counters_info {
/* Which table. */
char name[XT_TABLE_MAXNAMELEN];
@@ -172,4 +162,19 @@ struct xt_counters_info
XT_ENTRY_ITERATE_CONTINUE(type, entries, size, 0, fn, args)
+/* pos is normally a struct ipt_entry/ip6t_entry/etc. */
+#define xt_entry_foreach(pos, ehead, esize) \
+ for ((pos) = (typeof(pos))(ehead); \
+ (pos) < (typeof(pos))((char *)(ehead) + (esize)); \
+ (pos) = (typeof(pos))((char *)(pos) + (pos)->next_offset))
+
+/* can only be xt_entry_match, so no use of typeof here */
+#define xt_ematch_foreach(pos, entry) \
+ for ((pos) = (struct xt_entry_match *)entry->elems; \
+ (pos) < (struct xt_entry_match *)((char *)(entry) + \
+ (entry)->target_offset); \
+ (pos) = (struct xt_entry_match *)((char *)(pos) + \
+ (pos)->u.match_size))
+
+
#endif /* _X_TABLES_H */
diff --git a/include/linux/netfilter/xt_tcpudp.h b/include/linux/netfilter/xt_tcpudp.h
index a490a0bc..38aa7b39 100644
--- a/include/linux/netfilter/xt_tcpudp.h
+++ b/include/linux/netfilter/xt_tcpudp.h
@@ -4,8 +4,7 @@
#include <linux/types.h>
/* TCP matching stuff */
-struct xt_tcp
-{
+struct xt_tcp {
__u16 spts[2]; /* Source port range. */
__u16 dpts[2]; /* Destination port range. */
__u8 option; /* TCP Option iff non-zero*/
@@ -22,8 +21,7 @@ struct xt_tcp
#define XT_TCP_INV_MASK 0x0F /* All possible flags. */
/* UDP matching stuff */
-struct xt_udp
-{
+struct xt_udp {
__u16 spts[2]; /* Source port range. */
__u16 dpts[2]; /* Destination port range. */
__u8 invflags; /* Inverse flags */
diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h
index a9f21c9b..735f4b1b 100644
--- a/include/linux/netfilter_ipv4/ip_tables.h
+++ b/include/linux/netfilter_ipv4/ip_tables.h
@@ -70,8 +70,7 @@ struct ipt_ip {
/* This structure defines each of the firewall rules. Consists of 3
parts which are 1) general IP header stuff 2) match specific
stuff 3) the target to perform if the rule matches */
-struct ipt_entry
-{
+struct ipt_entry {
struct ipt_ip ip;
/* Mark with fields that we care about. */
@@ -129,8 +128,7 @@ struct ipt_entry
#define IPT_UDP_INV_MASK XT_UDP_INV_MASK
/* ICMP matching stuff */
-struct ipt_icmp
-{
+struct ipt_icmp {
u_int8_t type; /* type to match */
u_int8_t code[2]; /* range of code */
u_int8_t invflags; /* Inverse flags */
@@ -140,8 +138,7 @@ struct ipt_icmp
#define IPT_ICMP_INV 0x01 /* Invert the sense of type/code test */
/* The argument to IPT_SO_GET_INFO */
-struct ipt_getinfo
-{
+struct ipt_getinfo {
/* Which table: caller fills this in. */
char name[IPT_TABLE_MAXNAMELEN];
@@ -163,8 +160,7 @@ struct ipt_getinfo
};
/* The argument to IPT_SO_SET_REPLACE. */
-struct ipt_replace
-{
+struct ipt_replace {
/* Which table. */
char name[IPT_TABLE_MAXNAMELEN];
@@ -198,8 +194,7 @@ struct ipt_replace
#define ipt_counters_info xt_counters_info
/* The argument to IPT_SO_GET_ENTRIES. */
-struct ipt_get_entries
-{
+struct ipt_get_entries {
/* Which table: user fills this in. */
char name[IPT_TABLE_MAXNAMELEN];
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index ec780bbf..958b7f80 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -29,16 +29,14 @@
struct net;
-struct sockaddr_nl
-{
+struct sockaddr_nl {
sa_family_t nl_family; /* AF_NETLINK */
unsigned short nl_pad; /* zero */
__u32 nl_pid; /* port ID */
__u32 nl_groups; /* multicast groups mask */
};
-struct nlmsghdr
-{
+struct nlmsghdr {
__u32 nlmsg_len; /* Length of message including header */
__u16 nlmsg_type; /* Message content */
__u16 nlmsg_flags; /* Additional flags */
@@ -94,8 +92,7 @@ struct nlmsghdr
#define NLMSG_MIN_TYPE 0x10 /* < 0x10: reserved control messages */
-struct nlmsgerr
-{
+struct nlmsgerr {
int error;
struct nlmsghdr msg;
};
@@ -106,8 +103,7 @@ struct nlmsgerr
#define NETLINK_BROADCAST_ERROR 4
#define NETLINK_NO_ENOBUFS 5
-struct nl_pktinfo
-{
+struct nl_pktinfo {
__u32 group;
};
@@ -127,8 +123,7 @@ enum {
* <-------------- nlattr->nla_len -------------->
*/
-struct nlattr
-{
+struct nlattr {
__u16 nla_len;
__u16 nla_type;
};
diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h
index 3c842edf..7f6ba865 100644
--- a/include/linux/pkt_cls.h
+++ b/include/linux/pkt_cls.h
@@ -75,8 +75,7 @@ bits 9,10,11: redirect counter - redirect TTL. Loop avoidance
#define SET_TC_AT(v,n) ((V_TC_AT(n)) | (v & ~M_TC_AT))
/* Action attributes */
-enum
-{
+enum {
TCA_ACT_UNSPEC,
TCA_ACT_KIND,
TCA_ACT_OPTIONS,
@@ -108,8 +107,7 @@ enum
#define TC_ACT_JUMP 0x10000000
/* Action type identifiers*/
-enum
-{
+enum {
TCA_ID_UNSPEC=0,
TCA_ID_POLICE=1,
/* other actions go here */
@@ -118,8 +116,7 @@ enum
#define TCA_ID_MAX __TCA_ID_MAX
-struct tc_police
-{
+struct tc_police {
__u32 index;
int action;
#define TC_POLICE_UNSPEC TC_ACT_UNSPEC
@@ -138,15 +135,13 @@ struct tc_police
__u32 capab;
};
-struct tcf_t
-{
+struct tcf_t {
__u64 install;
__u64 lastuse;
__u64 expires;
};
-struct tc_cnt
-{
+struct tc_cnt {
int refcnt;
int bindcnt;
};
@@ -158,8 +153,7 @@ struct tc_cnt
int refcnt; \
int bindcnt
-enum
-{
+enum {
TCA_POLICE_UNSPEC,
TCA_POLICE_TBF,
TCA_POLICE_RATE,
@@ -182,8 +176,7 @@ enum
#define TC_U32_UNSPEC 0
#define TC_U32_ROOT (0xFFF00000)
-enum
-{
+enum {
TCA_U32_UNSPEC,
TCA_U32_CLASSID,
TCA_U32_HASH,
@@ -200,16 +193,14 @@ enum
#define TCA_U32_MAX (__TCA_U32_MAX - 1)
-struct tc_u32_key
-{
+struct tc_u32_key {
__be32 mask;
__be32 val;
int off;
int offmask;
};
-struct tc_u32_sel
-{
+struct tc_u32_sel {
unsigned char flags;
unsigned char offshift;
unsigned char nkeys;
@@ -223,15 +214,13 @@ struct tc_u32_sel
struct tc_u32_key keys[0];
};
-struct tc_u32_mark
-{
+struct tc_u32_mark {
__u32 val;
__u32 mask;
__u32 success;
};
-struct tc_u32_pcnt
-{
+struct tc_u32_pcnt {
__u64 rcnt;
__u64 rhit;
__u64 kcnts[0];
@@ -249,8 +238,7 @@ struct tc_u32_pcnt
/* RSVP filter */
-enum
-{
+enum {
TCA_RSVP_UNSPEC,
TCA_RSVP_CLASSID,
TCA_RSVP_DST,
@@ -263,15 +251,13 @@ enum
#define TCA_RSVP_MAX (__TCA_RSVP_MAX - 1 )
-struct tc_rsvp_gpi
-{
+struct tc_rsvp_gpi {
__u32 key;
__u32 mask;
int offset;
};
-struct tc_rsvp_pinfo
-{
+struct tc_rsvp_pinfo {
struct tc_rsvp_gpi dpi;
struct tc_rsvp_gpi spi;
__u8 protocol;
@@ -282,8 +268,7 @@ struct tc_rsvp_pinfo
/* ROUTE filter */
-enum
-{
+enum {
TCA_ROUTE4_UNSPEC,
TCA_ROUTE4_CLASSID,
TCA_ROUTE4_TO,
@@ -299,8 +284,7 @@ enum
/* FW filter */
-enum
-{
+enum {
TCA_FW_UNSPEC,
TCA_FW_CLASSID,
TCA_FW_POLICE,
@@ -314,8 +298,7 @@ enum
/* TC index filter */
-enum
-{
+enum {
TCA_TCINDEX_UNSPEC,
TCA_TCINDEX_HASH,
TCA_TCINDEX_MASK,
@@ -331,8 +314,7 @@ enum
/* Flow filter */
-enum
-{
+enum {
FLOW_KEY_SRC,
FLOW_KEY_DST,
FLOW_KEY_PROTO,
@@ -355,14 +337,12 @@ enum
#define FLOW_KEY_MAX (__FLOW_KEY_MAX - 1)
-enum
-{
+enum {
FLOW_MODE_MAP,
FLOW_MODE_HASH,
};
-enum
-{
+enum {
TCA_FLOW_UNSPEC,
TCA_FLOW_KEYS,
TCA_FLOW_MODE,
@@ -383,8 +363,7 @@ enum
/* Basic filter */
-enum
-{
+enum {
TCA_BASIC_UNSPEC,
TCA_BASIC_CLASSID,
TCA_BASIC_EMATCHES,
@@ -398,8 +377,7 @@ enum
/* Cgroup classifier */
-enum
-{
+enum {
TCA_CGROUP_UNSPEC,
TCA_CGROUP_ACT,
TCA_CGROUP_POLICE,
@@ -411,14 +389,12 @@ enum
/* Extended Matches */
-struct tcf_ematch_tree_hdr
-{
+struct tcf_ematch_tree_hdr {
__u16 nmatches;
__u16 progid;
};
-enum
-{
+enum {
TCA_EMATCH_TREE_UNSPEC,
TCA_EMATCH_TREE_HDR,
TCA_EMATCH_TREE_LIST,
@@ -426,8 +402,7 @@ enum
};
#define TCA_EMATCH_TREE_MAX (__TCA_EMATCH_TREE_MAX - 1)
-struct tcf_ematch_hdr
-{
+struct tcf_ematch_hdr {
__u16 matchid;
__u16 kind;
__u16 flags;
@@ -457,8 +432,7 @@ struct tcf_ematch_hdr
#define TCF_EM_REL_MASK 3
#define TCF_EM_REL_VALID(v) (((v) & TCF_EM_REL_MASK) != TCF_EM_REL_MASK)
-enum
-{
+enum {
TCF_LAYER_LINK,
TCF_LAYER_NETWORK,
TCF_LAYER_TRANSPORT,
@@ -479,13 +453,11 @@ enum
#define TCF_EM_VLAN 6
#define TCF_EM_MAX 6
-enum
-{
+enum {
TCF_EM_PROG_TC
};
-enum
-{
+enum {
TCF_EM_OPND_EQ,
TCF_EM_OPND_GT,
TCF_EM_OPND_LT
diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h
index d51a2b3e..2cfa4bc8 100644
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -29,8 +29,7 @@
Particular schedulers may have also their private records.
*/
-struct tc_stats
-{
+struct tc_stats {
__u64 bytes; /* NUmber of enqueues bytes */
__u32 packets; /* Number of enqueued packets */
__u32 drops; /* Packets dropped because of lack of resources */
@@ -42,8 +41,7 @@ struct tc_stats
__u32 backlog;
};
-struct tc_estimator
-{
+struct tc_estimator {
signed char interval;
unsigned char ewma_log;
};
@@ -75,8 +73,7 @@ struct tc_estimator
#define TC_H_ROOT (0xFFFFFFFFU)
#define TC_H_INGRESS (0xFFFFFFF1U)
-struct tc_ratespec
-{
+struct tc_ratespec {
unsigned char cell_log;
unsigned char __reserved;
unsigned short overhead;
@@ -109,8 +106,7 @@ enum {
/* FIFO section */
-struct tc_fifo_qopt
-{
+struct tc_fifo_qopt {
__u32 limit; /* Queue length: bytes for bfifo, packets for pfifo */
};
@@ -119,8 +115,7 @@ struct tc_fifo_qopt
#define TCQ_PRIO_BANDS 16
#define TCQ_MIN_PRIO_BANDS 2
-struct tc_prio_qopt
-{
+struct tc_prio_qopt {
int bands; /* Number of bands */
__u8 priomap[TC_PRIO_MAX+1]; /* Map: logical priority -> PRIO band */
};
@@ -134,8 +129,7 @@ struct tc_multiq_qopt {
/* TBF section */
-struct tc_tbf_qopt
-{
+struct tc_tbf_qopt {
struct tc_ratespec rate;
struct tc_ratespec peakrate;
__u32 limit;
@@ -143,8 +137,7 @@ struct tc_tbf_qopt
__u32 mtu;
};
-enum
-{
+enum {
TCA_TBF_UNSPEC,
TCA_TBF_PARMS,
TCA_TBF_RTAB,
@@ -161,8 +154,7 @@ enum
/* SFQ section */
-struct tc_sfq_qopt
-{
+struct tc_sfq_qopt {
unsigned quantum; /* Bytes per round allocated to flow */
int perturb_period; /* Period of hash perturbation */
__u32 limit; /* Maximal packets in queue */
@@ -170,8 +162,7 @@ struct tc_sfq_qopt
unsigned flows; /* Maximal number of flows */
};
-struct tc_sfq_xstats
-{
+struct tc_sfq_xstats {
__s32 allot;
};
@@ -186,8 +177,7 @@ struct tc_sfq_xstats
/* RED section */
-enum
-{
+enum {
TCA_RED_UNSPEC,
TCA_RED_PARMS,
TCA_RED_STAB,
@@ -196,8 +186,7 @@ enum
#define TCA_RED_MAX (__TCA_RED_MAX - 1)
-struct tc_red_qopt
-{
+struct tc_red_qopt {
__u32 limit; /* HARD maximal queue length (bytes) */
__u32 qth_min; /* Min average length threshold (bytes) */
__u32 qth_max; /* Max average length threshold (bytes) */
@@ -209,8 +198,7 @@ struct tc_red_qopt
#define TC_RED_HARDDROP 2
};
-struct tc_red_xstats
-{
+struct tc_red_xstats {
__u32 early; /* Early drops */
__u32 pdrop; /* Drops due to queue limits */
__u32 other; /* Drops due to drop() calls */
@@ -221,8 +209,7 @@ struct tc_red_xstats
#define MAX_DPs 16
-enum
-{
+enum {
TCA_GRED_UNSPEC,
TCA_GRED_PARMS,
TCA_GRED_STAB,
@@ -232,8 +219,7 @@ enum
#define TCA_GRED_MAX (__TCA_GRED_MAX - 1)
-struct tc_gred_qopt
-{
+struct tc_gred_qopt {
__u32 limit; /* HARD maximal queue length (bytes) */
__u32 qth_min; /* Min average length threshold (bytes) */
__u32 qth_max; /* Max average length threshold (bytes) */
@@ -253,8 +239,7 @@ struct tc_gred_qopt
};
/* gred setup */
-struct tc_gred_sopt
-{
+struct tc_gred_sopt {
__u32 DPs;
__u32 def_DP;
__u8 grio;
@@ -267,8 +252,7 @@ struct tc_gred_sopt
#define TC_HTB_MAXDEPTH 8
#define TC_HTB_PROTOVER 3 /* the same as HTB and TC's major */
-struct tc_htb_opt
-{
+struct tc_htb_opt {
struct tc_ratespec rate;
struct tc_ratespec ceil;
__u32 buffer;
@@ -277,8 +261,7 @@ struct tc_htb_opt
__u32 level; /* out only */
__u32 prio;
};
-struct tc_htb_glob
-{
+struct tc_htb_glob {
__u32 version; /* to match HTB/TC */
__u32 rate2quantum; /* bps->quantum divisor */
__u32 defcls; /* default class number */
@@ -287,8 +270,7 @@ struct tc_htb_glob
/* stats */
__u32 direct_pkts; /* count of non shapped packets */
};
-enum
-{
+enum {
TCA_HTB_UNSPEC,
TCA_HTB_PARMS,
TCA_HTB_INIT,
@@ -299,8 +281,7 @@ enum
#define TCA_HTB_MAX (__TCA_HTB_MAX - 1)
-struct tc_htb_xstats
-{
+struct tc_htb_xstats {
__u32 lends;
__u32 borrows;
__u32 giants; /* too big packets (rate will not be accurate) */
@@ -310,28 +291,24 @@ struct tc_htb_xstats
/* HFSC section */
-struct tc_hfsc_qopt
-{
+struct tc_hfsc_qopt {
__u16 defcls; /* default class */
};
-struct tc_service_curve
-{
+struct tc_service_curve {
__u32 m1; /* slope of the first segment in bps */
__u32 d; /* x-projection of the first segment in us */
__u32 m2; /* slope of the second segment in bps */
};
-struct tc_hfsc_stats
-{
+struct tc_hfsc_stats {
__u64 work; /* total work done */
__u64 rtwork; /* work done by real-time criteria */
__u32 period; /* current period */
__u32 level; /* class level in hierarchy */
};
-enum
-{
+enum {
TCA_HFSC_UNSPEC,
TCA_HFSC_RSC,
TCA_HFSC_FSC,
@@ -348,8 +325,7 @@ enum
#define TC_CBQ_MAXLEVEL 8
#define TC_CBQ_DEF_EWMA 5
-struct tc_cbq_lssopt
-{
+struct tc_cbq_lssopt {
unsigned char change;
unsigned char flags;
#define TCF_CBQ_LSS_BOUNDED 1
@@ -368,8 +344,7 @@ struct tc_cbq_lssopt
__u32 avpkt;
};
-struct tc_cbq_wrropt
-{
+struct tc_cbq_wrropt {
unsigned char flags;
unsigned char priority;
unsigned char cpriority;
@@ -378,8 +353,7 @@ struct tc_cbq_wrropt
__u32 weight;
};
-struct tc_cbq_ovl
-{
+struct tc_cbq_ovl {
unsigned char strategy;
#define TC_CBQ_OVL_CLASSIC 0
#define TC_CBQ_OVL_DELAY 1
@@ -391,30 +365,26 @@ struct tc_cbq_ovl
__u32 penalty;
};
-struct tc_cbq_police
-{
+struct tc_cbq_police {
unsigned char police;
unsigned char __res1;
unsigned short __res2;
};
-struct tc_cbq_fopt
-{
+struct tc_cbq_fopt {
__u32 split;
__u32 defmap;
__u32 defchange;
};
-struct tc_cbq_xstats
-{
+struct tc_cbq_xstats {
__u32 borrows;
__u32 overactions;
__s32 avgidle;
__s32 undertime;
};
-enum
-{
+enum {
TCA_CBQ_UNSPEC,
TCA_CBQ_LSSOPT,
TCA_CBQ_WRROPT,
@@ -459,8 +429,7 @@ enum {
/* Network emulator */
-enum
-{
+enum {
TCA_NETEM_UNSPEC,
TCA_NETEM_CORR,
TCA_NETEM_DELAY_DIST,
@@ -471,8 +440,7 @@ enum
#define TCA_NETEM_MAX (__TCA_NETEM_MAX - 1)
-struct tc_netem_qopt
-{
+struct tc_netem_qopt {
__u32 latency; /* added delay (us) */
__u32 limit; /* fifo limit (packets) */
__u32 loss; /* random packet loss (0=none ~0=100%) */
@@ -481,21 +449,18 @@ struct tc_netem_qopt
__u32 jitter; /* random jitter in latency (us) */
};
-struct tc_netem_corr
-{
+struct tc_netem_corr {
__u32 delay_corr; /* delay correlation */
__u32 loss_corr; /* packet loss correlation */
__u32 dup_corr; /* duplicate correlation */
};
-struct tc_netem_reorder
-{
+struct tc_netem_reorder {
__u32 probability;
__u32 correlation;
};
-struct tc_netem_corrupt
-{
+struct tc_netem_corrupt {
__u32 probability;
__u32 correlation;
};
@@ -504,8 +469,7 @@ struct tc_netem_corrupt
/* DRR */
-enum
-{
+enum {
TCA_DRR_UNSPEC,
TCA_DRR_QUANTUM,
__TCA_DRR_MAX
@@ -513,8 +477,7 @@ enum
#define TCA_DRR_MAX (__TCA_DRR_MAX - 1)
-struct tc_drr_stats
-{
+struct tc_drr_stats {
__u32 deficit;
};
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index e8623807..0d8ef9ec 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -7,6 +7,13 @@
#include <linux/if_addr.h>
#include <linux/neighbour.h>
+/* rtnetlink families. Values up to 127 are reserved for real address
+ * families, values above 128 may be used arbitrarily.
+ */
+#define RTNL_FAMILY_IPMR 128
+#define RTNL_FAMILY_IP6MR 129
+#define RTNL_FAMILY_MAX 129
+
/****
* Routing/neighbour discovery messages.
****/
@@ -127,8 +134,7 @@ enum {
with attribute type.
*/
-struct rtattr
-{
+struct rtattr {
unsigned short rta_len;
unsigned short rta_type;
};
@@ -154,8 +160,7 @@ struct rtattr
* Definitions used in routing table administration.
****/
-struct rtmsg
-{
+struct rtmsg {
unsigned char rtm_family;
unsigned char rtm_dst_len;
unsigned char rtm_src_len;
@@ -171,8 +176,7 @@ struct rtmsg
/* rtm_type */
-enum
-{
+enum {
RTN_UNSPEC,
RTN_UNICAST, /* Gateway or direct route */
RTN_LOCAL, /* Accept locally */
@@ -230,8 +234,7 @@ enum
could be assigned a value between UNIVERSE and LINK.
*/
-enum rt_scope_t
-{
+enum rt_scope_t {
RT_SCOPE_UNIVERSE=0,
/* User defined values */
RT_SCOPE_SITE=200,
@@ -249,8 +252,7 @@ enum rt_scope_t
/* Reserved table identifiers */
-enum rt_class_t
-{
+enum rt_class_t {
RT_TABLE_UNSPEC=0,
/* User defined values */
RT_TABLE_COMPAT=252,
@@ -263,8 +265,7 @@ enum rt_class_t
/* Routing message attributes */
-enum rtattr_type_t
-{
+enum rtattr_type_t {
RTA_UNSPEC,
RTA_DST,
RTA_SRC,
@@ -298,8 +299,7 @@ enum rtattr_type_t
* and rtt for different paths from multipath.
*/
-struct rtnexthop
-{
+struct rtnexthop {
unsigned short rtnh_len;
unsigned char rtnh_flags;
unsigned char rtnh_hops;
@@ -325,8 +325,7 @@ struct rtnexthop
/* RTM_CACHEINFO */
-struct rta_cacheinfo
-{
+struct rta_cacheinfo {
__u32 rta_clntref;
__u32 rta_lastuse;
__s32 rta_expires;
@@ -341,8 +340,7 @@ struct rta_cacheinfo
/* RTM_METRICS --- array of struct rtattr with types of RTAX_* */
-enum
-{
+enum {
RTAX_UNSPEC,
#define RTAX_UNSPEC RTAX_UNSPEC
RTAX_LOCK,
@@ -371,6 +369,8 @@ enum
#define RTAX_FEATURES RTAX_FEATURES
RTAX_RTO_MIN,
#define RTAX_RTO_MIN RTAX_RTO_MIN
+ RTAX_INITRWND,
+#define RTAX_INITRWND RTAX_INITRWND
__RTAX_MAX
};
@@ -381,8 +381,7 @@ enum
#define RTAX_FEATURE_TIMESTAMP 0x00000004
#define RTAX_FEATURE_ALLFRAG 0x00000008
-struct rta_session
-{
+struct rta_session {
__u8 proto;
__u8 pad1;
__u16 pad2;
@@ -407,8 +406,7 @@ struct rta_session
* General form of address family dependent message.
****/
-struct rtgenmsg
-{
+struct rtgenmsg {
unsigned char rtgen_family;
};
@@ -421,8 +419,7 @@ struct rtgenmsg
* on network protocol.
*/
-struct ifinfomsg
-{
+struct ifinfomsg {
unsigned char ifi_family;
unsigned char __ifi_pad;
unsigned short ifi_type; /* ARPHRD_* */
@@ -435,8 +432,7 @@ struct ifinfomsg
* prefix information
****/
-struct prefixmsg
-{
+struct prefixmsg {
unsigned char prefix_family;
unsigned char prefix_pad1;
unsigned short prefix_pad2;
@@ -457,8 +453,7 @@ enum
#define PREFIX_MAX (__PREFIX_MAX - 1)
-struct prefix_cacheinfo
-{
+struct prefix_cacheinfo {
__u32 preferred_time;
__u32 valid_time;
};
@@ -468,8 +463,7 @@ struct prefix_cacheinfo
* Traffic control messages.
****/
-struct tcmsg
-{
+struct tcmsg {
unsigned char tcm_family;
unsigned char tcm__pad1;
unsigned short tcm__pad2;
@@ -479,8 +473,7 @@ struct tcmsg
__u32 tcm_info;
};
-enum
-{
+enum {
TCA_UNSPEC,
TCA_KIND,
TCA_OPTIONS,
@@ -502,8 +495,7 @@ enum
* Neighbor Discovery userland options
****/
-struct nduseroptmsg
-{
+struct nduseroptmsg {
unsigned char nduseropt_family;
unsigned char nduseropt_pad1;
unsigned short nduseropt_opts_len; /* Total length of options */
@@ -515,8 +507,7 @@ struct nduseroptmsg
/* Followed by one or more ND options */
};
-enum
-{
+enum {
NDUSEROPT_UNSPEC,
NDUSEROPT_SRCADDR,
__NDUSEROPT_MAX
@@ -596,8 +587,7 @@ enum rtnetlink_groups {
#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
/* TC action piece */
-struct tcamsg
-{
+struct tcamsg {
unsigned char tca_family;
unsigned char tca__pad1;
unsigned short tca__pad2;
diff --git a/include/linux/tc_act/tc_gact.h b/include/linux/tc_act/tc_gact.h
index e895c0a3..f7bf94ee 100644
--- a/include/linux/tc_act/tc_gact.h
+++ b/include/linux/tc_act/tc_gact.h
@@ -5,14 +5,12 @@
#include <linux/pkt_cls.h>
#define TCA_ACT_GACT 5
-struct tc_gact
-{
+struct tc_gact {
tc_gen;
};
-struct tc_gact_p
-{
+struct tc_gact_p {
#define PGACT_NONE 0
#define PGACT_NETRAND 1
#define PGACT_DETERM 2
@@ -22,8 +20,7 @@ struct tc_gact_p
int paction;
};
-enum
-{
+enum {
TCA_GACT_UNSPEC,
TCA_GACT_TM,
TCA_GACT_PARMS,
diff --git a/include/linux/tc_act/tc_ipt.h b/include/linux/tc_act/tc_ipt.h
index 4b6f7b6c..a2335563 100644
--- a/include/linux/tc_act/tc_ipt.h
+++ b/include/linux/tc_act/tc_ipt.h
@@ -5,8 +5,7 @@
#define TCA_ACT_IPT 6
-enum
-{
+enum {
TCA_IPT_UNSPEC,
TCA_IPT_TABLE,
TCA_IPT_HOOK,
diff --git a/include/linux/tc_act/tc_mirred.h b/include/linux/tc_act/tc_mirred.h
index 0a99ab60..7561750e 100644
--- a/include/linux/tc_act/tc_mirred.h
+++ b/include/linux/tc_act/tc_mirred.h
@@ -10,15 +10,13 @@
#define TCA_INGRESS_REDIR 3 /* packet redirect to INGRESS*/
#define TCA_INGRESS_MIRROR 4 /* mirror packet to INGRESS */
-struct tc_mirred
-{
+struct tc_mirred {
tc_gen;
int eaction; /* one of IN/EGRESS_MIRROR/REDIR */
__u32 ifindex; /* ifindex of egress port */
};
-enum
-{
+enum {
TCA_MIRRED_UNSPEC,
TCA_MIRRED_TM,
TCA_MIRRED_PARMS,
diff --git a/include/linux/tc_act/tc_nat.h b/include/linux/tc_act/tc_nat.h
index e7cf31e8..6663aeba 100644
--- a/include/linux/tc_act/tc_nat.h
+++ b/include/linux/tc_act/tc_nat.h
@@ -6,8 +6,7 @@
#define TCA_ACT_NAT 9
-enum
-{
+enum {
TCA_NAT_UNSPEC,
TCA_NAT_PARMS,
TCA_NAT_TM,
@@ -17,8 +16,7 @@ enum
#define TCA_NAT_FLAG_EGRESS 1
-struct tc_nat
-{
+struct tc_nat {
tc_gen;
__be32 old_addr;
__be32 new_addr;
diff --git a/include/linux/tc_act/tc_pedit.h b/include/linux/tc_act/tc_pedit.h
index 54ce9064..716cfabc 100644
--- a/include/linux/tc_act/tc_pedit.h
+++ b/include/linux/tc_act/tc_pedit.h
@@ -6,8 +6,7 @@
#define TCA_ACT_PEDIT 7
-enum
-{
+enum {
TCA_PEDIT_UNSPEC,
TCA_PEDIT_TM,
TCA_PEDIT_PARMS,
@@ -15,8 +14,7 @@ enum
};
#define TCA_PEDIT_MAX (__TCA_PEDIT_MAX - 1)
-struct tc_pedit_key
-{
+struct tc_pedit_key {
__u32 mask; /* AND */
__u32 val; /*XOR */
__u32 off; /*offset */
@@ -25,8 +23,7 @@ struct tc_pedit_key
__u32 shift;
};
-struct tc_pedit_sel
-{
+struct tc_pedit_sel {
tc_gen;
unsigned char nkeys;
unsigned char flags;
diff --git a/include/linux/tc_act/tc_skbedit.h b/include/linux/tc_act/tc_skbedit.h
index a14e461a..7a2e910a 100644
--- a/include/linux/tc_act/tc_skbedit.h
+++ b/include/linux/tc_act/tc_skbedit.h
@@ -26,6 +26,7 @@
#define SKBEDIT_F_PRIORITY 0x1
#define SKBEDIT_F_QUEUE_MAPPING 0x2
+#define SKBEDIT_F_MARK 0x4
struct tc_skbedit {
tc_gen;
@@ -37,6 +38,7 @@ enum {
TCA_SKBEDIT_PARMS,
TCA_SKBEDIT_PRIORITY,
TCA_SKBEDIT_QUEUE_MAPPING,
+ TCA_SKBEDIT_MARK,
__TCA_SKBEDIT_MAX
};
#define TCA_SKBEDIT_MAX (__TCA_SKBEDIT_MAX - 1)
diff --git a/include/linux/tc_ematch/tc_em_cmp.h b/include/linux/tc_ematch/tc_em_cmp.h
index 38e7f7b2..f34bb1ba 100644
--- a/include/linux/tc_ematch/tc_em_cmp.h
+++ b/include/linux/tc_ematch/tc_em_cmp.h
@@ -4,8 +4,7 @@
#include <linux/types.h>
#include <linux/pkt_cls.h>
-struct tcf_em_cmp
-{
+struct tcf_em_cmp {
__u32 val;
__u32 mask;
__u16 off;
@@ -15,8 +14,7 @@ struct tcf_em_cmp
__u8 opnd:4;
};
-enum
-{
+enum {
TCF_EM_ALIGN_U8 = 1,
TCF_EM_ALIGN_U16 = 2,
TCF_EM_ALIGN_U32 = 4
diff --git a/include/linux/tc_ematch/tc_em_meta.h b/include/linux/tc_ematch/tc_em_meta.h
index dcfb733f..0864206e 100644
--- a/include/linux/tc_ematch/tc_em_meta.h
+++ b/include/linux/tc_ematch/tc_em_meta.h
@@ -4,8 +4,7 @@
#include <linux/types.h>
#include <linux/pkt_cls.h>
-enum
-{
+enum {
TCA_EM_META_UNSPEC,
TCA_EM_META_HDR,
TCA_EM_META_LVALUE,
@@ -14,8 +13,7 @@ enum
};
#define TCA_EM_META_MAX (__TCA_EM_META_MAX - 1)
-struct tcf_meta_val
-{
+struct tcf_meta_val {
__u16 kind;
__u8 shift;
__u8 op;
@@ -26,16 +24,14 @@ struct tcf_meta_val
#define TCF_META_ID_MASK 0x7ff
#define TCF_META_ID(kind) ((kind) & TCF_META_ID_MASK)
-enum
-{
+enum {
TCF_META_TYPE_VAR,
TCF_META_TYPE_INT,
__TCF_META_TYPE_MAX
};
#define TCF_META_TYPE_MAX (__TCF_META_TYPE_MAX - 1)
-enum
-{
+enum {
TCF_META_ID_VALUE,
TCF_META_ID_RANDOM,
TCF_META_ID_LOADAVG_0,
@@ -87,8 +83,7 @@ enum
};
#define TCF_META_ID_MAX (__TCF_META_ID_MAX - 1)
-struct tcf_meta_hdr
-{
+struct tcf_meta_hdr {
struct tcf_meta_val left;
struct tcf_meta_val right;
};
diff --git a/include/linux/tc_ematch/tc_em_nbyte.h b/include/linux/tc_ematch/tc_em_nbyte.h
index 9ed8c2e5..7172cfb9 100644
--- a/include/linux/tc_ematch/tc_em_nbyte.h
+++ b/include/linux/tc_ematch/tc_em_nbyte.h
@@ -4,8 +4,7 @@
#include <linux/types.h>
#include <linux/pkt_cls.h>
-struct tcf_em_nbyte
-{
+struct tcf_em_nbyte {
__u16 off;
__u16 len:12;
__u8 layer:4;
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index a59bc4a9..07f2b63e 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -10,8 +10,7 @@
/* Structure to encapsulate addresses. I do not want to use
* "standard" structure. My apologies.
*/
-typedef union
-{
+typedef union {
__be32 a4;
__be32 a6[4];
} xfrm_address_t;
@@ -20,8 +19,7 @@ typedef union
* the state by (spi,daddr,ah/esp) or to store information about
* spi, protocol and tunnel address on output.
*/
-struct xfrm_id
-{
+struct xfrm_id {
xfrm_address_t daddr;
__be32 spi;
__u8 proto;
@@ -45,8 +43,7 @@ struct xfrm_sec_ctx {
/* Selector, used as selector both on policy rules (SPD) and SAs. */
-struct xfrm_selector
-{
+struct xfrm_selector {
xfrm_address_t daddr;
xfrm_address_t saddr;
__be16 dport;
@@ -63,8 +60,7 @@ struct xfrm_selector
#define XFRM_INF (~(__u64)0)
-struct xfrm_lifetime_cfg
-{
+struct xfrm_lifetime_cfg {
__u64 soft_byte_limit;
__u64 hard_byte_limit;
__u64 soft_packet_limit;
@@ -75,16 +71,14 @@ struct xfrm_lifetime_cfg
__u64 hard_use_expires_seconds;
};
-struct xfrm_lifetime_cur
-{
+struct xfrm_lifetime_cur {
__u64 bytes;
__u64 packets;
__u64 add_time;
__u64 use_time;
};
-struct xfrm_replay_state
-{
+struct xfrm_replay_state {
__u32 oseq;
__u32 seq;
__u32 bitmap;
@@ -96,6 +90,13 @@ struct xfrm_algo {
char alg_key[0];
};
+struct xfrm_algo_auth {
+ char alg_name[64];
+ unsigned int alg_key_len; /* in bits */
+ unsigned int alg_trunc_len; /* in bits */
+ char alg_key[0];
+};
+
struct xfrm_algo_aead {
char alg_name[64];
unsigned int alg_key_len; /* in bits */
@@ -109,16 +110,14 @@ struct xfrm_stats {
__u32 integrity_failed;
};
-enum
-{
+enum {
XFRM_POLICY_TYPE_MAIN = 0,
XFRM_POLICY_TYPE_SUB = 1,
XFRM_POLICY_TYPE_MAX = 2,
XFRM_POLICY_TYPE_ANY = 255
};
-enum
-{
+enum {
XFRM_POLICY_IN = 0,
XFRM_POLICY_OUT = 1,
XFRM_POLICY_FWD = 2,
@@ -126,8 +125,7 @@ enum
XFRM_POLICY_MAX = 3
};
-enum
-{
+enum {
XFRM_SHARE_ANY, /* No limitations */
XFRM_SHARE_SESSION, /* For this session only */
XFRM_SHARE_USER, /* For this user only */
@@ -269,8 +267,8 @@ enum xfrm_attr_type_t {
XFRMA_ALG_COMP, /* struct xfrm_algo */
XFRMA_ENCAP, /* struct xfrm_algo + struct xfrm_encap_tmpl */
XFRMA_TMPL, /* 1 or more struct xfrm_user_tmpl */
- XFRMA_SA,
- XFRMA_POLICY,
+ XFRMA_SA, /* struct xfrm_usersa_info */
+ XFRMA_POLICY, /*struct xfrm_userpolicy_info */
XFRMA_SEC_CTX, /* struct xfrm_sec_ctx */
XFRMA_LTIME_VAL,
XFRMA_REPLAY_VAL,
@@ -278,16 +276,23 @@ enum xfrm_attr_type_t {
XFRMA_ETIMER_THRESH,
XFRMA_SRCADDR, /* xfrm_address_t */
XFRMA_COADDR, /* xfrm_address_t */
- XFRMA_LASTUSED,
+ XFRMA_LASTUSED, /* unsigned long */
XFRMA_POLICY_TYPE, /* struct xfrm_userpolicy_type */
XFRMA_MIGRATE,
XFRMA_ALG_AEAD, /* struct xfrm_algo_aead */
XFRMA_KMADDRESS, /* struct xfrm_user_kmaddress */
+ XFRMA_ALG_AUTH_TRUNC, /* struct xfrm_algo_auth */
+ XFRMA_MARK, /* struct xfrm_mark */
__XFRMA_MAX
#define XFRMA_MAX (__XFRMA_MAX - 1)
};
+struct xfrm_mark {
+ __u32 v; /* value */
+ __u32 m; /* mask */
+};
+
enum xfrm_sadattr_type_t {
XFRMA_SAD_UNSPEC,
XFRMA_SAD_CNT,
diff --git a/ip/Android.mk b/ip/Android.mk
index f3a41b1b..6b977808 100644
--- a/ip/Android.mk
+++ b/ip/Android.mk
@@ -5,7 +5,7 @@ LOCAL_SRC_FILES := ip.c ipaddress.c ipaddrlabel.c iproute.c iprule.c \
rtm_map.c iptunnel.c ip6tunnel.c tunnel.c ipneigh.c ipntable.c \
iplink.c ipmaddr.c ipmonitor.c ipmroute.c ipprefix.c ipxfrm.c \
xfrm_state.c xfrm_policy.c xfrm_monitor.c iplink_vlan.c \
- link_veth.c link_gre.c iplink_can.c
+ link_veth.c link_gre.c iplink_can.c iptuntap.c
LOCAL_MODULE := ip
diff --git a/ip/Makefile b/ip/Makefile
index 51914e85..2f223ca6 100644
--- a/ip/Makefile
+++ b/ip/Makefile
@@ -1,8 +1,9 @@
IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o \
rtm_map.o iptunnel.o ip6tunnel.o tunnel.o ipneigh.o ipntable.o iplink.o \
- ipmaddr.o ipmonitor.o ipmroute.o ipprefix.o \
+ ipmaddr.o ipmonitor.o ipmroute.o ipprefix.o iptuntap.o \
ipxfrm.o xfrm_state.o xfrm_policy.o xfrm_monitor.o \
- iplink_vlan.o link_veth.o link_gre.o iplink_can.o
+ iplink_vlan.o link_veth.o link_gre.o iplink_can.o \
+ iplink_macvlan.o
RTMONOBJ=rtmon.o
diff --git a/ip/ip.c b/ip/ip.c
index 0b416bfb..9d6f1699 100644
--- a/ip/ip.c
+++ b/ip/ip.c
@@ -42,7 +42,7 @@ static void usage(void)
"Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }\n"
" ip [ -force ] -batch filename\n"
"where OBJECT := { link | addr | addrlabel | route | rule | neigh | ntable |\n"
-" tunnel | maddr | mroute | monitor | xfrm }\n"
+" tunnel | tuntap | maddr | mroute | mrule | monitor | xfrm }\n"
" OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n"
" -f[amily] { inet | inet6 | ipx | dnet | link } |\n"
" -o[neline] | -t[imestamp] | -b[atch] [filename] |\n"
@@ -71,9 +71,12 @@ static const struct cmd {
{ "link", do_iplink },
{ "tunnel", do_iptunnel },
{ "tunl", do_iptunnel },
+ { "tuntap", do_iptuntap },
+ { "tap", do_iptuntap },
{ "monitor", do_ipmonitor },
{ "xfrm", do_xfrm },
{ "mroute", do_multiroute },
+ { "mrule", do_multirule },
{ "help", do_help },
{ 0, 0 }
};
@@ -97,7 +100,6 @@ static int batch(const char *name)
char *line = NULL;
size_t len = 0;
int ret = 0;
- int lineno = 0;
if (name && strcmp(name, "-") != 0) {
if (freopen(name, "r", stdin) == NULL) {
@@ -112,6 +114,7 @@ static int batch(const char *name)
return -1;
}
+ cmdlineno = 0;
while (getcmdline(&line, &len, stdin) != -1) {
char *largv[100];
int largc;
@@ -121,7 +124,7 @@ static int batch(const char *name)
continue; /* blank line */
if (do_cmd(largv[0], largc, largv)) {
- fprintf(stderr, "Command failed %s:%d\n", name, lineno);
+ fprintf(stderr, "Command failed %s:%d\n", name, cmdlineno);
ret = 1;
if (!force)
break;
diff --git a/ip/ip_common.h b/ip/ip_common.h
index 273065f5..a1141869 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -32,10 +32,12 @@ extern int do_ipneigh(int argc, char **argv);
extern int do_ipntable(int argc, char **argv);
extern int do_iptunnel(int argc, char **argv);
extern int do_ip6tunnel(int argc, char **argv);
+extern int do_iptuntap(int argc, char **argv);
extern int do_iplink(int argc, char **argv);
extern int do_ipmonitor(int argc, char **argv);
extern int do_multiaddr(int argc, char **argv);
extern int do_multiroute(int argc, char **argv);
+extern int do_multirule(int argc, char **argv);
extern int do_xfrm(int argc, char **argv);
static inline int rtm_get_table(struct rtmsg *r, struct rtattr **tb)
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index c638ca74..3a411b19 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -62,7 +62,7 @@ static void usage(void)
iplink_usage();
}
fprintf(stderr, "Usage: ip addr {add|change|replace} IFADDR dev STRING [ LIFETIME ]\n");
- fprintf(stderr, " [ CONFFLAG-LIST]\n");
+ fprintf(stderr, " [ CONFFLAG-LIST ]\n");
fprintf(stderr, " ip addr del IFADDR dev STRING\n");
fprintf(stderr, " ip addr {show|flush} [ dev STRING ] [ scope SCOPE-ID ]\n");
fprintf(stderr, " [ to PREFIX ] [ FLAG-LIST ] [ label PATTERN ]\n");
@@ -72,7 +72,8 @@ static void usage(void)
fprintf(stderr, "SCOPE-ID := [ host | link | global | NUMBER ]\n");
fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] FLAG\n");
fprintf(stderr, "FLAG := [ permanent | dynamic | secondary | primary |\n");
- fprintf(stderr, " tentative | deprecated | CONFFLAG-LIST ]\n");
+ fprintf(stderr, " tentative | deprecated | dadfailed | temporary |\n");
+ fprintf(stderr, " CONFFLAG-LIST ]\n");
fprintf(stderr, "CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG\n");
fprintf(stderr, "CONFFLAG := [ home | nodad ]\n");
fprintf(stderr, "LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]\n");
@@ -186,6 +187,36 @@ static void print_linktype(FILE *fp, struct rtattr *tb)
}
}
+static void print_vfinfo(FILE *fp, struct rtattr *vfinfo)
+{
+ struct ifla_vf_mac *vf_mac;
+ struct ifla_vf_vlan *vf_vlan;
+ struct ifla_vf_tx_rate *vf_tx_rate;
+ struct rtattr *vf[IFLA_VF_MAX+1];
+ SPRINT_BUF(b1);
+
+ if (vfinfo->rta_type != IFLA_VF_INFO) {
+ fprintf(stderr, "BUG: rta type is %d\n", vfinfo->rta_type);
+ return;
+ }
+
+ parse_rtattr_nested(vf, IFLA_VF_MAX, vfinfo);
+
+ vf_mac = RTA_DATA(vf[IFLA_VF_MAC]);
+ vf_vlan = RTA_DATA(vf[IFLA_VF_VLAN]);
+ vf_tx_rate = RTA_DATA(vf[IFLA_VF_TX_RATE]);
+
+ fprintf(fp, "\n vf %d MAC %s", vf_mac->vf,
+ ll_addr_n2a((unsigned char *)&vf_mac->mac,
+ ETH_ALEN, 0, b1, sizeof(b1)));
+ if (vf_vlan->vlan)
+ fprintf(fp, ", vlan %d", vf_vlan->vlan);
+ if (vf_vlan->qos)
+ fprintf(fp, ", qos %d", vf_vlan->qos);
+ if (vf_tx_rate->rate)
+ fprintf(fp, ", tx rate %d (Mbps)", vf_tx_rate->rate);
+}
+
int print_linkinfo(const struct sockaddr_nl *who,
struct nlmsghdr *n, void *arg)
{
@@ -283,7 +314,60 @@ int print_linkinfo(const struct sockaddr_nl *who,
fprintf(fp,"\n alias %s",
(const char *) RTA_DATA(tb[IFLA_IFALIAS]));
- if (do_link && tb[IFLA_STATS] && show_stats) {
+ if (do_link && tb[IFLA_STATS64] && show_stats) {
+ struct rtnl_link_stats64 slocal;
+ struct rtnl_link_stats64 *s = RTA_DATA(tb[IFLA_STATS64]);
+ if (((unsigned long)s) & (sizeof(unsigned long)-1)) {
+ memcpy(&slocal, s, sizeof(slocal));
+ s = &slocal;
+ }
+ fprintf(fp, "%s", _SL_);
+ fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s",
+ s->rx_compressed ? "compressed" : "", _SL_);
+ fprintf(fp, " %-10llu %-8llu %-7llu %-7llu %-7llu %-7llu",
+ (unsigned long long)s->rx_bytes,
+ (unsigned long long)s->rx_packets,
+ (unsigned long long)s->rx_errors,
+ (unsigned long long)s->rx_dropped,
+ (unsigned long long)s->rx_over_errors,
+ (unsigned long long)s->multicast);
+ if (s->rx_compressed)
+ fprintf(fp, " %-7llu",
+ (unsigned long long)s->rx_compressed);
+ if (show_stats > 1) {
+ fprintf(fp, "%s", _SL_);
+ fprintf(fp, " RX errors: length crc frame fifo missed%s", _SL_);
+ fprintf(fp, " %-7llu %-7llu %-7llu %-7llu %-7llu",
+ (unsigned long long)s->rx_length_errors,
+ (unsigned long long)s->rx_crc_errors,
+ (unsigned long long)s->rx_frame_errors,
+ (unsigned long long)s->rx_fifo_errors,
+ (unsigned long long)s->rx_missed_errors);
+ }
+ fprintf(fp, "%s", _SL_);
+ fprintf(fp, " TX: bytes packets errors dropped carrier collsns %s%s",
+ s->tx_compressed ? "compressed" : "", _SL_);
+ fprintf(fp, " %-10llu %-8llu %-7llu %-7llu %-7llu %-7llu",
+ (unsigned long long)s->tx_bytes,
+ (unsigned long long)s->tx_packets,
+ (unsigned long long)s->tx_errors,
+ (unsigned long long)s->tx_dropped,
+ (unsigned long long)s->tx_carrier_errors,
+ (unsigned long long)s->collisions);
+ if (s->tx_compressed)
+ fprintf(fp, " %-7llu",
+ (unsigned long long)s->tx_compressed);
+ if (show_stats > 1) {
+ fprintf(fp, "%s", _SL_);
+ fprintf(fp, " TX errors: aborted fifo window heartbeat%s", _SL_);
+ fprintf(fp, " %-7llu %-7llu %-7llu %-7llu",
+ (unsigned long long)s->tx_aborted_errors,
+ (unsigned long long)s->tx_fifo_errors,
+ (unsigned long long)s->tx_window_errors,
+ (unsigned long long)s->tx_heartbeat_errors);
+ }
+ }
+ if (do_link && !tb[IFLA_STATS64] && tb[IFLA_STATS] && show_stats) {
struct rtnl_link_stats slocal;
struct rtnl_link_stats *s = RTA_DATA(tb[IFLA_STATS]);
if (((unsigned long)s) & (sizeof(unsigned long)-1)) {
@@ -330,6 +414,13 @@ int print_linkinfo(const struct sockaddr_nl *who,
);
}
}
+ if (do_link && tb[IFLA_VFINFO_LIST] && tb[IFLA_NUM_VF]) {
+ struct rtattr *i, *vflist = tb[IFLA_VFINFO_LIST];
+ int rem = RTA_PAYLOAD(vflist);
+ for (i = RTA_DATA(vflist); RTA_OK(i, rem); i = RTA_NEXT(i, rem))
+ print_vfinfo(fp, i);
+ }
+
fprintf(fp, "\n");
fflush(fp);
return 0;
@@ -483,7 +574,10 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
fprintf(fp, "scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1, sizeof(b1)));
if (ifa->ifa_flags&IFA_F_SECONDARY) {
ifa->ifa_flags &= ~IFA_F_SECONDARY;
- fprintf(fp, "secondary ");
+ if (ifa->ifa_family == AF_INET6)
+ fprintf(fp, "temporary ");
+ else
+ fprintf(fp, "secondary ");
}
if (ifa->ifa_flags&IFA_F_TENTATIVE) {
ifa->ifa_flags &= ~IFA_F_TENTATIVE;
@@ -660,7 +754,8 @@ static int ipaddr_list_or_flush(int argc, char **argv, int flush)
} else if (strcmp(*argv, "permanent") == 0) {
filter.flags |= IFA_F_PERMANENT;
filter.flagmask |= IFA_F_PERMANENT;
- } else if (strcmp(*argv, "secondary") == 0) {
+ } else if (strcmp(*argv, "secondary") == 0 ||
+ strcmp(*argv, "temporary") == 0) {
filter.flags |= IFA_F_SECONDARY;
filter.flagmask |= IFA_F_SECONDARY;
} else if (strcmp(*argv, "primary") == 0) {
@@ -678,6 +773,9 @@ static int ipaddr_list_or_flush(int argc, char **argv, int flush)
} else if (strcmp(*argv, "nodad") == 0) {
filter.flags |= IFA_F_NODAD;
filter.flagmask |= IFA_F_NODAD;
+ } else if (strcmp(*argv, "dadfailed") == 0) {
+ filter.flags |= IFA_F_DADFAILED;
+ filter.flagmask |= IFA_F_DADFAILED;
} else if (strcmp(*argv, "label") == 0) {
NEXT_ARG();
filter.label = *argv;
@@ -1006,7 +1104,7 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
}
if (l && matches(d, l) != 0) {
fprintf(stderr, "\"dev\" (%s) must match \"label\" (%s).\n", d, l);
- exit(1);
+ return -1;
}
if (peer_len == 0 && local_len) {
@@ -1071,7 +1169,7 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
}
if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
- exit(2);
+ return -2;
return 0;
}
diff --git a/ip/ipaddrlabel.c b/ip/ipaddrlabel.c
index cf438d63..95e813df 100644
--- a/ip/ipaddrlabel.c
+++ b/ip/ipaddrlabel.c
@@ -252,6 +252,8 @@ static int ipaddrlabel_flush(int argc, char **argv)
int do_ipaddrlabel(int argc, char **argv)
{
+ ll_init_map(&rth);
+
if (argc < 1) {
return ipaddrlabel_list(0, NULL);
} else if (matches(argv[0], "list") == 0 ||
diff --git a/ip/iplink.c b/ip/iplink.c
index 32cce240..cb2c4f5e 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -68,6 +68,9 @@ void iplink_usage(void)
fprintf(stderr, " [ mtu MTU ]\n");
fprintf(stderr, " [ netns PID ]\n");
fprintf(stderr, " [ alias NAME ]\n");
+ fprintf(stderr, " [ vf NUM [ mac LLADDR ]\n");
+ fprintf(stderr, " [ vlan VLANID [ qos VLAN-QOS ] ]\n");
+ fprintf(stderr, " [ rate TXRATE ] ] \n");
fprintf(stderr, " ip link show [ DEVICE ]\n");
if (iplink_have_newlink()) {
@@ -173,6 +176,73 @@ struct iplink_req {
char buf[1024];
};
+int iplink_parse_vf(int vf, int *argcp, char ***argvp,
+ struct iplink_req *req)
+{
+ int len, argc = *argcp;
+ char **argv = *argvp;
+ struct rtattr *vfinfo;
+
+ vfinfo = addattr_nest(&req->n, sizeof(*req), IFLA_VF_INFO);
+
+ while (NEXT_ARG_OK()) {
+ NEXT_ARG();
+ if (matches(*argv, "mac") == 0) {
+ struct ifla_vf_mac ivm;
+ NEXT_ARG();
+ ivm.vf = vf;
+ len = ll_addr_a2n((char *)ivm.mac, 32, *argv);
+ if (len < 0)
+ return -1;
+ addattr_l(&req->n, sizeof(*req), IFLA_VF_MAC, &ivm, sizeof(ivm));
+ } else if (matches(*argv, "vlan") == 0) {
+ struct ifla_vf_vlan ivv;
+ NEXT_ARG();
+ if (get_unsigned(&ivv.vlan, *argv, 0)) {
+ invarg("Invalid \"vlan\" value\n", *argv);
+ }
+ ivv.vf = vf;
+ ivv.qos = 0;
+ if (NEXT_ARG_OK()) {
+ NEXT_ARG();
+ if (matches(*argv, "qos") == 0) {
+ NEXT_ARG();
+ if (get_unsigned(&ivv.qos, *argv, 0)) {
+ invarg("Invalid \"qos\" value\n", *argv);
+ }
+ } else {
+ /* rewind arg */
+ PREV_ARG();
+ }
+ }
+ addattr_l(&req->n, sizeof(*req), IFLA_VF_VLAN, &ivv, sizeof(ivv));
+ } else if (matches(*argv, "rate") == 0) {
+ struct ifla_vf_tx_rate ivt;
+ NEXT_ARG();
+ if (get_unsigned(&ivt.rate, *argv, 0)) {
+ invarg("Invalid \"rate\" value\n", *argv);
+ }
+ ivt.vf = vf;
+ addattr_l(&req->n, sizeof(*req), IFLA_VF_TX_RATE, &ivt, sizeof(ivt));
+
+ } else {
+ /* rewind arg */
+ PREV_ARG();
+ break;
+ }
+ }
+
+ if (argc == *argcp)
+ incomplete_command();
+
+ addattr_nest_end(&req->n, vfinfo);
+
+ *argcp = argc;
+ *argvp = argv;
+ return 0;
+}
+
+
int iplink_parse(int argc, char **argv, struct iplink_req *req,
char **name, char **type, char **link, char **dev)
{
@@ -181,6 +251,7 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
int qlen = -1;
int mtu = -1;
int netns = -1;
+ int vf = -1;
ret = argc;
@@ -278,6 +349,18 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
req->i.ifi_flags |= IFF_NOARP;
} else
return on_off("noarp");
+ } else if (strcmp(*argv, "vf") == 0) {
+ struct rtattr *vflist;
+ NEXT_ARG();
+ if (get_integer(&vf, *argv, 0)) {
+ invarg("Invalid \"vf\" value\n", *argv);
+ }
+ vflist = addattr_nest(&req->n, sizeof(*req),
+ IFLA_VFINFO_LIST);
+ len = iplink_parse_vf(vf, &argc, &argv, req);
+ if (len < 0)
+ return -1;
+ addattr_nest_end(&req->n, vflist);
#ifdef IFF_DYNAMIC
} else if (matches(*argv, "dynamic") == 0) {
NEXT_ARG();
diff --git a/ip/iplink_can.c b/ip/iplink_can.c
index 50221e1c..c8af4bc2 100644
--- a/ip/iplink_can.c
+++ b/ip/iplink_can.c
@@ -30,6 +30,8 @@ static void usage(void)
"\t[ loopback { on | off } ]\n"
"\t[ listen-only { on | off } ]\n"
"\t[ triple-sampling { on | off } ]\n"
+ "\t[ one-shot { on | off } ]\n"
+ "\t[ berr-reporting { on | off } ]\n"
"\n"
"\t[ restart-ms TIME-MS ]\n"
"\t[ restart ]\n"
@@ -84,6 +86,8 @@ static void print_ctrlmode(FILE *f, __u32 cm)
_PF(CAN_CTRLMODE_LOOPBACK, "LOOPBACK");
_PF(CAN_CTRLMODE_LISTENONLY, "LISTEN-ONLY");
_PF(CAN_CTRLMODE_3_SAMPLES, "TRIPLE-SAMPLING");
+ _PF(CAN_CTRLMODE_ONE_SHOT, "ONE-SHOT");
+ _PF(CAN_CTRLMODE_BERR_REPORTING, "BERR-REPORTING");
#undef _PF
if (cm)
fprintf(f, "%x", cm);
@@ -142,6 +146,14 @@ static int can_parse_opt(struct link_util *lu, int argc, char **argv,
NEXT_ARG();
set_ctrlmode("triple-sampling", *argv, &cm,
CAN_CTRLMODE_3_SAMPLES);
+ } else if (matches(*argv, "one-shot") == 0) {
+ NEXT_ARG();
+ set_ctrlmode("one-shot", *argv, &cm,
+ CAN_CTRLMODE_ONE_SHOT);
+ } else if (matches(*argv, "berr-reporting") == 0) {
+ NEXT_ARG();
+ set_ctrlmode("berr-reporting", *argv, &cm,
+ CAN_CTRLMODE_BERR_REPORTING);
} else if (matches(*argv, "restart") == 0) {
__u32 val = 1;
@@ -200,6 +212,13 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
can_state_names[*state] : "UNKNOWN");
}
+ if (tb[IFLA_CAN_BERR_COUNTER]) {
+ struct can_berr_counter *bc =
+ RTA_DATA(tb[IFLA_CAN_BERR_COUNTER]);
+
+ fprintf(f, "(berr-counter tx %d rx %d) ", bc->txerr, bc->rxerr);
+ }
+
if (tb[IFLA_CAN_RESTART_MS]) {
__u32 *restart_ms = RTA_DATA(tb[IFLA_CAN_RESTART_MS]);
diff --git a/ip/iplink_macvlan.c b/ip/iplink_macvlan.c
new file mode 100644
index 00000000..a3c78bd8
--- /dev/null
+++ b/ip/iplink_macvlan.c
@@ -0,0 +1,93 @@
+/*
+ * iplink_vlan.c VLAN device support
+ *
+ * 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: Patrick McHardy <kaber@trash.net>
+ * Arnd Bergmann <arnd@arndb.de>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <linux/if_link.h>
+
+#include "rt_names.h"
+#include "utils.h"
+#include "ip_common.h"
+
+static void explain(void)
+{
+ fprintf(stderr,
+ "Usage: ... macvlan mode { private | vepa | bridge }\n"
+ );
+}
+
+static int mode_arg(void)
+{
+ fprintf(stderr, "Error: argument of \"mode\" must be \"private\", "
+ "\"vepa\" or \"bridge\"\n");
+ return -1;
+}
+
+static int macvlan_parse_opt(struct link_util *lu, int argc, char **argv,
+ struct nlmsghdr *n)
+{
+ while (argc > 0) {
+ if (matches(*argv, "mode") == 0) {
+ __u32 mode = 0;
+ NEXT_ARG();
+
+ if (strcmp(*argv, "private") == 0)
+ mode = MACVLAN_MODE_PRIVATE;
+ else if (strcmp(*argv, "vepa") == 0)
+ mode = MACVLAN_MODE_VEPA;
+ else if (strcmp(*argv, "bridge") == 0)
+ mode = MACVLAN_MODE_BRIDGE;
+ else
+ return mode_arg();
+
+ addattr32(n, 1024, IFLA_MACVLAN_MODE, mode);
+ } else if (matches(*argv, "help") == 0) {
+ explain();
+ return -1;
+ } else {
+ fprintf(stderr, "macvlan: what is \"%s\"?\n", *argv);
+ explain();
+ return -1;
+ }
+ argc--, argv++;
+ }
+
+ return 0;
+}
+
+static void macvlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
+{
+ __u32 mode;
+
+ if (!tb)
+ return;
+
+ if (!tb[IFLA_MACVLAN_MODE] ||
+ RTA_PAYLOAD(tb[IFLA_MACVLAN_MODE]) < sizeof(__u32))
+ return;
+
+ mode = *(__u32 *)RTA_DATA(tb[IFLA_VLAN_ID]);
+ fprintf(f, " mode %s ",
+ mode == MACVLAN_MODE_PRIVATE ? "private"
+ : mode == MACVLAN_MODE_VEPA ? "vepa"
+ : mode == MACVLAN_MODE_BRIDGE ? "bridge"
+ : "unknown");
+}
+
+struct link_util macvlan_link_util = {
+ .id = "macvlan",
+ .maxattr = IFLA_MACVLAN_MAX,
+ .parse_opt = macvlan_parse_opt,
+ .print_opt = macvlan_print_opt,
+};
diff --git a/ip/iplink_vlan.c b/ip/iplink_vlan.c
index 97244826..223feb31 100644
--- a/ip/iplink_vlan.c
+++ b/ip/iplink_vlan.c
@@ -27,6 +27,7 @@ static void explain(void)
"VLANID := 0-4095\n"
"FLAG-LIST := [ FLAG-LIST ] FLAG\n"
"FLAG := [ reorder_hdr { on | off } ] [ gvrp { on | off } ]\n"
+ " [ loose_binding { on | off } ]\n"
"QOS-MAP := [ QOS-MAP ] QOS-MAPPING\n"
"QOS-MAPPING := FROM:TO\n"
);
@@ -102,6 +103,15 @@ static int vlan_parse_opt(struct link_util *lu, int argc, char **argv,
flags.flags &= ~VLAN_FLAG_GVRP;
else
return on_off("gvrp");
+ } else if (matches(*argv, "loose_binding") == 0) {
+ NEXT_ARG();
+ flags.mask |= VLAN_FLAG_LOOSE_BINDING;
+ if (strcmp(*argv, "on") == 0)
+ flags.flags |= VLAN_FLAG_LOOSE_BINDING;
+ else if (strcmp(*argv, "off") == 0)
+ flags.flags &= ~VLAN_FLAG_LOOSE_BINDING;
+ else
+ return on_off("loose_binding");
} else if (matches(*argv, "ingress-qos-map") == 0) {
NEXT_ARG();
if (vlan_parse_qos_map(&argc, &argv, n,
@@ -156,6 +166,7 @@ static void vlan_print_flags(FILE *fp, __u32 flags)
}
_PF(REORDER_HDR);
_PF(GVRP);
+ _PF(LOOSE_BINDING);
#undef _PF
if (flags)
fprintf(fp, "%x", flags);
diff --git a/ip/iproute.c b/ip/iproute.c
index b60926da..711576ea 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -46,6 +46,7 @@ static const char *mx_names[RTAX_MAX+1] = {
[RTAX_INITCWND] = "initcwnd",
[RTAX_FEATURES] = "features",
[RTAX_RTO_MIN] = "rto_min",
+ [RTAX_INITRWND] = "initrwnd",
};
static void usage(void) __attribute__((noreturn));
@@ -68,12 +69,11 @@ static void usage(void)
fprintf(stderr, " [ rtt TIME ] [ rttvar TIME ] [reordering NUMBER ]\n");
fprintf(stderr, " [ window NUMBER] [ cwnd NUMBER ] [ initcwnd NUMBER ]\n");
fprintf(stderr, " [ ssthresh NUMBER ] [ realms REALM ] [ src ADDRESS ]\n");
- fprintf(stderr, " [ rto_min TIME ] [ hoplimit NUMBER ] \n");
+ fprintf(stderr, " [ rto_min TIME ] [ hoplimit NUMBER ] [ initrwnd NUMBER ]\n");
fprintf(stderr, "TYPE := [ unicast | local | broadcast | multicast | throw |\n");
fprintf(stderr, " unreachable | prohibit | blackhole | nat ]\n");
fprintf(stderr, "TABLE_ID := [ local | main | default | all | NUMBER ]\n");
fprintf(stderr, "SCOPE := [ host | link | global | NUMBER ]\n");
- fprintf(stderr, "FLAGS := [ equalize ]\n");
fprintf(stderr, "MP_ALGO := { rr | drr | random | wrandom }\n");
fprintf(stderr, "NHFLAGS := [ onlink | pervasive ]\n");
fprintf(stderr, "RTPROTO := [ kernel | boot | static | NUMBER ]\n");
@@ -160,14 +160,11 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
if (r->rtm_family == AF_INET6 && table != RT_TABLE_MAIN)
ip6_multiple_tables = 1;
+ if (filter.cloned == !(r->rtm_flags&RTM_F_CLONED))
+ return 0;
+
if (r->rtm_family == AF_INET6 && !ip6_multiple_tables) {
- if (filter.cloned) {
- if (!(r->rtm_flags&RTM_F_CLONED))
- return 0;
- }
if (filter.tb) {
- if (!filter.cloned && r->rtm_flags&RTM_F_CLONED)
- return 0;
if (filter.tb == RT_TABLE_LOCAL) {
if (r->rtm_type != RTN_LOCAL)
return 0;
@@ -179,10 +176,6 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
}
}
} else {
- if (filter.cloned) {
- if (!(r->rtm_flags&RTM_F_CLONED))
- return 0;
- }
if (filter.tb > 0 && filter.tb != table)
return 0;
}
@@ -382,8 +375,6 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
fprintf(fp, "onlink ");
if (r->rtm_flags & RTNH_F_PERVASIVE)
fprintf(fp, "pervasive ");
- if (r->rtm_flags & RTM_F_EQUALIZE)
- fprintf(fp, "equalize ");
if (r->rtm_flags & RTM_F_NOTIFY)
fprintf(fp, "notify ");
@@ -423,9 +414,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
PRTFL(FAST, "fastroute");
PRTFL(NOTIFY, "notify");
PRTFL(TPROXY, "proxy");
-#ifdef RTCF_EQUALIZE
- PRTFL(EQUALIZE, "equalize");
-#endif
+
if (flags)
fprintf(fp, "%s%x> ", first ? "<" : "", flags);
if (tb[RTA_CACHEINFO]) {
@@ -493,7 +482,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
if (mxrta[i] == NULL)
continue;
if (!hz)
- hz = get_hz();
+ hz = get_user_hz();
if (i < sizeof(mx_names)/sizeof(char*) && mx_names[i])
fprintf(fp, " %s", mx_names[i]);
@@ -505,7 +494,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
val = *(unsigned*)RTA_DATA(mxrta[i]);
switch (i) {
case RTAX_HOPLIMIT:
- if ((long)val == -1)
+ if ((int)val == -1)
val = 0;
/* fall through */
default:
@@ -849,6 +838,16 @@ int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
if (get_unsigned(&win, *argv, 0))
invarg("\"initcwnd\" value is invalid\n", *argv);
rta_addattr32(mxrta, sizeof(mxbuf), RTAX_INITCWND, win);
+ } else if (matches(*argv, "initrwnd") == 0) {
+ unsigned win;
+ NEXT_ARG();
+ if (strcmp(*argv, "lock") == 0) {
+ mxlock |= (1<<RTAX_INITRWND);
+ NEXT_ARG();
+ }
+ if (get_unsigned(&win, *argv, 0))
+ invarg("\"initrwnd\" value is invalid\n", *argv);
+ rta_addattr32(mxrta, sizeof(mxbuf), RTAX_INITRWND, win);
} else if (matches(*argv, "rttvar") == 0) {
unsigned win;
NEXT_ARG();
@@ -878,9 +877,6 @@ int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
addattr32(&req.n, sizeof(req), RTA_FLOW, realm);
} else if (strcmp(*argv, "onlink") == 0) {
req.r.rtm_flags |= RTNH_F_ONLINK;
- } else if (matches(*argv, "equalize") == 0 ||
- strcmp(*argv, "eql") == 0) {
- req.r.rtm_flags |= RTM_F_EQUALIZE;
} else if (strcmp(*argv, "nexthop") == 0) {
nhs_ok = 1;
break;
diff --git a/ip/iprule.c b/ip/iprule.c
index 20be990b..9318d8ca 100644
--- a/ip/iprule.c
+++ b/ip/iprule.c
@@ -34,7 +34,7 @@ static void usage(void)
{
fprintf(stderr, "Usage: ip rule [ list | add | del | flush ] SELECTOR ACTION\n");
fprintf(stderr, "SELECTOR := [ not ] [ from PREFIX ] [ to PREFIX ] [ tos TOS ] [ fwmark FWMARK[/MASK] ]\n");
- fprintf(stderr, " [ dev STRING ] [ pref NUMBER ]\n");
+ fprintf(stderr, " [ iif STRING ] [ oif STRING ] [ pref NUMBER ]\n");
fprintf(stderr, "ACTION := [ table TABLE_ID ]\n");
fprintf(stderr, " [ prohibit | reject | unreachable ]\n");
fprintf(stderr, " [ realms [SRCREALM/]DSTREALM ]\n");
@@ -142,7 +142,13 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
if (tb[FRA_IFNAME]) {
fprintf(fp, "iif %s ", (char*)RTA_DATA(tb[FRA_IFNAME]));
- if (r->rtm_flags & FIB_RULE_DEV_DETACHED)
+ if (r->rtm_flags & FIB_RULE_IIF_DETACHED)
+ fprintf(fp, "[detached] ");
+ }
+
+ if (tb[FRA_OIFNAME]) {
+ fprintf(fp, "oif %s ", (char*)RTA_DATA(tb[FRA_OIFNAME]));
+ if (r->rtm_flags & FIB_RULE_OIF_DETACHED)
fprintf(fp, "[detached] ");
}
@@ -264,7 +270,8 @@ static int iprule_modify(int cmd, int argc, char **argv)
if (get_u32(&pref, *argv, 0))
invarg("preference value is invalid\n", *argv);
addattr32(&req.n, sizeof(req), FRA_PRIORITY, pref);
- } else if (strcmp(*argv, "tos") == 0) {
+ } else if (strcmp(*argv, "tos") == 0 ||
+ matches(*argv, "dsfield") == 0) {
__u32 tos;
NEXT_ARG();
if (rtnl_dsfield_a2n(&tos, *argv))
@@ -307,6 +314,9 @@ static int iprule_modify(int cmd, int argc, char **argv)
strcmp(*argv, "iif") == 0) {
NEXT_ARG();
addattr_l(&req.n, sizeof(req), FRA_IFNAME, *argv, strlen(*argv)+1);
+ } else if (strcmp(*argv, "oif") == 0) {
+ NEXT_ARG();
+ addattr_l(&req.n, sizeof(req), FRA_OIFNAME, *argv, strlen(*argv)+1);
} else if (strcmp(*argv, "nat") == 0 ||
matches(*argv, "map-to") == 0) {
NEXT_ARG();
@@ -427,3 +437,24 @@ int do_iprule(int argc, char **argv)
exit(-1);
}
+int do_multirule(int argc, char **argv)
+{
+ switch (preferred_family) {
+ case AF_UNSPEC:
+ case AF_INET:
+ preferred_family = RTNL_FAMILY_IPMR;
+ break;
+ case AF_INET6:
+ preferred_family = RTNL_FAMILY_IP6MR;
+ break;
+ case RTNL_FAMILY_IPMR:
+ case RTNL_FAMILY_IP6MR:
+ break;
+ default:
+ fprintf(stderr, "Multicast rules are only supported for IPv4/IPv6, was: %i\n",
+ preferred_family);
+ exit(-1);
+ }
+
+ return do_iprule(argc, argv);
+}
diff --git a/ip/iptunnel.c b/ip/iptunnel.c
index dcd7ee6f..3525fbb2 100644
--- a/ip/iptunnel.c
+++ b/ip/iptunnel.c
@@ -32,10 +32,11 @@ static void usage(void) __attribute__((noreturn));
static void usage(void)
{
- fprintf(stderr, "Usage: ip tunnel { add | change | del | show | prl } [ NAME ]\n");
+ fprintf(stderr, "Usage: ip tunnel { add | change | del | show | prl | 6rd } [ NAME ]\n");
fprintf(stderr, " [ mode { ipip | gre | sit | isatap } ] [ remote ADDR ] [ local ADDR ]\n");
fprintf(stderr, " [ [i|o]seq ] [ [i|o]key KEY ] [ [i|o]csum ]\n");
fprintf(stderr, " [ prl-default ADDR ] [ prl-nodefault ADDR ] [ prl-delete ADDR ]\n");
+ fprintf(stderr, " [ 6rd-prefix ADDR ] [ 6rd-relay_prefix ADDR ] [ 6rd-reset ]\n");
fprintf(stderr, " [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]\n");
fprintf(stderr, "\n");
fprintf(stderr, "Where: NAME := STRING\n");
@@ -302,11 +303,13 @@ static int do_del(int argc, char **argv)
static void print_tunnel(struct ip_tunnel_parm *p)
{
+ struct ip_tunnel_6rd ip6rd;
char s1[1024];
char s2[1024];
char s3[64];
char s4[64];
+ memset(&ip6rd, 0, sizeof(ip6rd));
inet_ntop(AF_INET, &p->i_key, s3, sizeof(s3));
inet_ntop(AF_INET, &p->o_key, s4, sizeof(s4));
@@ -362,6 +365,17 @@ static void print_tunnel(struct ip_tunnel_parm *p)
if (!(p->iph.frag_off&htons(IP_DF)))
printf(" nopmtudisc");
+ if (p->iph.protocol == IPPROTO_IPV6 && !tnl_ioctl_get_6rd(p->name, &ip6rd) && ip6rd.prefixlen) {
+ printf(" 6rd-prefix %s/%u ",
+ inet_ntop(AF_INET6, &ip6rd.prefix, s1, sizeof(s1)),
+ ip6rd.prefixlen);
+ if (ip6rd.relay_prefix) {
+ printf("6rd-relay_prefix %s/%u ",
+ format_host(AF_INET, 4, &ip6rd.relay_prefix, s1, sizeof(s1)),
+ ip6rd.relay_prefixlen);
+ }
+ }
+
if ((p->i_flags&GRE_KEY) && (p->o_flags&GRE_KEY) && p->o_key == p->i_key)
printf(" key %s", s3);
else if ((p->i_flags|p->o_flags)&GRE_KEY) {
@@ -528,6 +542,52 @@ static int do_prl(int argc, char **argv)
return tnl_prl_ioctl(cmd, medium, &p);
}
+static int do_6rd(int argc, char **argv)
+{
+ struct ip_tunnel_6rd ip6rd;
+ int devname = 0;
+ int cmd = 0;
+ char medium[IFNAMSIZ];
+ inet_prefix prefix;
+
+ memset(&ip6rd, 0, sizeof(ip6rd));
+ memset(&medium, 0, sizeof(medium));
+
+ while (argc > 0) {
+ if (strcmp(*argv, "6rd-prefix") == 0) {
+ NEXT_ARG();
+ if (get_prefix(&prefix, *argv, AF_INET6))
+ invarg("invalid 6rd_prefix\n", *argv);
+ cmd = SIOCADD6RD;
+ memcpy(&ip6rd.prefix, prefix.data, 16);
+ ip6rd.prefixlen = prefix.bitlen;
+ } else if (strcmp(*argv, "6rd-relay_prefix") == 0) {
+ NEXT_ARG();
+ if (get_prefix(&prefix, *argv, AF_INET))
+ invarg("invalid 6rd-relay_prefix\n", *argv);
+ cmd = SIOCADD6RD;
+ memcpy(&ip6rd.relay_prefix, prefix.data, 4);
+ ip6rd.relay_prefixlen = prefix.bitlen;
+ } else if (strcmp(*argv, "6rd-reset") == 0) {
+ cmd = SIOCDEL6RD;
+ } else if (strcmp(*argv, "dev") == 0) {
+ NEXT_ARG();
+ strncpy(medium, *argv, IFNAMSIZ-1);
+ devname++;
+ } else {
+ fprintf(stderr,"%s: Invalid 6RD parameter.\n", *argv);
+ exit(-1);
+ }
+ argc--; argv++;
+ }
+ if (devname == 0) {
+ fprintf(stderr, "Must specify dev.\n");
+ exit(-1);
+ }
+
+ return tnl_6rd_ioctl(cmd, medium, &ip6rd);
+}
+
int do_iptunnel(int argc, char **argv)
{
switch (preferred_family) {
@@ -561,6 +621,8 @@ int do_iptunnel(int argc, char **argv)
return do_show(argc-1, argv+1);
if (matches(*argv, "prl") == 0)
return do_prl(argc-1, argv+1);
+ if (matches(*argv, "6rd") == 0)
+ return do_6rd(argc-1, argv+1);
if (matches(*argv, "help") == 0)
usage();
} else
diff --git a/ip/iptuntap.c b/ip/iptuntap.c
new file mode 100644
index 00000000..2a8aa7fc
--- /dev/null
+++ b/ip/iptuntap.c
@@ -0,0 +1,323 @@
+/*
+ * iptunnel.c "ip tuntap"
+ *
+ * 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: David Woodhouse <David.Woodhouse@intel.com>
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <sys/ioctl.h>
+#include <linux/if.h>
+#include <linux/if_tun.h>
+#include <pwd.h>
+#include <grp.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <errno.h>
+
+#include "rt_names.h"
+#include "utils.h"
+#include "ip_common.h"
+
+#define TUNDEV "/dev/net/tun"
+
+static void usage(void) __attribute__((noreturn));
+
+static void usage(void)
+{
+ fprintf(stderr, "Usage: ip tuntap { add | del } [ dev PHYS_DEV ] \n");
+ fprintf(stderr, " [ mode { tun | tap } ] [ user USER ] [ group GROUP ]\n");
+ fprintf(stderr, " [ one_queue ] [ pi ] [ vnet_hdr ]\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Where: USER := { STRING | NUMBER }\n");
+ fprintf(stderr, " GROUP := { STRING | NUMBER }\n");
+ exit(-1);
+}
+
+static int tap_add_ioctl(struct ifreq *ifr, uid_t uid, gid_t gid)
+{
+ int fd = open(TUNDEV, O_RDWR);
+ int ret = -1;
+
+#ifdef IFF_TUN_EXCL
+ ifr->ifr_flags |= IFF_TUN_EXCL;
+#endif
+
+ fd = open(TUNDEV, O_RDWR);
+ if (fd < 0) {
+ perror("open");
+ return -1;
+ }
+ if (ioctl(fd, TUNSETIFF, ifr)) {
+ perror("ioctl(TUNSETIFF)");
+ goto out;
+ }
+ if (uid != -1 && ioctl(fd, TUNSETOWNER, uid)) {
+ perror("ioctl(TUNSETOWNER)");
+ goto out;
+ }
+ if (gid != -1 && ioctl(fd, TUNSETGROUP, gid)) {
+ perror("ioctl(TUNSETGROUP)");
+ goto out;
+ }
+ if (ioctl(fd, TUNSETPERSIST, 1)) {
+ perror("ioctl(TUNSETPERSIST)");
+ goto out;
+ }
+ ret = 0;
+ out:
+ close(fd);
+ return ret;
+}
+
+static int tap_del_ioctl(struct ifreq *ifr)
+{
+ int fd = open(TUNDEV, O_RDWR);
+ int ret = -1;
+
+ if (fd < 0) {
+ perror("open");
+ return -1;
+ }
+ if (ioctl(fd, TUNSETIFF, ifr)) {
+ perror("ioctl(TUNSETIFF)");
+ goto out;
+ }
+ if (ioctl(fd, TUNSETPERSIST, 0)) {
+ perror("ioctl(TUNSETPERSIST)");
+ goto out;
+ }
+ ret = 0;
+ out:
+ close(fd);
+ return ret;
+
+}
+static int parse_args(int argc, char **argv, struct ifreq *ifr, uid_t *uid, gid_t *gid)
+{
+ int count = 0;
+
+ memset(ifr, 0, sizeof(*ifr));
+
+ ifr->ifr_flags |= IFF_NO_PI;
+
+ while (argc > 0) {
+ if (matches(*argv, "mode") == 0) {
+ NEXT_ARG();
+ if (matches(*argv, "tun") == 0) {
+ if (ifr->ifr_flags & IFF_TAP) {
+ fprintf(stderr,"You managed to ask for more than one tunnel mode.\n");
+ exit(-1);
+ }
+ ifr->ifr_flags |= IFF_TUN;
+ } else if (matches(*argv, "tap") == 0) {
+ if (ifr->ifr_flags & IFF_TUN) {
+ fprintf(stderr,"You managed to ask for more than one tunnel mode.\n");
+ exit(-1);
+ }
+ ifr->ifr_flags |= IFF_TAP;
+ } else {
+ fprintf(stderr,"Cannot guess tunnel mode.\n");
+ exit(-1);
+ }
+ } else if (uid && matches(*argv, "user") == 0) {
+ char *end;
+ unsigned long user;
+
+ NEXT_ARG();
+ if (**argv && ((user = strtol(*argv, &end, 10)), !*end))
+ *uid = user;
+ else {
+ struct passwd *pw = getpwnam(*argv);
+ if (!pw) {
+ fprintf(stderr, "invalid user \"%s\"\n", *argv);
+ exit(-1);
+ }
+ *uid = pw->pw_uid;
+ }
+ } else if (gid && matches(*argv, "group") == 0) {
+ char *end;
+ unsigned long group;
+
+ NEXT_ARG();
+
+ if (**argv && ((group = strtol(*argv, &end, 10)), !*end))
+ *gid = group;
+ else {
+ struct group *gr = getgrnam(*argv);
+ if (!gr) {
+ fprintf(stderr, "invalid group \"%s\"\n", *argv);
+ exit(-1);
+ }
+ *gid = gr->gr_gid;
+ }
+ } else if (matches(*argv, "pi") == 0) {
+ ifr->ifr_flags &= ~IFF_NO_PI;
+ } else if (matches(*argv, "one_queue") == 0) {
+ ifr->ifr_flags |= IFF_ONE_QUEUE;
+ } else if (matches(*argv, "vnet_hdr") == 0) {
+ ifr->ifr_flags |= IFF_VNET_HDR;
+ } else if (matches(*argv, "dev") == 0) {
+ NEXT_ARG();
+ strncpy(ifr->ifr_name, *argv, IFNAMSIZ-1);
+ } else {
+ if (matches(*argv, "name") == 0) {
+ NEXT_ARG();
+ } else if (matches(*argv, "help") == 0)
+ usage();
+ if (ifr->ifr_name[0])
+ duparg2("name", *argv);
+ strncpy(ifr->ifr_name, *argv, IFNAMSIZ);
+ }
+ count++;
+ argc--; argv++;
+ }
+
+ return 0;
+}
+
+
+static int do_add(int argc, char **argv)
+{
+ struct ifreq ifr;
+ uid_t uid = -1;
+ gid_t gid = -1;
+
+ if (parse_args(argc, argv, &ifr, &uid, &gid) < 0)
+ return -1;
+
+ if (!(ifr.ifr_flags & TUN_TYPE_MASK)) {
+ fprintf(stderr, "You failed to specify a tunnel mode\n");
+ return -1;
+ }
+ return tap_add_ioctl(&ifr, uid, gid);
+}
+
+static int do_del(int argc, char **argv)
+{
+ struct ifreq ifr;
+
+ if (parse_args(argc, argv, &ifr, NULL, NULL) < 0)
+ return -1;
+
+ return tap_del_ioctl(&ifr);
+}
+
+static int read_prop(char *dev, char *prop, long *value)
+{
+ char fname[IFNAMSIZ+25], buf[80], *endp;
+ ssize_t len;
+ int fd;
+ long result;
+
+ sprintf(fname, "/sys/class/net/%s/%s", dev, prop);
+ fd = open(fname, O_RDONLY);
+ if (fd < 0) {
+ if (strcmp(prop, "tun_flags"))
+ fprintf(stderr, "open %s: %s\n", fname,
+ strerror(errno));
+ return -1;
+ }
+ len = read(fd, buf, sizeof(buf)-1);
+ close(fd);
+ if (len < 0) {
+ fprintf(stderr, "read %s: %s", fname, strerror(errno));
+ return -1;
+ }
+
+ buf[len] = 0;
+ result = strtol(buf, &endp, 0);
+ if (*endp != '\n') {
+ fprintf(stderr, "Failed to parse %s\n", fname);
+ return -1;
+ }
+ *value = result;
+ return 0;
+}
+
+static void print_flags(long flags)
+{
+ if (flags & IFF_TUN)
+ printf(" tun");
+
+ if (flags & IFF_TAP)
+ printf(" tap");
+
+ if (!(flags & IFF_NO_PI))
+ printf(" pi");
+
+ if (flags & IFF_ONE_QUEUE)
+ printf(" one_queue");
+
+ if (flags & IFF_VNET_HDR)
+ printf(" vnet_hdr");
+
+ flags &= ~(IFF_TUN|IFF_TAP|IFF_NO_PI|IFF_ONE_QUEUE|IFF_VNET_HDR);
+ if (flags)
+ printf(" UNKNOWN_FLAGS:%lx", flags);
+}
+
+static int do_show(int argc, char **argv)
+{
+ DIR *dir;
+ struct dirent *d;
+ long flags, owner = -1, group = -1;
+
+ dir = opendir("/sys/class/net");
+ if (!dir) {
+ perror("opendir");
+ return -1;
+ }
+ while ((d = readdir(dir))) {
+ if (d->d_name[0] == '.' &&
+ (d->d_name[1] == 0 || d->d_name[1] == '.'))
+ continue;
+
+ if (read_prop(d->d_name, "tun_flags", &flags))
+ continue;
+
+ read_prop(d->d_name, "owner", &owner);
+ read_prop(d->d_name, "group", &group);
+
+ printf("%s:", d->d_name);
+ print_flags(flags);
+ if (owner != -1)
+ printf(" user %ld", owner);
+ if (group != -1)
+ printf(" group %ld", group);
+ printf("\n");
+ }
+ return 0;
+}
+
+int do_iptuntap(int argc, char **argv)
+{
+ if (argc > 0) {
+ if (matches(*argv, "add") == 0)
+ return do_add(argc-1, argv+1);
+ if (matches(*argv, "del") == 0)
+ return do_del(argc-1, argv+1);
+ if (matches(*argv, "show") == 0 ||
+ matches(*argv, "lst") == 0 ||
+ matches(*argv, "list") == 0)
+ return do_show(argc-1, argv+1);
+ if (matches(*argv, "help") == 0)
+ usage();
+ } else
+ return do_show(0, NULL);
+
+ fprintf(stderr, "Command \"%s\" is unknown, try \"ip tuntap help\".\n",
+ *argv);
+ exit(-1);
+}
diff --git a/ip/ipxfrm.c b/ip/ipxfrm.c
index 612f5015..32e56b15 100644
--- a/ip/ipxfrm.c
+++ b/ip/ipxfrm.c
@@ -632,9 +632,48 @@ static void xfrm_tmpl_print(struct xfrm_user_tmpl *tmpls, int len,
}
}
+int xfrm_parse_mark(struct xfrm_mark *mark, int *argcp, char ***argvp)
+{
+ int argc = *argcp;
+ char **argv = *argvp;
+
+ NEXT_ARG();
+ if (get_u32(&mark->v, *argv, 0)) {
+ invarg("Illegal \"mark\" value\n", *argv);
+ }
+ if (argc > 1)
+ NEXT_ARG();
+ else { /* last entry on parse line */
+ mark->m = 0xffffffff;
+ goto done;
+ }
+
+ if (strcmp(*argv, "mask") == 0) {
+ NEXT_ARG();
+ if (get_u32(&mark->m, *argv, 0)) {
+ invarg("Illegal \"mark\" mask\n", *argv);
+ }
+ } else {
+ mark->m = 0xffffffff;
+ PREV_ARG();
+ }
+
+done:
+ *argcp = argc;
+ *argvp = argv;
+
+ return 0;
+}
+
void xfrm_xfrma_print(struct rtattr *tb[], __u16 family,
FILE *fp, const char *prefix)
{
+ if (tb[XFRMA_MARK]) {
+ struct rtattr *rta = tb[XFRMA_MARK];
+ struct xfrm_mark *m = (struct xfrm_mark *) RTA_DATA(rta);
+ fprintf(fp, "\tmark %d/0x%x\n", m->v, m->m);
+ }
+
if (tb[XFRMA_ALG_AUTH]) {
struct rtattr *rta = tb[XFRMA_ALG_AUTH];
xfrm_algo_print((struct xfrm_algo *) RTA_DATA(rta),
@@ -743,6 +782,7 @@ void xfrm_xfrma_print(struct rtattr *tb[], __u16 family,
fprintf(fp, "%s", strxf_time(lastused));
fprintf(fp, "%s", _SL_);
}
+
}
static int xfrm_selector_iszero(struct xfrm_selector *s)
@@ -783,6 +823,8 @@ void xfrm_state_info_print(struct xfrm_usersa_info *xsinfo,
XFRM_FLAG_PRINT(fp, flags, XFRM_STATE_DECAP_DSCP, "decap-dscp");
XFRM_FLAG_PRINT(fp, flags, XFRM_STATE_NOPMTUDISC, "nopmtudisc");
XFRM_FLAG_PRINT(fp, flags, XFRM_STATE_WILDRECV, "wildrecv");
+ XFRM_FLAG_PRINT(fp, flags, XFRM_STATE_ICMP, "icmp");
+ XFRM_FLAG_PRINT(fp, flags, XFRM_STATE_AF_UNSPEC, "af-unspec");
if (flags)
fprintf(fp, "%x", flags);
}
diff --git a/ip/tunnel.c b/ip/tunnel.c
index d1296e68..6efbd2df 100644
--- a/ip/tunnel.c
+++ b/ip/tunnel.c
@@ -26,6 +26,7 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
+#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
@@ -168,7 +169,7 @@ int tnl_del_ioctl(const char *basedev, const char *name, void *p)
return err;
}
-int tnl_prl_ioctl(int cmd, const char *name, void *p)
+static int tnl_gen_ioctl(int cmd, const char *name, void *p, int skiperr)
{
struct ifreq ifr;
int fd;
@@ -178,8 +179,23 @@ int tnl_prl_ioctl(int cmd, const char *name, void *p)
ifr.ifr_ifru.ifru_data = p;
fd = socket(preferred_family, SOCK_DGRAM, 0);
err = ioctl(fd, cmd, &ifr);
- if (err)
+ if (err && errno != skiperr)
perror("ioctl");
close(fd);
return err;
}
+
+int tnl_prl_ioctl(int cmd, const char *name, void *p)
+{
+ return tnl_gen_ioctl(cmd, name, p, -1);
+}
+
+int tnl_6rd_ioctl(int cmd, const char *name, void *p)
+{
+ return tnl_gen_ioctl(cmd, name, p, -1);
+}
+
+int tnl_ioctl_get_6rd(const char *name, void *p)
+{
+ return tnl_gen_ioctl(SIOCGET6RD, name, p, EINVAL);
+}
diff --git a/ip/tunnel.h b/ip/tunnel.h
index 0661e277..ded226b4 100644
--- a/ip/tunnel.h
+++ b/ip/tunnel.h
@@ -32,5 +32,7 @@ int tnl_get_ioctl(const char *basedev, void *p);
int tnl_add_ioctl(int cmd, const char *basedev, const char *name, void *p);
int tnl_del_ioctl(const char *basedev, const char *name, void *p);
int tnl_prl_ioctl(int cmd, const char *name, void *p);
+int tnl_6rd_ioctl(int cmd, const char *name, void *p);
+int tnl_ioctl_get_6rd(const char *name, void *p);
#endif
diff --git a/ip/xfrm.h b/ip/xfrm.h
index 104fb208..d3ca5c53 100644
--- a/ip/xfrm.h
+++ b/ip/xfrm.h
@@ -121,6 +121,7 @@ int xfrm_xfrmproto_is_ipsec(__u8 proto);
int xfrm_xfrmproto_is_ro(__u8 proto);
int xfrm_xfrmproto_getbyname(char *name);
int xfrm_algotype_getbyname(char *name);
+int xfrm_parse_mark(struct xfrm_mark *mark, int *argcp, char ***argvp);
const char *strxf_xfrmproto(__u8 proto);
const char *strxf_algotype(int type);
const char *strxf_mask8(__u8 mask);
diff --git a/ip/xfrm_policy.c b/ip/xfrm_policy.c
index 0a8f0b36..dba1dbd1 100644
--- a/ip/xfrm_policy.c
+++ b/ip/xfrm_policy.c
@@ -33,7 +33,6 @@
#include <linux/xfrm.h>
#include <linux/in.h>
#include <linux/in6.h>
-
#include "utils.h"
#include "xfrm.h"
#include "ip_common.h"
@@ -57,8 +56,8 @@ static void usage(void) __attribute__((noreturn));
static void usage(void)
{
fprintf(stderr, "Usage: ip xfrm policy { add | update } dir DIR SELECTOR [ index INDEX ] [ ptype PTYPE ]\n");
- fprintf(stderr, " [ action ACTION ] [ priority PRIORITY ] [ flag FLAG-LIST ] [ LIMIT-LIST ] [ TMPL-LIST ]\n");
- fprintf(stderr, "Usage: ip xfrm policy { delete | get } dir DIR [ SELECTOR | index INDEX ] [ ptype PTYPE ]\n");
+ fprintf(stderr, " [ action ACTION ] [ priority PRIORITY ] [ flag FLAG-LIST ] [ LIMIT-LIST ] [ TMPL-LIST ] [mark MARK [mask MASK]]\n");
+ fprintf(stderr, "Usage: ip xfrm policy { delete | get } dir DIR [ SELECTOR | index INDEX ] [ ptype PTYPE ] [mark MARK [mask MASK]]\n");
fprintf(stderr, "Usage: ip xfrm policy { deleteall | list } [ dir DIR ] [ SELECTOR ]\n");
fprintf(stderr, " [ index INDEX ] [ action ACTION ] [ priority PRIORITY ] [ flag FLAG-LIST ]\n");
fprintf(stderr, "Usage: ip xfrm policy flush [ ptype PTYPE ]\n");
@@ -204,10 +203,10 @@ static int xfrm_tmpl_parse(struct xfrm_user_tmpl *tmpl,
break;
}
idp = *argv;
+ preferred_family = AF_UNSPEC;
xfrm_id_parse(&tmpl->saddr, &tmpl->id, &tmpl->family,
0, &argc, &argv);
- if (preferred_family == AF_UNSPEC)
- preferred_family = tmpl->family;
+ preferred_family = tmpl->family;
}
if (!NEXT_ARG_OK())
@@ -238,6 +237,7 @@ static int xfrm_policy_modify(int cmd, unsigned flags, int argc, char **argv)
struct xfrm_userpolicy_type upt;
char tmpls_buf[XFRM_TMPLS_BUF_SIZE];
int tmpls_len = 0;
+ struct xfrm_mark mark = {0, 0};
memset(&req, 0, sizeof(req));
memset(&upt, 0, sizeof(upt));
@@ -261,6 +261,8 @@ static int xfrm_policy_modify(int cmd, unsigned flags, int argc, char **argv)
NEXT_ARG();
xfrm_policy_dir_parse(&req.xpinfo.dir, &argc, &argv);
+ } else if (strcmp(*argv, "mark") == 0) {
+ xfrm_parse_mark(&mark, &argc, &argv);
} else if (strcmp(*argv, "index") == 0) {
NEXT_ARG();
if (get_u32(&req.xpinfo.index, *argv, 0))
@@ -337,6 +339,16 @@ static int xfrm_policy_modify(int cmd, unsigned flags, int argc, char **argv)
(void *)tmpls_buf, tmpls_len);
}
+ if (mark.m & mark.v) {
+ int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
+ (void *)&mark, sizeof(mark));
+ if (r < 0) {
+ fprintf(stderr, "%s: XFRMA_MARK failed\n",__func__);
+ exit(1);
+ }
+ }
+
+
if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
exit(1);
@@ -518,6 +530,7 @@ static int xfrm_policy_get_or_delete(int argc, char **argv, int delete,
char *indexp = NULL;
char *ptypep = NULL;
struct xfrm_userpolicy_type upt;
+ struct xfrm_mark mark = {0, 0};
memset(&req, 0, sizeof(req));
memset(&upt, 0, sizeof(upt));
@@ -535,6 +548,8 @@ static int xfrm_policy_get_or_delete(int argc, char **argv, int delete,
NEXT_ARG();
xfrm_policy_dir_parse(&req.xpid.dir, &argc, &argv);
+ } else if (strcmp(*argv, "mark") == 0) {
+ xfrm_parse_mark(&mark, &argc, &argv);
} else if (strcmp(*argv, "index") == 0) {
if (indexp)
duparg("index", *argv);
@@ -587,6 +602,15 @@ static int xfrm_policy_get_or_delete(int argc, char **argv, int delete,
if (req.xpid.sel.family == AF_UNSPEC)
req.xpid.sel.family = AF_INET;
+ if (mark.m & mark.v) {
+ int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
+ (void *)&mark, sizeof(mark));
+ if (r < 0) {
+ fprintf(stderr, "%s: XFRMA_MARK failed\n",__func__);
+ exit(1);
+ }
+ }
+
if (rtnl_talk(&rth, &req.n, 0, 0, res_nlbuf, NULL, NULL) < 0)
exit(2);
diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c
index 1780f41e..49f35ed4 100644
--- a/ip/xfrm_state.c
+++ b/ip/xfrm_state.c
@@ -33,7 +33,6 @@
#include <linux/xfrm.h>
#include <linux/in.h>
#include <linux/in6.h>
-
#include "utils.h"
#include "xfrm.h"
#include "ip_common.h"
@@ -71,7 +70,7 @@ static void usage(void)
fprintf(stderr, "Usage: ip xfrm state flush [ proto XFRM_PROTO ]\n");
fprintf(stderr, "Usage: ip xfrm state count \n");
- fprintf(stderr, "ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM_PROTO ] [ spi SPI ]\n");
+ fprintf(stderr, "ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM_PROTO ] [ spi SPI ] [mark MARK [mask MASK]]\n");
//fprintf(stderr, "XFRM_PROTO := [ esp | ah | comp ]\n");
fprintf(stderr, "XFRM_PROTO := [ ");
fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_ESP));
@@ -87,7 +86,7 @@ static void usage(void)
//fprintf(stderr, "REQID - number(default=0)\n");
fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] FLAG\n");
- fprintf(stderr, "FLAG := [ noecn | decap-dscp | nopmtudisc | wildrecv ]\n");
+ fprintf(stderr, "FLAG := [ noecn | decap-dscp | nopmtudisc | wildrecv | icmp | af-unspec ]\n");
fprintf(stderr, "ENCAP := ENCAP-TYPE SPORT DPORT OADDR\n");
fprintf(stderr, "ENCAP-TYPE := espinudp | espinudp-nonike\n");
@@ -214,6 +213,10 @@ static int xfrm_state_flag_parse(__u8 *flags, int *argcp, char ***argvp)
*flags |= XFRM_STATE_NOPMTUDISC;
else if (strcmp(*argv, "wildrecv") == 0)
*flags |= XFRM_STATE_WILDRECV;
+ else if (strcmp(*argv, "icmp") == 0)
+ *flags |= XFRM_STATE_ICMP;
+ else if (strcmp(*argv, "af-unspec") == 0)
+ *flags |= XFRM_STATE_AF_UNSPEC;
else {
PREV_ARG(); /* back track */
break;
@@ -246,6 +249,7 @@ static int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv)
char *aalgop = NULL;
char *calgop = NULL;
char *coap = NULL;
+ struct xfrm_mark mark = {0, 0};
memset(&req, 0, sizeof(req));
memset(&replay, 0, sizeof(replay));
@@ -264,6 +268,8 @@ static int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv)
if (strcmp(*argv, "mode") == 0) {
NEXT_ARG();
xfrm_mode_parse(&req.xsinfo.mode, &argc, &argv);
+ } else if (strcmp(*argv, "mark") == 0) {
+ xfrm_parse_mark(&mark, &argc, &argv);
} else if (strcmp(*argv, "reqid") == 0) {
NEXT_ARG();
xfrm_reqid_parse(&req.xsinfo.reqid, &argc, &argv);
@@ -440,6 +446,15 @@ parse_algo:
exit(1);
}
+ if (mark.m & mark.v) {
+ int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
+ (void *)&mark, sizeof(mark));
+ if (r < 0) {
+ fprintf(stderr, "XFRMA_MARK failed\n");
+ exit(1);
+ }
+ }
+
switch (req.xsinfo.mode) {
case XFRM_MODE_TRANSPORT:
case XFRM_MODE_TUNNEL:
@@ -519,6 +534,7 @@ static int xfrm_state_allocspi(int argc, char **argv)
char *idp = NULL;
char *minp = NULL;
char *maxp = NULL;
+ struct xfrm_mark mark = {0, 0};
char res_buf[NLMSG_BUF_SIZE];
struct nlmsghdr *res_n = (struct nlmsghdr *)res_buf;
@@ -542,6 +558,8 @@ static int xfrm_state_allocspi(int argc, char **argv)
if (strcmp(*argv, "mode") == 0) {
NEXT_ARG();
xfrm_mode_parse(&req.xspi.info.mode, &argc, &argv);
+ } else if (strcmp(*argv, "mark") == 0) {
+ xfrm_parse_mark(&mark, &argc, &argv);
} else if (strcmp(*argv, "reqid") == 0) {
NEXT_ARG();
xfrm_reqid_parse(&req.xspi.info.reqid, &argc, &argv);
@@ -618,6 +636,15 @@ static int xfrm_state_allocspi(int argc, char **argv)
req.xspi.max = 0xffff;
}
+ if (mark.m & mark.v) {
+ int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
+ (void *)&mark, sizeof(mark));
+ if (r < 0) {
+ fprintf(stderr, "XFRMA_MARK failed\n");
+ exit(1);
+ }
+ }
+
if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
exit(1);
@@ -763,6 +790,7 @@ static int xfrm_state_get_or_delete(int argc, char **argv, int delete)
} req;
struct xfrm_id id;
char *idp = NULL;
+ struct xfrm_mark mark = {0, 0};
memset(&req, 0, sizeof(req));
@@ -774,26 +802,39 @@ static int xfrm_state_get_or_delete(int argc, char **argv, int delete)
while (argc > 0) {
xfrm_address_t saddr;
- if (idp)
- invarg("unknown", *argv);
- idp = *argv;
+ if (strcmp(*argv, "mark") == 0) {
+ xfrm_parse_mark(&mark, &argc, &argv);
+ } else {
+ if (idp)
+ invarg("unknown", *argv);
+ idp = *argv;
- /* ID */
- memset(&id, 0, sizeof(id));
- memset(&saddr, 0, sizeof(saddr));
- xfrm_id_parse(&saddr, &id, &req.xsid.family, 0,
- &argc, &argv);
+ /* ID */
+ memset(&id, 0, sizeof(id));
+ memset(&saddr, 0, sizeof(saddr));
+ xfrm_id_parse(&saddr, &id, &req.xsid.family, 0,
+ &argc, &argv);
- memcpy(&req.xsid.daddr, &id.daddr, sizeof(req.xsid.daddr));
- req.xsid.spi = id.spi;
- req.xsid.proto = id.proto;
+ memcpy(&req.xsid.daddr, &id.daddr, sizeof(req.xsid.daddr));
+ req.xsid.spi = id.spi;
+ req.xsid.proto = id.proto;
- addattr_l(&req.n, sizeof(req.buf), XFRMA_SRCADDR,
- (void *)&saddr, sizeof(saddr));
+ addattr_l(&req.n, sizeof(req.buf), XFRMA_SRCADDR,
+ (void *)&saddr, sizeof(saddr));
+ }
argc--; argv++;
}
+ if (mark.m & mark.v) {
+ int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
+ (void *)&mark, sizeof(mark));
+ if (r < 0) {
+ fprintf(stderr, "XFRMA_MARK failed\n");
+ exit(1);
+ }
+ }
+
if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
exit(1);
diff --git a/lib/dnet_ntop.c b/lib/dnet_ntop.c
index 9500df86..507a7eb8 100644
--- a/lib/dnet_ntop.c
+++ b/lib/dnet_ntop.c
@@ -1,4 +1,5 @@
#include <errno.h>
+#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
@@ -35,11 +36,14 @@ static __inline__ int do_digit(char *str, u_int16_t *addr, u_int16_t scale, size
static const char *dnet_ntop1(const struct dn_naddr *dna, char *str, size_t len)
{
- u_int16_t addr = dn_ntohs(*(u_int16_t *)dna->a_addr);
- u_int16_t area = addr >> 10;
+ u_int16_t addr, area;
size_t pos = 0;
int started = 0;
+ memcpy(&addr, dna->a_addr, sizeof(addr));
+ addr = dn_ntohs(addr);
+ area = addr >> 10;
+
if (dna->a_len != 2)
return NULL;
diff --git a/lib/dnet_pton.c b/lib/dnet_pton.c
index bd7727ae..73857562 100644
--- a/lib/dnet_pton.c
+++ b/lib/dnet_pton.c
@@ -1,4 +1,5 @@
#include <errno.h>
+#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
@@ -37,6 +38,7 @@ static int dnet_num(const char *src, u_int16_t * dst)
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;
int pos;
@@ -48,7 +50,8 @@ static int dnet_pton1(const char *src, struct dn_naddr *dna)
if ((pos == 0) || (node > 1023))
return 0;
dna->a_len = 2;
- *(u_int16_t *)dna->a_addr = dn_htons((area << 10) | node);
+ addr = dn_htons((area << 10) | node);
+ memcpy(dna->a_addr, &addr, sizeof(addr));
return 1;
}
diff --git a/lib/libnetlink.c b/lib/libnetlink.c
index 4ba60190..cfeb8941 100644
--- a/lib/libnetlink.c
+++ b/lib/libnetlink.c
@@ -644,7 +644,7 @@ int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
{
memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
while (RTA_OK(rta, len)) {
- if (rta->rta_type <= max)
+ if ((rta->rta_type <= max) && (!tb[rta->rta_type]))
tb[rta->rta_type] = rta;
rta = RTA_NEXT(rta,len);
}
diff --git a/lib/ll_map.c b/lib/ll_map.c
index 5addf4a4..b8b49aa1 100644
--- a/lib/ll_map.c
+++ b/lib/ll_map.c
@@ -161,6 +161,7 @@ unsigned ll_name_to_index(const char *name)
static int icache;
struct idxmap *im;
int i;
+ unsigned idx;
if (name == NULL)
return 0;
@@ -176,7 +177,10 @@ unsigned ll_name_to_index(const char *name)
}
}
- return if_nametoindex(name);
+ idx = if_nametoindex(name);
+ if (idx == 0)
+ sscanf(name, "if%u", &idx);
+ return idx;
}
int ll_init_map(struct rtnl_handle *rth)
diff --git a/lib/ll_types.c b/lib/ll_types.c
index 9d75bd26..448892bf 100644
--- a/lib/ll_types.c
+++ b/lib/ll_types.c
@@ -30,7 +30,7 @@
const char * ll_type_n2a(int type, char *buf, int len)
{
#define __PF(f,n) { ARPHRD_##f, #n },
-static struct {
+static const struct {
int type;
const char *name;
} arphrd_names[] = {
@@ -40,25 +40,14 @@ __PF(EETHER,eether)
__PF(AX25,ax25)
__PF(PRONET,pronet)
__PF(CHAOS,chaos)
-#ifdef ARPHRD_IEEE802_TR
__PF(IEEE802,ieee802)
-#else
-__PF(IEEE802,tr)
-#endif
__PF(ARCNET,arcnet)
__PF(APPLETLK,atalk)
__PF(DLCI,dlci)
-#ifdef ARPHRD_ATM
__PF(ATM,atm)
-#endif
__PF(METRICOM,metricom)
-#ifdef ARPHRD_IEEE1394
__PF(IEEE1394,ieee1394)
-#endif
-#ifdef ARPHRD_INFINIBAND
__PF(INFINIBAND,infiniband)
-#endif
-
__PF(SLIP,slip)
__PF(CSLIP,cslip)
__PF(SLIP6,slip6)
@@ -67,20 +56,13 @@ __PF(RSRVD,rsrvd)
__PF(ADAPT,adapt)
__PF(ROSE,rose)
__PF(X25,x25)
-#ifdef ARPHRD_HWX25
__PF(HWX25,hwx25)
-#endif
__PF(CAN,can)
__PF(PPP,ppp)
__PF(HDLC,hdlc)
__PF(LAPB,lapb)
-#ifdef ARPHRD_DDCMP
__PF(DDCMP,ddcmp)
-#endif
-#ifdef ARPHRD_RAWHDLC
__PF(RAWHDLC,rawhdlc)
-#endif
-
__PF(TUNNEL,ipip)
__PF(TUNNEL6,tunnel6)
__PF(FRAD,frad)
@@ -113,21 +95,17 @@ __PF(FCFABRIC+9,fcfb9)
__PF(FCFABRIC+10,fcfb10)
__PF(FCFABRIC+11,fcfb11)
__PF(FCFABRIC+12,fcfb12)
-#ifdef ARPHRD_IEEE802_TR
__PF(IEEE802_TR,tr)
-#endif
-#ifdef ARPHRD_IEEE80211
__PF(IEEE80211,ieee802.11)
-#endif
-#ifdef ARPHRD_IEEE80211_PRISM
__PF(IEEE80211_PRISM,ieee802.11/prism)
-#endif
-#ifdef ARPHRD_IEEE80211_RADIOTAP
__PF(IEEE80211_RADIOTAP,ieee802.11/radiotap)
-#endif
-#ifdef ARPHRD_VOID
+__PF(IEEE802154, ieee802.15.4)
+__PF(PHONET, phonet)
+__PF(PHONET_PIPE, phonet_pipe)
+__PF(CAIF, caif)
+
+__PF(NONE, none)
__PF(VOID,void)
-#endif
};
#undef __PF
diff --git a/man/man8/ip.8 b/man/man8/ip.8
index a8fccc41..1a73efa6 100644
--- a/man/man8/ip.8
+++ b/man/man8/ip.8
@@ -27,6 +27,34 @@ ip \- show / manipulate routing, devices, policy routing and tunnels
\fB\-o\fR[\fIneline\fR] }
.ti -8
+.BI "ip link add link " DEVICE
+.RB "[ " name " ]"
+.I NAME
+.br
+.RB "[ " txqueuelen
+.IR PACKETS " ]"
+.br
+.RB "[ " address
+.IR LLADDR " ]"
+.RB "[ " broadcast
+.IR LLADDR " ]"
+.br
+.RB "[ " mtu
+.IR MTU " ]"
+.br
+.BR type TYPE
+.RI "[ " ARGS " ]"
+
+.ti -8
+.IR TYPE " := [ "
+.BR vlan " | " maclan " | " can " ]"
+
+.ti -8
+.BI "ip link delete " DEVICE
+.BI type TYPE
+.RI "[ " ARGS " ]"
+
+.ti -8
.BI "ip link set " DEVICE
.RB "{ " up " | " down " | " arp " { " on " | " off " } |"
.br
@@ -53,7 +81,21 @@ ip \- show / manipulate routing, devices, policy routing and tunnels
.IR MTU " |"
.br
.B netns
-.IR PID " }"
+.IR PID " |"
+.br
+.B alias
+.IR NAME " |"
+.br
+.B vf
+.IR NUM " ["
+.B mac
+.IR LLADDR " ] ["
+.B vlan
+.IR VLANID " [ "
+.B qos
+.IR VLAN-QOS " ] ] ["
+.B rate
+.IR TXRATE " ]"
.ti -8
.B ip link show
@@ -97,7 +139,7 @@ ip \- show / manipulate routing, devices, policy routing and tunnels
.ti -8
.IR FLAG " := "
.RB "[ " permanent " | " dynamic " | " secondary " | " primary " | "\
-tentative " | " deprecated " ]"
+tentative " | " deprecated " | " dadfailed " | " temporary " ]"
.ti -8
.BR "ip addrlabel" " { " add " | " del " } " prefix
@@ -195,7 +237,11 @@ replace " | " monitor " } "
.B realms
.IR REALM " ] [ "
.B rto_min
-.IR TIME " ]"
+.IR TIME " ] [ "
+.B initcwnd
+.IR NUMBER " ] [ "
+.B initrwnd
+.IR NUMBER " ]"
.ti -8
.IR TYPE " := [ "
@@ -213,10 +259,6 @@ throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]"
.IR NUMBER " ]"
.ti -8
-.IR FLAGS " := [ "
-.BR equalize " ]"
-
-.ti -8
.IR NHFLAGS " := [ "
.BR onlink " | " pervasive " ]"
@@ -240,7 +282,9 @@ throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]"
.IR TOS " ] [ "
.B fwmark
.IR FWMARK[/MASK] " ] [ "
-.B dev
+.B iif
+.IR STRING " ] [ "
+.B oif
.IR STRING " ] [ "
.B pref
.IR NUMBER " ]"
@@ -819,12 +863,50 @@ or, if the objects of this class cannot be listed,
is a network device and the corresponding commands
display and change the state of devices.
-.SS ip link set - change device attributes
+.SS ip link add - add virtual link
.TP
-.BI dev " NAME " (default)
+.BI link " DEVICE "
+specifies the physical device to act operate on.
+
.I NAME
-specifies network device to operate on.
+specifies the name of the new virtual device.
+
+.I TYPE
+specifies the type of the new device.
+.sp
+Link types:
+
+.in +8
+.B vlan
+- 802.1q tagged virrtual LAN interface
+.sp
+.B macvlan
+- virtual interface base on link layer address (MAC)
+.sp
+.B can
+- Controller Area Network interface
+.in -8
+
+.SS ip link delete - delete virtual link
+.I DEVICE
+specifies the virtual device to act operate on.
+.I TYPE
+specifies the type of the device.
+
+
+.TP
+.BI dev " DEVICE "
+specifies the physical device to act operate on.
+
+.SS ip link set - change device attributes
+
+.TP
+.BI dev " DEVICE "
+.I DEVICE
+specifies network device to operate on. When configuring SR-IOV Virtual Fuction
+(VF) devices, this keyword should specify the associated Physical Function (PF)
+device.
.TP
.BR up " and " down
@@ -886,7 +968,56 @@ the interface is
.TP
.BI netns " PID"
move the device to the network namespace associated with the process
-.IR "PID" .
+.IR "PID".
+
+.TP
+.BI alias " NAME"
+give the device a symbolic name for easy reference.
+
+.TP
+.BI vf " NUM"
+specify a Virtual Function device to be configured. The associated PF device
+must be specified using the
+.B dev
+parameter.
+
+.in +8
+.BI mac " LLADDRESS"
+- change the station address for the specified VF. The
+.B vf
+parameter must be specified.
+
+.sp
+.BI vlan " VLANID"
+- change the assigned VLAN for the specified VF. When specified, all traffic
+sent from the VF will be tagged with the specified VLAN ID. Incoming traffic
+will be filtered for the specified VLAN ID, and will have all VLAN tags
+stripped before being passed to the VF. Setting this parameter to 0 disables
+VLAN tagging and filtering. The
+.B vf
+parameter must be specified.
+
+.sp
+.BI qos " VLAN-QOS"
+- assign VLAN QOS (priority) bits for the VLAN tag. When specified, all VLAN
+tags transmitted by the VF will include the specified priority bits in the
+VLAN tag. If not specified, the value is assumed to be 0. Both the
+.B vf
+and
+.B vlan
+parameters must be specified. Setting both
+.B vlan
+and
+.B qos
+as 0 disables VLAN tagging and filtering for the VF.
+
+.sp
+.BI rate " TXRATE"
+- change the allowed transmit bandwidth, in Mbps, for the specified VF.
+Setting this parameter to 0 disables rate limiting. The
+.B vf
+parameter must be specified.
+.in -8
.PP
.B Warning:
@@ -1030,7 +1161,7 @@ addresses.
.TP
.B tentative
-(IPv6 only) only list addresses which did not pass duplicate
+(IPv6 only) only list addresses which have not yet passed duplicate
address detection.
.TP
@@ -1038,6 +1169,15 @@ address detection.
(IPv6 only) only list deprecated addresses.
.TP
+.B dadfailed
+(IPv6 only) only list addresses which have failed duplicate
+address detection.
+
+.TP
+.B temporary
+(IPv6 only) only list temporary addresses.
+
+.TP
.BR primary " and " secondary
only list primary (or secondary) addresses.
@@ -1321,13 +1461,13 @@ normal routing tables.
.P
.B Route tables:
-Linux-2.x can pack routes into several routing
-tables identified by a number in the range from 1 to 255 or by
-name from the file
+Linux-2.x can pack routes into several routing tables identified
+by a number in the range from 1 to 2^31 or by name from the file
.B /etc/iproute2/rt_tables
By default all normal routes are inserted into the
.B main
table (ID 254) and the kernel only uses this table when calculating routes.
+Values (0, 253, 254, and 255) are reserved for built-in use.
.sp
Actually, one other table always exists, which is invisible but
@@ -1487,6 +1627,19 @@ the clamp for congestion window. It is ignored if the
flag is not used.
.TP
+.BI initcwnd " NUMBER " "(2.5.70+ only)"
+the initial congestion window size for connections to this destination.
+Actual window size is this value multiplied by the MSS
+(``Maximal Segment Size'') for same connection. The default is
+zero, meaning to use the values specified in RFC2414.
+
+.TP
+.BI initrwnd " NUMBER " "(2.6.33+ only)"
+the initial receive window size for connections to this destination.
+Actual window size is this value multiplied by the MSS of the connection.
+The default value is zero, meaning to use Slow Start value.
+
+.TP
.BI advmss " NUMBER " "(2.3.15+ only)"
the MSS ('Maximal Segment Size') to advertise to these
destinations when establishing TCP connections. If it is not given,
@@ -1589,14 +1742,6 @@ to assign (or not to assign) protocol tags.
pretend that the nexthop is directly attached to this link,
even if it does not match any interface prefix.
-.TP
-.B equalize
-allow packet by packet randomization on multipath routes.
-Without this modifier, the route will be frozen to one selected
-nexthop, so that load splitting will only occur on per-flow base.
-.B equalize
-only works if the kernel is patched.
-
.SS ip route delete - delete route
.B ip route del
@@ -1936,6 +2081,12 @@ that you may create separate routing tables for forwarded and local
packets and, hence, completely segregate them.
.TP
+.BI oif " NAME"
+select the outgoing device to match. The outgoing interface is only
+available for packets originating from local sockets that are bound to
+a device.
+
+.TP
.BI tos " TOS"
.TP
.BI dsfield " TOS"
diff --git a/man/man8/tc-drr.8 b/man/man8/tc-drr.8
new file mode 100644
index 00000000..16a8ec0d
--- /dev/null
+++ b/man/man8/tc-drr.8
@@ -0,0 +1,94 @@
+.TH TC 8 "January 2010" "iproute2" "Linux"
+.SH NAME
+drr \- deficit round robin scheduler
+.SH SYNOPSIS
+.B tc qdisc ... add drr
+.B [ quantum
+bytes
+.B ]
+
+.SH DESCRIPTION
+
+The Deficit Round Robin Scheduler is a classful queuing discipline as
+a more flexible replacement for Stochastic Fairness Queuing.
+
+Unlike SFQ, there are no built-in queues \-\- you need to add classes
+and then set up filters to classify packets accordingly.
+This can be useful e.g. for using RED qdiscs with different settings for particular
+traffic. There is no default class \-\- if a packet cannot be classified,
+it is dropped.
+
+.SH ALGORITHM
+Each class is assigned a deficit counter, initialized to
+.B quantum.
+
+DRR maintains an (internal) ''active'' list of classes whose qdiscs are
+non-empty. This list is used for dequeuing. A packet is dequeued from
+the class at the head of the list if the packet size is smaller or equal
+to the deficit counter. If the counter is too small, it is increased by
+.B quantum
+and the scheduler moves on to the next class in the active list.
+
+
+.SH PARAMETERS
+.TP
+quantum
+Amount of bytes a flow is allowed to dequeue before the scheduler moves to
+the next class. Defaults to the MTU of the interface. The minimum value is 1.
+
+.SH EXAMPLE & USAGE
+
+To attach to device eth0, using the interface MTU as its quantum:
+.P
+# tc qdisc add dev eth0 handle 1 root drr
+.P
+Adding two classes:
+.P
+# tc class add dev eth0 parent 1: classid 1:1 drr
+# tc class add dev eth0 parent 1: classid 1:2 drr
+.P
+You also need to add at least one filter to classify packets.
+.P
+# tc filter add dev eth0 protocol .. classid 1:1
+.P
+
+Like SFQ, DRR is only useful when it owns the queue \-\- it is a pure scheduler and does
+not delay packets. Attaching non-work-conserving qdiscs like tbf to it does not make
+sense \-\- other qdiscs in the active list will also become inactive until the dequeue
+operation succeeds. Embed DRR within another qdisc like HTB or HFSC to ensure it owns the queue.
+.P
+You can mimic SFQ behavior by assigning packets to the attached classes using the
+flow filter:
+
+.B tc qdisc add dev .. drr
+
+.B for i in .. 1024;do
+.br
+.B \ttc class add dev .. classid $handle:$(print %x $i)
+.br
+.B \ttc qdisc add dev .. fifo limit 16
+.br
+.B done
+
+.B tc filter add .. protocol ip .. $handle flow hash keys src,dst,proto,proto-src,proto-dst divisor 1024 perturb 10
+
+
+.SH SOURCE
+.TP
+o
+M. Shreedhar and George Varghese "Efficient Fair
+Queuing using Deficit Round Robin", Proc. SIGCOMM 95.
+
+.SH NOTES
+
+This implementation does not drop packets from the longest queue on overrun,
+as limits are handled by the individual child qdiscs.
+
+.SH SEE ALSO
+.BR tc (8),
+.BR tc-htb (8),
+.BR tc-sfq (8)
+
+.SH AUTHOR
+sched_drr was written by Patrick McHardy.
+
diff --git a/man/man8/tc-prio.8 b/man/man8/tc-prio.8
index 780bcd5a..1625fccc 100644
--- a/man/man8/tc-prio.8
+++ b/man/man8/tc-prio.8
@@ -50,7 +50,7 @@ be enqueued.
From userspace
A process with sufficient privileges can encode the destination class
directly with SO_PRIORITY, see
-.BR tc(7).
+.BR socket(7).
.TP
with a tc filter
A tc filter attached to the root qdisc can point traffic directly to a class
diff --git a/man/man8/tc-sfq.8 b/man/man8/tc-sfq.8
index 337c7950..8f2b4333 100644
--- a/man/man8/tc-sfq.8
+++ b/man/man8/tc-sfq.8
@@ -51,6 +51,9 @@ on the fullest bucket, thus maintaining fairness.
.SH PARAMETERS
.TP
+limit
+Upper limit of the SFQ. Can be used to reduce the default length of 128 packets.
+.TP
perturb
Interval in seconds for queue algorithm perturbation. Defaults to 0, which means that
no perturbation occurs. Do not set too low for each perturbation may cause some packet
diff --git a/man/man8/tc.8 b/man/man8/tc.8
index 8c0880fa..e17ce68b 100644
--- a/man/man8/tc.8
+++ b/man/man8/tc.8
@@ -367,6 +367,7 @@ print rates in IEC units (ie. 1K = 1024).
was written by Alexey N. Kuznetsov and added in Linux 2.2.
.SH SEE ALSO
.BR tc-cbq (8),
+.BR tc-drr (8),
.BR tc-htb (8),
.BR tc-sfq (8),
.BR tc-red (8),
diff --git a/misc/ss.c b/misc/ss.c
index 8a9663cf..482b6bb8 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -195,90 +195,147 @@ static FILE *ephemeral_ports_open(void)
return generic_proc_open("PROC_IP_LOCAL_PORT_RANGE", "sys/net/ipv4/ip_local_port_range");
}
-int find_users(unsigned ino, char *buf, int buflen)
+struct user_ent {
+ struct user_ent *next;
+ unsigned int ino;
+ int pid;
+ int fd;
+ char process[0];
+};
+
+#define USER_ENT_HASH_SIZE 256
+struct user_ent *user_ent_hash[USER_ENT_HASH_SIZE];
+
+static int user_ent_hashfn(unsigned int ino)
{
- char pattern[64];
- int pattern_len;
- char *ptr = buf;
- char name[1024];
- DIR *dir;
- struct dirent *d;
- int cnt = 0;
- int nameoff;
+ int val = (ino >> 24) ^ (ino >> 16) ^ (ino >> 8) ^ ino;
- if (!ino)
- return 0;
+ return val & (USER_ENT_HASH_SIZE - 1);
+}
+
+static void user_ent_add(unsigned int ino, const char *process, int pid, int fd)
+{
+ struct user_ent *p, **pp;
+ int str_len;
- sprintf(pattern, "socket:[%u]", ino);
- pattern_len = strlen(pattern);
+ str_len = strlen(process) + 1;
+ p = malloc(sizeof(struct user_ent) + str_len);
+ if (!p)
+ abort();
+ p->next = NULL;
+ p->ino = ino;
+ p->pid = pid;
+ p->fd = fd;
+ strcpy(p->process, process);
+
+ pp = &user_ent_hash[user_ent_hashfn(ino)];
+ p->next = *pp;
+ *pp = p;
+}
- strncpy(name, getenv("PROC_ROOT") ? : "/proc/", sizeof(name)/2);
- name[sizeof(name)/2] = 0;
- if (strlen(name) == 0 ||
- name[strlen(name)-1] != '/')
+static void user_ent_hash_build(void)
+{
+ const char *root = getenv("PROC_ROOT") ? : "/proc/";
+ struct dirent *d;
+ char name[1024];
+ int nameoff;
+ DIR *dir;
+
+ strcpy(name, root);
+ if (strlen(name) == 0 || name[strlen(name)-1] != '/')
strcat(name, "/");
+
nameoff = strlen(name);
- if ((dir = opendir(name)) == NULL)
- return 0;
+
+ dir = opendir(name);
+ if (!dir)
+ return;
while ((d = readdir(dir)) != NULL) {
- DIR *dir1;
struct dirent *d1;
- int pid;
- int pos;
- char crap;
char process[16];
+ int pid, pos;
+ DIR *dir1;
+ char crap;
if (sscanf(d->d_name, "%d%c", &pid, &crap) != 1)
continue;
- sprintf(name+nameoff, "%d/fd/", pid);
+ sprintf(name + nameoff, "%d/fd/", pid);
pos = strlen(name);
if ((dir1 = opendir(name)) == NULL)
continue;
- process[0] = 0;
+ process[0] = '\0';
while ((d1 = readdir(dir1)) != NULL) {
- int fd, n;
+ const char *pattern = "socket:[";
+ unsigned int ino;
char lnk[64];
+ int fd, n;
if (sscanf(d1->d_name, "%d%c", &fd, &crap) != 1)
continue;
sprintf(name+pos, "%d", fd);
n = readlink(name, lnk, sizeof(lnk)-1);
- if (n != pattern_len ||
- memcmp(lnk, pattern, n))
+ if (strncmp(lnk, pattern, strlen(pattern)))
continue;
- if (ptr-buf >= buflen-1)
- break;
+ sscanf(lnk, "socket:[%u]", &ino);
- if (process[0] == 0) {
+ if (process[0] == '\0') {
char tmp[1024];
FILE *fp;
- snprintf(tmp, sizeof(tmp), "%s/%d/stat",
- getenv("PROC_ROOT") ? : "/proc", pid);
+
+ snprintf(tmp, sizeof(tmp), "%s/%d/stat", root, pid);
if ((fp = fopen(tmp, "r")) != NULL) {
fscanf(fp, "%*d (%[^)])", process);
fclose(fp);
}
}
- snprintf(ptr, buflen-(ptr-buf), "(\"%s\",%d,%d),", process, pid, fd);
- ptr += strlen(ptr);
- cnt++;
+ user_ent_add(ino, process, pid, fd);
}
closedir(dir1);
}
closedir(dir);
+}
+
+int find_users(unsigned ino, char *buf, int buflen)
+{
+ struct user_ent *p;
+ int cnt = 0;
+ char *ptr;
+
+ if (!ino)
+ return 0;
+
+ p = user_ent_hash[user_ent_hashfn(ino)];
+ ptr = buf;
+ while (p) {
+ if (p->ino != ino)
+ goto next;
+
+ if (ptr - buf >= buflen - 1)
+ break;
+
+ snprintf(ptr, buflen - (ptr - buf),
+ "(\"%s\",%d,%d),",
+ p->process, p->pid, p->fd);
+ ptr += strlen(ptr);
+ cnt++;
+
+ next:
+ p = p->next;
+ }
+
if (ptr != buf)
- ptr[-1] = 0;
+ ptr[-1] = '\0';
+
return cnt;
}
-
/* Get stats from slab */
struct slabstat
@@ -2476,6 +2533,7 @@ int main(int argc, char *argv[])
break;
case 'p':
show_users++;
+ user_ent_hash_build();
break;
case 'd':
current_filter.dbs |= (1<<DCCP_DB);
diff --git a/netem/Makefile b/netem/Makefile
index b6ccfc6a..e52e125e 100644
--- a/netem/Makefile
+++ b/netem/Makefile
@@ -20,9 +20,9 @@ stats: stats.c
$(HOSTCC) $(CCOPTS) -I../include -o $@ $@.c -lm
install: all
- mkdir -p $(DESTDIR)/lib/tc
+ mkdir -p $(DESTDIR)$(LIBDIR)/tc
for i in $(DISTDATA); \
- do install -m 755 $$i $(DESTDIR)/lib/tc; \
+ do install -m 644 $$i $(DESTDIR)$(LIBDIR)/tc; \
done
clean:
diff --git a/tc/Makefile b/tc/Makefile
index f3dd2b76..3aa9f263 100644
--- a/tc/Makefile
+++ b/tc/Makefile
@@ -43,19 +43,20 @@ TCMODULES += em_cmp.o
TCMODULES += em_u32.o
TCMODULES += em_meta.o
+TCSO :=
+ifeq ($(TC_CONFIG_ATM),y)
+ TCSO += q_atm.so
+endif
ifeq ($(TC_CONFIG_XT),y)
- TCMODULES += m_xt.o
- LDLIBS += -lxtables
+ TCSO += m_xt.so
else
ifeq ($(TC_CONFIG_XT_OLD),y)
- TCMODULES += m_xt_old.o
- LDLIBS += -lxtables
+ TCSO += m_xt_old.so
else
ifeq ($(TC_CONFIG_XT_OLD_H),y)
CFLAGS += -DTC_CONFIG_XT_H
- TCMODULES += m_xt_old.o
- LDLIBS += -lxtables
+ TCSO += m_xt_old.so
else
TCMODULES += m_ipt.o
endif
@@ -77,17 +78,17 @@ TCLIB += tc_estimator.o
TCLIB += tc_stab.o
CFLAGS += -DCONFIG_GACT -DCONFIG_GACT_PROB
-
-TCSO :=
-ifeq ($(TC_CONFIG_ATM),y)
- TCSO += q_atm.so
+ifneq ($(IPT_LIB_DIR),)
+ CFLAGS += -DIPT_LIB_DIR=\"$(IPT_LIB_DIR)\"
endif
YACC := bison
LEX := flex
+MODDESTDIR := $(DESTDIR)$(patsubst /usr%,%,$(LIBDIR))/tc
+
%.so: %.c
- $(CC) $(CFLAGS) -shared -fpic $< -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) -shared -fpic $< -o $@
all: libtc.a tc $(TCSO)
@@ -98,11 +99,18 @@ libtc.a: $(TCLIB)
$(AR) rcs $@ $(TCLIB)
install: all
- mkdir -p $(DESTDIR)$(LIBDIR)/tc
+ mkdir -p $(MODDESTDIR)
install -m 0755 tc $(DESTDIR)$(SBINDIR)
for i in $(TCSO); \
- do install -m 755 $$i $(DESTDIR)$(LIBDIR)/tc; \
+ do install -m 755 $$i $(MODDESTDIR); \
done
+ if [ ! -f $(MODDESTDIR)/m_ipt.so ]; then \
+ if [ -f $(MODDESTDIR)/m_xt.so ]; \
+ then ln -s m_xt.so $(MODDESTDIR)/m_ipt.so ; \
+ elif [ -f $(MODDESTDIR)/m_xt_old.so ]; \
+ then ln -s m_xt_old.so $(MODDESTDIR)/m_ipt.so ; \
+ fi; \
+ fi
clean:
rm -f $(TCOBJ) $(TCLIB) libtc.a tc *.so emp_ematch.yacc.h; \
@@ -111,6 +119,12 @@ clean:
q_atm.so: q_atm.c
$(CC) $(CFLAGS) $(LDFLAGS) -shared -fpic -o q_atm.so q_atm.c -latm
+m_xt.so: m_xt.c
+ $(CC) $(CFLAGS) $(LDFLAGS) -shared -fpic -o m_xt.so m_xt.c -lxtables
+
+m_xt_old.so: m_xt_old.c
+ $(CC) $(CFLAGS) $(LDFLAGS) -shared -fpic -o m_xt_old.so m_xt_old.c -lxtables
+
%.yacc.c: %.y
$(YACC) $(YACCFLAGS) -o $@ $<
diff --git a/tc/emp_ematch.l b/tc/emp_ematch.l
index 0184753a..d9b45be1 100644
--- a/tc/emp_ematch.l
+++ b/tc/emp_ematch.l
@@ -63,7 +63,7 @@
%}
-%x str
+%x lexstr
%option 8bit stack warn noyywrap prefix="ematch_"
%%
@@ -78,17 +78,17 @@
}
strbuf_index = 0;
- BEGIN(str);
+ BEGIN(lexstr);
}
-<str>\" {
+<lexstr>\" {
BEGIN(INITIAL);
yylval.b = bstr_new(strbuf, strbuf_index);
yylval.b->quoted = 1;
return ATTRIBUTE;
}
-<str>\\[0-7]{1,3} { /* octal escape sequence */
+<lexstr>\\[0-7]{1,3} { /* octal escape sequence */
int res;
sscanf(yytext + 1, "%o", &res);
@@ -100,12 +100,12 @@
strbuf_append_char((unsigned char) res);
}
-<str>\\[0-9]+ { /* catch wrong octal escape seq. */
+<lexstr>\\[0-9]+ { /* catch wrong octal escape seq. */
fprintf(stderr, "error: invalid octale escape sequence\n");
return ERROR;
}
-<str>\\x[0-9a-fA-F]{1,2} {
+<lexstr>\\x[0-9a-fA-F]{1,2} {
int res;
sscanf(yytext + 2, "%x", &res);
@@ -118,16 +118,16 @@
strbuf_append_char((unsigned char) res);
}
-<str>\\n strbuf_append_char('\n');
-<str>\\r strbuf_append_char('\r');
-<str>\\t strbuf_append_char('\t');
-<str>\\v strbuf_append_char('\v');
-<str>\\b strbuf_append_char('\b');
-<str>\\f strbuf_append_char('\f');
-<str>\\a strbuf_append_char('\a');
+<lexstr>\\n strbuf_append_char('\n');
+<lexstr>\\r strbuf_append_char('\r');
+<lexstr>\\t strbuf_append_char('\t');
+<lexstr>\\v strbuf_append_char('\v');
+<lexstr>\\b strbuf_append_char('\b');
+<lexstr>\\f strbuf_append_char('\f');
+<lexstr>\\a strbuf_append_char('\a');
-<str>\\(.|\n) strbuf_append_char(yytext[1]);
-<str>[^\\\n\"]+ strbuf_append_charp(yytext);
+<lexstr>\\(.|\n) strbuf_append_char(yytext[1]);
+<lexstr>[^\\\n\"]+ strbuf_append_charp(yytext);
[aA][nN][dD] return AND;
[oO][rR] return OR;
diff --git a/tc/f_fw.c b/tc/f_fw.c
index cc8ea2d8..219b404f 100644
--- a/tc/f_fw.c
+++ b/tc/f_fw.c
@@ -31,8 +31,6 @@ static void explain(void)
fprintf(stderr, "\nNOTE: CLASSID is parsed as hexadecimal input.\n");
}
-#define usage() return(-1)
-
static int fw_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n)
{
struct tc_police tp;
diff --git a/tc/f_route.c b/tc/f_route.c
index 67dd49c0..eccf924b 100644
--- a/tc/f_route.c
+++ b/tc/f_route.c
@@ -34,8 +34,6 @@ static void explain(void)
fprintf(stderr, "\nNOTE: CLASSID is parsed as hexadecimal input.\n");
}
-#define usage() return(-1)
-
static int route_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n)
{
struct tc_police tp;
diff --git a/tc/f_rsvp.c b/tc/f_rsvp.c
index 7e1e6d92..808310df 100644
--- a/tc/f_rsvp.c
+++ b/tc/f_rsvp.c
@@ -37,8 +37,6 @@ static void explain(void)
fprintf(stderr, "\nNOTE: CLASSID is parsed as hexadecimal input.\n");
}
-#define usage() return(-1)
-
int get_addr_and_pi(int *argc_p, char ***argv_p, inet_prefix * addr,
struct tc_rsvp_pinfo *pinfo, int dir, int family)
{
diff --git a/tc/f_tcindex.c b/tc/f_tcindex.c
index 39ac75ad..cb6f854c 100644
--- a/tc/f_tcindex.c
+++ b/tc/f_tcindex.c
@@ -24,10 +24,6 @@ static void explain(void)
"[ police POLICE_SPEC ]\n");
}
-
-#define usage() return(-1)
-
-
static int tcindex_parse_opt(struct filter_util *qu, char *handle, int argc,
char **argv, struct nlmsghdr *n)
{
diff --git a/tc/f_u32.c b/tc/f_u32.c
index cb3f67ea..d9d40914 100644
--- a/tc/f_u32.c
+++ b/tc/f_u32.c
@@ -45,8 +45,6 @@ static void explain(void)
fprintf(stderr, "\nNOTE: CLASSID is parsed at hexadecimal input.\n");
}
-#define usage() return(-1)
-
int get_u32_handle(__u32 *handle, const char *str)
{
__u32 htid=0, hash=0, nodeid=0;
@@ -405,6 +403,43 @@ static int parse_ip6_addr(int *argc_p, char ***argv_p,
return res;
}
+static int parse_ip6_class(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
+{
+ int res = -1;
+ int argc = *argc_p;
+ char **argv = *argv_p;
+ __u32 key;
+ __u32 mask;
+ int off = 0;
+ int offmask = 0;
+
+ if (argc < 2)
+ return -1;
+
+ if (get_u32(&key, *argv, 0))
+ return -1;
+ argc--; argv++;
+
+ if (get_u32(&mask, *argv, 16))
+ return -1;
+ argc--; argv++;
+
+ if (key > 0xFF || mask > 0xFF)
+ return -1;
+
+ key <<= 20;
+ mask <<= 20;
+ key = htonl(key);
+ mask = htonl(mask);
+
+ if (res = pack_key(sel, key, mask, off, offmask) < 0)
+ return -1;
+
+ *argc_p = argc;
+ *argv_p = argv;
+ return 0;
+}
+
static int parse_ether_addr(int *argc_p, char ***argv_p,
struct tc_u32_sel *sel, int off)
{
@@ -413,7 +448,6 @@ static int parse_ether_addr(int *argc_p, char ***argv_p,
char **argv = *argv_p;
__u8 addr[6];
int offmask = 0;
- __u32 key;
int i;
if (argc < 1)
@@ -434,10 +468,8 @@ static int parse_ether_addr(int *argc_p, char ***argv_p,
return -1;
}
- for (i = 0; i < 6; i += 2) {
- key = *(__u16 *) (addr + i);
-
- res = pack_key16(sel, key, 0xFFFF, off + i, offmask);
+ for (i = 0; i < 6; i++) {
+ res = pack_key8(sel, addr[i], 0xFF, off + i, offmask);
if (res < 0)
return -1;
}
@@ -524,7 +556,7 @@ static int parse_ip6(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
res = parse_ip6_addr(&argc, &argv, sel, 24);
} else if (strcmp(*argv, "priority") == 0) {
NEXT_ARG();
- res = parse_u8(&argc, &argv, sel, 4, 0);
+ res = parse_ip6_class(&argc, &argv, sel);
} else if (strcmp(*argv, "protocol") == 0) {
NEXT_ARG();
res = parse_u8(&argc, &argv, sel, 6, 0);
diff --git a/tc/m_action.c b/tc/m_action.c
index 7ec79d5b..11814c9f 100644
--- a/tc/m_action.c
+++ b/tc/m_action.c
@@ -111,8 +111,8 @@ restart_s:
return a;
}
- snprintf(buf, sizeof(buf), "m_%s.so", str);
- dlh = dlopen(buf, RTLD_LAZY);
+ snprintf(buf, sizeof(buf), "%s/m_%s.so", get_tc_lib(), str);
+ dlh = dlopen(buf, RTLD_LAZY | RTLD_GLOBAL);
if (dlh == NULL) {
dlh = aBODY;
if (dlh == NULL) {
diff --git a/tc/m_ematch.c b/tc/m_ematch.c
index 7f79a065..4c3acf82 100644
--- a/tc/m_ematch.c
+++ b/tc/m_ematch.c
@@ -449,12 +449,14 @@ static int print_ematch_list(FILE *fd, struct tcf_ematch_tree_hdr *hdr,
if (tb == NULL)
return -1;
- if (parse_rtattr_nested(tb, hdr->nmatches, rta) < 0)
- goto errout;
+ if (hdr->nmatches > 0) {
+ if (parse_rtattr_nested(tb, hdr->nmatches, rta) < 0)
+ goto errout;
- fprintf(fd, "\n ");
- if (print_ematch_seq(fd, tb, 1, 1) < 0)
- goto errout;
+ fprintf(fd, "\n ");
+ if (print_ematch_seq(fd, tb, 1, 1) < 0)
+ goto errout;
+ }
err = 0;
errout:
diff --git a/tc/m_mirred.c b/tc/m_mirred.c
index 226df4d2..0d771bc4 100644
--- a/tc/m_mirred.c
+++ b/tc/m_mirred.c
@@ -26,8 +26,6 @@
#include "tc_common.h"
#include <linux/tc_act/tc_mirred.h>
-int mirred_d = 1;
-
static void
explain(void)
{
@@ -196,9 +194,6 @@ parse_egress(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, str
}
}
- if (mirred_d)
- fprintf(stdout, "Action %d device %s ifindex %d\n",p.action, d,p.ifindex);
-
tail = NLMSG_TAIL(n);
addattr_l(n, MAX_MSG, tca_id, NULL, 0);
addattr_l(n, MAX_MSG, TCA_MIRRED_PARMS, &p, sizeof (p));
diff --git a/tc/m_skbedit.c b/tc/m_skbedit.c
index 9044353d..990b9c7d 100644
--- a/tc/m_skbedit.c
+++ b/tc/m_skbedit.c
@@ -31,10 +31,13 @@
static void
explain(void)
{
- fprintf(stderr, "Usage: ... skbedit "
- "queue_mapping QUEUE_MAPPING | priority PRIORITY \n"
- "QUEUE_MAPPING = device transmit queue to use\n"
- "PRIORITY = classID to assign to priority field\n");
+ fprintf(stderr, "Usage: ... skbedit <[QM] [PM] [MM]>\n"
+ "QM = queue_mapping QUEUE_MAPPING\n"
+ "PM = priority PRIORITY \n"
+ "MM = mark MARK \n"
+ "QUEUE_MAPPING = device transmit queue to use\n"
+ "PRIORITY = classID to assign to priority field\n"
+ "MARK = firewall mark to set\n");
}
static void
@@ -54,7 +57,7 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
struct rtattr *tail;
unsigned int tmp;
__u16 queue_mapping;
- __u32 flags = 0, priority;
+ __u32 flags = 0, priority, mark;
struct tc_skbedit sel = { 0 };
if (matches(*argv, "skbedit") != 0)
@@ -80,6 +83,14 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
return -1;
}
ok++;
+ } else if (matches(*argv, "mark") == 0) {
+ flags |= SKBEDIT_F_MARK;
+ NEXT_ARG();
+ if (get_u32(&mark, *argv, 0)) {
+ fprintf(stderr, "Illegal mark\n");
+ return -1;
+ }
+ ok++;
} else if (matches(*argv, "help") == 0) {
usage();
} else {
@@ -137,6 +148,9 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
if (flags & SKBEDIT_F_PRIORITY)
addattr_l(n, MAX_MSG, TCA_SKBEDIT_PRIORITY,
&priority, sizeof(priority));
+ if (flags & SKBEDIT_F_MARK)
+ addattr_l(n, MAX_MSG, TCA_SKBEDIT_MARK,
+ &mark, sizeof(mark));
tail->rta_len = (char *)NLMSG_TAIL(n) - (char *)tail;
*argc_p = argc;
@@ -150,6 +164,7 @@ static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg)
struct rtattr *tb[TCA_SKBEDIT_MAX + 1];
SPRINT_BUF(b1);
__u32 *priority;
+ __u32 *mark;
__u16 *queue_mapping;
if (arg == NULL)
@@ -174,6 +189,10 @@ static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg)
priority = RTA_DATA(tb[TCA_SKBEDIT_PRIORITY]);
fprintf(f, " priority %s", sprint_tc_classid(*priority, b1));
}
+ if (tb[TCA_SKBEDIT_MARK] != NULL) {
+ mark = RTA_DATA(tb[TCA_SKBEDIT_MARK]);
+ fprintf(f, " mark %d", *mark);
+ }
if (show_stats) {
if (tb[TCA_SKBEDIT_TM]) {
diff --git a/tc/m_xt.c b/tc/m_xt.c
index 3972d2d2..bfc49371 100644
--- a/tc/m_xt.c
+++ b/tc/m_xt.c
@@ -39,6 +39,11 @@
# define XT_LIB_DIR "/lib/xtables"
#endif
+#ifndef ALIGN
+#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
+#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
+#endif
+
static const char *tname = "mangle";
char *lib_dir;
diff --git a/tc/m_xt_old.c b/tc/m_xt_old.c
index 0c7ec604..3804d7f2 100644
--- a/tc/m_xt_old.c
+++ b/tc/m_xt_old.c
@@ -40,6 +40,11 @@
#include "xt-internal.h"
#endif
+#ifndef ALIGN
+#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
+#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
+#endif
+
static const char *pname = "tc-ipt";
static const char *tname = "mangle";
static const char *pversion = "0.2";
diff --git a/tc/q_atm.c b/tc/q_atm.c
index 4c8dc0b8..eec0d776 100644
--- a/tc/q_atm.c
+++ b/tc/q_atm.c
@@ -26,8 +26,6 @@
#define MAX_HDR_LEN 64
-#define usage() return(-1)
-
static int atm_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
{
diff --git a/tc/q_cbq.c b/tc/q_cbq.c
index c99dc3b6..3c5e72c1 100644
--- a/tc/q_cbq.c
+++ b/tc/q_cbq.c
@@ -46,7 +46,6 @@ static void explain1(char *arg)
fprintf(stderr, "Illegal \"%s\"\n", arg);
}
-#define usage() return(-1)
static int cbq_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
{
@@ -319,7 +318,7 @@ static int cbq_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str
NEXT_ARG();
if (get_tc_classid(&fopt.split, *argv)) {
fprintf(stderr, "Invalid split node ID.\n");
- usage();
+ return -1;
}
fopt_ok++;
} else if (matches(*argv, "defmap") == 0) {
diff --git a/tc/q_drr.c b/tc/q_drr.c
index 7d2d8741..81de44d9 100644
--- a/tc/q_drr.c
+++ b/tc/q_drr.c
@@ -33,7 +33,6 @@ static void explain2(void)
fprintf(stderr, "Usage: ... drr quantum SIZE\n");
}
-#define usage() return(-1)
static int drr_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
{
diff --git a/tc/q_dsmark.c b/tc/q_dsmark.c
index cdb5bf2f..cfbb3351 100644
--- a/tc/q_dsmark.c
+++ b/tc/q_dsmark.c
@@ -19,9 +19,6 @@
#include "tc_util.h"
-#define usage() return(-1)
-
-
static void explain(void)
{
fprintf(stderr,"Usage: dsmark indices INDICES [ default_index "
diff --git a/tc/q_fifo.c b/tc/q_fifo.c
index 9f3b3eb2..6242a98b 100644
--- a/tc/q_fifo.c
+++ b/tc/q_fifo.c
@@ -25,11 +25,9 @@
static void explain(void)
{
- fprintf(stderr, "Usage: ... [p|b]fifo [ limit NUMBER ]\n");
+ fprintf(stderr, "Usage: ... <[p|b]fifo | pfifo_head_drop> [ limit NUMBER ]\n");
}
-#define usage() return(-1)
-
static int fifo_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
{
int ok=0;
@@ -91,6 +89,12 @@ struct qdisc_util pfifo_qdisc_util = {
.print_qopt = fifo_print_opt,
};
+struct qdisc_util pfifo_head_drop_qdisc_util = {
+ .id = "pfifo_head_drop",
+ .parse_qopt = fifo_parse_opt,
+ .print_qopt = fifo_print_opt,
+};
+
extern int prio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt);
struct qdisc_util pfifo_fast_qdisc_util = {
.id = "pfifo_fast",
diff --git a/tc/q_gred.c b/tc/q_gred.c
index ecef42e9..df4aa3d8 100644
--- a/tc/q_gred.c
+++ b/tc/q_gred.c
@@ -46,8 +46,6 @@ static void explain(void)
"[grio]\n");
}
-#define usage() return(-1)
-
static int init_gred(struct qdisc_util *qu, int argc, char **argv,
struct nlmsghdr *n)
{
@@ -215,16 +213,13 @@ static int gred_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct n
argc--; argv++;
}
- if (!ok)
- return 0;
-
if (rate == 0)
get_rate(&rate, "10Mbit");
if (!opt.qth_min || !opt.qth_max || !burst || !opt.limit || !avpkt ||
(opt.DP<0)) {
fprintf(stderr, "Required parameter (min, max, burst, limit, "
- "avpket, DP) is missing\n");
+ "avpkt, DP) is missing\n");
return -1;
}
diff --git a/tc/q_htb.c b/tc/q_htb.c
index c69e350d..caa47c26 100644
--- a/tc/q_htb.c
+++ b/tc/q_htb.c
@@ -58,8 +58,6 @@ static void explain1(char *arg)
}
-#define usage() return(-1)
-
static int htb_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
{
struct tc_htb_glob opt;
diff --git a/tc/q_ingress.c b/tc/q_ingress.c
index 71fbd493..ba58e722 100644
--- a/tc/q_ingress.c
+++ b/tc/q_ingress.c
@@ -32,8 +32,6 @@ static void explain(void)
fprintf(stderr, "Usage: ... ingress \n");
}
-#define usage() return(-1)
-
static int ingress_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
{
diff --git a/tc/q_multiq.c b/tc/q_multiq.c
index 306e170d..fce5e449 100644
--- a/tc/q_multiq.c
+++ b/tc/q_multiq.c
@@ -41,8 +41,6 @@ static void explain(void)
fprintf(stderr, "Usage: ... multiq [help]\n");
}
-#define usage() return(-1)
-
static int multiq_parse_opt(struct qdisc_util *qu, int argc, char **argv,
struct nlmsghdr *n)
{
diff --git a/tc/q_netem.c b/tc/q_netem.c
index 33b3d2a4..6aaaded9 100644
--- a/tc/q_netem.c
+++ b/tc/q_netem.c
@@ -42,8 +42,6 @@ static void explain1(const char *arg)
fprintf(stderr, "Illegal \"%s\"\n", arg);
}
-#define usage() return(-1)
-
/* Upper bound on size of distribution
* really (TCA_BUF_MAX - other headers) / sizeof (__s16)
*/
diff --git a/tc/q_prio.c b/tc/q_prio.c
index 31a37cd8..2f54d550 100644
--- a/tc/q_prio.c
+++ b/tc/q_prio.c
@@ -28,11 +28,8 @@ static void explain(void)
fprintf(stderr, "Usage: ... prio bands NUMBER priomap P1 P2...[multiqueue]\n");
}
-#define usage() return(-1)
-
static int prio_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
{
- int ok=0;
int pmap_mode = 0;
int idx = 0;
struct tc_prio_qopt opt={3,{ 1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 }};
@@ -48,7 +45,6 @@ static int prio_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct n
fprintf(stderr, "Illegal \"bands\"\n");
return -1;
}
- ok++;
} else if (strcmp(*argv, "priomap") == 0) {
if (pmap_mode) {
fprintf(stderr, "Error: duplicate priomap\n");
diff --git a/tc/q_red.c b/tc/q_red.c
index 6f93b26a..4b1b8893 100644
--- a/tc/q_red.c
+++ b/tc/q_red.c
@@ -31,11 +31,8 @@ static void explain(void)
fprintf(stderr, " probability PROBABILITY bandwidth KBPS [ ecn ]\n");
}
-#define usage() return(-1)
-
static int red_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
{
- int ok=0;
struct tc_red_qopt opt;
unsigned burst = 0;
unsigned avpkt = 0;
@@ -55,52 +52,44 @@ static int red_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nl
fprintf(stderr, "Illegal \"limit\"\n");
return -1;
}
- ok++;
} else if (strcmp(*argv, "min") == 0) {
NEXT_ARG();
if (get_size(&opt.qth_min, *argv)) {
fprintf(stderr, "Illegal \"min\"\n");
return -1;
}
- ok++;
} else if (strcmp(*argv, "max") == 0) {
NEXT_ARG();
if (get_size(&opt.qth_max, *argv)) {
fprintf(stderr, "Illegal \"max\"\n");
return -1;
}
- ok++;
} else if (strcmp(*argv, "burst") == 0) {
NEXT_ARG();
if (get_unsigned(&burst, *argv, 0)) {
fprintf(stderr, "Illegal \"burst\"\n");
return -1;
}
- ok++;
} else if (strcmp(*argv, "avpkt") == 0) {
NEXT_ARG();
if (get_size(&avpkt, *argv)) {
fprintf(stderr, "Illegal \"avpkt\"\n");
return -1;
}
- ok++;
} else if (strcmp(*argv, "probability") == 0) {
NEXT_ARG();
if (sscanf(*argv, "%lg", &probability) != 1) {
fprintf(stderr, "Illegal \"probability\"\n");
return -1;
}
- ok++;
} else if (strcmp(*argv, "bandwidth") == 0) {
NEXT_ARG();
if (get_rate(&rate, *argv)) {
fprintf(stderr, "Illegal \"bandwidth\"\n");
return -1;
}
- ok++;
} else if (strcmp(*argv, "ecn") == 0) {
ecn_ok = 1;
- ok++;
} else if (strcmp(*argv, "help") == 0) {
explain();
return -1;
@@ -112,14 +101,11 @@ static int red_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nl
argc--; argv++;
}
- if (!ok)
- return 0;
-
if (rate == 0)
get_rate(&rate, "10Mbit");
if (!opt.qth_min || !opt.qth_max || !burst || !opt.limit || !avpkt) {
- fprintf(stderr, "Required parameter (min, max, burst, limit, avpket) is missing\n");
+ fprintf(stderr, "Required parameter (min, max, burst, limit, avpkt) is missing\n");
return -1;
}
diff --git a/tc/q_rr.c b/tc/q_rr.c
index 9bb8c7de..1ff3ac96 100644
--- a/tc/q_rr.c
+++ b/tc/q_rr.c
@@ -28,11 +28,9 @@ static void explain(void)
fprintf(stderr, "Usage: ... rr bands NUMBER priomap P1 P2... [multiqueue]\n");
}
-#define usage() return(-1)
static int rr_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
{
- int ok = 0;
int pmap_mode = 0;
int idx = 0;
struct tc_prio_qopt opt={3,{ 1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 }};
@@ -48,7 +46,6 @@ static int rr_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlm
fprintf(stderr, "Illegal \"bands\"\n");
return -1;
}
- ok++;
} else if (strcmp(*argv, "priomap") == 0) {
if (pmap_mode) {
fprintf(stderr, "Error: duplicate priomap\n");
diff --git a/tc/q_sfq.c b/tc/q_sfq.c
index ce4dade8..71a3c9ac 100644
--- a/tc/q_sfq.c
+++ b/tc/q_sfq.c
@@ -28,8 +28,6 @@ static void explain(void)
fprintf(stderr, "Usage: ... sfq [ limit NUMBER ] [ perturb SECS ] [ quantum BYTES ]\n");
}
-#define usage() return(-1)
-
static int sfq_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
{
int ok=0;
diff --git a/tc/q_tbf.c b/tc/q_tbf.c
index dbf95863..dc556fe0 100644
--- a/tc/q_tbf.c
+++ b/tc/q_tbf.c
@@ -36,8 +36,6 @@ static void explain1(char *arg)
}
-#define usage() return(-1)
-
static int tbf_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
{
int ok=0;
@@ -158,8 +156,10 @@ static int tbf_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nl
argc--; argv++;
}
- if (!ok)
- return 0;
+ if (!ok) {
+ explain();
+ return -1;
+ }
if (opt.rate.rate == 0 || !buffer) {
fprintf(stderr, "Both \"rate\" and \"burst\" are required.\n");