Merge branch 'master' into net-next
diff --git a/bridge/br_common.h b/bridge/br_common.h
index 169a162..41eb0dc 100644
--- a/bridge/br_common.h
+++ b/bridge/br_common.h
@@ -1,3 +1,6 @@
+#define MDB_RTA(r) \
+ ((struct rtattr *)(((char *)(r)) + RTA_ALIGN(sizeof(struct br_mdb_entry))))
+
extern int print_linkinfo(const struct sockaddr_nl *who,
struct nlmsghdr *n,
void *arg);
diff --git a/bridge/mdb.c b/bridge/mdb.c
index 24c4903..600596c 100644
--- a/bridge/mdb.c
+++ b/bridge/mdb.c
@@ -49,7 +49,7 @@
}
static void print_mdb_entry(FILE *f, int ifindex, struct br_mdb_entry *e,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, struct rtattr **tb)
{
SPRINT_BUF(abuf);
const void *src;
@@ -60,26 +60,36 @@
(const void *)&e->addr.u.ip6;
if (n->nlmsg_type == RTM_DELMDB)
fprintf(f, "Deleted ");
- fprintf(f, "dev %s port %s grp %s %s", ll_index_to_name(ifindex),
+ fprintf(f, "dev %s port %s grp %s %s %s", ll_index_to_name(ifindex),
ll_index_to_name(e->ifindex),
inet_ntop(af, src, abuf, sizeof(abuf)),
- (e->state & MDB_PERMANENT) ? "permanent" : "temp");
+ (e->state & MDB_PERMANENT) ? "permanent" : "temp",
+ (e->flags & MDB_FLAGS_OFFLOAD) ? "offload" : "");
if (e->vid)
fprintf(f, " vid %hu", e->vid);
+ if (show_stats && tb && tb[MDBA_MDB_EATTR_TIMER]) {
+ struct timeval tv;
+
+ __jiffies_to_tv(&tv, rta_getattr_u32(tb[MDBA_MDB_EATTR_TIMER]));
+ fprintf(f, "%4i.%.2i", (int)tv.tv_sec, (int)tv.tv_usec/10000);
+ }
fprintf(f, "\n");
}
static void br_print_mdb_entry(FILE *f, int ifindex, struct rtattr *attr,
struct nlmsghdr *n)
{
+ struct rtattr *etb[MDBA_MDB_EATTR_MAX + 1];
+ struct br_mdb_entry *e;
struct rtattr *i;
int rem;
- struct br_mdb_entry *e;
rem = RTA_PAYLOAD(attr);
for (i = RTA_DATA(attr); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
e = RTA_DATA(i);
- print_mdb_entry(f, ifindex, e, n);
+ parse_rtattr(etb, MDBA_MDB_EATTR_MAX, MDB_RTA(RTA_DATA(i)),
+ RTA_PAYLOAD(i) - RTA_ALIGN(sizeof(*e)));
+ print_mdb_entry(f, ifindex, e, n, etb);
}
}
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index f970f9d..ffaba7c 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -81,6 +81,9 @@
BPF_MAP_TYPE_ARRAY,
BPF_MAP_TYPE_PROG_ARRAY,
BPF_MAP_TYPE_PERF_EVENT_ARRAY,
+ BPF_MAP_TYPE_PERCPU_HASH,
+ BPF_MAP_TYPE_PERCPU_ARRAY,
+ BPF_MAP_TYPE_STACK_TRACE,
};
enum bpf_prog_type {
@@ -270,6 +273,31 @@
*/
BPF_FUNC_perf_event_output,
BPF_FUNC_skb_load_bytes,
+
+ /**
+ * bpf_get_stackid(ctx, map, flags) - walk user or kernel stack and return id
+ * @ctx: struct pt_regs*
+ * @map: pointer to stack_trace map
+ * @flags: bits 0-7 - numer of stack frames to skip
+ * bit 8 - collect user stack instead of kernel
+ * bit 9 - compare stacks by hash only
+ * bit 10 - if two different stacks hash into the same stackid
+ * discard old
+ * other bits - reserved
+ * Return: >= 0 stackid on success or negative error
+ */
+ BPF_FUNC_get_stackid,
+
+ /**
+ * bpf_csum_diff(from, from_size, to, to_size, seed) - calculate csum diff
+ * @from: raw from buffer
+ * @from_size: length of from buffer
+ * @to: raw to buffer
+ * @to_size: length of to buffer
+ * @seed: optional seed
+ * Return: csum result
+ */
+ BPF_FUNC_csum_diff,
__BPF_FUNC_MAX_ID,
};
@@ -285,6 +313,7 @@
/* BPF_FUNC_l4_csum_replace flags. */
#define BPF_F_PSEUDO_HDR (1ULL << 4)
+#define BPF_F_MARK_MANGLED_0 (1ULL << 5)
/* BPF_FUNC_clone_redirect and BPF_FUNC_redirect flags. */
#define BPF_F_INGRESS (1ULL << 0)
@@ -292,6 +321,12 @@
/* BPF_FUNC_skb_set_tunnel_key and BPF_FUNC_skb_get_tunnel_key flags. */
#define BPF_F_TUNINFO_IPV6 (1ULL << 0)
+/* BPF_FUNC_get_stackid flags. */
+#define BPF_F_SKIP_FIELD_MASK 0xffULL
+#define BPF_F_USER_STACK (1ULL << 8)
+#define BPF_F_FAST_STACK_CMP (1ULL << 9)
+#define BPF_F_REUSE_STACKID (1ULL << 10)
+
/* user accessible mirror of in-kernel sk_buff.
* new fields can only be added to the end of this structure
*/
diff --git a/include/linux/genetlink.h b/include/linux/genetlink.h
index 8a1d500..e792092 100644
--- a/include/linux/genetlink.h
+++ b/include/linux/genetlink.h
@@ -21,6 +21,7 @@
#define GENL_CMD_CAP_DO 0x02
#define GENL_CMD_CAP_DUMP 0x04
#define GENL_CMD_CAP_HASPOL 0x08
+#define GENL_UNS_ADMIN_PERM 0x10
/*
* List of reserved static generic netlink identifiers:
diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
index ee197a3..8de96b7 100644
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -137,11 +137,17 @@
/* Bridge multicast database attributes
* [MDBA_MDB] = {
* [MDBA_MDB_ENTRY] = {
- * [MDBA_MDB_ENTRY_INFO]
+ * [MDBA_MDB_ENTRY_INFO] {
+ * struct br_mdb_entry
+ * [MDBA_MDB_EATTR attributes]
+ * }
* }
* }
* [MDBA_ROUTER] = {
- * [MDBA_ROUTER_PORT]
+ * [MDBA_ROUTER_PORT] = {
+ * u32 ifindex
+ * [MDBA_ROUTER_PATTR attributes]
+ * }
* }
*/
enum {
@@ -166,6 +172,22 @@
};
#define MDBA_MDB_ENTRY_MAX (__MDBA_MDB_ENTRY_MAX - 1)
+/* per mdb entry additional attributes */
+enum {
+ MDBA_MDB_EATTR_UNSPEC,
+ MDBA_MDB_EATTR_TIMER,
+ __MDBA_MDB_EATTR_MAX
+};
+#define MDBA_MDB_EATTR_MAX (__MDBA_MDB_EATTR_MAX - 1)
+
+/* multicast router types */
+enum {
+ MDB_RTR_TYPE_DISABLED,
+ MDB_RTR_TYPE_TEMP_QUERY,
+ MDB_RTR_TYPE_PERM,
+ MDB_RTR_TYPE_TEMP
+};
+
enum {
MDBA_ROUTER_UNSPEC,
MDBA_ROUTER_PORT,
@@ -173,6 +195,15 @@
};
#define MDBA_ROUTER_MAX (__MDBA_ROUTER_MAX - 1)
+/* router port attributes */
+enum {
+ MDBA_ROUTER_PATTR_UNSPEC,
+ MDBA_ROUTER_PATTR_TIMER,
+ MDBA_ROUTER_PATTR_TYPE,
+ __MDBA_ROUTER_PATTR_MAX
+};
+#define MDBA_ROUTER_PATTR_MAX (__MDBA_ROUTER_PATTR_MAX - 1)
+
struct br_port_msg {
__u8 family;
__u32 ifindex;
@@ -183,6 +214,8 @@
#define MDB_TEMPORARY 0
#define MDB_PERMANENT 1
__u8 state;
+#define MDB_FLAGS_OFFLOAD (1 << 0)
+ __u8 flags;
__u16 vid;
struct {
union {
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index d91f2c9..0331c72 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -35,6 +35,8 @@
/* for cslip etc */
__u32 rx_compressed;
__u32 tx_compressed;
+
+ __u32 rx_nohandler; /* dropped, no handler found */
};
/* The main device statistics structure */
@@ -68,6 +70,8 @@
/* for cslip etc */
__u64 rx_compressed;
__u64 tx_compressed;
+
+ __u64 rx_nohandler; /* dropped, no handler found */
};
/* The struct should be in sync with struct ifmap */
@@ -399,6 +403,14 @@
#define IFLA_VRF_MAX (__IFLA_VRF_MAX - 1)
+enum {
+ IFLA_VRF_PORT_UNSPEC,
+ IFLA_VRF_PORT_TABLE,
+ __IFLA_VRF_PORT_MAX
+};
+
+#define IFLA_VRF_PORT_MAX (__IFLA_VRF_PORT_MAX - 1)
+
/* IPVLAN section */
enum {
IFLA_IPVLAN_UNSPEC,
diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h
index a323146..a1b89a1 100644
--- a/include/linux/pkt_cls.h
+++ b/include/linux/pkt_cls.h
@@ -118,6 +118,7 @@
TCA_U32_INDEV,
TCA_U32_PCNT,
TCA_U32_MARK,
+ TCA_U32_FLAGS,
__TCA_U32_MAX
};
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 1e9b4a6..55d6567 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -196,6 +196,9 @@
__u64 tcpi_bytes_received; /* RFC4898 tcpEStatsAppHCThruOctetsReceived */
__u32 tcpi_segs_out; /* RFC4898 tcpEStatsPerfSegsOut */
__u32 tcpi_segs_in; /* RFC4898 tcpEStatsPerfSegsIn */
+
+ __u32 tcpi_notsent_bytes;
+ __u32 tcpi_min_rtt;
};
/* for TCP_MD5SIG socket option */
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 9d254d2..c4a8fc3 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -481,7 +481,8 @@
/* RX error stats */
if (show_stats > 1) {
fprintf(fp, "%s", _SL_);
- fprintf(fp, " RX errors: length crc frame fifo missed%s", _SL_);
+ fprintf(fp, " RX errors: length crc frame fifo missed%s%s",
+ s->rx_nohandler ? " nohandler" : "", _SL_);
fprintf(fp, " ");
print_num(fp, 8, s->rx_length_errors);
@@ -489,6 +490,9 @@
print_num(fp, 7, s->rx_frame_errors);
print_num(fp, 7, s->rx_fifo_errors);
print_num(fp, 7, s->rx_missed_errors);
+ if (s->rx_nohandler)
+ print_num(fp, 7, s->rx_nohandler);
+
}
fprintf(fp, "%s", _SL_);
@@ -496,7 +500,6 @@
fprintf(fp, " TX: bytes packets errors dropped carrier collsns %s%s",
s->tx_compressed ? "compressed" : "", _SL_);
-
fprintf(fp, " ");
print_num(fp, 10, s->tx_bytes);
print_num(fp, 8, s->tx_packets);
@@ -546,13 +549,16 @@
/* RX error stats */
if (show_stats > 1) {
fprintf(fp, "%s", _SL_);
- fprintf(fp, " RX errors: length crc frame fifo missed%s", _SL_);
+ fprintf(fp, " RX errors: length crc frame fifo missed%s%s",
+ s->rx_nohandler ? " nohandler" : "", _SL_);
fprintf(fp, " ");
print_num(fp, 8, s->rx_length_errors);
print_num(fp, 7, s->rx_crc_errors);
print_num(fp, 7, s->rx_frame_errors);
print_num(fp, 7, s->rx_fifo_errors);
print_num(fp, 7, s->rx_missed_errors);
+ if (s->rx_nohandler)
+ print_num(fp, 7, s->rx_nohandler);
}
fprintf(fp, "%s", _SL_);
@@ -590,12 +596,23 @@
static void __print_link_stats(FILE *fp, struct rtattr **tb)
{
- if (tb[IFLA_STATS64])
- print_link_stats64(fp, RTA_DATA(tb[IFLA_STATS64]),
- tb[IFLA_CARRIER_CHANGES]);
- else if (tb[IFLA_STATS])
- print_link_stats32(fp, RTA_DATA(tb[IFLA_STATS]),
- tb[IFLA_CARRIER_CHANGES]);
+ const struct rtattr *carrier_changes = tb[IFLA_CARRIER_CHANGES];
+
+ if (tb[IFLA_STATS64]) {
+ struct rtnl_link_stats64 stats = { 0 };
+
+ memcpy(&stats, RTA_DATA(tb[IFLA_STATS64]),
+ MIN(RTA_PAYLOAD(tb[IFLA_STATS64]), sizeof(stats)));
+
+ print_link_stats64(fp, &stats, carrier_changes);
+ } else if (tb[IFLA_STATS]) {
+ struct rtnl_link_stats stats = { 0 };
+
+ memcpy(&stats, RTA_DATA(tb[IFLA_STATS]),
+ MIN(RTA_PAYLOAD(tb[IFLA_STATS]), sizeof(stats)));
+
+ print_link_stats32(fp, &stats, carrier_changes);
+ }
}
static void print_link_stats(FILE *fp, struct nlmsghdr *n)
diff --git a/ip/iplink_vrf.c b/ip/iplink_vrf.c
index 9b4b772..abc7968 100644
--- a/ip/iplink_vrf.c
+++ b/ip/iplink_vrf.c
@@ -64,6 +64,18 @@
fprintf(f, "table %u ", rta_getattr_u32(tb[IFLA_VRF_TABLE]));
}
+static void vrf_slave_print_opt(struct link_util *lu, FILE *f,
+ struct rtattr *tb[])
+{
+ if (!tb)
+ return;
+
+ if (tb[IFLA_VRF_PORT_TABLE]) {
+ fprintf(f, "table %u ",
+ rta_getattr_u32(tb[IFLA_VRF_PORT_TABLE]));
+ }
+}
+
static void vrf_print_help(struct link_util *lu, int argc, char **argv,
FILE *f)
{
@@ -77,3 +89,10 @@
.print_opt = vrf_print_opt,
.print_help = vrf_print_help,
};
+
+struct link_util vrf_slave_link_util = {
+ .id = "vrf",
+ .maxattr = IFLA_VRF_PORT_MAX,
+ .print_opt = vrf_slave_print_opt,
+ .slave = true,
+};
diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
index efd416e..0e98edf 100644
--- a/man/man8/bridge.8
+++ b/man/man8/bridge.8
@@ -503,6 +503,11 @@
option, the command becomes verbose. It prints out the ports known to have
a connected router.
+.PP
+With the
+.B -statistics
+option, the command displays timer values for mdb entries.
+
.SH bridge vlan - VLAN filter list
.B vlan
diff --git a/misc/ss.c b/misc/ss.c
index 13fcc8f..f0f5902 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -778,7 +778,9 @@
unsigned int sacked;
unsigned int fackets;
unsigned int reordering;
+ unsigned int not_sent;
double rcv_rtt;
+ double min_rtt;
int rcv_space;
bool has_ts_opt;
bool has_sack_opt;
@@ -1737,6 +1739,10 @@
printf(" rcv_rtt:%g", s->rcv_rtt);
if (s->rcv_space)
printf(" rcv_space:%d", s->rcv_space);
+ if (s->not_sent)
+ printf(" notsent:%u", s->not_sent);
+ if (s->min_rtt)
+ printf(" minrtt:%g", s->min_rtt);
}
static void tcp_timer_print(struct tcpstat *s)
@@ -1990,6 +1996,8 @@
s.bytes_received = info->tcpi_bytes_received;
s.segs_out = info->tcpi_segs_out;
s.segs_in = info->tcpi_segs_in;
+ s.not_sent = info->tcpi_notsent_bytes;
+ s.min_rtt = (double) info->tcpi_min_rtt / 1000;
tcp_stats_print(&s);
free(s.dctcp);
}