From fec62c0ec74658e3a02903d36166e051714425f0 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 27 Mar 2018 15:33:13 -0700 Subject: [PATCH 01/19] tc: help and whitespace cleanup Break long lines, and cleanup usage message. Signed-off-by: Stephen Hemminger --- tc/tc.c | 46 +++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/tc/tc.c b/tc/tc.c index 63e64fec..89265562 100644 --- a/tc/tc.c +++ b/tc/tc.c @@ -60,10 +60,13 @@ static int print_noqopt(struct qdisc_util *qu, FILE *f, return 0; } -static int parse_noqopt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n, const char *dev) +static int parse_noqopt(struct qdisc_util *qu, int argc, char **argv, + struct nlmsghdr *n, const char *dev) { if (argc) { - fprintf(stderr, "Unknown qdisc \"%s\", hence option \"%s\" is unparsable\n", qu->id, *argv); + fprintf(stderr, + "Unknown qdisc \"%s\", hence option \"%s\" is unparsable\n", + qu->id, *argv); return -1; } return 0; @@ -79,12 +82,15 @@ static int print_nofopt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u return 0; } -static int parse_nofopt(struct filter_util *qu, char *fhandle, int argc, char **argv, struct nlmsghdr *n) +static int parse_nofopt(struct filter_util *qu, char *fhandle, + int argc, char **argv, struct nlmsghdr *n) { __u32 handle; if (argc) { - fprintf(stderr, "Unknown filter \"%s\", hence option \"%s\" is unparsable\n", qu->id, *argv); + fprintf(stderr, + "Unknown filter \"%s\", hence option \"%s\" is unparsable\n", + qu->id, *argv); return -1; } if (fhandle) { @@ -186,11 +192,14 @@ noexist: static void usage(void) { - fprintf(stderr, "Usage: tc [ OPTIONS ] OBJECT { COMMAND | help }\n" - " tc [-force] -batch filename\n" - "where OBJECT := { qdisc | class | filter | action | monitor | exec }\n" - " OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] | -p[retty] | -b[atch] [filename] | -n[etns] name |\n" - " -nm | -nam[es] | { -cf | -conf } path } | -j[son]\n"); + fprintf(stderr, + "Usage: tc [ OPTIONS ] OBJECT { COMMAND | help }\n" + " tc [-force] -batch filename\n" + "where OBJECT := { qdisc | class | filter | action | monitor | exec }\n" + " OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[aw] |\n" + " -j[son] | -p[retty] |\n" + " -b[atch] [filename] | -n[etns] name |\n" + " -nm | -nam[es] | { -cf | -conf } path }\n"); } static int do_cmd(int argc, char **argv, void *buf, size_t buflen) @@ -224,8 +233,8 @@ static bool batchsize_enabled(int argc, char *argv[]) char *c; char *subc[TC_MAX_SUBC]; } table[] = { - {"filter", {"add", "delete", "change", "replace", NULL}}, - {"actions", {"add", "change", "replace", NULL}}, + { "filter", { "add", "delete", "change", "replace", NULL} }, + { "actions", { "add", "change", "replace", NULL} }, { NULL }, }, *iter; char *s; @@ -262,11 +271,11 @@ static struct batch_buf *get_batch_buf(struct batch_buf **pool, struct batch_buf *buf; if (*pool == NULL) - buf = calloc(1, sizeof (struct batch_buf)); + buf = calloc(1, sizeof(struct batch_buf)); else { buf = *pool; *pool = (*pool)->next; - memset(buf, 0, sizeof (struct batch_buf)); + memset(buf, 0, sizeof(struct batch_buf)); } if (*head == NULL) @@ -325,7 +334,8 @@ static int batch(const char *name) batch_mode = 1; if (name && strcmp(name, "-") != 0) { if (freopen(name, "r", stdin) == NULL) { - fprintf(stderr, "Cannot open file \"%s\" for reading: %s\n", + fprintf(stderr, + "Cannot open file \"%s\" for reading: %s\n", name, strerror(errno)); return -1; } @@ -388,7 +398,7 @@ static int batch(const char *name) } ret = do_cmd(largc, largv, tail == NULL ? NULL : tail->buf, - tail == NULL ? 0 : sizeof (tail->buf)); + tail == NULL ? 0 : sizeof(tail->buf)); if (ret != 0) { fprintf(stderr, "Command failed %s:%d\n", name, cmdlineno - 1); @@ -404,7 +414,7 @@ static int batch(const char *name) struct batch_buf *buf; struct nlmsghdr *n; - iov = iovs = malloc(batchsize * sizeof (struct iovec)); + iov = iovs = malloc(batchsize * sizeof(struct iovec)); for (buf = head; buf != NULL; buf = buf->next, ++iov) { n = (struct nlmsghdr *)&buf->buf; iov->iov_base = n; @@ -485,7 +495,9 @@ int main(int argc, char **argv) } else if (matches(argv[1], "-json") == 0) { ++json; } else { - fprintf(stderr, "Option \"%s\" is unknown, try \"tc -help\".\n", argv[1]); + fprintf(stderr, + "Option \"%s\" is unknown, try \"tc -help\".\n", + argv[1]); return -1; } argc--; argv++; From d64a22f393bb4cdaa8e100f5432b3782257f81b6 Mon Sep 17 00:00:00 2001 From: Roman Mashak Date: Tue, 20 Mar 2018 14:21:47 -0400 Subject: [PATCH 02/19] tc: print index, refcnt & bindcnt for nat action Signed-off-by: Roman Mashak --- tc/m_nat.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tc/m_nat.c b/tc/m_nat.c index 1e4ff51f..f6e37395 100644 --- a/tc/m_nat.c +++ b/tc/m_nat.c @@ -169,6 +169,9 @@ print_nat(struct action_util *au, FILE * f, struct rtattr *arg) format_host_r(AF_INET, 4, &sel->new_addr, buf2, sizeof(buf2))); print_action_control(f, " ", sel->action, ""); + fprintf(f, "\n\t index %u ref %d bind %d", + sel->index, sel->refcnt, sel->bindcnt); + if (show_stats) { if (tb[TCA_NAT_TM]) { struct tcf_t *tm = RTA_DATA(tb[TCA_NAT_TM]); @@ -177,6 +180,8 @@ print_nat(struct action_util *au, FILE * f, struct rtattr *arg) } } + fprintf(f, "\n"); + return 0; } From c121111ecbe32d795f99c99b17ce1553f5d63305 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 28 Mar 2018 01:51:54 +0200 Subject: [PATCH 03/19] ss: Allow excluding a socket table from being queried The original problem was that a simple call to 'ss' leads to loading of sctp_diag kernel module which might not be desired. While searching for a workaround, it became clear how inconvenient it is to exclude a single socket table from being queried. This patch allows to prefix an item passed to '-A' parameter with an exclamation mark to inverse its meaning. Signed-off-by: Phil Sutter --- man/man8/ss.8 | 8 +++- misc/ss.c | 108 +++++++++++++++++++++++++++----------------------- 2 files changed, 66 insertions(+), 50 deletions(-) diff --git a/man/man8/ss.8 b/man/man8/ss.8 index 973afbe0..28033d8f 100644 --- a/man/man8/ss.8 +++ b/man/man8/ss.8 @@ -317,7 +317,10 @@ Currently the following families are supported: unix, inet, inet6, link, netlink List of socket tables to dump, separated by commas. The following identifiers are understood: all, inet, tcp, udp, raw, unix, packet, netlink, unix_dgram, unix_stream, unix_seqpacket, packet_raw, packet_dgram, dccp, sctp, -vsock_stream, vsock_dgram. +vsock_stream, vsock_dgram. Any item in the list may optionally be prefixed by +an exclamation mark +.RB ( ! ) +to exclude that socket table from being dumped. .TP .B \-D FILE, \-\-diag=FILE Do not display anything, just dump raw information about TCP sockets to FILE after applying filters. If FILE is - stdout is used. @@ -380,6 +383,9 @@ Find all local processes connected to X server. .TP .B ss -o state fin-wait-1 '( sport = :http or sport = :https )' dst 193.233.7/24 List all the tcp sockets in state FIN-WAIT-1 for our apache to network 193.233.7/24 and look at their timers. +.TP +.B ss -a -A 'all,!tcp' +List sockets in all states from all socket tables but TCP. .SH SEE ALSO .BR ip (8), .br diff --git a/misc/ss.c b/misc/ss.c index 6338820b..05522176 100644 --- a/misc/ss.c +++ b/misc/ss.c @@ -329,10 +329,14 @@ static const struct filter default_afs[AF_MAX] = { static int do_default = 1; static struct filter current_filter; -static void filter_db_set(struct filter *f, int db) +static void filter_db_set(struct filter *f, int db, bool enable) { - f->states |= default_dbs[db].states; - f->dbs |= 1 << db; + if (enable) { + f->states |= default_dbs[db].states; + f->dbs |= 1 << db; + } else { + f->dbs &= ~(1 << db); + } do_default = 0; } @@ -349,21 +353,21 @@ static int filter_af_get(struct filter *f, int af) return !!(f->families & FAMILY_MASK(af)); } -static void filter_default_dbs(struct filter *f) +static void filter_default_dbs(struct filter *f, bool enable) { - filter_db_set(f, UDP_DB); - filter_db_set(f, DCCP_DB); - filter_db_set(f, TCP_DB); - filter_db_set(f, RAW_DB); - filter_db_set(f, UNIX_ST_DB); - filter_db_set(f, UNIX_DG_DB); - filter_db_set(f, UNIX_SQ_DB); - filter_db_set(f, PACKET_R_DB); - filter_db_set(f, PACKET_DG_DB); - filter_db_set(f, NETLINK_DB); - filter_db_set(f, SCTP_DB); - filter_db_set(f, VSOCK_ST_DB); - filter_db_set(f, VSOCK_DG_DB); + filter_db_set(f, UDP_DB, enable); + filter_db_set(f, DCCP_DB, enable); + filter_db_set(f, TCP_DB, enable); + filter_db_set(f, RAW_DB, enable); + filter_db_set(f, UNIX_ST_DB, enable); + filter_db_set(f, UNIX_DG_DB, enable); + filter_db_set(f, UNIX_SQ_DB, enable); + filter_db_set(f, PACKET_R_DB, enable); + filter_db_set(f, PACKET_DG_DB, enable); + filter_db_set(f, NETLINK_DB, enable); + filter_db_set(f, SCTP_DB, enable); + filter_db_set(f, VSOCK_ST_DB, enable); + filter_db_set(f, VSOCK_DG_DB, enable); } static void filter_states_set(struct filter *f, int states) @@ -4712,19 +4716,19 @@ int main(int argc, char *argv[]) follow_events = 1; break; case 'd': - filter_db_set(¤t_filter, DCCP_DB); + filter_db_set(¤t_filter, DCCP_DB, true); break; case 't': - filter_db_set(¤t_filter, TCP_DB); + filter_db_set(¤t_filter, TCP_DB, true); break; case 'S': - filter_db_set(¤t_filter, SCTP_DB); + filter_db_set(¤t_filter, SCTP_DB, true); break; case 'u': - filter_db_set(¤t_filter, UDP_DB); + filter_db_set(¤t_filter, UDP_DB, true); break; case 'w': - filter_db_set(¤t_filter, RAW_DB); + filter_db_set(¤t_filter, RAW_DB, true); break; case 'x': filter_af_set(¤t_filter, AF_UNIX); @@ -4781,59 +4785,65 @@ int main(int argc, char *argv[]) } p = p1 = optarg; do { + bool enable = true; + if ((p1 = strchr(p, ',')) != NULL) *p1 = 0; + if (p[0] == '!') { + enable = false; + p++; + } if (strcmp(p, "all") == 0) { - filter_default_dbs(¤t_filter); + filter_default_dbs(¤t_filter, enable); } else if (strcmp(p, "inet") == 0) { - filter_db_set(¤t_filter, UDP_DB); - filter_db_set(¤t_filter, DCCP_DB); - filter_db_set(¤t_filter, TCP_DB); - filter_db_set(¤t_filter, SCTP_DB); - filter_db_set(¤t_filter, RAW_DB); + filter_db_set(¤t_filter, UDP_DB, enable); + filter_db_set(¤t_filter, DCCP_DB, enable); + filter_db_set(¤t_filter, TCP_DB, enable); + filter_db_set(¤t_filter, SCTP_DB, enable); + filter_db_set(¤t_filter, RAW_DB, enable); } else if (strcmp(p, "udp") == 0) { - filter_db_set(¤t_filter, UDP_DB); + filter_db_set(¤t_filter, UDP_DB, enable); } else if (strcmp(p, "dccp") == 0) { - filter_db_set(¤t_filter, DCCP_DB); + filter_db_set(¤t_filter, DCCP_DB, enable); } else if (strcmp(p, "tcp") == 0) { - filter_db_set(¤t_filter, TCP_DB); + filter_db_set(¤t_filter, TCP_DB, enable); } else if (strcmp(p, "sctp") == 0) { - filter_db_set(¤t_filter, SCTP_DB); + filter_db_set(¤t_filter, SCTP_DB, enable); } else if (strcmp(p, "raw") == 0) { - filter_db_set(¤t_filter, RAW_DB); + filter_db_set(¤t_filter, RAW_DB, enable); } else if (strcmp(p, "unix") == 0) { - filter_db_set(¤t_filter, UNIX_ST_DB); - filter_db_set(¤t_filter, UNIX_DG_DB); - filter_db_set(¤t_filter, UNIX_SQ_DB); + filter_db_set(¤t_filter, UNIX_ST_DB, enable); + filter_db_set(¤t_filter, UNIX_DG_DB, enable); + filter_db_set(¤t_filter, UNIX_SQ_DB, enable); } else if (strcasecmp(p, "unix_stream") == 0 || strcmp(p, "u_str") == 0) { - filter_db_set(¤t_filter, UNIX_ST_DB); + filter_db_set(¤t_filter, UNIX_ST_DB, enable); } else if (strcasecmp(p, "unix_dgram") == 0 || strcmp(p, "u_dgr") == 0) { - filter_db_set(¤t_filter, UNIX_DG_DB); + filter_db_set(¤t_filter, UNIX_DG_DB, enable); } else if (strcasecmp(p, "unix_seqpacket") == 0 || strcmp(p, "u_seq") == 0) { - filter_db_set(¤t_filter, UNIX_SQ_DB); + filter_db_set(¤t_filter, UNIX_SQ_DB, enable); } else if (strcmp(p, "packet") == 0) { - filter_db_set(¤t_filter, PACKET_R_DB); - filter_db_set(¤t_filter, PACKET_DG_DB); + filter_db_set(¤t_filter, PACKET_R_DB, enable); + filter_db_set(¤t_filter, PACKET_DG_DB, enable); } else if (strcmp(p, "packet_raw") == 0 || strcmp(p, "p_raw") == 0) { - filter_db_set(¤t_filter, PACKET_R_DB); + filter_db_set(¤t_filter, PACKET_R_DB, enable); } else if (strcmp(p, "packet_dgram") == 0 || strcmp(p, "p_dgr") == 0) { - filter_db_set(¤t_filter, PACKET_DG_DB); + filter_db_set(¤t_filter, PACKET_DG_DB, enable); } else if (strcmp(p, "netlink") == 0) { - filter_db_set(¤t_filter, NETLINK_DB); + filter_db_set(¤t_filter, NETLINK_DB, enable); } else if (strcmp(p, "vsock") == 0) { - filter_db_set(¤t_filter, VSOCK_ST_DB); - filter_db_set(¤t_filter, VSOCK_DG_DB); + filter_db_set(¤t_filter, VSOCK_ST_DB, enable); + filter_db_set(¤t_filter, VSOCK_DG_DB, enable); } else if (strcmp(p, "vsock_stream") == 0 || strcmp(p, "v_str") == 0) { - filter_db_set(¤t_filter, VSOCK_ST_DB); + filter_db_set(¤t_filter, VSOCK_ST_DB, enable); } else if (strcmp(p, "vsock_dgram") == 0 || strcmp(p, "v_dgr") == 0) { - filter_db_set(¤t_filter, VSOCK_DG_DB); + filter_db_set(¤t_filter, VSOCK_DG_DB, enable); } else { fprintf(stderr, "ss: \"%s\" is illegal socket table id\n", p); usage(); @@ -4926,7 +4936,7 @@ int main(int argc, char *argv[]) if (do_default) { state_filter = state_filter ? state_filter : SS_CONN; - filter_default_dbs(¤t_filter); + filter_default_dbs(¤t_filter, true); } filter_states_set(¤t_filter, state_filter); From 67d5fd558730ddbf271e44ad087137a7afde9247 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 28 Mar 2018 01:51:55 +0200 Subject: [PATCH 04/19] ss: Put filter DB parsing into a separate function Use a table for database name parsing. The tricky bit is to allow for association of a (nearly) arbitrary number of DBs with each name. Luckily the number is not fully arbitrary as there is an upper bound of MAX_DB items. Since it is not possible to have a variable length array inside a variable length array, use this knowledge to make the inner array of fixed length. But since DB values start from zero, an explicit end entry needs to be present as well, so the inner array has to be MAX_DB + 1 in size. Signed-off-by: Phil Sutter --- misc/ss.c | 114 +++++++++++++++++++++++++++--------------------------- 1 file changed, 56 insertions(+), 58 deletions(-) diff --git a/misc/ss.c b/misc/ss.c index 05522176..83e476a0 100644 --- a/misc/ss.c +++ b/misc/ss.c @@ -340,6 +340,61 @@ static void filter_db_set(struct filter *f, int db, bool enable) do_default = 0; } +static int filter_db_parse(struct filter *f, const char *s) +{ + const struct { + const char *name; + int dbs[MAX_DB + 1]; + } db_name_tbl[] = { +#define ENTRY(name, ...) { #name, { __VA_ARGS__, MAX_DB } } + ENTRY(all, UDP_DB, DCCP_DB, TCP_DB, RAW_DB, + UNIX_ST_DB, UNIX_DG_DB, UNIX_SQ_DB, + PACKET_R_DB, PACKET_DG_DB, NETLINK_DB, + SCTP_DB, VSOCK_ST_DB, VSOCK_DG_DB), + ENTRY(inet, UDP_DB, DCCP_DB, TCP_DB, SCTP_DB, RAW_DB), + ENTRY(udp, UDP_DB), + ENTRY(dccp, DCCP_DB), + ENTRY(tcp, TCP_DB), + ENTRY(sctp, SCTP_DB), + ENTRY(raw, RAW_DB), + ENTRY(unix, UNIX_ST_DB, UNIX_DG_DB, UNIX_SQ_DB), + ENTRY(unix_stream, UNIX_ST_DB), + ENTRY(u_str, UNIX_ST_DB), /* alias for unix_stream */ + ENTRY(unix_dgram, UNIX_DG_DB), + ENTRY(u_dgr, UNIX_DG_DB), /* alias for unix_dgram */ + ENTRY(unix_seqpacket, UNIX_SQ_DB), + ENTRY(u_seq, UNIX_SQ_DB), /* alias for unix_seqpacket */ + ENTRY(packet, PACKET_R_DB, PACKET_DG_DB), + ENTRY(packet_raw, PACKET_R_DB), + ENTRY(p_raw, PACKET_R_DB), /* alias for packet_raw */ + ENTRY(packet_dgram, PACKET_DG_DB), + ENTRY(p_dgr, PACKET_DG_DB), /* alias for packet_dgram */ + ENTRY(netlink, NETLINK_DB), + ENTRY(vsock, VSOCK_ST_DB, VSOCK_DG_DB), + ENTRY(vsock_stream, VSOCK_ST_DB), + ENTRY(v_str, VSOCK_ST_DB), /* alias for vsock_stream */ + ENTRY(vsock_dgram, VSOCK_DG_DB), + ENTRY(v_dgr, VSOCK_DG_DB), /* alias for vsock_dgram */ +#undef ENTRY + }; + bool enable = true; + unsigned int i; + const int *dbp; + + if (s[0] == '!') { + enable = false; + s++; + } + for (i = 0; i < ARRAY_SIZE(db_name_tbl); i++) { + if (strcmp(s, db_name_tbl[i].name)) + continue; + for (dbp = db_name_tbl[i].dbs; *dbp != MAX_DB; dbp++) + filter_db_set(f, *dbp, enable); + return 0; + } + return -1; +} + static void filter_af_set(struct filter *f, int af) { f->states |= default_afs[af].states; @@ -4785,66 +4840,9 @@ int main(int argc, char *argv[]) } p = p1 = optarg; do { - bool enable = true; - if ((p1 = strchr(p, ',')) != NULL) *p1 = 0; - if (p[0] == '!') { - enable = false; - p++; - } - if (strcmp(p, "all") == 0) { - filter_default_dbs(¤t_filter, enable); - } else if (strcmp(p, "inet") == 0) { - filter_db_set(¤t_filter, UDP_DB, enable); - filter_db_set(¤t_filter, DCCP_DB, enable); - filter_db_set(¤t_filter, TCP_DB, enable); - filter_db_set(¤t_filter, SCTP_DB, enable); - filter_db_set(¤t_filter, RAW_DB, enable); - } else if (strcmp(p, "udp") == 0) { - filter_db_set(¤t_filter, UDP_DB, enable); - } else if (strcmp(p, "dccp") == 0) { - filter_db_set(¤t_filter, DCCP_DB, enable); - } else if (strcmp(p, "tcp") == 0) { - filter_db_set(¤t_filter, TCP_DB, enable); - } else if (strcmp(p, "sctp") == 0) { - filter_db_set(¤t_filter, SCTP_DB, enable); - } else if (strcmp(p, "raw") == 0) { - filter_db_set(¤t_filter, RAW_DB, enable); - } else if (strcmp(p, "unix") == 0) { - filter_db_set(¤t_filter, UNIX_ST_DB, enable); - filter_db_set(¤t_filter, UNIX_DG_DB, enable); - filter_db_set(¤t_filter, UNIX_SQ_DB, enable); - } else if (strcasecmp(p, "unix_stream") == 0 || - strcmp(p, "u_str") == 0) { - filter_db_set(¤t_filter, UNIX_ST_DB, enable); - } else if (strcasecmp(p, "unix_dgram") == 0 || - strcmp(p, "u_dgr") == 0) { - filter_db_set(¤t_filter, UNIX_DG_DB, enable); - } else if (strcasecmp(p, "unix_seqpacket") == 0 || - strcmp(p, "u_seq") == 0) { - filter_db_set(¤t_filter, UNIX_SQ_DB, enable); - } else if (strcmp(p, "packet") == 0) { - filter_db_set(¤t_filter, PACKET_R_DB, enable); - filter_db_set(¤t_filter, PACKET_DG_DB, enable); - } else if (strcmp(p, "packet_raw") == 0 || - strcmp(p, "p_raw") == 0) { - filter_db_set(¤t_filter, PACKET_R_DB, enable); - } else if (strcmp(p, "packet_dgram") == 0 || - strcmp(p, "p_dgr") == 0) { - filter_db_set(¤t_filter, PACKET_DG_DB, enable); - } else if (strcmp(p, "netlink") == 0) { - filter_db_set(¤t_filter, NETLINK_DB, enable); - } else if (strcmp(p, "vsock") == 0) { - filter_db_set(¤t_filter, VSOCK_ST_DB, enable); - filter_db_set(¤t_filter, VSOCK_DG_DB, enable); - } else if (strcmp(p, "vsock_stream") == 0 || - strcmp(p, "v_str") == 0) { - filter_db_set(¤t_filter, VSOCK_ST_DB, enable); - } else if (strcmp(p, "vsock_dgram") == 0 || - strcmp(p, "v_dgr") == 0) { - filter_db_set(¤t_filter, VSOCK_DG_DB, enable); - } else { + if (filter_db_parse(¤t_filter, p)) { fprintf(stderr, "ss: \"%s\" is illegal socket table id\n", p); usage(); } From 3e1652c94cbfa8e5a54f706daaf073b1a48536b8 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 28 Mar 2018 01:51:56 +0200 Subject: [PATCH 05/19] ss: Drop filter_default_dbs() Instead call filter_db_parse(..., "all"). This eliminates the duplicate default DB definition. Signed-off-by: Phil Sutter --- misc/ss.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/misc/ss.c b/misc/ss.c index 83e476a0..fc8e2a0d 100644 --- a/misc/ss.c +++ b/misc/ss.c @@ -408,23 +408,6 @@ static int filter_af_get(struct filter *f, int af) return !!(f->families & FAMILY_MASK(af)); } -static void filter_default_dbs(struct filter *f, bool enable) -{ - filter_db_set(f, UDP_DB, enable); - filter_db_set(f, DCCP_DB, enable); - filter_db_set(f, TCP_DB, enable); - filter_db_set(f, RAW_DB, enable); - filter_db_set(f, UNIX_ST_DB, enable); - filter_db_set(f, UNIX_DG_DB, enable); - filter_db_set(f, UNIX_SQ_DB, enable); - filter_db_set(f, PACKET_R_DB, enable); - filter_db_set(f, PACKET_DG_DB, enable); - filter_db_set(f, NETLINK_DB, enable); - filter_db_set(f, SCTP_DB, enable); - filter_db_set(f, VSOCK_ST_DB, enable); - filter_db_set(f, VSOCK_DG_DB, enable); -} - static void filter_states_set(struct filter *f, int states) { if (states) @@ -4934,7 +4917,7 @@ int main(int argc, char *argv[]) if (do_default) { state_filter = state_filter ? state_filter : SS_CONN; - filter_default_dbs(¤t_filter, true); + filter_db_parse(¤t_filter, "all"); } filter_states_set(¤t_filter, state_filter); From 83b3c6054407013e8279f1d3413c51bfec95f6b3 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 28 Mar 2018 11:06:55 -0700 Subject: [PATCH 06/19] rdma: fix man page typos Signed-off-by: Stephen Hemminger --- man/man8/rdma-link.8 | 2 +- man/man8/rdma.8 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/man/man8/rdma-link.8 b/man/man8/rdma-link.8 index 8ed049ef..97dd8bb9 100644 --- a/man/man8/rdma-link.8 +++ b/man/man8/rdma-link.8 @@ -30,7 +30,7 @@ rdma-link \- rdma link configuration .PP .I "DEV/PORT_INDEX" -- specifies the RDMa link to show. +- specifies the RDMA link to show. If this argument is omitted all links are listed. .SH "EXAMPLES" diff --git a/man/man8/rdma.8 b/man/man8/rdma.8 index 798b33d3..69134f45 100644 --- a/man/man8/rdma.8 +++ b/man/man8/rdma.8 @@ -33,7 +33,7 @@ tool and exit. .TP .BR "\-d" , " --details" -Otuput detailed information. +Output detailed information. .TP .BR "\-p" , " --pretty" From 6c6c0291d259dd9d41ff3d470a836ff3e74d00ee Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 19 Mar 2018 09:40:47 -0700 Subject: [PATCH 07/19] bridge: avoid snprint truncation on time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes new gcc warning about possible string overflow. mdb.c: In function ‘__print_router_port_stats’: mdb.c:61:11: warning: ‘%.2i’ directive output may be truncated writing between 2 and 7 bytes into a region of size between 0 and 4 [-Wformat-truncation=] "%4i.%.2i", (int)tv.tv_sec, ^~~~ Note: already fixed in iproute2-next. Signed-off-by: Stephen Hemminger --- bridge/mdb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bridge/mdb.c b/bridge/mdb.c index 58c20b82..659cac3f 100644 --- a/bridge/mdb.c +++ b/bridge/mdb.c @@ -55,7 +55,7 @@ static void __print_router_port_stats(FILE *f, struct rtattr *pattr) __jiffies_to_tv(&tv, rta_getattr_u32(tb[MDBA_ROUTER_PATTR_TIMER])); if (jw_global) { - char formatted_time[9]; + char formatted_time[32]; snprintf(formatted_time, sizeof(formatted_time), "%4i.%.2i", (int)tv.tv_sec, @@ -184,7 +184,7 @@ static void print_mdb_entry(FILE *f, int ifindex, struct br_mdb_entry *e, __jiffies_to_tv(&tv, rta_getattr_u32(tb[MDBA_MDB_EATTR_TIMER])); if (jw_global) { - char formatted_time[9]; + char formatted_time[32]; snprintf(formatted_time, sizeof(formatted_time), "%4i.%.2i", (int)tv.tv_sec, From 95744efac4ffdbb9b625aedd41cd6c5636189cfe Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 19 Mar 2018 09:43:33 -0700 Subject: [PATCH 08/19] pedit: fix strncpy warning Newer versions of Gcc warn about string truncation. Fix by using strlcpy. Signed-off-by: Stephen Hemminger --- tc/m_pedit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/m_pedit.c b/tc/m_pedit.c index 26549eee..8577f875 100644 --- a/tc/m_pedit.c +++ b/tc/m_pedit.c @@ -111,7 +111,7 @@ reg: noexist: p = calloc(1, sizeof(*p)); if (p) { - strncpy(p->id, str, sizeof(p->id) - 1); + strlcpy(p->id, str, sizeof(p->id)); p->parse_peopt = pedit_parse_nopopt; goto reg; } From fc9d755a3e7c25868a4cd63da1136d6abcc6474a Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 19 Mar 2018 09:31:09 -0700 Subject: [PATCH 09/19] ip: use strlcpy() to avoid truncation This fixes gcc-8 warnings about strncpy bounds by using strlcpy instead. Signed-off-by: Stephen Hemminger --- ip/iplink.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ip/iplink.c b/ip/iplink.c index d401311b..cca530ee 100644 --- a/ip/iplink.c +++ b/ip/iplink.c @@ -1114,7 +1114,7 @@ static int do_chflags(const char *dev, __u32 flags, __u32 mask) int fd; int err; - strncpy(ifr.ifr_name, dev, IFNAMSIZ); + strlcpy(ifr.ifr_name, dev, IFNAMSIZ); fd = get_ctl_fd(); if (fd < 0) return -1; @@ -1141,8 +1141,8 @@ static int do_changename(const char *dev, const char *newdev) int fd; int err; - strncpy(ifr.ifr_name, dev, IFNAMSIZ); - strncpy(ifr.ifr_newname, newdev, IFNAMSIZ); + strlcpy(ifr.ifr_name, dev, IFNAMSIZ); + strlcpy(ifr.ifr_newname, newdev, IFNAMSIZ); fd = get_ctl_fd(); if (fd < 0) return -1; @@ -1165,7 +1165,7 @@ static int set_qlen(const char *dev, int qlen) if (s < 0) return -1; - strncpy(ifr.ifr_name, dev, IFNAMSIZ); + strlcpy(ifr.ifr_name, dev, IFNAMSIZ); if (ioctl(s, SIOCSIFTXQLEN, &ifr) < 0) { perror("SIOCSIFXQLEN"); close(s); @@ -1185,7 +1185,7 @@ static int set_mtu(const char *dev, int mtu) if (s < 0) return -1; - strncpy(ifr.ifr_name, dev, IFNAMSIZ); + strlcpy(ifr.ifr_name, dev, IFNAMSIZ); if (ioctl(s, SIOCSIFMTU, &ifr) < 0) { perror("SIOCSIFMTU"); close(s); @@ -1212,7 +1212,7 @@ static int get_address(const char *dev, int *htype) return -1; } - strncpy(ifr.ifr_name, dev, IFNAMSIZ); + strlcpy(ifr.ifr_name, dev, IFNAMSIZ); if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) { perror("SIOCGIFINDEX"); close(s); @@ -1243,7 +1243,7 @@ static int parse_address(const char *dev, int hatype, int halen, int alen; memset(ifr, 0, sizeof(*ifr)); - strncpy(ifr->ifr_name, dev, IFNAMSIZ); + strlcpy(ifr->ifr_name, dev, IFNAMSIZ); ifr->ifr_hwaddr.sa_family = hatype; alen = ll_addr_a2n(ifr->ifr_hwaddr.sa_data, 14, lla); if (alen < 0) From fcb18aa3d95392562be0c0a8f64424068ba146c8 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 19 Mar 2018 09:34:01 -0700 Subject: [PATCH 10/19] tunnel: use strlcpy to avoid strncpy warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes warnings about strncpy size by using strlcpy. tunnel.c: In function ‘tnl_gen_ioctl’: tunnel.c:145:2: warning: ‘strncpy’ specified bound 16 equals destination size [-Wstringop-truncation] strncpy(ifr.ifr_name, name, IFNAMSIZ); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Signed-off-by: Stephen Hemminger --- ip/tunnel.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ip/tunnel.c b/ip/tunnel.c index 948d5f7c..abd9fa2f 100644 --- a/ip/tunnel.c +++ b/ip/tunnel.c @@ -64,7 +64,7 @@ int tnl_get_ioctl(const char *basedev, void *p) int fd; int err; - strncpy(ifr.ifr_name, basedev, IFNAMSIZ); + strlcpy(ifr.ifr_name, basedev, IFNAMSIZ); ifr.ifr_ifru.ifru_data = (void *)p; fd = socket(preferred_family, SOCK_DGRAM, 0); @@ -89,9 +89,9 @@ int tnl_add_ioctl(int cmd, const char *basedev, const char *name, void *p) int err; if (cmd == SIOCCHGTUNNEL && name[0]) - strncpy(ifr.ifr_name, name, IFNAMSIZ); + strlcpy(ifr.ifr_name, name, IFNAMSIZ); else - strncpy(ifr.ifr_name, basedev, IFNAMSIZ); + strlcpy(ifr.ifr_name, basedev, IFNAMSIZ); ifr.ifr_ifru.ifru_data = p; fd = socket(preferred_family, SOCK_DGRAM, 0); @@ -115,9 +115,9 @@ int tnl_del_ioctl(const char *basedev, const char *name, void *p) int err; if (name[0]) - strncpy(ifr.ifr_name, name, IFNAMSIZ); + strlcpy(ifr.ifr_name, name, IFNAMSIZ); else - strncpy(ifr.ifr_name, basedev, IFNAMSIZ); + strlcpy(ifr.ifr_name, basedev, IFNAMSIZ); ifr.ifr_ifru.ifru_data = p; @@ -142,7 +142,7 @@ static int tnl_gen_ioctl(int cmd, const char *name, int fd; int err; - strncpy(ifr.ifr_name, name, IFNAMSIZ); + strlcpy(ifr.ifr_name, name, IFNAMSIZ); ifr.ifr_ifru.ifru_data = p; fd = socket(preferred_family, SOCK_DGRAM, 0); From b8a6088e13ee302657f8c720f3e0f4226dbdaa17 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 19 Mar 2018 16:21:51 -0700 Subject: [PATCH 11/19] tc_class: fix snprintf warning Size buffer big enough to avoid any possible overflow. Signed-off-by: Stephen Hemminger --- tc/tc_class.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tc/tc_class.c b/tc/tc_class.c index 1b214b82..91802518 100644 --- a/tc/tc_class.c +++ b/tc/tc_class.c @@ -219,7 +219,7 @@ static void graph_cls_show(FILE *fp, char *buf, struct hlist_head *root_list, char cls_id_str[256] = {}; struct rtattr *tb[TCA_MAX + 1]; struct qdisc_util *q; - char str[100] = {}; + char str[300] = {}; hlist_for_each_safe(n, tmp_cls, root_list) { struct hlist_node *c, *tmp_chld; @@ -242,7 +242,8 @@ static void graph_cls_show(FILE *fp, char *buf, struct hlist_head *root_list, graph_indent(buf, cls, 0, 0); print_tc_classid(cls_id_str, sizeof(cls_id_str), cls->id); - sprintf(str, "+---(%s)", cls_id_str); + snprintf(str, sizeof(str), + "+---(%s)", cls_id_str); strcat(buf, str); parse_rtattr(tb, TCA_MAX, (struct rtattr *)cls->data, From d5732e34707b0e62c2fcbaf78ca3bd26b229a993 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 19 Mar 2018 16:22:39 -0700 Subject: [PATCH 12/19] ematch: fix possible snprintf overflow Fixes gcc 8 warning about possible snprint overflow Signed-off-by: Stephen Hemminger --- tc/m_ematch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/m_ematch.c b/tc/m_ematch.c index d2bb5c38..0d66dc68 100644 --- a/tc/m_ematch.c +++ b/tc/m_ematch.c @@ -161,7 +161,7 @@ static struct ematch_util *get_ematch_kind(char *kind) static struct ematch_util *get_ematch_kind_num(__u16 kind) { - char name[32]; + char name[513]; if (lookup_map(kind, name, sizeof(name), EMATCH_MAP) < 0) return NULL; From da8034a01904b7f8ed5a96624d06f56b8d3e4afd Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 19 Mar 2018 16:23:18 -0700 Subject: [PATCH 13/19] misc: avoid snprintf warnings in ss and nstat Gcc 8 checks that target buffer is big enough. Signed-off-by: Stephen Hemminger --- misc/nstat.c | 4 ++-- misc/ss.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/nstat.c b/misc/nstat.c index a4dd405d..433a1f48 100644 --- a/misc/nstat.c +++ b/misc/nstat.c @@ -178,12 +178,12 @@ static int count_spaces(const char *line) static void load_ugly_table(FILE *fp) { - char buf[4096]; + char buf[2048]; struct nstat_ent *db = NULL; struct nstat_ent *n; while (fgets(buf, sizeof(buf), fp) != NULL) { - char idbuf[sizeof(buf)]; + char idbuf[4096]; int off; char *p; int count1, count2, skip = 0; diff --git a/misc/ss.c b/misc/ss.c index fc8e2a0d..76fca3fb 100644 --- a/misc/ss.c +++ b/misc/ss.c @@ -4093,7 +4093,7 @@ static int netlink_show_one(struct filter *f, if (!pid) { done = 1; - strncpy(procname, "kernel", 6); + strncpy(procname, "kernel", 7); } else if (pid > 0) { FILE *fp; From 08a93b32f50cbd3faa94e2121a518c0105afc1e5 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 19 Mar 2018 16:36:39 -0700 Subject: [PATCH 14/19] bpf: avoid compiler warnings about strncpy Use strlcpy to avoid cases where sizeof(buf) == strlen(buf) Signed-off-by: Stephen Hemminger Acked-by: Daniel Borkmann --- lib/bpf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/bpf.c b/lib/bpf.c index c38d92d8..04bc5a56 100644 --- a/lib/bpf.c +++ b/lib/bpf.c @@ -2593,7 +2593,7 @@ bpf_map_set_send(int fd, struct sockaddr_un *addr, unsigned int addr_len, char *amsg_buf; int i; - strncpy(msg.aux.obj_name, aux->obj, sizeof(msg.aux.obj_name)); + strlcpy(msg.aux.obj_name, aux->obj, sizeof(msg.aux.obj_name)); memcpy(&msg.aux.obj_st, aux->st, sizeof(msg.aux.obj_st)); cmsg_buf = bpf_map_set_init(&msg, addr, addr_len); @@ -2682,7 +2682,7 @@ int bpf_send_map_fds(const char *path, const char *obj) return -1; } - strncpy(addr.sun_path, path, sizeof(addr.sun_path)); + strlcpy(addr.sun_path, path, sizeof(addr.sun_path)); ret = connect(fd, (struct sockaddr *)&addr, sizeof(addr)); if (ret < 0) { @@ -2715,7 +2715,7 @@ int bpf_recv_map_fds(const char *path, int *fds, struct bpf_map_aux *aux, return -1; } - strncpy(addr.sun_path, path, sizeof(addr.sun_path)); + strlcpy(addr.sun_path, path, sizeof(addr.sun_path)); ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); if (ret < 0) { From 89e3c36b066d7fe9bd90a4740cc7aa4d859f0dda Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 29 Mar 2018 08:40:26 -0700 Subject: [PATCH 15/19] namespace: limit the length of namespace name to avoid snprintf overflow This fixes problem reported by gcc-8 Signed-off-by: Stephen Hemminger --- lib/namespace.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/namespace.c b/lib/namespace.c index 6f3356d0..43e0fe34 100644 --- a/lib/namespace.c +++ b/lib/namespace.c @@ -17,12 +17,15 @@ static void bind_etc(const char *name) { - char etc_netns_path[PATH_MAX]; + char etc_netns_path[sizeof(NETNS_ETC_DIR) + NAME_MAX]; char netns_name[PATH_MAX]; char etc_name[PATH_MAX]; struct dirent *entry; DIR *dir; + if (strlen(name) >= NAME_MAX) + return; + snprintf(etc_netns_path, sizeof(etc_netns_path), "%s/%s", NETNS_ETC_DIR, name); dir = opendir(etc_netns_path); if (!dir) From c12180725089d85ffb01eb3e072c992cdef3afdc Mon Sep 17 00:00:00 2001 From: Alexander Zubkov Date: Wed, 28 Mar 2018 01:57:13 +0200 Subject: [PATCH 16/19] arrange prefix parsing code after redundant patches A problem was reported with parsing of prefixes all/any/default. Commit 7696f1097f79be2ce5984a8a16103fd17391cac2 fixes the problem, but there were also other pathces applied: 00b31a6b2ecf73ee477f701098164600a2bfe227, which were intended to fix the same problem. And they became redundant now. This patch reverts changes introduced by those redundant patches. Signed-off-by: Alexander Zubkov --- ip/iproute.c | 65 +++++++++++++++++++++++++++++++++++++--------------- lib/utils.c | 13 ----------- 2 files changed, 46 insertions(+), 32 deletions(-) diff --git a/ip/iproute.c b/ip/iproute.c index 32c93ed5..bf886fda 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -191,20 +191,42 @@ static int filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len) return 0; if ((filter.tos^r->rtm_tos)&filter.tosmask) return 0; - if (filter.rdst.family && - (r->rtm_family != filter.rdst.family || filter.rdst.bitlen > r->rtm_dst_len)) - return 0; - if (filter.mdst.family && - (r->rtm_family != filter.mdst.family || - (filter.mdst.bitlen >= 0 && filter.mdst.bitlen < r->rtm_dst_len))) - return 0; - if (filter.rsrc.family && - (r->rtm_family != filter.rsrc.family || filter.rsrc.bitlen > r->rtm_src_len)) - return 0; - if (filter.msrc.family && - (r->rtm_family != filter.msrc.family || - (filter.msrc.bitlen >= 0 && filter.msrc.bitlen < r->rtm_src_len))) - return 0; + if (filter.rdst.family) { + if (r->rtm_family != filter.rdst.family || + filter.rdst.bitlen > r->rtm_dst_len) + return 0; + } else if (filter.rdst.flags & PREFIXLEN_SPECIFIED) { + if (filter.rdst.bitlen > r->rtm_dst_len) + return 0; + } + if (filter.mdst.family) { + if (r->rtm_family != filter.mdst.family || + (filter.mdst.bitlen >= 0 && + filter.mdst.bitlen < r->rtm_dst_len)) + return 0; + } else if (filter.mdst.flags & PREFIXLEN_SPECIFIED) { + if (filter.mdst.bitlen >= 0 && + filter.mdst.bitlen < r->rtm_dst_len) + return 0; + } + if (filter.rsrc.family) { + if (r->rtm_family != filter.rsrc.family || + filter.rsrc.bitlen > r->rtm_src_len) + return 0; + } else if (filter.rsrc.flags & PREFIXLEN_SPECIFIED) { + if (filter.rsrc.bitlen > r->rtm_src_len) + return 0; + } + if (filter.msrc.family) { + if (r->rtm_family != filter.msrc.family || + (filter.msrc.bitlen >= 0 && + filter.msrc.bitlen < r->rtm_src_len)) + return 0; + } else if (filter.msrc.flags & PREFIXLEN_SPECIFIED) { + if (filter.msrc.bitlen >= 0 && + filter.msrc.bitlen < r->rtm_src_len) + return 0; + } if (filter.rvia.family) { int family = r->rtm_family; @@ -221,7 +243,9 @@ static int filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len) if (tb[RTA_DST]) memcpy(&dst.data, RTA_DATA(tb[RTA_DST]), (r->rtm_dst_len+7)/8); - if (filter.rsrc.family || filter.msrc.family) { + if (filter.rsrc.family || filter.msrc.family || + filter.rsrc.flags & PREFIXLEN_SPECIFIED || + filter.msrc.flags & PREFIXLEN_SPECIFIED) { if (tb[RTA_SRC]) memcpy(&src.data, RTA_DATA(tb[RTA_SRC]), (r->rtm_src_len+7)/8); } @@ -241,15 +265,18 @@ static int filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len) memcpy(&prefsrc.data, RTA_DATA(tb[RTA_PREFSRC]), host_len/8); } - if (filter.rdst.family && inet_addr_match(&dst, &filter.rdst, filter.rdst.bitlen)) + if ((filter.rdst.family || filter.rdst.flags & PREFIXLEN_SPECIFIED) && + inet_addr_match(&dst, &filter.rdst, filter.rdst.bitlen)) return 0; - if (filter.mdst.family && filter.mdst.bitlen >= 0 && + if ((filter.mdst.family || filter.mdst.flags & PREFIXLEN_SPECIFIED) && inet_addr_match(&dst, &filter.mdst, r->rtm_dst_len)) return 0; - if (filter.rsrc.family && inet_addr_match(&src, &filter.rsrc, filter.rsrc.bitlen)) + if ((filter.rsrc.family || filter.rsrc.flags & PREFIXLEN_SPECIFIED) && + inet_addr_match(&src, &filter.rsrc, filter.rsrc.bitlen)) return 0; - if (filter.msrc.family && filter.msrc.bitlen >= 0 && + if ((filter.msrc.family || filter.msrc.flags & PREFIXLEN_SPECIFIED) && + filter.msrc.bitlen >= 0 && inet_addr_match(&src, &filter.msrc, r->rtm_src_len)) return 0; diff --git a/lib/utils.c b/lib/utils.c index dadefb55..b9e9a6ca 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -693,19 +693,6 @@ int get_prefix_1(inet_prefix *dst, char *arg, int family) char *slash; int err, bitlen, flags; - memset(dst, 0, sizeof(*dst)); - - if (strcmp(arg, "default") == 0 || - strcmp(arg, "any") == 0 || - strcmp(arg, "all") == 0) { - if ((family == AF_DECnet) || (family == AF_MPLS)) - return -1; - dst->family = family; - dst->bytelen = 0; - dst->bitlen = 0; - return 0; - } - slash = strchr(arg, '/'); if (slash) *slash = 0; From 200e9d19615636096fe849a96f9bf0b15df43704 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 2 Apr 2018 09:17:42 -0700 Subject: [PATCH 17/19] uapi/if_ether: add definition of ether type field Part of upstream commit 4bbb3e0e8239 ("net: Fix vlan untag for bridge and vlan_dev with reorder_hdr off") Signed-off-by: Stephen Hemminger --- include/uapi/linux/if_ether.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h index a34b152e..fc22aadb 100644 --- a/include/uapi/linux/if_ether.h +++ b/include/uapi/linux/if_ether.h @@ -30,6 +30,7 @@ */ #define ETH_ALEN 6 /* Octets in one ethernet addr */ +#define ETH_TLEN 2 /* Octets in ethernet type field */ #define ETH_HLEN 14 /* Total octets in header. */ #define ETH_ZLEN 60 /* Min. octets in frame sans FCS */ #define ETH_DATA_LEN 1500 /* Max. octets in payload */ From 6b4f03f518c9488604ea89d3945621f2f15994ab Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 29 Mar 2018 16:26:16 +0200 Subject: [PATCH 18/19] man: fix devlink object list Signed-off-by: Jiri Pirko Signed-off-by: Stephen Hemminger --- man/man8/devlink.8 | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/man/man8/devlink.8 b/man/man8/devlink.8 index b83909da..7986310f 100644 --- a/man/man8/devlink.8 +++ b/man/man8/devlink.8 @@ -19,7 +19,7 @@ devlink \- Devlink tool .ti -8 .IR OBJECT " := { " -.BR dev " | " port " | " monitor " }" +.BR dev " | " port " | " monitor " | " sb " | " resource " }" .sp .ti -8 @@ -74,6 +74,14 @@ When combined with -j generate a pretty JSON output. .B monitor - watch for netlink messages. +.TP +.B sb +- devlink shared buffer configuration. + +.TP +.B resource +- devlink device resource configuration. + .SS .I COMMAND From 4b6c4177ee66421770f0bbcc765c29135e44d921 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 2 Apr 2018 10:06:08 -0700 Subject: [PATCH 19/19] v4.16.0 --- include/SNAPSHOT.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SNAPSHOT.h b/include/SNAPSHOT.h index 771bee72..fe39766b 100644 --- a/include/SNAPSHOT.h +++ b/include/SNAPSHOT.h @@ -1 +1 @@ -static const char SNAPSHOT[] = "180129"; +static const char SNAPSHOT[] = "180402";