aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Schmidt <yath@yath.de>2012-05-22 08:54:51 +0200
committerSebastian Schmidt <yath@yath.de>2012-05-26 17:48:13 +0200
commitd636d644c17cf7cd9f03a74212f4edfe3d9f84a8 (patch)
tree281e4ce11f81da16472af995412c09811b7238ae
parent768a5430cdbd4d7738a8dacccd7849f79f6889bc (diff)
downloadandroid_external_iproute2-ics.tar.gz
android_external_iproute2-ics.tar.bz2
android_external_iproute2-ics.zip
Merge upstream v3.4.0ics-releaseicscm-9.1.0
This merges upstream's iproute2 version 3.4.0. The merge incorporates the following commits: commit db70d91c7859700f9febf9bad8c29681bf9ac711 Author: Stephen Hemminger <shemminger@vyatta.com> Date: Mon May 21 14:12:19 2012 -0700 v3.4.0 commit 9fc56974acc5bef7a2bb0d0402c74f5d7cf6b3d5 Author: Andreas Henriksson <andreas@fatal.se> Date: Mon May 21 15:48:06 2012 +0200 iproute2: trivial fix of ip link syntax in manpage Reported by Ivan Vilata i Balaguer <ivan@selidor.net> found that the description of the `ip link add` command in the manpage is outdated regarding the compulsory `link DEVICE` option. For instance, `ip link help` says: Usage: ip link add [link DEV] [ name ] NAME ... But the manpage still says: ip link add link DEVICE [ name ] NAME (Trying to provide a `link` option e.g. under an LXC container can frustrate the creation of dummy devices which don't need an actual device.) The syntax of the "ip link help" output was fixed in commit "iproute2: Fix usage and man page for 'ip link'" (a22e92951d). This updates the manpage to mark "link DEVICE" as an optional argument there as well. http://bugs.debian.org/673171 Signed-off-by: Andreas Henriksson <andreas@fatal.se> commit e6232cf647b4a2a8861ec5ad3d37973237bd764e Author: Vijay Subramanian <subramanian.vijay@gmail.com> Date: Thu May 3 13:15:46 2012 -0700 Update man8 Makefile Commit (761a1e60 iproute2 - Split up manual page installation ) introduced man/man8/Makefile but did not add all the man pages. This patch adds the missing man pages for installation. Signed-off-by: Vijay Subramanian <subramanian.vijay@gmail.com> commit 6121e1fef859e0063e26f83af0a3e15ab5453017 Author: James Chapman <jchapman@katalix.com> Date: Tue May 1 15:25:23 2012 +0100 iproute2: add ip-l2tp man page Add a man page to cover the "ip l2tp" commands. Add a reference to it in the main ip page. This version removes the unnecessary setting of promiscuous mode in the examples. Signed-off-by: James Chapman <jchapman@katalix.com> commit 910b039771dd655e53bccaea6e82735718ab4e61 Author: Shan Wei <shanwei88@gmail.com> Date: Thu May 3 16:39:52 2012 +0800 ss: use new INET_DIAG_SKMEMINFO option to get more memory information for tcp socket INET_DIAG_SKMEMINFO is used to monitor socket memory information which contains more information than INET_DIAG_MEMINFO. -m option is retained for old kernel that don't surpport INET_DIAG_SKMEMINFO. Signed-off-by: Shan Wei <davidshan@tencent.com> commit e2780880761df1ab1e8249653e9a18d19d66ae81 Author: Stephen Hemminger <shemminger@vyatta.com> Date: Thu Apr 26 08:06:38 2012 -0700 Revert "iproute2: allow IPv6 addresses for l2tp local and remote parameters" This reverts commit 16eba34485b7275f1b72d6c480d7062127617370. Hold off until next release. commit 16eba34485b7275f1b72d6c480d7062127617370 Author: Chris Elston <celston@katalix.com> Date: Fri Apr 20 01:29:42 2012 +0000 iproute2: allow IPv6 addresses for l2tp local and remote parameters Adds support for parsing IPv6 addresses to the parameters local and remote in the l2tp commands. Requires netlink attributes L2TP_ATTR_IP6_SADDR and L2TP_ATTR_IP6_DADDR, added in a required kernel patch already submitted to netdev. Also enables printing of IPv6 addresses returned by the L2TP_CMD_TUNNEL_GET request. Signed-off-by: Chris Elston <celston@katalix.com> Signed-off-by: James Chapman <jchapman@katalix.com> commit 5c434a9e5a5eafec09ec9939b255948843423f80 Author: Christoph J. Thompson <cjsthompson@gmail.com> Date: Thu Mar 1 17:46:26 2012 +0100 iproute2 - Fix up and simplify variables pointing to install directories Define where is the are located the iproute2 config files. Get rid of trailing slashes for paths in several file. Signed-off-by: Christoph J. Thompson <cjsthompson@gmail.com> commit 761a1e602862b5f26b4e7e748fe51303a628958f Author: Christoph J. Thompson <cjsthompson@gmail.com> Date: Thu Mar 1 17:45:45 2012 +0100 iproute2 - Split up manual page installation Generate manual pages based on where the config files are installed. Add missing manual pages for utilities which are links to other binaries. Make tc-pfifo.8 a real file that points to tc-bfifo.8 instead of symlink which causes problems with compressing manual pages. Signed-off-by: Christoph J. Thompson <cjsthompson@gmail.com> commit c8610020b802a63cbf463b7d31f03a86f4acaa04 Author: Christoph J. Thompson <cjsthompson@gmail.com> Date: Thu Mar 1 06:45:17 2012 +0000 iproute2 - Split up cflags Allows setting optimisation flags at compile time without patching the Makefile. modified: Makefile Signed-off-by: Christoph J. Thompson <cjsthompson@gmail.com> commit fb72129b78ac97433bf38da2b233a48358e30fac Author: Christoph J. Thompson <cjsthompson@gmail.com> Date: Thu Mar 1 06:44:43 2012 +0000 iproute2 - Don't hardcode the path to config files Allows using an alternate path for config files. Signed-off-by: Christoph J. Thompson <cjsthompson@gmail.com> commit bd886ebb1ffd84301caa2341b671df9a9e2db4c9 Author: Rose, Gregory V <gregory.v.rose@intel.com> Date: Tue Feb 21 10:43:09 2012 +0000 iproute2: Add netlink attribute to filter dump requests Add a new netlink attribute type to the dump request to allow filtering of the information returned for the respective matching interfaces. At this time the only filter defined is to request virtual function (VF) device info for interfaces that attached VFs. It will also be possible to extend the request with other yet to be defined netlink attributes in the future. Signed-off-by: Greg Rose <gregory.v.rose@intel.com> commit 29cea29df0dfe45562fd42673e26608d25180eee Author: Stephen Hemminger <shemminger@vyatta.com> Date: Tue Apr 10 09:11:21 2012 -0700 Merge in 3.3-rc2 kernel headers commit 9fb6dc2bef427f13ad794cad187cda60be1cc06e Author: Florian Westphal <fw@strlen.de> Date: Sun Apr 8 12:34:14 2012 +0000 tc: man: choke counts packets, not bytes commit 930a75f9257a3e00fcfede94de5a4516fe34bd22 Author: Eric Dumazet <eric.dumazet@gmail.com> Date: Tue Apr 10 09:00:16 2012 -0700 Fix ss if INET_DIAG not enabled in kernel If kernel doesn't have INET_DIAG and using newish version of iproute nothing would be displayed. commit ff24746cca1ef0c92d46614158e6672acd6b63d3 Author: Stephen Hemminger <shemminger@vyatta.com> Date: Tue Apr 10 08:47:55 2012 -0700 Convert to use rta_getattr_ functions User new functions (inspired by libmnl) to do type safe access of routeing attributes commit 49b730d7b237a3c0b2361e77877228199f32cf9c Author: Jorge Boncompte [DTI2] <jorge@dti2.net> Date: Tue Apr 10 08:23:59 2012 -0700 iproute: show metrics as an unsigned value Avoids showing negative metrics. Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net> commit 4ccfb44dfbe4bf34130cf601a2a59152f4eec816 Author: Stephen Hemminger <stephen.hemminger@vyatta.com> Date: Thu Apr 5 15:10:19 2012 -0700 Make link mode case independent The link mode is printed in upper case, and following the general rule that ip command output should work on input, allow either case. commit 4f2fdd44b6694f713aa638cc2222a2d7d17dfe5f Author: Stephen Hemminger <stephen.hemminger@vyatta.com> Date: Thu Apr 5 15:08:57 2012 -0700 Add ability to set link state with ip Exposes existing netlink operations to modify link state of devices. commit ae5555d3342299252b8690ead236694b7dc660c9 Author: João Valverde <jpv950@gmail.com> Date: Mon Mar 26 21:00:08 2012 +0100 ipl2tp: allow setting session interface name Hi, I've attached a trivial patch for iproute2 to allow naming interfaces created with "ip l2tp add session". I believe patches should go through the netdev mailing list but this patch is so small I figured that would just add noise. Hope that's OK. Originally I thought I would need a bigger patch and was going to take a stab at implementing something like ip l2tp add tunnel L2TP_TUNNEL_ARGS ip link add name NAME [ LINK_OPTS ] type l2tp L2TP_SESSION_ARGS (a better interface IMHO) but all the code was there already, all that I needed to add was option parsing. Thanks, João Valverde From fd8c3b712527d2e959aeabc6f6b71a9910e7be7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Valverde?= <joao.valverde@ist.utl.pt> Date: Mon, 26 Mar 2012 18:30:56 +0100 Subject: [PATCH] ipl2tp: allow setting session interface name Change-Id: I7e56b18a7cebb0600aee3e6502251b996f9cac05
-rw-r--r--Makefile30
-rw-r--r--genl/ctrl.c2
-rw-r--r--include/SNAPSHOT.h2
-rw-r--r--include/linux/if.h2
-rw-r--r--include/linux/if_link.h3
-rw-r--r--include/linux/pkt_sched.h21
-rw-r--r--ip/Android.mk2
-rw-r--r--ip/ip_common.h3
-rw-r--r--ip/ipaddress.c22
-rw-r--r--ip/ipl2tp.c5
-rw-r--r--ip/iplink.c16
-rw-r--r--ip/iplink_macvlan.c2
-rw-r--r--ip/iplink_macvtap.c2
-rw-r--r--ip/iplink_vlan.c2
-rw-r--r--ip/ipneigh.c2
-rw-r--r--ip/ipntable.c44
-rw-r--r--ip/iproute.c8
-rw-r--r--ip/iprule.c12
-rw-r--r--ip/ipxfrm.c2
-rw-r--r--ip/link_gre.c42
-rw-r--r--lib/Android.mk4
-rw-r--r--lib/libnetlink.c13
-rw-r--r--lib/rt_names.c14
-rw-r--r--man/Makefile20
-rw-r--r--man/man3/Makefile13
-rw-r--r--man/man8/Makefile32
-rw-r--r--man/man8/ctstat.81
-rw-r--r--man/man8/ip-address.8.in240
-rw-r--r--man/man8/ip-l2tp.8376
-rw-r--r--man/man8/ip-link.811
-rw-r--r--man/man8/ip-link.8.in376
-rw-r--r--man/man8/ip-route.8.in744
-rw-r--r--man/man8/ip.83
-rw-r--r--man/man8/nstat.81
-rw-r--r--man/man8/routef.81
-rw-r--r--man/man8/rtstat.81
-rw-r--r--man/man8/tc-choke.811
-rw-r--r--[l---------]man/man8/tc-pfifo.82
-rw-r--r--misc/ss.c26
-rw-r--r--tc/Android.mk2
-rw-r--r--tc/Makefile2
-rw-r--r--tc/em_meta.c4
-rw-r--r--tc/f_basic.c2
-rw-r--r--tc/f_flow.c18
-rw-r--r--tc/f_fw.c6
-rw-r--r--tc/f_route.c6
-rw-r--r--tc/f_rsvp.c4
-rw-r--r--tc/f_tcindex.c4
-rw-r--r--tc/f_u32.c10
-rw-r--r--tc/m_ipt.c6
-rw-r--r--tc/m_police.c2
-rw-r--r--tc/m_xt.c6
-rw-r--r--tc/m_xt_old.c6
-rw-r--r--tc/q_atm.c6
-rw-r--r--tc/q_choke.c2
-rw-r--r--tc/q_drr.c2
-rw-r--r--tc/q_dsmark.c8
-rw-r--r--tc/q_prio.c2
-rw-r--r--tc/q_qfq.c4
-rw-r--r--tc/q_red.c2
-rw-r--r--tc/q_rr.c2
-rw-r--r--tc/tc_class.c2
-rw-r--r--tc/tc_filter.c2
-rw-r--r--tc/tc_qdisc.c2
-rw-r--r--tc/tc_util.c2
65 files changed, 2060 insertions, 167 deletions
diff --git a/Makefile b/Makefile
index a2810e5..c107955 100644
--- a/Makefile
+++ b/Makefile
@@ -1,10 +1,11 @@
-DESTDIR=/usr/
ROOTDIR=$(DESTDIR)
-LIBDIR=/usr/lib/
+PREFIX=/usr
+LIBDIR=$(PREFIX)/lib
SBINDIR=/sbin
CONFDIR=/etc/iproute2
-DOCDIR=/share/doc/iproute2
-MANDIR=/share/man
+DATADIR=$(PREFIX)/share
+DOCDIR=$(DATADIR)/doc/iproute2
+MANDIR=$(DATADIR)/man
ARPDDIR=/var/lib/arpd
# Path to db_185.h include
@@ -17,6 +18,8 @@ ifneq ($(SHARED_LIBS),y)
DEFINES+= -DNO_SHARED_LIBS
endif
+DEFINES+=-DCONFDIR=\"$(CONFDIR)\"
+
#options if you have a bind>=4.9.4 libresolv (or, maybe, glibc)
LDLIBS=-lresolv
ADDLIB=
@@ -29,11 +32,13 @@ ADDLIB+=ipx_ntop.o ipx_pton.o
CC = gcc
HOSTCC = gcc
-CCOPTS = -D_GNU_SOURCE -O2 -Wstrict-prototypes -Wall
-CFLAGS = $(CCOPTS) -I../include $(DEFINES)
+DEFINES += -D_GNU_SOURCE
+CCOPTS = -O2
+WFLAGS = -Wall -Wstrict-prototypes
+CFLAGS = $(WFLAGS) $(CCOPTS) -I../include $(DEFINES)
YACCFLAGS = -d -t -v
-SUBDIRS=lib ip tc misc netem genl
+SUBDIRS=lib ip tc misc netem genl man
LIBNETLINK=../lib/libnetlink.a ../lib/libutil.a
LDLIBS += $(LIBNETLINK)
@@ -58,17 +63,6 @@ install: all
$(DESTDIR)$(DOCDIR)/examples/diffserv
@for i in $(SUBDIRS) doc; do $(MAKE) -C $$i install; done
install -m 0644 $(shell find etc/iproute2 -maxdepth 1 -type f) $(DESTDIR)$(CONFDIR)
- install -m 0755 -d $(DESTDIR)$(MANDIR)/man8
- install -m 0644 $(shell find man/man8 -maxdepth 1 -type f) $(DESTDIR)$(MANDIR)/man8
- install -m 0755 -d $(DESTDIR)$(MANDIR)/man7
- install -m 0644 $(shell find man/man7 -maxdepth 1 -type f) $(DESTDIR)$(MANDIR)/man7
- ln -sf tc-bfifo.8 $(DESTDIR)$(MANDIR)/man8/tc-pfifo.8
- ln -sf lnstat.8 $(DESTDIR)$(MANDIR)/man8/rtstat.8
- ln -sf lnstat.8 $(DESTDIR)$(MANDIR)/man8/ctstat.8
- ln -sf rtacct.8 $(DESTDIR)$(MANDIR)/man8/nstat.8
- ln -sf routel.8 $(DESTDIR)$(MANDIR)/man8/routef.8
- install -m 0755 -d $(DESTDIR)$(MANDIR)/man3
- install -m 0644 $(shell find man/man3 -maxdepth 1 -type f) $(DESTDIR)$(MANDIR)/man3
snapshot:
echo "static const char SNAPSHOT[] = \""`date +%y%m%d`"\";" \
diff --git a/genl/ctrl.c b/genl/ctrl.c
index 58d13be..6d97c26 100644
--- a/genl/ctrl.c
+++ b/genl/ctrl.c
@@ -104,7 +104,7 @@ int genl_ctrl_resolve_family(const char *family)
goto errout;
}
- ret = *(__u16 *) RTA_DATA(tb[CTRL_ATTR_FAMILY_ID]);
+ ret = rta_getattr_u16(tb[CTRL_ATTR_FAMILY_ID]);
}
errout:
diff --git a/include/SNAPSHOT.h b/include/SNAPSHOT.h
index ef9ff75..9395cab 100644
--- a/include/SNAPSHOT.h
+++ b/include/SNAPSHOT.h
@@ -1 +1 @@
-static const char SNAPSHOT[] = "120319";
+static const char SNAPSHOT[] = "120521";
diff --git a/include/linux/if.h b/include/linux/if.h
index b5084d4..b3383a9 100644
--- a/include/linux/if.h
+++ b/include/linux/if.h
@@ -80,6 +80,8 @@
* skbs on transmit */
#define IFF_UNICAST_FLT 0x20000 /* Supports unicast filtering */
#define IFF_TEAM_PORT 0x40000 /* device used as team port */
+#define IFF_SUPP_NOFCS 0x80000 /* device supports sending custom FCS */
+
#define IF_GET_IFACE 0x0001 /* for querying only */
#define IF_GET_PROTO 0x0002
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 06a3a47..d02ab09 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -148,6 +148,9 @@ enum {
#define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
+/* New extended info filters for IFLA_EXT_MASK */
+#define RTEXT_FILTER_VF (1 << 0)
+
enum {
IFLA_INET_UNSPEC,
IFLA_INET_CONF,
diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h
index 0d5b793..410b33d 100644
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -127,6 +127,27 @@ struct tc_multiq_qopt {
__u16 max_bands; /* Maximum number of queues */
};
+/* PLUG section */
+
+#define TCQ_PLUG_BUFFER 0
+#define TCQ_PLUG_RELEASE_ONE 1
+#define TCQ_PLUG_RELEASE_INDEFINITE 2
+#define TCQ_PLUG_LIMIT 3
+
+struct tc_plug_qopt {
+ /* TCQ_PLUG_BUFFER: Inset a plug into the queue and
+ * buffer any incoming packets
+ * TCQ_PLUG_RELEASE_ONE: Dequeue packets from queue head
+ * to beginning of the next plug.
+ * TCQ_PLUG_RELEASE_INDEFINITE: Dequeue all packets from queue.
+ * Stop buffering packets until the next TCQ_PLUG_BUFFER
+ * command is received (just act as a pass-thru queue).
+ * TCQ_PLUG_LIMIT: Increase/decrease queue size
+ */
+ int action;
+ __u32 limit;
+};
+
/* TBF section */
struct tc_tbf_qopt {
diff --git a/ip/Android.mk b/ip/Android.mk
index 1cc6f9b..3307c55 100644
--- a/ip/Android.mk
+++ b/ip/Android.mk
@@ -17,7 +17,7 @@ LOCAL_SHARED_LIBRARIES += libiprouteutil libnetlink
LOCAL_C_INCLUDES := $(KERNEL_HEADERS) external/iproute2/include
-LOCAL_CFLAGS := -O2 -g -W -Wall
+LOCAL_CFLAGS := -O2 -g -Wall -Wstrict-prototypes
include $(BUILD_EXECUTABLE)
diff --git a/ip/ip_common.h b/ip/ip_common.h
index b45c5ee..5fa2cc0 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -1,3 +1,4 @@
+extern int get_operstate(const char *name);
extern int print_linkinfo(const struct sockaddr_nl *who,
struct nlmsghdr *n,
void *arg);
@@ -46,7 +47,7 @@ static inline int rtm_get_table(struct rtmsg *r, struct rtattr **tb)
{
__u32 table = r->rtm_table;
if (tb[RTA_TABLE])
- table = *(__u32*) RTA_DATA(tb[RTA_TABLE]);
+ table = rta_getattr_u32(tb[RTA_TABLE]);
return table;
}
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 8453d1f..c28a986 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -136,6 +136,16 @@ static void print_operstate(FILE *f, __u8 state)
fprintf(f, "state %s ", oper_states[state]);
}
+int get_operstate(const char *name)
+{
+ int i;
+
+ for (i = 0; i < sizeof(oper_states)/sizeof(oper_states[0]); i++)
+ if (strcasecmp(name, oper_states[i]) == 0)
+ return i;
+ return -1;
+}
+
static void print_queuelen(FILE *f, struct rtattr *tb[IFLA_MAX + 1])
{
int qlen;
@@ -150,7 +160,7 @@ static void print_queuelen(FILE *f, struct rtattr *tb[IFLA_MAX + 1])
return;
memset(&ifr, 0, sizeof(ifr));
- strcpy(ifr.ifr_name, (char *)RTA_DATA(tb[IFLA_IFNAME]));
+ strcpy(ifr.ifr_name, rta_getattr_str(tb[IFLA_IFNAME]));
if (ioctl(s, SIOCGIFTXQLEN, &ifr) < 0) {
fprintf(f, "ioctl(SIOCGIFXQLEN) failed: %s\n", strerror(errno));
close(s);
@@ -392,7 +402,7 @@ int print_linkinfo(const struct sockaddr_nl *who,
fprintf(fp, "Deleted ");
fprintf(fp, "%d: %s", ifi->ifi_index,
- tb[IFLA_IFNAME] ? (char*)RTA_DATA(tb[IFLA_IFNAME]) : "<nil>");
+ tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "<nil>");
if (tb[IFLA_LINK]) {
SPRINT_BUF(b1);
@@ -412,14 +422,14 @@ int print_linkinfo(const struct sockaddr_nl *who,
if (tb[IFLA_MTU])
fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
if (tb[IFLA_QDISC])
- fprintf(fp, "qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC]));
+ fprintf(fp, "qdisc %s ", rta_getattr_str(tb[IFLA_QDISC]));
if (tb[IFLA_MASTER]) {
SPRINT_BUF(b1);
fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
}
if (tb[IFLA_OPERSTATE])
- print_operstate(fp, *(__u8 *)RTA_DATA(tb[IFLA_OPERSTATE]));
+ print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));
if (do_link && tb[IFLA_LINKMODE])
print_linkmode(fp, tb[IFLA_LINKMODE]);
@@ -455,7 +465,7 @@ int print_linkinfo(const struct sockaddr_nl *who,
if (do_link && tb[IFLA_IFALIAS])
fprintf(fp,"\n alias %s",
- (const char *) RTA_DATA(tb[IFLA_IFALIAS]));
+ rta_getattr_str(tb[IFLA_IFALIAS]));
if (do_link && show_stats) {
if (tb[IFLA_STATS64])
@@ -660,7 +670,7 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
if (ifa_flags)
fprintf(fp, "flags %02x ", ifa_flags);
if (rta_tb[IFA_LABEL])
- fprintf(fp, "%s", (char*)RTA_DATA(rta_tb[IFA_LABEL]));
+ fprintf(fp, "%s", rta_getattr_str(rta_tb[IFA_LABEL]));
if (rta_tb[IFA_CACHEINFO]) {
struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]);
fprintf(fp, "%s", _SL_);
diff --git a/ip/ipl2tp.c b/ip/ipl2tp.c
index 97f98b6..c5683f5 100644
--- a/ip/ipl2tp.c
+++ b/ip/ipl2tp.c
@@ -488,7 +488,7 @@ static void usage(void)
fprintf(stderr, " tunnel_id ID peer_tunnel_id ID\n");
fprintf(stderr, " [ encap { ip | udp } ]\n");
fprintf(stderr, " [ udp_sport PORT ] [ udp_dport PORT ]\n");
- fprintf(stderr, "Usage: ip l2tp add session\n");
+ fprintf(stderr, "Usage: ip l2tp add session [ name NAME ]\n");
fprintf(stderr, " tunnel_id ID\n");
fprintf(stderr, " session_id ID peer_session_id ID\n");
fprintf(stderr, " [ cookie HEXSTR ] [ peer_cookie HEXSTR ]\n");
@@ -524,6 +524,9 @@ static int parse_args(int argc, char **argv, int cmd, struct l2tp_parm *p)
fprintf(stderr, "Unknown tunnel encapsulation.\n");
exit(-1);
}
+ } else if (strcmp(*argv, "name") == 0) {
+ NEXT_ARG();
+ p->ifname = *argv;
} else if (strcmp(*argv, "remote") == 0) {
NEXT_ARG();
p->peer_ip.s_addr = get_addr32(*argv);
diff --git a/ip/iplink.c b/ip/iplink.c
index 8dc089a..447ae3d 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -38,7 +38,7 @@
#define IPLINK_IOCTL_COMPAT 1
#ifndef LIBDIR
-#define LIBDIR "/usr/lib/"
+#define LIBDIR "/usr/lib"
#endif
static void usage(void) __attribute__((noreturn));
@@ -138,9 +138,9 @@ struct link_util *get_link_kind(const char *id)
int get_link_mode(const char *mode)
{
- if (strcmp(mode, "default") == 0)
+ if (strcasecmp(mode, "default") == 0)
return IF_LINK_MODE_DEFAULT;
- if (strcmp(mode, "dormant") == 0)
+ if (strcasecmp(mode, "dormant") == 0)
return IF_LINK_MODE_DORMANT;
return -1;
}
@@ -437,10 +437,18 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
} else if (strcmp(*argv, "mode") == 0) {
int mode;
NEXT_ARG();
- mode = get_link_mode(*argv);
+ mode = get_link_mode(*argv);
if (mode < 0)
invarg("Invalid link mode\n", *argv);
addattr8(&req->n, sizeof(*req), IFLA_LINKMODE, mode);
+ } else if (strcmp(*argv, "state") == 0) {
+ int state;
+ NEXT_ARG();
+ state = get_operstate(*argv);
+ if (state < 0)
+ invarg("Invalid operstate\n", *argv);
+
+ addattr8(&req->n, sizeof(*req), IFLA_OPERSTATE, state);
} else {
if (strcmp(*argv, "dev") == 0) {
NEXT_ARG();
diff --git a/ip/iplink_macvlan.c b/ip/iplink_macvlan.c
index 15022aa..ed0e34b 100644
--- a/ip/iplink_macvlan.c
+++ b/ip/iplink_macvlan.c
@@ -79,7 +79,7 @@ static void macvlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]
RTA_PAYLOAD(tb[IFLA_MACVLAN_MODE]) < sizeof(__u32))
return;
- mode = *(__u32 *)RTA_DATA(tb[IFLA_VLAN_ID]);
+ mode = rta_getattr_u32(tb[IFLA_VLAN_ID]);
fprintf(f, " mode %s ",
mode == MACVLAN_MODE_PRIVATE ? "private"
: mode == MACVLAN_MODE_VEPA ? "vepa"
diff --git a/ip/iplink_macvtap.c b/ip/iplink_macvtap.c
index 07aed4e..6c7fe1f 100644
--- a/ip/iplink_macvtap.c
+++ b/ip/iplink_macvtap.c
@@ -76,7 +76,7 @@ static void macvtap_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]
RTA_PAYLOAD(tb[IFLA_MACVLAN_MODE]) < sizeof(__u32))
return;
- mode = *(__u32 *)RTA_DATA(tb[IFLA_VLAN_ID]);
+ mode = rta_getattr_u32(tb[IFLA_VLAN_ID]);
fprintf(f, " mode %s ",
mode == MACVLAN_MODE_PRIVATE ? "private"
: mode == MACVLAN_MODE_VEPA ? "vepa"
diff --git a/ip/iplink_vlan.c b/ip/iplink_vlan.c
index 223feb3..97af8d6 100644
--- a/ip/iplink_vlan.c
+++ b/ip/iplink_vlan.c
@@ -183,7 +183,7 @@ static void vlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
RTA_PAYLOAD(tb[IFLA_VLAN_ID]) < sizeof(__u16))
return;
- fprintf(f, "id %u ", *(__u16 *)RTA_DATA(tb[IFLA_VLAN_ID]));
+ fprintf(f, "id %u ", rta_getattr_u16(tb[IFLA_VLAN_ID]));
if (tb[IFLA_VLAN_FLAGS]) {
if (RTA_PAYLOAD(tb[IFLA_VLAN_FLAGS]) < sizeof(*flags))
diff --git a/ip/ipneigh.c b/ip/ipneigh.c
index 313cc63..93cfba2 100644
--- a/ip/ipneigh.c
+++ b/ip/ipneigh.c
@@ -282,7 +282,7 @@ int print_neigh(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
}
if (tb[NDA_PROBES] && show_stats) {
- __u32 p = *(__u32 *) RTA_DATA(tb[NDA_PROBES]);
+ __u32 p = rta_getattr_u32(tb[NDA_PROBES]);
fprintf(fp, " probes %u", p);
}
diff --git a/ip/ipntable.c b/ip/ipntable.c
index b00d3dc..639f512 100644
--- a/ip/ipntable.c
+++ b/ip/ipntable.c
@@ -376,7 +376,7 @@ int print_ntable(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
n->nlmsg_len - NLMSG_LENGTH(sizeof(*ndtm)));
if (tb[NDTA_NAME]) {
- char *name = RTA_DATA(tb[NDTA_NAME]);
+ const char *name = rta_getattr_str(tb[NDTA_NAME]);
if (strlen(filter.name) > 0 && strcmp(filter.name, name))
return 0;
@@ -386,7 +386,7 @@ int print_ntable(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
RTA_PAYLOAD(tb[NDTA_PARMS]));
if (tpb[NDTPA_IFINDEX]) {
- __u32 ifindex = *(__u32 *)RTA_DATA(tpb[NDTPA_IFINDEX]);
+ __u32 ifindex = rta_getattr_u32(tpb[NDTPA_IFINDEX]);
if (filter.index && filter.index != ifindex)
return 0;
@@ -406,7 +406,7 @@ int print_ntable(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
fprintf(fp, "(%d) ", ndtm->ndtm_family);
if (tb[NDTA_NAME]) {
- char *name = RTA_DATA(tb[NDTA_NAME]);
+ const char *name = rta_getattr_str(tb[NDTA_NAME]);
fprintf(fp, "%s ", name);
}
@@ -418,19 +418,19 @@ int print_ntable(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
fprintf(fp, " ");
if (tb[NDTA_THRESH1]) {
- __u32 thresh1 = *(__u32 *)RTA_DATA(tb[NDTA_THRESH1]);
+ __u32 thresh1 = rta_getattr_u32(tb[NDTA_THRESH1]);
fprintf(fp, "thresh1 %u ", thresh1);
}
if (tb[NDTA_THRESH2]) {
- __u32 thresh2 = *(__u32 *)RTA_DATA(tb[NDTA_THRESH2]);
+ __u32 thresh2 = rta_getattr_u32(tb[NDTA_THRESH2]);
fprintf(fp, "thresh2 %u ", thresh2);
}
if (tb[NDTA_THRESH3]) {
- __u32 thresh3 = *(__u32 *)RTA_DATA(tb[NDTA_THRESH3]);
+ __u32 thresh3 = rta_getattr_u32(tb[NDTA_THRESH3]);
fprintf(fp, "thresh3 %u ", thresh3);
}
if (tb[NDTA_GC_INTERVAL]) {
- __u64 gc_int = *(__u64 *)RTA_DATA(tb[NDTA_GC_INTERVAL]);
+ __u64 gc_int = rta_getattr_u64(tb[NDTA_GC_INTERVAL]);
fprintf(fp, "gc_int %llu ", gc_int);
}
@@ -469,7 +469,7 @@ int print_ntable(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
if (tb[NDTA_PARMS]) {
if (tpb[NDTPA_IFINDEX]) {
- __u32 ifindex = *(__u32 *)RTA_DATA(tpb[NDTPA_IFINDEX]);
+ __u32 ifindex = rta_getattr_u32(tpb[NDTPA_IFINDEX]);
fprintf(fp, " ");
fprintf(fp, "dev %s ", ll_index_to_name(ifindex));
@@ -479,19 +479,19 @@ int print_ntable(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
fprintf(fp, " ");
if (tpb[NDTPA_REFCNT]) {
- __u32 refcnt = *(__u32 *)RTA_DATA(tpb[NDTPA_REFCNT]);
+ __u32 refcnt = rta_getattr_u32(tpb[NDTPA_REFCNT]);
fprintf(fp, "refcnt %u ", refcnt);
}
if (tpb[NDTPA_REACHABLE_TIME]) {
- __u64 reachable = *(__u64 *)RTA_DATA(tpb[NDTPA_REACHABLE_TIME]);
+ __u64 reachable = rta_getattr_u64(tpb[NDTPA_REACHABLE_TIME]);
fprintf(fp, "reachable %llu ", reachable);
}
if (tpb[NDTPA_BASE_REACHABLE_TIME]) {
- __u64 breachable = *(__u64 *)RTA_DATA(tpb[NDTPA_BASE_REACHABLE_TIME]);
+ __u64 breachable = rta_getattr_u64(tpb[NDTPA_BASE_REACHABLE_TIME]);
fprintf(fp, "base_reachable %llu ", breachable);
}
if (tpb[NDTPA_RETRANS_TIME]) {
- __u64 retrans = *(__u64 *)RTA_DATA(tpb[NDTPA_RETRANS_TIME]);
+ __u64 retrans = rta_getattr_u64(tpb[NDTPA_RETRANS_TIME]);
fprintf(fp, "retrans %llu ", retrans);
}
@@ -500,15 +500,15 @@ int print_ntable(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
fprintf(fp, " ");
if (tpb[NDTPA_GC_STALETIME]) {
- __u64 gc_stale = *(__u64 *)RTA_DATA(tpb[NDTPA_GC_STALETIME]);
+ __u64 gc_stale = rta_getattr_u64(tpb[NDTPA_GC_STALETIME]);
fprintf(fp, "gc_stale %llu ", gc_stale);
}
if (tpb[NDTPA_DELAY_PROBE_TIME]) {
- __u64 delay_probe = *(__u64 *)RTA_DATA(tpb[NDTPA_DELAY_PROBE_TIME]);
+ __u64 delay_probe = rta_getattr_u64(tpb[NDTPA_DELAY_PROBE_TIME]);
fprintf(fp, "delay_probe %llu ", delay_probe);
}
if (tpb[NDTPA_QUEUE_LEN]) {
- __u32 queue = *(__u32 *)RTA_DATA(tpb[NDTPA_QUEUE_LEN]);
+ __u32 queue = rta_getattr_u32(tpb[NDTPA_QUEUE_LEN]);
fprintf(fp, "queue %u ", queue);
}
@@ -517,15 +517,15 @@ int print_ntable(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
fprintf(fp, " ");
if (tpb[NDTPA_APP_PROBES]) {
- __u32 aprobe = *(__u32 *)RTA_DATA(tpb[NDTPA_APP_PROBES]);
+ __u32 aprobe = rta_getattr_u32(tpb[NDTPA_APP_PROBES]);
fprintf(fp, "app_probes %u ", aprobe);
}
if (tpb[NDTPA_UCAST_PROBES]) {
- __u32 uprobe = *(__u32 *)RTA_DATA(tpb[NDTPA_UCAST_PROBES]);
+ __u32 uprobe = rta_getattr_u32(tpb[NDTPA_UCAST_PROBES]);
fprintf(fp, "ucast_probes %u ", uprobe);
}
if (tpb[NDTPA_MCAST_PROBES]) {
- __u32 mprobe = *(__u32 *)RTA_DATA(tpb[NDTPA_MCAST_PROBES]);
+ __u32 mprobe = rta_getattr_u32(tpb[NDTPA_MCAST_PROBES]);
fprintf(fp, "mcast_probes %u ", mprobe);
}
@@ -534,19 +534,19 @@ int print_ntable(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
fprintf(fp, " ");
if (tpb[NDTPA_ANYCAST_DELAY]) {
- __u64 anycast_delay = *(__u64 *)RTA_DATA(tpb[NDTPA_ANYCAST_DELAY]);
+ __u64 anycast_delay = rta_getattr_u64(tpb[NDTPA_ANYCAST_DELAY]);
fprintf(fp, "anycast_delay %llu ", anycast_delay);
}
if (tpb[NDTPA_PROXY_DELAY]) {
- __u64 proxy_delay = *(__u64 *)RTA_DATA(tpb[NDTPA_PROXY_DELAY]);
+ __u64 proxy_delay = rta_getattr_u64(tpb[NDTPA_PROXY_DELAY]);
fprintf(fp, "proxy_delay %llu ", proxy_delay);
}
if (tpb[NDTPA_PROXY_QLEN]) {
- __u32 pqueue = *(__u32 *)RTA_DATA(tpb[NDTPA_PROXY_QLEN]);
+ __u32 pqueue = rta_getattr_u32(tpb[NDTPA_PROXY_QLEN]);
fprintf(fp, "proxy_queue %u ", pqueue);
}
if (tpb[NDTPA_LOCKTIME]) {
- __u64 locktime = *(__u64 *)RTA_DATA(tpb[NDTPA_LOCKTIME]);
+ __u64 locktime = rta_getattr_u64(tpb[NDTPA_LOCKTIME]);
fprintf(fp, "locktime %llu ", locktime);
}
diff --git a/ip/iproute.c b/ip/iproute.c
index c97f979..5cd313e 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -227,7 +227,7 @@ int filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
if (filter.realmmask) {
__u32 realms = 0;
if (tb[RTA_FLOW])
- realms = *(__u32*)RTA_DATA(tb[RTA_FLOW]);
+ realms = rta_getattr_u32(tb[RTA_FLOW]);
if ((realms^filter.realm)&filter.realmmask)
return 0;
}
@@ -404,7 +404,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
abuf, sizeof(abuf)));
}
if (tb[RTA_PRIORITY])
- fprintf(fp, " metric %d ", *(__u32*)RTA_DATA(tb[RTA_PRIORITY]));
+ fprintf(fp, " metric %u ", rta_getattr_u32(tb[RTA_PRIORITY]));
if (r->rtm_flags & RTNH_F_DEAD)
fprintf(fp, "dead ");
if (r->rtm_flags & RTNH_F_ONLINK)
@@ -424,7 +424,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
}
if (tb[RTA_FLOW] && filter.realmmask != ~0U) {
- __u32 to = *(__u32*)RTA_DATA(tb[RTA_FLOW]);
+ __u32 to = rta_getattr_u32(tb[RTA_FLOW]);
__u32 from = to>>16;
to &= 0xFFFF;
fprintf(fp, "realm%s ", from ? "s" : "");
@@ -589,7 +589,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
abuf, sizeof(abuf)));
}
if (tb[RTA_FLOW]) {
- __u32 to = *(__u32*)RTA_DATA(tb[RTA_FLOW]);
+ __u32 to = rta_getattr_u32(tb[RTA_FLOW]);
__u32 from = to>>16;
to &= 0xFFFF;
fprintf(fp, " realm%s ", from ? "s" : "");
diff --git a/ip/iprule.c b/ip/iprule.c
index f983731..a5fcd43 100644
--- a/ip/iprule.c
+++ b/ip/iprule.c
@@ -131,23 +131,23 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
__u32 mark = 0, mask = 0;
if (tb[FRA_FWMARK])
- mark = *(__u32*)RTA_DATA(tb[FRA_FWMARK]);
+ mark = rta_getattr_u32(tb[FRA_FWMARK]);
if (tb[FRA_FWMASK] &&
- (mask = *(__u32*)RTA_DATA(tb[FRA_FWMASK])) != 0xFFFFFFFF)
+ (mask = rta_getattr_u32(tb[FRA_FWMASK])) != 0xFFFFFFFF)
fprintf(fp, "fwmark 0x%x/0x%x ", mark, mask);
else
fprintf(fp, "fwmark 0x%x ", mark);
}
if (tb[FRA_IFNAME]) {
- fprintf(fp, "iif %s ", (char*)RTA_DATA(tb[FRA_IFNAME]));
+ fprintf(fp, "iif %s ", rta_getattr_str(tb[FRA_IFNAME]));
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]));
+ fprintf(fp, "oif %s ", rta_getattr_str(tb[FRA_OIFNAME]));
if (r->rtm_flags & FIB_RULE_OIF_DETACHED)
fprintf(fp, "[detached] ");
}
@@ -157,7 +157,7 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
fprintf(fp, "lookup %s ", rtnl_rttable_n2a(table, b1, sizeof(b1)));
if (tb[FRA_FLOW]) {
- __u32 to = *(__u32*)RTA_DATA(tb[FRA_FLOW]);
+ __u32 to = rta_getattr_u32(tb[FRA_FLOW]);
__u32 from = to>>16;
to &= 0xFFFF;
if (from) {
@@ -180,7 +180,7 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
} else if (r->rtm_type == FR_ACT_GOTO) {
fprintf(fp, "goto ");
if (tb[FRA_GOTO])
- fprintf(fp, "%u", *(__u32 *) RTA_DATA(tb[FRA_GOTO]));
+ fprintf(fp, "%u", rta_getattr_u32(tb[FRA_GOTO]));
else
fprintf(fp, "none");
if (r->rtm_flags & FIB_RULE_UNRESOLVED)
diff --git a/ip/ipxfrm.c b/ip/ipxfrm.c
index adeac60..6be62e0 100644
--- a/ip/ipxfrm.c
+++ b/ip/ipxfrm.c
@@ -809,7 +809,7 @@ void xfrm_xfrma_print(struct rtattr *tb[], __u16 family,
return;
}
- lastused = *(__u64 *)RTA_DATA(tb[XFRMA_LASTUSED]);
+ lastused = rta_getattr_u64(tb[XFRMA_LASTUSED]);
fprintf(fp, "%s", strxf_time(lastused));
fprintf(fp, "%s", _SL_);
diff --git a/ip/link_gre.c b/ip/link_gre.c
index 5002095..839fb29 100644
--- a/ip/link_gre.c
+++ b/ip/link_gre.c
@@ -98,35 +98,35 @@ get_failed:
linkinfo[IFLA_INFO_DATA]);
if (greinfo[IFLA_GRE_IKEY])
- ikey = *(__u32 *)RTA_DATA(greinfo[IFLA_GRE_IKEY]);
+ ikey = rta_getattr_u32(greinfo[IFLA_GRE_IKEY]);
if (greinfo[IFLA_GRE_OKEY])
- okey = *(__u32 *)RTA_DATA(greinfo[IFLA_GRE_OKEY]);
+ okey = rta_getattr_u32(greinfo[IFLA_GRE_OKEY]);
if (greinfo[IFLA_GRE_IFLAGS])
- iflags = *(__u16 *)RTA_DATA(greinfo[IFLA_GRE_IFLAGS]);
+ iflags = rta_getattr_u16(greinfo[IFLA_GRE_IFLAGS]);
if (greinfo[IFLA_GRE_OFLAGS])
- oflags = *(__u16 *)RTA_DATA(greinfo[IFLA_GRE_OFLAGS]);
+ oflags = rta_getattr_u16(greinfo[IFLA_GRE_OFLAGS]);
if (greinfo[IFLA_GRE_LOCAL])
- saddr = *(__u32 *)RTA_DATA(greinfo[IFLA_GRE_LOCAL]);
+ saddr = rta_getattr_u32(greinfo[IFLA_GRE_LOCAL]);
if (greinfo[IFLA_GRE_REMOTE])
- daddr = *(__u32 *)RTA_DATA(greinfo[IFLA_GRE_REMOTE]);
+ daddr = rta_getattr_u32(greinfo[IFLA_GRE_REMOTE]);
if (greinfo[IFLA_GRE_PMTUDISC])
- pmtudisc = *(__u8 *)RTA_DATA(
+ pmtudisc = rta_getattr_u8(
greinfo[IFLA_GRE_PMTUDISC]);
if (greinfo[IFLA_GRE_TTL])
- ttl = *(__u8 *)RTA_DATA(greinfo[IFLA_GRE_TTL]);
+ ttl = rta_getattr_u8(greinfo[IFLA_GRE_TTL]);
if (greinfo[IFLA_GRE_TOS])
- tos = *(__u8 *)RTA_DATA(greinfo[IFLA_GRE_TOS]);
+ tos = rta_getattr_u8(greinfo[IFLA_GRE_TOS]);
if (greinfo[IFLA_GRE_LINK])
- link = *(__u8 *)RTA_DATA(greinfo[IFLA_GRE_LINK]);
+ link = rta_getattr_u8(greinfo[IFLA_GRE_LINK]);
}
while (argc > 0) {
@@ -279,7 +279,7 @@ static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
return;
if (tb[IFLA_GRE_REMOTE]) {
- unsigned addr = *(__u32 *)RTA_DATA(tb[IFLA_GRE_REMOTE]);
+ unsigned addr = rta_getattr_u32(tb[IFLA_GRE_REMOTE]);
if (addr)
remote = format_host(AF_INET, 4, &addr, s1, sizeof(s1));
@@ -288,7 +288,7 @@ static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
fprintf(f, "remote %s ", remote);
if (tb[IFLA_GRE_LOCAL]) {
- unsigned addr = *(__u32 *)RTA_DATA(tb[IFLA_GRE_LOCAL]);
+ unsigned addr = rta_getattr_u32(tb[IFLA_GRE_LOCAL]);
if (addr)
local = format_host(AF_INET, 4, &addr, s1, sizeof(s1));
@@ -296,8 +296,8 @@ static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
fprintf(f, "local %s ", local);
- if (tb[IFLA_GRE_LINK] && *(__u32 *)RTA_DATA(tb[IFLA_GRE_LINK])) {
- unsigned link = *(__u32 *)RTA_DATA(tb[IFLA_GRE_LINK]);
+ if (tb[IFLA_GRE_LINK] && rta_getattr_u32(tb[IFLA_GRE_LINK])) {
+ unsigned link = rta_getattr_u32(tb[IFLA_GRE_LINK]);
const char *n = if_indextoname(link, s2);
if (n)
@@ -306,13 +306,13 @@ static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
fprintf(f, "dev %u ", link);
}
- if (tb[IFLA_GRE_TTL] && *(__u8 *)RTA_DATA(tb[IFLA_GRE_TTL]))
- fprintf(f, "ttl %d ", *(__u8 *)RTA_DATA(tb[IFLA_GRE_TTL]));
+ if (tb[IFLA_GRE_TTL] && rta_getattr_u8(tb[IFLA_GRE_TTL]))
+ fprintf(f, "ttl %d ", rta_getattr_u8(tb[IFLA_GRE_TTL]));
else
fprintf(f, "ttl inherit ");
- if (tb[IFLA_GRE_TOS] && *(__u8 *)RTA_DATA(tb[IFLA_GRE_TOS])) {
- int tos = *(__u8 *)RTA_DATA(tb[IFLA_GRE_TOS]);
+ if (tb[IFLA_GRE_TOS] && rta_getattr_u8(tb[IFLA_GRE_TOS])) {
+ int tos = rta_getattr_u8(tb[IFLA_GRE_TOS]);
fputs("tos ", f);
if (tos == 1)
@@ -322,14 +322,14 @@ static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
}
if (tb[IFLA_GRE_PMTUDISC] &&
- !*(__u8 *)RTA_DATA(tb[IFLA_GRE_PMTUDISC]))
+ !rta_getattr_u8(tb[IFLA_GRE_PMTUDISC]))
fputs("nopmtudisc ", f);
if (tb[IFLA_GRE_IFLAGS])
- iflags = *(__u16 *)RTA_DATA(tb[IFLA_GRE_IFLAGS]);
+ iflags = rta_getattr_u16(tb[IFLA_GRE_IFLAGS]);
if (tb[IFLA_GRE_OFLAGS])
- oflags = *(__u16 *)RTA_DATA(tb[IFLA_GRE_OFLAGS]);
+ oflags = rta_getattr_u16(tb[IFLA_GRE_OFLAGS]);
if ((iflags & GRE_KEY) && tb[IFLA_GRE_IKEY]) {
inet_ntop(AF_INET, RTA_DATA(tb[IFLA_GRE_IKEY]), s2, sizeof(s2));
diff --git a/lib/Android.mk b/lib/Android.mk
index 76af7f1..d96e34c 100644
--- a/lib/Android.mk
+++ b/lib/Android.mk
@@ -5,7 +5,7 @@ LOCAL_SRC_FILES := utils.c rt_names.c ll_types.c ll_proto.c ll_addr.c inet_proto
LOCAL_MODULE := libiprouteutil
LOCAL_SYSTEM_SHARED_LIBRARIES := libc
LOCAL_C_INCLUDES := $(KERNEL_HEADERS) external/iproute2/include
-LOCAL_CFLAGS := -O2 -g -W -Wall \
+LOCAL_CFLAGS := -O2 -g -Wall -Wstrict-prototypes \
-DHAVE_UNISTD_H \
-DHAVE_ERRNO_H \
-DHAVE_NETINET_IN_H \
@@ -34,7 +34,7 @@ LOCAL_SRC_FILES := ll_map.c libnetlink.c
LOCAL_MODULE := libnetlink
LOCAL_SYSTEM_SHARED_LIBRARIES := libc
LOCAL_C_INCLUDES := $(KERNEL_HEADERS) external/iproute2/include
-LOCAL_CFLAGS := -O2 -g -W -Wall \
+LOCAL_CFLAGS := -O2 -g -Wall -Wstrict-prototypes \
-DHAVE_UNISTD_H \
-DHAVE_ERRNO_H \
-DHAVE_NETINET_IN_H \
diff --git a/lib/libnetlink.c b/lib/libnetlink.c
index c581e11..a74162f 100644
--- a/lib/libnetlink.c
+++ b/lib/libnetlink.c
@@ -10,6 +10,12 @@
*
*/
+#ifdef ANDROID
+/* Make sure to include the shipped if_link.h before anything
+ * else pulls in the bionic linux headers */
+#include <shipped/linux/if_link.h>
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -94,6 +100,9 @@ int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type)
struct {
struct nlmsghdr nlh;
struct rtgenmsg g;
+ __u16 align_rta; /* attribute has to be 32bit aligned */
+ struct rtattr ext_req;
+ __u32 ext_filter_mask;
} req;
memset(&req, 0, sizeof(req));
@@ -104,6 +113,10 @@ int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type)
req.nlh.nlmsg_seq = rth->dump = ++rth->seq;
req.g.rtgen_family = family;
+ req.ext_req.rta_type = IFLA_EXT_MASK;
+ req.ext_req.rta_len = RTA_LENGTH(sizeof(__u32));
+ req.ext_filter_mask = RTEXT_FILTER_VF;
+
return send(rth->fd, (void*)&req, sizeof(req), 0);
}
diff --git a/lib/rt_names.c b/lib/rt_names.c
index a290021..52ecdb2 100644
--- a/lib/rt_names.c
+++ b/lib/rt_names.c
@@ -23,6 +23,10 @@
#include "rt_names.h"
+#ifndef CONFDIR
+#define CONFDIR "/etc/iproute2"
+#endif
+
struct rtnl_hash_entry {
struct rtnl_hash_entry *next;
char * name;
@@ -129,7 +133,7 @@ static int rtnl_rtprot_init;
static void rtnl_rtprot_initialize(void)
{
rtnl_rtprot_init = 1;
- rtnl_tab_initialize("/etc/iproute2/rt_protos",
+ rtnl_tab_initialize(CONFDIR "/rt_protos",
rtnl_rtprot_tab, 256);
}
@@ -196,7 +200,7 @@ static void rtnl_rtscope_initialize(void)
rtnl_rtscope_tab[254] = "host";
rtnl_rtscope_tab[253] = "link";
rtnl_rtscope_tab[200] = "site";
- rtnl_tab_initialize("/etc/iproute2/rt_scopes",
+ rtnl_tab_initialize(CONFDIR "/rt_scopes",
rtnl_rtscope_tab, 256);
}
@@ -259,7 +263,7 @@ static int rtnl_rtrealm_init;
static void rtnl_rtrealm_initialize(void)
{
rtnl_rtrealm_init = 1;
- rtnl_tab_initialize("/etc/iproute2/rt_realms",
+ rtnl_tab_initialize(CONFDIR "/rt_realms",
rtnl_rtrealm_tab, 256);
}
@@ -328,7 +332,7 @@ static int rtnl_rttable_init;
static void rtnl_rttable_initialize(void)
{
rtnl_rttable_init = 1;
- rtnl_hash_initialize("/etc/iproute2/rt_tables",
+ rtnl_hash_initialize(CONFDIR "/rt_tables",
rtnl_rttable_hash, 256);
}
@@ -396,7 +400,7 @@ static int rtnl_rtdsfield_init;
static void rtnl_rtdsfield_initialize(void)
{
rtnl_rtdsfield_init = 1;
- rtnl_tab_initialize("/etc/iproute2/rt_dsfield",
+ rtnl_tab_initialize(CONFDIR "/rt_dsfield",
rtnl_rtdsfield_tab, 256);
}
diff --git a/man/Makefile b/man/Makefile
new file mode 100644
index 0000000..67fea05
--- /dev/null
+++ b/man/Makefile
@@ -0,0 +1,20 @@
+INSTALL=install
+INSTALLDIR=install -m 0755 -d
+INSTALLMAN=install -m 0644
+
+SUBDIRS = man3 man8
+
+all:
+ @for subdir in $(SUBDIRS); do $(MAKE) -C $$subdir; done
+
+distclean: clean
+
+clean:
+ @for subdir in $(SUBDIRS); do $(MAKE) -C $$subdir clean; done
+
+install:
+ @for subdir in $(SUBDIRS); do $(MAKE) -C $$subdir install; done
+
+.PHONY: install clean distclean
+
+.EXPORT_ALL_VARIABLES:
diff --git a/man/man3/Makefile b/man/man3/Makefile
new file mode 100644
index 0000000..bf55658
--- /dev/null
+++ b/man/man3/Makefile
@@ -0,0 +1,13 @@
+MAN3PAGES=libnetlink.3
+
+all:
+
+distclean: clean
+
+clean:
+
+install:
+ $(INSTALLDIR) $(DESTDIR)$(MANDIR)/man3
+ $(INSTALLMAN) $(MAN3PAGES) $(DESTDIR)$(MANDIR)/man3
+
+.PHONY: install clean distclean
diff --git a/man/man8/Makefile b/man/man8/Makefile
new file mode 100644
index 0000000..6873a4b
--- /dev/null
+++ b/man/man8/Makefile
@@ -0,0 +1,32 @@
+TARGETS = ip-address.8 ip-link.8 ip-route.8
+
+MAN8PAGES = $(TARGETS) ip.8 arpd.8 lnstat.8 routel.8 rtacct.8 rtmon.8 ss.8 \
+ tc-bfifo.8 tc-cbq-details.8 tc-cbq.8 tc-drr.8 tc-htb.8 \
+ tc-pfifo.8 tc-pfifo_fast.8 tc-prio.8 tc-red.8 tc-sfq.8 \
+ tc-tbf.8 tc.8 rtstat.8 ctstat.8 nstat.8 routef.8 \
+ tc-sfb.8 tc-netem.8 tc-choke.8 ip-tunnel.8 ip-rule.8 ip-ntable.8 \
+ ip-monitor.8 tc-stab.8 tc-hfsc.8 ip-xfrm.8 ip-netns.8 \
+ ip-neighbour.8 ip-mroute.8 ip-maddress.8 ip-addrlabel.8
+
+
+all: $(TARGETS)
+
+ip-address.8: ip-address.8.in
+ sed "s|@SYSCONFDIR@|$(CONFDIR)|g" $< > $@
+
+ip-link.8: ip-link.8.in
+ sed "s|@SYSCONFDIR@|$(CONFDIR)|g" $< > $@
+
+ip-route.8: ip-route.8.in
+ sed "s|@SYSCONFDIR@|$(CONFDIR)|g" $< > $@
+
+distclean: clean
+
+clean:
+ @rm -f $(TARGETS)
+
+install:
+ $(INSTALLDIR) $(DESTDIR)$(MANDIR)/man8
+ $(INSTALLMAN) $(MAN8PAGES) $(DESTDIR)$(MANDIR)/man8
+
+.PHONY: install clean distclean
diff --git a/man/man8/ctstat.8 b/man/man8/ctstat.8
new file mode 100644
index 0000000..080e2b2
--- /dev/null
+++ b/man/man8/ctstat.8
@@ -0,0 +1 @@
+.so man8/lnstat.8
diff --git a/man/man8/ip-address.8.in b/man/man8/ip-address.8.in
new file mode 100644
index 0000000..63bf9cb
--- /dev/null
+++ b/man/man8/ip-address.8.in
@@ -0,0 +1,240 @@
+.TH "IP\-ADDRESS" 8 "20 Dec 2011" "iproute2" "Linux"
+.SH "NAME"
+ip-address \- protocol address management
+.SH "SYNOPSIS"
+.sp
+.ad l
+.in +8
+.ti -8
+.B ip
+.RI "[ " OPTIONS " ]"
+.B address
+.RI " { " COMMAND " | "
+.BR help " }"
+.sp
+
+.ti -8
+.BR "ip address" " { " add " | " del " } "
+.IB IFADDR " dev " STRING
+
+.ti -8
+.BR "ip address" " { " show " | " flush " } [ " dev
+.IR STRING " ] [ "
+.B scope
+.IR SCOPE-ID " ] [ "
+.B to
+.IR PREFIX " ] [ " FLAG-LIST " ] [ "
+.B label
+.IR PATTERN " ]"
+
+.ti -8
+.IR IFADDR " := " PREFIX " | " ADDR
+.B peer
+.IR PREFIX " [ "
+.B broadcast
+.IR ADDR " ] [ "
+.B anycast
+.IR ADDR " ] [ "
+.B label
+.IR STRING " ] [ "
+.B scope
+.IR SCOPE-ID " ]"
+
+.ti -8
+.IR SCOPE-ID " := "
+.RB "[ " host " | " link " | " global " | "
+.IR NUMBER " ]"
+
+.ti -8
+.IR FLAG-LIST " := [ " FLAG-LIST " ] " FLAG
+
+.ti -8
+.IR FLAG " := "
+.RB "[ " permanent " | " dynamic " | " secondary " | " primary " | "\
+tentative " | " deprecated " | " dadfailed " | " temporary " ]"
+
+.SH "DESCRIPTION"
+The
+.B address
+is a protocol (IP or IPv6) address attached
+to a network device. Each device must have at least one address
+to use the corresponding protocol. It is possible to have several
+different addresses attached to one device. These addresses are not
+discriminated, so that the term
+.B alias
+is not quite appropriate for them and we do not use it in this document.
+.sp
+The
+.B ip address
+command displays addresses and their properties, adds new addresses
+and deletes old ones.
+
+.SS ip address add - add new protocol address.
+
+.TP
+.BI dev " NAME"
+the name of the device to add the address to.
+
+.TP
+.BI local " ADDRESS " (default)
+the address of the interface. The format of the address depends
+on the protocol. It is a dotted quad for IP and a sequence of
+hexadecimal halfwords separated by colons for IPv6. The
+.I ADDRESS
+may be followed by a slash and a decimal number which encodes
+the network prefix length.
+
+.TP
+.BI peer " ADDRESS"
+the address of the remote endpoint for pointopoint interfaces.
+Again, the
+.I ADDRESS
+may be followed by a slash and a decimal number, encoding the network
+prefix length. If a peer address is specified, the local address
+cannot have a prefix length. The network prefix is associated
+with the peer rather than with the local address.
+
+.TP
+.BI broadcast " ADDRESS"
+the broadcast address on the interface.
+.sp
+It is possible to use the special symbols
+.B '+'
+and
+.B '-'
+instead of the broadcast address. In this case, the broadcast address
+is derived by setting/resetting the host bits of the interface prefix.
+
+.TP
+.BI label " NAME"
+Each address may be tagged with a label string.
+In order to preserve compatibility with Linux-2.0 net aliases,
+this string must coincide with the name of the device or must be prefixed
+with the device name followed by colon.
+
+.TP
+.BI scope " SCOPE_VALUE"
+the scope of the area where this address is valid.
+The available scopes are listed in file
+.BR "@SYSCONFDIR@/rt_scopes" .
+Predefined scope values are:
+
+.in +8
+.B global
+- the address is globally valid.
+.sp
+.B site
+- (IPv6 only) the address is site local, i.e. it is
+valid inside this site.
+.sp
+.B link
+- the address is link local, i.e. it is valid only on this device.
+.sp
+.B host
+- the address is valid only inside this host.
+.in -8
+
+.SS ip address delete - delete protocol address
+.B Arguments:
+coincide with the arguments of
+.B ip addr add.
+The device name is a required argument. The rest are optional.
+If no arguments are given, the first address is deleted.
+
+.SS ip address show - look at protocol addresses
+
+.TP
+.BI dev " NAME " (default)
+name of device.
+
+.TP
+.BI scope " SCOPE_VAL"
+only list addresses with this scope.
+
+.TP
+.BI to " PREFIX"
+only list addresses matching this prefix.
+
+.TP
+.BI label " PATTERN"
+only list addresses with labels matching the
+.IR "PATTERN" .
+.I PATTERN
+is a usual shell style pattern.
+
+.TP
+.BR dynamic " and " permanent
+(IPv6 only) only list addresses installed due to stateless
+address configuration or only list permanent (not dynamic)
+addresses.
+
+.TP
+.B tentative
+(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.
+
+.SS ip address flush - flush protocol addresses
+This command flushes the protocol addresses selected by some criteria.
+
+.PP
+This command has the same arguments as
+.B show.
+The difference is that it does not run when no arguments are given.
+
+.PP
+.B Warning:
+This command (and other
+.B flush
+commands described below) is pretty dangerous. If you make a mistake,
+it will not forgive it, but will cruelly purge all the addresses.
+
+.PP
+With the
+.B -statistics
+option, the command becomes verbose. It prints out the number of deleted
+addresses and the number of rounds made to flush the address list. If
+this option is given twice,
+.B ip address flush
+also dumps all the deleted addresses in the format described in the
+previous subsection.
+
+.SH "EXAMPLES"
+.PP
+ip address show dev eth0
+.RS 4
+Shows the addresses assigned to network interface eth0
+.RE
+.PP
+ip addr add 2001:0db8:85a3::0370:7334/64 dev eth1
+.RS 4
+Adds an IPv6 address to network interface eth1
+.RE
+.PP
+ip addr flush dev eth4
+.RS 4
+Removes all addresses from device eth4
+.RE
+
+.SH SEE ALSO
+.br
+.BR ip (8)
+
+.SH AUTHOR
+Original Manpage by Michail Litvak <mci@owl.openwall.com>
diff --git a/man/man8/ip-l2tp.8 b/man/man8/ip-l2tp.8
new file mode 100644
index 0000000..18a83d4
--- /dev/null
+++ b/man/man8/ip-l2tp.8
@@ -0,0 +1,376 @@
+.TH IP\-L2TP 8 "19 Apr 2012" "iproute2" "Linux"
+.SH "NAME"
+ip-l2tp - L2TPv3 static unmanaged tunnel configuration
+.SH "SYNOPSIS"
+.sp
+.ad l
+.in +8
+.ti -8
+.B ip
+.RI "[ " OPTIONS " ]"
+.B l2tp
+.RI " { " COMMAND " | "
+.BR help " }"
+.sp
+.ti -8
+.BR "ip l2tp add tunnel"
+.br
+.B remote
+.RI "[ " ADDR " ]"
+.B local
+.RI "[ " ADDR " ]"
+.br
+.B tunnel_id
+.IR ID
+.B peer_tunnel_id
+.IR ID
+.br
+.RB "[ " encap " { " ip " | " udp " } ]"
+.br
+.RB "[ " udp_sport
+.IR PORT
+.RB " ] [ " udp_dport
+.IR PORT
+.RB " ]"
+.br
+.ti -8
+.BR "ip l2tp add session"
+.RB "[ " name
+.IR NAME
+.RB " ]"
+.br
+.B tunnel_id
+.IR ID
+.B session_id
+.IR ID
+.B peer_session_id
+.IR ID
+.br
+.RB "[ " cookie
+.IR HEXSTR
+.RB " ] [ " peer_cookie
+.IR HEXSTR
+.RB " ]"
+.br
+.RB "[ " offset
+.IR OFFSET
+.RB " ] [ " peer_offset
+.IR OFFSET
+.RB " ]"
+.br
+.ti -8
+.BR "ip l2tp del tunnel"
+.B tunnel_id
+.IR ID
+.br
+.ti -8
+.BR "ip l2tp del session"
+.B tunnel_id
+.IR ID
+.B session_id
+.IR ID
+.br
+.ti -8
+.BR "ip l2tp show tunnel"
+.B "[" tunnel_id
+.IR ID
+.B "]"
+.br
+.ti -8
+.BR "ip l2tp show session"
+.B "[" tunnel_id
+.IR ID
+.B "] [" session_id
+.IR ID
+.B "]"
+.br
+.ti -8
+.IR NAME " := "
+.IR STRING
+.ti -8
+.IR ADDR " := { " IP_ADDRESS " }"
+.ti -8
+.IR PORT " := { " NUMBER " }"
+.ti -8
+.IR ID " := { " NUMBER " }"
+.ti -8
+.ti -8
+.IR HEXSTR " := { 8 or 16 hex digits (4 / 8 bytes) }"
+.SH DESCRIPTION
+The
+.B ip l2tp
+commands are used to establish static, or so-called
+.I unmanaged
+L2TPv3 ethernet tunnels. For unmanaged tunnels, there is no L2TP
+control protocol so no userspace daemon is required - tunnels are
+manually created by issuing commands at a local system and at a remote
+peer.
+.PP
+L2TPv3 is suitable for Layer-2 tunnelling. Static tunnels are useful
+to establish network links across IP networks when the tunnels are
+fixed. L2TPv3 tunnels can carry data of more than one session. Each
+session is identified by a session_id and its parent tunnel's
+tunnel_id. A tunnel must be created before a session can be created in
+the tunnel.
+.PP
+When creating an L2TP tunnel, the IP address of the remote peer is
+specified, which can be either an IPv4 or IPv6 address. The local IP
+address to be used to reach the peer must also be specified. This is
+the address on which the local system will listen for and accept
+received L2TP data packets from the peer.
+.PP
+L2TPv3 defines two packet encapsulation formats: UDP or IP. UDP
+encapsulation is most common. IP encapsulation uses a dedicated IP
+protocol value to carry L2TP data without the overhead of UDP. Use IP
+encapsulation only when there are no NAT devices or firewalls in the
+network path.
+.PP
+When an L2TPv3 ethernet session is created, a virtual network
+interface is created for the session, which must then be configured
+and brought up, just like any other network interface. When data is
+passed through the interface, it is carried over the L2TP tunnel to
+the peer. By configuring the system's routing tables or adding the
+interface to a bridge, the L2TP interface is like a virtual wire
+(pseudowire) connected to the peer.
+.PP
+Establishing an unmanaged L2TPv3 ethernet pseudowire involves manually
+creating L2TP contexts on the local system and at the peer. Parameters
+used at each site must correspond or no data will be passed. No
+consistency checks are possible since there is no control protocol
+used to establish unmanaged L2TP tunnels. Once the virtual network
+interface of a given L2TP session is configured and enabled, data can
+be transmitted, even if the peer isn't yet configured. If the peer
+isn't configured, the L2TP data packets will be discarded by
+the peer.
+.PP
+To establish an unmanaged L2TP tunnel, use
+.B l2tp add tunnel
+and
+.B l2tp add session
+commands described in this document. Then configure and enable the
+tunnel's virtual network interface, as required.
+.PP
+Note that unmanaged tunnels carry only ethernet frames. If you need to
+carry PPP traffic (L2TPv2) or your peer doesn't support unmanaged
+L2TPv3 tunnels, you will need an L2TP server which implements the L2TP
+control protocol. The L2TP control protocol allows dynamic L2TP
+tunnels and sessions to be established and provides for detecting and
+acting upon network failures.
+.SS ip l2tp add tunnel - add a new tunnel
+.TP
+.BI name " NAME "
+sets the session network interface name. Default is l2tpethN.
+.TP
+.BI tunnel_id " ID"
+set the tunnel id, which is a 32-bit integer value. Uniquely
+identifies the tunnel. The value used must match the peer_tunnel_id
+value being used at the peer.
+.TP
+.BI peer_tunnel_id " ID"
+set the peer tunnel id, which is a 32-bit integer value assigned to
+the tunnel by the peer. The value used must match the tunnel_id value
+being used at the peer.
+.TP
+.BI remote " ADDR"
+set the IP address of the remote peer. May be specified as an IPv4
+address or an IPv6 address.
+.TP
+.BI local " ADDR"
+set the IP address of the local interface to be used for the
+tunnel. This address must be the address of a local interface. May be
+specified as an IPv4 address or an IPv6 address.
+.TP
+.BI encap " ENCAP"
+set the encapsulation type of the tunnel.
+.br
+Valid values for encapsulation are:
+.BR udp ", " ip "."
+.TP
+.BI udp_sport " PORT"
+set the UDP source port to be used for the tunnel. Must be present
+when udp encapsulation is selected. Ignored when ip encapsulation is
+selected.
+.TP
+.BI udp_dport " PORT"
+set the UDP destination port to be used for the tunnel. Must be
+present when udp encapsulation is selected. Ignored when ip
+encapsulation is selected.
+.SS ip l2tp del tunnel - destroy a tunnel
+.TP
+.BI tunnel_id " ID"
+set the tunnel id of the tunnel to be deleted. All sessions within the
+tunnel must be deleted first.
+.SS ip l2tp show tunnel - show information about tunnels
+.TP
+.BI tunnel_id " ID"
+set the tunnel id of the tunnel to be shown. If not specified,
+information about all tunnels is printed.
+.SS ip l2tp add session - add a new session to a tunnel
+.TP
+.BI name " NAME "
+sets the session network interface name. Default is l2tpethN.
+.TP
+.BI tunnel_id " ID"
+set the tunnel id, which is a 32-bit integer value. Uniquely
+identifies the tunnel into which the session will be created. The
+tunnel must already exist.
+.TP
+.BI session_id " ID"
+set the session id, which is a 32-bit integer value. Uniquely
+identifies the session being created. The value used must match the
+peer_session_id value being used at the peer.
+.TP
+.BI peer_session_id " ID"
+set the peer session id, which is a 32-bit integer value assigned to
+the session by the peer. The value used must match the session_id
+value being used at the peer.
+.TP
+.BI cookie " HEXSTR"
+sets an optional cookie value to be assigned to the session. This is a
+4 or 8 byte value, specified as 8 or 16 hex digits,
+e.g. 014d3636deadbeef. The value must match the peer_cookie value set
+at the peer. The cookie value is carried in L2TP data packets and is
+checked for expected value at the peer. Default is to use no cookie.
+.TP
+.BI peer_cookie " HEXSTR"
+sets an optional peer cookie value to be assigned to the session. This
+is a 4 or 8 byte value, specified as 8 or 16 hex digits,
+e.g. 014d3636deadbeef. The value must match the cookie value set at
+the peer. It tells the local system what cookie value to expect to
+find in received L2TP packets. Default is to use no cookie.
+.TP
+.BI offset " OFFSET"
+sets the byte offset from the L2TP header where user data starts in
+transmitted L2TP data packets. This is hardly ever used. If set, the
+value must match the peer_offset value used at the peer. Default is 0.
+.TP
+.BI peer_offset " OFFSET"
+sets the byte offset from the L2TP header where user data starts in
+received L2TP data packets. This is hardly ever used. If set, the
+value must match the offset value used at the peer. Default is 0.
+.SS ip l2tp del session - destroy a session
+.TP
+.BI tunnel_id " ID"
+set the tunnel id in which the session to be deleted is located.
+.TP
+.BI session_id " ID"
+set the session id of the session to be deleted.
+.SS ip l2tp show session - show information about sessions
+.TP
+.BI tunnel_id " ID"
+set the tunnel id of the session(s) to be shown. If not specified,
+information about sessions in all tunnels is printed.
+.TP
+.BI session_id " ID"
+set the session id of the session to be shown. If not specified,
+information about all sessions is printed.
+.SH EXAMPLES
+.PP
+.SS Setup L2TP tunnels and sessions
+.nf
+site-A:# ip l2tp add tunnel tunnel_id 3000 peer_tunnel_id 4000 \\
+ encap udp local 1.2.3.4 remote 5.6.7.8 \\
+ udp_sport 5000 udp_dport 6000
+site-A:# ip l2tp add session tunnel_id 3000 session_id 1000 \\
+ peer_session_id 2000
+
+site-B:# ip l2tp add tunnel tunnel_id 4000 peer_tunnel_id 3000 \\
+ encap udp local 5.6.7.8 remote 1.2.3.4 \\
+ udp_sport 6000 udp_dport 5000
+site-B:# ip l2tp add session tunnel_id 4000 session_id 2000 \\
+ peer_session_id 1000
+
+site-A:# ip link set l2tpeth0 up mtu 1488
+
+site-B:# ip link set l2tpeth0 up mtu 1488
+.fi
+.PP
+Notice that the IP addresses, UDP ports and tunnel / session ids are
+matched and reversed at each site.
+.SS Configure as IP interfaces
+The two interfaces can be configured with IP addresses if only IP data
+is to be carried. This is perhaps the simplest configuration.
+.PP
+.nf
+site-A:# ip addr add 10.42.1.1 peer 10.42.1.2 dev l2tpeth0
+
+site-B:# ip addr add 10.42.1.2 peer 10.42.1.1 dev l2tpeth0
+
+site-A:# ping 10.42.1.2
+.fi
+.PP
+Now the link should be usable. Add static routes as needed to have
+data sent over the new link.
+.PP
+.SS Configure as bridged interfaces
+To carry non-IP data, the L2TP network interface is added to a bridge
+instead of being assigned its own IP address, using standard Linux
+utilities. Since raw ethernet frames are then carried inside the
+tunnel, the MTU of the L2TP interfaces must be set to allow space for
+those headers.
+.PP
+.nf
+site-A:# ip link set l2tpeth0 up mtu 1446
+site-A:# brctl addbr br0
+site-A:# brctl addif br0 l2tpeth0
+site-A:# brctl addif br0 eth0
+site-A:# ip link set br0 up
+.fi
+.PP
+If you are using VLANs, setup a bridge per VLAN and bridge each VLAN
+over a separate L2TP session. For example, to bridge VLAN ID 5 on eth1
+over an L2TP pseudowire:
+.PP
+.nf
+site-A:# ip link set l2tpeth0 up mtu 1446
+site-A:# brctl addbr brvlan5
+site-A:# brctl addif brvlan5 l2tpeth0.5
+site-A:# brctl addif brvlan5 eth1.5
+site-A:# ip link set brvlan5 up
+.fi
+.PP
+Adding the L2TP interface to a bridge causes the bridge to forward
+traffic over the L2TP pseudowire just like it forwards over any other
+interface. The bridge learns MAC addresses of hosts attached to each
+interface and intelligently forwards frames from one bridge port to
+another. IP addresses are not assigned to the l2tpethN interfaces. If
+the bridge is correctly configured at both sides of the L2TP
+pseudowire, it should be possible to reach hosts in the peer's bridged
+network.
+.PP
+When raw ethernet frames are bridged across an L2TP tunnel, large
+frames may be fragmented and forwarded as individual IP fragments to
+the recipient, depending on the MTU of the physical interface used by
+the tunnel. When the ethernet frames carry protocols which are
+reassembled by the recipient, like IP, this isn't a problem. However,
+such fragmentation can cause problems for protocols like PPPoE where
+the recipient expects to receive ethernet frames exactly as
+transmitted. In such cases, it is important that frames leaving the
+tunnel are reassembled back into a single frame before being
+forwarded on. To do so, enable netfilter connection tracking
+(conntrack) or manually load the Linux netfilter degrag modules at
+each tunnel endpoint.
+.PP
+.nf
+site-A:# modprobe nf_degrag_ipv4
+
+site-B:# modprobe nf_degrag_ipv4
+.fi
+.PP
+If L2TP is being used over IPv6, use the IPv6 degrag module.
+.SH INTEROPABILITY
+.PP
+Unmanaged (static) L2TPv3 tunnels are supported by some network
+equipment equipment vendors such as Cisco.
+.PP
+In Linux, L2TP Hello messages are not supported in unmanaged
+tunnels. Hello messages are used by L2TP clients and servers to detect
+link failures in order to automate tearing down and reestablishing
+dynamic tunnels. If a non-Linux peer supports Hello messages in
+unmanaged tunnels, it must be turned off to interoperate with Linux.
+.SH SEE ALSO
+.br
+.BR brctl (8)
+.BR ip (8)
+.SH AUTHOR
+James Chapman <jchapman@katalix.com>
diff --git a/man/man8/ip-link.8 b/man/man8/ip-link.8
index acc6d28..24d2ec7 100644
--- a/man/man8/ip-link.8
+++ b/man/man8/ip-link.8
@@ -23,7 +23,9 @@ ip-link \- network device configuration
\fB\-o\fR[\fIneline\fR] }
.ti -8
-.BI "ip link add link " DEVICE
+.BI "ip link add"
+.RB "[ " link
+.IR DEVICE " ]"
.RB "[ " name " ]"
.I NAME
.br
@@ -103,6 +105,9 @@ ip-link \- network device configuration
.B mode
.IR LINKMODE " |"
.br
+.B state
+.IR LINKSTATE " |"
+.br
.B master
.IR DEVICE
.br
@@ -260,6 +265,10 @@ mode changes the behaviour so that device goes into DORMANT state instead
of UP when driver is ready.
.TP
+.BI state " LINKSTATE"
+allows setting the operational link state. The values (defined in RFC2863)
+are: UP, DOWN, TESTING, UNKNOWN, DORMANT, NOTPRESENT, LOWERLAYERDOWN.
+.TP
.BI alias " NAME"
give the device a symbolic name for easy reference.
diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
new file mode 100644
index 0000000..9386cc6
--- /dev/null
+++ b/man/man8/ip-link.8.in
@@ -0,0 +1,376 @@
+.TH IP\-LINK 8 "20 Dec 2011" "iproute2" "Linux"
+.SH "NAME"
+ip-link \- network device configuration
+.SH "SYNOPSIS"
+.sp
+.ad l
+.in +8
+.ti -8
+.B ip
+.RI "[ " OPTIONS " ]"
+.B link
+.RI " { " COMMAND " | "
+.BR help " }"
+.sp
+
+.ti -8
+.IR OPTIONS " := { "
+\fB\-V\fR[\fIersion\fR] |
+\fB\-s\fR[\fItatistics\fR] |
+\fB\-r\fR[\fIesolve\fR] |
+\fB\-f\fR[\fIamily\fR] {
+.BR inet " | " inet6 " | " ipx " | " dnet " | " link " } | "
+\fB\-o\fR[\fIneline\fR] }
+
+.ti -8
+.BI "ip link add"
+.RB "[ " link
+.IR DEVICE " ]"
+.RB "[ " name " ]"
+.I NAME
+.br
+.RB "[ " txqueuelen
+.IR PACKETS " ]"
+.br
+.RB "[ " address
+.IR LLADDR " ]"
+.RB "[ " broadcast
+.IR LLADDR " ]"
+.br
+.RB "[ " mtu
+.IR MTU " ]"
+.br
+.BR type " TYPE"
+.RI "[ " ARGS " ]"
+
+.ti -8
+.IR TYPE " := [ "
+.BR vlan " | " veth " | " vcan " | " dummy " | " ifb " | " macvlan " | " can " | " bridge " ]"
+
+.ti -8
+.BI "ip link delete " DEVICE
+.BI type " TYPE"
+.RI "[ " ARGS " ]"
+
+.ti -8
+.BR "ip link set " {
+.IR DEVICE " | "
+.BI "group " GROUP
+.RB "} { " up " | " down " | " arp " { " on " | " off " } |"
+.br
+.BR promisc " { " on " | " off " } |"
+.br
+.BR allmulticast " { " on " | " off " } |"
+.br
+.BR dynamic " { " on " | " off " } |"
+.br
+.BR multicast " { " on " | " off " } |"
+.br
+.B txqueuelen
+.IR PACKETS " |"
+.br
+.B name
+.IR NEWNAME " |"
+.br
+.B address
+.IR LLADDR " |"
+.B broadcast
+.IR LLADDR " |"
+.br
+.B mtu
+.IR MTU " |"
+.br
+.B netns
+.IR PID " |"
+.br
+.B netns
+.IR NETNSNAME " |"
+.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 " ] ["
+.B spoofchk { on | off }
+] |
+.br
+.B master
+.IR DEVICE
+.br
+.B nomaster
+.BR " }"
+
+
+.ti -8
+.B ip link show
+.RI "[ " DEVICE " | "
+.B group
+.IR GROUP " ]"
+
+.SH "DESCRIPTION"
+.SS ip link add - add virtual link
+
+.TP
+.BI link " DEVICE "
+specifies the physical device to act operate on.
+
+.I NAME
+specifies the name of the new virtual device.
+
+.I TYPE
+specifies the type of the new device.
+.sp
+Link types:
+
+.in +8
+.B vlan
+- 802.1q tagged virtual LAN interface
+.sp
+.B veth
+- Virtual ethernet interface
+.sp
+.B vcan
+- Virtual Local CAN interface
+.sp
+.B dummy
+- Dummy network interface
+.sp
+.B ifb
+- Intermediate Functional Block device
+.sp
+.B macvlan
+- virtual interface base on link layer address (MAC)
+.sp
+.B can
+- Controller Area Network interface
+.sp
+.B bridge
+- Ethernet Bridge device
+.in -8
+
+.SS ip link delete - delete virtual link
+.I DEVICE
+specifies the virtual device to act operate on.
+.I TYPE
+specifies the type of the device.
+
+
+.TP
+.BI dev " DEVICE "
+specifies the physical device to act operate on.
+
+.SS ip link set - change device attributes
+
+.TP
+.BI dev " DEVICE "
+.I DEVICE
+specifies network device to operate on. When configuring SR-IOV Virtual Fuction
+(VF) devices, this keyword should specify the associated Physical Function (PF)
+device.
+
+.TP
+.BI group " GROUP "
+.I GROUP
+has a dual role: If both group and dev are present, then move the device to the
+specified group. If only a group is specified, then the command operates on
+all devices in that group.
+
+.TP
+.BR up " and " down
+change the state of the device to
+.B UP
+or
+.BR "DOWN" .
+
+.TP
+.BR "arp on " or " arp off"
+change the
+.B NOARP
+flag on the device.
+
+.TP
+.BR "multicast on " or " multicast off"
+change the
+.B MULTICAST
+flag on the device.
+
+.TP
+.BR "dynamic on " or " dynamic off"
+change the
+.B DYNAMIC
+flag on the device.
+
+.TP
+.BI name " NAME"
+change the name of the device. This operation is not
+recommended if the device is running or has some addresses
+already configured.
+
+.TP
+.BI txqueuelen " NUMBER"
+.TP
+.BI txqlen " NUMBER"
+change the transmit queue length of the device.
+
+.TP
+.BI mtu " NUMBER"
+change the
+.I MTU
+of the device.
+
+.TP
+.BI address " LLADDRESS"
+change the station address of the interface.
+
+.TP
+.BI broadcast " LLADDRESS"
+.TP
+.BI brd " LLADDRESS"
+.TP
+.BI peer " LLADDRESS"
+change the link layer broadcast address or the peer address when
+the interface is
+.IR "POINTOPOINT" .
+
+.TP
+.BI netns " PID"
+move the device to the network namespace associated with the process
+.IR "PID".
+
+.TP
+.BI netns " NETNSNAME"
+move the device to the network namespace associated with name
+.IR "NETNSNAME".
+
+.TP
+.BI alias " NAME"
+give the device a symbolic name for easy reference.
+
+.TP
+.BI group " GROUP"
+specify the group the device belongs to.
+The available groups are listed in file
+.BR "@SYSCONFDIR@/group" .
+
+.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.
+
+.sp
+.BI spoofchk " on|off"
+- turn packet spoof checking on or off for the specified VF.
+.in -8
+
+.TP
+.BI master " DEVICE"
+set master device of the device (enslave device).
+
+.TP
+.BI nomaster
+unset master device of the device (release device).
+
+.PP
+.B Warning:
+If multiple parameter changes are requested,
+.B ip
+aborts immediately after any of the changes have failed.
+This is the only case when
+.B ip
+can move the system to an unpredictable state. The solution
+is to avoid changing several parameters with one
+.B ip link set
+call.
+
+.SS ip link show - display device attributes
+
+.TP
+.BI dev " NAME " (default)
+.I NAME
+specifies the network device to show.
+If this argument is omitted all devices in the default group are listed.
+
+.TP
+.BI group " GROUP "
+.I GROUP
+specifies what group of devices to show.
+
+.TP
+.B up
+only display running interfaces.
+
+.SH "EXAMPLES"
+.PP
+ip link show
+.RS 4
+Shows the state of all network interfaces on the system.
+.RE
+.PP
+ip link set dev ppp0 mtu 1400
+.RS 4
+Change the MTU the ppp0 device.
+.RE
+.PP
+ip link add link eth0 name eth0.10 type vlan id 10
+.RS 4
+Creates a new vlan device eth0.10 on device eth0.
+.RE
+.PP
+ip link delete dev eth0.10
+.RS 4
+Removes vlan device.
+.RE
+
+.SH SEE ALSO
+.br
+.BR ip (8)
+
+.SH AUTHOR
+Original Manpage by Michail Litvak <mci@owl.openwall.com>
diff --git a/man/man8/ip-route.8.in b/man/man8/ip-route.8.in
new file mode 100644
index 0000000..0ca6107
--- /dev/null
+++ b/man/man8/ip-route.8.in
@@ -0,0 +1,744 @@
+.TH IP\-ROUTE 8 "20 Dec 2011" "iproute2" "Linux"
+.SH "NAME"
+ip-route \- routing table management
+.SH "SYNOPSIS"
+.sp
+.ad l
+.in +8
+.ti -8
+.B ip
+.RI "[ " OPTIONS " ]"
+.B route
+.RI " { " COMMAND " | "
+.BR help " }"
+.sp
+.ti -8
+
+.ti -8
+.BR "ip route" " { "
+.BR list " | " flush " } "
+.I SELECTOR
+
+.ti -8
+.BR "ip route save"
+.I SELECTOR
+
+.ti -8
+.BR "ip route restore"
+
+.ti -8
+.B ip route get
+.IR ADDRESS " [ "
+.BI from " ADDRESS " iif " STRING"
+.RB " ] [ " oif
+.IR STRING " ] [ "
+.B tos
+.IR TOS " ]"
+
+.ti -8
+.BR "ip route" " { " add " | " del " | " change " | " append " | "\
+replace " } "
+.I ROUTE
+
+.ti -8
+.IR SELECTOR " := "
+.RB "[ " root
+.IR PREFIX " ] [ "
+.B match
+.IR PREFIX " ] [ "
+.B exact
+.IR PREFIX " ] [ "
+.B table
+.IR TABLE_ID " ] [ "
+.B proto
+.IR RTPROTO " ] [ "
+.B type
+.IR TYPE " ] [ "
+.B scope
+.IR SCOPE " ]"
+
+.ti -8
+.IR ROUTE " := " NODE_SPEC " [ " INFO_SPEC " ]"
+
+.ti -8
+.IR NODE_SPEC " := [ " TYPE " ] " PREFIX " ["
+.B tos
+.IR TOS " ] [ "
+.B table
+.IR TABLE_ID " ] [ "
+.B proto
+.IR RTPROTO " ] [ "
+.B scope
+.IR SCOPE " ] [ "
+.B metric
+.IR METRIC " ]"
+
+.ti -8
+.IR INFO_SPEC " := " "NH OPTIONS FLAGS" " ["
+.B nexthop
+.IR NH " ] ..."
+
+.ti -8
+.IR NH " := [ "
+.B via
+.IR ADDRESS " ] [ "
+.B dev
+.IR STRING " ] [ "
+.B weight
+.IR NUMBER " ] " NHFLAGS
+
+.ti -8
+.IR OPTIONS " := " FLAGS " [ "
+.B mtu
+.IR NUMBER " ] [ "
+.B advmss
+.IR NUMBER " ] [ "
+.B rtt
+.IR TIME " ] [ "
+.B rttvar
+.IR TIME " ] [ "
+.B window
+.IR NUMBER " ] [ "
+.B cwnd
+.IR NUMBER " ] [ "
+.B ssthresh
+.IR REALM " ] [ "
+.B realms
+.IR REALM " ] [ "
+.B rto_min
+.IR TIME " ] [ "
+.B initcwnd
+.IR NUMBER " ] [ "
+.B initrwnd
+.IR NUMBER " ]"
+
+.ti -8
+.IR TYPE " := [ "
+.BR unicast " | " local " | " broadcast " | " multicast " | "\
+throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]"
+
+.ti -8
+.IR TABLE_ID " := [ "
+.BR local "| " main " | " default " | " all " |"
+.IR NUMBER " ]"
+
+.ti -8
+.IR SCOPE " := [ "
+.BR host " | " link " | " global " |"
+.IR NUMBER " ]"
+
+.ti -8
+.IR NHFLAGS " := [ "
+.BR onlink " | " pervasive " ]"
+
+.ti -8
+.IR RTPROTO " := [ "
+.BR kernel " | " boot " | " static " |"
+.IR NUMBER " ]"
+
+
+.SH DESCRIPTION
+.B ip route
+is used to manipulate entries in the kernel routing tables.
+.sp
+.B Route types:
+
+.in +8
+.B unicast
+- the route entry describes real paths to the destinations covered
+by the route prefix.
+
+.sp
+.B unreachable
+- these destinations are unreachable. Packets are discarded and the
+ICMP message
+.I host unreachable
+is generated.
+The local senders get an
+.I EHOSTUNREACH
+error.
+
+.sp
+.B blackhole
+- these destinations are unreachable. Packets are discarded silently.
+The local senders get an
+.I EINVAL
+error.
+
+.sp
+.B prohibit
+- these destinations are unreachable. Packets are discarded and the
+ICMP message
+.I communication administratively prohibited
+is generated. The local senders get an
+.I EACCES
+error.
+
+.sp
+.B local
+- the destinations are assigned to this host. The packets are looped
+back and delivered locally.
+
+.sp
+.B broadcast
+- the destinations are broadcast addresses. The packets are sent as
+link broadcasts.
+
+.sp
+.B throw
+- a special control route used together with policy rules. If such a
+route is selected, lookup in this table is terminated pretending that
+no route was found. Without policy routing it is equivalent to the
+absence of the route in the routing table. The packets are dropped
+and the ICMP message
+.I net unreachable
+is generated. The local senders get an
+.I ENETUNREACH
+error.
+
+.sp
+.B nat
+- a special NAT route. Destinations covered by the prefix
+are considered to be dummy (or external) addresses which require translation
+to real (or internal) ones before forwarding. The addresses to translate to
+are selected with the attribute
+.B Warning:
+Route NAT is no longer supported in Linux 2.6.
+
+
+.BR "via" .
+.sp
+.B anycast
+.RI "- " "not implemented"
+the destinations are
+.I anycast
+addresses assigned to this host. They are mainly equivalent
+to
+.B local
+with one difference: such addresses are invalid when used
+as the source address of any packet.
+
+.sp
+.B multicast
+- a special type used for multicast routing. It is not present in
+normal routing tables.
+.in -8
+
+.P
+.B Route tables:
+Linux-2.x can pack routes into several routing tables identified
+by a number in the range from 1 to 2^31 or by name from the file
+.B @SYSCONFDIR@/rt_tables
+By default all normal routes are inserted into the
+.B main
+table (ID 254) and the kernel only uses this table when calculating routes.
+Values (0, 253, 254, and 255) are reserved for built-in use.
+
+.sp
+Actually, one other table always exists, which is invisible but
+even more important. It is the
+.B local
+table (ID 255). This table
+consists of routes for local and broadcast addresses. The kernel maintains
+this table automatically and the administrator usually need not modify it
+or even look at it.
+
+The multiple routing tables enter the game when
+.I policy routing
+is used.
+
+.SS ip route add - add new route
+.SS ip route change - change route
+.SS ip route replace - change or add new one
+
+.TP
+.BI to " TYPE PREFIX " (default)
+the destination prefix of the route. If
+.I TYPE
+is omitted,
+.B ip
+assumes type
+.BR "unicast" .
+Other values of
+.I TYPE
+are listed above.
+.I PREFIX
+is an IP or IPv6 address optionally followed by a slash and the
+prefix length. If the length of the prefix is missing,
+.B ip
+assumes a full-length host route. There is also a special
+.I PREFIX
+.B default
+- which is equivalent to IP
+.B 0/0
+or to IPv6
+.BR "::/0" .
+
+.TP
+.BI tos " TOS"
+.TP
+.BI dsfield " TOS"
+the Type Of Service (TOS) key. This key has no associated mask and
+the longest match is understood as: First, compare the TOS
+of the route and of the packet. If they are not equal, then the packet
+may still match a route with a zero TOS.
+.I TOS
+is either an 8 bit hexadecimal number or an identifier
+from
+.BR "@SYSCONFDIR@/rt_dsfield" .
+
+.TP
+.BI metric " NUMBER"
+.TP
+.BI preference " NUMBER"
+the preference value of the route.
+.I NUMBER
+is an arbitrary 32bit number.
+
+.TP
+.BI table " TABLEID"
+the table to add this route to.
+.I TABLEID
+may be a number or a string from the file
+.BR "@SYSCONFDIR@/rt_tables" .
+If this parameter is omitted,
+.B ip
+assumes the
+.B main
+table, with the exception of
+.BR local " , " broadcast " and " nat
+routes, which are put into the
+.B local
+table by default.
+
+.TP
+.BI dev " NAME"
+the output device name.
+
+.TP
+.BI via " ADDRESS"
+the address of the nexthop router. Actually, the sense of this field
+depends on the route type. For normal
+.B unicast
+routes it is either the true next hop router or, if it is a direct
+route installed in BSD compatibility mode, it can be a local address
+of the interface. For NAT routes it is the first address of the block
+of translated IP destinations.
+
+.TP
+.BI src " ADDRESS"
+the source address to prefer when sending to the destinations
+covered by the route prefix.
+
+.TP
+.BI realm " REALMID"
+the realm to which this route is assigned.
+.I REALMID
+may be a number or a string from the file
+.BR "@SYSCONFDIR@/rt_realms" .
+
+.TP
+.BI mtu " MTU"
+.TP
+.BI "mtu lock" " MTU"
+the MTU along the path to the destination. If the modifier
+.B lock
+is not used, the MTU may be updated by the kernel due to
+Path MTU Discovery. If the modifier
+.B lock
+is used, no path MTU discovery will be tried, all packets
+will be sent without the DF bit in IPv4 case or fragmented
+to MTU for IPv6.
+
+.TP
+.BI window " NUMBER"
+the maximal window for TCP to advertise to these destinations,
+measured in bytes. It limits maximal data bursts that our TCP
+peers are allowed to send to us.
+
+.TP
+.BI rtt " TIME"
+the initial RTT ('Round Trip Time') estimate. If no suffix is
+specified the units are raw values passed directly to the
+routing code to maintain compatibility with previous releases.
+Otherwise if a suffix of s, sec or secs is used to specify
+seconds and ms, msec or msecs to specify milliseconds.
+
+
+.TP
+.BI rttvar " TIME " "(2.3.15+ only)"
+the initial RTT variance estimate. Values are specified as with
+.BI rtt
+above.
+
+.TP
+.BI rto_min " TIME " "(2.6.23+ only)"
+the minimum TCP Retransmission TimeOut to use when communicating with this
+destination. Values are specified as with
+.BI rtt
+above.
+
+.TP
+.BI ssthresh " NUMBER " "(2.3.15+ only)"
+an estimate for the initial slow start threshold.
+
+.TP
+.BI cwnd " NUMBER " "(2.3.15+ only)"
+the clamp for congestion window. It is ignored if the
+.B lock
+flag is not used.
+
+.TP
+.BI initcwnd " NUMBER " "(2.5.70+ only)"
+the initial congestion window size for connections to this destination.
+Actual window size is this value multiplied by the MSS
+(``Maximal Segment Size'') for same connection. The default is
+zero, meaning to use the values specified in RFC2414.
+
+.TP
+.BI initrwnd " NUMBER " "(2.6.33+ only)"
+the initial receive window size for connections to this destination.
+Actual window size is this value multiplied by the MSS of the connection.
+The default value is zero, meaning to use Slow Start value.
+
+.TP
+.BI advmss " NUMBER " "(2.3.15+ only)"
+the MSS ('Maximal Segment Size') to advertise to these
+destinations when establishing TCP connections. If it is not given,
+Linux uses a default value calculated from the first hop device MTU.
+(If the path to these destination is asymmetric, this guess may be wrong.)
+
+.TP
+.BI reordering " NUMBER " "(2.3.15+ only)"
+Maximal reordering on the path to this destination.
+If it is not given, Linux uses the value selected with
+.B sysctl
+variable
+.BR "net/ipv4/tcp_reordering" .
+
+.TP
+.BI nexthop " NEXTHOP"
+the nexthop of a multipath route.
+.I NEXTHOP
+is a complex value with its own syntax similar to the top level
+argument lists:
+
+.in +8
+.BI via " ADDRESS"
+- is the nexthop router.
+.sp
+
+.BI dev " NAME"
+- is the output device.
+.sp
+
+.BI weight " NUMBER"
+- is a weight for this element of a multipath
+route reflecting its relative bandwidth or quality.
+.in -8
+
+.TP
+.BI scope " SCOPE_VAL"
+the scope of the destinations covered by the route prefix.
+.I SCOPE_VAL
+may be a number or a string from the file
+.BR "@SYSCONFDIR@/rt_scopes" .
+If this parameter is omitted,
+.B ip
+assumes scope
+.B global
+for all gatewayed
+.B unicast
+routes, scope
+.B link
+for direct
+.BR unicast " and " broadcast
+routes and scope
+.BR host " for " local
+routes.
+
+.TP
+.BI protocol " RTPROTO"
+the routing protocol identifier of this route.
+.I RTPROTO
+may be a number or a string from the file
+.BR "@SYSCONFDIR@/rt_protos" .
+If the routing protocol ID is not given,
+.B ip assumes protocol
+.B boot
+(i.e. it assumes the route was added by someone who doesn't
+understand what they are doing). Several protocol values have
+a fixed interpretation.
+Namely:
+
+.in +8
+.B redirect
+- the route was installed due to an ICMP redirect.
+.sp
+
+.B kernel
+- the route was installed by the kernel during autoconfiguration.
+.sp
+
+.B boot
+- the route was installed during the bootup sequence.
+If a routing daemon starts, it will purge all of them.
+.sp
+
+.B static
+- the route was installed by the administrator
+to override dynamic routing. Routing daemon will respect them
+and, probably, even advertise them to its peers.
+.sp
+
+.B ra
+- the route was installed by Router Discovery protocol.
+.in -8
+
+.sp
+The rest of the values are not reserved and the administrator is free
+to assign (or not to assign) protocol tags.
+
+.TP
+.B onlink
+pretend that the nexthop is directly attached to this link,
+even if it does not match any interface prefix.
+
+.SS ip route delete - delete route
+
+.B ip route del
+has the same arguments as
+.BR "ip route add" ,
+but their semantics are a bit different.
+
+Key values
+.RB "(" to ", " tos ", " preference " and " table ")"
+select the route to delete. If optional attributes are present,
+.B ip
+verifies that they coincide with the attributes of the route to delete.
+If no route with the given key and attributes was found,
+.B ip route del
+fails.
+
+.SS ip route show - list routes
+the command displays the contents of the routing tables or the route(s)
+selected by some criteria.
+
+.TP
+.BI to " SELECTOR " (default)
+only select routes from the given range of destinations.
+.I SELECTOR
+consists of an optional modifier
+.RB "(" root ", " match " or " exact ")"
+and a prefix.
+.BI root " PREFIX"
+selects routes with prefixes not shorter than
+.IR PREFIX "."
+F.e.
+.BI root " 0/0"
+selects the entire routing table.
+.BI match " PREFIX"
+selects routes with prefixes not longer than
+.IR PREFIX "."
+F.e.
+.BI match " 10.0/16"
+selects
+.IR 10.0/16 ","
+.IR 10/8 " and " 0/0 ,
+but it does not select
+.IR 10.1/16 " and " 10.0.0/24 .
+And
+.BI exact " PREFIX"
+(or just
+.IR PREFIX ")"
+selects routes with this exact prefix. If neither of these options
+are present,
+.B ip
+assumes
+.BI root " 0/0"
+i.e. it lists the entire table.
+
+.TP
+.BI tos " TOS"
+.BI dsfield " TOS"
+only select routes with the given TOS.
+
+.TP
+.BI table " TABLEID"
+show the routes from this table(s). The default setting is to show
+.BR table main "."
+.I TABLEID
+may either be the ID of a real table or one of the special values:
+.sp
+.in +8
+.B all
+- list all of the tables.
+.sp
+.B cache
+- dump the routing cache.
+.in -8
+
+.TP
+.B cloned
+.TP
+.B cached
+list cloned routes i.e. routes which were dynamically forked from
+other routes because some route attribute (f.e. MTU) was updated.
+Actually, it is equivalent to
+.BR "table cache" "."
+
+.TP
+.BI from " SELECTOR"
+the same syntax as for
+.BR to ","
+but it binds the source address range rather than destinations.
+Note that the
+.B from
+option only works with cloned routes.
+
+.TP
+.BI protocol " RTPROTO"
+only list routes of this protocol.
+
+.TP
+.BI scope " SCOPE_VAL"
+only list routes with this scope.
+
+.TP
+.BI type " TYPE"
+only list routes of this type.
+
+.TP
+.BI dev " NAME"
+only list routes going via this device.
+
+.TP
+.BI via " PREFIX"
+only list routes going via the nexthop routers selected by
+.IR PREFIX "."
+
+.TP
+.BI src " PREFIX"
+only list routes with preferred source addresses selected
+by
+.IR PREFIX "."
+
+.TP
+.BI realm " REALMID"
+.TP
+.BI realms " FROMREALM/TOREALM"
+only list routes with these realms.
+
+.SS ip route flush - flush routing tables
+this command flushes routes selected by some criteria.
+
+.sp
+The arguments have the same syntax and semantics as the arguments of
+.BR "ip route show" ,
+but routing tables are not listed but purged. The only difference is
+the default action:
+.B show
+dumps all the IP main routing table but
+.B flush
+prints the helper page.
+
+.sp
+With the
+.B -statistics
+option, the command becomes verbose. It prints out the number of
+deleted routes and the number of rounds made to flush the routing
+table. If the option is given
+twice,
+.B ip route flush
+also dumps all the deleted routes in the format described in the
+previous subsection.
+
+.SS ip route get - get a single route
+this command gets a single route to a destination and prints its
+contents exactly as the kernel sees it.
+
+.TP
+.BI to " ADDRESS " (default)
+the destination address.
+
+.TP
+.BI from " ADDRESS"
+the source address.
+
+.TP
+.BI tos " TOS"
+.TP
+.BI dsfield " TOS"
+the Type Of Service.
+
+.TP
+.BI iif " NAME"
+the device from which this packet is expected to arrive.
+
+.TP
+.BI oif " NAME"
+force the output device on which this packet will be routed.
+
+.TP
+.B connected
+if no source address
+.RB "(option " from ")"
+was given, relookup the route with the source set to the preferred
+address received from the first lookup.
+If policy routing is used, it may be a different route.
+
+.P
+Note that this operation is not equivalent to
+.BR "ip route show" .
+.B show
+shows existing routes.
+.B get
+resolves them and creates new clones if necessary. Essentially,
+.B get
+is equivalent to sending a packet along this path.
+If the
+.B iif
+argument is not given, the kernel creates a route
+to output packets towards the requested destination.
+This is equivalent to pinging the destination
+with a subsequent
+.BR "ip route ls cache" ,
+however, no packets are actually sent. With the
+.B iif
+argument, the kernel pretends that a packet arrived from this interface
+and searches for a path to forward the packet.
+
+.SS ip route save - save routing table information to stdout
+this command behaves like
+.BR "ip route show"
+except that the output is raw data suitable for passing to
+.BR "ip route restore" .
+
+.SS ip route restore - restore routing table information from stdin
+this command expects to read a data stream as returned from
+.BR "ip route save" .
+It will attempt to restore the routing table information exactly as
+it was at the time of the save, so any translation of information
+in the stream (such as device indexes) must be done first. Any existing
+routes are left unchanged. Any routes specified in the data stream that
+already exist in the table will be ignored.
+
+.SH EXAMPLES
+.PP
+ip ro
+.RS 4
+Show all route entries in the kernel.
+.RE
+.PP
+ip route add default via 192.168.1.1 dev eth0
+.RS 4
+Adds a default route (for all addresses) via the local gateway 192.168.1.1 that can
+be reached on device eth0.
+.RE
+
+.SH SEE ALSO
+.br
+.BR ip (8)
+
+.SH AUTHOR
+Original Manpage by Michail Litvak <mci@owl.openwall.com>
diff --git a/man/man8/ip.8 b/man/man8/ip.8
index 0f9f454..ede3d12 100644
--- a/man/man8/ip.8
+++ b/man/man8/ip.8
@@ -113,7 +113,7 @@ host addresses.
.TP
.B l2tp
-- tunnel PPP over IP (L2TP).
+- tunnel ethernet over IP (L2TPv3).
.TP
.B link
@@ -205,6 +205,7 @@ was written by Alexey N. Kuznetsov and added in Linux 2.2.
.SH SEE ALSO
.BR ip-address (8),
.BR ip-addrlabel (8),
+.BR ip-l2tp (8),
.BR ip-link (8),
.BR ip-maddress (8),
.BR ip-monitor (8),
diff --git a/man/man8/nstat.8 b/man/man8/nstat.8
new file mode 100644
index 0000000..c703cc8
--- /dev/null
+++ b/man/man8/nstat.8
@@ -0,0 +1 @@
+.so man8/rtacct.8
diff --git a/man/man8/routef.8 b/man/man8/routef.8
new file mode 100644
index 0000000..c2a7059
--- /dev/null
+++ b/man/man8/routef.8
@@ -0,0 +1 @@
+.so man8/routel.8
diff --git a/man/man8/rtstat.8 b/man/man8/rtstat.8
new file mode 100644
index 0000000..080e2b2
--- /dev/null
+++ b/man/man8/rtstat.8
@@ -0,0 +1 @@
+.so man8/lnstat.8
diff --git a/man/man8/tc-choke.8 b/man/man8/tc-choke.8
index 7b213be..620c7f6 100644
--- a/man/man8/tc-choke.8
+++ b/man/man8/tc-choke.8
@@ -4,11 +4,11 @@ choke \- choose and keep scheduler
.SH SYNOPSIS
.B tc qdisc ... choke
.B limit
-bytes
+packets
.B min
-bytes
+packets
.B max
-bytes
+packets
.B avpkt
bytes
.B burst
@@ -22,7 +22,7 @@ chance
CHOKe (CHOose and Keep for responsive flows, CHOose and Kill for unresponsive flows)
is a classless qdisc designed to both identify and penalize flows that monopolize the
-queue. CHOKe is a variation of RED, and the configuration is the same as RED.
+queue. CHOKe is a variation of RED, and the configuration is similar to RED.
.SH ALGORITHM
Once the queue hits a certain average length, a random packet is drawn from the
@@ -39,7 +39,8 @@ If the queue length exceeds
The marking probability computation is the same as used by the RED qdisc.
.SH PARAMETERS
-The parameters are the same as for RED, see
+The parameters are the same as for RED, except that RED uses bytes whereas choke
+counts packets. See
.BR tc-red (8)
for a description.
diff --git a/man/man8/tc-pfifo.8 b/man/man8/tc-pfifo.8
index 70a54af..ed23850 120000..100644
--- a/man/man8/tc-pfifo.8
+++ b/man/man8/tc-pfifo.8
@@ -1 +1 @@
-tc-bfifo.8 \ No newline at end of file
+.so man8/tc-bfifo.8
diff --git a/misc/ss.c b/misc/ss.c
index 5414f75..cf529ef 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -1336,7 +1336,17 @@ static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r)
parse_rtattr(tb, INET_DIAG_MAX, (struct rtattr*)(r+1),
nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
- if (tb[INET_DIAG_MEMINFO]) {
+ if (tb[INET_DIAG_SKMEMINFO]) {
+ const __u32 *skmeminfo = RTA_DATA(tb[INET_DIAG_SKMEMINFO]);
+ printf(" skmem:(r%u,rb%u,t%u,tb%u,f%u,w%u,o%u)",
+ skmeminfo[SK_MEMINFO_RMEM_ALLOC],
+ skmeminfo[SK_MEMINFO_RCVBUF],
+ skmeminfo[SK_MEMINFO_WMEM_ALLOC],
+ skmeminfo[SK_MEMINFO_SNDBUF],
+ skmeminfo[SK_MEMINFO_FWD_ALLOC],
+ skmeminfo[SK_MEMINFO_WMEM_QUEUED],
+ skmeminfo[SK_MEMINFO_OPTMEM]);
+ }else if (tb[INET_DIAG_MEMINFO]) {
const struct inet_diag_meminfo *minfo
= RTA_DATA(tb[INET_DIAG_MEMINFO]);
printf(" mem:(r%u,w%u,f%u,t%u)",
@@ -1370,7 +1380,7 @@ static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r)
}
if (tb[INET_DIAG_CONG])
- printf(" %s", (char *) RTA_DATA(tb[INET_DIAG_CONG]));
+ printf(" %s", rta_getattr_str(tb[INET_DIAG_CONG]));
if (info->tcpi_options & TCPI_OPT_WSCALE)
printf(" wscale:%d,%d", info->tcpi_snd_wscale,
@@ -1505,8 +1515,10 @@ static int tcp_show_netlink(struct filter *f, FILE *dump_fp, int socktype)
memset(&req.r, 0, sizeof(req.r));
req.r.idiag_family = AF_INET;
req.r.idiag_states = f->states;
- if (show_mem)
+ if (show_mem) {
req.r.idiag_ext |= (1<<(INET_DIAG_MEMINFO-1));
+ req.r.idiag_ext |= (1<<(INET_DIAG_SKMEMINFO-1));
+ }
if (show_tcpinfo) {
req.r.idiag_ext |= (1<<(INET_DIAG_INFO-1));
@@ -1534,8 +1546,10 @@ static int tcp_show_netlink(struct filter *f, FILE *dump_fp, int socktype)
.msg_iovlen = f->f ? 3 : 1,
};
- if (sendmsg(fd, &msg, 0) < 0)
+ if (sendmsg(fd, &msg, 0) < 0) {
+ close(fd);
return -1;
+ }
iov[0] = (struct iovec){
.iov_base = buf,
@@ -1589,6 +1603,10 @@ static int tcp_show_netlink(struct filter *f, FILE *dump_fp, int socktype)
fprintf(stderr, "ERROR truncated\n");
} else {
errno = -err->error;
+ if (errno == EOPNOTSUPP) {
+ close(fd);
+ return -1;
+ }
perror("TCPDIAG answers");
}
close(fd);
diff --git a/tc/Android.mk b/tc/Android.mk
index 02c84f3..0de1928 100644
--- a/tc/Android.mk
+++ b/tc/Android.mk
@@ -18,7 +18,7 @@ LOCAL_SHARED_LIBRARIES += libiprouteutil libnetlink
LOCAL_C_INCLUDES := $(KERNEL_HEADERS) external/iproute2/include
-LOCAL_CFLAGS := -O2 -g -W -Wall
+LOCAL_CFLAGS := -O2 -g -Wall -Wstrict-prototypes
include $(BUILD_EXECUTABLE)
diff --git a/tc/Makefile b/tc/Makefile
index f523adc..be8cd5a 100644
--- a/tc/Makefile
+++ b/tc/Makefile
@@ -91,7 +91,7 @@ YACC := bison
LEX := flex
CFLAGS += -DYY_NO_INPUT
-MODDESTDIR := $(DESTDIR)$(patsubst /usr%,%,$(LIBDIR))/tc
+MODDESTDIR := $(DESTDIR)$(LIBDIR)/tc
%.so: %.c
$(CC) $(CFLAGS) $(LDFLAGS) -shared -fpic $< -o $@
diff --git a/tc/em_meta.c b/tc/em_meta.c
index 033e29f..fad6b12 100644
--- a/tc/em_meta.c
+++ b/tc/em_meta.c
@@ -448,7 +448,7 @@ static inline int print_value(FILE *fd, int type, struct rtattr *rta)
"size mismatch.\n");
return -1;
}
- fprintf(fd, "%d", *(__u32 *) RTA_DATA(rta));
+ fprintf(fd, "%d", rta_getattr_u32(rta));
break;
case TCF_META_TYPE_VAR:
@@ -485,7 +485,7 @@ static int print_object(FILE *fd, struct tcf_meta_val *obj, struct rtattr *rta)
goto size_mismatch;
fprintf(fd, " mask 0x%08x",
- *(__u32*) RTA_DATA(rta));
+ rta_getattr_u32(rta));
}
break;
}
diff --git a/tc/f_basic.c b/tc/f_basic.c
index ad41633..67d26ec 100644
--- a/tc/f_basic.c
+++ b/tc/f_basic.c
@@ -122,7 +122,7 @@ static int basic_print_opt(struct filter_util *qu, FILE *f,
if (tb[TCA_BASIC_CLASSID]) {
SPRINT_BUF(b1);
fprintf(f, "flowid %s ",
- sprint_tc_classid(*(__u32*)RTA_DATA(tb[TCA_BASIC_CLASSID]), b1));
+ sprint_tc_classid(rta_getattr_u32(tb[TCA_BASIC_CLASSID]), b1));
}
if (tb[TCA_BASIC_EMATCHES])
diff --git a/tc/f_flow.c b/tc/f_flow.c
index 7d7af8c..6a8bfcb 100644
--- a/tc/f_flow.c
+++ b/tc/f_flow.c
@@ -286,7 +286,7 @@ static int flow_print_opt(struct filter_util *fu, FILE *f, struct rtattr *opt,
fprintf(f, "handle 0x%x ", handle);
if (tb[TCA_FLOW_MODE]) {
- __u32 mode = *(__u32 *)RTA_DATA(tb[TCA_FLOW_MODE]);
+ __u32 mode = rta_getattr_u32(tb[TCA_FLOW_MODE]);
switch (mode) {
case FLOW_MODE_MAP:
@@ -299,7 +299,7 @@ static int flow_print_opt(struct filter_util *fu, FILE *f, struct rtattr *opt,
}
if (tb[TCA_FLOW_KEYS]) {
- __u32 keymask = *(__u32 *)RTA_DATA(tb[TCA_FLOW_KEYS]);
+ __u32 keymask = rta_getattr_u32(tb[TCA_FLOW_KEYS]);
char *sep = "";
fprintf(f, "keys ");
@@ -313,9 +313,9 @@ static int flow_print_opt(struct filter_util *fu, FILE *f, struct rtattr *opt,
}
if (tb[TCA_FLOW_MASK])
- mask = *(__u32 *)RTA_DATA(tb[TCA_FLOW_MASK]);
+ mask = rta_getattr_u32(tb[TCA_FLOW_MASK]);
if (tb[TCA_FLOW_XOR])
- val = *(__u32 *)RTA_DATA(tb[TCA_FLOW_XOR]);
+ val = rta_getattr_u32(tb[TCA_FLOW_XOR]);
if (mask != ~0 || val != 0) {
__u32 or = (mask & val) ^ val;
@@ -331,21 +331,21 @@ static int flow_print_opt(struct filter_util *fu, FILE *f, struct rtattr *opt,
if (tb[TCA_FLOW_RSHIFT])
fprintf(f, "rshift %u ",
- *(__u32 *)RTA_DATA(tb[TCA_FLOW_RSHIFT]));
+ rta_getattr_u32(tb[TCA_FLOW_RSHIFT]));
if (tb[TCA_FLOW_ADDEND])
fprintf(f, "addend 0x%x ",
- *(__u32 *)RTA_DATA(tb[TCA_FLOW_ADDEND]));
+ rta_getattr_u32(tb[TCA_FLOW_ADDEND]));
if (tb[TCA_FLOW_DIVISOR])
fprintf(f, "divisor %u ",
- *(__u32 *)RTA_DATA(tb[TCA_FLOW_DIVISOR]));
+ rta_getattr_u32(tb[TCA_FLOW_DIVISOR]));
if (tb[TCA_FLOW_BASECLASS])
fprintf(f, "baseclass %s ",
- sprint_tc_classid(*(__u32 *)RTA_DATA(tb[TCA_FLOW_BASECLASS]), b1));
+ sprint_tc_classid(rta_getattr_u32(tb[TCA_FLOW_BASECLASS]), b1));
if (tb[TCA_FLOW_PERTURB])
fprintf(f, "perturb %usec ",
- *(__u32 *)RTA_DATA(tb[TCA_FLOW_PERTURB]));
+ rta_getattr_u32(tb[TCA_FLOW_PERTURB]));
if (tb[TCA_FLOW_EMATCHES])
print_ematch(f, tb[TCA_FLOW_EMATCHES]);
diff --git a/tc/f_fw.c b/tc/f_fw.c
index 219b404..161e2f7 100644
--- a/tc/f_fw.c
+++ b/tc/f_fw.c
@@ -130,7 +130,7 @@ static int fw_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u
if(handle)
mark = handle;
if(tb[TCA_FW_MASK] &&
- (mask = *(__u32*)RTA_DATA(tb[TCA_FW_MASK])) != 0xFFFFFFFF)
+ (mask = rta_getattr_u32(tb[TCA_FW_MASK])) != 0xFFFFFFFF)
fprintf(f, "handle 0x%x/0x%x ", mark, mask);
else
fprintf(f, "handle 0x%x ", handle);
@@ -138,14 +138,14 @@ static int fw_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u
if (tb[TCA_FW_CLASSID]) {
SPRINT_BUF(b1);
- fprintf(f, "classid %s ", sprint_tc_classid(*(__u32*)RTA_DATA(tb[TCA_FW_CLASSID]), b1));
+ fprintf(f, "classid %s ", sprint_tc_classid(rta_getattr_u32(tb[TCA_FW_CLASSID]), b1));
}
if (tb[TCA_FW_POLICE])
tc_print_police(f, tb[TCA_FW_POLICE]);
if (tb[TCA_FW_INDEV]) {
struct rtattr *idev = tb[TCA_FW_INDEV];
- fprintf(f, "input dev %s ",(char *)RTA_DATA(idev));
+ fprintf(f, "input dev %s ",rta_getattr_str(idev));
}
if (tb[TCA_FW_ACT]) {
diff --git a/tc/f_route.c b/tc/f_route.c
index eccf924..649e0ec 100644
--- a/tc/f_route.c
+++ b/tc/f_route.c
@@ -148,12 +148,12 @@ static int route_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt,
if (tb[TCA_ROUTE4_CLASSID]) {
SPRINT_BUF(b1);
- fprintf(f, "flowid %s ", sprint_tc_classid(*(__u32*)RTA_DATA(tb[TCA_ROUTE4_CLASSID]), b1));
+ fprintf(f, "flowid %s ", sprint_tc_classid(rta_getattr_u32(tb[TCA_ROUTE4_CLASSID]), b1));
}
if (tb[TCA_ROUTE4_TO])
- fprintf(f, "to %s ", rtnl_rtrealm_n2a(*(__u32*)RTA_DATA(tb[TCA_ROUTE4_TO]), b1, sizeof(b1)));
+ fprintf(f, "to %s ", rtnl_rtrealm_n2a(rta_getattr_u32(tb[TCA_ROUTE4_TO]), b1, sizeof(b1)));
if (tb[TCA_ROUTE4_FROM])
- fprintf(f, "from %s ", rtnl_rtrealm_n2a(*(__u32*)RTA_DATA(tb[TCA_ROUTE4_FROM]), b1, sizeof(b1)));
+ fprintf(f, "from %s ", rtnl_rtrealm_n2a(rta_getattr_u32(tb[TCA_ROUTE4_FROM]), b1, sizeof(b1)));
if (tb[TCA_ROUTE4_IIF])
fprintf(f, "fromif %s", ll_index_to_name(*(int*)RTA_DATA(tb[TCA_ROUTE4_IIF])));
if (tb[TCA_ROUTE4_POLICE])
diff --git a/tc/f_rsvp.c b/tc/f_rsvp.c
index 808310d..8eaf85d 100644
--- a/tc/f_rsvp.c
+++ b/tc/f_rsvp.c
@@ -336,9 +336,9 @@ static int rsvp_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, _
if (tb[TCA_RSVP_CLASSID]) {
SPRINT_BUF(b1);
if (!pinfo || pinfo->tunnelhdr == 0)
- fprintf(f, "flowid %s ", sprint_tc_classid(*(__u32*)RTA_DATA(tb[TCA_RSVP_CLASSID]), b1));
+ fprintf(f, "flowid %s ", sprint_tc_classid(rta_getattr_u32(tb[TCA_RSVP_CLASSID]), b1));
else
- fprintf(f, "tunnel %d skip %d ", *(__u32*)RTA_DATA(tb[TCA_RSVP_CLASSID]), pinfo->tunnelhdr);
+ fprintf(f, "tunnel %d skip %d ", rta_getattr_u32(tb[TCA_RSVP_CLASSID]), pinfo->tunnelhdr);
} else if (pinfo && pinfo->tunnelhdr)
fprintf(f, "tunnel [BAD] skip %d ", pinfo->tunnelhdr);
diff --git a/tc/f_tcindex.c b/tc/f_tcindex.c
index cb6f854..590c0a6 100644
--- a/tc/f_tcindex.c
+++ b/tc/f_tcindex.c
@@ -134,7 +134,7 @@ static int tcindex_print_opt(struct filter_util *qu, FILE *f,
if (RTA_PAYLOAD(tb[TCA_TCINDEX_HASH]) < sizeof(hash))
return -1;
- hash = *(__u16 *) RTA_DATA(tb[TCA_TCINDEX_HASH]);
+ hash = rta_getattr_u16(tb[TCA_TCINDEX_HASH]);
fprintf(f,"hash %d ",hash);
}
if (tb[TCA_TCINDEX_MASK]) {
@@ -142,7 +142,7 @@ static int tcindex_print_opt(struct filter_util *qu, FILE *f,
if (RTA_PAYLOAD(tb[TCA_TCINDEX_MASK]) < sizeof(mask))
return -1;
- mask = *(__u16 *) RTA_DATA(tb[TCA_TCINDEX_MASK]);
+ mask = rta_getattr_u16(tb[TCA_TCINDEX_MASK]);
fprintf(f,"mask 0x%04x ",mask);
}
if (tb[TCA_TCINDEX_SHIFT]) {
diff --git a/tc/f_u32.c b/tc/f_u32.c
index 479b3f1..975c0b5 100644
--- a/tc/f_u32.c
+++ b/tc/f_u32.c
@@ -1198,9 +1198,9 @@ static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt,
}
if (tb[TCA_U32_DIVISOR]) {
- fprintf(f, "ht divisor %d ", *(__u32*)RTA_DATA(tb[TCA_U32_DIVISOR]));
+ fprintf(f, "ht divisor %d ", rta_getattr_u32(tb[TCA_U32_DIVISOR]));
} else if (tb[TCA_U32_HASH]) {
- __u32 htid = *(__u32*)RTA_DATA(tb[TCA_U32_HASH]);
+ __u32 htid = rta_getattr_u32(tb[TCA_U32_HASH]);
fprintf(f, "key ht %x bkt %x ", TC_U32_USERHTID(htid),
TC_U32_HASH(htid));
} else {
@@ -1210,14 +1210,14 @@ static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt,
SPRINT_BUF(b1);
fprintf(f, "%sflowid %s ",
!sel || !(sel->flags&TC_U32_TERMINAL) ? "*" : "",
- sprint_tc_classid(*(__u32*)RTA_DATA(tb[TCA_U32_CLASSID]), b1));
+ sprint_tc_classid(rta_getattr_u32(tb[TCA_U32_CLASSID]), b1));
} else if (sel && sel->flags&TC_U32_TERMINAL) {
fprintf(f, "terminal flowid ??? ");
}
if (tb[TCA_U32_LINK]) {
SPRINT_BUF(b1);
fprintf(f, "link %s ",
- sprint_u32_handle(*(__u32*)RTA_DATA(tb[TCA_U32_LINK]), b1));
+ sprint_u32_handle(rta_getattr_u32(tb[TCA_U32_LINK]), b1));
}
if (tb[TCA_U32_PCNT]) {
@@ -1278,7 +1278,7 @@ static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt,
}
if (tb[TCA_U32_INDEV]) {
struct rtattr *idev = tb[TCA_U32_INDEV];
- fprintf(f, "\n input dev %s\n", (char *) RTA_DATA(idev));
+ fprintf(f, "\n input dev %s\n", rta_getattr_str(idev));
}
if (tb[TCA_U32_ACT]) {
tc_print_action(f, tb[TCA_U32_ACT]);
diff --git a/tc/m_ipt.c b/tc/m_ipt.c
index b8655f8..dc2dedc 100644
--- a/tc/m_ipt.c
+++ b/tc/m_ipt.c
@@ -552,7 +552,7 @@ print_ipt(struct action_util *au,FILE * f, struct rtattr *arg)
fprintf(f, "[NULL ipt table name ] assuming mangle ");
} else {
fprintf(f, "tablename: %s ",
- (char *) RTA_DATA(tb[TCA_IPT_TABLE]));
+ rta_getattr_str(tb[TCA_IPT_TABLE]));
}
if (tb[TCA_IPT_HOOK] == NULL) {
@@ -560,7 +560,7 @@ print_ipt(struct action_util *au,FILE * f, struct rtattr *arg)
return -1;
} else {
__u32 hook;
- hook = *(__u32 *) RTA_DATA(tb[TCA_IPT_HOOK]);
+ hook = rta_getattr_u32(tb[TCA_IPT_HOOK]);
fprintf(f, " hook: %s \n", ipthooks[hook]);
}
@@ -591,7 +591,7 @@ print_ipt(struct action_util *au,FILE * f, struct rtattr *arg)
fprintf(f, " [NULL ipt target index ]\n");
} else {
__u32 index;
- index = *(__u32 *) RTA_DATA(tb[TCA_IPT_INDEX]);
+ index = rta_getattr_u32(tb[TCA_IPT_INDEX]);
fprintf(f, " \n\tindex %d", index);
}
diff --git a/tc/m_police.c b/tc/m_police.c
index ace43b5..c3869b6 100644
--- a/tc/m_police.c
+++ b/tc/m_police.c
@@ -353,7 +353,7 @@ print_police(struct action_util *a, FILE *f, struct rtattr *arg)
if (p->peakrate.rate)
fprintf(f, "peakrate %s ", sprint_rate(p->peakrate.rate, b1));
if (tb[TCA_POLICE_AVRATE])
- fprintf(f, "avrate %s ", sprint_rate(*(__u32*)RTA_DATA(tb[TCA_POLICE_AVRATE]), b1));
+ fprintf(f, "avrate %s ", sprint_rate(rta_getattr_u32(tb[TCA_POLICE_AVRATE]), b1));
fprintf(f, "action %s", police_action_n2a(p->action, b1, sizeof(b1)));
if (tb[TCA_POLICE_RESULT]) {
fprintf(f, "/%s ", police_action_n2a(*(int*)RTA_DATA(tb[TCA_POLICE_RESULT]), b1, sizeof(b1)));
diff --git a/tc/m_xt.c b/tc/m_xt.c
index 8f2a295..bcc4d75 100644
--- a/tc/m_xt.c
+++ b/tc/m_xt.c
@@ -284,7 +284,7 @@ print_ipt(struct action_util *au,FILE * f, struct rtattr *arg)
fprintf(f, "[NULL ipt table name ] assuming mangle ");
} else {
fprintf(f, "tablename: %s ",
- (char *) RTA_DATA(tb[TCA_IPT_TABLE]));
+ rta_getattr_str(tb[TCA_IPT_TABLE]));
}
if (tb[TCA_IPT_HOOK] == NULL) {
@@ -292,7 +292,7 @@ print_ipt(struct action_util *au,FILE * f, struct rtattr *arg)
return -1;
} else {
__u32 hook;
- hook = *(__u32 *) RTA_DATA(tb[TCA_IPT_HOOK]);
+ hook = rta_getattr_u32(tb[TCA_IPT_HOOK]);
fprintf(f, " hook: %s \n", ipthooks[hook]);
}
@@ -328,7 +328,7 @@ print_ipt(struct action_util *au,FILE * f, struct rtattr *arg)
fprintf(f, " [NULL ipt target index ]\n");
} else {
__u32 index;
- index = *(__u32 *) RTA_DATA(tb[TCA_IPT_INDEX]);
+ index = rta_getattr_u32(tb[TCA_IPT_INDEX]);
fprintf(f, " \n\tindex %d", index);
}
diff --git a/tc/m_xt_old.c b/tc/m_xt_old.c
index 7ed7ecc..554e4ed 100644
--- a/tc/m_xt_old.c
+++ b/tc/m_xt_old.c
@@ -367,7 +367,7 @@ print_ipt(struct action_util *au,FILE * f, struct rtattr *arg)
fprintf(f, "[NULL ipt table name ] assuming mangle ");
} else {
fprintf(f, "tablename: %s ",
- (char *) RTA_DATA(tb[TCA_IPT_TABLE]));
+ rta_getattr_str(tb[TCA_IPT_TABLE]));
}
if (tb[TCA_IPT_HOOK] == NULL) {
@@ -375,7 +375,7 @@ print_ipt(struct action_util *au,FILE * f, struct rtattr *arg)
return -1;
} else {
__u32 hook;
- hook = *(__u32 *) RTA_DATA(tb[TCA_IPT_HOOK]);
+ hook = rta_getattr_u32(tb[TCA_IPT_HOOK]);
fprintf(f, " hook: %s \n", ipthooks[hook]);
}
@@ -406,7 +406,7 @@ print_ipt(struct action_util *au,FILE * f, struct rtattr *arg)
fprintf(f, " [NULL ipt target index ]\n");
} else {
__u32 index;
- index = *(__u32 *) RTA_DATA(tb[TCA_IPT_INDEX]);
+ index = rta_getattr_u32(tb[TCA_IPT_INDEX]);
fprintf(f, " \n\tindex %d", index);
}
diff --git a/tc/q_atm.c b/tc/q_atm.c
index eec0d77..2598e29 100644
--- a/tc/q_atm.c
+++ b/tc/q_atm.c
@@ -210,11 +210,11 @@ static int atm_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
}
if (tb[TCA_ATM_HDR]) {
int i;
+ const __u8 *hdr = RTA_DATA(tb[TCA_ATM_HDR]);
fprintf(f,"hdr");
for (i = 0; i < RTA_PAYLOAD(tb[TCA_ATM_HDR]); i++)
- fprintf(f,"%c%02x",i ? '.' : ' ',
- ((unsigned char *) RTA_DATA(tb[TCA_ATM_HDR]))[i]);
+ fprintf(f,"%c%02x", i ? '.' : ' ', hdr[i]);
if (!i) fprintf(f," .");
fprintf(f," ");
}
@@ -224,7 +224,7 @@ static int atm_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
if (RTA_PAYLOAD(tb[TCA_ATM_EXCESS]) < sizeof(excess))
fprintf(stderr,"ATM: excess class ID too short\n");
else {
- excess = *(__u32 *) RTA_DATA(tb[TCA_ATM_EXCESS]);
+ excess = rta_getattr_u32(tb[TCA_ATM_EXCESS]);
if (!excess) fprintf(f,"excess clp ");
else {
char buf[64];
diff --git a/tc/q_choke.c b/tc/q_choke.c
index c616926..6fbcadf 100644
--- a/tc/q_choke.c
+++ b/tc/q_choke.c
@@ -182,7 +182,7 @@ static int choke_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
return -1;
if (tb[TCA_CHOKE_MAX_P] &&
RTA_PAYLOAD(tb[TCA_CHOKE_MAX_P]) >= sizeof(__u32))
- max_P = *(__u32 *)RTA_DATA(tb[TCA_CHOKE_MAX_P]);
+ max_P = rta_getattr_u32(tb[TCA_CHOKE_MAX_P]);
fprintf(f, "limit %up min %up max %up ",
qopt->limit, qopt->qth_min, qopt->qth_max);
diff --git a/tc/q_drr.c b/tc/q_drr.c
index 9d3788f..746736d 100644
--- a/tc/q_drr.c
+++ b/tc/q_drr.c
@@ -93,7 +93,7 @@ static int drr_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
if (tb[TCA_DRR_QUANTUM])
fprintf(f, "quantum %s ",
- sprint_size(*(__u32 *)RTA_DATA(tb[TCA_DRR_QUANTUM]), b1));
+ sprint_size(rta_getattr_u32(tb[TCA_DRR_QUANTUM]), b1));
return 0;
}
diff --git a/tc/q_dsmark.c b/tc/q_dsmark.c
index cfbb335..05185c0 100644
--- a/tc/q_dsmark.c
+++ b/tc/q_dsmark.c
@@ -140,25 +140,25 @@ static int dsmark_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
if (!RTA_PAYLOAD(tb[TCA_DSMARK_MASK]))
fprintf(stderr,"dsmark: empty mask\n");
else fprintf(f,"mask 0x%02x ",
- *(__u8 *) RTA_DATA(tb[TCA_DSMARK_MASK]));
+ rta_getattr_u8(tb[TCA_DSMARK_MASK]));
}
if (tb[TCA_DSMARK_VALUE]) {
if (!RTA_PAYLOAD(tb[TCA_DSMARK_VALUE]))
fprintf(stderr,"dsmark: empty value\n");
else fprintf(f,"value 0x%02x ",
- *(__u8 *) RTA_DATA(tb[TCA_DSMARK_VALUE]));
+ rta_getattr_u8(tb[TCA_DSMARK_VALUE]));
}
if (tb[TCA_DSMARK_INDICES]) {
if (RTA_PAYLOAD(tb[TCA_DSMARK_INDICES]) < sizeof(__u16))
fprintf(stderr,"dsmark: indices too short\n");
else fprintf(f,"indices 0x%04x ",
- *(__u16 *) RTA_DATA(tb[TCA_DSMARK_INDICES]));
+ rta_getattr_u16(tb[TCA_DSMARK_INDICES]));
}
if (tb[TCA_DSMARK_DEFAULT_INDEX]) {
if (RTA_PAYLOAD(tb[TCA_DSMARK_DEFAULT_INDEX]) < sizeof(__u16))
fprintf(stderr,"dsmark: default_index too short\n");
else fprintf(f,"default_index 0x%04x ",
- *(__u16 *) RTA_DATA(tb[TCA_DSMARK_DEFAULT_INDEX]));
+ rta_getattr_u16(tb[TCA_DSMARK_DEFAULT_INDEX]));
}
if (tb[TCA_DSMARK_SET_TC_INDEX]) fprintf(f,"set_tc_index ");
return 0;
diff --git a/tc/q_prio.c b/tc/q_prio.c
index 2f54d55..79b4fd0 100644
--- a/tc/q_prio.c
+++ b/tc/q_prio.c
@@ -112,7 +112,7 @@ int prio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
if (tb[TCA_PRIO_MQ])
fprintf(f, " multiqueue: %s ",
- *(unsigned char *)RTA_DATA(tb[TCA_PRIO_MQ]) ? "on" : "off");
+ rta_getattr_u8(tb[TCA_PRIO_MQ]) ? "on" : "off");
return 0;
}
diff --git a/tc/q_qfq.c b/tc/q_qfq.c
index 3ade662..05b4d84 100644
--- a/tc/q_qfq.c
+++ b/tc/q_qfq.c
@@ -102,12 +102,12 @@ static int qfq_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
if (tb[TCA_QFQ_WEIGHT]) {
fprintf(f, "weight %u ",
- *(__u32 *)RTA_DATA(tb[TCA_QFQ_WEIGHT]));
+ rta_getattr_u32(tb[TCA_QFQ_WEIGHT]));
}
if (tb[TCA_QFQ_LMAX]) {
fprintf(f, "maxpkt %u ",
- *(__u32 *)RTA_DATA(tb[TCA_QFQ_LMAX]));
+ rta_getattr_u32(tb[TCA_QFQ_LMAX]));
}
return 0;
diff --git a/tc/q_red.c b/tc/q_red.c
index aad47be..65a1301 100644
--- a/tc/q_red.c
+++ b/tc/q_red.c
@@ -180,7 +180,7 @@ static int red_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
if (tb[TCA_RED_MAX_P] &&
RTA_PAYLOAD(tb[TCA_RED_MAX_P]) >= sizeof(__u32))
- max_P = *(__u32 *)RTA_DATA(tb[TCA_RED_MAX_P]);
+ max_P = rta_getattr_u32(tb[TCA_RED_MAX_P]);
fprintf(f, "limit %s min %s max %s ",
sprint_size(qopt->limit, b1),
diff --git a/tc/q_rr.c b/tc/q_rr.c
index 1ff3ac9..79072ad 100644
--- a/tc/q_rr.c
+++ b/tc/q_rr.c
@@ -107,7 +107,7 @@ int rr_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
if (tb[TCA_PRIO_MQ])
fprintf(f, " multiqueue: %s ",
- *(unsigned char *)RTA_DATA(tb[TCA_PRIO_MQ]) ? "on" : "off");
+ rta_getattr_u8(tb[TCA_PRIO_MQ]) ? "on" : "off");
return 0;
}
diff --git a/tc/tc_class.c b/tc/tc_class.c
index 3a1a0ac..de18fd1 100644
--- a/tc/tc_class.c
+++ b/tc/tc_class.c
@@ -191,7 +191,7 @@ int print_class(const struct sockaddr_nl *who,
else
print_tc_classid(abuf, sizeof(abuf), t->tcm_handle);
}
- fprintf(fp, "class %s %s ", (char*)RTA_DATA(tb[TCA_KIND]), abuf);
+ fprintf(fp, "class %s %s ", rta_getattr_str(tb[TCA_KIND]), abuf);
if (filter_ifindex == 0)
fprintf(fp, "dev %s ", ll_index_to_name(t->tcm_ifindex));
diff --git a/tc/tc_filter.c b/tc/tc_filter.c
index d4b0b67..207302f 100644
--- a/tc/tc_filter.c
+++ b/tc/tc_filter.c
@@ -240,7 +240,7 @@ int print_filter(const struct sockaddr_nl *who,
fprintf(fp, "pref %u ", prio);
}
}
- fprintf(fp, "%s ", (char*)RTA_DATA(tb[TCA_KIND]));
+ fprintf(fp, "%s ", rta_getattr_str(tb[TCA_KIND]));
q = get_filter_kind(RTA_DATA(tb[TCA_KIND]));
if (tb[TCA_OPTIONS]) {
if (q)
diff --git a/tc/tc_qdisc.c b/tc/tc_qdisc.c
index 0822e63..3f932a7 100644
--- a/tc/tc_qdisc.c
+++ b/tc/tc_qdisc.c
@@ -229,7 +229,7 @@ int print_qdisc(const struct sockaddr_nl *who,
if (n->nlmsg_type == RTM_DELQDISC)
fprintf(fp, "deleted ");
- fprintf(fp, "qdisc %s %x: ", (char*)RTA_DATA(tb[TCA_KIND]), t->tcm_handle>>16);
+ fprintf(fp, "qdisc %s %x: ", rta_getattr_str(tb[TCA_KIND]), t->tcm_handle>>16);
if (filter_ifindex == 0)
fprintf(fp, "dev %s ", ll_index_to_name(t->tcm_ifindex));
if (t->tcm_parent == TC_H_ROOT)
diff --git a/tc/tc_util.c b/tc/tc_util.c
index 36e3c7d..926ed08 100644
--- a/tc/tc_util.c
+++ b/tc/tc_util.c
@@ -25,7 +25,7 @@
#include "tc_util.h"
#ifndef LIBDIR
-#define LIBDIR "/usr/lib/"
+#define LIBDIR "/usr/lib"
#endif
const char *get_tc_lib(void)