diff options
author | Dmitry Shmidt <dimitrysh@google.com> | 2011-01-06 15:37:12 -0800 |
---|---|---|
committer | Dmitry Shmidt <dimitrysh@google.com> | 2011-01-06 15:37:12 -0800 |
commit | 1a441f49ec87ef74b978d7ae17da2a9b2ca6e811 (patch) | |
tree | a0fe569be05241e141f7bf03c5b42bd548c096d9 | |
parent | 722fcc24bc9c1d1066e01ba8890c20602d5c8413 (diff) | |
download | iproute2-1a441f49ec87ef74b978d7ae17da2a9b2ca6e811.tar.gz |
Update iproute2 to ver 2.6.35android-sdk-tools_r12android-sdk-adt_r12android-sdk-3.1_r1android-3.2_r1android-3.2.4_r1android-3.2.2_r2android-3.2.2_r1android-3.2.1_r2android-3.2.1_r1android-3.1_r1
Change-Id: I8a85cc051aea35e4562c7fea46c148ed2757efc6
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
96 files changed, 2135 insertions, 644 deletions
@@ -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 @@ -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 @@ -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), @@ -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; @@ -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) { @@ -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]) { @@ -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"; @@ -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) { @@ -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) { @@ -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; } @@ -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"); @@ -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; } @@ -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"); @@ -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; @@ -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"); |