diff --git a/.gitignore b/.gitignore index 8199aae6..5ee20805 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,22 @@ +static-syms.h Config *.o *.a *.so *~ +\#*# +# cscope +cscope.* +ncscope.* +# for patch generation +*.diff +*.patch +*.orig +*.rej +# for quilt +patches +series +# for gdb +.gdbinit +.gdb_history +*.gdb diff --git a/Makefile b/Makefile index 74e9d627..77a85c6e 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,12 @@ ARPDDIR=/var/lib/arpd # Path to db_185.h include DBM_INCLUDE:=$(ROOTDIR)/usr/include +SHARED_LIBS = y + DEFINES= -DRESOLVE_HOSTNAMES -DLIBDIR=\"$(LIBDIR)\" +ifneq ($(SHARED_LIBS),y) +DEFINES+= -DNO_SHARED_LIBS +endif #options if you have a bind>=4.9.4 libresolv (or, maybe, glibc) LDLIBS=-lresolv diff --git a/configure b/configure index df40370a..92a0b484 100755 --- a/configure +++ b/configure @@ -3,11 +3,8 @@ # INCLUDE=${1:-"$PWD/include"} -echo "# Generated config based on" $INCLUDE >Config - -echo "TC schedulers" - -echo -n " ATM " +check_atm() +{ cat >/tmp/atmtest.c < int main(int argc, char **argv) { @@ -25,8 +22,46 @@ else echo no fi rm -f /tmp/atmtest.c /tmp/atmtest +} -echo -n " IPT " +check_xt() +{ +#check if we have xtables from iptables >= 1.4.5. +cat >/tmp/ipttest.c < +#include +static struct xtables_globals test_globals = { + .option_offset = 0, + .program_name = "tc-ipt", + .program_version = XTABLES_VERSION, + .orig_opts = NULL, + .opts = NULL, + .exit_err = NULL, +}; + +int main(int argc, char **argv) +{ + xtables_init_all(&test_globals, NFPROTO_IPV4); + return 0; +} + +EOF + +if gcc -I$INCLUDE $IPTC -o /tmp/ipttest /tmp/ipttest.c $IPTL -ldl -lxtables >/dev/null 2>&1 +then + echo "TC_CONFIG_XT:=y" >>Config + echo "using xtables" +fi +rm -f /tmp/ipttest.c /tmp/ipttest +} + +check_xt_old() +{ +# bail if previous XT checks has already succeded. +if grep TC_CONFIG_XT Config > /dev/null +then + return +fi #check if we need dont our internal header .. cat >/tmp/ipttest.c </dev/null 2>&1 if [ $? -eq 0 ] then - echo "TC_CONFIG_XT:=y" >>Config - echo "using xtables seems no need for internal.h" -else - echo "failed test 2" + echo "TC_CONFIG_XT_OLD:=y" >>Config + echo "using old xtables (no need for xt-internal.h)" +fi +rm -f /tmp/ipttest.c /tmp/ipttest +} + +check_xt_old_internal_h() +{ +# bail if previous XT checks has already succeded. +if grep TC_CONFIG_XT Config > /dev/null +then + return fi #check if we need our own internal.h @@ -85,10 +128,30 @@ gcc -I$INCLUDE $IPTC -o /tmp/ipttest /tmp/ipttest.c $IPTL -ldl >/dev/null 2>&1 if [ $? -eq 0 ] then - echo "using xtables instead of iptables (need for internal.h)" - echo "TC_CONFIG_XT_H:=y" >>Config - -else - echo "failed test 3 using iptables" + echo "using old xtables with xt-internal.h" + echo "TC_CONFIG_XT_OLD_H:=y" >>Config fi rm -f /tmp/ipttest.c /tmp/ipttest +} + +check_ipt() +{ + if ! grep TC_CONFIG_XT Config > /dev/null + then + echo "using iptables" + fi +} + +echo "# Generated config based on" $INCLUDE >Config + +echo "TC schedulers" + +echo -n " ATM " +check_atm + +echo -n " IPT " +check_xt +check_xt_old +check_xt_old_internal_h +check_ipt + diff --git a/doc/ip-cref.tex b/doc/ip-cref.tex index bb4eb783..056e3bf5 100644 --- a/doc/ip-cref.tex +++ b/doc/ip-cref.tex @@ -1324,8 +1324,25 @@ peers are allowed to send to us. If it is not given, Linux uses the value selected with \verb|sysctl| variable \verb|net/ipv4/tcp_reordering|. +\item \verb|hoplimit NUMBER| +--- [2.5.74+ only] Maximum number of hops on the path to this destination. + The default is the value selected with the \verb|sysctl| variable + \verb|net/ipv4/ip_default_ttl|. +\item \verb|initcwnd NUMBER| +--- [2.5.70+ only] 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~\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 @@ -1380,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} @@ -2653,6 +2662,9 @@ http://www.cisco.com/univercd/cc/td/doc/product/software/ios120. \bibitem{RFC-DHCP} R.~Droms. ``Dynamic Host Configuration Protocol.'', RFC-2131 +\bibitem{RFC2414} M.~Allman, S.~Floyd, C.~Partridge. +``Increasing TCP's Initial Window'', RFC-2414. + \end{thebibliography} diff --git a/genl/Makefile b/genl/Makefile index 64358755..44bb83cd 100644 --- a/genl/Makefile +++ b/genl/Makefile @@ -1,6 +1,7 @@ GENLOBJ=genl.o include ../Config +SHARED_LIBS ?= y GENLMODULES := GENLMODULES += ctrl.o @@ -9,8 +10,10 @@ GENLOBJ += $(GENLMODULES) GENLLIB := +ifeq ($(SHARED_LIBS),y) LDFLAGS += -Wl,-export-dynamic LDLIBS += -lm -ldl +endif all: genl @@ -21,3 +24,15 @@ install: all clean: rm -f $(GENLOBJ) $(GENLLIB) genl + +ifneq ($(SHARED_LIBS),y) + +genl: static-syms.o +static-syms.o: static-syms.h +static-syms.h: $(wildcard *.c) + files="$^" ; \ + for s in `grep -B 3 '\ $@ + +endif diff --git a/genl/static-syms.c b/genl/static-syms.c new file mode 100644 index 00000000..1ed3a8a9 --- /dev/null +++ b/genl/static-syms.c @@ -0,0 +1,6 @@ +#include +void *_dlsym(const char *sym) +{ +#include "static-syms.h" + return NULL; +} diff --git a/include/SNAPSHOT.h b/include/SNAPSHOT.h index 4001bf09..f07d1e71 100644 --- a/include/SNAPSHOT.h +++ b/include/SNAPSHOT.h @@ -1 +1 @@ -static const char SNAPSHOT[] = "090324"; +static const char SNAPSHOT[] = "100224"; diff --git a/include/dlfcn.h b/include/dlfcn.h new file mode 100644 index 00000000..b0be5a0f --- /dev/null +++ b/include/dlfcn.h @@ -0,0 +1,39 @@ +/* + * Stub dlfcn implementation for systems that lack shared library support + * but obviously can still reference compiled-in symbols. + */ + +#ifndef NO_SHARED_LIBS +#include_next +#else + +#define RTLD_LAZY 0 +#define _FAKE_DLFCN_HDL (void *)0xbeefcafe + +static inline void *dlopen(const char *file, int flag) +{ + if (file == NULL) + return _FAKE_DLFCN_HDL; + else + return NULL; +} + +extern void *_dlsym(const char *sym); +static inline void *dlsym(void *handle, const char *sym) +{ + if (handle != _FAKE_DLFCN_HDL) + return NULL; + return _dlsym(sym); +} + +static inline char *dlerror(void) +{ + return NULL; +} + +static inline int dlclose(void *handle) +{ + return (handle == _FAKE_DLFCN_HDL) ? 0 : 1; +} + +#endif diff --git a/include/libnetlink.h b/include/libnetlink.h index 0e024682..07bd707e 100644 --- a/include/libnetlink.h +++ b/include/libnetlink.h @@ -17,6 +17,8 @@ struct rtnl_handle __u32 dump; }; +extern int rcvbuf; + extern int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions); extern int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, int protocol); extern void rtnl_close(struct rtnl_handle *rth); @@ -25,10 +27,22 @@ extern int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int l typedef int (*rtnl_filter_t)(const struct sockaddr_nl *, struct nlmsghdr *n, void *); + +struct rtnl_dump_filter_arg +{ + rtnl_filter_t filter; + void *arg1; + rtnl_filter_t junk; + void *arg2; +}; + +extern int rtnl_dump_filter_l(struct rtnl_handle *rth, + const struct rtnl_dump_filter_arg *arg); extern int rtnl_dump_filter(struct rtnl_handle *rth, rtnl_filter_t filter, void *arg1, rtnl_filter_t junk, void *arg2); + extern int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, unsigned groups, struct nlmsghdr *answer, rtnl_filter_t junk, 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 @@ -69,6 +69,14 @@ enum can_state { CAN_STATE_MAX }; +/* + * CAN bus error counters + */ +struct can_berr_counter { + __u16 txerr; + __u16 rxerr; +}; + /* * CAN controller mode */ @@ -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/if.h b/include/linux/if.h index 010a0d29..51fcf6a4 100644 --- a/include/linux/if.h +++ b/include/linux/if.h @@ -70,6 +70,7 @@ #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 IF_GET_IFACE 0x0001 /* for querying only */ #define IF_GET_PROTO 0x0002 @@ -125,8 +126,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 +136,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 +160,7 @@ struct if_settings * remainder may be interface specific. */ -struct ifreq -{ +struct ifreq { #define IFHWADDRLEN 6 union { @@ -211,11 +209,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 08ea9800..58b39f47 100644 --- a/include/linux/if_addr.h +++ b/include/linux/if_addr.h @@ -4,8 +4,7 @@ #include #include -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, @@ -41,13 +39,13 @@ enum #define IFA_F_NODAD 0x02 #define IFA_F_OPTIMISTIC 0x04 +#define IFA_F_DADFAILED 0x08 #define IFA_F_HOMEADDRESS 0x10 #define IFA_F_DEPRECATED 0x20 #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 -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 f1869439..cafee458 100644 --- a/include/linux/if_arp.h +++ b/include/linux/if_arp.h @@ -87,7 +87,6 @@ #define ARPHRD_IEEE80211_PRISM 802 /* IEEE 802.11 + Prism2 header */ #define ARPHRD_IEEE80211_RADIOTAP 803 /* IEEE 802.11 + radiotap header */ #define ARPHRD_IEEE802154 804 -#define ARPHRD_IEEE802154_PHY 805 #define ARPHRD_PHONET 820 /* PhoNet media type */ #define ARPHRD_PHONET_PIPE 821 /* PhoNet pipe header */ @@ -134,8 +133,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_link.h b/include/linux/if_link.h index b0b9e8a6..5110b96a 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h @@ -5,8 +5,7 @@ #include /* 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 */ @@ -39,8 +38,7 @@ struct rtnl_link_stats }; /* 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 +47,7 @@ struct rtnl_link_ifmap __u8 port; }; -enum -{ +enum { IFLA_UNSPEC, IFLA_ADDRESS, IFLA_BROADCAST, @@ -81,6 +78,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_VF_MAC, /* Hardware queue specific attributes */ + IFLA_VF_VLAN, + IFLA_VF_TX_RATE, /* TX Bandwidth Allocation */ + IFLA_VFINFO, __IFLA_MAX }; @@ -121,8 +123,7 @@ enum */ /* Subtype attributes for IFLA_PROTINFO */ -enum -{ +enum { IFLA_INET6_UNSPEC, IFLA_INET6_FLAGS, /* link flags */ IFLA_INET6_CONF, /* sysctl parameters */ @@ -135,16 +136,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 +155,7 @@ enum /* VLAN section */ -enum -{ +enum { IFLA_VLAN_UNSPEC, IFLA_VLAN_ID, IFLA_VLAN_FLAGS, @@ -173,8 +171,7 @@ struct ifla_vlan_flags { __u32 mask; }; -enum -{ +enum { IFLA_VLAN_QOS_UNSPEC, IFLA_VLAN_QOS_MAPPING, __IFLA_VLAN_QOS_MAX @@ -182,10 +179,49 @@ 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 */ + +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; +}; #endif /* _LINUX_IF_LINK_H */ diff --git a/include/linux/if_tunnel.h b/include/linux/if_tunnel.h index 92290759..6c8d1d1e 100644 --- a/include/linux/if_tunnel.h +++ b/include/linux/if_tunnel.h @@ -12,6 +12,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 +26,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; @@ -41,15 +44,21 @@ struct ip_tunnel_prl { __u16 flags; __u16 __reserved; __u32 datalen; - __u32 rs_delay; + __u32 __reserved2; /* data follows */ }; /* 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 #include -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 2faed2a9..3dbf0cc4 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -28,23 +28,18 @@ #include #include #include +#include #define MAX_ADDR_LEN 32 /* Largest hardware address length */ -/* Driver transmit return codes */ -#define NETDEV_TX_OK 0 /* driver took care of packet */ -#define NETDEV_TX_BUSY 1 /* driver tx path was busy*/ -#define NETDEV_TX_LOCKED -1 /* driver tx lock was already taken */ - /* * Network device statistics. Akin to the 2.0 ether stats but * 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..1616f4fb 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -6,8 +6,7 @@ #define XT_FUNCTION_MAXNAMELEN 30 #define XT_TABLE_MAXNAMELEN 32 -struct xt_entry_match -{ +struct xt_entry_match { union { struct { __u16 match_size; @@ -31,8 +30,7 @@ struct xt_entry_match unsigned char data[0]; }; -struct xt_entry_target -{ +struct xt_entry_target { union { struct { __u16 target_size; @@ -64,16 +62,14 @@ 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 -{ +struct xt_get_revision { char name[XT_FUNCTION_MAXNAMELEN-1]; __u8 revision; @@ -90,16 +86,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((s), __alignof__(struct _xt_align)) /* Standard return verdict, or do jump. */ #define XT_STANDARD_TARGET "" @@ -109,14 +103,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 +164,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 /* 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 63d1c697..e94981d8 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -104,7 +104,7 @@ enum { RTM_NEWADDRLABEL = 72, #define RTM_NEWADDRLABEL RTM_NEWADDRLABEL RTM_DELADDRLABEL, -#define RTM_NEWADDRLABEL RTM_NEWADDRLABEL +#define RTM_DELADDRLABEL RTM_DELADDRLABEL RTM_GETADDRLABEL, #define RTM_GETADDRLABEL RTM_GETADDRLABEL @@ -127,8 +127,7 @@ enum { with attribute type. */ -struct rtattr -{ +struct rtattr { unsigned short rta_len; unsigned short rta_type; }; @@ -154,8 +153,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 +169,7 @@ struct rtmsg /* rtm_type */ -enum -{ +enum { RTN_UNSPEC, RTN_UNICAST, /* Gateway or direct route */ RTN_LOCAL, /* Accept locally */ @@ -230,8 +227,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 +245,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 +258,7 @@ enum rt_class_t /* Routing message attributes */ -enum rtattr_type_t -{ +enum rtattr_type_t { RTA_UNSPEC, RTA_DST, RTA_SRC, @@ -298,8 +292,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 +318,7 @@ struct rtnexthop /* RTM_CACHEINFO */ -struct rta_cacheinfo -{ +struct rta_cacheinfo { __u32 rta_clntref; __u32 rta_lastuse; __s32 rta_expires; @@ -341,8 +333,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 +362,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 +374,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 +399,7 @@ struct rta_session * General form of address family dependent message. ****/ -struct rtgenmsg -{ +struct rtgenmsg { unsigned char rtgen_family; }; @@ -421,8 +412,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 +425,7 @@ struct ifinfomsg * prefix information ****/ -struct prefixmsg -{ +struct prefixmsg { unsigned char prefix_family; unsigned char prefix_pad1; unsigned short prefix_pad2; @@ -457,8 +446,7 @@ enum #define PREFIX_MAX (__PREFIX_MAX - 1) -struct prefix_cacheinfo -{ +struct prefix_cacheinfo { __u32 preferred_time; __u32 valid_time; }; @@ -468,8 +456,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 +466,7 @@ struct tcmsg __u32 tcm_info; }; -enum -{ +enum { TCA_UNSPEC, TCA_KIND, TCA_OPTIONS, @@ -502,8 +488,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 +500,7 @@ struct nduseroptmsg /* Followed by one or more ND options */ }; -enum -{ +enum { NDUSEROPT_UNSPEC, NDUSEROPT_SRCADDR, __NDUSEROPT_MAX @@ -596,8 +580,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/socket.h b/include/linux/socket.h index dff22f98..1057869e 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -16,291 +16,4 @@ struct __kernel_sockaddr_storage { /* _SS_MAXSIZE value minus size of ss_family */ } __attribute__ ((aligned(_K_SS_ALIGNSIZE))); /* force desired alignment */ -#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) - -#include /* arch-dependent defines */ -#include /* the SIOCxxx I/O controls */ -#include /* iovec support */ -#include /* pid_t */ - /* */ - - -typedef unsigned short sa_family_t; - -/* - * 1003.1g requires sa_family_t and that sa_data is char. - */ - -struct sockaddr { - sa_family_t sa_family; /* address family, AF_xxx */ - char sa_data[14]; /* 14 bytes of protocol address */ -}; - -struct linger { - int l_onoff; /* Linger active */ - int l_linger; /* How long to linger for */ -}; - -#define sockaddr_storage __kernel_sockaddr_storage - -/* - * As we do 4.4BSD message passing we use a 4.4BSD message passing - * system, not 4.3. Thus msg_accrights(len) are now missing. They - * belong in an obscure libc emulation or the bin. - */ - -struct msghdr { - void * msg_name; /* Socket name */ - int msg_namelen; /* Length of name */ - struct iovec * msg_iov; /* Data blocks */ - __kernel_size_t msg_iovlen; /* Number of blocks */ - void * msg_control; /* Per protocol magic (eg BSD file descriptor passing) */ - __kernel_size_t msg_controllen; /* Length of cmsg list */ - unsigned msg_flags; -}; - -/* - * POSIX 1003.1g - ancillary data object information - * Ancillary data consits of a sequence of pairs of - * (cmsghdr, cmsg_data[]) - */ - -struct cmsghdr { - __kernel_size_t cmsg_len; /* data byte count, including hdr */ - int cmsg_level; /* originating protocol */ - int cmsg_type; /* protocol-specific type */ -}; - -/* - * Ancilliary data object information MACROS - * Table 5-14 of POSIX 1003.1g - */ - -#define __CMSG_NXTHDR(ctl, len, cmsg) __cmsg_nxthdr((ctl),(len),(cmsg)) -#define CMSG_NXTHDR(mhdr, cmsg) cmsg_nxthdr((mhdr), (cmsg)) - -#define CMSG_ALIGN(len) ( ((len)+sizeof(long)-1) & ~(sizeof(long)-1) ) - -#define CMSG_DATA(cmsg) ((void *)((char *)(cmsg) + CMSG_ALIGN(sizeof(struct cmsghdr)))) -#define CMSG_SPACE(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + CMSG_ALIGN(len)) -#define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (len)) - -#define __CMSG_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr) ? \ - (struct cmsghdr *)(ctl) : \ - (struct cmsghdr *)NULL) -#define CMSG_FIRSTHDR(msg) __CMSG_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen) -#define CMSG_OK(mhdr, cmsg) ((cmsg)->cmsg_len >= sizeof(struct cmsghdr) && \ - (cmsg)->cmsg_len <= (unsigned long) \ - ((mhdr)->msg_controllen - \ - ((char *)(cmsg) - (char *)(mhdr)->msg_control))) - -/* - * This mess will go away with glibc - */ - -#if defined(__GNUC__) -#define __KINLINE static __inline__ -#elif defined(__cplusplus) -#define __KINLINE static __inline__ -#else -#define __KINLINE static -#endif - - -/* - * Get the next cmsg header - * - * PLEASE, do not touch this function. If you think, that it is - * incorrect, grep kernel sources and think about consequences - * before trying to improve it. - * - * Now it always returns valid, not truncated ancillary object - * HEADER. But caller still MUST check, that cmsg->cmsg_len is - * inside range, given by msg->msg_controllen before using - * ancillary object DATA. --ANK (980731) - */ - -__KINLINE struct cmsghdr * __cmsg_nxthdr(void *__ctl, __kernel_size_t __size, - struct cmsghdr *__cmsg) -{ - struct cmsghdr * __ptr; - - __ptr = (struct cmsghdr*)(((unsigned char *) __cmsg) + CMSG_ALIGN(__cmsg->cmsg_len)); - if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size) - return (struct cmsghdr *)0; - - return __ptr; -} - -__KINLINE struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr *__cmsg) -{ - return __cmsg_nxthdr(__msg->msg_control, __msg->msg_controllen, __cmsg); -} - -/* "Socket"-level control message types: */ - -#define SCM_RIGHTS 0x01 /* rw: access rights (array of int) */ -#define SCM_CREDENTIALS 0x02 /* rw: struct ucred */ -#define SCM_SECURITY 0x03 /* rw: security label */ - -struct ucred { - __u32 pid; - __u32 uid; - __u32 gid; -}; - -/* Supported address families. */ -#define AF_UNSPEC 0 -#define AF_UNIX 1 /* Unix domain sockets */ -#define AF_LOCAL 1 /* POSIX name for AF_UNIX */ -#define AF_INET 2 /* Internet IP Protocol */ -#define AF_AX25 3 /* Amateur Radio AX.25 */ -#define AF_IPX 4 /* Novell IPX */ -#define AF_APPLETALK 5 /* AppleTalk DDP */ -#define AF_NETROM 6 /* Amateur Radio NET/ROM */ -#define AF_BRIDGE 7 /* Multiprotocol bridge */ -#define AF_ATMPVC 8 /* ATM PVCs */ -#define AF_X25 9 /* Reserved for X.25 project */ -#define AF_INET6 10 /* IP version 6 */ -#define AF_ROSE 11 /* Amateur Radio X.25 PLP */ -#define AF_DECnet 12 /* Reserved for DECnet project */ -#define AF_NETBEUI 13 /* Reserved for 802.2LLC project*/ -#define AF_SECURITY 14 /* Security callback pseudo AF */ -#define AF_KEY 15 /* PF_KEY key management API */ -#define AF_NETLINK 16 -#define AF_ROUTE AF_NETLINK /* Alias to emulate 4.4BSD */ -#define AF_PACKET 17 /* Packet family */ -#define AF_ASH 18 /* Ash */ -#define AF_ECONET 19 /* Acorn Econet */ -#define AF_ATMSVC 20 /* ATM SVCs */ -#define AF_RDS 21 /* RDS sockets */ -#define AF_SNA 22 /* Linux SNA Project (nutters!) */ -#define AF_IRDA 23 /* IRDA sockets */ -#define AF_PPPOX 24 /* PPPoX sockets */ -#define AF_WANPIPE 25 /* Wanpipe API Sockets */ -#define AF_LLC 26 /* Linux LLC */ -#define AF_CAN 29 /* Controller Area Network */ -#define AF_TIPC 30 /* TIPC sockets */ -#define AF_BLUETOOTH 31 /* Bluetooth sockets */ -#define AF_IUCV 32 /* IUCV sockets */ -#define AF_RXRPC 33 /* RxRPC sockets */ -#define AF_ISDN 34 /* mISDN sockets */ -#define AF_PHONET 35 /* Phonet sockets */ -#define AF_IEEE802154 36 /* IEEE802154 sockets */ -#define AF_MAX 37 /* For now.. */ - -/* Protocol families, same as address families. */ -#define PF_UNSPEC AF_UNSPEC -#define PF_UNIX AF_UNIX -#define PF_LOCAL AF_LOCAL -#define PF_INET AF_INET -#define PF_AX25 AF_AX25 -#define PF_IPX AF_IPX -#define PF_APPLETALK AF_APPLETALK -#define PF_NETROM AF_NETROM -#define PF_BRIDGE AF_BRIDGE -#define PF_ATMPVC AF_ATMPVC -#define PF_X25 AF_X25 -#define PF_INET6 AF_INET6 -#define PF_ROSE AF_ROSE -#define PF_DECnet AF_DECnet -#define PF_NETBEUI AF_NETBEUI -#define PF_SECURITY AF_SECURITY -#define PF_KEY AF_KEY -#define PF_NETLINK AF_NETLINK -#define PF_ROUTE AF_ROUTE -#define PF_PACKET AF_PACKET -#define PF_ASH AF_ASH -#define PF_ECONET AF_ECONET -#define PF_ATMSVC AF_ATMSVC -#define PF_RDS AF_RDS -#define PF_SNA AF_SNA -#define PF_IRDA AF_IRDA -#define PF_PPPOX AF_PPPOX -#define PF_WANPIPE AF_WANPIPE -#define PF_LLC AF_LLC -#define PF_CAN AF_CAN -#define PF_TIPC AF_TIPC -#define PF_BLUETOOTH AF_BLUETOOTH -#define PF_IUCV AF_IUCV -#define PF_RXRPC AF_RXRPC -#define PF_ISDN AF_ISDN -#define PF_PHONET AF_PHONET -#define PF_IEEE802154 AF_IEEE802154 -#define PF_MAX AF_MAX - -/* Maximum queue length specifiable by listen. */ -#define SOMAXCONN 128 - -/* Flags we can use with send/ and recv. - Added those for 1003.1g not all are supported yet - */ - -#define MSG_OOB 1 -#define MSG_PEEK 2 -#define MSG_DONTROUTE 4 -#define MSG_TRYHARD 4 /* Synonym for MSG_DONTROUTE for DECnet */ -#define MSG_CTRUNC 8 -#define MSG_PROBE 0x10 /* Do not send. Only probe path f.e. for MTU */ -#define MSG_TRUNC 0x20 -#define MSG_DONTWAIT 0x40 /* Nonblocking io */ -#define MSG_EOR 0x80 /* End of record */ -#define MSG_WAITALL 0x100 /* Wait for a full request */ -#define MSG_FIN 0x200 -#define MSG_SYN 0x400 -#define MSG_CONFIRM 0x800 /* Confirm path validity */ -#define MSG_RST 0x1000 -#define MSG_ERRQUEUE 0x2000 /* Fetch message from error queue */ -#define MSG_NOSIGNAL 0x4000 /* Do not generate SIGPIPE */ -#define MSG_MORE 0x8000 /* Sender will send more */ - -#define MSG_EOF MSG_FIN - -#define MSG_CMSG_CLOEXEC 0x40000000 /* Set close_on_exit for file - descriptor received through - SCM_RIGHTS */ -#if defined(CONFIG_COMPAT) -#define MSG_CMSG_COMPAT 0x80000000 /* This message needs 32 bit fixups */ -#else -#define MSG_CMSG_COMPAT 0 /* We never have 32 bit fixups */ -#endif - - -/* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */ -#define SOL_IP 0 -/* #define SOL_ICMP 1 No-no-no! Due to Linux :-) we cannot use SOL_ICMP=1 */ -#define SOL_TCP 6 -#define SOL_UDP 17 -#define SOL_IPV6 41 -#define SOL_ICMPV6 58 -#define SOL_SCTP 132 -#define SOL_UDPLITE 136 /* UDP-Lite (RFC 3828) */ -#define SOL_RAW 255 -#define SOL_IPX 256 -#define SOL_AX25 257 -#define SOL_ATALK 258 -#define SOL_NETROM 259 -#define SOL_ROSE 260 -#define SOL_DECNET 261 -#define SOL_X25 262 -#define SOL_PACKET 263 -#define SOL_ATM 264 /* ATM layer (cell level) */ -#define SOL_AAL 265 /* ATM Adaption Layer (packet level) */ -#define SOL_IRDA 266 -#define SOL_NETBEUI 267 -#define SOL_LLC 268 -#define SOL_DCCP 269 -#define SOL_NETLINK 270 -#define SOL_TIPC 271 -#define SOL_RXRPC 272 -#define SOL_PPPOL2TP 273 -#define SOL_BLUETOOTH 274 -#define SOL_PNPIPE 275 -#define SOL_RDS 276 -#define SOL_IUCV 277 - -/* IPX options */ -#define IPX_TYPE 1 - -#endif /* not kernel and not glibc */ #endif /* _LINUX_SOCKET_H */ 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 #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 #include -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 #include -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 #include -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/include/ll_map.h b/include/ll_map.h index c4d5c6d1..752b8279 100644 --- a/include/ll_map.h +++ b/include/ll_map.h @@ -9,5 +9,7 @@ extern const char *ll_index_to_name(unsigned idx); extern const char *ll_idx_n2a(unsigned idx, char *buf); extern int ll_index_to_type(unsigned idx); extern unsigned ll_index_to_flags(unsigned idx); +extern unsigned ll_index_to_addr(unsigned idx, unsigned char *addr, + unsigned alen); #endif /* __LL_MAP_H__ */ diff --git a/ip/Makefile b/ip/Makefile index fd16fe94..2f223ca6 100644 --- a/ip/Makefile +++ b/ip/Makefile @@ -2,7 +2,8 @@ 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 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 @@ -23,6 +24,20 @@ install: all clean: rm -f $(ALLOBJ) $(TARGETS) -LDLIBS += -ldl +SHARED_LIBS ?= y +ifeq ($(SHARED_LIBS),y) +LDLIBS += -ldl LDFLAGS += -Wl,-export-dynamic + +else + +ip: static-syms.o +static-syms.o: static-syms.h +static-syms.h: $(wildcard *.c) + files="$^" ; \ + for s in `grep -B 3 '\ $@ + +endif diff --git a/ip/ip.c b/ip/ip.c index d846a763..e0cf1753 100644 --- a/ip/ip.c +++ b/ip/ip.c @@ -7,11 +7,6 @@ * 2 of the License, or (at your option) any later version. * * Authors: Alexey Kuznetsov, - * - * - * Changes: - * - * Rani Assaf 980929: resolve addresses */ #include @@ -50,7 +45,8 @@ static void usage(void) " tunnel | tuntap | maddr | mroute | 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"); +" -o[neline] | -t[imestamp] | -b[atch] [filename] |\n" +" -rc[vbuf] [size]}\n"); exit(-1); } @@ -102,7 +98,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) { @@ -117,6 +112,7 @@ static int batch(const char *name) return -1; } + cmdlineno = 0; while (getcmdline(&line, &len, stdin) != -1) { char *largv[100]; int largc; @@ -126,7 +122,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; @@ -215,6 +211,19 @@ int main(int argc, char **argv) if (argc <= 1) usage(); batch_file = argv[1]; + } else if (matches(opt, "-rcvbuf") == 0) { + unsigned int size; + + argc--; + argv++; + if (argc <= 1) + usage(); + if (get_unsigned(&size, argv[1], 0)) { + fprintf(stderr, "Invalid rcvbuf size '%s'\n", + argv[1]); + exit(-1); + } + rcvbuf = size; } else if (matches(opt, "-help") == 0) { usage(); } else { diff --git a/ip/ip6tunnel.c b/ip/ip6tunnel.c index 8852a67a..203e4a3a 100644 --- a/ip/ip6tunnel.c +++ b/ip/ip6tunnel.c @@ -15,11 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* - * based on: - * $Id: s.ipv6tunnel.c 1.7 02/12/11 11:21:51+02:00 antti@traci.mipl.mediapoli.com $ - * - */ /* * Author: * Masahide NAKAMURA @USAGI diff --git a/ip/ipaddress.c b/ip/ipaddress.c index 267ecb36..3186f9cb 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -8,8 +8,6 @@ * * Authors: Alexey Kuznetsov, * - * Changes: - * Laszlo Valko 990223: address label must be zero terminated */ #include @@ -64,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"); @@ -74,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"); @@ -332,6 +331,31 @@ int print_linkinfo(const struct sockaddr_nl *who, ); } } + if (do_link && tb[IFLA_VFINFO] && tb[IFLA_NUM_VF]) { + SPRINT_BUF(b1); + struct rtattr *rta = tb[IFLA_VFINFO]; + struct ifla_vf_info *ivi; + int i; + for (i = 0; i < *(int *)RTA_DATA(tb[IFLA_NUM_VF]); i++) { + if (rta->rta_type != IFLA_VFINFO) { + fprintf(stderr, "BUG: rta type is %d\n", rta->rta_type); + break; + } + ivi = RTA_DATA(rta); + fprintf(fp, "\n vf %d: MAC %s", + ivi->vf, + ll_addr_n2a((unsigned char *)&ivi->mac, + ETH_ALEN, 0, b1, sizeof(b1))); + if (ivi->vlan) + fprintf(fp, ", vlan %d", ivi->vlan); + if (ivi->qos) + fprintf(fp, ", qos %d", ivi->qos); + if (ivi->tx_rate) + fprintf(fp, ", tx rate %d (Mbps_", + ivi->tx_rate); + rta = (struct rtattr *)((char *)rta + RTA_ALIGN(rta->rta_len)); + } + } fprintf(fp, "\n"); fflush(fp); return 0; @@ -485,7 +509,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; @@ -508,6 +535,10 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, fprintf(fp, "dynamic "); } else ifa->ifa_flags &= ~IFA_F_PERMANENT; + if (ifa->ifa_flags&IFA_F_DADFAILED) { + ifa->ifa_flags &= ~IFA_F_DADFAILED; + fprintf(fp, "dadfailed "); + } if (ifa->ifa_flags) fprintf(fp, "flags %02x ", ifa->ifa_flags); if (rta_tb[IFA_LABEL]) @@ -537,6 +568,27 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, return 0; } +int print_addrinfo_primary(const struct sockaddr_nl *who, struct nlmsghdr *n, + void *arg) +{ + struct ifaddrmsg *ifa = NLMSG_DATA(n); + + if (!ifa->ifa_flags & IFA_F_SECONDARY) + return 0; + + return print_addrinfo(who, n, arg); +} + +int print_addrinfo_secondary(const struct sockaddr_nl *who, struct nlmsghdr *n, + void *arg) +{ + struct ifaddrmsg *ifa = NLMSG_DATA(n); + + if (ifa->ifa_flags & IFA_F_SECONDARY) + return 0; + + return print_addrinfo(who, n, arg); +} struct nlmsg_list { @@ -637,7 +689,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) { @@ -655,6 +708,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; @@ -698,12 +754,32 @@ static int ipaddr_list_or_flush(int argc, char **argv, int flush) filter.flushe = sizeof(flushb); while (round < MAX_ROUNDS) { + const struct rtnl_dump_filter_arg a[3] = { + { + .filter = print_addrinfo_secondary, + .arg1 = stdout, + .junk = NULL, + .arg2 = NULL + }, + { + .filter = print_addrinfo_primary, + .arg1 = stdout, + .junk = NULL, + .arg2 = NULL + }, + { + .filter = NULL, + .arg1 = NULL, + .junk = NULL, + .arg2 = NULL + }, + }; if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) { perror("Cannot send dump request"); exit(1); } filter.flushed = 0; - if (rtnl_dump_filter(&rth, print_addrinfo, stdout, NULL, NULL) < 0) { + if (rtnl_dump_filter_l(&rth, a) < 0) { fprintf(stderr, "Flush terminated\n"); exit(1); } diff --git a/ip/iplink.c b/ip/iplink.c index 32cce240..97fca8be 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()) { @@ -181,6 +184,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 +282,54 @@ 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) { + NEXT_ARG(); + if (get_integer(&vf, *argv, 0)) { + invarg("Invalid \"vf\" value\n", *argv); + } + } else if (matches(*argv, "mac") == 0) { + struct ifla_vf_mac ivm; + NEXT_ARG(); + if (vf < 0) { + missarg("vf"); + } + 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 (vf < 0) { + missarg("vf"); + } + 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); + } + } + } + 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 (vf < 0) { + missarg("vf"); + } + 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)); #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 + * Arnd Bergmann + */ + +#include +#include +#include +#include +#include + +#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/ipmroute.c b/ip/ipmroute.c index 8f4b0612..977143cc 100644 --- a/ip/ipmroute.c +++ b/ip/ipmroute.c @@ -95,7 +95,8 @@ static void read_mroute_list(FILE *ofp) char obuf[256]; oiflist[0] = 0; - if (sscanf(buf, "%x%x%d%u%u%u%s", maddr.data, msrc.data, &vifi, + if (sscanf(buf, "%x%x%d%u%u%u %[^\n]", + maddr.data, msrc.data, &vifi, &pkts, &b, &w, oiflist) < 6) continue; diff --git a/ip/ipneigh.c b/ip/ipneigh.c index 30c7c72d..2d96ab7c 100644 --- a/ip/ipneigh.c +++ b/ip/ipneigh.c @@ -8,10 +8,6 @@ * * Authors: Alexey Kuznetsov, * - * - * Changes: - * - * Rani Assaf 980929: resolve addresses */ #include diff --git a/ip/iproute.c b/ip/iproute.c index bf0f31bd..8252e182 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -8,11 +8,6 @@ * * Authors: Alexey Kuznetsov, * - * - * Changes: - * - * Rani Assaf 980929: resolve addresses - * Kunihiro Ishiguro 001102: rtnh_ifindex was not initialized */ #include @@ -51,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)); @@ -70,15 +66,14 @@ static void usage(void) fprintf(stderr, "INFO_SPEC := NH OPTIONS FLAGS [ nexthop NH ]...\n"); fprintf(stderr, "NH := [ via ADDRESS ] [ dev STRING ] [ weight NUMBER ] NHFLAGS\n"); fprintf(stderr, "OPTIONS := FLAGS [ mtu NUMBER ] [ advmss NUMBER ]\n"); - fprintf(stderr, " [ rtt TIME ] [ rttvar TIME ]\n"); + 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 ]\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"); @@ -387,8 +382,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 "); @@ -428,9 +421,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]) { @@ -768,6 +759,18 @@ int iproute_modify(int cmd, unsigned flags, int argc, char **argv) if (get_unsigned(&mtu, *argv, 0)) invarg("\"mtu\" value is invalid\n", *argv); rta_addattr32(mxrta, sizeof(mxbuf), RTAX_MTU, mtu); +#ifdef RTAX_HOPLIMIT + } else if (strcmp(*argv, "hoplimit") == 0) { + unsigned hoplimit; + NEXT_ARG(); + if (strcmp(*argv, "lock") == 0) { + mxlock |= (1< * - * - * Changes: - * - * Rani Assaf 980929: resolve addresses */ #include @@ -38,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"); @@ -146,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] "); } @@ -311,6 +313,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(); diff --git a/ip/iptunnel.c b/ip/iptunnel.c index 338d8bdf..1cd9fbd6 100644 --- a/ip/iptunnel.c +++ b/ip/iptunnel.c @@ -8,12 +8,6 @@ * * Authors: Alexey Kuznetsov, * - * - * Changes: - * - * Rani Assaf 980929: resolve addresses - * Rani Assaf 980930: do not allow key for ipip/sit - * Phil Karn 990408: "pmtudisc" flag */ #include @@ -38,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"); @@ -308,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)); @@ -368,6 +365,17 @@ static void print_tunnel(struct ip_tunnel_parm *p) if (!(p->iph.frag_off&htons(IP_DF))) printf(" nopmtudisc"); + if (!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) { @@ -534,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) { @@ -567,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/ipxfrm.c b/ip/ipxfrm.c index 708ce9fe..78e1926d 100644 --- a/ip/ipxfrm.c +++ b/ip/ipxfrm.c @@ -351,16 +351,12 @@ void xfrm_stats_print(struct xfrm_stats *s, FILE *fp, const char *prefix) { if (prefix) fputs(prefix, fp); - fprintf(fp, "stats:"); - fprintf(fp, "%s", _SL_); + fprintf(fp, "stats:%s", _SL_); if (prefix) fputs(prefix, fp); - fprintf(fp, " "); - fprintf(fp, "replay-window %u ", s->replay_window); - fprintf(fp, "replay %u ", s->replay); - fprintf(fp, "failed %u", s->integrity_failed); - fprintf(fp, "%s", _SL_); + fprintf(fp, " replay-window %u replay %u failed %u%s", + s->replay_window, s->replay, s->integrity_failed, _SL_); } static const char *strxf_time(__u64 time) @@ -392,72 +388,52 @@ void xfrm_lifetime_print(struct xfrm_lifetime_cfg *cfg, if (cfg) { if (prefix) fputs(prefix, fp); - fprintf(fp, "lifetime config:"); - fprintf(fp, "%s", _SL_); + fprintf(fp, "lifetime config:%s",_SL_); if (prefix) fputs(prefix, fp); - fprintf(fp, " "); - fprintf(fp, "limit: "); - fprintf(fp, "soft "); - fprintf(fp, strxf_limit(cfg->soft_byte_limit)); - fprintf(fp, "(bytes), hard "); - fprintf(fp, strxf_limit(cfg->hard_byte_limit)); - fprintf(fp, "(bytes)"); - fprintf(fp, "%s", _SL_); + fprintf(fp, " limit: soft %s(bytes),", + strxf_limit(cfg->soft_byte_limit)); + fprintf(fp, " hard %s(bytes)%s", + strxf_limit(cfg->hard_byte_limit), _SL_); if (prefix) fputs(prefix, fp); - fprintf(fp, " "); - fprintf(fp, "limit: "); - fprintf(fp, "soft "); - fprintf(fp, strxf_limit(cfg->soft_packet_limit)); - fprintf(fp, "(packets), hard "); - fprintf(fp, strxf_limit(cfg->hard_packet_limit)); - fprintf(fp, "(packets)"); - fprintf(fp, "%s", _SL_); + fprintf(fp, " limit: soft %s(packets),", + strxf_limit(cfg->soft_packet_limit)); + fprintf(fp, " hard %s(packets)%s", + strxf_limit(cfg->hard_packet_limit), _SL_); if (prefix) fputs(prefix, fp); - fprintf(fp, " "); - fprintf(fp, "expire add: "); - fprintf(fp, "soft "); - fprintf(fp, "%llu", (unsigned long long) cfg->soft_add_expires_seconds); - fprintf(fp, "(sec), hard "); - fprintf(fp, "%llu", (unsigned long long) cfg->hard_add_expires_seconds); - fprintf(fp, "(sec)"); - fprintf(fp, "%s", _SL_); + fprintf(fp, " expire add: soft %llu(sec), hard %llu(sec)%s", + (unsigned long long) cfg->soft_add_expires_seconds, + (unsigned long long) cfg->hard_add_expires_seconds, + _SL_); if (prefix) fputs(prefix, fp); - fprintf(fp, " "); - fprintf(fp, "expire use: "); - fprintf(fp, "soft "); - fprintf(fp, "%llu", (unsigned long long) cfg->soft_use_expires_seconds); - fprintf(fp, "(sec), hard "); - fprintf(fp, "%llu", (unsigned long long) cfg->hard_use_expires_seconds); - fprintf(fp, "(sec)"); - fprintf(fp, "%s", _SL_); + fprintf(fp, " expire use: soft %llu(sec), hard %llu(sec)%s", + (unsigned long long) cfg->soft_use_expires_seconds, + (unsigned long long) cfg->hard_use_expires_seconds, + _SL_); } if (cur) { if (prefix) fputs(prefix, fp); - fprintf(fp, "lifetime current:"); - fprintf(fp, "%s", _SL_); + fprintf(fp, "lifetime current:%s", _SL_); if (prefix) fputs(prefix, fp); - fprintf(fp, " "); - fprintf(fp, "%llu(bytes), ", (unsigned long long) cur->bytes); - fprintf(fp, "%llu(packets)", (unsigned long long) cur->packets); - fprintf(fp, "%s", _SL_); + fprintf(fp, " %llu(bytes), %llu(packets)%s", + (unsigned long long) cur->bytes, + (unsigned long long) cur->packets, + _SL_); if (prefix) fputs(prefix, fp); - fprintf(fp, " "); - fprintf(fp, "add %s ", strxf_time(cur->add_time)); - fprintf(fp, "use %s", strxf_time(cur->use_time)); - fprintf(fp, "%s", _SL_); + fprintf(fp, " add %s ", strxf_time(cur->add_time)); + fprintf(fp, "use %s%s", strxf_time(cur->use_time), _SL_); } } @@ -653,9 +629,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), @@ -764,6 +779,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) @@ -804,6 +820,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/static-syms.c b/ip/static-syms.c new file mode 100644 index 00000000..1ed3a8a9 --- /dev/null +++ b/ip/static-syms.c @@ -0,0 +1,6 @@ +#include +void *_dlsym(const char *sym) +{ +#include "static-syms.h" + return NULL; +} diff --git a/ip/tunnel.c b/ip/tunnel.c index d1296e68..d389e866 100644 --- a/ip/tunnel.c +++ b/ip/tunnel.c @@ -168,7 +168,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) { struct ifreq ifr; int fd; @@ -183,3 +183,18 @@ int tnl_prl_ioctl(int cmd, const char *name, void *p) close(fd); return err; } + +int tnl_prl_ioctl(int cmd, const char *name, void *p) +{ + return tnl_gen_ioctl(cmd, name, p); +} + +int tnl_6rd_ioctl(int cmd, const char *name, void *p) +{ + return tnl_gen_ioctl(cmd, name, p); +} + +int tnl_ioctl_get_6rd(const char *name, void *p) +{ + return tnl_gen_ioctl(SIOCGET6RD, name, p); +} diff --git a/ip/tunnel.h b/ip/tunnel.h index 0661e277..ded226b4 100644 --- a/ip/tunnel.h +++ b/ip/tunnel.h @@ -32,5 +32,7 @@ int tnl_get_ioctl(const char *basedev, void *p); int tnl_add_ioctl(int cmd, const char *basedev, const char *name, void *p); int tnl_del_ioctl(const char *basedev, const char *name, void *p); int tnl_prl_ioctl(int cmd, const char *name, void *p); +int tnl_6rd_ioctl(int cmd, const char *name, void *p); +int tnl_ioctl_get_6rd(const char *name, void *p); #endif diff --git a/ip/xfrm.h b/ip/xfrm.h index 104fb208..d3ca5c53 100644 --- a/ip/xfrm.h +++ b/ip/xfrm.h @@ -121,6 +121,7 @@ int xfrm_xfrmproto_is_ipsec(__u8 proto); int xfrm_xfrmproto_is_ro(__u8 proto); int xfrm_xfrmproto_getbyname(char *name); int xfrm_algotype_getbyname(char *name); +int xfrm_parse_mark(struct xfrm_mark *mark, int *argcp, char ***argvp); const char *strxf_xfrmproto(__u8 proto); const char *strxf_algotype(int type); const char *strxf_mask8(__u8 mask); diff --git a/ip/xfrm_policy.c b/ip/xfrm_policy.c index 11116e5f..121afa13 100644 --- a/ip/xfrm_policy.c +++ b/ip/xfrm_policy.c @@ -54,8 +54,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"); @@ -201,10 +201,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()) @@ -235,6 +235,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)); @@ -258,6 +259,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)) @@ -334,6 +337,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); @@ -515,6 +528,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)); @@ -532,6 +546,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); @@ -584,6 +600,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 b1e3f220..38d40391 100644 --- a/ip/xfrm_state.c +++ b/ip/xfrm_state.c @@ -67,7 +67,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)); @@ -83,7 +83,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"); @@ -210,6 +210,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; @@ -242,6 +246,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)); @@ -260,6 +265,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); @@ -436,6 +443,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: @@ -515,6 +531,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; @@ -538,6 +555,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); @@ -614,6 +633,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); @@ -759,6 +787,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)); @@ -770,26 +799,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/Makefile b/lib/Makefile index bc270bff..da2f0fcb 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,3 +1,4 @@ +CFLAGS += -fPIC UTILOBJ=utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o inet_proto.o diff --git a/lib/libnetlink.c b/lib/libnetlink.c index b68e2fdb..cfeb8941 100644 --- a/lib/libnetlink.c +++ b/lib/libnetlink.c @@ -25,6 +25,8 @@ #include "libnetlink.h" +int rcvbuf = 1024 * 1024; + void rtnl_close(struct rtnl_handle *rth) { if (rth->fd >= 0) { @@ -38,7 +40,6 @@ int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, { socklen_t addr_len; int sndbuf = 32768; - int rcvbuf = 32768; memset(rth, 0, sizeof(*rth)); @@ -137,8 +138,8 @@ int rtnl_send_check(struct rtnl_handle *rth, const char *buf, int len) fprintf(stderr, "ERROR truncated\n"); else errno = -err->error; + return -1; } - return -1; } return 0; @@ -171,11 +172,8 @@ int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) return sendmsg(rth->fd, &msg, 0); } -int rtnl_dump_filter(struct rtnl_handle *rth, - rtnl_filter_t filter, - void *arg1, - rtnl_filter_t junk, - void *arg2) +int rtnl_dump_filter_l(struct rtnl_handle *rth, + const struct rtnl_dump_filter_arg *arg) { struct sockaddr_nl nladdr; struct iovec iov; @@ -190,7 +188,7 @@ int rtnl_dump_filter(struct rtnl_handle *rth, iov.iov_base = buf; while (1) { int status; - struct nlmsghdr *h; + const struct rtnl_dump_filter_arg *a; iov.iov_len = sizeof(buf); status = recvmsg(rth->fd, &msg, 0); @@ -208,40 +206,45 @@ int rtnl_dump_filter(struct rtnl_handle *rth, return -1; } - h = (struct nlmsghdr*)buf; - while (NLMSG_OK(h, status)) { - int err; + for (a = arg; a->filter; a++) { + struct nlmsghdr *h = (struct nlmsghdr*)buf; - if (nladdr.nl_pid != 0 || - h->nlmsg_pid != rth->local.nl_pid || - h->nlmsg_seq != rth->dump) { - if (junk) { - err = junk(&nladdr, h, arg2); - if (err < 0) - return err; - } - goto skip_it; - } + while (NLMSG_OK(h, status)) { + int err; - if (h->nlmsg_type == NLMSG_DONE) - return 0; - if (h->nlmsg_type == NLMSG_ERROR) { - struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h); - if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) { - fprintf(stderr, "ERROR truncated\n"); - } else { - errno = -err->error; - perror("RTNETLINK answers"); + if (nladdr.nl_pid != 0 || + h->nlmsg_pid != rth->local.nl_pid || + h->nlmsg_seq != rth->dump) { + if (a->junk) { + err = a->junk(&nladdr, h, + a->arg2); + if (err < 0) + return err; + } + goto skip_it; } - return -1; - } - err = filter(&nladdr, h, arg1); - if (err < 0) - return err; + + if (h->nlmsg_type == NLMSG_DONE) + return 0; + if (h->nlmsg_type == NLMSG_ERROR) { + struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h); + if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) { + fprintf(stderr, + "ERROR truncated\n"); + } else { + errno = -err->error; + perror("RTNETLINK answers"); + } + return -1; + } + err = a->filter(&nladdr, h, a->arg1); + if (err < 0) + return err; skip_it: - h = NLMSG_NEXT(h, status); - } + h = NLMSG_NEXT(h, status); + } + } while (0); if (msg.msg_flags & MSG_TRUNC) { fprintf(stderr, "Message truncated\n"); continue; @@ -253,6 +256,20 @@ skip_it: } } +int rtnl_dump_filter(struct rtnl_handle *rth, + rtnl_filter_t filter, + void *arg1, + rtnl_filter_t junk, + void *arg2) +{ + const struct rtnl_dump_filter_arg a[2] = { + { .filter = filter, .arg1 = arg1, .junk = junk, .arg2 = arg2 }, + { .filter = NULL, .arg1 = NULL, .junk = NULL, .arg2 = NULL } + }; + + return rtnl_dump_filter_l(rth, a); +} + int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, unsigned groups, struct nlmsghdr *answer, rtnl_filter_t junk, @@ -409,6 +426,8 @@ int rtnl_listen(struct rtnl_handle *rtnl, continue; fprintf(stderr, "netlink receive error %s (%d)\n", strerror(errno), errno); + if (errno == ENOBUFS) + continue; return -1; } if (status == 0) { @@ -625,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 c1d61a9a..5addf4a4 100644 --- a/lib/ll_map.c +++ b/lib/ll_map.c @@ -31,7 +31,7 @@ struct idxmap int type; int alen; unsigned flags; - unsigned char addr[8]; + unsigned char addr[20]; char name[16]; }; @@ -134,6 +134,27 @@ unsigned ll_index_to_flags(unsigned idx) return 0; } +unsigned ll_index_to_addr(unsigned idx, unsigned char *addr, + unsigned alen) +{ + struct idxmap *im; + + if (idx == 0) + return 0; + + for (im = idxmap[idx&0xF]; im; im = im->next) { + if (im->index == idx) { + if (alen > sizeof(im->addr)) + alen = sizeof(im->addr); + if (alen > im->alen) + alen = im->alen; + memcpy(addr, im->addr, alen); + return alen; + } + } + return 0; +} + unsigned ll_name_to_index(const char *name) { static char ncache[16]; diff --git a/lib/utils.c b/lib/utils.c index 0bb08325..a60d884e 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -8,10 +8,6 @@ * * Authors: Alexey Kuznetsov, * - * - * Changes: - * - * Rani Assaf 980929: resolve addresses */ #include diff --git a/man/man8/ip.8 b/man/man8/ip.8 index a8fccc41..3efa0455 100644 --- a/man/man8/ip.8 +++ b/man/man8/ip.8 @@ -53,7 +53,23 @@ 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 " ]" +.BR " }" + .ti -8 .B ip link show @@ -97,7 +113,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 @@ -212,10 +228,6 @@ throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]" .BR host " | " link " | " global " |" .IR NUMBER " ]" -.ti -8 -.IR FLAGS " := [ " -.BR equalize " ]" - .ti -8 .IR NHFLAGS " := [ " .BR onlink " | " pervasive " ]" @@ -240,7 +252,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 " ]" @@ -824,7 +838,9 @@ display and change the state of devices. .TP .BI dev " NAME " (default) .I NAME -specifies network device to operate on. +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 +902,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,13 +1095,22 @@ 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 .B deprecated (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. @@ -1589,14 +1663,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 @@ -1935,6 +2001,12 @@ the rule only matches packets originating from this host. This means 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 diff --git a/man/man8/tc-drr.8 b/man/man8/tc-drr.8 new file mode 100644 index 00000000..16a8ec0d --- /dev/null +++ b/man/man8/tc-drr.8 @@ -0,0 +1,94 @@ +.TH TC 8 "January 2010" "iproute2" "Linux" +.SH NAME +drr \- deficit round robin scheduler +.SH SYNOPSIS +.B tc qdisc ... add drr +.B [ quantum +bytes +.B ] + +.SH DESCRIPTION + +The Deficit Round Robin Scheduler is a classful queuing discipline as +a more flexible replacement for Stochastic Fairness Queuing. + +Unlike SFQ, there are no built-in queues \-\- you need to add classes +and then set up filters to classify packets accordingly. +This can be useful e.g. for using RED qdiscs with different settings for particular +traffic. There is no default class \-\- if a packet cannot be classified, +it is dropped. + +.SH ALGORITHM +Each class is assigned a deficit counter, initialized to +.B quantum. + +DRR maintains an (internal) ''active'' list of classes whose qdiscs are +non-empty. This list is used for dequeuing. A packet is dequeued from +the class at the head of the list if the packet size is smaller or equal +to the deficit counter. If the counter is too small, it is increased by +.B quantum +and the scheduler moves on to the next class in the active list. + + +.SH PARAMETERS +.TP +quantum +Amount of bytes a flow is allowed to dequeue before the scheduler moves to +the next class. Defaults to the MTU of the interface. The minimum value is 1. + +.SH EXAMPLE & USAGE + +To attach to device eth0, using the interface MTU as its quantum: +.P +# tc qdisc add dev eth0 handle 1 root drr +.P +Adding two classes: +.P +# tc class add dev eth0 parent 1: classid 1:1 drr +# tc class add dev eth0 parent 1: classid 1:2 drr +.P +You also need to add at least one filter to classify packets. +.P +# tc filter add dev eth0 protocol .. classid 1:1 +.P + +Like SFQ, DRR is only useful when it owns the queue \-\- it is a pure scheduler and does +not delay packets. Attaching non-work-conserving qdiscs like tbf to it does not make +sense \-\- other qdiscs in the active list will also become inactive until the dequeue +operation succeeds. Embed DRR within another qdisc like HTB or HFSC to ensure it owns the queue. +.P +You can mimic SFQ behavior by assigning packets to the attached classes using the +flow filter: + +.B tc qdisc add dev .. drr + +.B for i in .. 1024;do +.br +.B \ttc class add dev .. classid $handle:$(print %x $i) +.br +.B \ttc qdisc add dev .. fifo limit 16 +.br +.B done + +.B tc filter add .. protocol ip .. $handle flow hash keys src,dst,proto,proto-src,proto-dst divisor 1024 perturb 10 + + +.SH SOURCE +.TP +o +M. Shreedhar and George Varghese "Efficient Fair +Queuing using Deficit Round Robin", Proc. SIGCOMM 95. + +.SH NOTES + +This implementation does not drop packets from the longest queue on overrun, +as limits are handled by the individual child qdiscs. + +.SH SEE ALSO +.BR tc (8), +.BR tc-htb (8), +.BR tc-sfq (8) + +.SH AUTHOR +sched_drr was written by Patrick McHardy. + diff --git a/man/man8/tc-prio.8 b/man/man8/tc-prio.8 index 780bcd5a..1625fccc 100644 --- a/man/man8/tc-prio.8 +++ b/man/man8/tc-prio.8 @@ -50,7 +50,7 @@ be enqueued. From userspace A process with sufficient privileges can encode the destination class directly with SO_PRIORITY, see -.BR tc(7). +.BR socket(7). .TP with a tc filter A tc filter attached to the root qdisc can point traffic directly to a class diff --git a/man/man8/tc-sfq.8 b/man/man8/tc-sfq.8 index 337c7950..8f2b4333 100644 --- a/man/man8/tc-sfq.8 +++ b/man/man8/tc-sfq.8 @@ -51,6 +51,9 @@ on the fullest bucket, thus maintaining fairness. .SH PARAMETERS .TP +limit +Upper limit of the SFQ. Can be used to reduce the default length of 128 packets. +.TP perturb Interval in seconds for queue algorithm perturbation. Defaults to 0, which means that no perturbation occurs. Do not set too low for each perturbation may cause some packet diff --git a/man/man8/tc.8 b/man/man8/tc.8 index 8c0880fa..e17ce68b 100644 --- a/man/man8/tc.8 +++ b/man/man8/tc.8 @@ -367,6 +367,7 @@ print rates in IEC units (ie. 1K = 1024). was written by Alexey N. Kuznetsov and added in Linux 2.2. .SH SEE ALSO .BR tc-cbq (8), +.BR tc-drr (8), .BR tc-htb (8), .BR tc-sfq (8), .BR tc-red (8), diff --git a/misc/arpd.c b/misc/arpd.c index 71cd082e..128c49d7 100644 --- a/misc/arpd.c +++ b/misc/arpd.c @@ -775,27 +775,9 @@ int main(int argc, char **argv) load_initial_table(); - if (1) { - int fd; - pid_t pid = fork(); - - if (pid > 0) - _exit(0); - if (pid < 0) { - perror("arpd: fork"); - goto do_abort; - } - - chdir("/"); - fd = open("/dev/null", O_RDWR); - if (fd >= 0) { - dup2(fd, 0); - dup2(fd, 1); - dup2(fd, 2); - if (fd > 2) - close(fd); - } - setsid(); + if (daemon(0, 0)) { + perror("arpd: daemon"); + goto do_abort; } openlog("arpd", LOG_PID | LOG_CONS, LOG_DAEMON); diff --git a/misc/ifstat.c b/misc/ifstat.c index 68dfdeee..0ce8c928 100644 --- a/misc/ifstat.c +++ b/misc/ifstat.c @@ -663,10 +663,10 @@ int main(int argc, char *argv[]) perror("ifstat: listen"); exit(-1); } - if (fork()) - exit(0); - chdir("/"); - close(0); close(1); close(2); setsid(); + if (daemon(0, 0)) { + perror("ifstat: daemon"); + exit(-1); + } signal(SIGPIPE, SIG_IGN); signal(SIGCHLD, sigchild); server_loop(fd); diff --git a/misc/nstat.c b/misc/nstat.c index 80e695fc..4f73c628 100644 --- a/misc/nstat.c +++ b/misc/nstat.c @@ -445,7 +445,7 @@ static void usage(void) int main(int argc, char *argv[]) { - char hist_name[128]; + char *hist_name; struct sockaddr_un sun; FILE *hist_fp = NULL; int ch; @@ -513,10 +513,10 @@ int main(int argc, char *argv[]) perror("nstat: listen"); exit(-1); } - if (fork()) - exit(0); - chdir("/"); - close(0); close(1); close(2); setsid(); + if (daemon(0, 0)) { + perror("nstat: daemon"); + exit(-1); + } signal(SIGPIPE, SIG_IGN); signal(SIGCHLD, sigchild); server_loop(fd); @@ -526,10 +526,10 @@ int main(int argc, char *argv[]) patterns = argv; npatterns = argc; - if (getenv("NSTAT_HISTORY")) - snprintf(hist_name, sizeof(hist_name), getenv("NSTAT_HISTORY")); - else + if ((hist_name = getenv("NSTAT_HISTORY")) == NULL) { + hist_name = malloc(128); sprintf(hist_name, "/tmp/.nstat.u%d", getuid()); + } if (reset_history) unlink(hist_name); diff --git a/misc/rtacct.c b/misc/rtacct.c index eb3ea9ec..a247dfd2 100644 --- a/misc/rtacct.c +++ b/misc/rtacct.c @@ -524,10 +524,10 @@ int main(int argc, char *argv[]) perror("rtacct: listen"); exit(-1); } - if (fork()) - exit(0); - chdir("/"); - close(0); close(1); close(2); setsid(); + if (daemon(0, 0)) { + perror("rtacct: daemon"); + exit(-1); + } signal(SIGPIPE, SIG_IGN); signal(SIGCHLD, sigchild); server_loop(fd); diff --git a/misc/ss.c b/misc/ss.c index ac7f4110..8a9663cf 100644 --- a/misc/ss.c +++ b/misc/ss.c @@ -2331,12 +2331,9 @@ int print_summary(void) return 0; } - -static void usage(void) __attribute__((noreturn)); - -static void usage(void) +static void _usage(FILE *dest) { - fprintf(stderr, + fprintf(dest, "Usage: ss [ OPTIONS ]\n" " ss [ OPTIONS ] [ FILTER ]\n" " -h, --help this message\n" @@ -2368,6 +2365,19 @@ static void usage(void) " -F, --filter=FILE read filter information from FILE\n" " FILTER := [ state TCP-STATE ] [ EXPRESSION ]\n" ); +} + +static void help(void) __attribute__((noreturn)); +static void help(void) +{ + _usage(stdout); + exit(0); +} + +static void usage(void) __attribute__((noreturn)); +static void usage(void) +{ + _usage(stderr); exit(-1); } @@ -2514,7 +2524,7 @@ int main(int argc, char *argv[]) else if (strcmp(optarg, "netlink") == 0) preferred_family = AF_NETLINK; else if (strcmp(optarg, "help") == 0) - usage(); + help(); else { fprintf(stderr, "ss: \"%s\" is invalid family\n", optarg); usage(); @@ -2596,6 +2606,7 @@ int main(int argc, char *argv[]) exit(0); case 'h': case '?': + help(); default: usage(); } diff --git a/tc/Makefile b/tc/Makefile index 3ff25358..0b5d7d3e 100644 --- a/tc/Makefile +++ b/tc/Makefile @@ -3,6 +3,7 @@ TCOBJ= tc.o tc_qdisc.o tc_class.o tc_filter.o tc_util.o \ m_ematch.o emp_ematch.yacc.o emp_ematch.lex.o include ../Config +SHARED_LIBS ?= y TCMODULES := TCMODULES += q_fifo.o @@ -47,17 +48,27 @@ ifeq ($(TC_CONFIG_XT),y) TCMODULES += m_xt.o LDLIBS += -lxtables else - ifeq ($(TC_CONFIG_XT_H),y) - CFLAGS += -DTC_CONFIG_XT_H - TCMODULES += m_xt.o - LDLIBS += -lxtables + ifeq ($(TC_CONFIG_XT_OLD),y) + TCMODULES += m_xt_old.o + LDLIBS += -lxtables else - TCMODULES += m_ipt.o + ifeq ($(TC_CONFIG_XT_OLD_H),y) + CFLAGS += -DTC_CONFIG_XT_H + TCMODULES += m_xt_old.o + LDLIBS += -lxtables + else + TCMODULES += m_ipt.o + endif endif endif TCOBJ += $(TCMODULES) -LDLIBS += -L. -ltc -lm -ldl +LDLIBS += -L. -ltc -lm + +ifeq ($(SHARED_LIBS),y) +LDLIBS += -ldl +LDFLAGS += -Wl,-export-dynamic +endif TCLIB := tc_core.o TCLIB += tc_red.o @@ -72,14 +83,11 @@ ifeq ($(TC_CONFIG_ATM),y) TCSO += q_atm.so endif - -LDFLAGS += -Wl,-export-dynamic - YACC := bison LEX := flex %.so: %.c - $(CC) $(CFLAGS) -shared -fpic $< -o $@ + $(CC) $(CFLAGS) $(LDFLAGS) -shared -fpic $< -o $@ all: libtc.a tc $(TCSO) @@ -108,3 +116,15 @@ q_atm.so: q_atm.c %.lex.c: %.l $(LEX) $(LEXFLAGS) -o$@ $< + +ifneq ($(SHARED_LIBS),y) + +tc: static-syms.o +static-syms.o: static-syms.h +static-syms.h: $(wildcard *.c) + files="$^" ; \ + for s in `grep -B 3 '\ $@ + +endif diff --git a/tc/em_cmp.c b/tc/em_cmp.c index ce72a429..6addce07 100644 --- a/tc/em_cmp.c +++ b/tc/em_cmp.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include "m_ematch.h" diff --git a/tc/em_meta.c b/tc/em_meta.c index ee6034fb..033e29f2 100644 --- a/tc/em_meta.c +++ b/tc/em_meta.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include "m_ematch.h" diff --git a/tc/em_nbyte.c b/tc/em_nbyte.c index 242c361b..87f3e9d2 100644 --- a/tc/em_nbyte.c +++ b/tc/em_nbyte.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include "m_ematch.h" diff --git a/tc/em_u32.c b/tc/em_u32.c index 402bea0e..21ed70fd 100644 --- a/tc/em_u32.c +++ b/tc/em_u32.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include "m_ematch.h" diff --git a/tc/f_fw.c b/tc/f_fw.c index b5117356..219b404f 100644 --- a/tc/f_fw.c +++ b/tc/f_fw.c @@ -31,22 +31,18 @@ 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; struct tcmsg *t = NLMSG_DATA(n); struct rtattr *tail; + __u32 mask = 0; + int mask_set = 0; memset(&tp, 0, sizeof(tp)); - tail = NLMSG_TAIL(n); - addattr_l(n, 4096, TCA_OPTIONS, NULL, 0); - if (handle) { char *slash; - __u32 mask = 0; if ((slash = strchr(handle, '/')) != NULL) *slash = '\0'; if (get_u32(&t->tcm_handle, handle, 0)) { @@ -58,13 +54,19 @@ static int fw_parse_opt(struct filter_util *qu, char *handle, int argc, char **a fprintf(stderr, "Illegal \"handle\" mask\n"); return -1; } - addattr32(n, MAX_MSG, TCA_FW_MASK, mask); + mask_set = 1; } } if (argc == 0) return 0; + tail = NLMSG_TAIL(n); + addattr_l(n, 4096, TCA_OPTIONS, NULL, 0); + + if (mask_set) + addattr32(n, MAX_MSG, TCA_FW_MASK, mask); + while (argc > 0) { if (matches(*argv, "classid") == 0 || matches(*argv, "flowid") == 0) { diff --git a/tc/f_route.c b/tc/f_route.c index 67dd49c0..eccf924b 100644 --- a/tc/f_route.c +++ b/tc/f_route.c @@ -34,8 +34,6 @@ static void explain(void) fprintf(stderr, "\nNOTE: CLASSID is parsed as hexadecimal input.\n"); } -#define usage() return(-1) - static int route_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n) { struct tc_police tp; diff --git a/tc/f_rsvp.c b/tc/f_rsvp.c index 7e1e6d92..808310df 100644 --- a/tc/f_rsvp.c +++ b/tc/f_rsvp.c @@ -37,8 +37,6 @@ static void explain(void) fprintf(stderr, "\nNOTE: CLASSID is parsed as hexadecimal input.\n"); } -#define usage() return(-1) - int get_addr_and_pi(int *argc_p, char ***argv_p, inet_prefix * addr, struct tc_rsvp_pinfo *pinfo, int dir, int family) { diff --git a/tc/f_tcindex.c b/tc/f_tcindex.c index 39ac75ad..cb6f854c 100644 --- a/tc/f_tcindex.c +++ b/tc/f_tcindex.c @@ -24,10 +24,6 @@ static void explain(void) "[ police POLICE_SPEC ]\n"); } - -#define usage() return(-1) - - static int tcindex_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n) { diff --git a/tc/f_u32.c b/tc/f_u32.c index cb3f67ea..4f5f74e4 100644 --- a/tc/f_u32.c +++ b/tc/f_u32.c @@ -45,8 +45,6 @@ static void explain(void) fprintf(stderr, "\nNOTE: CLASSID is parsed at hexadecimal input.\n"); } -#define usage() return(-1) - int get_u32_handle(__u32 *handle, const char *str) { __u32 htid=0, hash=0, nodeid=0; diff --git a/tc/m_ipt.c b/tc/m_ipt.c index d17d3245..99d9965a 100644 --- a/tc/m_ipt.c +++ b/tc/m_ipt.c @@ -226,6 +226,10 @@ get_target_name(const char *name) struct iptables_target *m; char path[strlen(lib_dir) + sizeof ("/libipt_.so") + strlen(name)]; +#ifdef NO_SHARED_LIBS + return NULL; +#endif + new_name = malloc(strlen(name) + 1); lname = malloc(strlen(name) + 1); if (new_name) diff --git a/tc/m_nat.c b/tc/m_nat.c index 6e7fd055..01ec0328 100644 --- a/tc/m_nat.c +++ b/tc/m_nat.c @@ -19,7 +19,6 @@ #include #include #include -#include #include "utils.h" #include "tc_util.h" #include diff --git a/tc/m_skbedit.c b/tc/m_skbedit.c index 9044353d..990b9c7d 100644 --- a/tc/m_skbedit.c +++ b/tc/m_skbedit.c @@ -31,10 +31,13 @@ static void explain(void) { - fprintf(stderr, "Usage: ... skbedit " - "queue_mapping QUEUE_MAPPING | priority PRIORITY \n" - "QUEUE_MAPPING = device transmit queue to use\n" - "PRIORITY = classID to assign to priority field\n"); + fprintf(stderr, "Usage: ... skbedit <[QM] [PM] [MM]>\n" + "QM = queue_mapping QUEUE_MAPPING\n" + "PM = priority PRIORITY \n" + "MM = mark MARK \n" + "QUEUE_MAPPING = device transmit queue to use\n" + "PRIORITY = classID to assign to priority field\n" + "MARK = firewall mark to set\n"); } static void @@ -54,7 +57,7 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, struct rtattr *tail; unsigned int tmp; __u16 queue_mapping; - __u32 flags = 0, priority; + __u32 flags = 0, priority, mark; struct tc_skbedit sel = { 0 }; if (matches(*argv, "skbedit") != 0) @@ -80,6 +83,14 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, return -1; } ok++; + } else if (matches(*argv, "mark") == 0) { + flags |= SKBEDIT_F_MARK; + NEXT_ARG(); + if (get_u32(&mark, *argv, 0)) { + fprintf(stderr, "Illegal mark\n"); + return -1; + } + ok++; } else if (matches(*argv, "help") == 0) { usage(); } else { @@ -137,6 +148,9 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, if (flags & SKBEDIT_F_PRIORITY) addattr_l(n, MAX_MSG, TCA_SKBEDIT_PRIORITY, &priority, sizeof(priority)); + if (flags & SKBEDIT_F_MARK) + addattr_l(n, MAX_MSG, TCA_SKBEDIT_MARK, + &mark, sizeof(mark)); tail->rta_len = (char *)NLMSG_TAIL(n) - (char *)tail; *argc_p = argc; @@ -150,6 +164,7 @@ static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg) struct rtattr *tb[TCA_SKBEDIT_MAX + 1]; SPRINT_BUF(b1); __u32 *priority; + __u32 *mark; __u16 *queue_mapping; if (arg == NULL) @@ -174,6 +189,10 @@ static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg) priority = RTA_DATA(tb[TCA_SKBEDIT_PRIORITY]); fprintf(f, " priority %s", sprint_tc_classid(*priority, b1)); } + if (tb[TCA_SKBEDIT_MARK] != NULL) { + mark = RTA_DATA(tb[TCA_SKBEDIT_MARK]); + fprintf(f, " mark %d", *mark); + } if (show_stats) { if (tb[TCA_SKBEDIT_TM]) { diff --git a/tc/m_xt.c b/tc/m_xt.c index 0fe61899..3972d2d2 100644 --- a/tc/m_xt.c +++ b/tc/m_xt.c @@ -10,14 +10,12 @@ * Authors: J Hadi Salim (hadi@cyberus.ca) */ -/*XXX: in the future (xtables 1.4.3?) get rid of everything tagged - * as TC_CONFIG_XT_H */ - #include #include #include #include #include +#include #include #include #include @@ -37,13 +35,13 @@ #include #include #include -#ifdef TC_CONFIG_XT_H -#include "xt-internal.h" +#ifndef XT_LIB_DIR +# define XT_LIB_DIR "/lib/xtables" #endif -static const char *pname = "tc-ipt"; static const char *tname = "mangle"; -static const char *pversion = "0.2"; + +char *lib_dir; static const char *ipthooks[] = { "NF_IP_PRE_ROUTING", @@ -54,113 +52,23 @@ static const char *ipthooks[] = { }; static struct option original_opts[] = { - {"jump", 1, 0, 'j'}, + { + .name = "jump", + .has_arg = 1, + .val = 'j' + }, {0, 0, 0, 0} }; -static struct option *opts = original_opts; -static unsigned int global_option_offset = 0; -char *lib_dir; -const char *program_version = XTABLES_VERSION; -const char *program_name = "tc-ipt"; -struct afinfo afinfo = { - .family = AF_INET, - .libprefix = "libxt_", - .ipproto = IPPROTO_IP, - .kmod = "ip_tables", - .so_rev_target = IPT_SO_GET_REVISION_TARGET, +static struct xtables_globals tcipt_globals = { + .option_offset = 0, + .program_name = "tc-ipt", + .program_version = "0.2", + .orig_opts = original_opts, + .opts = original_opts, + .exit_err = NULL, }; - -#define OPTION_OFFSET 256 - -/*XXX: TC_CONFIG_XT_H */ -static void free_opts(struct option *local_opts) -{ - if (local_opts != original_opts) { - free(local_opts); - opts = original_opts; - global_option_offset = 0; - } -} - -/*XXX: TC_CONFIG_XT_H */ -static struct option * -merge_options(struct option *oldopts, const struct option *newopts, - unsigned int *option_offset) -{ - struct option *merge; - unsigned int num_old, num_new, i; - - for (num_old = 0; oldopts[num_old].name; num_old++) ; - for (num_new = 0; newopts[num_new].name; num_new++) ; - - *option_offset = global_option_offset + OPTION_OFFSET; - - merge = malloc(sizeof (struct option) * (num_new + num_old + 1)); - memcpy(merge, oldopts, num_old * sizeof (struct option)); - for (i = 0; i < num_new; i++) { - merge[num_old + i] = newopts[i]; - merge[num_old + i].val += *option_offset; - } - memset(merge + num_old + num_new, 0, sizeof (struct option)); - - return merge; -} - - -/*XXX: TC_CONFIG_XT_H */ -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -/*XXX: TC_CONFIG_XT_H */ -int -check_inverse(const char option[], int *invert, int *my_optind, int argc) -{ - if (option && strcmp(option, "!") == 0) { - if (*invert) - exit_error(PARAMETER_PROBLEM, - "Multiple `!' flags not allowed"); - *invert = TRUE; - if (my_optind != NULL) { - ++*my_optind; - if (argc && *my_optind > argc) - exit_error(PARAMETER_PROBLEM, - "no argument following `!'"); - } - - return TRUE; - } - return FALSE; -} - -/*XXX: TC_CONFIG_XT_H */ -void exit_error(enum exittype status, const char *msg, ...) -{ - va_list args; - - va_start(args, msg); - fprintf(stderr, "%s v%s: ", pname, pversion); - vfprintf(stderr, msg, args); - va_end(args); - fprintf(stderr, "\n"); - /* On error paths, make sure that we don't leak memory */ - exit(status); -} - -/*XXX: TC_CONFIG_XT_H */ -static void set_revision(char *name, u_int8_t revision) -{ - /* Old kernel sources don't have ".revision" field, - * but we stole a byte from name. */ - name[IPT_FUNCTION_MAXNAMELEN - 2] = '\0'; - name[IPT_FUNCTION_MAXNAMELEN - 1] = revision; -} - /* * we may need to check for version mismatch */ @@ -172,10 +80,10 @@ build_st(struct xtables_target *target, struct xt_entry_target *t) XT_ALIGN(sizeof (struct xt_entry_target)) + target->size; if (NULL == t) { - target->t = fw_calloc(1, size); + target->t = xtables_calloc(1, size); target->t->u.target_size = size; strcpy(target->t->u.user.name, target->name); - set_revision(target->t->u.user.name, target->revision); + xtables_set_revision(target->t->u.user.name, target->revision); if (target->init != NULL) target->init(target->t); @@ -217,6 +125,7 @@ static int parse_ipt(struct action_util *a,int *argc_p, __u32 hook = 0, index = 0; res = 0; + xtables_init_all(&tcipt_globals, NFPROTO_IPV4); set_lib_dir(); { @@ -235,21 +144,22 @@ static int parse_ipt(struct action_util *a,int *argc_p, } while (1) { - c = getopt_long(argc, argv, "j:", opts, NULL); + c = getopt_long(argc, argv, "j:", tcipt_globals.opts, NULL); if (c == -1) break; switch (c) { case 'j': - m = find_target(optarg, TRY_LOAD); + m = xtables_find_target(optarg, XTF_TRY_LOAD); if (NULL != m) { if (0 > build_st(m, NULL)) { printf(" %s error \n", m->name); return -1; } - opts = - merge_options(opts, m->extra_opts, - &m->option_offset); + tcipt_globals.opts = + xtables_merge_options(tcipt_globals.opts, + m->extra_opts, + &m->option_offset); } else { fprintf(stderr," failed to find target %s\n\n", optarg); return -1; @@ -277,7 +187,7 @@ static int parse_ipt(struct action_util *a,int *argc_p, if (matches(argv[optind], "index") == 0) { if (get_u32(&index, argv[optind + 1], 10)) { fprintf(stderr, "Illegal \"index\"\n"); - free_opts(opts); + xtables_free_opts(1); return -1; } iok++; @@ -292,7 +202,7 @@ static int parse_ipt(struct action_util *a,int *argc_p, } /* check that we passed the correct parameters to the target */ - if (m) + if (m && m->final_check) m->final_check(m->tflags); { @@ -335,7 +245,7 @@ static int parse_ipt(struct action_util *a,int *argc_p, *argv_p = argv; optind = 0; - free_opts(opts); + xtables_free_opts(1); /* Clear flags if target will be used again */ m->tflags=0; m->used=0; @@ -357,6 +267,7 @@ print_ipt(struct action_util *au,FILE * f, struct rtattr *arg) if (arg == NULL) return -1; + xtables_init_all(&tcipt_globals, NFPROTO_IPV4); set_lib_dir(); parse_rtattr_nested(tb, TCA_IPT_MAX, arg); @@ -383,16 +294,17 @@ print_ipt(struct action_util *au,FILE * f, struct rtattr *arg) } else { struct xtables_target *m = NULL; t = RTA_DATA(tb[TCA_IPT_TARG]); - m = find_target(t->u.user.name, TRY_LOAD); + m = xtables_find_target(t->u.user.name, XTF_TRY_LOAD); if (NULL != m) { if (0 > build_st(m, t)) { fprintf(stderr, " %s error \n", m->name); return -1; } - opts = - merge_options(opts, m->extra_opts, - &m->option_offset); + tcipt_globals.opts = + xtables_merge_options(tcipt_globals.opts, + m->extra_opts, + &m->option_offset); } else { fprintf(stderr, " failed to find target %s\n\n", t->u.user.name); @@ -421,7 +333,7 @@ print_ipt(struct action_util *au,FILE * f, struct rtattr *arg) fprintf(f, " \n"); } - free_opts(opts); + xtables_free_opts(1); return 0; } diff --git a/tc/m_xt_old.c b/tc/m_xt_old.c new file mode 100644 index 00000000..0c7ec604 --- /dev/null +++ b/tc/m_xt_old.c @@ -0,0 +1,433 @@ +/* + * m_xt.c xtables based targets + * utilities mostly ripped from iptables + * + * This program is free software; you can distribute 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: J Hadi Salim (hadi@cyberus.ca) + */ + +/*XXX: in the future (xtables 1.4.3?) get rid of everything tagged + * as TC_CONFIG_XT_H */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "utils.h" +#include "tc_util.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef TC_CONFIG_XT_H +#include "xt-internal.h" +#endif + +static const char *pname = "tc-ipt"; +static const char *tname = "mangle"; +static const char *pversion = "0.2"; + +static const char *ipthooks[] = { + "NF_IP_PRE_ROUTING", + "NF_IP_LOCAL_IN", + "NF_IP_FORWARD", + "NF_IP_LOCAL_OUT", + "NF_IP_POST_ROUTING", +}; + +static struct option original_opts[] = { + {"jump", 1, 0, 'j'}, + {0, 0, 0, 0} +}; + +static struct option *opts = original_opts; +static unsigned int global_option_offset = 0; +char *lib_dir; +const char *program_version = XTABLES_VERSION; +const char *program_name = "tc-ipt"; +struct afinfo afinfo = { + .family = AF_INET, + .libprefix = "libxt_", + .ipproto = IPPROTO_IP, + .kmod = "ip_tables", + .so_rev_target = IPT_SO_GET_REVISION_TARGET, +}; + + +#define OPTION_OFFSET 256 + +/*XXX: TC_CONFIG_XT_H */ +static void free_opts(struct option *local_opts) +{ + if (local_opts != original_opts) { + free(local_opts); + opts = original_opts; + global_option_offset = 0; + } +} + +/*XXX: TC_CONFIG_XT_H */ +static struct option * +merge_options(struct option *oldopts, const struct option *newopts, + unsigned int *option_offset) +{ + struct option *merge; + unsigned int num_old, num_new, i; + + for (num_old = 0; oldopts[num_old].name; num_old++) ; + for (num_new = 0; newopts[num_new].name; num_new++) ; + + *option_offset = global_option_offset + OPTION_OFFSET; + + merge = malloc(sizeof (struct option) * (num_new + num_old + 1)); + memcpy(merge, oldopts, num_old * sizeof (struct option)); + for (i = 0; i < num_new; i++) { + merge[num_old + i] = newopts[i]; + merge[num_old + i].val += *option_offset; + } + memset(merge + num_old + num_new, 0, sizeof (struct option)); + + return merge; +} + + +/*XXX: TC_CONFIG_XT_H */ +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +/*XXX: TC_CONFIG_XT_H */ +int +check_inverse(const char option[], int *invert, int *my_optind, int argc) +{ + if (option && strcmp(option, "!") == 0) { + if (*invert) + exit_error(PARAMETER_PROBLEM, + "Multiple `!' flags not allowed"); + *invert = TRUE; + if (my_optind != NULL) { + ++*my_optind; + if (argc && *my_optind > argc) + exit_error(PARAMETER_PROBLEM, + "no argument following `!'"); + } + + return TRUE; + } + return FALSE; +} + +/*XXX: TC_CONFIG_XT_H */ +void exit_error(enum exittype status, const char *msg, ...) +{ + va_list args; + + va_start(args, msg); + fprintf(stderr, "%s v%s: ", pname, pversion); + vfprintf(stderr, msg, args); + va_end(args); + fprintf(stderr, "\n"); + /* On error paths, make sure that we don't leak memory */ + exit(status); +} + +/*XXX: TC_CONFIG_XT_H */ +static void set_revision(char *name, u_int8_t revision) +{ + /* Old kernel sources don't have ".revision" field, + * but we stole a byte from name. */ + name[IPT_FUNCTION_MAXNAMELEN - 2] = '\0'; + name[IPT_FUNCTION_MAXNAMELEN - 1] = revision; +} + +/* + * we may need to check for version mismatch +*/ +int +build_st(struct xtables_target *target, struct xt_entry_target *t) +{ + + size_t size = + XT_ALIGN(sizeof (struct xt_entry_target)) + target->size; + + if (NULL == t) { + target->t = fw_calloc(1, size); + target->t->u.target_size = size; + strcpy(target->t->u.user.name, target->name); + set_revision(target->t->u.user.name, target->revision); + + if (target->init != NULL) + target->init(target->t); + } else { + target->t = t; + } + return 0; + +} + +inline void set_lib_dir(void) +{ + + lib_dir = getenv("XTABLES_LIBDIR"); + if (!lib_dir) { + lib_dir = getenv("IPTABLES_LIB_DIR"); + if (lib_dir) + fprintf(stderr, "using deprecated IPTABLES_LIB_DIR \n"); + } + if (lib_dir == NULL) + lib_dir = XT_LIB_DIR; + +} + +static int parse_ipt(struct action_util *a,int *argc_p, + char ***argv_p, int tca_id, struct nlmsghdr *n) +{ + struct xtables_target *m = NULL; + struct ipt_entry fw; + struct rtattr *tail; + int c; + int rargc = *argc_p; + char **argv = *argv_p; + int argc = 0, iargc = 0; + char k[16]; + int res = -1; + int size = 0; + int iok = 0, ok = 0; + __u32 hook = 0, index = 0; + res = 0; + + set_lib_dir(); + + { + int i; + for (i = 0; i < rargc; i++) { + if (NULL == argv[i] || 0 == strcmp(argv[i], "action")) { + break; + } + } + iargc = argc = i; + } + + if (argc <= 2) { + fprintf(stderr,"bad arguements to ipt %d vs %d \n", argc, rargc); + return -1; + } + + while (1) { + c = getopt_long(argc, argv, "j:", opts, NULL); + if (c == -1) + break; + switch (c) { + case 'j': + m = find_target(optarg, TRY_LOAD); + if (NULL != m) { + + if (0 > build_st(m, NULL)) { + printf(" %s error \n", m->name); + return -1; + } + opts = + merge_options(opts, m->extra_opts, + &m->option_offset); + } else { + fprintf(stderr," failed to find target %s\n\n", optarg); + return -1; + } + ok++; + break; + + default: + memset(&fw, 0, sizeof (fw)); + if (m) { + m->parse(c - m->option_offset, argv, 0, + &m->tflags, NULL, &m->t); + } else { + fprintf(stderr," failed to find target %s\n\n", optarg); + return -1; + + } + ok++; + break; + + } + } + + if (iargc > optind) { + if (matches(argv[optind], "index") == 0) { + if (get_u32(&index, argv[optind + 1], 10)) { + fprintf(stderr, "Illegal \"index\"\n"); + free_opts(opts); + return -1; + } + iok++; + + optind += 2; + } + } + + if (!ok && !iok) { + fprintf(stderr," ipt Parser BAD!! (%s)\n", *argv); + return -1; + } + + /* check that we passed the correct parameters to the target */ + if (m) + m->final_check(m->tflags); + + { + struct tcmsg *t = NLMSG_DATA(n); + if (t->tcm_parent != TC_H_ROOT + && t->tcm_parent == TC_H_MAJ(TC_H_INGRESS)) { + hook = NF_IP_PRE_ROUTING; + } else { + hook = NF_IP_POST_ROUTING; + } + } + + tail = NLMSG_TAIL(n); + addattr_l(n, MAX_MSG, tca_id, NULL, 0); + fprintf(stdout, "tablename: %s hook: %s\n ", tname, ipthooks[hook]); + fprintf(stdout, "\ttarget: "); + + if (m) + m->print(NULL, m->t, 0); + fprintf(stdout, " index %d\n", index); + + if (strlen(tname) > 16) { + size = 16; + k[15] = 0; + } else { + size = 1 + strlen(tname); + } + strncpy(k, tname, size); + + addattr_l(n, MAX_MSG, TCA_IPT_TABLE, k, size); + addattr_l(n, MAX_MSG, TCA_IPT_HOOK, &hook, 4); + addattr_l(n, MAX_MSG, TCA_IPT_INDEX, &index, 4); + if (m) + addattr_l(n, MAX_MSG, TCA_IPT_TARG, m->t, m->t->u.target_size); + tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; + + argc -= optind; + argv += optind; + *argc_p = rargc - iargc; + *argv_p = argv; + + optind = 0; + free_opts(opts); + /* Clear flags if target will be used again */ + m->tflags=0; + m->used=0; + /* Free allocated memory */ + if (m->t) + free(m->t); + + + return 0; + +} + +static int +print_ipt(struct action_util *au,FILE * f, struct rtattr *arg) +{ + struct rtattr *tb[TCA_IPT_MAX + 1]; + struct xt_entry_target *t = NULL; + + if (arg == NULL) + return -1; + + set_lib_dir(); + + parse_rtattr_nested(tb, TCA_IPT_MAX, arg); + + if (tb[TCA_IPT_TABLE] == NULL) { + fprintf(f, "[NULL ipt table name ] assuming mangle "); + } else { + fprintf(f, "tablename: %s ", + (char *) RTA_DATA(tb[TCA_IPT_TABLE])); + } + + if (tb[TCA_IPT_HOOK] == NULL) { + fprintf(f, "[NULL ipt hook name ]\n "); + return -1; + } else { + __u32 hook; + hook = *(__u32 *) RTA_DATA(tb[TCA_IPT_HOOK]); + fprintf(f, " hook: %s \n", ipthooks[hook]); + } + + if (tb[TCA_IPT_TARG] == NULL) { + fprintf(f, "\t[NULL ipt target parameters ] \n"); + return -1; + } else { + struct xtables_target *m = NULL; + t = RTA_DATA(tb[TCA_IPT_TARG]); + m = find_target(t->u.user.name, TRY_LOAD); + if (NULL != m) { + if (0 > build_st(m, t)) { + fprintf(stderr, " %s error \n", m->name); + return -1; + } + + opts = + merge_options(opts, m->extra_opts, + &m->option_offset); + } else { + fprintf(stderr, " failed to find target %s\n\n", + t->u.user.name); + return -1; + } + fprintf(f, "\ttarget "); + m->print(NULL, m->t, 0); + if (tb[TCA_IPT_INDEX] == NULL) { + fprintf(f, " [NULL ipt target index ]\n"); + } else { + __u32 index; + index = *(__u32 *) RTA_DATA(tb[TCA_IPT_INDEX]); + fprintf(f, " \n\tindex %d", index); + } + + if (tb[TCA_IPT_CNT]) { + struct tc_cnt *c = RTA_DATA(tb[TCA_IPT_CNT]);; + fprintf(f, " ref %d bind %d", c->refcnt, c->bindcnt); + } + if (show_stats) { + if (tb[TCA_IPT_TM]) { + struct tcf_t *tm = RTA_DATA(tb[TCA_IPT_TM]); + print_tm(f,tm); + } + } + fprintf(f, " \n"); + + } + free_opts(opts); + + return 0; +} + +struct action_util ipt_action_util = { + .id = "ipt", + .parse_aopt = parse_ipt, + .print_aopt = print_ipt, +}; + diff --git a/tc/q_atm.c b/tc/q_atm.c index 4c8dc0b8..eec0d776 100644 --- a/tc/q_atm.c +++ b/tc/q_atm.c @@ -26,8 +26,6 @@ #define MAX_HDR_LEN 64 -#define usage() return(-1) - static int atm_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { diff --git a/tc/q_cbq.c b/tc/q_cbq.c index c99dc3b6..3c5e72c1 100644 --- a/tc/q_cbq.c +++ b/tc/q_cbq.c @@ -46,7 +46,6 @@ static void explain1(char *arg) fprintf(stderr, "Illegal \"%s\"\n", arg); } -#define usage() return(-1) static int cbq_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { @@ -319,7 +318,7 @@ static int cbq_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str NEXT_ARG(); if (get_tc_classid(&fopt.split, *argv)) { fprintf(stderr, "Invalid split node ID.\n"); - usage(); + return -1; } fopt_ok++; } else if (matches(*argv, "defmap") == 0) { diff --git a/tc/q_drr.c b/tc/q_drr.c index 7d2d8741..81de44d9 100644 --- a/tc/q_drr.c +++ b/tc/q_drr.c @@ -33,7 +33,6 @@ static void explain2(void) fprintf(stderr, "Usage: ... drr quantum SIZE\n"); } -#define usage() return(-1) static int drr_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { diff --git a/tc/q_dsmark.c b/tc/q_dsmark.c index cdb5bf2f..cfbb3351 100644 --- a/tc/q_dsmark.c +++ b/tc/q_dsmark.c @@ -19,9 +19,6 @@ #include "tc_util.h" -#define usage() return(-1) - - static void explain(void) { fprintf(stderr,"Usage: dsmark indices INDICES [ default_index " diff --git a/tc/q_fifo.c b/tc/q_fifo.c index 9f3b3eb2..6242a98b 100644 --- a/tc/q_fifo.c +++ b/tc/q_fifo.c @@ -25,11 +25,9 @@ static void explain(void) { - fprintf(stderr, "Usage: ... [p|b]fifo [ limit NUMBER ]\n"); + fprintf(stderr, "Usage: ... <[p|b]fifo | pfifo_head_drop> [ limit NUMBER ]\n"); } -#define usage() return(-1) - static int fifo_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { int ok=0; @@ -91,6 +89,12 @@ struct qdisc_util pfifo_qdisc_util = { .print_qopt = fifo_print_opt, }; +struct qdisc_util pfifo_head_drop_qdisc_util = { + .id = "pfifo_head_drop", + .parse_qopt = fifo_parse_opt, + .print_qopt = fifo_print_opt, +}; + extern int prio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt); struct qdisc_util pfifo_fast_qdisc_util = { .id = "pfifo_fast", diff --git a/tc/q_gred.c b/tc/q_gred.c index ecef42e9..df4aa3d8 100644 --- a/tc/q_gred.c +++ b/tc/q_gred.c @@ -46,8 +46,6 @@ static void explain(void) "[grio]\n"); } -#define usage() return(-1) - static int init_gred(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { @@ -215,16 +213,13 @@ static int gred_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct n argc--; argv++; } - if (!ok) - return 0; - if (rate == 0) get_rate(&rate, "10Mbit"); if (!opt.qth_min || !opt.qth_max || !burst || !opt.limit || !avpkt || (opt.DP<0)) { fprintf(stderr, "Required parameter (min, max, burst, limit, " - "avpket, DP) is missing\n"); + "avpkt, DP) is missing\n"); return -1; } diff --git a/tc/q_htb.c b/tc/q_htb.c index c69e350d..caa47c26 100644 --- a/tc/q_htb.c +++ b/tc/q_htb.c @@ -58,8 +58,6 @@ static void explain1(char *arg) } -#define usage() return(-1) - static int htb_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { struct tc_htb_glob opt; diff --git a/tc/q_ingress.c b/tc/q_ingress.c index 71fbd493..ba58e722 100644 --- a/tc/q_ingress.c +++ b/tc/q_ingress.c @@ -32,8 +32,6 @@ static void explain(void) fprintf(stderr, "Usage: ... ingress \n"); } -#define usage() return(-1) - static int ingress_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { diff --git a/tc/q_multiq.c b/tc/q_multiq.c index 306e170d..fce5e449 100644 --- a/tc/q_multiq.c +++ b/tc/q_multiq.c @@ -41,8 +41,6 @@ static void explain(void) fprintf(stderr, "Usage: ... multiq [help]\n"); } -#define usage() return(-1) - static int multiq_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { diff --git a/tc/q_netem.c b/tc/q_netem.c index d06932e8..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) */ @@ -100,8 +98,8 @@ static int get_distribution(const char *type, __s16 *data, int maxdata) static int isnumber(const char *arg) { char *p; - (void) strtod(arg, &p); - return (p != arg); + + return strtod(arg, &p) != 0 || p != arg; } #define NEXT_IS_NUMBER() (NEXT_ARG_OK() && isnumber(argv[1])) diff --git a/tc/q_prio.c b/tc/q_prio.c index 6883edb0..2f54d550 100644 --- a/tc/q_prio.c +++ b/tc/q_prio.c @@ -8,10 +8,6 @@ * * Authors: Alexey Kuznetsov, * - * Changes: - * - * Ole Husgaard : 990513: prio2band map was always reset. - * J Hadi Salim : 990609: priomap fix. */ #include @@ -32,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 }}; @@ -52,7 +45,6 @@ static int prio_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct n fprintf(stderr, "Illegal \"bands\"\n"); return -1; } - ok++; } else if (strcmp(*argv, "priomap") == 0) { if (pmap_mode) { fprintf(stderr, "Error: duplicate priomap\n"); diff --git a/tc/q_red.c b/tc/q_red.c index 6f93b26a..4b1b8893 100644 --- a/tc/q_red.c +++ b/tc/q_red.c @@ -31,11 +31,8 @@ static void explain(void) fprintf(stderr, " probability PROBABILITY bandwidth KBPS [ ecn ]\n"); } -#define usage() return(-1) - static int red_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { - int ok=0; struct tc_red_qopt opt; unsigned burst = 0; unsigned avpkt = 0; @@ -55,52 +52,44 @@ static int red_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nl fprintf(stderr, "Illegal \"limit\"\n"); return -1; } - ok++; } else if (strcmp(*argv, "min") == 0) { NEXT_ARG(); if (get_size(&opt.qth_min, *argv)) { fprintf(stderr, "Illegal \"min\"\n"); return -1; } - ok++; } else if (strcmp(*argv, "max") == 0) { NEXT_ARG(); if (get_size(&opt.qth_max, *argv)) { fprintf(stderr, "Illegal \"max\"\n"); return -1; } - ok++; } else if (strcmp(*argv, "burst") == 0) { NEXT_ARG(); if (get_unsigned(&burst, *argv, 0)) { fprintf(stderr, "Illegal \"burst\"\n"); return -1; } - ok++; } else if (strcmp(*argv, "avpkt") == 0) { NEXT_ARG(); if (get_size(&avpkt, *argv)) { fprintf(stderr, "Illegal \"avpkt\"\n"); return -1; } - ok++; } else if (strcmp(*argv, "probability") == 0) { NEXT_ARG(); if (sscanf(*argv, "%lg", &probability) != 1) { fprintf(stderr, "Illegal \"probability\"\n"); return -1; } - ok++; } else if (strcmp(*argv, "bandwidth") == 0) { NEXT_ARG(); if (get_rate(&rate, *argv)) { fprintf(stderr, "Illegal \"bandwidth\"\n"); return -1; } - ok++; } else if (strcmp(*argv, "ecn") == 0) { ecn_ok = 1; - ok++; } else if (strcmp(*argv, "help") == 0) { explain(); return -1; @@ -112,14 +101,11 @@ static int red_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nl argc--; argv++; } - if (!ok) - return 0; - if (rate == 0) get_rate(&rate, "10Mbit"); if (!opt.qth_min || !opt.qth_max || !burst || !opt.limit || !avpkt) { - fprintf(stderr, "Required parameter (min, max, burst, limit, avpket) is missing\n"); + fprintf(stderr, "Required parameter (min, max, burst, limit, avpkt) is missing\n"); return -1; } diff --git a/tc/q_rr.c b/tc/q_rr.c index 9335c470..1ff3ac96 100644 --- a/tc/q_rr.c +++ b/tc/q_rr.c @@ -8,11 +8,6 @@ * * Authors: PJ Waskiewicz, * Original Authors: Alexey Kuznetsov, (from PRIO) - * - * Changes: - * - * Ole Husgaard : 990513: prio2band map was always reset. - * J Hadi Salim : 990609: priomap fix. */ #include @@ -33,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 }}; @@ -53,7 +46,6 @@ static int rr_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlm fprintf(stderr, "Illegal \"bands\"\n"); return -1; } - ok++; } else if (strcmp(*argv, "priomap") == 0) { if (pmap_mode) { fprintf(stderr, "Error: duplicate priomap\n"); diff --git a/tc/q_sfq.c b/tc/q_sfq.c index ce4dade8..71a3c9ac 100644 --- a/tc/q_sfq.c +++ b/tc/q_sfq.c @@ -28,8 +28,6 @@ static void explain(void) fprintf(stderr, "Usage: ... sfq [ limit NUMBER ] [ perturb SECS ] [ quantum BYTES ]\n"); } -#define usage() return(-1) - static int sfq_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { int ok=0; diff --git a/tc/q_tbf.c b/tc/q_tbf.c index dbf95863..dc556fe0 100644 --- a/tc/q_tbf.c +++ b/tc/q_tbf.c @@ -36,8 +36,6 @@ static void explain1(char *arg) } -#define usage() return(-1) - static int tbf_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { int ok=0; @@ -158,8 +156,10 @@ static int tbf_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nl argc--; argv++; } - if (!ok) - return 0; + if (!ok) { + explain(); + return -1; + } if (opt.rate.rate == 0 || !buffer) { fprintf(stderr, "Both \"rate\" and \"burst\" are required.\n"); diff --git a/tc/static-syms.c b/tc/static-syms.c new file mode 100644 index 00000000..1ed3a8a9 --- /dev/null +++ b/tc/static-syms.c @@ -0,0 +1,6 @@ +#include +void *_dlsym(const char *sym) +{ +#include "static-syms.h" + return NULL; +}