Merge branch 'master' into net-next-3.11
diff --git a/bridge/fdb.c b/bridge/fdb.c
index 591fbbe..e2e53f1 100644
--- a/bridge/fdb.c
+++ b/bridge/fdb.c
@@ -30,7 +30,7 @@
 
 static void usage(void)
 {
-	fprintf(stderr, "Usage: bridge fdb { add | append | del } ADDR dev DEV {self|master} [ temp ]\n"
+	fprintf(stderr, "Usage: bridge fdb { add | append | del | replace } ADDR dev DEV {self|master} [ temp ]\n"
 		        "              [router] [ dst IPADDR] [ vlan VID ]\n"
 		        "              [ port PORT] [ vni VNI ] [via DEV]\n");
 	fprintf(stderr, "       bridge fdb {show} [ dev DEV ]\n");
@@ -334,6 +334,8 @@
 			return fdb_modify(RTM_NEWNEIGH, NLM_F_CREATE|NLM_F_EXCL, argc-1, argv+1);
 		if (matches(*argv, "append") == 0)
 			return fdb_modify(RTM_NEWNEIGH, NLM_F_CREATE|NLM_F_APPEND, argc-1, argv+1);
+		if (matches(*argv, "replace") == 0)
+			return fdb_modify(RTM_NEWNEIGH, NLM_F_CREATE|NLM_F_REPLACE, argc-1, argv+1);
 		if (matches(*argv, "delete") == 0)
 			return fdb_modify(RTM_DELNEIGH, 0, argc-1, argv+1);
 		if (matches(*argv, "show") == 0 ||
diff --git a/doc/ip-cref.tex b/doc/ip-cref.tex
index d8fed66..f062b3a 100644
--- a/doc/ip-cref.tex
+++ b/doc/ip-cref.tex
@@ -2542,13 +2542,15 @@
 the \verb|monitor| command is the first in the command line and then
 the object list follows:
 \begin{verbatim}
-  ip monitor [ file FILE ] [ all | OBJECT-LIST ]
+  ip monitor [ file FILE ] [ all | OBJECT-LIST ] [ label ]
 \end{verbatim}
-\verb|OBJECT-LIST| is the list of object types that we want to monitor.
-It may contain \verb|link|, \verb|address| and \verb|route|.
-If no \verb|file| argument is given, \verb|ip| opens RTNETLINK,
-listens on it and dumps state changes in the format described
-in previous sections.
+\verb|OBJECT-LIST| is the list of object types that we want to
+monitor.  It may contain \verb|link|, \verb|address| and \verb|route|.
+Specifying \verb|label| indicates that output lines should be labelled
+with the type of object being printed --- this happens by default if
+\verb|all| is specified.  If no \verb|file| argument is given,
+\verb|ip| opens RTNETLINK, listens on it and dumps state changes in
+the format described in previous sections.
 
 If a file name is given, it does not listen on RTNETLINK,
 but opens the file containing RTNETLINK messages saved in binary format
diff --git a/include/SNAPSHOT.h b/include/SNAPSHOT.h
index 63b857d..8f896b7 100644
--- a/include/SNAPSHOT.h
+++ b/include/SNAPSHOT.h
@@ -1 +1 @@
-static const char SNAPSHOT[] = "130716";
+static const char SNAPSHOT[] = "130903";
diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h
index dbd71b0..09d62b9 100644
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -73,9 +73,17 @@
 #define TC_H_ROOT	(0xFFFFFFFFU)
 #define TC_H_INGRESS    (0xFFFFFFF1U)
 
+/* Need to corrospond to iproute2 tc/tc_core.h "enum link_layer" */
+enum tc_link_layer {
+	TC_LINKLAYER_UNAWARE, /* Indicate unaware old iproute2 util */
+	TC_LINKLAYER_ETHERNET,
+	TC_LINKLAYER_ATM,
+};
+#define TC_LINKLAYER_MASK 0x0F /* limit use to lower 4 bits */
+
 struct tc_ratespec {
 	unsigned char	cell_log;
-	unsigned char	__reserved;
+	__u8		linklayer; /* lower 4 bits */
 	unsigned short	overhead;
 	short		cell_align;
 	unsigned short	mpu;
diff --git a/ip/iplink_macvlan.c b/ip/iplink_macvlan.c
index 5b4b868..ec51106 100644
--- a/ip/iplink_macvlan.c
+++ b/ip/iplink_macvlan.c
@@ -79,7 +79,7 @@
 	    RTA_PAYLOAD(tb[IFLA_MACVLAN_MODE]) < sizeof(__u32))
 		return;
 
-	mode = rta_getattr_u32(tb[IFLA_VLAN_ID]);
+	mode = rta_getattr_u32(tb[IFLA_MACVLAN_MODE]);
 	fprintf(f, " mode %s ",
 		  mode == MACVLAN_MODE_PRIVATE ? "private"
 		: mode == MACVLAN_MODE_VEPA    ? "vepa"
diff --git a/ip/ipmonitor.c b/ip/ipmonitor.c
index 86c473e..70f2a7a 100644
--- a/ip/ipmonitor.c
+++ b/ip/ipmonitor.c
@@ -29,14 +29,13 @@
 
 static void usage(void)
 {
-	fprintf(stderr, "Usage: ip monitor [ all | LISTofOBJECTS ] [ FILE ]\n");
+	fprintf(stderr, "Usage: ip monitor [ all | LISTofOBJECTS ] [ FILE ] [ label ]\n");
 	fprintf(stderr, "LISTofOBJECTS := link | address | route | mroute | prefix |\n");
 	fprintf(stderr, "                 neigh | netconf\n");
 	fprintf(stderr, "FILE := file FILENAME\n");
 	exit(-1);
 }
 
-
 static int accept_msg(const struct sockaddr_nl *who,
 		      struct nlmsghdr *n, void *arg)
 {
@@ -88,6 +87,13 @@
 	}
 	if (n->nlmsg_type == RTM_NEWNEIGH || n->nlmsg_type == RTM_DELNEIGH ||
 	    n->nlmsg_type == RTM_GETNEIGH) {
+		if (preferred_family) {
+			struct ndmsg *r = NLMSG_DATA(n);
+
+			if (r->ndm_family != preferred_family)
+				return 0;
+		}
+
 		if (prefix_banner)
 			fprintf(fp, "[NEIGH]");
 		print_neigh(who, n, arg);
@@ -157,6 +163,8 @@
 		if (matches(*argv, "file") == 0) {
 			NEXT_ARG();
 			file = *argv;
+		} else if (matches(*argv, "label") == 0) {
+			prefix_banner = 1;
 		} else if (matches(*argv, "link") == 0) {
 			llink=1;
 			groups = 0;
diff --git a/ip/ipnetns.c b/ip/ipnetns.c
index 794a498..89dda3f 100644
--- a/ip/ipnetns.c
+++ b/ip/ipnetns.c
@@ -167,7 +167,7 @@
 		fprintf(stderr, "unshare failed: %s\n", strerror(errno));
 		return -1;
 	}
-	/* Don't let any mounts propogate back to the parent */
+	/* Don't let any mounts propagate back to the parent */
 	if (mount("", "/", "none", MS_SLAVE | MS_REC, NULL)) {
 		fprintf(stderr, "\"mount --make-rslave /\" failed: %s\n",
 			strerror(errno));
@@ -205,11 +205,15 @@
 				exit(1);
 			}
 
-			/* If child failed, propogate status */
-			if (WIFEXITED(status))
-				exit(WEXITSTATUS(status));
+			if (WIFEXITED(status)) {
+				/* ip must return the status of the child,
+				 * but do_cmd() will add a minus to this,
+				 * so let's add another one here to cancel it.
+				 */
+				return -WEXITSTATUS(status);
+			}
 
-			return 0;
+			exit(1);
 		}
 	}
 
@@ -405,7 +409,7 @@
 	/* Create the base netns directory if it doesn't exist */
 	mkdir(NETNS_RUN_DIR, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
 
-	/* Make it possible for network namespace mounts to propogate between
+	/* Make it possible for network namespace mounts to propagate between
 	 * mount namespaces.  This makes it likely that a unmounting a network
 	 * namespace file in one namespace will unmount the network namespace
 	 * file in all namespaces allowing the network namespace to be freed
diff --git a/ip/ipntable.c b/ip/ipntable.c
index 67b199e..193e50c 100644
--- a/ip/ipntable.c
+++ b/ip/ipntable.c
@@ -305,7 +305,7 @@
 	if (!namep)
 		missarg("NAME");
 	if (!threshsp && !gc_intp && !parms_change) {
-		fprintf(stderr, "Not enough information: changable attributes required.\n");
+		fprintf(stderr, "Not enough information: changeable attributes required.\n");
 		exit(-1);
 	}
 
diff --git a/ip/iproute.c b/ip/iproute.c
index b069f1e..25a56d1 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -63,7 +63,7 @@
 	fprintf(stderr, "       ip route restore\n");
 	fprintf(stderr, "       ip route showdump\n");
 	fprintf(stderr, "       ip route get ADDRESS [ from ADDRESS iif STRING ]\n");
-	fprintf(stderr, "                            [ oif STRING ]  [ tos TOS ]\n");
+	fprintf(stderr, "                            [ oif STRING ] [ tos TOS ]\n");
 	fprintf(stderr, "                            [ mark NUMBER ]\n");
 	fprintf(stderr, "       ip route { add | del | change | append | replace } ROUTE\n");
 	fprintf(stderr, "SELECTOR := [ root PREFIX ] [ match PREFIX ] [ exact PREFIX ]\n");
@@ -76,7 +76,7 @@
 	fprintf(stderr, "INFO_SPEC := NH OPTIONS FLAGS [ nexthop NH ]...\n");
 	fprintf(stderr, "NH := [ via ADDRESS ] [ dev STRING ] [ weight NUMBER ] NHFLAGS\n");
 	fprintf(stderr, "OPTIONS := FLAGS [ mtu NUMBER ] [ advmss NUMBER ]\n");
-	fprintf(stderr, "           [ rtt TIME ] [ rttvar TIME ] [reordering NUMBER ]\n");
+	fprintf(stderr, "           [ rtt TIME ] [ rttvar TIME ] [ reordering NUMBER ]\n");
 	fprintf(stderr, "           [ window NUMBER] [ cwnd NUMBER ] [ initcwnd NUMBER ]\n");
 	fprintf(stderr, "           [ ssthresh NUMBER ] [ realms REALM ] [ src ADDRESS ]\n");
 	fprintf(stderr, "           [ rto_min TIME ] [ hoplimit NUMBER ] [ initrwnd NUMBER ]\n");
diff --git a/ip/iptunnel.c b/ip/iptunnel.c
index 43f8585..40186d3 100644
--- a/ip/iptunnel.c
+++ b/ip/iptunnel.c
@@ -280,7 +280,7 @@
 		return -1;
 
 	if (p.iph.ttl && p.iph.frag_off == 0) {
-		fprintf(stderr, "ttl != 0 and noptmudisc are incompatible\n");
+		fprintf(stderr, "ttl != 0 and nopmtudisc are incompatible\n");
 		return -1;
 	}
 
diff --git a/ip/ipxfrm.c b/ip/ipxfrm.c
index 0a3a9fb..411d9d5 100644
--- a/ip/ipxfrm.c
+++ b/ip/ipxfrm.c
@@ -856,7 +856,7 @@
 		if (flags)
 			fprintf(fp, "%x", flags);
 	}
-	if (show_stats > 0 || tb[XFRMA_SA_EXTRA_FLAGS]) {
+	if (show_stats > 0 && tb[XFRMA_SA_EXTRA_FLAGS]) {
 		__u32 extra_flags = *(__u32 *)RTA_DATA(tb[XFRMA_SA_EXTRA_FLAGS]);
 
 		fprintf(fp, "extra_flag ");
diff --git a/ip/link_iptnl.c b/ip/link_iptnl.c
index 394254d..d5324f8 100644
--- a/ip/link_iptnl.c
+++ b/ip/link_iptnl.c
@@ -233,7 +233,7 @@
 	}
 
 	if (ttl && pmtudisc == 0) {
-		fprintf(stderr, "ttl != 0 and noptmudisc are incompatible\n");
+		fprintf(stderr, "ttl != 0 and nopmtudisc are incompatible\n");
 		exit(-1);
 	}
 
diff --git a/ip/link_veth.c b/ip/link_veth.c
index 3d19b01..7730f39 100644
--- a/ip/link_veth.c
+++ b/ip/link_veth.c
@@ -19,9 +19,8 @@
 
 static void usage(void)
 {
-	printf("Usage: ip link <options> type veth "
-	       "[peer <options>]\nTo get <options> type "
-	       "'ip link add help'\n");
+	printf("Usage: ip link <options> type veth [peer <options>]\n"
+	       "To get <options> type 'ip link add help'\n");
 }
 
 static int veth_parse_opt(struct link_util *lu, int argc, char **argv,
diff --git a/man/man8/ip-route.8.in b/man/man8/ip-route.8.in
index 7191bce..79bc7f1 100644
--- a/man/man8/ip-route.8.in
+++ b/man/man8/ip-route.8.in
@@ -97,6 +97,8 @@
 .IR TIME " ] [ "
 .B  rttvar
 .IR TIME " ] [ "
+.B  reordering
+.IR NUMBER " ] [ "
 .B  window
 .IR NUMBER " ] [ "
 .B  cwnd
@@ -110,7 +112,7 @@
 .B  initcwnd
 .IR NUMBER " ] [ "
 .B  initrwnd
-.IR NUMBER " ]"
+.IR NUMBER " ] [ "
 .B  quickack
 .IR BOOL " ]"
 
diff --git a/tc/m_ipt.c b/tc/m_ipt.c
index dc2dedc..bb016f1 100644
--- a/tc/m_ipt.c
+++ b/tc/m_ipt.c
@@ -415,7 +415,7 @@
 	}
 
 	if (argc <= 2) {
-		fprintf(stderr,"bad arguements to ipt %d vs %d \n", argc, rargc);
+		fprintf(stderr,"bad arguments to ipt %d vs %d \n", argc, rargc);
 		return -1;
 	}
 
diff --git a/tc/m_mirred.c b/tc/m_mirred.c
index 1ef9f2b..dc231d7 100644
--- a/tc/m_mirred.c
+++ b/tc/m_mirred.c
@@ -105,7 +105,7 @@
 			} else if (!mirror && matches(*argv, "mirror") == 0) {
 				mirror=1;
 				if (redir) {
-					fprintf(stderr, "Cant have both mirror and redir\n");
+					fprintf(stderr, "Can't have both mirror and redir\n");
 					return -1;
 				}
 				p.eaction = TCA_EGRESS_MIRROR;
@@ -114,7 +114,7 @@
 			} else if (!redir && matches(*argv, "redirect") == 0) {
 				redir=1;
 				if (mirror) {
-					fprintf(stderr, "Cant have both mirror and redir\n");
+					fprintf(stderr, "Can't have both mirror and redir\n");
 					return -1;
 				}
 				p.eaction = TCA_EGRESS_REDIR;
@@ -215,14 +215,14 @@
 	char **argv = *argv_p;
 
 	if (argc < 0) {
-		fprintf(stderr,"mirred bad arguement count %d\n", argc);
+		fprintf(stderr,"mirred bad argument count %d\n", argc);
 		return -1;
 	}
 
 	if (matches(*argv, "mirred") == 0) {
 		NEXT_ARG();
 	} else {
-		fprintf(stderr,"mirred bad arguement %s\n", *argv);
+		fprintf(stderr,"mirred bad argument %s\n", *argv);
 		return -1;
 	}
 
diff --git a/tc/m_police.c b/tc/m_police.c
index 53cbefc..300287e 100644
--- a/tc/m_police.c
+++ b/tc/m_police.c
@@ -322,9 +322,11 @@
 print_police(struct action_util *a, FILE *f, struct rtattr *arg)
 {
 	SPRINT_BUF(b1);
+	SPRINT_BUF(b2);
 	struct tc_police *p;
 	struct rtattr *tb[TCA_POLICE_MAX+1];
 	unsigned buffer;
+	unsigned int linklayer;
 
 	if (arg == NULL)
 		return 0;
@@ -360,6 +362,9 @@
 	} else
 		fprintf(f, " ");
 	fprintf(f, "overhead %ub ", p->rate.overhead);
+	linklayer = (p->rate.linklayer & TC_LINKLAYER_MASK);
+	if (linklayer > TC_LINKLAYER_ETHERNET || show_details)
+		fprintf(f, "linklayer %s ", sprint_linklayer(linklayer, b2));
 	fprintf(f, "\nref %d bind %d\n",p->refcnt, p->bindcnt);
 
 	return 0;
diff --git a/tc/m_xt.c b/tc/m_xt.c
index e918670..27029c1 100644
--- a/tc/m_xt.c
+++ b/tc/m_xt.c
@@ -147,7 +147,7 @@
 	}
 
 	if (argc <= 2) {
-		fprintf(stderr,"bad arguements to ipt %d vs %d \n", argc, rargc);
+		fprintf(stderr,"bad arguments to ipt %d vs %d \n", argc, rargc);
 		return -1;
 	}
 
diff --git a/tc/m_xt_old.c b/tc/m_xt_old.c
index 554e4ed..4d61a5a 100644
--- a/tc/m_xt_old.c
+++ b/tc/m_xt_old.c
@@ -232,7 +232,7 @@
 	}
 
 	if (argc <= 2) {
-		fprintf(stderr,"bad arguements to ipt %d vs %d \n", argc, rargc);
+		fprintf(stderr,"bad arguments to ipt %d vs %d \n", argc, rargc);
 		return -1;
 	}
 
diff --git a/tc/q_cbq.c b/tc/q_cbq.c
index 3c5e72c..d76600c 100644
--- a/tc/q_cbq.c
+++ b/tc/q_cbq.c
@@ -442,7 +442,9 @@
 	struct tc_cbq_wrropt *wrr = NULL;
 	struct tc_cbq_fopt *fopt = NULL;
 	struct tc_cbq_ovl *ovl = NULL;
+	unsigned int linklayer;
 	SPRINT_BUF(b1);
+	SPRINT_BUF(b2);
 
 	if (opt == NULL)
 		return 0;
@@ -486,6 +488,9 @@
 		char buf[64];
 		print_rate(buf, sizeof(buf), r->rate);
 		fprintf(f, "rate %s ", buf);
+		linklayer = (r->linklayer & TC_LINKLAYER_MASK);
+		if (linklayer > TC_LINKLAYER_ETHERNET || show_details)
+			fprintf(f, "linklayer %s ", sprint_linklayer(linklayer, b2));
 		if (show_details) {
 			fprintf(f, "cell %ub ", 1<<r->cell_log);
 			if (r->mpu)
diff --git a/tc/q_htb.c b/tc/q_htb.c
index 9321c0a..7b6f908 100644
--- a/tc/q_htb.c
+++ b/tc/q_htb.c
@@ -244,9 +244,11 @@
 	struct tc_htb_opt *hopt;
 	struct tc_htb_glob *gopt;
 	double buffer,cbuffer;
+	unsigned int linklayer;
 	SPRINT_BUF(b1);
 	SPRINT_BUF(b2);
 	SPRINT_BUF(b3);
+	SPRINT_BUF(b4);
 
 	if (opt == NULL)
 		return 0;
@@ -268,6 +270,9 @@
 		buffer = tc_calc_xmitsize(hopt->rate.rate, hopt->buffer);
 		fprintf(f, "ceil %s ", sprint_rate(hopt->ceil.rate, b1));
 		cbuffer = tc_calc_xmitsize(hopt->ceil.rate, hopt->cbuffer);
+		linklayer = (hopt->rate.linklayer & TC_LINKLAYER_MASK);
+		if (linklayer > TC_LINKLAYER_ETHERNET || show_details)
+			fprintf(f, "linklayer %s ", sprint_linklayer(linklayer, b4));
 		if (show_details) {
 			fprintf(f, "burst %s/%u mpu %s overhead %s ",
 				sprint_size(buffer, b1),
diff --git a/tc/q_tbf.c b/tc/q_tbf.c
index 72cfff6..34784a4 100644
--- a/tc/q_tbf.c
+++ b/tc/q_tbf.c
@@ -239,10 +239,12 @@
 {
 	struct rtattr *tb[TCA_TBF_PTAB+1];
 	struct tc_tbf_qopt *qopt;
+	unsigned int linklayer;
 	double buffer, mtu;
 	double latency;
 	SPRINT_BUF(b1);
 	SPRINT_BUF(b2);
+	SPRINT_BUF(b3);
 
 	if (opt == NULL)
 		return 0;
@@ -294,6 +296,9 @@
 	if (qopt->rate.overhead) {
 		fprintf(f, "overhead %d", qopt->rate.overhead);
 	}
+	linklayer = (qopt->rate.linklayer & TC_LINKLAYER_MASK);
+	if (linklayer > TC_LINKLAYER_ETHERNET || show_details)
+		fprintf(f, "linklayer %s ", sprint_linklayer(linklayer, b3));
 
 	return 0;
 }
diff --git a/tc/tc_core.c b/tc/tc_core.c
index 85b072e..a524337 100644
--- a/tc/tc_core.c
+++ b/tc/tc_core.c
@@ -102,6 +102,21 @@
 	}
 }
 
+/* Notice, the rate table calculated here, have gotten replaced in the
+ * kernel and is no-longer used for lookups.
+ *
+ * This happened in kernel release v3.8 caused by kernel
+ *  - commit 56b765b79 ("htb: improved accuracy at high rates").
+ * This change unfortunately caused breakage of tc overhead and
+ * linklayer parameters.
+ *
+ * Kernel overhead handling got fixed in kernel v3.10 by
+ * - commit 01cb71d2d47 (net_sched: restore "overhead xxx" handling)
+ *
+ * Kernel linklayer handling got fixed in kernel v3.11 by
+ * - commit 8a8e3d84b17 (net_sched: restore "linklayer atm" handling)
+ */
+
 /*
    rtab[pkt_len>>cell_log] = pkt_xmit_time
  */
@@ -131,6 +146,7 @@
 
 	r->cell_align=-1; // Due to the sz calc
 	r->cell_log=cell_log;
+	r->linklayer = (linklayer & TC_LINKLAYER_MASK);
 	return cell_log;
 }
 
diff --git a/tc/tc_qdisc.c b/tc/tc_qdisc.c
index f3bf5b5..3002a56 100644
--- a/tc/tc_qdisc.c
+++ b/tc/tc_qdisc.c
@@ -137,15 +137,15 @@
 	if (est.ewma_log)
 		addattr_l(&req.n, sizeof(req), TCA_RATE, &est, sizeof(est));
 
-	if (q) {
-		if (!q->parse_qopt) {
-			fprintf(stderr, "qdisc '%s' does not support option parsing\n", k);
-			return -1;
-		}
-		if (q->parse_qopt(q, argc, argv, &req.n))
-			return 1;
-	} else {
-		if (argc) {
+	if (argc) {
+		if (q) {
+			if (!q->parse_qopt) {
+				fprintf(stderr, "qdisc '%s' does not support option parsing\n", k);
+				return -1;
+			}
+			if (q->parse_qopt(q, argc, argv, &req.n))
+				return 1;
+		} else {
 			if (matches(*argv, "help") == 0)
 				usage();