From d8fb9ec9c0b943b17ff7c504192f1fc5b8bef0ed Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Sep 29 2020 07:07:47 +0000 Subject: import iproute-4.11.0-30.el7 --- diff --git a/.gitignore b/.gitignore index 669af3f..60d0bbc 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/iproute-4.11.0-0.el7.tar.xz +SOURCES/iproute-4.11.0-25.el7.tar.xz diff --git a/.iproute.metadata b/.iproute.metadata index 5ace8c2..8aba7f1 100644 --- a/.iproute.metadata +++ b/.iproute.metadata @@ -1 +1 @@ -44b3b021eb4bf5416469e485753d877df1c3c848 SOURCES/iproute-4.11.0-0.el7.tar.xz +d56e9c2df29a87bb09b35a0a977694170ac05a82 SOURCES/iproute-4.11.0-25.el7.tar.xz diff --git a/SOURCES/0001-Confirm-success-for-each-tc-batch-command.patch b/SOURCES/0001-Confirm-success-for-each-tc-batch-command.patch deleted file mode 100644 index 844fec6..0000000 --- a/SOURCES/0001-Confirm-success-for-each-tc-batch-command.patch +++ /dev/null @@ -1,105 +0,0 @@ -From d9a1dc236a9bcc06f04d609e2654f76c6a9459e7 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Mon, 14 Dec 2015 21:02:18 +0100 -Subject: [PATCH] Confirm success for each tc -batch command -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=977844 -Upstream Status: Rejected. - -The original patch has been extended by the related man page additions -which were contained in another local patch. - -commit 8c5024483cbbfdc092945a00be05d917485b9af3 -Author: Petr Písař -Date: Thu Sep 19 11:25:49 2013 +0200 - - Confirm success for each tc -batch command - - If `tc -force -batch' is fed by a controlling program from a pipe, - it's not possible to recognize when a command has been processes - successfully. - - This patch adds an optional `-OK' option to the tc(8) tool, so `tc - -force -OK -batch' will print "OK\n" to standard output on each - successfully completed tc command. - - Signed-off-by: Petr Písař - -Signed-off-by: Phil Sutter ---- - man/man8/tc.8 | 8 +++++++- - tc/tc.c | 8 +++++++- - 2 files changed, 14 insertions(+), 2 deletions(-) - -diff --git a/man/man8/tc.8 b/man/man8/tc.8 -index f96911ae1d77d..a341a8f995f85 100644 ---- a/man/man8/tc.8 -+++ b/man/man8/tc.8 -@@ -62,7 +62,7 @@ tc \- show / manipulate traffic control settings - .P - .ti 8 - .IR OPTIONS " := {" --\fB[ -force ] -b\fR[\fIatch\fR] \fB[ filename ] \fR| -+\fB[ -force ] [ -OK ] -b\fR[\fIatch\fR] \fB[ filename ] \fR| - \fB[ \fB-n\fR[\fIetns\fR] name \fB] \fR| - \fB[ \fB-nm \fR| \fB-nam\fR[\fIes\fR] \fB] \fR| - \fB[ \fR{ \fB-cf \fR| \fB-c\fR[\fIonf\fR] \fR} \fB[ filename ] \fB] \fR} -@@ -602,6 +602,12 @@ First failure will cause termination of tc. - don't terminate tc on errors in batch mode. - If there were any errors during execution of the commands, the application return code will be non zero. - -+.TP -+.BR "\-OK" -+in batch mode, print -+.B OK -+and a new line on standard output after each successfully interpreted command. -+ - .TP - .BR "\-n" , " \-net" , " \-netns " - switches -diff --git a/tc/tc.c b/tc/tc.c -index 8e64a82b4271c..360c9f11c235b 100644 ---- a/tc/tc.c -+++ b/tc/tc.c -@@ -42,6 +42,7 @@ int batch_mode; - int resolve_hosts; - int use_iec; - int force; -+int ok; - bool use_names; - - static char *conf_file; -@@ -188,7 +189,7 @@ noexist: - static void usage(void) - { - fprintf(stderr, "Usage: tc [ OPTIONS ] OBJECT { COMMAND | help }\n" -- " tc [-force] -batch filename\n" -+ " tc [-force] [-OK] -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 }\n"); -@@ -254,6 +255,9 @@ static int batch(const char *name) - ret = 1; - if (!force) - break; -+ } else if (ok) { -+ printf("OK\n"); -+ fflush(stdout); - } - } - if (line) -@@ -293,6 +297,8 @@ int main(int argc, char **argv) - return 0; - } else if (matches(argv[1], "-force") == 0) { - ++force; -+ } else if (matches(argv[1], "-OK") == 0) { -+ ++ok; - } else if (matches(argv[1], "-batch") == 0) { - argc--; argv++; - if (argc <= 1) --- -2.21.0 - diff --git a/SOURCES/0001-netns-make-var-run-netns-bind-mount-recursive.patch b/SOURCES/0001-netns-make-var-run-netns-bind-mount-recursive.patch new file mode 100644 index 0000000..d86731e --- /dev/null +++ b/SOURCES/0001-netns-make-var-run-netns-bind-mount-recursive.patch @@ -0,0 +1,41 @@ +From 7348e6148f641d4bc24cb3277ac9fa7675a1825c Mon Sep 17 00:00:00 2001 +From: Andrea Claudi +Date: Wed, 13 Nov 2019 11:40:24 +0100 +Subject: [PATCH] netns: make /var/run/netns bind-mount recursive + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1771556 +Upstream Status: iproute2.git commit d6a4076b6ba65 + +commit d6a4076b6ba6547d7e52c377a7c58c56eb5ea16e +Author: Casey Callendrello +Date: Tue Aug 1 17:46:09 2017 +0200 + + netns: make /var/run/netns bind-mount recursive + + When ip netns {add|delete} is first run, it bind-mounts /var/run/netns + on top of itself, then marks it as shared. However, if there are already + bind-mounts in the directory from other tools, these would not be + propagated. Fix this by recursively bind-mounting. + + Signed-off-by: Casey Callendrello + Acked-by: "Eric W. Biederman" +--- + ip/ipnetns.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ip/ipnetns.c b/ip/ipnetns.c +index 427b59c57381d..c8e22e9b6e952 100644 +--- a/ip/ipnetns.c ++++ b/ip/ipnetns.c +@@ -640,7 +640,7 @@ static int netns_add(int argc, char **argv) + } + + /* Upgrade NETNS_RUN_DIR to a mount point */ +- if (mount(NETNS_RUN_DIR, NETNS_RUN_DIR, "none", MS_BIND, NULL)) { ++ if (mount(NETNS_RUN_DIR, NETNS_RUN_DIR, "none", MS_BIND | MS_REC, NULL)) { + fprintf(stderr, "mount --bind %s %s failed: %s\n", + NETNS_RUN_DIR, NETNS_RUN_DIR, strerror(errno)); + return -1; +-- +2.21.0 + diff --git a/SOURCES/0002-Really-fix-get_addr-and-get_prefix-error-messages.patch b/SOURCES/0002-Really-fix-get_addr-and-get_prefix-error-messages.patch deleted file mode 100644 index 34aed4d..0000000 --- a/SOURCES/0002-Really-fix-get_addr-and-get_prefix-error-messages.patch +++ /dev/null @@ -1,88 +0,0 @@ -From aed8229c0bec5c56deaf1ea2047ca0263732477f Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Fri, 11 Aug 2017 11:11:32 +0200 -Subject: [PATCH] Really fix get_addr() and get_prefix() error messages - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1477206 -Upstream Status: iproute2.git commit 34705c807a389 - -commit 34705c807a38909247d1bb29ccdffe42e5c1dab3 -Author: Phil Sutter -Date: Tue Aug 1 18:36:11 2017 +0200 - - Really fix get_addr() and get_prefix() error messages - - Both functions take the desired address family as a parameter. So using - that to notify the user what address family was expected is correct, - unlike using dst->family which will tell the user only what address - family was specified. - - The situation which commit 334af76143368 tried to fix was when 'ip' - would accept addresses from multiple families. In that case, the family - parameter is set to AF_UNSPEC so that get_addr_1() may accept any valid - address. - - This patch introduces a wrapper around family_name() which returns the - string "any valid" for AF_UNSPEC instead of the three question marks - unsuitable for use in error messages. - - Tests for AF_UNSPEC: - - | # ip a a 256.10.166.1/24 dev d0 - | Error: any valid prefix is expected rather than "256.10.166.1/24". - - | # ip neighbor add proxy 2001:db8::g dev d0 - | Error: any valid address is expected rather than "2001:db8::g". - - Tests for explicit address family: - - | # ip -6 addrlabel add prefix 1.1.1.1/24 label 123 - | Error: inet6 prefix is expected rather than "1.1.1.1/24". - - | # ip -4 addrlabel add prefix dead:beef::1/24 label 123 - | Error: inet prefix is expected rather than "dead:beef::1/24". - - Reported-by: Jaroslav Aster - Fixes: 334af76143368 ("fix get_addr() and get_prefix() error messages") - Signed-off-by: Phil Sutter ---- - lib/utils.c | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) - -diff --git a/lib/utils.c b/lib/utils.c -index 6d5642f4f1f3f..7d6ee53ad938d 100644 ---- a/lib/utils.c -+++ b/lib/utils.c -@@ -613,12 +613,19 @@ done: - return err; - } - -+static const char *family_name_verbose(int family) -+{ -+ if (family == AF_UNSPEC) -+ return "any valid"; -+ return family_name(family); -+} -+ - int get_addr(inet_prefix *dst, const char *arg, int family) - { - if (get_addr_1(dst, arg, family)) { - fprintf(stderr, - "Error: %s address is expected rather than \"%s\".\n", -- family_name(dst->family), arg); -+ family_name_verbose(family), arg); - exit(1); - } - return 0; -@@ -636,7 +643,7 @@ int get_prefix(inet_prefix *dst, char *arg, int family) - if (get_prefix_1(dst, arg, family)) { - fprintf(stderr, - "Error: %s prefix is expected rather than \"%s\".\n", -- family_name(dst->family), arg); -+ family_name_verbose(family), arg); - exit(1); - } - return 0; --- -2.21.0 - diff --git a/SOURCES/0002-nstat-print-useful-error-messages-in-abort-cases.patch b/SOURCES/0002-nstat-print-useful-error-messages-in-abort-cases.patch new file mode 100644 index 0000000..f9252ac --- /dev/null +++ b/SOURCES/0002-nstat-print-useful-error-messages-in-abort-cases.patch @@ -0,0 +1,121 @@ +From d82789f3e39983a41752d322c52f0a9c36d9419a Mon Sep 17 00:00:00 2001 +From: Andrea Claudi +Date: Tue, 21 Apr 2020 12:44:38 +0200 +Subject: [PATCH] nstat: print useful error messages in abort() cases + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1792908 +Upstream Status: iproute2.git commit 2c7056ac26412 +Conflicts: context change due to missing commit 72cdb77d1a31a + ("nstat: fix load_ugly_table() limits") + +commit 2c7056ac26412fe99443a283f0c1261cb81ccea2 +Author: Andrea Claudi +Date: Mon Feb 17 14:46:18 2020 +0100 + + nstat: print useful error messages in abort() cases + + When nstat temporary file is corrupted or in some other corner cases, + nstat use abort() to stop its execution. This can puzzle some users, + wondering what is the reason for the crash. + + This commit replaces abort() with some meaningful error messages and exit() + + Reported-by: Renaud Métrich + Signed-off-by: Andrea Claudi + Signed-off-by: Stephen Hemminger +--- + misc/nstat.c | 47 +++++++++++++++++++++++++++++++++-------------- + 1 file changed, 33 insertions(+), 14 deletions(-) + +diff --git a/misc/nstat.c b/misc/nstat.c +index a4dd405d43a93..33c428c8b2418 100644 +--- a/misc/nstat.c ++++ b/misc/nstat.c +@@ -143,14 +143,19 @@ static void load_good_table(FILE *fp) + } + /* idbuf is as big as buf, so this is safe */ + nr = sscanf(buf, "%s%llu%lg", idbuf, &val, &rate); +- if (nr < 2) +- abort(); ++ if (nr < 2) { ++ fprintf(stderr, "%s:%d: error parsing history file\n", ++ __FILE__, __LINE__); ++ exit(-2); ++ } + if (nr < 3) + rate = 0; + if (useless_number(idbuf)) + continue; +- if ((n = malloc(sizeof(*n))) == NULL) +- abort(); ++ if ((n = malloc(sizeof(*n))) == NULL) { ++ perror("nstat: malloc"); ++ exit(-1); ++ } + n->id = strdup(idbuf); + n->val = val; + n->rate = rate; +@@ -189,8 +194,11 @@ static void load_ugly_table(FILE *fp) + int count1, count2, skip = 0; + + p = strchr(buf, ':'); +- if (!p) +- abort(); ++ if (!p) { ++ fprintf(stderr, "%s:%d: error parsing history file\n", ++ __FILE__, __LINE__); ++ exit(-2); ++ } + count1 = count_spaces(buf); + *p = 0; + idbuf[0] = 0; +@@ -210,8 +218,10 @@ static void load_ugly_table(FILE *fp) + strncat(idbuf, p, sizeof(idbuf) - off - 1); + } + n = malloc(sizeof(*n)); +- if (!n) +- abort(); ++ if (!n) { ++ perror("nstat: malloc"); ++ exit(-1); ++ } + n->id = strdup(idbuf); + n->rate = 0; + n->next = db; +@@ -219,18 +229,27 @@ static void load_ugly_table(FILE *fp) + p = next; + } + n = db; +- if (fgets(buf, sizeof(buf), fp) == NULL) +- abort(); ++ if (fgets(buf, sizeof(buf), fp) == NULL) { ++ fprintf(stderr, "%s:%d: error parsing history file\n", ++ __FILE__, __LINE__); ++ exit(-2); ++ } + count2 = count_spaces(buf); + if (count2 > count1) + skip = count2 - count1; + do { + p = strrchr(buf, ' '); +- if (!p) +- abort(); ++ if (!p) { ++ fprintf(stderr, "%s:%d: error parsing history file\n", ++ __FILE__, __LINE__); ++ exit(-2); ++ } + *p = 0; +- if (sscanf(p+1, "%llu", &n->val) != 1) +- abort(); ++ if (sscanf(p+1, "%llu", &n->val) != 1) { ++ fprintf(stderr, "%s:%d: error parsing history file\n", ++ __FILE__, __LINE__); ++ exit(-2); ++ } + /* Trick to skip "dummy" trailing ICMP MIB in 2.4 */ + if (skip) + skip--; +-- +2.25.3 + diff --git a/SOURCES/0003-tc-Add-support-for-the-CBS-qdisc.patch b/SOURCES/0003-tc-Add-support-for-the-CBS-qdisc.patch new file mode 100644 index 0000000..7e86094 --- /dev/null +++ b/SOURCES/0003-tc-Add-support-for-the-CBS-qdisc.patch @@ -0,0 +1,197 @@ +From ea5c3a2ffa0b7f4e720457821bfdd594516744d1 Mon Sep 17 00:00:00 2001 +From: Andrea Claudi +Date: Tue, 21 Apr 2020 14:32:49 +0200 +Subject: [PATCH] tc: Add support for the CBS qdisc + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1557461 +Upstream Status: iproute2.git commit c9681ac1b3e0c + +commit c9681ac1b3e0cd7b8e8b8cba17ac7090775ca647 +Author: Vinicius Costa Gomes +Date: Thu Oct 26 10:17:48 2017 -0700 + + tc: Add support for the CBS qdisc + + The Credit Based Shaper (CBS) queueing discipline allows bandwidth + reservation with sub-milisecond precision. It is defined by the + 802.1Q-2014 specification (section 8.6.8.2 and Annex L). + + The syntax is: + + tc qdisc add dev DEV parent NODE cbs locredit + hicredit sendslope + idleslope + + (The order is not important) + + Signed-off-by: Vinicius Costa Gomes + Signed-off-by: Jeff Kirsher +--- + tc/Makefile | 1 + + tc/q_cbs.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 143 insertions(+) + create mode 100644 tc/q_cbs.c + +diff --git a/tc/Makefile b/tc/Makefile +index 9a6bb1ddea57e..6b4e5f2b20762 100644 +--- a/tc/Makefile ++++ b/tc/Makefile +@@ -72,6 +72,7 @@ TCMODULES += q_hhf.o + TCMODULES += q_clsact.o + TCMODULES += e_bpf.o + TCMODULES += f_matchall.o ++TCMODULES += q_cbs.o + + TCSO := + ifeq ($(TC_CONFIG_ATM),y) +diff --git a/tc/q_cbs.c b/tc/q_cbs.c +new file mode 100644 +index 0000000000000..e53be6548ad9a +--- /dev/null ++++ b/tc/q_cbs.c +@@ -0,0 +1,142 @@ ++/* ++ * q_cbs.c CBS. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ * ++ * Authors: Vinicius Costa Gomes ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "utils.h" ++#include "tc_util.h" ++ ++static void explain(void) ++{ ++ fprintf(stderr, "Usage: ... cbs hicredit BYTES locredit BYTES sendslope BPS idleslope BPS\n"); ++ fprintf(stderr, " [offload 0|1]\n"); ++ ++} ++ ++static void explain1(const char *arg, const char *val) ++{ ++ fprintf(stderr, "cbs: illegal value for \"%s\": \"%s\"\n", arg, val); ++} ++ ++static int cbs_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) ++{ ++ struct tc_cbs_qopt opt = {}; ++ struct rtattr *tail; ++ ++ while (argc > 0) { ++ if (matches(*argv, "offload") == 0) { ++ NEXT_ARG(); ++ if (opt.offload) { ++ fprintf(stderr, "cbs: duplicate \"offload\" specification\n"); ++ return -1; ++ } ++ if (get_u8(&opt.offload, *argv, 0)) { ++ explain1("offload", *argv); ++ return -1; ++ } ++ } else if (matches(*argv, "hicredit") == 0) { ++ NEXT_ARG(); ++ if (opt.hicredit) { ++ fprintf(stderr, "cbs: duplicate \"hicredit\" specification\n"); ++ return -1; ++ } ++ if (get_s32(&opt.hicredit, *argv, 0)) { ++ explain1("hicredit", *argv); ++ return -1; ++ } ++ } else if (matches(*argv, "locredit") == 0) { ++ NEXT_ARG(); ++ if (opt.locredit) { ++ fprintf(stderr, "cbs: duplicate \"locredit\" specification\n"); ++ return -1; ++ } ++ if (get_s32(&opt.locredit, *argv, 0)) { ++ explain1("locredit", *argv); ++ return -1; ++ } ++ } else if (matches(*argv, "sendslope") == 0) { ++ NEXT_ARG(); ++ if (opt.sendslope) { ++ fprintf(stderr, "cbs: duplicate \"sendslope\" specification\n"); ++ return -1; ++ } ++ if (get_s32(&opt.sendslope, *argv, 0)) { ++ explain1("sendslope", *argv); ++ return -1; ++ } ++ } else if (matches(*argv, "idleslope") == 0) { ++ NEXT_ARG(); ++ if (opt.idleslope) { ++ fprintf(stderr, "cbs: duplicate \"idleslope\" specification\n"); ++ return -1; ++ } ++ if (get_s32(&opt.idleslope, *argv, 0)) { ++ explain1("idleslope", *argv); ++ return -1; ++ } ++ } else if (strcmp(*argv, "help") == 0) { ++ explain(); ++ return -1; ++ } else { ++ fprintf(stderr, "cbs: unknown parameter \"%s\"\n", *argv); ++ explain(); ++ return -1; ++ } ++ argc--; argv++; ++ } ++ ++ tail = NLMSG_TAIL(n); ++ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); ++ addattr_l(n, 2024, TCA_CBS_PARMS, &opt, sizeof(opt)); ++ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; ++ return 0; ++} ++ ++static int cbs_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) ++{ ++ struct rtattr *tb[TCA_CBS_MAX+1]; ++ struct tc_cbs_qopt *qopt; ++ ++ if (opt == NULL) ++ return 0; ++ ++ parse_rtattr_nested(tb, TCA_CBS_MAX, opt); ++ ++ if (tb[TCA_CBS_PARMS] == NULL) ++ return -1; ++ ++ qopt = RTA_DATA(tb[TCA_CBS_PARMS]); ++ if (RTA_PAYLOAD(tb[TCA_CBS_PARMS]) < sizeof(*qopt)) ++ return -1; ++ ++ fprintf(f, "hicredit %d ", qopt->hicredit); ++ fprintf(f, "locredit %d ", qopt->locredit); ++ fprintf(f, "sendslope %d ", qopt->sendslope); ++ fprintf(f, "idleslope %d ", qopt->idleslope); ++ fprintf(f, "offload %d ", qopt->offload); ++ ++ return 0; ++} ++ ++struct qdisc_util cbs_qdisc_util = { ++ .id = "cbs", ++ .parse_qopt = cbs_parse_opt, ++ .print_qopt = cbs_print_opt, ++}; +-- +2.25.3 + diff --git a/SOURCES/0003-tc-simple-Fix-documentation.patch b/SOURCES/0003-tc-simple-Fix-documentation.patch deleted file mode 100644 index dc79174..0000000 --- a/SOURCES/0003-tc-simple-Fix-documentation.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 3d016b2ca5862b3f47da5b28aca43bd96d5c3c49 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Fri, 11 Aug 2017 11:13:26 +0200 -Subject: [PATCH] tc-simple: Fix documentation - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1477523 -Upstream Status: iproute2.git commit e2a055dd23f0e - -commit e2a055dd23f0e7527a987c24687cb6b0b86f0cde -Author: Phil Sutter -Date: Thu Aug 3 17:00:51 2017 +0200 - - tc-simple: Fix documentation - - - CONTROL has to come last, otherwise 'index' applies to gact and not - simple itself. - - Man page wasn't updated to reflect syntax changes. - - Signed-off-by: Phil Sutter ---- - man/man8/tc-simple.8 | 29 ++++++++++++++++++++++++++--- - tc/m_simple.c | 4 ++-- - 2 files changed, 28 insertions(+), 5 deletions(-) - -diff --git a/man/man8/tc-simple.8 b/man/man8/tc-simple.8 -index 2206dc3b88614..7363ab563e189 100644 ---- a/man/man8/tc-simple.8 -+++ b/man/man8/tc-simple.8 -@@ -6,15 +6,37 @@ simple - basic example action - .in +8 - .ti -8 - .BR tc " ... " "action simple" --.I STRING -+[ -+.BI sdata " STRING" -+] [ -+.BI index " INDEX" -+] [ -+.I CONTROL -+] -+ -+.ti -8 -+.IR CONTROL " := {" -+.BR reclassify " | " pipe " | " drop " | " continue " | " ok " }" -+ - .SH DESCRIPTION - This is a pedagogical example rather than an actually useful action. Upon every access, it prints the given - .I STRING - which may be of arbitrary length. - .SH OPTIONS - .TP --.I STRING -+.BI sdata " STRING" - The actual string to print. -+.TP -+.BI index " INDEX" -+Optional action index value. -+.TP -+.I CONTROL -+Indicate how -+.B tc -+should proceed after executing the action. For a description of the possible -+.I CONTROL -+values, see -+.BR tc-actions (8). - .SH EXAMPLES - The following example makes the kernel yell "Incoming ICMP!" every time it sees - an incoming ICMP on eth0. Steps are: -@@ -36,7 +58,7 @@ display stats again and observe increment by 1 - .EX - hadi@noma1:$ tc qdisc add dev eth0 ingress - hadi@noma1:$tc filter add dev eth0 parent ffff: protocol ip prio 5 \\ -- u32 match ip protocol 1 0xff flowid 1:1 action simple "Incoming ICMP" -+ u32 match ip protocol 1 0xff flowid 1:1 action simple sdata "Incoming ICMP" - - hadi@noma1:$ sudo tc -s filter ls dev eth0 parent ffff: - filter protocol ip pref 5 u32 -@@ -74,3 +96,4 @@ display stats again and observe increment by 1 - .EE - .SH SEE ALSO - .BR tc (8) -+.BR tc-actions (8) -diff --git a/tc/m_simple.c b/tc/m_simple.c -index 3a8bd916d3bfb..ab633849f7b45 100644 ---- a/tc/m_simple.c -+++ b/tc/m_simple.c -@@ -81,10 +81,10 @@ - #endif - static void explain(void) - { -- fprintf(stderr, "Usage:... simple [sdata STRING] [CONTROL] [index INDEX]\n"); -+ fprintf(stderr, "Usage:... simple [sdata STRING] [index INDEX] [CONTROL]\n"); - fprintf(stderr, "\tSTRING being an arbitrary string\n" -- "\tCONTROL := reclassify|pipe|drop|continue|ok\n" - "\tINDEX := optional index value used\n"); -+ "\tCONTROL := reclassify|pipe|drop|continue|ok\n" - } - - static void usage(void) --- -2.21.0 - diff --git a/SOURCES/0004-man-Add-initial-manpage-for-tc-cbs-8.patch b/SOURCES/0004-man-Add-initial-manpage-for-tc-cbs-8.patch new file mode 100644 index 0000000..593b494 --- /dev/null +++ b/SOURCES/0004-man-Add-initial-manpage-for-tc-cbs-8.patch @@ -0,0 +1,142 @@ +From 716aa9141156b5284679b40545e20c7164957bf3 Mon Sep 17 00:00:00 2001 +From: Andrea Claudi +Date: Tue, 21 Apr 2020 14:32:49 +0200 +Subject: [PATCH] man: Add initial manpage for tc-cbs(8) + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1557461 +Upstream Status: iproute2.git commit d65298892062e + +commit d65298892062e8757e94d36f23fe3ea835ff66dc +Author: Vinicius Costa Gomes +Date: Thu Oct 26 10:17:49 2017 -0700 + + man: Add initial manpage for tc-cbs(8) + + Signed-off-by: Vinicius Costa Gomes + Signed-off-by: Jeff Kirsher +--- + man/man8/tc-cbs.8 | 112 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 112 insertions(+) + create mode 100644 man/man8/tc-cbs.8 + +diff --git a/man/man8/tc-cbs.8 b/man/man8/tc-cbs.8 +new file mode 100644 +index 0000000000000..97e00c84ded16 +--- /dev/null ++++ b/man/man8/tc-cbs.8 +@@ -0,0 +1,112 @@ ++.TH CBS 8 "18 Sept 2017" "iproute2" "Linux" ++.SH NAME ++CBS \- Credit Based Shaper (CBS) Qdisc ++.SH SYNOPSIS ++.B tc qdisc ... dev ++dev ++.B parent ++classid ++.B [ handle ++major: ++.B ] cbs idleslope ++idleslope ++.B sendslope ++sendslope ++.B hicredit ++hicredit ++.B locredit ++locredit ++.B [ offload ++0|1 ++.B ] ++ ++.SH DESCRIPTION ++The CBS (Credit Based Shaper) qdisc implements the shaping algorithm ++defined by the IEEE 802.1Q-2014 Section 8.6.8.2, which applies a well ++defined rate limiting method to the traffic. ++ ++This queueing discipline is intended to be used by TSN (Time Sensitive ++Networking) applications, the CBS parameters are derived directly by ++what is described by the Annex L of the IEEE 802.1Q-2014 ++Sepcification. The algorithm and how it affects the latency are ++detailed there. ++ ++CBS is meant to be installed under another qdisc that maps packet ++flows to traffic classes, one example is ++.BR mqprio(8). ++ ++.SH PARAMETERS ++.TP ++idleslope ++Idleslope is the rate of credits that is accumulated (in kilobits per ++second) when there is at least one packet waiting for transmission. ++Packets are transmitted when the current value of credits is equal or ++greater than zero. When there is no packet to be transmitted the ++amount of credits is set to zero. This is the main tunable of the CBS ++algorithm. ++.TP ++sendslope ++Sendslope is the rate of credits that is depleted (it should be a ++negative number of kilobits per second) when a transmission is ++ocurring. It can be calculated as follows, (IEEE 802.1Q-2014 Section ++8.6.8.2 item g): ++ ++sendslope = idleslope - port_transmit_rate ++ ++.TP ++hicredit ++Hicredit defines the maximum amount of credits (in bytes) that can be ++accumulated. Hicredit depends on the characteristics of interfering ++traffic, 'max_interference_size' is the maximum size of any burst of ++traffic that can delay the transmission of a frame that is available ++for transmission for this traffic class, (IEEE 802.1Q-2014 Annex L, ++Equation L-3): ++ ++hicredit = max_interference_size * (idleslope / port_transmit_rate) ++ ++.TP ++locredit ++Locredit is the minimum amount of credits that can be reached. It is a ++function of the traffic flowing through this qdisc (IEEE 802.1Q-2014 ++Annex L, Equation L-2): ++ ++locredit = max_frame_size * (sendslope / port_transmit_rate) ++ ++.TP ++offload ++When ++.B offload ++is 1, ++.BR cbs(8) ++will try to configure the network interface so the CBS algorithm runs ++in the controller. The default is 0. ++ ++.SH EXAMPLES ++ ++CBS is used to enforce a Quality of Service by limiting the data rate ++of a traffic class, to separate packets into traffic classes the user ++may choose ++.BR mqprio(8), ++and configure it like this: ++ ++.EX ++# tc qdisc add dev eth0 handle 100: parent root mqprio num_tc 3 \\ ++ map 2 2 1 0 2 2 2 2 2 2 2 2 2 2 2 2 \\ ++ queues 1@0 1@1 2@2 \\ ++ hw 0 ++.EE ++.P ++To replace the current queuing disciple by CBS in the current queueing ++discipline connected to traffic class number 0, issue: ++.P ++.EX ++# tc qdisc replace dev eth0 parent 100:4 cbs \\ ++ locredit -1470 hicredit 30 sendslope -980000 idleslope 20000 ++.EE ++ ++These values are obtained from the following parameters, idleslope is ++20mbit/s, the transmission rate is 1Gbit/s and the maximum interfering ++frame size is 1500 bytes. ++ ++.SH AUTHORS ++Vinicius Costa Gomes +-- +2.25.3 + diff --git a/SOURCES/0004-tc-fix-m_simple-usage.patch b/SOURCES/0004-tc-fix-m_simple-usage.patch deleted file mode 100644 index 14d24ef..0000000 --- a/SOURCES/0004-tc-fix-m_simple-usage.patch +++ /dev/null @@ -1,37 +0,0 @@ -From d203110b883afafa58b735a3e94c71f255db7608 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Fri, 11 Aug 2017 11:13:26 +0200 -Subject: [PATCH] tc: fix m_simple usage - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1477523 -Upstream Status: iproute2.git commit 620fc6696d4f4 - -commit 620fc6696d4f4e9ad540a45892873b0382907739 -Author: Stephen Hemminger -Date: Thu Aug 3 16:10:18 2017 -0700 - - tc: fix m_simple usage - - Signed-off-by: Stephen Hemminger ---- - tc/m_simple.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/tc/m_simple.c b/tc/m_simple.c -index ab633849f7b45..65e48addf161b 100644 ---- a/tc/m_simple.c -+++ b/tc/m_simple.c -@@ -83,8 +83,8 @@ static void explain(void) - { - fprintf(stderr, "Usage:... simple [sdata STRING] [index INDEX] [CONTROL]\n"); - fprintf(stderr, "\tSTRING being an arbitrary string\n" -- "\tINDEX := optional index value used\n"); -- "\tCONTROL := reclassify|pipe|drop|continue|ok\n" -+ "\tINDEX := optional index value used\n" -+ "\tCONTROL := reclassify|pipe|drop|continue|ok\n"); - } - - static void usage(void) --- -2.21.0 - diff --git a/SOURCES/0005-bpf-Make-bytecode-file-reading-a-little-more-robust.patch b/SOURCES/0005-bpf-Make-bytecode-file-reading-a-little-more-robust.patch deleted file mode 100644 index 5563224..0000000 --- a/SOURCES/0005-bpf-Make-bytecode-file-reading-a-little-more-robust.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 91cda136ef27402256dbf85434374b43ab52d932 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Fri, 11 Aug 2017 11:15:30 +0200 -Subject: [PATCH] bpf: Make bytecode-file reading a little more robust - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1477491 -Upstream Status: iproute2.git commit 3da3ebfca85b8 - -commit 3da3ebfca85b8f1e8252b898453d8cb383c5c398 -Author: Phil Sutter -Date: Wed Aug 2 14:57:56 2017 +0200 - - bpf: Make bytecode-file reading a little more robust - - bpf_parse_string() will now correctly handle: - - - Extraneous whitespace, - - OPs on multiple lines and - - overlong file names. - - The added feature of allowing to have OPs on multiple lines (like e.g. - tcpdump prints them) is rather a side effect of fixing detection of - malformed bytecode files having random content on a second line, like - e.g.: - - | 4,40 0 0 12,21 0 1 2048,6 0 0 262144,6 0 0 0 - | foobar - - Cc: Daniel Borkmann - Signed-off-by: Phil Sutter - Acked-by: Daniel Borkmann ---- - lib/bpf.c | 32 ++++++++++++++++++++++++-------- - 1 file changed, 24 insertions(+), 8 deletions(-) - -diff --git a/lib/bpf.c b/lib/bpf.c -index 04ee1ab9b2bc3..73dac5c37cc91 100644 ---- a/lib/bpf.c -+++ b/lib/bpf.c -@@ -160,11 +160,11 @@ static int bpf_parse_string(char *arg, bool from_file, __u16 *bpf_len, - - if (from_file) { - size_t tmp_len, op_len = sizeof("65535 255 255 4294967295,"); -- char *tmp_string, *last; -+ char *tmp_string, *pos, c, c_prev = ' '; - FILE *fp; - - tmp_len = sizeof("4096,") + BPF_MAXINSNS * op_len; -- tmp_string = calloc(1, tmp_len); -+ tmp_string = pos = calloc(1, tmp_len); - if (tmp_string == NULL) - return -ENOMEM; - -@@ -175,17 +175,33 @@ static int bpf_parse_string(char *arg, bool from_file, __u16 *bpf_len, - return -ENOENT; - } - -- if (!fgets(tmp_string, tmp_len, fp)) { -+ while ((c = fgetc(fp)) != EOF) { -+ switch (c) { -+ case '\n': -+ if (c_prev != ',') -+ *(pos++) = ','; -+ break; -+ case ' ': -+ case '\t': -+ if (c_prev != ' ') -+ *(pos++) = c; -+ break; -+ default: -+ *(pos++) = c; -+ } -+ if (pos - tmp_string == tmp_len) -+ break; -+ c_prev = c; -+ } -+ -+ if (!feof(fp)) { - free(tmp_string); - fclose(fp); -- return -EIO; -+ return -E2BIG; - } - - fclose(fp); -- -- last = &tmp_string[strlen(tmp_string) - 1]; -- if (*last == '\n') -- *last = 0; -+ *pos = 0; - - *need_release = true; - *bpf_string = tmp_string; --- -2.21.0 - diff --git a/SOURCES/0005-man-Clarify-idleslope-calculation-for-tc-cbs.patch b/SOURCES/0005-man-Clarify-idleslope-calculation-for-tc-cbs.patch new file mode 100644 index 0000000..8d27903 --- /dev/null +++ b/SOURCES/0005-man-Clarify-idleslope-calculation-for-tc-cbs.patch @@ -0,0 +1,55 @@ +From b8864890b18903936a68cda65ed1401703a2c67f Mon Sep 17 00:00:00 2001 +From: Andrea Claudi +Date: Tue, 21 Apr 2020 14:32:49 +0200 +Subject: [PATCH] man: Clarify idleslope calculation for tc-cbs + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1557461 +Upstream Status: iproute2.git commit 1915af404fdbf + +commit 1915af404fdbfbfef915078cec57d7425f500dd2 +Author: Jesus Sanchez-Palencia +Date: Fri Nov 10 14:34:36 2017 -0800 + + man: Clarify idleslope calculation for tc-cbs + + In order to calculate the idleSlope parameter of CBS correctly, users + must take into account the entire packet size, including the overhead + from all layers. + + Add some more details to the man page to clarify that, giving one + simple example and pointing users to the correct 802.1Q section for + further clarifications if needed. + + Signed-off-by: Jesus Sanchez-Palencia +--- + man/man8/tc-cbs.8 | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/man/man8/tc-cbs.8 b/man/man8/tc-cbs.8 +index 97e00c84ded16..32e1e0d4089fb 100644 +--- a/man/man8/tc-cbs.8 ++++ b/man/man8/tc-cbs.8 +@@ -43,7 +43,19 @@ second) when there is at least one packet waiting for transmission. + Packets are transmitted when the current value of credits is equal or + greater than zero. When there is no packet to be transmitted the + amount of credits is set to zero. This is the main tunable of the CBS +-algorithm. ++algorithm and represents the bandwidth that will be consumed. ++Note that when calculating idleslope, the entire packet size must be ++considered, including headers from all layers (i.e. MAC framing and any ++overhead from the physical layer), as described by IEEE 802.1Q-2014 ++section 34.4. ++ ++As an example, for an ethernet frame carrying 284 bytes of payload, ++and with no VLAN tags, you must add 14 bytes for the Ethernet headers, ++4 bytes for the Frame check sequence (CRC), and 20 bytes for the L1 ++overhead: 12 bytes of interpacket gap, 7 bytes of preamble and 1 byte ++of start of frame delimiter. That results in 322 bytes for the total ++packet size, which is then used for calculating the idleslope. ++ + .TP + sendslope + Sendslope is the rate of credits that is depleted (it should be a +-- +2.25.3 + diff --git a/SOURCES/0006-Update-kernel-headers.patch b/SOURCES/0006-Update-kernel-headers.patch new file mode 100644 index 0000000..127d596 --- /dev/null +++ b/SOURCES/0006-Update-kernel-headers.patch @@ -0,0 +1,364 @@ +From a99698f738e60e524c9ad98bebf8753d675c0b16 Mon Sep 17 00:00:00 2001 +From: Andrea Claudi +Date: Tue, 21 Apr 2020 14:53:23 +0200 +Subject: [PATCH] Update kernel headers + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1637437 +Upstream Status: iproute2.git commit 74eb09ad5669b + +commit 74eb09ad5669bb24ae4c37e712f9c28bc88c9231 +Author: David Ahern +Date: Sun Aug 12 14:23:31 2018 -0700 + + Update kernel headers + + Update kernel headers to commit + 78cbac647e61 (Merge branch 'ip-faster-in-order-IP-fragments'") + + Signed-off-by: David Ahern +--- + include/uapi/linux/bpf.h | 41 +++++++++++++++++++++++++++++++++++- + include/uapi/linux/btf.h | 2 +- + include/uapi/linux/can.h | 2 +- + include/uapi/linux/if_link.h | 12 +++++++++++ + include/uapi/linux/ip.h | 1 + + include/uapi/linux/l2tp.h | 15 +++++++------ + include/uapi/linux/netconf.h | 1 + + include/uapi/linux/pkt_cls.h | 32 ++++++++++++++++++++++++++-- + include/uapi/linux/tcp.h | 10 ++++++++- + include/uapi/linux/xfrm.h | 5 ++++- + 10 files changed, 107 insertions(+), 14 deletions(-) + +diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h +index b9a63672b297c..4bbe7e5d4c800 100644 +--- a/include/uapi/linux/bpf.h ++++ b/include/uapi/linux/bpf.h +@@ -75,6 +75,11 @@ struct bpf_lpm_trie_key { + __u8 data[0]; /* Arbitrary size */ + }; + ++struct bpf_cgroup_storage_key { ++ __u64 cgroup_inode_id; /* cgroup inode id */ ++ __u32 attach_type; /* program attach type */ ++}; ++ + /* BPF syscall commands, see bpf(2) man-page for details. */ + enum bpf_cmd { + BPF_MAP_CREATE, +@@ -120,6 +125,7 @@ enum bpf_map_type { + BPF_MAP_TYPE_CPUMAP, + BPF_MAP_TYPE_XSKMAP, + BPF_MAP_TYPE_SOCKHASH, ++ BPF_MAP_TYPE_CGROUP_STORAGE, + }; + + enum bpf_prog_type { +@@ -1371,6 +1377,20 @@ union bpf_attr { + * A 8-byte long non-decreasing number on success, or 0 if the + * socket field is missing inside *skb*. + * ++ * u64 bpf_get_socket_cookie(struct bpf_sock_addr *ctx) ++ * Description ++ * Equivalent to bpf_get_socket_cookie() helper that accepts ++ * *skb*, but gets socket from **struct bpf_sock_addr** contex. ++ * Return ++ * A 8-byte long non-decreasing number. ++ * ++ * u64 bpf_get_socket_cookie(struct bpf_sock_ops *ctx) ++ * Description ++ * Equivalent to bpf_get_socket_cookie() helper that accepts ++ * *skb*, but gets socket from **struct bpf_sock_ops** contex. ++ * Return ++ * A 8-byte long non-decreasing number. ++ * + * u32 bpf_get_socket_uid(struct sk_buff *skb) + * Return + * The owner UID of the socket associated to *skb*. If the socket +@@ -2075,6 +2095,24 @@ union bpf_attr { + * Return + * A 64-bit integer containing the current cgroup id based + * on the cgroup within which the current task is running. ++ * ++ * void* get_local_storage(void *map, u64 flags) ++ * Description ++ * Get the pointer to the local storage area. ++ * The type and the size of the local storage is defined ++ * by the *map* argument. ++ * The *flags* meaning is specific for each map type, ++ * and has to be 0 for cgroup local storage. ++ * ++ * Depending on the bpf program type, a local storage area ++ * can be shared between multiple instances of the bpf program, ++ * running simultaneously. ++ * ++ * A user should care about the synchronization by himself. ++ * For example, by using the BPF_STX_XADD instruction to alter ++ * the shared data. ++ * Return ++ * Pointer to the local storage area. + */ + #define __BPF_FUNC_MAPPER(FN) \ + FN(unspec), \ +@@ -2157,7 +2195,8 @@ union bpf_attr { + FN(rc_repeat), \ + FN(rc_keydown), \ + FN(skb_cgroup_id), \ +- FN(get_current_cgroup_id), ++ FN(get_current_cgroup_id), \ ++ FN(get_local_storage), + + /* integer value in 'imm' field of BPF_CALL instruction selects which helper + * function eBPF program intends to call +diff --git a/include/uapi/linux/btf.h b/include/uapi/linux/btf.h +index 5dd580a6726cd..8d2a8ffad56f9 100644 +--- a/include/uapi/linux/btf.h ++++ b/include/uapi/linux/btf.h +@@ -76,7 +76,7 @@ struct btf_type { + */ + #define BTF_INT_ENCODING(VAL) (((VAL) & 0x0f000000) >> 24) + #define BTF_INT_OFFSET(VAL) (((VAL & 0x00ff0000)) >> 16) +-#define BTF_INT_BITS(VAL) ((VAL) & 0x0000ffff) ++#define BTF_INT_BITS(VAL) ((VAL) & 0x000000ff) + + /* Attributes stored in the BTF_INT_ENCODING */ + #define BTF_INT_SIGNED (1 << 0) +diff --git a/include/uapi/linux/can.h b/include/uapi/linux/can.h +index 4d1ab8e7a4984..9009f0b6505cf 100644 +--- a/include/uapi/linux/can.h ++++ b/include/uapi/linux/can.h +@@ -77,7 +77,7 @@ typedef __u32 canid_t; + /* + * Controller Area Network Error Message Frame Mask structure + * +- * bit 0-28 : error class mask (see include/linux/can/error.h) ++ * bit 0-28 : error class mask (see include/uapi/linux/can/error.h) + * bit 29-31 : set to zero + */ + typedef __u32 can_err_mask_t; +diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h +index 1c64ed45353d5..1caf56584a690 100644 +--- a/include/uapi/linux/if_link.h ++++ b/include/uapi/linux/if_link.h +@@ -164,6 +164,8 @@ enum { + IFLA_CARRIER_UP_COUNT, + IFLA_CARRIER_DOWN_COUNT, + IFLA_NEW_IFINDEX, ++ IFLA_MIN_MTU, ++ IFLA_MAX_MTU, + __IFLA_MAX + }; + +@@ -457,6 +459,16 @@ enum { + + #define IFLA_MACSEC_MAX (__IFLA_MACSEC_MAX - 1) + ++/* XFRM section */ ++enum { ++ IFLA_XFRM_UNSPEC, ++ IFLA_XFRM_LINK, ++ IFLA_XFRM_IF_ID, ++ __IFLA_XFRM_MAX ++}; ++ ++#define IFLA_XFRM_MAX (__IFLA_XFRM_MAX - 1) ++ + enum macsec_validation_type { + MACSEC_VALIDATE_DISABLED = 0, + MACSEC_VALIDATE_CHECK = 1, +diff --git a/include/uapi/linux/ip.h b/include/uapi/linux/ip.h +index 883fd334496ab..f4ecd2fab84b5 100644 +--- a/include/uapi/linux/ip.h ++++ b/include/uapi/linux/ip.h +@@ -168,6 +168,7 @@ enum + IPV4_DEVCONF_IGNORE_ROUTES_WITH_LINKDOWN, + IPV4_DEVCONF_DROP_UNICAST_IN_L2_MULTICAST, + IPV4_DEVCONF_DROP_GRATUITOUS_ARP, ++ IPV4_DEVCONF_BC_FORWARDING, + __IPV4_DEVCONF_MAX + }; + +diff --git a/include/uapi/linux/l2tp.h b/include/uapi/linux/l2tp.h +index 1fe52a7dd4a94..131c3a26c2959 100644 +--- a/include/uapi/linux/l2tp.h ++++ b/include/uapi/linux/l2tp.h +@@ -60,14 +60,14 @@ struct sockaddr_l2tpip6 { + /* + * Commands. + * Valid TLVs of each command are:- +- * TUNNEL_CREATE - CONN_ID, pw_type, netns, ifname, ipinfo, udpinfo, udpcsum, vlanid ++ * TUNNEL_CREATE - CONN_ID, pw_type, netns, ifname, ipinfo, udpinfo, udpcsum + * TUNNEL_DELETE - CONN_ID + * TUNNEL_MODIFY - CONN_ID, udpcsum + * TUNNEL_GETSTATS - CONN_ID, (stats) + * TUNNEL_GET - CONN_ID, (...) +- * SESSION_CREATE - SESSION_ID, PW_TYPE, data_seq, cookie, peer_cookie, l2spec ++ * SESSION_CREATE - SESSION_ID, PW_TYPE, cookie, peer_cookie, l2spec + * SESSION_DELETE - SESSION_ID +- * SESSION_MODIFY - SESSION_ID, data_seq ++ * SESSION_MODIFY - SESSION_ID + * SESSION_GET - SESSION_ID, (...) + * SESSION_GETSTATS - SESSION_ID, (stats) + * +@@ -95,7 +95,7 @@ enum { + L2TP_ATTR_PW_TYPE, /* u16, enum l2tp_pwtype */ + L2TP_ATTR_ENCAP_TYPE, /* u16, enum l2tp_encap_type */ + L2TP_ATTR_OFFSET, /* u16 (not used) */ +- L2TP_ATTR_DATA_SEQ, /* u16 */ ++ L2TP_ATTR_DATA_SEQ, /* u16 (not used) */ + L2TP_ATTR_L2SPEC_TYPE, /* u8, enum l2tp_l2spec_type */ + L2TP_ATTR_L2SPEC_LEN, /* u8 (not used) */ + L2TP_ATTR_PROTO_VERSION, /* u8 */ +@@ -105,7 +105,7 @@ enum { + L2TP_ATTR_SESSION_ID, /* u32 */ + L2TP_ATTR_PEER_SESSION_ID, /* u32 */ + L2TP_ATTR_UDP_CSUM, /* u8 */ +- L2TP_ATTR_VLAN_ID, /* u16 */ ++ L2TP_ATTR_VLAN_ID, /* u16 (not used) */ + L2TP_ATTR_COOKIE, /* 0, 4 or 8 bytes */ + L2TP_ATTR_PEER_COOKIE, /* 0, 4 or 8 bytes */ + L2TP_ATTR_DEBUG, /* u32, enum l2tp_debug_flags */ +@@ -119,8 +119,8 @@ enum { + L2TP_ATTR_IP_DADDR, /* u32 */ + L2TP_ATTR_UDP_SPORT, /* u16 */ + L2TP_ATTR_UDP_DPORT, /* u16 */ +- L2TP_ATTR_MTU, /* u16 */ +- L2TP_ATTR_MRU, /* u16 */ ++ L2TP_ATTR_MTU, /* u16 (not used) */ ++ L2TP_ATTR_MRU, /* u16 (not used) */ + L2TP_ATTR_STATS, /* nested */ + L2TP_ATTR_IP6_SADDR, /* struct in6_addr */ + L2TP_ATTR_IP6_DADDR, /* struct in6_addr */ +@@ -169,6 +169,7 @@ enum l2tp_encap_type { + L2TP_ENCAPTYPE_IP, + }; + ++/* For L2TP_ATTR_DATA_SEQ. Unused. */ + enum l2tp_seqmode { + L2TP_SEQ_NONE = 0, + L2TP_SEQ_IP = 1, +diff --git a/include/uapi/linux/netconf.h b/include/uapi/linux/netconf.h +index 86ac1eb4c06e3..229e885179ad6 100644 +--- a/include/uapi/linux/netconf.h ++++ b/include/uapi/linux/netconf.h +@@ -18,6 +18,7 @@ enum { + NETCONFA_PROXY_NEIGH, + NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN, + NETCONFA_INPUT, ++ NETCONFA_BC_FORWARDING, + __NETCONFA_MAX + }; + #define NETCONFA_MAX (__NETCONFA_MAX - 1) +diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h +index b4512254036b9..be382fb0592d8 100644 +--- a/include/uapi/linux/pkt_cls.h ++++ b/include/uapi/linux/pkt_cls.h +@@ -45,6 +45,7 @@ enum { + * the skb and act like everything + * is alright. + */ ++#define TC_ACT_VALUE_MAX TC_ACT_TRAP + + /* There is a special kind of actions called "extended actions", + * which need a value parameter. These have a local opcode located in +@@ -55,11 +56,12 @@ enum { + #define __TC_ACT_EXT_SHIFT 28 + #define __TC_ACT_EXT(local) ((local) << __TC_ACT_EXT_SHIFT) + #define TC_ACT_EXT_VAL_MASK ((1 << __TC_ACT_EXT_SHIFT) - 1) +-#define TC_ACT_EXT_CMP(combined, opcode) \ +- (((combined) & (~TC_ACT_EXT_VAL_MASK)) == opcode) ++#define TC_ACT_EXT_OPCODE(combined) ((combined) & (~TC_ACT_EXT_VAL_MASK)) ++#define TC_ACT_EXT_CMP(combined, opcode) (TC_ACT_EXT_OPCODE(combined) == opcode) + + #define TC_ACT_JUMP __TC_ACT_EXT(1) + #define TC_ACT_GOTO_CHAIN __TC_ACT_EXT(2) ++#define TC_ACT_EXT_OPCODE_MAX TC_ACT_GOTO_CHAIN + + /* Action type identifiers*/ + enum { +@@ -478,11 +480,37 @@ enum { + TCA_FLOWER_KEY_ENC_IP_TTL, /* u8 */ + TCA_FLOWER_KEY_ENC_IP_TTL_MASK, /* u8 */ + ++ TCA_FLOWER_KEY_ENC_OPTS, ++ TCA_FLOWER_KEY_ENC_OPTS_MASK, ++ + __TCA_FLOWER_MAX, + }; + + #define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1) + ++enum { ++ TCA_FLOWER_KEY_ENC_OPTS_UNSPEC, ++ TCA_FLOWER_KEY_ENC_OPTS_GENEVE, /* Nested ++ * TCA_FLOWER_KEY_ENC_OPT_GENEVE_ ++ * attributes ++ */ ++ __TCA_FLOWER_KEY_ENC_OPTS_MAX, ++}; ++ ++#define TCA_FLOWER_KEY_ENC_OPTS_MAX (__TCA_FLOWER_KEY_ENC_OPTS_MAX - 1) ++ ++enum { ++ TCA_FLOWER_KEY_ENC_OPT_GENEVE_UNSPEC, ++ TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS, /* u16 */ ++ TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE, /* u8 */ ++ TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA, /* 4 to 128 bytes */ ++ ++ __TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX, ++}; ++ ++#define TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX \ ++ (__TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX - 1) ++ + enum { + TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0), + TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST = (1 << 1), +diff --git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h +index 2e766cf303fbe..d4db674df06b4 100644 +--- a/include/uapi/linux/tcp.h ++++ b/include/uapi/linux/tcp.h +@@ -231,6 +231,11 @@ struct tcp_info { + + __u32 tcpi_delivered; + __u32 tcpi_delivered_ce; ++ ++ __u64 tcpi_bytes_sent; /* RFC4898 tcpEStatsPerfHCDataOctetsOut */ ++ __u64 tcpi_bytes_retrans; /* RFC4898 tcpEStatsPerfOctetsRetrans */ ++ __u32 tcpi_dsack_dups; /* RFC4898 tcpEStatsStackDSACKDups */ ++ __u32 tcpi_reord_seen; /* reordering events seen */ + }; + + /* netlink attributes types for SCM_TIMESTAMPING_OPT_STATS */ +@@ -253,7 +258,10 @@ enum { + TCP_NLA_SND_SSTHRESH, /* Slow start size threshold */ + TCP_NLA_DELIVERED, /* Data pkts delivered incl. out-of-order */ + TCP_NLA_DELIVERED_CE, /* Like above but only ones w/ CE marks */ +- ++ TCP_NLA_BYTES_SENT, /* Data bytes sent including retransmission */ ++ TCP_NLA_BYTES_RETRANS, /* Data bytes retransmitted */ ++ TCP_NLA_DSACK_DUPS, /* DSACK blocks received */ ++ TCP_NLA_REORD_SEEN, /* reordering events seen */ + }; + + /* for TCP_MD5SIG socket option */ +diff --git a/include/uapi/linux/xfrm.h b/include/uapi/linux/xfrm.h +index 93fb1920101a2..5cdda9d37bdc0 100644 +--- a/include/uapi/linux/xfrm.h ++++ b/include/uapi/linux/xfrm.h +@@ -305,9 +305,12 @@ enum xfrm_attr_type_t { + XFRMA_ADDRESS_FILTER, /* struct xfrm_address_filter */ + XFRMA_PAD, + XFRMA_OFFLOAD_DEV, /* struct xfrm_state_offload */ +- XFRMA_OUTPUT_MARK, /* __u32 */ ++ XFRMA_SET_MARK, /* __u32 */ ++ XFRMA_SET_MARK_MASK, /* __u32 */ ++ XFRMA_IF_ID, /* __u32 */ + __XFRMA_MAX + ++#define XFRMA_OUTPUT_MARK XFRMA_SET_MARK /* Compatibility */ + #define XFRMA_MAX (__XFRMA_MAX - 1) + }; + +-- +2.25.3 + diff --git a/SOURCES/0006-ss-Fix-for-added-diag-support-check.patch b/SOURCES/0006-ss-Fix-for-added-diag-support-check.patch deleted file mode 100644 index 009cc5f..0000000 --- a/SOURCES/0006-ss-Fix-for-added-diag-support-check.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 2dc48cc4101b9788dcafd38b07a82f8c91b4d3f6 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 31 Aug 2017 14:23:11 +0200 -Subject: [PATCH] ss: Fix for added diag support check - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1487152 -Upstream Status: iproute2.git commit 6c6bbc30f4e7f - -commit 6c6bbc30f4e7fedc74381627f7ec86d26050b404 -Author: Phil Sutter -Date: Mon Aug 28 19:31:22 2017 +0200 - - ss: Fix for added diag support check - - Commit 9f66764e308e9 ("libnetlink: Add test for error code returned from - netlink reply") changed rtnl_dump_filter_l() to return an error in case - NLMSG_DONE would contain one, even if it was ENOENT. - - This in turn breaks ss when it tries to dump DCCP sockets on a system - without support for it: The function tcp_show(), which is shared between - TCP and DCCP, will start parsing /proc since inet_show_netlink() returns - an error - yet it parses /proc/net/tcp which doesn't make sense for DCCP - sockets at all. - - On my system, a call to 'ss' without further arguments prints the list - of connected TCP sockets twice. - - Fix this by introducing a dedicated function dccp_show() which does not - have a fallback to /proc, just like sctp_show(). And since tcp_show() - is no longer "multi-purpose", drop it's socktype parameter. - - Fixes: 9f66764e308e9 ("libnetlink: Add test for error code returned from netlink reply") - Signed-off-by: Phil Sutter ---- - misc/ss.c | 20 ++++++++++++++++---- - 1 file changed, 16 insertions(+), 4 deletions(-) - -diff --git a/misc/ss.c b/misc/ss.c -index 12763c9f42686..b84baf3b57fe5 100644 ---- a/misc/ss.c -+++ b/misc/ss.c -@@ -2735,7 +2735,7 @@ static int tcp_show_netlink_file(struct filter *f) - } - } - --static int tcp_show(struct filter *f, int socktype) -+static int tcp_show(struct filter *f) - { - FILE *fp = NULL; - char *buf = NULL; -@@ -2750,7 +2750,7 @@ static int tcp_show(struct filter *f, int socktype) - return tcp_show_netlink_file(f); - - if (!getenv("PROC_NET_TCP") && !getenv("PROC_ROOT") -- && inet_show_netlink(f, NULL, socktype) == 0) -+ && inet_show_netlink(f, NULL, IPPROTO_TCP) == 0) - return 0; - - /* Sigh... We have to parse /proc/net/tcp... */ -@@ -2818,6 +2818,18 @@ outerr: - } while (0); - } - -+static int dccp_show(struct filter *f) -+{ -+ if (!filter_af_get(f, AF_INET) && !filter_af_get(f, AF_INET6)) -+ return 0; -+ -+ if (!getenv("PROC_NET_DCCP") && !getenv("PROC_ROOT") -+ && inet_show_netlink(f, NULL, IPPROTO_DCCP) == 0) -+ return 0; -+ -+ return 0; -+} -+ - static int sctp_show(struct filter *f) - { - if (!filter_af_get(f, AF_INET) && !filter_af_get(f, AF_INET6)) -@@ -4368,9 +4380,9 @@ int main(int argc, char *argv[]) - if (current_filter.dbs & (1< -Date: Fri, 1 Sep 2017 13:05:45 +0200 -Subject: [PATCH] tc-simple.8: Fix reference to non-existing tc-actions.8 - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1477523 -Upstream Status: RHEL-only - -The referenced man page doesn't exist in RHEL iproute package, so better -refer to an existing one which also contains the CONTROL value -description. ---- - man/man8/tc-simple.8 | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/man/man8/tc-simple.8 b/man/man8/tc-simple.8 -index 7363ab563e189..a0deb0b13a82f 100644 ---- a/man/man8/tc-simple.8 -+++ b/man/man8/tc-simple.8 -@@ -36,7 +36,7 @@ Indicate how - should proceed after executing the action. For a description of the possible - .I CONTROL - values, see --.BR tc-actions (8). -+.BR tc-pedit (8). - .SH EXAMPLES - The following example makes the kernel yell "Incoming ICMP!" every time it sees - an incoming ICMP on eth0. Steps are: --- -2.21.0 - diff --git a/SOURCES/0007-uapi-update-bpf-headers.patch b/SOURCES/0007-uapi-update-bpf-headers.patch new file mode 100644 index 0000000..668c595 --- /dev/null +++ b/SOURCES/0007-uapi-update-bpf-headers.patch @@ -0,0 +1,124 @@ +From 6bc664d133faa4c04b5ad4fdcdca06f68616783e Mon Sep 17 00:00:00 2001 +From: Andrea Claudi +Date: Tue, 21 Apr 2020 14:53:23 +0200 +Subject: [PATCH] uapi: update bpf headers + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1637437 +Upstream Status: iproute2.git commit 0ebb420929dd1 + +commit 0ebb420929dd18562a1f76e9d09015719b913f75 +Author: Stephen Hemminger +Date: Thu Aug 30 07:55:49 2018 -0700 + + uapi: update bpf headers + + Signed-off-by: Stephen Hemminger +--- + include/uapi/linux/bpf.h | 56 +++++++++++++++++++++++++++++++++++++++- + 1 file changed, 55 insertions(+), 1 deletion(-) + +diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h +index 4bbe7e5d4c800..8eb284d2f1acb 100644 +--- a/include/uapi/linux/bpf.h ++++ b/include/uapi/linux/bpf.h +@@ -126,6 +126,7 @@ enum bpf_map_type { + BPF_MAP_TYPE_XSKMAP, + BPF_MAP_TYPE_SOCKHASH, + BPF_MAP_TYPE_CGROUP_STORAGE, ++ BPF_MAP_TYPE_REUSEPORT_SOCKARRAY, + }; + + enum bpf_prog_type { +@@ -150,6 +151,7 @@ enum bpf_prog_type { + BPF_PROG_TYPE_CGROUP_SOCK_ADDR, + BPF_PROG_TYPE_LWT_SEG6LOCAL, + BPF_PROG_TYPE_LIRC_MODE2, ++ BPF_PROG_TYPE_SK_REUSEPORT, + }; + + enum bpf_attach_type { +@@ -2091,6 +2093,24 @@ union bpf_attr { + * Return + * The id is returned or 0 in case the id could not be retrieved. + * ++ * u64 bpf_skb_ancestor_cgroup_id(struct sk_buff *skb, int ancestor_level) ++ * Description ++ * Return id of cgroup v2 that is ancestor of cgroup associated ++ * with the *skb* at the *ancestor_level*. The root cgroup is at ++ * *ancestor_level* zero and each step down the hierarchy ++ * increments the level. If *ancestor_level* == level of cgroup ++ * associated with *skb*, then return value will be same as that ++ * of **bpf_skb_cgroup_id**\ (). ++ * ++ * The helper is useful to implement policies based on cgroups ++ * that are upper in hierarchy than immediate cgroup associated ++ * with *skb*. ++ * ++ * The format of returned id and helper limitations are same as in ++ * **bpf_skb_cgroup_id**\ (). ++ * Return ++ * The id is returned or 0 in case the id could not be retrieved. ++ * + * u64 bpf_get_current_cgroup_id(void) + * Return + * A 64-bit integer containing the current cgroup id based +@@ -2113,6 +2133,14 @@ union bpf_attr { + * the shared data. + * Return + * Pointer to the local storage area. ++ * ++ * int bpf_sk_select_reuseport(struct sk_reuseport_md *reuse, struct bpf_map *map, void *key, u64 flags) ++ * Description ++ * Select a SO_REUSEPORT sk from a BPF_MAP_TYPE_REUSEPORT_ARRAY map ++ * It checks the selected sk is matching the incoming ++ * request in the skb. ++ * Return ++ * 0 on success, or a negative error in case of failure. + */ + #define __BPF_FUNC_MAPPER(FN) \ + FN(unspec), \ +@@ -2196,7 +2224,9 @@ union bpf_attr { + FN(rc_keydown), \ + FN(skb_cgroup_id), \ + FN(get_current_cgroup_id), \ +- FN(get_local_storage), ++ FN(get_local_storage), \ ++ FN(sk_select_reuseport), \ ++ FN(skb_ancestor_cgroup_id), + + /* integer value in 'imm' field of BPF_CALL instruction selects which helper + * function eBPF program intends to call +@@ -2413,6 +2443,30 @@ struct sk_msg_md { + __u32 local_port; /* stored in host byte order */ + }; + ++struct sk_reuseport_md { ++ /* ++ * Start of directly accessible data. It begins from ++ * the tcp/udp header. ++ */ ++ void *data; ++ void *data_end; /* End of directly accessible data */ ++ /* ++ * Total length of packet (starting from the tcp/udp header). ++ * Note that the directly accessible bytes (data_end - data) ++ * could be less than this "len". Those bytes could be ++ * indirectly read by a helper "bpf_skb_load_bytes()". ++ */ ++ __u32 len; ++ /* ++ * Eth protocol in the mac header (network byte order). e.g. ++ * ETH_P_IP(0x0800) and ETH_P_IPV6(0x86DD) ++ */ ++ __u32 eth_protocol; ++ __u32 ip_protocol; /* IP protocol. e.g. IPPROTO_TCP, IPPROTO_UDP */ ++ __u32 bind_inany; /* Is sock bound to an INANY address? */ ++ __u32 hash; /* A hash of the packet 4 tuples */ ++}; ++ + #define BPF_TAG_SIZE 8 + + struct bpf_prog_info { +-- +2.25.3 + diff --git a/SOURCES/0008-Update-kernel-headers.patch b/SOURCES/0008-Update-kernel-headers.patch new file mode 100644 index 0000000..91a3ef9 --- /dev/null +++ b/SOURCES/0008-Update-kernel-headers.patch @@ -0,0 +1,232 @@ +From 821d2b6a1350f69b350a3413fc08845f68788077 Mon Sep 17 00:00:00 2001 +From: Andrea Claudi +Date: Tue, 21 Apr 2020 14:53:23 +0200 +Subject: [PATCH] Update kernel headers + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1637437 +Upstream Status: iproute2.git commit d9c0be4e97954 + +commit d9c0be4e9795473a73793058674c34d56cdb5eea +Author: David Ahern +Date: Fri Sep 28 10:51:15 2018 -0700 + + Update kernel headers + + Update kernel headers to commit + a804e5e218754 ("selftests: forwarding: test for bridge sticky flag") + + Signed-off-by: David Ahern +--- + include/uapi/linux/bpf.h | 26 ++++++++++++++++++++++++++ + include/uapi/linux/gen_stats.h | 1 + + include/uapi/linux/if_addr.h | 1 + + include/uapi/linux/if_arp.h | 18 +++++++++--------- + include/uapi/linux/if_link.h | 2 ++ + include/uapi/linux/if_packet.h | 1 + + include/uapi/linux/in6.h | 1 + + include/uapi/linux/neighbour.h | 1 + + include/uapi/linux/pkt_cls.h | 2 ++ + include/uapi/linux/pkt_sched.h | 6 +++--- + 10 files changed, 47 insertions(+), 12 deletions(-) + +diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h +index 8eb284d2f1acb..abb7f7748c2de 100644 +--- a/include/uapi/linux/bpf.h ++++ b/include/uapi/linux/bpf.h +@@ -152,6 +152,7 @@ enum bpf_prog_type { + BPF_PROG_TYPE_LWT_SEG6LOCAL, + BPF_PROG_TYPE_LIRC_MODE2, + BPF_PROG_TYPE_SK_REUSEPORT, ++ BPF_PROG_TYPE_FLOW_DISSECTOR, + }; + + enum bpf_attach_type { +@@ -172,6 +173,7 @@ enum bpf_attach_type { + BPF_CGROUP_UDP4_SENDMSG, + BPF_CGROUP_UDP6_SENDMSG, + BPF_LIRC_MODE2, ++ BPF_FLOW_DISSECTOR, + __MAX_BPF_ATTACH_TYPE + }; + +@@ -2333,6 +2335,7 @@ struct __sk_buff { + /* ... here. */ + + __u32 data_meta; ++ struct bpf_flow_keys *flow_keys; + }; + + struct bpf_tunnel_key { +@@ -2778,4 +2781,27 @@ enum bpf_task_fd_type { + BPF_FD_TYPE_URETPROBE, /* filename + offset */ + }; + ++struct bpf_flow_keys { ++ __u16 nhoff; ++ __u16 thoff; ++ __u16 addr_proto; /* ETH_P_* of valid addrs */ ++ __u8 is_frag; ++ __u8 is_first_frag; ++ __u8 is_encap; ++ __u8 ip_proto; ++ __be16 n_proto; ++ __be16 sport; ++ __be16 dport; ++ union { ++ struct { ++ __be32 ipv4_src; ++ __be32 ipv4_dst; ++ }; ++ struct { ++ __u32 ipv6_src[4]; /* in6_addr; network order */ ++ __u32 ipv6_dst[4]; /* in6_addr; network order */ ++ }; ++ }; ++}; ++ + #endif /* __LINUX_BPF_H__ */ +diff --git a/include/uapi/linux/gen_stats.h b/include/uapi/linux/gen_stats.h +index 24a861c0d29d3..065408e16a807 100644 +--- a/include/uapi/linux/gen_stats.h ++++ b/include/uapi/linux/gen_stats.h +@@ -12,6 +12,7 @@ enum { + TCA_STATS_APP, + TCA_STATS_RATE_EST64, + TCA_STATS_PAD, ++ TCA_STATS_BASIC_HW, + __TCA_STATS_MAX, + }; + #define TCA_STATS_MAX (__TCA_STATS_MAX - 1) +diff --git a/include/uapi/linux/if_addr.h b/include/uapi/linux/if_addr.h +index a924606f36e56..c4dd87f9b44a1 100644 +--- a/include/uapi/linux/if_addr.h ++++ b/include/uapi/linux/if_addr.h +@@ -34,6 +34,7 @@ enum { + IFA_MULTICAST, + IFA_FLAGS, + IFA_RT_PRIORITY, /* u32, priority/metric for prefix route */ ++ IFA_TARGET_NETNSID, + __IFA_MAX, + }; + +diff --git a/include/uapi/linux/if_arp.h b/include/uapi/linux/if_arp.h +index cd136a6f821bb..dbfbc227deb8e 100644 +--- a/include/uapi/linux/if_arp.h ++++ b/include/uapi/linux/if_arp.h +@@ -114,18 +114,18 @@ + + /* ARP ioctl request. */ + struct arpreq { +- struct sockaddr arp_pa; /* protocol address */ +- struct sockaddr arp_ha; /* hardware address */ +- int arp_flags; /* flags */ +- struct sockaddr arp_netmask; /* netmask (only for proxy arps) */ +- char arp_dev[16]; ++ struct sockaddr arp_pa; /* protocol address */ ++ struct sockaddr arp_ha; /* hardware address */ ++ int arp_flags; /* flags */ ++ struct sockaddr arp_netmask; /* netmask (only for proxy arps) */ ++ char arp_dev[IFNAMSIZ]; + }; + + struct arpreq_old { +- struct sockaddr arp_pa; /* protocol address */ +- struct sockaddr arp_ha; /* hardware address */ +- int arp_flags; /* flags */ +- struct sockaddr arp_netmask; /* netmask (only for proxy arps) */ ++ struct sockaddr arp_pa; /* protocol address */ ++ struct sockaddr arp_ha; /* hardware address */ ++ int arp_flags; /* flags */ ++ struct sockaddr arp_netmask; /* netmask (only for proxy arps) */ + }; + + /* ARP Flag values. */ +diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h +index 1caf56584a690..502b065f0614b 100644 +--- a/include/uapi/linux/if_link.h ++++ b/include/uapi/linux/if_link.h +@@ -161,6 +161,7 @@ enum { + IFLA_EVENT, + IFLA_NEW_NETNSID, + IFLA_IF_NETNSID, ++ IFLA_TARGET_NETNSID = IFLA_IF_NETNSID, /* new alias */ + IFLA_CARRIER_UP_COUNT, + IFLA_CARRIER_DOWN_COUNT, + IFLA_NEW_IFINDEX, +@@ -551,6 +552,7 @@ enum { + IFLA_GENEVE_UDP_ZERO_CSUM6_TX, + IFLA_GENEVE_UDP_ZERO_CSUM6_RX, + IFLA_GENEVE_LABEL, ++ IFLA_GENEVE_TTL_INHERIT, + __IFLA_GENEVE_MAX + }; + #define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1) +diff --git a/include/uapi/linux/if_packet.h b/include/uapi/linux/if_packet.h +index 67b61d91d89bf..467b654bd4c7d 100644 +--- a/include/uapi/linux/if_packet.h ++++ b/include/uapi/linux/if_packet.h +@@ -57,6 +57,7 @@ struct sockaddr_ll { + #define PACKET_QDISC_BYPASS 20 + #define PACKET_ROLLOVER_STATS 21 + #define PACKET_FANOUT_DATA 22 ++#define PACKET_IGNORE_OUTGOING 23 + + #define PACKET_FANOUT_HASH 0 + #define PACKET_FANOUT_LB 1 +diff --git a/include/uapi/linux/in6.h b/include/uapi/linux/in6.h +index 409bb3f3aed67..2bb132a97333e 100644 +--- a/include/uapi/linux/in6.h ++++ b/include/uapi/linux/in6.h +@@ -177,6 +177,7 @@ struct in6_flowlabel_req { + #define IPV6_V6ONLY 26 + #define IPV6_JOIN_ANYCAST 27 + #define IPV6_LEAVE_ANYCAST 28 ++#define IPV6_MULTICAST_ALL 29 + + /* IPV6_MTU_DISCOVER values */ + #define IPV6_PMTUDISC_DONT 0 +diff --git a/include/uapi/linux/neighbour.h b/include/uapi/linux/neighbour.h +index 904db61484766..998155444e0db 100644 +--- a/include/uapi/linux/neighbour.h ++++ b/include/uapi/linux/neighbour.h +@@ -43,6 +43,7 @@ enum { + #define NTF_PROXY 0x08 /* == ATF_PUBL */ + #define NTF_EXT_LEARNED 0x10 + #define NTF_OFFLOADED 0x20 ++#define NTF_STICKY 0x40 + #define NTF_ROUTER 0x80 + + /* +diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h +index be382fb0592d8..401d0c1e612d3 100644 +--- a/include/uapi/linux/pkt_cls.h ++++ b/include/uapi/linux/pkt_cls.h +@@ -483,6 +483,8 @@ enum { + TCA_FLOWER_KEY_ENC_OPTS, + TCA_FLOWER_KEY_ENC_OPTS_MASK, + ++ TCA_FLOWER_IN_HW_COUNT, ++ + __TCA_FLOWER_MAX, + }; + +diff --git a/include/uapi/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h +index d9cc9dc4f547c..76ba49b0ec65f 100644 +--- a/include/uapi/linux/pkt_sched.h ++++ b/include/uapi/linux/pkt_sched.h +@@ -380,9 +380,9 @@ enum { + struct tc_htb_xstats { + __u32 lends; + __u32 borrows; +- __u32 giants; /* too big packets (rate will not be accurate) */ +- __u32 tokens; +- __u32 ctokens; ++ __u32 giants; /* unused since 'Make HTB scheduler work with TSO.' */ ++ __s32 tokens; ++ __s32 ctokens; + }; + + /* HFSC section */ +-- +2.25.3 + diff --git a/SOURCES/0008-lib-bpf-Fix-bytecode-file-parsing.patch b/SOURCES/0008-lib-bpf-Fix-bytecode-file-parsing.patch deleted file mode 100644 index 411953e..0000000 --- a/SOURCES/0008-lib-bpf-Fix-bytecode-file-parsing.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 584ca9f67952162dfdd02d984aa12640e45a4235 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Wed, 6 Sep 2017 11:53:53 +0200 -Subject: [PATCH] lib/bpf: Fix bytecode-file parsing - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1477491 -Upstream Status: iproute2.git commit 7c87c7fed18d1 - -commit 7c87c7fed18d1162e045c8331cb68fa440bc5728 -Author: Phil Sutter -Date: Tue Aug 29 17:09:45 2017 +0200 - - lib/bpf: Fix bytecode-file parsing - - The signedness of char type is implementation dependent, and there are - architectures on which it is unsigned by default. In that case, the - check whether fgetc() returned EOF failed because the return value was - assigned an (unsigned) char variable prior to comparison with EOF (which - is defined to -1). Fix this by using int as type for 'c' variable, which - also matches the declaration of fgetc(). - - While being at it, fix the parser logic to correctly handle multiple - empty lines and consecutive whitespace and tab characters to further - improve the parser's robustness. Note that this will still detect double - separator characters, so doesn't soften up the parser too much. - - Fixes: 3da3ebfca85b8 ("bpf: Make bytecode-file reading a little more robust") - Cc: Daniel Borkmann - Signed-off-by: Phil Sutter - Acked-by: Daniel Borkmann ---- - lib/bpf.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/lib/bpf.c b/lib/bpf.c -index 73dac5c37cc91..3aabf44d1abf8 100644 ---- a/lib/bpf.c -+++ b/lib/bpf.c -@@ -160,8 +160,9 @@ static int bpf_parse_string(char *arg, bool from_file, __u16 *bpf_len, - - if (from_file) { - size_t tmp_len, op_len = sizeof("65535 255 255 4294967295,"); -- char *tmp_string, *pos, c, c_prev = ' '; -+ char *tmp_string, *pos, c_prev = ' '; - FILE *fp; -+ int c; - - tmp_len = sizeof("4096,") + BPF_MAXINSNS * op_len; - tmp_string = pos = calloc(1, tmp_len); -@@ -180,18 +181,20 @@ static int bpf_parse_string(char *arg, bool from_file, __u16 *bpf_len, - case '\n': - if (c_prev != ',') - *(pos++) = ','; -+ c_prev = ','; - break; - case ' ': - case '\t': - if (c_prev != ' ') - *(pos++) = c; -+ c_prev = ' '; - break; - default: - *(pos++) = c; -+ c_prev = c; - } - if (pos - tmp_string == tmp_len) - break; -- c_prev = c; - } - - if (!feof(fp)) { --- -2.21.0 - diff --git a/SOURCES/0009-tc-simple.8-Fix-one-more-reference-to-non-existing-t.patch b/SOURCES/0009-tc-simple.8-Fix-one-more-reference-to-non-existing-t.patch deleted file mode 100644 index 3f0745e..0000000 --- a/SOURCES/0009-tc-simple.8-Fix-one-more-reference-to-non-existing-t.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 3905b2d8f676601c022804d197be9165dacff11c Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Wed, 6 Sep 2017 15:44:19 +0200 -Subject: [PATCH] tc-simple.8: Fix one more reference to non-existing - tc-actions.8 - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1477523 -Upstream Status: RHEL-only - -Previous fix missed to update the SEE ALSO section as well. ---- - man/man8/tc-simple.8 | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/man/man8/tc-simple.8 b/man/man8/tc-simple.8 -index a0deb0b13a82f..beab3132ee90e 100644 ---- a/man/man8/tc-simple.8 -+++ b/man/man8/tc-simple.8 -@@ -96,4 +96,4 @@ display stats again and observe increment by 1 - .EE - .SH SEE ALSO - .BR tc (8) --.BR tc-actions (8) -+.BR tc-pedit (8) --- -2.21.0 - diff --git a/SOURCES/0009-tc_util-Add-support-for-showing-TCA_STATS_BASIC_HW-s.patch b/SOURCES/0009-tc_util-Add-support-for-showing-TCA_STATS_BASIC_HW-s.patch new file mode 100644 index 0000000..6d5b4f9 --- /dev/null +++ b/SOURCES/0009-tc_util-Add-support-for-showing-TCA_STATS_BASIC_HW-s.patch @@ -0,0 +1,99 @@ +From 74fa5754e5a7cc140a7b586d22d9e7e7272ed28b Mon Sep 17 00:00:00 2001 +From: Andrea Claudi +Date: Tue, 21 Apr 2020 14:53:23 +0200 +Subject: [PATCH] tc_util: Add support for showing TCA_STATS_BASIC_HW + statistics + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1637437 +Upstream Status: iproute2.git commit 5ac138324e31c +Conflicts: adjust the code to make it compile due to missing + commit c91d262f414d2 ("tc: jsonify qdisc core") + +commit 5ac138324e31c75edc65c69cedcf699fb624c113 +Author: Eelco Chaudron +Date: Tue Oct 2 03:27:18 2018 -0400 + + tc_util: Add support for showing TCA_STATS_BASIC_HW statistics + + Add support for showing hardware specific counters to easy + troubleshooting hardware offload. + + $ tc -s filter show dev enp3s0np0 parent ffff: + filter protocol ip pref 1 flower chain 0 + filter protocol ip pref 1 flower chain 0 handle 0x1 + eth_type ipv4 + dst_ip 2.0.0.0 + src_ip 1.0.0.0 + ip_flags nofrag + in_hw + action order 1: mirred (Egress Redirect to device eth1) stolen + index 1 ref 1 bind 1 installed 0 sec used 0 sec + Action statistics: + Sent 534884742 bytes 8915697 pkt (dropped 0, overlimits 0 requeues 0) + Sent software 187542 bytes 4077 pkt + Sent hardware 534697200 bytes 8911620 pkt + backlog 0b 0p requeues 0 + cookie 89173e6a44447001becfd486bda17e29 + + Signed-off-by: Eelco Chaudron + Signed-off-by: David Ahern +--- + tc/tc_util.c | 35 +++++++++++++++++++++++++++++++++++ + 1 file changed, 35 insertions(+) + +diff --git a/tc/tc_util.c b/tc/tc_util.c +index e115e5a70e3a1..ecc6fa1cca5f1 100644 +--- a/tc/tc_util.c ++++ b/tc/tc_util.c +@@ -693,6 +693,38 @@ void print_tm(FILE *f, const struct tcf_t *tm) + fprintf(f, " expires %u sec", (unsigned int)(tm->expires/hz)); + } + ++static void print_tcstats_basic_hw(FILE *f, struct rtattr **tbs, char *prefix) ++{ ++ struct gnet_stats_basic bs_hw; ++ ++ if (!tbs[TCA_STATS_BASIC_HW]) ++ return; ++ ++ memcpy(&bs_hw, RTA_DATA(tbs[TCA_STATS_BASIC_HW]), ++ MIN(RTA_PAYLOAD(tbs[TCA_STATS_BASIC_HW]), sizeof(bs_hw))); ++ ++ if (bs_hw.bytes == 0 && bs_hw.packets == 0) ++ return; ++ ++ if (tbs[TCA_STATS_BASIC]) { ++ struct gnet_stats_basic bs; ++ ++ memcpy(&bs, RTA_DATA(tbs[TCA_STATS_BASIC]), ++ MIN(RTA_PAYLOAD(tbs[TCA_STATS_BASIC]), ++ sizeof(bs))); ++ ++ if (bs.bytes >= bs_hw.bytes && bs.packets >= bs_hw.packets) { ++ fprintf(f, "%s", prefix); ++ fprintf(f, "Sent software %llu bytes", bs.bytes - bs_hw.bytes); ++ fprintf(f, " %u pkt", bs.packets - bs_hw.packets); ++ } ++ } ++ ++ fprintf(f, "%s", prefix); ++ fprintf(f, "Sent hardware %llu bytes", bs_hw.bytes); ++ fprintf(f, " %u pkt", bs_hw.packets); ++} ++ + void print_tcstats2_attr(FILE *fp, struct rtattr *rta, char *prefix, struct rtattr **xstats) + { + SPRINT_BUF(b1); +@@ -716,6 +748,9 @@ void print_tcstats2_attr(FILE *fp, struct rtattr *rta, char *prefix, struct rtat + q.drops, q.overlimits, q.requeues); + } + ++ if (tbs[TCA_STATS_BASIC_HW]) ++ print_tcstats_basic_hw(fp, tbs, prefix); ++ + if (tbs[TCA_STATS_RATE_EST64]) { + struct gnet_stats_rate_est64 re = {0}; + +-- +2.25.3 + diff --git a/SOURCES/0010-ss-fix-NULL-pointer-access-when-parsing-unix-sockets.patch b/SOURCES/0010-ss-fix-NULL-pointer-access-when-parsing-unix-sockets.patch new file mode 100644 index 0000000..3f51236 --- /dev/null +++ b/SOURCES/0010-ss-fix-NULL-pointer-access-when-parsing-unix-sockets.patch @@ -0,0 +1,52 @@ +From c903640ae37106ae416592a413a1f55afd56eeda Mon Sep 17 00:00:00 2001 +From: Andrea Claudi +Date: Wed, 22 Apr 2020 10:21:03 +0200 +Subject: [PATCH] ss: fix NULL pointer access when parsing unix sockets with + oldformat + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1795891 +Upstream Status: iproute2.git commit ebbb219c924cc + +commit ebbb219c924ccedbc59e209d40b77d5dbeecd7cd +Author: Antonio Quartulli +Date: Sun Jan 7 02:31:50 2018 +0800 + + ss: fix NULL pointer access when parsing unix sockets with oldformat + + When parsing and printing the unix sockets in unix_show(), + if the oldformat is detected, the peer_name member of the sockstat + object is left uninitialized (NULL). + For this reason, if a filter has been specified on the command line, + a strcmp() will crash when trying to access it. + + Avoid crash by checking that peer_name is not NULL before + passing it to strcmp(). + + Cc: Stefano Brivio + Cc: Stephen Hemminger + Signed-off-by: Antonio Quartulli + Reviewed-by: Stefano Brivio + Signed-off-by: Stephen Hemminger +--- + misc/ss.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/misc/ss.c b/misc/ss.c +index 8f184fb929d31..0b66cca7aaab2 100644 +--- a/misc/ss.c ++++ b/misc/ss.c +@@ -3276,7 +3276,10 @@ static int unix_show(struct filter *f) + }; + + memcpy(st.local.data, &u->name, sizeof(u->name)); +- if (strcmp(u->peer_name, "*")) ++ /* when parsing the old format rport is set to 0 and ++ * therefore peer_name remains NULL ++ */ ++ if (u->peer_name && strcmp(u->peer_name, "*")) + memcpy(st.remote.data, &u->peer_name, + sizeof(u->peer_name)); + if (run_ssfilter(f->f, &st) == 0) { +-- +2.25.3 + diff --git a/SOURCES/0010-tc-m_xt-Prevent-a-segfault-in-libipt.patch b/SOURCES/0010-tc-m_xt-Prevent-a-segfault-in-libipt.patch deleted file mode 100644 index d1dbfdf..0000000 --- a/SOURCES/0010-tc-m_xt-Prevent-a-segfault-in-libipt.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 074062808c630f2efb55c7093d510b44a38e74e5 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 14 Sep 2017 15:27:47 +0200 -Subject: [PATCH] tc: m_xt: Prevent a segfault in libipt - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465599 -Upstream Status: iproute2.git commit f6fc1055e41a8 - -commit f6fc1055e41a8a924313c336b39b9ffe0c86938b -Author: Phil Sutter -Date: Tue May 23 15:40:57 2017 +0200 - - tc: m_xt: Prevent a segfault in libipt - - This happens with NAT targets, such as SNAT, DNAT and MASQUERADE. These - are still not usable with this patch, but at least tc doesn't crash - anymore when one tries to use them. - - Signed-off-by: Phil Sutter ---- - tc/m_xt.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/tc/m_xt.c b/tc/m_xt.c -index e59df8e10afef..ad52d239caf61 100644 ---- a/tc/m_xt.c -+++ b/tc/m_xt.c -@@ -146,6 +146,9 @@ static int parse_ipt(struct action_util *a, int *argc_p, - char ***argv_p, int tca_id, struct nlmsghdr *n) - { - struct xtables_target *m = NULL; -+#if XTABLES_VERSION_CODE >= 6 -+ struct ipt_entry fw = {}; -+#endif - struct rtattr *tail; - - int c; -@@ -206,7 +209,7 @@ static int parse_ipt(struct action_util *a, int *argc_p, - default: - #if XTABLES_VERSION_CODE >= 6 - if (m != NULL && m->x6_parse != NULL) { -- xtables_option_tpcall(c, argv, 0, m, NULL); -+ xtables_option_tpcall(c, argv, 0, m, &fw); - #else - if (m != NULL && m->parse != NULL) { - m->parse(c - m->option_offset, argv, 0, --- -2.21.0 - diff --git a/SOURCES/0011-link_gre6-really-support-encaplimit-option.patch b/SOURCES/0011-link_gre6-really-support-encaplimit-option.patch deleted file mode 100644 index feddc9a..0000000 --- a/SOURCES/0011-link_gre6-really-support-encaplimit-option.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 2db276543a03633a61ba0815a01c8bb2846830ab Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 14 Sep 2017 15:30:37 +0200 -Subject: [PATCH] link_gre6: really support encaplimit option - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1459600 -Upstream Status: iproute2.git commit a11b7b71a6eba -Conflicts: Context change due to missing commit ad4b1425c3182 - ("iplink: Expose IFLA_*_FWMARK attributes for supported link - types"). - -commit a11b7b71a6eba4ee80e931e4f75321a0cf0116f1 -Author: Nicolas Dichtel -Date: Wed Jun 14 18:45:42 2017 +0200 - - link_gre6: really support encaplimit option - - This option is documented in gre6 help, but was not supported. - - Fixes: af89576d7a8c ("iproute2: GRE over IPv6 tunnel support.") - Signed-off-by: Nicolas Dichtel ---- - ip/link_gre6.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/ip/link_gre6.c b/ip/link_gre6.c -index 1b4fb051b37f7..76416b26ff0e9 100644 ---- a/ip/link_gre6.c -+++ b/ip/link_gre6.c -@@ -339,6 +339,18 @@ get_failed: - encapflags |= TUNNEL_ENCAP_FLAG_REMCSUM; - } else if (strcmp(*argv, "noencap-remcsum") == 0) { - encapflags &= ~TUNNEL_ENCAP_FLAG_REMCSUM; -+ } else if (strcmp(*argv, "encaplimit") == 0) { -+ NEXT_ARG(); -+ if (strcmp(*argv, "none") == 0) { -+ flags |= IP6_TNL_F_IGN_ENCAP_LIMIT; -+ } else { -+ __u8 uval; -+ -+ if (get_u8(&uval, *argv, 0) < -1) -+ invarg("invalid ELIM", *argv); -+ encap_limit = uval; -+ flags &= ~IP6_TNL_F_IGN_ENCAP_LIMIT; -+ } - } else - usage(); - argc--; argv++; --- -2.21.0 - diff --git a/SOURCES/0011-xfrm-not-try-to-delete-ipcomp-states-when-using-dele.patch b/SOURCES/0011-xfrm-not-try-to-delete-ipcomp-states-when-using-dele.patch new file mode 100644 index 0000000..27f831d --- /dev/null +++ b/SOURCES/0011-xfrm-not-try-to-delete-ipcomp-states-when-using-dele.patch @@ -0,0 +1,55 @@ +From 6c28c0a3046a162698fa19f3c2f2682342905288 Mon Sep 17 00:00:00 2001 +From: Andrea Claudi +Date: Tue, 21 Apr 2020 12:49:56 +0200 +Subject: [PATCH] xfrm: not try to delete ipcomp states when using deleteall + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1767328 +Upstream Status: iproute2.git commit f9d696cf414c2 + +commit f9d696cf414c2c475764aa3b29cf288350f1e21f +Author: Xin Long +Date: Mon Feb 24 09:57:01 2020 -0500 + + xfrm: not try to delete ipcomp states when using deleteall + + In kernel space, ipcomp(sub) states used by main states are not + allowed to be deleted by users, they would be freed only when + all main states are destroyed and no one uses them. + + In user space, ip xfrm sta deleteall doesn't filter these ipcomp + states out, and it causes errors: + + # ip xfrm state add src 192.168.0.1 dst 192.168.0.2 spi 0x1000 \ + proto comp comp deflate mode tunnel sel src 192.168.0.1 dst \ + 192.168.0.2 proto gre + # ip xfrm sta deleteall + Failed to send delete-all request + : Operation not permitted + + This patch is to fix it by filtering ipcomp states with a check + xsinfo->id.proto == IPPROTO_IPIP. + + Fixes: c7699875bee0 ("Import patch ipxfrm-20040707_2.diff") + Signed-off-by: Xin Long + Signed-off-by: Stephen Hemminger +--- + ip/xfrm_state.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c +index 2222737cdd98d..8baa0eb669969 100644 +--- a/ip/xfrm_state.c ++++ b/ip/xfrm_state.c +@@ -1048,6 +1048,9 @@ static int xfrm_state_keep(const struct sockaddr_nl *who, + if (!xfrm_state_filter_match(xsinfo)) + return 0; + ++ if (xsinfo->id.proto == IPPROTO_IPIP) ++ return 0; ++ + if (xb->offset > xb->size) { + fprintf(stderr, "State buffer overflow\n"); + return -1; +-- +2.25.3 + diff --git a/SOURCES/0012-tc-fix-typo-in-manpage.patch b/SOURCES/0012-tc-fix-typo-in-manpage.patch deleted file mode 100644 index 1b6b2f1..0000000 --- a/SOURCES/0012-tc-fix-typo-in-manpage.patch +++ /dev/null @@ -1,40 +0,0 @@ -From beb8e1aa7ed08f86fb87ff58f7c69aaa2b68b862 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 14 Sep 2017 15:38:46 +0200 -Subject: [PATCH] tc: fix typo in manpage - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1417162 -Upstream Status: iproute2.git commit b09515553fded - -commit b09515553fded944713955815a3f1cc855384abd -Author: Matteo Croce -Date: Fri Jul 7 15:08:33 2017 +0200 - - tc: fix typo in manpage - - Fix a typo in the 'tc' manpage and reword some sentences. - - Signed-off-by: Matteo Croce ---- - man/man8/tc-csum.8 | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/man/man8/tc-csum.8 b/man/man8/tc-csum.8 -index 718301ded069b..409ab71791cce 100644 ---- a/man/man8/tc-csum.8 -+++ b/man/man8/tc-csum.8 -@@ -29,9 +29,9 @@ csum - checksum update action - The - .B csum - action triggers checksum recalculation of specified packet headers. It is --commonly used after packet editing using the -+commonly used to fix incorrect checksums after the - .B pedit --action to fix for then incorrect checksums. -+action has modified the packet content. - .SH OPTIONS - .TP - .I TARGET --- -2.21.0 - diff --git a/SOURCES/0012-xfrm-also-check-for-ipv6-state-in-xfrm_state_keep.patch b/SOURCES/0012-xfrm-also-check-for-ipv6-state-in-xfrm_state_keep.patch new file mode 100644 index 0000000..4f4b277 --- /dev/null +++ b/SOURCES/0012-xfrm-also-check-for-ipv6-state-in-xfrm_state_keep.patch @@ -0,0 +1,53 @@ +From 98ad13988375d240d6446954355da9622b87f1c1 Mon Sep 17 00:00:00 2001 +From: Andrea Claudi +Date: Thu, 30 Apr 2020 19:50:12 +0200 +Subject: [PATCH] xfrm: also check for ipv6 state in xfrm_state_keep + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1828034 +Upstream Status: iproute2.git commit d27fc6390ce32 + +commit d27fc6390ce32ecdba6324e22b1c341791c5c63f +Author: Xin Long +Date: Mon Apr 27 15:14:24 2020 +0800 + + xfrm: also check for ipv6 state in xfrm_state_keep + + As commit f9d696cf414c ("xfrm: not try to delete ipcomp states when using + deleteall") does, this patch is to fix the same issue for ip6 state where + xsinfo->id.proto == IPPROTO_IPV6. + + # ip xfrm state add src 2000::1 dst 2000::2 spi 0x1000 \ + proto comp comp deflate mode tunnel sel src 2000::1 dst \ + 2000::2 proto gre + # ip xfrm sta deleteall + Failed to send delete-all request + : Operation not permitted + + Note that the xsinfo->proto in common states can never be IPPROTO_IPV6. + + Fixes: f9d696cf414c ("xfrm: not try to delete ipcomp states when using deleteall") + Reported-by: Xiumei Mu + Signed-off-by: Xin Long + Acked-by: Andrea Claudi + Signed-off-by: Stephen Hemminger +--- + ip/xfrm_state.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c +index 8baa0eb669969..e0e24b0618294 100644 +--- a/ip/xfrm_state.c ++++ b/ip/xfrm_state.c +@@ -1048,7 +1048,8 @@ static int xfrm_state_keep(const struct sockaddr_nl *who, + if (!xfrm_state_filter_match(xsinfo)) + return 0; + +- if (xsinfo->id.proto == IPPROTO_IPIP) ++ if (xsinfo->id.proto == IPPROTO_IPIP || ++ xsinfo->id.proto == IPPROTO_IPV6) + return 0; + + if (xb->offset > xb->size) { +-- +2.25.4 + diff --git a/SOURCES/0013-ip-neigh-allow-flush-FAILED-neighbour-entry.patch b/SOURCES/0013-ip-neigh-allow-flush-FAILED-neighbour-entry.patch deleted file mode 100644 index 7fcbed2..0000000 --- a/SOURCES/0013-ip-neigh-allow-flush-FAILED-neighbour-entry.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 3b6fd8227cbb03b5b211d2cb53534ad405673668 Mon Sep 17 00:00:00 2001 -From: Matteo Croce -Date: Wed, 2 Aug 2017 13:57:17 +0200 -Subject: [PATCH] ip neigh: allow flush FAILED neighbour entry - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1469945 -Tested: locally using proper reproducer -Upstream Status: merged 37a5f7c5 - -commit 37a5f7c571623059ae671992f72feaa444a6ffc8 -Author: Hangbin Liu -Date: Fri Jun 16 11:31:52 2017 +0800 - - ip neigh: allow flush FAILED neighbour entry - - After upstream commit 5071034e4af7 ('neigh: Really delete an arp/neigh entry - on "ip neigh delete" or "arp -d"'), we could delete a single FAILED neighbour - entry now. But `ip neigh flush` still skip the FAILED entry. - - Move the filter after first round flush so we can flush FAILED entry on fixed - kernel and also do not keep retrying on old kernel. - - Signed-off-by: Hangbin Liu - -Signed-off-by: Matteo Croce ---- - ip/ipneigh.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ip/ipneigh.c b/ip/ipneigh.c -index 4d8fc85217451..9c38a60ddf4fe 100644 ---- a/ip/ipneigh.c -+++ b/ip/ipneigh.c -@@ -445,7 +445,6 @@ static int do_show_or_flush(int argc, char **argv, int flush) - filter.flushb = flushb; - filter.flushp = 0; - filter.flushe = sizeof(flushb); -- filter.state &= ~NUD_FAILED; - - while (round < MAX_ROUNDS) { - if (rtnl_dump_request_n(&rth, &req.n) < 0) { -@@ -474,6 +473,7 @@ static int do_show_or_flush(int argc, char **argv, int flush) - printf("\n*** Round %d, deleting %d entries ***\n", round, filter.flushed); - fflush(stdout); - } -+ filter.state &= ~NUD_FAILED; - } - printf("*** Flush not complete bailing out after %d rounds\n", - MAX_ROUNDS); --- -2.21.0 - diff --git a/SOURCES/0013-tc_util-Fix-format-of-TCA_STATS_BASIC_HW-statistics.patch b/SOURCES/0013-tc_util-Fix-format-of-TCA_STATS_BASIC_HW-statistics.patch new file mode 100644 index 0000000..5df101c --- /dev/null +++ b/SOURCES/0013-tc_util-Fix-format-of-TCA_STATS_BASIC_HW-statistics.patch @@ -0,0 +1,45 @@ +From e1383085284f283538af8598c52401b7d5906164 Mon Sep 17 00:00:00 2001 +From: Andrea Claudi +Date: Mon, 8 Jun 2020 14:50:35 +0200 +Subject: [PATCH] tc_util: Fix format of TCA_STATS_BASIC_HW statistics + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1637437 +Upstream Status: RHEL-only + +During the backport of commit 5ac138324e31c ("tc_util: Add support for showing +TCA_STATS_BASIC_HW statistics") some code was modified to avoid backporting a +large unrelated commit jsonifing the output of tc stats. + +The format of TCA_STATS_BASIC_HW statistics was unintentionally altered missing +a newline at the beginning of "Sent software" and "Sent hardware" lines. + +This commit fix the output format. + +Signed-off-by: Andrea Claudi +--- + tc/tc_util.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tc/tc_util.c b/tc/tc_util.c +index ecc6fa1cca5f1..28dc06ffac784 100644 +--- a/tc/tc_util.c ++++ b/tc/tc_util.c +@@ -714,13 +714,13 @@ static void print_tcstats_basic_hw(FILE *f, struct rtattr **tbs, char *prefix) + sizeof(bs))); + + if (bs.bytes >= bs_hw.bytes && bs.packets >= bs_hw.packets) { +- fprintf(f, "%s", prefix); ++ fprintf(f, "\n%s", prefix); + fprintf(f, "Sent software %llu bytes", bs.bytes - bs_hw.bytes); + fprintf(f, " %u pkt", bs.packets - bs_hw.packets); + } + } + +- fprintf(f, "%s", prefix); ++ fprintf(f, "\n%s", prefix); + fprintf(f, "Sent hardware %llu bytes", bs_hw.bytes); + fprintf(f, " %u pkt", bs_hw.packets); + } +-- +2.26.2 + diff --git a/SOURCES/0014-netns-avoid-directory-traversal.patch b/SOURCES/0014-netns-avoid-directory-traversal.patch deleted file mode 100644 index 866d9f4..0000000 --- a/SOURCES/0014-netns-avoid-directory-traversal.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 74061958f56a4626a3a146c72f16e43012e828f1 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 14 Sep 2017 15:39:23 +0200 -Subject: [PATCH] netns: avoid directory traversal - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1468529 -Upstream Status: iproute2.git commit 79928fd0552b5 - -commit 79928fd0552b520aa36a22e71144d10a32f7e4fe -Author: Matteo Croce -Date: Thu Jul 20 00:36:32 2017 +0200 - - netns: avoid directory traversal - - ip netns keeps track of created namespaces with bind mounts named - /var/run/netns/. No input sanitization is done, allowing creation and - deletion of files relatives to /var/run/netns or, if the path is non existent or - invalid, allows to create "untracked" namespaces (invisible to the tool). - - This commit denies creation or deletion of namespaces with names contaning - "/" or matching exactly "." or "..". - - Signed-off-by: Matteo Croce ---- - ip/ipnetns.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/ip/ipnetns.c b/ip/ipnetns.c -index 0b0378ab6560c..4254994442ccd 100644 ---- a/ip/ipnetns.c -+++ b/ip/ipnetns.c -@@ -766,6 +766,11 @@ static int netns_monitor(int argc, char **argv) - return 0; - } - -+static int invalid_name(const char *name) -+{ -+ return strchr(name, '/') || !strcmp(name, ".") || !strcmp(name, ".."); -+} -+ - int do_netns(int argc, char **argv) - { - netns_nsid_socket_init(); -@@ -775,6 +780,11 @@ int do_netns(int argc, char **argv) - return netns_list(0, NULL); - } - -+ if (argc > 1 && invalid_name(argv[1])) { -+ fprintf(stderr, "Invalid netns name \"%s\"\n", argv[1]); -+ exit(-1); -+ } -+ - if ((matches(*argv, "list") == 0) || (matches(*argv, "show") == 0) || - (matches(*argv, "lst") == 0)) { - netns_map_init(); --- -2.21.0 - diff --git a/SOURCES/0015-utils-return-default-family-when-rtm_family-is-not-R.patch b/SOURCES/0015-utils-return-default-family-when-rtm_family-is-not-R.patch deleted file mode 100644 index 7cebc46..0000000 --- a/SOURCES/0015-utils-return-default-family-when-rtm_family-is-not-R.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 420957e4c56f65703c6f2f24da0ea35c6b7bbcda Mon Sep 17 00:00:00 2001 -From: Stefano Brivio -Date: Thu, 27 Jul 2017 21:52:30 +0200 -Subject: [PATCH] utils: return default family when rtm_family is not - RTNL_FAMILY_IPMR/IP6MR - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1475762 -Upstream Status: iproute2.git commit 5ce897a03bfd - -commit 5ce897a03bfda76dc66dc1acfa014fc0e3d3022a -Author: Hangbin Liu -Date: Thu Jul 27 17:44:15 2017 +0800 - - utils: return default family when rtm_family is not RTNL_FAMILY_IPMR/IP6MR - - When we get a multicast route, the rtm_type is RTN_MULTICAST, but the - rtm_family may be AF_INET. If we only check the type with RTNL_FAMILY_IPMR, - we will get malformed address. e.g. - - + ip -4 route add multicast 172.111.1.1 dev em1 table main - - Before fix: - + ip route list type multicast table main - multicast ac6f:101:800:400:400:0:3c00:0 dev em1 scope link - - After fix: - + ip route list type multicast table main - multicast 172.111.1.1 dev em1 scope link - - Fixes: 56e3eb4c3400 ("ip: route: fix multicast route dumps") - Signed-off-by: Hangbin Liu - Acked-by: Phil Sutter - -Signed-off-by: Stefano Brivio ---- - lib/utils.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/lib/utils.c b/lib/utils.c -index 7d6ee53ad938d..9f55391d3c1ea 100644 ---- a/lib/utils.c -+++ b/lib/utils.c -@@ -1219,5 +1219,11 @@ int get_real_family(int rtm_type, int rtm_family) - if (rtm_type != RTN_MULTICAST) - return rtm_family; - -- return rtm_family == RTNL_FAMILY_IPMR ? AF_INET : AF_INET6; -+ if (rtm_family == RTNL_FAMILY_IPMR) -+ return AF_INET; -+ -+ if (rtm_family == RTNL_FAMILY_IP6MR) -+ return AF_INET6; -+ -+ return rtm_family; - } --- -2.21.0 - diff --git a/SOURCES/0016-link_gre6-Fix-for-changing-tclass-flowlabel.patch b/SOURCES/0016-link_gre6-Fix-for-changing-tclass-flowlabel.patch deleted file mode 100644 index 3748fb2..0000000 --- a/SOURCES/0016-link_gre6-Fix-for-changing-tclass-flowlabel.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 449517f7769dde4905564ce17e126bfd4e1f7147 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Fri, 6 Oct 2017 17:27:09 +0200 -Subject: [PATCH] link_gre6: Fix for changing tclass/flowlabel - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1487486 -Upstream Status: iproute2.git commit e7fefb3214b5a - -commit e7fefb3214b5a1ed030cab9df513560c503a9851 -Author: Phil Sutter -Date: Fri Sep 1 16:08:08 2017 +0200 - - link_gre6: Fix for changing tclass/flowlabel - - When trying to change tclass or flowlabel of a GREv6 tunnel which has - the respective value set already, the code accidentally bitwise OR'ed - the old and the new value, leading to unexpected results. Fix this by - clearing the relevant bits of flowinfo variable prior to assigning the - new value. - - Fixes: af89576d7a8c4 ("iproute2: GRE over IPv6 tunnel support.") - Signed-off-by: Phil Sutter ---- - ip/link_gre6.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/ip/link_gre6.c b/ip/link_gre6.c -index 76416b26ff0e9..fe3ab641a86c2 100644 ---- a/ip/link_gre6.c -+++ b/ip/link_gre6.c -@@ -282,6 +282,7 @@ get_failed: - else { - if (get_u8(&uval, *argv, 16)) - invarg("invalid TClass", *argv); -+ flowinfo &= ~IP6_FLOWINFO_TCLASS; - flowinfo |= htonl((__u32)uval << 20) & IP6_FLOWINFO_TCLASS; - flags &= ~IP6_TNL_F_USE_ORIG_TCLASS; - } -@@ -297,6 +298,7 @@ get_failed: - invarg("invalid Flowlabel", *argv); - if (uval > 0xFFFFF) - invarg("invalid Flowlabel", *argv); -+ flowinfo &= ~IP6_FLOWINFO_FLOWLABEL; - flowinfo |= htonl(uval) & IP6_FLOWINFO_FLOWLABEL; - flags &= ~IP6_TNL_F_USE_ORIG_FLOWLABEL; - } --- -2.21.0 - diff --git a/SOURCES/0017-netlink-Change-rtnl_dump_done-to-always-show-error.patch b/SOURCES/0017-netlink-Change-rtnl_dump_done-to-always-show-error.patch deleted file mode 100644 index 34e220a..0000000 --- a/SOURCES/0017-netlink-Change-rtnl_dump_done-to-always-show-error.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 61ccf0f453306e727e254e6de1641bb934a3b7ec Mon Sep 17 00:00:00 2001 -From: Hangbin Liu -Date: Wed, 8 Nov 2017 14:39:07 +0800 -Subject: [PATCH] netlink: Change rtnl_dump_done to always show error - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1380803 -Upstream Status: iproute2.git commit 05a14fc12188 - -commit 05a14fc1218885ba6236b409fbf6b89976b8636e -Author: David Ahern -Date: Tue May 16 14:22:46 2017 -0700 - - netlink: Change rtnl_dump_done to always show error - - The original code which became rtnl_dump_done only shows netlink errors - if the protocol is NETLINK_SOCK_DIAG, but netlink dumps always appends - the length which contains any error encountered during the dump. Update - rtnl_dump_done to always show the error if there is one. - - As an *example* without this patch, dumping a route object that exceeds - the internal buffer size terminates with no message to the user -- the - dump just ends because the NLMSG_DONE attribute was received. With this - patch the user at least gets a message that the dump was aborted. - - $ ip ro ls - default via 10.0.2.2 dev eth0 - 10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15 - 10.10.0.0/16 dev veth1 proto kernel scope link src 10.10.0.1 - 172.16.1.0/24 dev br0.11 proto kernel scope link src 172.16.1.1 - Error: Buffer too small for object - Dump terminated - - The point of this patch is to notify the user of a failure versus - silently exiting on a partial dump. Because the NLMSG_DONE attribute - was received, the entire dump needs to be restarted to use a larger - buffer for EMSGSIZE errors. That could be done automatically but it - has other user impacts (e.g., duplicate output if the dump is - restarted) and should be the subject of a different patch. - - Signed-off-by: David Ahern - -Signed-off-by: Hangbin Liu ---- - lib/libnetlink.c | 28 +++++++++++++++++----------- - 1 file changed, 17 insertions(+), 11 deletions(-) - -diff --git a/lib/libnetlink.c b/lib/libnetlink.c -index 9303b6686e2c8..e91bd5a02b956 100644 ---- a/lib/libnetlink.c -+++ b/lib/libnetlink.c -@@ -266,21 +266,27 @@ static int rtnl_dump_done(const struct rtnl_handle *rth, - { - int len = *(int *)NLMSG_DATA(h); - -- if (rth->proto == NETLINK_SOCK_DIAG) { -- if (h->nlmsg_len < NLMSG_LENGTH(sizeof(int))) { -- fprintf(stderr, "DONE truncated\n"); -- return -1; -- } -- -+ if (h->nlmsg_len < NLMSG_LENGTH(sizeof(int))) { -+ fprintf(stderr, "DONE truncated\n"); -+ return -1; -+ } - -- if (len < 0) { -- errno = -len; -- if (errno == ENOENT || errno == EOPNOTSUPP) -- return -1; -+ if (len < 0) { -+ errno = -len; -+ switch (errno) { -+ case ENOENT: -+ case EOPNOTSUPP: -+ return -1; -+ case EMSGSIZE: -+ fprintf(stderr, -+ "Error: Buffer too small for object.\n"); -+ break; -+ default: - perror("RTNETLINK answers"); -- return len; - } -+ return len; - } -+ - return 0; - } - --- -2.21.0 - diff --git a/SOURCES/0018-libnetlink-drop-unused-parameter-to-rtnl_dump_done.patch b/SOURCES/0018-libnetlink-drop-unused-parameter-to-rtnl_dump_done.patch deleted file mode 100644 index 65847b2..0000000 --- a/SOURCES/0018-libnetlink-drop-unused-parameter-to-rtnl_dump_done.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 9346e08c2f9059decf889fb89f2859e7ed61f573 Mon Sep 17 00:00:00 2001 -From: Hangbin Liu -Date: Wed, 8 Nov 2017 14:39:08 +0800 -Subject: [PATCH] libnetlink: drop unused parameter to rtnl_dump_done - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1380803 -Upstream Status: iproute2.git commit 0efa625765b4 - -commit 0efa625765b4481e1e474526eb0feda747b720e5 -Author: Stephen Hemminger -Date: Thu Aug 24 15:02:32 2017 -0700 - - libnetlink: drop unused parameter to rtnl_dump_done - - Signed-off-by: Stephen Hemminger - -Signed-off-by: Hangbin Liu ---- - lib/libnetlink.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/lib/libnetlink.c b/lib/libnetlink.c -index e91bd5a02b956..b08518d81f2dd 100644 ---- a/lib/libnetlink.c -+++ b/lib/libnetlink.c -@@ -261,8 +261,7 @@ int rtnl_dump_request_n(struct rtnl_handle *rth, struct nlmsghdr *n) - return sendmsg(rth->fd, &msg, 0); - } - --static int rtnl_dump_done(const struct rtnl_handle *rth, -- struct nlmsghdr *h) -+static int rtnl_dump_done(struct nlmsghdr *h) - { - int len = *(int *)NLMSG_DATA(h); - -@@ -368,7 +367,7 @@ int rtnl_dump_filter_l(struct rtnl_handle *rth, - dump_intr = 1; - - if (h->nlmsg_type == NLMSG_DONE) { -- err = rtnl_dump_done(rth, h); -+ err = rtnl_dump_done(h); - if (err < 0) - return -1; - --- -2.21.0 - diff --git a/SOURCES/0019-iproute-Add-support-for-extended-ack-to-rtnl_talk.patch b/SOURCES/0019-iproute-Add-support-for-extended-ack-to-rtnl_talk.patch deleted file mode 100644 index 7d0075e..0000000 --- a/SOURCES/0019-iproute-Add-support-for-extended-ack-to-rtnl_talk.patch +++ /dev/null @@ -1,255 +0,0 @@ -From a9f81b704c4e883a996927e77afdb960a7f47fd9 Mon Sep 17 00:00:00 2001 -From: Hangbin Liu -Date: Wed, 8 Nov 2017 14:39:09 +0800 -Subject: [PATCH] iproute: Add support for extended ack to rtnl_talk - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1380803 -Upstream Status: iproute2.git commit b6432e68ac2f -Conflicts: Manually added NETLINK_EXT_ACK define to linux headers. - -commit b6432e68ac2f1f6b4ea50aa0d6d47e72c445c71c -Author: Stephen Hemminger -Date: Fri Aug 4 09:52:15 2017 -0700 - - iproute: Add support for extended ack to rtnl_talk - - Add support for extended ack error reporting via libmnl. - Add a new function rtnl_talk_extack that takes a callback as an input - arg. If a netlink response contains extack attributes, the callback is - is invoked with the the err string, offset in the message and a pointer - to the message returned by the kernel. - - If iproute2 is built without libmnl, it will still work but - extended error reports from kernel will not be available. - - Signed-off-by: Stephen Hemminger - -Signed-off-by: Hangbin Liu - -squash! iproute: Add support for extended ack to rtnl_talk ---- - include/libnetlink.h | 6 +++ - include/linux/netlink.h | 1 + - lib/Makefile | 7 +++ - lib/libnetlink.c | 109 +++++++++++++++++++++++++++++++++++++--- - 4 files changed, 116 insertions(+), 7 deletions(-) - -diff --git a/include/libnetlink.h b/include/libnetlink.h -index bd0267dfcc02a..654aebc0f7632 100644 ---- a/include/libnetlink.h -+++ b/include/libnetlink.h -@@ -65,6 +65,9 @@ typedef int (*rtnl_listen_filter_t)(const struct sockaddr_nl *, - struct rtnl_ctrl_data *, - struct nlmsghdr *n, void *); - -+typedef int (*nl_ext_ack_fn_t)(const char *errmsg, uint32_t off, -+ const struct nlmsghdr *inner_nlh); -+ - struct rtnl_dump_filter_arg { - rtnl_filter_t filter; - void *arg1; -@@ -81,6 +84,9 @@ int rtnl_dump_filter_nc(struct rtnl_handle *rth, - int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, - struct nlmsghdr *answer, size_t len) - __attribute__((warn_unused_result)); -+int rtnl_talk_extack(struct rtnl_handle *rtnl, struct nlmsghdr *n, -+ struct nlmsghdr *answer, size_t len, nl_ext_ack_fn_t errfn) -+ __attribute__((warn_unused_result)); - int rtnl_talk_suppress_rtnl_errmsg(struct rtnl_handle *rtnl, struct nlmsghdr *n, - struct nlmsghdr *answer, size_t len) - __attribute__((warn_unused_result)); -diff --git a/include/linux/netlink.h b/include/linux/netlink.h -index a982b3c004395..d1e26a2bcdcbb 100644 ---- a/include/linux/netlink.h -+++ b/include/linux/netlink.h -@@ -113,6 +113,7 @@ struct nlmsgerr { - #define NETLINK_LISTEN_ALL_NSID 8 - #define NETLINK_LIST_MEMBERSHIPS 9 - #define NETLINK_CAP_ACK 10 -+#define NETLINK_EXT_ACK 11 - - struct nl_pktinfo { - __u32 group; -diff --git a/lib/Makefile b/lib/Makefile -index 1d24ca24b9a39..f81888cca974f 100644 ---- a/lib/Makefile -+++ b/lib/Makefile -@@ -4,6 +4,13 @@ ifeq ($(IP_CONFIG_SETNS),y) - CFLAGS += -DHAVE_SETNS - endif - -+ifeq ($(HAVE_MNL),y) -+ CFLAGS += $(shell $(PKG_CONFIG) libmnl --cflags) -+ LDLIBS += $(shell $(PKG_CONFIG) libmnl --libs) -+else -+@warn "libmnl required for error support" -+endif -+ - CFLAGS += -fPIC - - UTILOBJ = utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o \ -diff --git a/lib/libnetlink.c b/lib/libnetlink.c -index b08518d81f2dd..a0578312e83f8 100644 ---- a/lib/libnetlink.c -+++ b/lib/libnetlink.c -@@ -36,6 +36,79 @@ - - int rcvbuf = 1024 * 1024; - -+#ifdef HAVE_LIBMNL -+#include -+ -+static const enum mnl_attr_data_type extack_policy[NLMSGERR_ATTR_MAX + 1] = { -+ [NLMSGERR_ATTR_MSG] = MNL_TYPE_NUL_STRING, -+ [NLMSGERR_ATTR_OFFS] = MNL_TYPE_U32, -+}; -+ -+static int err_attr_cb(const struct nlattr *attr, void *data) -+{ -+ const struct nlattr **tb = data; -+ uint16_t type; -+ -+ if (mnl_attr_type_valid(attr, NLMSGERR_ATTR_MAX) < 0) -+ return MNL_CB_ERROR; -+ -+ type = mnl_attr_get_type(attr); -+ if (mnl_attr_validate(attr, extack_policy[type]) < 0) -+ return MNL_CB_ERROR; -+ -+ -+ tb[type] = attr; -+ return MNL_CB_OK; -+} -+ -+ -+/* dump netlink extended ack error message */ -+static int nl_dump_ext_err(const struct nlmsghdr *nlh, nl_ext_ack_fn_t errfn) -+{ -+ struct nlattr *tb[NLMSGERR_ATTR_MAX + 1]; -+ const struct nlmsgerr *err = mnl_nlmsg_get_payload(nlh); -+ const struct nlmsghdr *err_nlh = NULL; -+ unsigned int hlen = sizeof(*err); -+ const char *errmsg = NULL; -+ uint32_t off = 0; -+ -+ if (!errfn) -+ return 0; -+ -+ /* no TLVs, nothing to do here */ -+ if (!(nlh->nlmsg_flags & NLM_F_ACK_TLVS)) -+ return 0; -+ -+ /* if NLM_F_CAPPED is set then the inner err msg was capped */ -+ if (!(nlh->nlmsg_flags & NLM_F_CAPPED)) -+ hlen += mnl_nlmsg_get_payload_len(&err->msg); -+ -+ mnl_attr_parse(nlh, hlen, err_attr_cb, tb); -+ -+ if (tb[NLMSGERR_ATTR_MSG]) -+ errmsg = mnl_attr_get_str(tb[NLMSGERR_ATTR_MSG]); -+ -+ if (tb[NLMSGERR_ATTR_OFFS]) { -+ off = mnl_attr_get_u32(tb[NLMSGERR_ATTR_OFFS]); -+ -+ if (off > nlh->nlmsg_len) { -+ fprintf(stderr, -+ "Invalid offset for NLMSGERR_ATTR_OFFS\n"); -+ off = 0; -+ } else if (!(nlh->nlmsg_flags & NLM_F_CAPPED)) -+ err_nlh = &err->msg; -+ } -+ -+ return errfn(errmsg, off, err_nlh); -+} -+#else -+/* No extended error ack without libmnl */ -+static int nl_dump_ext_err(const struct nlmsghdr *nlh, nl_ext_ack_fn_t errfn) -+{ -+ return 0; -+} -+#endif -+ - void rtnl_close(struct rtnl_handle *rth) - { - if (rth->fd >= 0) { -@@ -49,6 +122,7 @@ int rtnl_open_byproto(struct rtnl_handle *rth, unsigned int subscriptions, - { - socklen_t addr_len; - int sndbuf = 32768; -+ int one = 1; - - memset(rth, 0, sizeof(*rth)); - -@@ -71,6 +145,10 @@ int rtnl_open_byproto(struct rtnl_handle *rth, unsigned int subscriptions, - return -1; - } - -+ /* Older kernels may no support extended ACK reporting */ -+ setsockopt(rth->fd, SOL_NETLINK, NETLINK_EXT_ACK, -+ &one, sizeof(one)); -+ - memset(&rth->local, 0, sizeof(rth->local)); - rth->local.nl_family = AF_NETLINK; - rth->local.nl_groups = subscriptions; -@@ -421,9 +499,19 @@ int rtnl_dump_filter_nc(struct rtnl_handle *rth, - return rtnl_dump_filter_l(rth, a); - } - -+static void rtnl_talk_error(struct nlmsghdr *h, struct nlmsgerr *err, -+ nl_ext_ack_fn_t errfn) -+{ -+ if (nl_dump_ext_err(h, errfn)) -+ return; -+ -+ fprintf(stderr, "RTNETLINK answers: %s\n", -+ strerror(-err->error)); -+} -+ - static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, - struct nlmsghdr *answer, size_t maxlen, -- bool show_rtnl_err) -+ bool show_rtnl_err, nl_ext_ack_fn_t errfn) - { - int status; - unsigned int seq; -@@ -510,10 +598,10 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, - return 0; - } - -- if (rtnl->proto != NETLINK_SOCK_DIAG && show_rtnl_err) -- fprintf(stderr, -- "RTNETLINK answers: %s\n", -- strerror(-err->error)); -+ if (rtnl->proto != NETLINK_SOCK_DIAG && -+ show_rtnl_err) -+ rtnl_talk_error(h, err, errfn); -+ - errno = -err->error; - return -1; - } -@@ -545,13 +633,20 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, - int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, - struct nlmsghdr *answer, size_t maxlen) - { -- return __rtnl_talk(rtnl, n, answer, maxlen, true); -+ return __rtnl_talk(rtnl, n, answer, maxlen, true, NULL); -+} -+ -+int rtnl_talk_extack(struct rtnl_handle *rtnl, struct nlmsghdr *n, -+ struct nlmsghdr *answer, size_t maxlen, -+ nl_ext_ack_fn_t errfn) -+{ -+ return __rtnl_talk(rtnl, n, answer, maxlen, true, errfn); - } - - int rtnl_talk_suppress_rtnl_errmsg(struct rtnl_handle *rtnl, struct nlmsghdr *n, - struct nlmsghdr *answer, size_t maxlen) - { -- return __rtnl_talk(rtnl, n, answer, maxlen, false); -+ return __rtnl_talk(rtnl, n, answer, maxlen, false, NULL); - } - - int rtnl_listen_all_nsid(struct rtnl_handle *rth) --- -2.21.0 - diff --git a/SOURCES/0020-iplink-check-for-message-truncation-in-iplink_get.patch b/SOURCES/0020-iplink-check-for-message-truncation-in-iplink_get.patch deleted file mode 100644 index ab7d10d..0000000 --- a/SOURCES/0020-iplink-check-for-message-truncation-in-iplink_get.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 8372b7bb8f7211563d888fdd30e473c161f7d0a0 Mon Sep 17 00:00:00 2001 -From: Hangbin Liu -Date: Wed, 8 Nov 2017 14:39:10 +0800 -Subject: [PATCH] iplink: check for message truncation in iplink_get() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1380803 -Upstream Status: iproute2.git commit 6599162b958e - -commit 6599162b958ea5a43d729df4f30aad515db26ff4 -Author: Michal Kubecek -Date: Fri Sep 1 18:39:11 2017 +0200 - - iplink: check for message truncation in iplink_get() - - If message length exceeds maxlen argument of rtnl_talk(), it is truncated - to maxlen but unlike in the case of truncation to the length of local - buffer in rtnl_talk(), the caller doesn't get any indication of a problem. - - In particular, iplink_get() passes the truncated message on and parsing it - results in various warnings and sometimes even a segfault (observed with - "ip link show dev ..." for a NIC with 125 VFs). - - Handle message truncation in iplink_get() the same way as truncation in - rtnl_talk() would be handled: return an error. - - Signed-off-by: Michal Kubecek - -Signed-off-by: Hangbin Liu ---- - ip/iplink.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/ip/iplink.c b/ip/iplink.c -index da3f9a779351c..2b2421f9a2281 100644 ---- a/ip/iplink.c -+++ b/ip/iplink.c -@@ -1031,6 +1031,11 @@ int iplink_get(unsigned int flags, char *name, __u32 filt_mask) - - if (rtnl_talk(&rth, &req.n, &answer.n, sizeof(answer)) < 0) - return -2; -+ if (answer.n.nlmsg_len > sizeof(answer.buf)) { -+ fprintf(stderr, "Message truncated from %u to %lu\n", -+ answer.n.nlmsg_len, sizeof(answer.buf)); -+ return -2; -+ } - - if (brief) - print_linkinfo_brief(NULL, &answer.n, stdout); --- -2.21.0 - diff --git a/SOURCES/0021-iplink-double-the-buffer-size-also-in-iplink_get.patch b/SOURCES/0021-iplink-double-the-buffer-size-also-in-iplink_get.patch deleted file mode 100644 index 4cab164..0000000 --- a/SOURCES/0021-iplink-double-the-buffer-size-also-in-iplink_get.patch +++ /dev/null @@ -1,48 +0,0 @@ -From c560900fc16eeac064cc7c43a96c5343fe68ae76 Mon Sep 17 00:00:00 2001 -From: Hangbin Liu -Date: Wed, 8 Nov 2017 14:39:11 +0800 -Subject: [PATCH] iplink: double the buffer size also in iplink_get() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1380803 -Upstream Status: iproute2.git commit 460c03f3f3cc - -commit 460c03f3f3cc436ff4673d75722ba68a6ec9343d -Author: Michal Kubecek -Date: Fri Sep 1 18:39:16 2017 +0200 - - iplink: double the buffer size also in iplink_get() - - Commit 72b365e8e0fd ("libnetlink: Double the dump buffer size") increased - the buffer size for "ip link show" command to 32 KB to handle NICs with - large number of VFs. With "dev" filter, a different code path is taken and - iplink_get() still uses only 16 KB buffer. - - The size of 32768 is not very future-proof as NICs supporting 120-128 VFs - are already in use so that single RTM_NEWLINK message in the dump can - exceed 30000 bytes. But it's what rtnl_talk() and rtnl_dump_filter_l() use - so let's be consistent. Once this proves insufficient, all three sizes - should be increased. - - Signed-off-by: Michal Kubecek - -Signed-off-by: Hangbin Liu ---- - ip/iplink.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ip/iplink.c b/ip/iplink.c -index 2b2421f9a2281..5afbadf0ce383 100644 ---- a/ip/iplink.c -+++ b/ip/iplink.c -@@ -1015,7 +1015,7 @@ int iplink_get(unsigned int flags, char *name, __u32 filt_mask) - }; - struct { - struct nlmsghdr n; -- char buf[16384]; -+ char buf[32768]; - } answer; - - if (name) { --- -2.21.0 - diff --git a/SOURCES/0022-lib-libnetlink-re-malloc-buff-if-size-is-not-enough.patch b/SOURCES/0022-lib-libnetlink-re-malloc-buff-if-size-is-not-enough.patch deleted file mode 100644 index f37143d..0000000 --- a/SOURCES/0022-lib-libnetlink-re-malloc-buff-if-size-is-not-enough.patch +++ /dev/null @@ -1,252 +0,0 @@ -From 49e7c0e7c8c9a982fd3aa69bbed4e306a1dcb331 Mon Sep 17 00:00:00 2001 -From: Hangbin Liu -Date: Wed, 8 Nov 2017 14:39:12 +0800 -Subject: [PATCH] lib/libnetlink: re malloc buff if size is not enough - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1380803 -Upstream Status: iproute2.git net-next commit 2d34851cd341 - -commit 2d34851cd341f0e1b3fc17ca3e6e874229f3a1f8 -Author: Hangbin Liu -Date: Thu Oct 26 09:41:46 2017 +0800 - - lib/libnetlink: re malloc buff if size is not enough - - With commit 72b365e8e0fd ("libnetlink: Double the dump buffer size") - we doubled the buffer size to support more VFs. But the VFs number is - increasing all the time. Some customers even use more than 200 VFs now. - - We could not double it everytime when the buffer is not enough. Let's just - not hard code the buffer size and malloc the correct number when running. - - Introduce function rtnl_recvmsg() to always return a newly allocated buffer. - The caller need to free it after using. - - Signed-off-by: Hangbin Liu - Signed-off-by: Phil Sutter - -Signed-off-by: Hangbin Liu ---- - lib/libnetlink.c | 114 +++++++++++++++++++++++++++++++++-------------- - 1 file changed, 80 insertions(+), 34 deletions(-) - -diff --git a/lib/libnetlink.c b/lib/libnetlink.c -index a0578312e83f8..446c9605ba19b 100644 ---- a/lib/libnetlink.c -+++ b/lib/libnetlink.c -@@ -386,6 +386,64 @@ static void rtnl_dump_error(const struct rtnl_handle *rth, - } - } - -+static int __rtnl_recvmsg(int fd, struct msghdr *msg, int flags) -+{ -+ int len; -+ -+ do { -+ len = recvmsg(fd, msg, flags); -+ } while (len < 0 && (errno == EINTR || errno == EAGAIN)); -+ -+ if (len < 0) { -+ fprintf(stderr, "netlink receive error %s (%d)\n", -+ strerror(errno), errno); -+ return -errno; -+ } -+ -+ if (len == 0) { -+ fprintf(stderr, "EOF on netlink\n"); -+ return -ENODATA; -+ } -+ -+ return len; -+} -+ -+static int rtnl_recvmsg(int fd, struct msghdr *msg, char **answer) -+{ -+ struct iovec *iov = msg->msg_iov; -+ char *buf; -+ int len; -+ -+ iov->iov_base = NULL; -+ iov->iov_len = 0; -+ -+ len = __rtnl_recvmsg(fd, msg, MSG_PEEK | MSG_TRUNC); -+ if (len < 0) -+ return len; -+ -+ buf = malloc(len); -+ if (!buf) { -+ fprintf(stderr, "malloc error: not enough buffer\n"); -+ return -ENOMEM; -+ } -+ -+ iov->iov_base = buf; -+ iov->iov_len = len; -+ -+ len = __rtnl_recvmsg(fd, msg, 0); -+ if (len < 0) { -+ free(buf); -+ return len; -+ } -+ -+ if (answer) -+ *answer = buf; -+ else -+ free(buf); -+ -+ return len; -+} -+ - int rtnl_dump_filter_l(struct rtnl_handle *rth, - const struct rtnl_dump_filter_arg *arg) - { -@@ -397,31 +455,18 @@ int rtnl_dump_filter_l(struct rtnl_handle *rth, - .msg_iov = &iov, - .msg_iovlen = 1, - }; -- char buf[32768]; -+ char *buf; - int dump_intr = 0; - -- iov.iov_base = buf; - while (1) { - int status; - const struct rtnl_dump_filter_arg *a; - int found_done = 0; - int msglen = 0; - -- iov.iov_len = sizeof(buf); -- status = recvmsg(rth->fd, &msg, 0); -- -- if (status < 0) { -- if (errno == EINTR || errno == EAGAIN) -- continue; -- fprintf(stderr, "netlink receive error %s (%d)\n", -- strerror(errno), errno); -- return -1; -- } -- -- if (status == 0) { -- fprintf(stderr, "EOF on netlink\n"); -- return -1; -- } -+ status = rtnl_recvmsg(rth->fd, &msg, &buf); -+ if (status < 0) -+ return status; - - if (rth->dump_fp) - fwrite(buf, 1, NLMSG_ALIGN(status), rth->dump_fp); -@@ -446,8 +491,10 @@ int rtnl_dump_filter_l(struct rtnl_handle *rth, - - if (h->nlmsg_type == NLMSG_DONE) { - err = rtnl_dump_done(h); -- if (err < 0) -+ if (err < 0) { -+ free(buf); - return -1; -+ } - - found_done = 1; - break; /* process next filter */ -@@ -455,19 +502,23 @@ int rtnl_dump_filter_l(struct rtnl_handle *rth, - - if (h->nlmsg_type == NLMSG_ERROR) { - rtnl_dump_error(rth, h); -+ free(buf); - return -1; - } - - if (!rth->dump_fp) { - err = a->filter(&nladdr, h, a->arg1); -- if (err < 0) -+ if (err < 0) { -+ free(buf); - return err; -+ } - } - - skip_it: - h = NLMSG_NEXT(h, msglen); - } - } -+ free(buf); - - if (found_done) { - if (dump_intr) -@@ -527,7 +578,7 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, - .msg_iov = &iov, - .msg_iovlen = 1, - }; -- char buf[32768] = {}; -+ char *buf; - - n->nlmsg_seq = seq = ++rtnl->seq; - -@@ -540,22 +591,12 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, - return -1; - } - -- iov.iov_base = buf; - while (1) { -- iov.iov_len = sizeof(buf); -- status = recvmsg(rtnl->fd, &msg, 0); -+ status = rtnl_recvmsg(rtnl->fd, &msg, &buf); -+ -+ if (status < 0) -+ return status; - -- if (status < 0) { -- if (errno == EINTR || errno == EAGAIN) -- continue; -- fprintf(stderr, "netlink receive error %s (%d)\n", -- strerror(errno), errno); -- return -1; -- } -- if (status == 0) { -- fprintf(stderr, "EOF on netlink\n"); -- return -1; -- } - if (msg.msg_namelen != sizeof(nladdr)) { - fprintf(stderr, - "sender address length == %d\n", -@@ -569,6 +610,7 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, - if (l < 0 || len > status) { - if (msg.msg_flags & MSG_TRUNC) { - fprintf(stderr, "Truncated message\n"); -+ free(buf); - return -1; - } - fprintf(stderr, -@@ -595,6 +637,7 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, - if (answer) - memcpy(answer, h, - MIN(maxlen, h->nlmsg_len)); -+ free(buf); - return 0; - } - -@@ -603,12 +646,14 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, - rtnl_talk_error(h, err, errfn); - - errno = -err->error; -+ free(buf); - return -1; - } - - if (answer) { - memcpy(answer, h, - MIN(maxlen, h->nlmsg_len)); -+ free(buf); - return 0; - } - -@@ -617,6 +662,7 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, - status -= NLMSG_ALIGN(len); - h = (struct nlmsghdr *)((char *)h + NLMSG_ALIGN(len)); - } -+ free(buf); - - if (msg.msg_flags & MSG_TRUNC) { - fprintf(stderr, "Message truncated\n"); --- -2.21.0 - diff --git a/SOURCES/0023-lib-libnetlink-update-rtnl_talk-to-support-malloc-bu.patch b/SOURCES/0023-lib-libnetlink-update-rtnl_talk-to-support-malloc-bu.patch deleted file mode 100644 index 60ed8a0..0000000 --- a/SOURCES/0023-lib-libnetlink-update-rtnl_talk-to-support-malloc-bu.patch +++ /dev/null @@ -1,1604 +0,0 @@ -From 3d76c7eea3caaddcc0608ad35a9e6fab3df11f8e Mon Sep 17 00:00:00 2001 -From: Hangbin Liu -Date: Wed, 8 Nov 2017 14:39:13 +0800 -Subject: [PATCH] lib/libnetlink: update rtnl_talk to support malloc buff at - run time - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1380803 -Upstream Status: iproute2.git net-next commit 86bf43c7c2fd - -Conflicts: -- iplink_get@ip/iplink.c: no function open_json_object() due to missing - e4a1216aeb2a ("ip: iplink.c: open/close json obj for ip -brief -json link - show dev DEV"). Lack of last parameter for print_linkinfo_brief() due to - missing 63891c70137f ("ip address: Change print_linkinfo_brief to take - filter as an input") -- gre_parse_opt@ip/link_gre.c: context conflicts due to missing new - flag IFLA_GRE_ERSPAN_INDEX. -- gre_parse_opt@ip/link_gre6.c: context conflicts due to missing new - flag IFLA_GRE_FWMARK. -- ip6tunnel_parse_opt@ip/link_ip6tnl.c: context conflicts due to missing new - flag IFLA_IPTUN_FWMARK. -- iptunnel_parse_opt@ip/link_iptnl.c: context conflicts due to missing new - flag IFLA_IPTUN_FWMARK. -- vti_parse_opt@ip/link_vti.c: context conflicts due to missing new flag - IFLA_VTI_FWMARK -- vti6_parse_opt@ip/link_vti6.c: context conflicts due to missing new flag - IFLA_VTI_FWMARK - -commit 86bf43c7c2fdc33d7c021b4a1add1c8facbca51c -Author: Hangbin Liu -Date: Thu Oct 26 09:41:47 2017 +0800 - - lib/libnetlink: update rtnl_talk to support malloc buff at run time - - This is an update for 460c03f3f3cc ("iplink: double the buffer size also in - iplink_get()"). After update, we will not need to double the buffer size - every time when VFs number increased. - - With call like rtnl_talk(&rth, &req.n, NULL, 0), we can simply remove the - length parameter. - - With call like rtnl_talk(&rth, nlh, nlh, sizeof(req), I add a new variable - answer to avoid overwrite data in nlh, because it may has more info after - nlh. also this will avoid nlh buffer not enough issue. - - We need to free answer after using. - - Signed-off-by: Hangbin Liu - Signed-off-by: Phil Sutter - -Signed-off-by: Hangbin Liu ---- - bridge/fdb.c | 2 +- - bridge/link.c | 2 +- - bridge/mdb.c | 2 +- - bridge/vlan.c | 2 +- - genl/ctrl.c | 19 ++++++++++++------- - include/libnetlink.h | 6 +++--- - ip/ipaddress.c | 4 ++-- - ip/ipaddrlabel.c | 4 ++-- - ip/ipfou.c | 4 ++-- - ip/ipila.c | 4 ++-- - ip/ipl2tp.c | 8 ++++---- - ip/iplink.c | 38 +++++++++++++++++++------------------- - ip/iplink_vrf.c | 44 ++++++++++++++++++++------------------------ - ip/ipmacsec.c | 2 +- - ip/ipneigh.c | 2 +- - ip/ipnetns.c | 23 ++++++++++++++--------- - ip/ipntable.c | 2 +- - ip/iproute.c | 26 +++++++++++++++++--------- - ip/iprule.c | 6 +++--- - ip/iptoken.c | 2 +- - ip/link_gre.c | 11 +++++++---- - ip/link_gre6.c | 11 +++++++---- - ip/link_ip6tnl.c | 11 +++++++---- - ip/link_iptnl.c | 11 +++++++---- - ip/link_vti.c | 11 +++++++---- - ip/link_vti6.c | 11 +++++++---- - ip/tcp_metrics.c | 8 +++++--- - ip/xfrm_policy.c | 25 +++++++++++++------------ - ip/xfrm_state.c | 30 ++++++++++++++++-------------- - lib/libgenl.c | 9 +++++++-- - lib/libnetlink.c | 24 +++++++++++------------- - misc/ss.c | 2 +- - tc/m_action.c | 12 ++++++------ - tc/tc_class.c | 2 +- - tc/tc_filter.c | 8 +++++--- - tc/tc_qdisc.c | 2 +- - 36 files changed, 216 insertions(+), 174 deletions(-) - -diff --git a/bridge/fdb.c b/bridge/fdb.c -index a71a78f23b202..4859edb2473b7 100644 ---- a/bridge/fdb.c -+++ b/bridge/fdb.c -@@ -529,7 +529,7 @@ static int fdb_modify(int cmd, int flags, int argc, char **argv) - return -1; - } - -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) - return -1; - - return 0; -diff --git a/bridge/link.c b/bridge/link.c -index 93472ad3699e3..cc29a2adb2e01 100644 ---- a/bridge/link.c -+++ b/bridge/link.c -@@ -426,7 +426,7 @@ static int brlink_modify(int argc, char **argv) - addattr_nest_end(&req.n, nest); - } - -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) - return -1; - - return 0; -diff --git a/bridge/mdb.c b/bridge/mdb.c -index e60ff3ef3f485..fbd8184dacf85 100644 ---- a/bridge/mdb.c -+++ b/bridge/mdb.c -@@ -298,7 +298,7 @@ static int mdb_modify(int cmd, int flags, int argc, char **argv) - entry.vid = vid; - addattr_l(&req.n, sizeof(req), MDBA_SET_ENTRY, &entry, sizeof(entry)); - -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) - return -1; - - return 0; -diff --git a/bridge/vlan.c b/bridge/vlan.c -index ebcdacee309bc..5d683595e0e32 100644 ---- a/bridge/vlan.c -+++ b/bridge/vlan.c -@@ -133,7 +133,7 @@ static int vlan_modify(int cmd, int argc, char **argv) - - addattr_nest_end(&req.n, afspec); - -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) - return -1; - - return 0; -diff --git a/genl/ctrl.c b/genl/ctrl.c -index 6abd52582d0d3..21e857cfcfc25 100644 ---- a/genl/ctrl.c -+++ b/genl/ctrl.c -@@ -55,6 +55,7 @@ int genl_ctrl_resolve_family(const char *family) - }; - struct nlmsghdr *nlh = &req.n; - struct genlmsghdr *ghdr = &req.g; -+ struct nlmsghdr *answer = NULL; - - if (rtnl_open_byproto(&rth, 0, NETLINK_GENERIC) < 0) { - fprintf(stderr, "Cannot open generic netlink socket\n"); -@@ -63,19 +64,19 @@ int genl_ctrl_resolve_family(const char *family) - - addattr_l(nlh, 128, CTRL_ATTR_FAMILY_NAME, family, strlen(family) + 1); - -- if (rtnl_talk(&rth, nlh, nlh, sizeof(req)) < 0) { -+ if (rtnl_talk(&rth, nlh, &answer) < 0) { - fprintf(stderr, "Error talking to the kernel\n"); - goto errout; - } - - { - struct rtattr *tb[CTRL_ATTR_MAX + 1]; -- int len = nlh->nlmsg_len; -+ int len = answer->nlmsg_len; - struct rtattr *attrs; - -- if (nlh->nlmsg_type != GENL_ID_CTRL) { -+ if (answer->nlmsg_type != GENL_ID_CTRL) { - fprintf(stderr, "Not a controller message, nlmsg_len=%d " -- "nlmsg_type=0x%x\n", nlh->nlmsg_len, nlh->nlmsg_type); -+ "nlmsg_type=0x%x\n", answer->nlmsg_len, answer->nlmsg_type); - goto errout; - } - -@@ -88,10 +89,11 @@ int genl_ctrl_resolve_family(const char *family) - - if (len < 0) { - fprintf(stderr, "wrong controller message len %d\n", len); -+ free(answer); - return -1; - } - -- attrs = (struct rtattr *) ((char *) ghdr + GENL_HDRLEN); -+ attrs = (struct rtattr *) ((char *) answer + NLMSG_LENGTH(GENL_HDRLEN)); - parse_rtattr(tb, CTRL_ATTR_MAX, attrs, len); - - if (tb[CTRL_ATTR_FAMILY_ID] == NULL) { -@@ -103,6 +105,7 @@ int genl_ctrl_resolve_family(const char *family) - } - - errout: -+ free(answer); - rtnl_close(&rth); - return ret; - } -@@ -299,6 +302,7 @@ static int ctrl_list(int cmd, int argc, char **argv) - .g.cmd = CTRL_CMD_GETFAMILY, - }; - struct nlmsghdr *nlh = &req.n; -+ struct nlmsghdr *answer = NULL; - - if (rtnl_open_byproto(&rth, 0, NETLINK_GENERIC) < 0) { - fprintf(stderr, "Cannot open generic netlink socket\n"); -@@ -331,12 +335,12 @@ static int ctrl_list(int cmd, int argc, char **argv) - goto ctrl_done; - } - -- if (rtnl_talk(&rth, nlh, nlh, sizeof(req)) < 0) { -+ if (rtnl_talk(&rth, nlh, &answer) < 0) { - fprintf(stderr, "Error talking to the kernel\n"); - goto ctrl_done; - } - -- if (print_ctrl2(NULL, nlh, (void *) stdout) < 0) { -+ if (print_ctrl2(NULL, answer, (void *) stdout) < 0) { - fprintf(stderr, "Dump terminated\n"); - goto ctrl_done; - } -@@ -358,6 +362,7 @@ static int ctrl_list(int cmd, int argc, char **argv) - - ret = 0; - ctrl_done: -+ free(answer); - rtnl_close(&rth); - return ret; - } -diff --git a/include/libnetlink.h b/include/libnetlink.h -index 654aebc0f7632..2136d2bdd0379 100644 ---- a/include/libnetlink.h -+++ b/include/libnetlink.h -@@ -82,13 +82,13 @@ int rtnl_dump_filter_nc(struct rtnl_handle *rth, - #define rtnl_dump_filter(rth, filter, arg) \ - rtnl_dump_filter_nc(rth, filter, arg, 0) - int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, -- struct nlmsghdr *answer, size_t len) -+ struct nlmsghdr **answer) - __attribute__((warn_unused_result)); - int rtnl_talk_extack(struct rtnl_handle *rtnl, struct nlmsghdr *n, -- struct nlmsghdr *answer, size_t len, nl_ext_ack_fn_t errfn) -+ struct nlmsghdr **answer, nl_ext_ack_fn_t errfn) - __attribute__((warn_unused_result)); - int rtnl_talk_suppress_rtnl_errmsg(struct rtnl_handle *rtnl, struct nlmsghdr *n, -- struct nlmsghdr *answer, size_t len) -+ struct nlmsghdr **answer) - __attribute__((warn_unused_result)); - int rtnl_send(struct rtnl_handle *rth, const void *buf, int) - __attribute__((warn_unused_result)); -diff --git a/ip/ipaddress.c b/ip/ipaddress.c -index b8d9c7d917fe8..7492075687a9e 100644 ---- a/ip/ipaddress.c -+++ b/ip/ipaddress.c -@@ -1356,7 +1356,7 @@ static int restore_handler(const struct sockaddr_nl *nl, - - ll_init_map(&rth); - -- ret = rtnl_talk(&rth, n, n, sizeof(*n)); -+ ret = rtnl_talk(&rth, n, NULL); - if ((ret < 0) && (errno == EEXIST)) - ret = 0; - -@@ -2064,7 +2064,7 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv) - return -1; - } - -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) - return -2; - - return 0; -diff --git a/ip/ipaddrlabel.c b/ip/ipaddrlabel.c -index 1d324dac02119..6ea9bfffdd0d1 100644 ---- a/ip/ipaddrlabel.c -+++ b/ip/ipaddrlabel.c -@@ -176,7 +176,7 @@ static int ipaddrlabel_modify(int cmd, int argc, char **argv) - if (req.ifal.ifal_family == AF_UNSPEC) - req.ifal.ifal_family = AF_INET6; - -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) - return -2; - - return 0; -@@ -203,7 +203,7 @@ static int flush_addrlabel(const struct sockaddr_nl *who, struct nlmsghdr *n, vo - if (rtnl_open(&rth2, 0) < 0) - return -1; - -- if (rtnl_talk(&rth2, n, NULL, 0) < 0) -+ if (rtnl_talk(&rth2, n, NULL) < 0) - return -2; - - rtnl_close(&rth2); -diff --git a/ip/ipfou.c b/ip/ipfou.c -index 00dbe150710d2..23000dc696d6a 100644 ---- a/ip/ipfou.c -+++ b/ip/ipfou.c -@@ -116,7 +116,7 @@ static int do_add(int argc, char **argv) - - fou_parse_opt(argc, argv, &req.n, true); - -- if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&genl_rth, &req.n, NULL) < 0) - return -2; - - return 0; -@@ -128,7 +128,7 @@ static int do_del(int argc, char **argv) - - fou_parse_opt(argc, argv, &req.n, false); - -- if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&genl_rth, &req.n, NULL) < 0) - return -2; - - return 0; -diff --git a/ip/ipila.c b/ip/ipila.c -index 843cc1652589f..0403fc4238b9d 100644 ---- a/ip/ipila.c -+++ b/ip/ipila.c -@@ -220,7 +220,7 @@ static int do_add(int argc, char **argv) - - ila_parse_opt(argc, argv, &req.n, true); - -- if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&genl_rth, &req.n, NULL) < 0) - return -2; - - return 0; -@@ -232,7 +232,7 @@ static int do_del(int argc, char **argv) - - ila_parse_opt(argc, argv, &req.n, false); - -- if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&genl_rth, &req.n, NULL) < 0) - return -2; - - return 0; -diff --git a/ip/ipl2tp.c b/ip/ipl2tp.c -index 88664c909e11f..742adbe4f9c3a 100644 ---- a/ip/ipl2tp.c -+++ b/ip/ipl2tp.c -@@ -129,7 +129,7 @@ static int create_tunnel(struct l2tp_parm *p) - addattr(&req.n, 1024, L2TP_ATTR_UDP_ZERO_CSUM6_RX); - } - -- if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&genl_rth, &req.n, NULL) < 0) - return -2; - - return 0; -@@ -142,7 +142,7 @@ static int delete_tunnel(struct l2tp_parm *p) - - addattr32(&req.n, 128, L2TP_ATTR_CONN_ID, p->tunnel_id); - -- if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&genl_rth, &req.n, NULL) < 0) - return -2; - - return 0; -@@ -185,7 +185,7 @@ static int create_session(struct l2tp_parm *p) - if (p->ifname && p->ifname[0]) - addattrstrz(&req.n, 1024, L2TP_ATTR_IFNAME, p->ifname); - -- if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&genl_rth, &req.n, NULL) < 0) - return -2; - - return 0; -@@ -198,7 +198,7 @@ static int delete_session(struct l2tp_parm *p) - - addattr32(&req.n, 1024, L2TP_ATTR_CONN_ID, p->tunnel_id); - addattr32(&req.n, 1024, L2TP_ATTR_SESSION_ID, p->session_id); -- if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&genl_rth, &req.n, NULL) < 0) - return -2; - - return 0; -diff --git a/ip/iplink.c b/ip/iplink.c -index 5afbadf0ce383..b08d227d44bee 100644 ---- a/ip/iplink.c -+++ b/ip/iplink.c -@@ -247,19 +247,26 @@ static int nl_get_ll_addr_len(unsigned int dev_index) - .ifi_index = dev_index, - } - }; -+ struct nlmsghdr *answer; - struct rtattr *tb[IFLA_MAX+1]; - -- if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0) -+ if (rtnl_talk(&rth, &req.n, &answer) < 0) - return -1; - -- len = req.n.nlmsg_len - NLMSG_LENGTH(sizeof(req.i)); -- if (len < 0) -+ len = answer->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifinfomsg)); -+ if (len < 0) { -+ free(answer); - return -1; -+ } - -- parse_rtattr_flags(tb, IFLA_MAX, IFLA_RTA(&req.i), len, NLA_F_NESTED); -- if (!tb[IFLA_ADDRESS]) -+ parse_rtattr_flags(tb, IFLA_MAX, IFLA_RTA(NLMSG_DATA(answer)), -+ len, NLA_F_NESTED); -+ if (!tb[IFLA_ADDRESS]) { -+ free(answer); - return -1; -+ } - -+ free(answer); - return RTA_PAYLOAD(tb[IFLA_ADDRESS]); - } - -@@ -903,7 +910,7 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv) - - req.i.ifi_index = 0; - addattr32(&req.n, sizeof(req), IFLA_GROUP, group); -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) - return -2; - return 0; - } -@@ -998,7 +1005,7 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv) - return -1; - } - -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) - return -2; - - return 0; -@@ -1013,10 +1020,7 @@ int iplink_get(unsigned int flags, char *name, __u32 filt_mask) - .n.nlmsg_type = RTM_GETLINK, - .i.ifi_family = preferred_family, - }; -- struct { -- struct nlmsghdr n; -- char buf[32768]; -- } answer; -+ struct nlmsghdr *answer; - - if (name) { - len = strlen(name) + 1; -@@ -1029,19 +1033,15 @@ int iplink_get(unsigned int flags, char *name, __u32 filt_mask) - } - addattr32(&req.n, sizeof(req), IFLA_EXT_MASK, filt_mask); - -- if (rtnl_talk(&rth, &req.n, &answer.n, sizeof(answer)) < 0) -- return -2; -- if (answer.n.nlmsg_len > sizeof(answer.buf)) { -- fprintf(stderr, "Message truncated from %u to %lu\n", -- answer.n.nlmsg_len, sizeof(answer.buf)); -+ if (rtnl_talk(&rth, &req.n, &answer) < 0) - return -2; -- } - - if (brief) -- print_linkinfo_brief(NULL, &answer.n, stdout); -+ print_linkinfo_brief(NULL, answer, stdout); - else -- print_linkinfo(NULL, &answer.n, stdout); -+ print_linkinfo(NULL, answer, stdout); - -+ free(answer); - return 0; - } - -diff --git a/ip/iplink_vrf.c b/ip/iplink_vrf.c -index 917630e853375..370bb86815a80 100644 ---- a/ip/iplink_vrf.c -+++ b/ip/iplink_vrf.c -@@ -114,10 +114,7 @@ __u32 ipvrf_get_table(const char *name) - .ifi_family = preferred_family, - }, - }; -- struct { -- struct nlmsghdr n; -- char buf[8192]; -- } answer; -+ struct nlmsghdr *answer; - struct rtattr *tb[IFLA_MAX+1]; - struct rtattr *li[IFLA_INFO_MAX+1]; - struct rtattr *vrf_attr[IFLA_VRF_MAX + 1]; -@@ -127,8 +124,7 @@ __u32 ipvrf_get_table(const char *name) - - addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name, strlen(name) + 1); - -- if (rtnl_talk_suppress_rtnl_errmsg(&rth, &req.n, -- &answer.n, sizeof(answer)) < 0) { -+ if (rtnl_talk_suppress_rtnl_errmsg(&rth, &req.n, &answer) < 0) { - /* special case "default" vrf to be the main table */ - if (errno == ENODEV && !strcmp(name, "default")) - rtnl_rttable_a2n(&tb_id, "main"); -@@ -136,25 +132,25 @@ __u32 ipvrf_get_table(const char *name) - return tb_id; - } - -- ifi = NLMSG_DATA(&answer.n); -- len = answer.n.nlmsg_len - NLMSG_LENGTH(sizeof(*ifi)); -+ ifi = NLMSG_DATA(answer); -+ len = answer->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi)); - if (len < 0) { - fprintf(stderr, "BUG: Invalid response to link query.\n"); -- return 0; -+ goto out; - } - - parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); - - if (!tb[IFLA_LINKINFO]) -- return 0; -+ goto out; - - parse_rtattr_nested(li, IFLA_INFO_MAX, tb[IFLA_LINKINFO]); - - if (!li[IFLA_INFO_KIND] || !li[IFLA_INFO_DATA]) -- return 0; -+ goto out; - - if (strcmp(RTA_DATA(li[IFLA_INFO_KIND]), "vrf")) -- return 0; -+ goto out; - - parse_rtattr_nested(vrf_attr, IFLA_VRF_MAX, li[IFLA_INFO_DATA]); - if (vrf_attr[IFLA_VRF_TABLE]) -@@ -163,6 +159,8 @@ __u32 ipvrf_get_table(const char *name) - if (!tb_id) - fprintf(stderr, "BUG: VRF %s is missing table id\n", name); - -+out: -+ free(answer); - return tb_id; - } - -@@ -182,10 +180,7 @@ int name_is_vrf(const char *name) - .ifi_family = preferred_family, - }, - }; -- struct { -- struct nlmsghdr n; -- char buf[8192]; -- } answer; -+ struct nlmsghdr *answer; - struct rtattr *tb[IFLA_MAX+1]; - struct rtattr *li[IFLA_INFO_MAX+1]; - struct ifinfomsg *ifi; -@@ -193,29 +188,30 @@ int name_is_vrf(const char *name) - - addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name, strlen(name) + 1); - -- if (rtnl_talk_suppress_rtnl_errmsg(&rth, &req.n, -- &answer.n, sizeof(answer)) < 0) -+ if (rtnl_talk_suppress_rtnl_errmsg(&rth, &req.n, &answer) < 0) - return 0; - -- ifi = NLMSG_DATA(&answer.n); -- len = answer.n.nlmsg_len - NLMSG_LENGTH(sizeof(*ifi)); -+ ifi = NLMSG_DATA(answer); -+ len = answer->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi)); - if (len < 0) { - fprintf(stderr, "BUG: Invalid response to link query.\n"); -- return 0; -+ goto out; - } - - parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); - - if (!tb[IFLA_LINKINFO]) -- return 0; -+ goto out; - - parse_rtattr_nested(li, IFLA_INFO_MAX, tb[IFLA_LINKINFO]); - - if (!li[IFLA_INFO_KIND]) -- return 0; -+ goto out; - - if (strcmp(RTA_DATA(li[IFLA_INFO_KIND]), "vrf")) -- return 0; -+ goto out; - -+out: -+ free(answer); - return ifi->ifi_index; - } -diff --git a/ip/ipmacsec.c b/ip/ipmacsec.c -index aa89a00f5aad6..9a2d0ebf82091 100644 ---- a/ip/ipmacsec.c -+++ b/ip/ipmacsec.c -@@ -421,7 +421,7 @@ static int do_modify_nl(enum cmd c, enum macsec_nl_commands cmd, int ifindex, - addattr_nest_end(&req.n, attr_sa); - - talk: -- if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&genl_rth, &req.n, NULL) < 0) - return -2; - - return 0; -diff --git a/ip/ipneigh.c b/ip/ipneigh.c -index 9c38a60ddf4fe..32f2d553c712f 100644 ---- a/ip/ipneigh.c -+++ b/ip/ipneigh.c -@@ -184,7 +184,7 @@ static int ipneigh_modify(int cmd, int flags, int argc, char **argv) - return -1; - } - -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) - exit(2); - - return 0; -diff --git a/ip/ipnetns.c b/ip/ipnetns.c -index 4254994442ccd..1c0ade90dee5e 100644 ---- a/ip/ipnetns.c -+++ b/ip/ipnetns.c -@@ -95,12 +95,13 @@ static int get_netnsid_from_name(const char *name) - struct nlmsghdr n; - struct rtgenmsg g; - char buf[1024]; -- } answer, req = { -+ } req = { - .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)), - .n.nlmsg_flags = NLM_F_REQUEST, - .n.nlmsg_type = RTM_GETNSID, - .g.rtgen_family = AF_UNSPEC, - }; -+ struct nlmsghdr *answer; - struct rtattr *tb[NETNSA_MAX + 1]; - struct rtgenmsg *rthdr; - int len, fd; -@@ -110,26 +111,30 @@ static int get_netnsid_from_name(const char *name) - return fd; - - addattr32(&req.n, 1024, NETNSA_FD, fd); -- if (rtnl_talk(&rtnsh, &req.n, &answer.n, sizeof(answer)) < 0) { -+ if (rtnl_talk(&rtnsh, &req.n, &answer) < 0) { - close(fd); - return -2; - } - close(fd); - - /* Validate message and parse attributes */ -- if (answer.n.nlmsg_type == NLMSG_ERROR) -- return -1; -+ if (answer->nlmsg_type == NLMSG_ERROR) -+ goto err_out; - -- rthdr = NLMSG_DATA(&answer.n); -- len = answer.n.nlmsg_len - NLMSG_SPACE(sizeof(*rthdr)); -+ rthdr = NLMSG_DATA(answer); -+ len = answer->nlmsg_len - NLMSG_SPACE(sizeof(*rthdr)); - if (len < 0) -- return -1; -+ goto err_out; - - parse_rtattr(tb, NETNSA_MAX, NETNS_RTA(rthdr), len); - -- if (tb[NETNSA_NSID]) -+ if (tb[NETNSA_NSID]) { -+ free(answer); - return rta_getattr_u32(tb[NETNSA_NSID]); -+ } - -+err_out: -+ free(answer); - return -1; - } - -@@ -690,7 +695,7 @@ static int set_netnsid_from_name(const char *name, int nsid) - - addattr32(&req.n, 1024, NETNSA_FD, fd); - addattr32(&req.n, 1024, NETNSA_NSID, nsid); -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) - err = -2; - - close(fd); -diff --git a/ip/ipntable.c b/ip/ipntable.c -index 879626ee4f491..65063321c85f8 100644 ---- a/ip/ipntable.c -+++ b/ip/ipntable.c -@@ -306,7 +306,7 @@ static int ipntable_modify(int cmd, int flags, int argc, char **argv) - RTA_PAYLOAD(parms_rta)); - } - -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) - exit(2); - - return 0; -diff --git a/ip/iproute.c b/ip/iproute.c -index 5e23613dadbaf..35fdce8a64f35 100644 ---- a/ip/iproute.c -+++ b/ip/iproute.c -@@ -1271,7 +1271,7 @@ static int iproute_modify(int cmd, unsigned int flags, int argc, char **argv) - if (!type_ok && req.r.rtm_family == AF_MPLS) - req.r.rtm_type = RTN_UNICAST; - -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) - return -2; - - return 0; -@@ -1649,6 +1649,7 @@ static int iproute_get(int argc, char **argv) - }; - char *idev = NULL; - char *odev = NULL; -+ struct nlmsghdr *answer; - int connected = 0; - int from_ok = 0; - unsigned int mark = 0; -@@ -1753,26 +1754,29 @@ static int iproute_get(int argc, char **argv) - - req.r.rtm_flags |= RTM_F_LOOKUP_TABLE; - -- if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0) -+ if (rtnl_talk(&rth, &req.n, &answer) < 0) - return -2; - - if (connected && !from_ok) { -- struct rtmsg *r = NLMSG_DATA(&req.n); -- int len = req.n.nlmsg_len; -+ struct rtmsg *r = NLMSG_DATA(answer); -+ int len = answer->nlmsg_len; - struct rtattr *tb[RTA_MAX+1]; - -- if (print_route(NULL, &req.n, (void *)stdout) < 0) { -+ if (print_route(NULL, answer, (void *)stdout) < 0) { - fprintf(stderr, "An error :-)\n"); -+ free(answer); - return -1; - } - -- if (req.n.nlmsg_type != RTM_NEWROUTE) { -+ if (answer->nlmsg_type != RTM_NEWROUTE) { - fprintf(stderr, "Not a route?\n"); -+ free(answer); - return -1; - } - len -= NLMSG_LENGTH(sizeof(*r)); - if (len < 0) { - fprintf(stderr, "Wrong len %d\n", len); -+ free(answer); - return -1; - } - -@@ -1783,6 +1787,7 @@ static int iproute_get(int argc, char **argv) - r->rtm_src_len = 8*RTA_PAYLOAD(tb[RTA_PREFSRC]); - } else if (!tb[RTA_SRC]) { - fprintf(stderr, "Failed to connect the route\n"); -+ free(answer); - return -1; - } - if (!odev && tb[RTA_OIF]) -@@ -1796,15 +1801,18 @@ static int iproute_get(int argc, char **argv) - req.n.nlmsg_flags = NLM_F_REQUEST; - req.n.nlmsg_type = RTM_GETROUTE; - -- if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0) -+ free(answer); -+ if (rtnl_talk(&rth, &req.n, &answer) < 0) - return -2; - } - -- if (print_route(NULL, &req.n, (void *)stdout) < 0) { -+ if (print_route(NULL, answer, (void *)stdout) < 0) { - fprintf(stderr, "An error :-)\n"); -+ free(answer); - return -1; - } - -+ free(answer); - return 0; - } - -@@ -1848,7 +1856,7 @@ restore: - - ll_init_map(&rth); - -- ret = rtnl_talk(&rth, n, n, sizeof(*n)); -+ ret = rtnl_talk(&rth, n, NULL); - if ((ret < 0) && (errno == EEXIST)) - ret = 0; - -diff --git a/ip/iprule.c b/ip/iprule.c -index 8313138db815f..e64b4d7db2815 100644 ---- a/ip/iprule.c -+++ b/ip/iprule.c -@@ -393,7 +393,7 @@ static int flush_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, - if (rtnl_open(&rth2, 0) < 0) - return -1; - -- if (rtnl_talk(&rth2, n, NULL, 0) < 0) -+ if (rtnl_talk(&rth2, n, NULL) < 0) - return -2; - - rtnl_close(&rth2); -@@ -553,7 +553,7 @@ static int restore_handler(const struct sockaddr_nl *nl, - - ll_init_map(&rth); - -- ret = rtnl_talk(&rth, n, n, sizeof(*n)); -+ ret = rtnl_talk(&rth, n, NULL); - if ((ret < 0) && (errno == EEXIST)) - ret = 0; - -@@ -760,7 +760,7 @@ static int iprule_modify(int cmd, int argc, char **argv) - if (!table_ok && cmd == RTM_NEWRULE) - req.r.rtm_table = RT_TABLE_MAIN; - -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) - return -2; - - return 0; -diff --git a/ip/iptoken.c b/ip/iptoken.c -index 1869f764424ff..0528bad70a80e 100644 ---- a/ip/iptoken.c -+++ b/ip/iptoken.c -@@ -166,7 +166,7 @@ static int iptoken_set(int argc, char **argv, bool delete) - addattr_nest_end(&req.n, afs6); - addattr_nest_end(&req.n, afs); - -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) - return -2; - - return 0; -diff --git a/ip/link_gre.c b/ip/link_gre.c -index 35d437a15562c..ced993692e6f6 100644 ---- a/ip/link_gre.c -+++ b/ip/link_gre.c -@@ -64,7 +64,6 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv, - struct { - struct nlmsghdr n; - struct ifinfomsg i; -- char buf[16384]; - } req = { - .n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)), - .n.nlmsg_flags = NLM_F_REQUEST, -@@ -72,6 +71,7 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv, - .i.ifi_family = preferred_family, - .i.ifi_index = ifi->ifi_index, - }; -+ struct nlmsghdr *answer = NULL; - struct rtattr *tb[IFLA_MAX + 1]; - struct rtattr *linkinfo[IFLA_INFO_MAX+1]; - struct rtattr *greinfo[IFLA_GRE_MAX + 1]; -@@ -93,19 +93,20 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv, - __u8 metadata = 0; - - if (!(n->nlmsg_flags & NLM_F_CREATE)) { -- if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0) { -+ if (rtnl_talk(&rth, &req.n, &answer) < 0) { - get_failed: - fprintf(stderr, - "Failed to get existing tunnel info.\n"); -+ free(answer); - return -1; - } - -- len = req.n.nlmsg_len; -+ len = answer->nlmsg_len; - len -= NLMSG_LENGTH(sizeof(*ifi)); - if (len < 0) - goto get_failed; - -- parse_rtattr(tb, IFLA_MAX, IFLA_RTA(&req.i), len); -+ parse_rtattr(tb, IFLA_MAX, IFLA_RTA(NLMSG_DATA(answer)), len); - - if (!tb[IFLA_LINKINFO]) - goto get_failed; -@@ -160,6 +161,8 @@ get_failed: - - if (greinfo[IFLA_GRE_COLLECT_METADATA]) - metadata = 1; -+ -+ free(answer); - } - - while (argc > 0) { -diff --git a/ip/link_gre6.c b/ip/link_gre6.c -index fe3ab641a86c2..932f9ee96124d 100644 ---- a/ip/link_gre6.c -+++ b/ip/link_gre6.c -@@ -76,7 +76,6 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv, - struct { - struct nlmsghdr n; - struct ifinfomsg i; -- char buf[1024]; - } req = { - .n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)), - .n.nlmsg_flags = NLM_F_REQUEST, -@@ -84,6 +83,7 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv, - .i.ifi_family = preferred_family, - .i.ifi_index = ifi->ifi_index, - }; -+ struct nlmsghdr *answer = NULL; - struct rtattr *tb[IFLA_MAX + 1]; - struct rtattr *linkinfo[IFLA_INFO_MAX+1]; - struct rtattr *greinfo[IFLA_GRE_MAX + 1]; -@@ -105,19 +105,20 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv, - int len; - - if (!(n->nlmsg_flags & NLM_F_CREATE)) { -- if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0) { -+ if (rtnl_talk(&rth, &req.n, &answer) < 0) { - get_failed: - fprintf(stderr, - "Failed to get existing tunnel info.\n"); -+ free(answer); - return -1; - } - -- len = req.n.nlmsg_len; -+ len = answer->nlmsg_len; - len -= NLMSG_LENGTH(sizeof(*ifi)); - if (len < 0) - goto get_failed; - -- parse_rtattr(tb, IFLA_MAX, IFLA_RTA(&req.i), len); -+ parse_rtattr(tb, IFLA_MAX, IFLA_RTA(NLMSG_DATA(answer)), len); - - if (!tb[IFLA_LINKINFO]) - goto get_failed; -@@ -174,6 +175,8 @@ get_failed: - - if (greinfo[IFLA_GRE_ENCAP_DPORT]) - encapdport = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_DPORT]); -+ -+ free(answer); - } - - while (argc > 0) { -diff --git a/ip/link_ip6tnl.c b/ip/link_ip6tnl.c -index 6bb968d3c9189..230436437fffb 100644 ---- a/ip/link_ip6tnl.c -+++ b/ip/link_ip6tnl.c -@@ -74,7 +74,6 @@ static int ip6tunnel_parse_opt(struct link_util *lu, int argc, char **argv, - struct { - struct nlmsghdr n; - struct ifinfomsg i; -- char buf[2048]; - } req = { - .n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)), - .n.nlmsg_flags = NLM_F_REQUEST, -@@ -82,6 +81,7 @@ static int ip6tunnel_parse_opt(struct link_util *lu, int argc, char **argv, - .i.ifi_family = preferred_family, - .i.ifi_index = ifi->ifi_index, - }; -+ struct nlmsghdr *answer = NULL; - struct rtattr *tb[IFLA_MAX + 1]; - struct rtattr *linkinfo[IFLA_INFO_MAX+1]; - struct rtattr *iptuninfo[IFLA_IPTUN_MAX + 1]; -@@ -101,19 +101,20 @@ static int ip6tunnel_parse_opt(struct link_util *lu, int argc, char **argv, - __u8 metadata = 0; - - if (!(n->nlmsg_flags & NLM_F_CREATE)) { -- if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0) { -+ if (rtnl_talk(&rth, &req.n, &answer) < 0) { - get_failed: - fprintf(stderr, - "Failed to get existing tunnel info.\n"); -+ free(answer); - return -1; - } - -- len = req.n.nlmsg_len; -+ len = answer->nlmsg_len; - len -= NLMSG_LENGTH(sizeof(*ifi)); - if (len < 0) - goto get_failed; - -- parse_rtattr(tb, IFLA_MAX, IFLA_RTA(&req.i), len); -+ parse_rtattr(tb, IFLA_MAX, IFLA_RTA(NLMSG_DATA(answer)), len); - - if (!tb[IFLA_LINKINFO]) - goto get_failed; -@@ -153,6 +154,8 @@ get_failed: - proto = rta_getattr_u8(iptuninfo[IFLA_IPTUN_PROTO]); - if (iptuninfo[IFLA_IPTUN_COLLECT_METADATA]) - metadata = 1; -+ -+ free(answer); - } - - while (argc > 0) { -diff --git a/ip/link_iptnl.c b/ip/link_iptnl.c -index f180b921e4710..528e287814f6b 100644 ---- a/ip/link_iptnl.c -+++ b/ip/link_iptnl.c -@@ -72,7 +72,6 @@ static int iptunnel_parse_opt(struct link_util *lu, int argc, char **argv, - struct { - struct nlmsghdr n; - struct ifinfomsg i; -- char buf[2048]; - } req = { - .n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)), - .n.nlmsg_flags = NLM_F_REQUEST, -@@ -80,6 +79,7 @@ static int iptunnel_parse_opt(struct link_util *lu, int argc, char **argv, - .i.ifi_family = preferred_family, - .i.ifi_index = ifi->ifi_index, - }; -+ struct nlmsghdr *answer = NULL; - struct rtattr *tb[IFLA_MAX + 1]; - struct rtattr *linkinfo[IFLA_INFO_MAX+1]; - struct rtattr *iptuninfo[IFLA_IPTUN_MAX + 1]; -@@ -103,19 +103,20 @@ static int iptunnel_parse_opt(struct link_util *lu, int argc, char **argv, - __u8 metadata = 0; - - if (!(n->nlmsg_flags & NLM_F_CREATE)) { -- if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0) { -+ if (rtnl_talk(&rth, &req.n, &answer) < 0) { - get_failed: - fprintf(stderr, - "Failed to get existing tunnel info.\n"); -+ free(answer); - return -1; - } - -- len = req.n.nlmsg_len; -+ len = answer->nlmsg_len; - len -= NLMSG_LENGTH(sizeof(*ifi)); - if (len < 0) - goto get_failed; - -- parse_rtattr(tb, IFLA_MAX, IFLA_RTA(&req.i), len); -+ parse_rtattr(tb, IFLA_MAX, IFLA_RTA(NLMSG_DATA(answer)), len); - - if (!tb[IFLA_LINKINFO]) - goto get_failed; -@@ -179,6 +180,8 @@ get_failed: - rta_getattr_u16(iptuninfo[IFLA_IPTUN_6RD_RELAY_PREFIXLEN]); - if (iptuninfo[IFLA_IPTUN_COLLECT_METADATA]) - metadata = 1; -+ -+ free(answer); - } - - while (argc > 0) { -diff --git a/ip/link_vti.c b/ip/link_vti.c -index 95bc23e928972..d2aacbe78ded1 100644 ---- a/ip/link_vti.c -+++ b/ip/link_vti.c -@@ -51,7 +51,6 @@ static int vti_parse_opt(struct link_util *lu, int argc, char **argv, - struct { - struct nlmsghdr n; - struct ifinfomsg i; -- char buf[1024]; - } req = { - .n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)), - .n.nlmsg_flags = NLM_F_REQUEST, -@@ -59,6 +58,7 @@ static int vti_parse_opt(struct link_util *lu, int argc, char **argv, - .i.ifi_family = preferred_family, - .i.ifi_index = ifi->ifi_index, - }; -+ struct nlmsghdr *answer = NULL; - struct rtattr *tb[IFLA_MAX + 1]; - struct rtattr *linkinfo[IFLA_INFO_MAX+1]; - struct rtattr *vtiinfo[IFLA_VTI_MAX + 1]; -@@ -70,19 +70,20 @@ static int vti_parse_opt(struct link_util *lu, int argc, char **argv, - int len; - - if (!(n->nlmsg_flags & NLM_F_CREATE)) { -- if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0) { -+ if (rtnl_talk(&rth, &req.n, &answer) < 0) { - get_failed: - fprintf(stderr, - "Failed to get existing tunnel info.\n"); -+ free(answer); - return -1; - } - -- len = req.n.nlmsg_len; -+ len = answer->nlmsg_len; - len -= NLMSG_LENGTH(sizeof(*ifi)); - if (len < 0) - goto get_failed; - -- parse_rtattr(tb, IFLA_MAX, IFLA_RTA(&req.i), len); -+ parse_rtattr(tb, IFLA_MAX, IFLA_RTA(NLMSG_DATA(answer)), len); - - if (!tb[IFLA_LINKINFO]) - goto get_failed; -@@ -109,6 +110,8 @@ get_failed: - - if (vtiinfo[IFLA_VTI_LINK]) - link = rta_getattr_u8(vtiinfo[IFLA_VTI_LINK]); -+ -+ free(answer); - } - - while (argc > 0) { -diff --git a/ip/link_vti6.c b/ip/link_vti6.c -index 9ca127af8a5d5..aedfbeaeea0e1 100644 ---- a/ip/link_vti6.c -+++ b/ip/link_vti6.c -@@ -46,7 +46,6 @@ static int vti6_parse_opt(struct link_util *lu, int argc, char **argv, - struct { - struct nlmsghdr n; - struct ifinfomsg i; -- char buf[1024]; - } req = { - .n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)), - .n.nlmsg_flags = NLM_F_REQUEST, -@@ -54,6 +53,7 @@ static int vti6_parse_opt(struct link_util *lu, int argc, char **argv, - .i.ifi_family = preferred_family, - .i.ifi_index = ifi->ifi_index, - }; -+ struct nlmsghdr *answer = NULL; - struct rtattr *tb[IFLA_MAX + 1]; - struct rtattr *linkinfo[IFLA_INFO_MAX+1]; - struct rtattr *vtiinfo[IFLA_VTI_MAX + 1]; -@@ -65,19 +65,20 @@ static int vti6_parse_opt(struct link_util *lu, int argc, char **argv, - int len; - - if (!(n->nlmsg_flags & NLM_F_CREATE)) { -- if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0) { -+ if (rtnl_talk(&rth, &req.n, &answer) < 0) { - get_failed: - fprintf(stderr, - "Failed to get existing tunnel info.\n"); -+ free(answer); - return -1; - } - -- len = req.n.nlmsg_len; -+ len = answer->nlmsg_len; - len -= NLMSG_LENGTH(sizeof(*ifi)); - if (len < 0) - goto get_failed; - -- parse_rtattr(tb, IFLA_MAX, IFLA_RTA(&req.i), len); -+ parse_rtattr(tb, IFLA_MAX, IFLA_RTA(NLMSG_DATA(answer)), len); - - if (!tb[IFLA_LINKINFO]) - goto get_failed; -@@ -104,6 +105,8 @@ get_failed: - - if (vtiinfo[IFLA_VTI_LINK]) - link = rta_getattr_u8(vtiinfo[IFLA_VTI_LINK]); -+ -+ free(answer); - } - - while (argc > 0) { -diff --git a/ip/tcp_metrics.c b/ip/tcp_metrics.c -index 8972acd05fb28..3f9790e8fedde 100644 ---- a/ip/tcp_metrics.c -+++ b/ip/tcp_metrics.c -@@ -306,6 +306,7 @@ static int process_msg(const struct sockaddr_nl *who, struct nlmsghdr *n, - static int tcpm_do_cmd(int cmd, int argc, char **argv) - { - TCPM_REQUEST(req, 1024, TCP_METRICS_CMD_GET, NLM_F_REQUEST); -+ struct nlmsghdr *answer; - int atype = -1, stype = -1; - int ack; - -@@ -457,15 +458,16 @@ static int tcpm_do_cmd(int cmd, int argc, char **argv) - } - - if (ack) { -- if (rtnl_talk(&grth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&grth, &req.n, NULL) < 0) - return -2; - } else if (atype >= 0) { -- if (rtnl_talk(&grth, &req.n, &req.n, sizeof(req)) < 0) -+ if (rtnl_talk(&grth, &req.n, &answer) < 0) - return -2; -- if (process_msg(NULL, &req.n, stdout) < 0) { -+ if (process_msg(NULL, answer, stdout) < 0) { - fprintf(stderr, "Dump terminated\n"); - exit(1); - } -+ free(answer); - } else { - req.n.nlmsg_seq = grth.dump = ++grth.seq; - if (rtnl_send(&grth, &req, req.n.nlmsg_len) < 0) { -diff --git a/ip/xfrm_policy.c b/ip/xfrm_policy.c -index de689c4d86c4d..98460a072bd4e 100644 ---- a/ip/xfrm_policy.c -+++ b/ip/xfrm_policy.c -@@ -386,7 +386,7 @@ static int xfrm_policy_modify(int cmd, unsigned int flags, int argc, char **argv - if (req.xpinfo.sel.family == AF_UNSPEC) - req.xpinfo.sel.family = AF_INET; - -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) - exit(2); - - rtnl_close(&rth); -@@ -548,7 +548,7 @@ int xfrm_policy_print(const struct sockaddr_nl *who, struct nlmsghdr *n, - } - - static int xfrm_policy_get_or_delete(int argc, char **argv, int delete, -- void *res_nlbuf, size_t res_size) -+ struct nlmsghdr **answer) - { - struct rtnl_handle rth; - struct { -@@ -659,7 +659,7 @@ static int xfrm_policy_get_or_delete(int argc, char **argv, int delete, - (void *)&ctx, ctx.sctx.len); - } - -- if (rtnl_talk(&rth, &req.n, res_nlbuf, res_size) < 0) -+ if (rtnl_talk(&rth, &req.n, answer) < 0) - exit(2); - - rtnl_close(&rth); -@@ -669,21 +669,21 @@ static int xfrm_policy_get_or_delete(int argc, char **argv, int delete, - - static int xfrm_policy_delete(int argc, char **argv) - { -- return xfrm_policy_get_or_delete(argc, argv, 1, NULL, 0); -+ return xfrm_policy_get_or_delete(argc, argv, 1, NULL); - } - - static int xfrm_policy_get(int argc, char **argv) - { -- char buf[NLMSG_BUF_SIZE] = {}; -- struct nlmsghdr *n = (struct nlmsghdr *)buf; -+ struct nlmsghdr *n = NULL; - -- xfrm_policy_get_or_delete(argc, argv, 0, n, sizeof(buf)); -+ xfrm_policy_get_or_delete(argc, argv, 0, &n); - - if (xfrm_policy_print(NULL, n, (void *)stdout) < 0) { - fprintf(stderr, "An error :-)\n"); - exit(1); - } - -+ free(n); - return 0; - } - -@@ -1049,7 +1049,7 @@ static int xfrm_spd_setinfo(int argc, char **argv) - if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0) - exit(1); - -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) - exit(2); - - rtnl_close(&rth); -@@ -1063,22 +1063,23 @@ static int xfrm_spd_getinfo(int argc, char **argv) - struct { - struct nlmsghdr n; - __u32 flags; -- char ans[128]; - } req = { - .n.nlmsg_len = NLMSG_LENGTH(sizeof(__u32)), - .n.nlmsg_flags = NLM_F_REQUEST, - .n.nlmsg_type = XFRM_MSG_GETSPDINFO, - .flags = 0XFFFFFFFF, - }; -+ struct nlmsghdr *answer; - - if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0) - exit(1); - -- if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0) -+ if (rtnl_talk(&rth, &req.n, &answer) < 0) - exit(2); - -- print_spdinfo(&req.n, (void *)stdout); -+ print_spdinfo(answer, (void *)stdout); - -+ free(answer); - rtnl_close(&rth); - - return 0; -@@ -1123,7 +1124,7 @@ static int xfrm_policy_flush(int argc, char **argv) - if (show_stats > 1) - fprintf(stderr, "Flush policy\n"); - -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) - exit(2); - - rtnl_close(&rth); -diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c -index ea7d4f3460578..04ed3492ad3b5 100644 ---- a/ip/xfrm_state.c -+++ b/ip/xfrm_state.c -@@ -677,7 +677,7 @@ static int xfrm_state_modify(int cmd, unsigned int flags, int argc, char **argv) - if (req.xsinfo.family == AF_UNSPEC) - req.xsinfo.family = AF_INET; - -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) - exit(2); - - rtnl_close(&rth); -@@ -708,8 +708,7 @@ static int xfrm_state_allocspi(int argc, char **argv) - char *minp = NULL; - char *maxp = NULL; - struct xfrm_mark mark = {0, 0}; -- char res_buf[NLMSG_BUF_SIZE] = {}; -- struct nlmsghdr *res_n = (struct nlmsghdr *)res_buf; -+ struct nlmsghdr *answer; - - while (argc > 0) { - if (strcmp(*argv, "mode") == 0) { -@@ -809,14 +808,15 @@ static int xfrm_state_allocspi(int argc, char **argv) - req.xspi.info.family = AF_INET; - - -- if (rtnl_talk(&rth, &req.n, res_n, sizeof(res_buf)) < 0) -+ if (rtnl_talk(&rth, &req.n, &answer) < 0) - exit(2); - -- if (xfrm_state_print(NULL, res_n, (void *)stdout) < 0) { -+ if (xfrm_state_print(NULL, answer, (void *)stdout) < 0) { - fprintf(stderr, "An error :-)\n"); - exit(1); - } - -+ free(answer); - rtnl_close(&rth); - - return 0; -@@ -997,19 +997,20 @@ static int xfrm_state_get_or_delete(int argc, char **argv, int delete) - req.xsid.family = AF_INET; - - if (delete) { -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) - exit(2); - } else { -- char buf[NLMSG_BUF_SIZE] = {}; -- struct nlmsghdr *res_n = (struct nlmsghdr *)buf; -+ struct nlmsghdr *answer; - -- if (rtnl_talk(&rth, &req.n, res_n, sizeof(req)) < 0) -+ if (rtnl_talk(&rth, &req.n, &answer) < 0) - exit(2); - -- if (xfrm_state_print(NULL, res_n, (void *)stdout) < 0) { -+ if (xfrm_state_print(NULL, answer, (void *)stdout) < 0) { - fprintf(stderr, "An error :-)\n"); - exit(1); - } -+ -+ free(answer); - } - - rtnl_close(&rth); -@@ -1265,22 +1266,23 @@ static int xfrm_sad_getinfo(int argc, char **argv) - struct { - struct nlmsghdr n; - __u32 flags; -- char ans[64]; - } req = { - .n.nlmsg_len = NLMSG_LENGTH(sizeof(req.flags)), - .n.nlmsg_flags = NLM_F_REQUEST, - .n.nlmsg_type = XFRM_MSG_GETSADINFO, - .flags = 0XFFFFFFFF, - }; -+ struct nlmsghdr *answer; - - if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0) - exit(1); - -- if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0) -+ if (rtnl_talk(&rth, &req.n, &answer) < 0) - exit(2); - -- print_sadinfo(&req.n, (void *)stdout); -+ print_sadinfo(answer, (void *)stdout); - -+ free(answer); - rtnl_close(&rth); - - return 0; -@@ -1327,7 +1329,7 @@ static int xfrm_state_flush(int argc, char **argv) - fprintf(stderr, "Flush state with XFRM-PROTO value \"%s\"\n", - strxf_xfrmproto(req.xsf.proto)); - -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) - exit(2); - - rtnl_close(&rth); -diff --git a/lib/libgenl.c b/lib/libgenl.c -index 50d2d9217dcbc..bb5fbb5f518d2 100644 ---- a/lib/libgenl.c -+++ b/lib/libgenl.c -@@ -49,16 +49,21 @@ int genl_resolve_family(struct rtnl_handle *grth, const char *family) - { - GENL_REQUEST(req, 1024, GENL_ID_CTRL, 0, 0, CTRL_CMD_GETFAMILY, - NLM_F_REQUEST); -+ struct nlmsghdr *answer; -+ int fnum; - - addattr_l(&req.n, sizeof(req), CTRL_ATTR_FAMILY_NAME, - family, strlen(family) + 1); - -- if (rtnl_talk(grth, &req.n, &req.n, sizeof(req)) < 0) { -+ if (rtnl_talk(grth, &req.n, &answer) < 0) { - fprintf(stderr, "Error talking to the kernel\n"); - return -2; - } - -- return genl_parse_getfamily(&req.n); -+ fnum = genl_parse_getfamily(answer); -+ free(answer); -+ -+ return fnum; - } - - int genl_init_handle(struct rtnl_handle *grth, const char *family, -diff --git a/lib/libnetlink.c b/lib/libnetlink.c -index 446c9605ba19b..75e20abf0b97f 100644 ---- a/lib/libnetlink.c -+++ b/lib/libnetlink.c -@@ -561,7 +561,7 @@ static void rtnl_talk_error(struct nlmsghdr *h, struct nlmsgerr *err, - } - - static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, -- struct nlmsghdr *answer, size_t maxlen, -+ struct nlmsghdr **answer, - bool show_rtnl_err, nl_ext_ack_fn_t errfn) - { - int status; -@@ -635,9 +635,9 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, - fprintf(stderr, "ERROR truncated\n"); - } else if (!err->error) { - if (answer) -- memcpy(answer, h, -- MIN(maxlen, h->nlmsg_len)); -- free(buf); -+ *answer = (struct nlmsghdr *)buf; -+ else -+ free(buf); - return 0; - } - -@@ -651,9 +651,7 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, - } - - if (answer) { -- memcpy(answer, h, -- MIN(maxlen, h->nlmsg_len)); -- free(buf); -+ *answer = (struct nlmsghdr *)buf; - return 0; - } - -@@ -677,22 +675,22 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, - } - - int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, -- struct nlmsghdr *answer, size_t maxlen) -+ struct nlmsghdr **answer) - { -- return __rtnl_talk(rtnl, n, answer, maxlen, true, NULL); -+ return __rtnl_talk(rtnl, n, answer, true, NULL); - } - - int rtnl_talk_extack(struct rtnl_handle *rtnl, struct nlmsghdr *n, -- struct nlmsghdr *answer, size_t maxlen, -+ struct nlmsghdr **answer, - nl_ext_ack_fn_t errfn) - { -- return __rtnl_talk(rtnl, n, answer, maxlen, true, errfn); -+ return __rtnl_talk(rtnl, n, answer, true, errfn); - } - - int rtnl_talk_suppress_rtnl_errmsg(struct rtnl_handle *rtnl, struct nlmsghdr *n, -- struct nlmsghdr *answer, size_t maxlen) -+ struct nlmsghdr **answer) - { -- return __rtnl_talk(rtnl, n, answer, maxlen, false, NULL); -+ return __rtnl_talk(rtnl, n, answer, false, NULL); - } - - int rtnl_listen_all_nsid(struct rtnl_handle *rth) -diff --git a/misc/ss.c b/misc/ss.c -index b84baf3b57fe5..d3fb9a751b3ab 100644 ---- a/misc/ss.c -+++ b/misc/ss.c -@@ -2588,7 +2588,7 @@ static int kill_inet_sock(struct nlmsghdr *h, void *arg, struct sockstat *s) - raw->sdiag_raw_protocol = s->raw_prot; - } - -- return rtnl_talk(rth, &req.nlh, NULL, 0); -+ return rtnl_talk(rth, &req.nlh, NULL); - } - - static int show_one_inet_sock(const struct sockaddr_nl *addr, -diff --git a/tc/m_action.c b/tc/m_action.c -index 6ebe85e1cbe36..90b2a11e5d9e8 100644 ---- a/tc/m_action.c -+++ b/tc/m_action.c -@@ -506,18 +506,18 @@ static int tc_action_gd(int cmd, unsigned int flags, int *argc_p, char ***argv_p - tail->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail; - - req.n.nlmsg_seq = rth.dump = ++rth.seq; -- if (cmd == RTM_GETACTION) -- ans = &req.n; - -- if (rtnl_talk(&rth, &req.n, ans, MAX_MSG) < 0) { -+ if (rtnl_talk(&rth, &req.n, &ans) < 0) { - fprintf(stderr, "We have an error talking to the kernel\n"); - return 1; - } - -- if (ans && print_action(NULL, &req.n, (void *)stdout) < 0) { -+ if (cmd == RTM_GETACTION && print_action(NULL, ans, stdout) < 0) { - fprintf(stderr, "Dump terminated\n"); -+ free(ans); - return 1; - } -+ free(ans); - - *argc_p = argc; - *argv_p = argv; -@@ -550,7 +550,7 @@ static int tc_action_modify(int cmd, unsigned int flags, int *argc_p, char ***ar - } - tail->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail; - -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) { -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) { - fprintf(stderr, "We have an error talking to the kernel\n"); - ret = -1; - } -@@ -617,7 +617,7 @@ static int tc_act_list_or_flush(int argc, char **argv, int event) - req.n.nlmsg_type = RTM_DELACTION; - req.n.nlmsg_flags |= NLM_F_ROOT; - req.n.nlmsg_flags |= NLM_F_REQUEST; -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) { -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) { - fprintf(stderr, "We have an error flushing\n"); - return 1; - } -diff --git a/tc/tc_class.c b/tc/tc_class.c -index 1a1f1fa225b40..0214775b95a6c 100644 ---- a/tc/tc_class.c -+++ b/tc/tc_class.c -@@ -149,7 +149,7 @@ static int tc_class_modify(int cmd, unsigned int flags, int argc, char **argv) - } - } - -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) - return 2; - - return 0; -diff --git a/tc/tc_filter.c b/tc/tc_filter.c -index ff8713b98e315..e640492b25ba6 100644 ---- a/tc/tc_filter.c -+++ b/tc/tc_filter.c -@@ -181,7 +181,7 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv) - } - } - -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) { -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) { - fprintf(stderr, "We have an error talking to the kernel\n"); - return 2; - } -@@ -307,6 +307,7 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv) - .t.tcm_parent = TC_H_UNSPEC, - .t.tcm_family = AF_UNSPEC, - }; -+ struct nlmsghdr *answer; - struct filter_util *q = NULL; - __u32 prio = 0; - __u32 protocol = 0; -@@ -445,13 +446,14 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv) - return -1; - } - -- if (rtnl_talk(&rth, &req.n, &req.n, MAX_MSG) < 0) { -+ if (rtnl_talk(&rth, &req.n, &answer) < 0) { - fprintf(stderr, "We have an error talking to the kernel\n"); - return 2; - } - -- print_filter(NULL, &req.n, (void *)stdout); -+ print_filter(NULL, answer, (void *)stdout); - -+ free(answer); - return 0; - } - -diff --git a/tc/tc_qdisc.c b/tc/tc_qdisc.c -index 3a3701c204704..8b0c5c72dbad1 100644 ---- a/tc/tc_qdisc.c -+++ b/tc/tc_qdisc.c -@@ -190,7 +190,7 @@ static int tc_qdisc_modify(int cmd, unsigned int flags, int argc, char **argv) - req.t.tcm_ifindex = idx; - } - -- if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) -+ if (rtnl_talk(&rth, &req.n, NULL) < 0) - return 2; - - return 0; --- -2.21.0 - diff --git a/SOURCES/0024-Update-linux-headers.patch b/SOURCES/0024-Update-linux-headers.patch deleted file mode 100644 index 343725e..0000000 --- a/SOURCES/0024-Update-linux-headers.patch +++ /dev/null @@ -1,2048 +0,0 @@ -From 7f123fac8aa0ff7741777935121e1b394c56e75a Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Fri, 10 Nov 2017 10:19:43 +0100 -Subject: [PATCH] Update linux headers - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1456539 - -This updates include/linux to the state just before commit 596b1c94aa38e -("iproute: build more easily on Android"). ---- - include/linux/bpf.h | 253 +++++++++++++++++- - include/linux/can/vxcan.h | 12 + - include/linux/devlink.h | 92 ++++++- - include/linux/elf-em.h | 1 - - include/linux/if_arp.h | 2 + - include/linux/if_ether.h | 6 + - include/linux/if_link.h | 37 ++- - include/linux/if_packet.h | 1 + - include/linux/if_tunnel.h | 4 + - include/linux/inet_diag.h | 2 + - include/linux/ipsec.h | 47 ++++ - include/linux/lwtunnel.h | 1 + - include/linux/magic.h | 3 + - include/linux/mpls_iptunnel.h | 2 + - include/linux/neighbour.h | 1 + - include/linux/netlink.h | 67 ++++- - include/linux/netlink_diag.h | 10 + - include/linux/pfkeyv2.h | 383 +++++++++++++++++++++++++++ - include/linux/pkt_cls.h | 37 ++- - include/linux/pkt_sched.h | 8 + - include/linux/rtnetlink.h | 36 ++- - include/linux/sctp.h | 38 +++ - include/linux/seg6.h | 54 ++++ - include/linux/seg6_genl.h | 32 +++ - include/linux/seg6_hmac.h | 22 ++ - include/linux/seg6_iptunnel.h | 40 +++ - include/linux/seg6_local.h | 68 +++++ - include/linux/tc_act/tc_bpf.h | 1 + - include/linux/tc_act/tc_tunnel_key.h | 1 + - include/linux/tcp.h | 27 +- - include/linux/xfrm.h | 9 + - 31 files changed, 1272 insertions(+), 25 deletions(-) - create mode 100644 include/linux/can/vxcan.h - create mode 100644 include/linux/ipsec.h - create mode 100644 include/linux/pfkeyv2.h - create mode 100644 include/linux/seg6.h - create mode 100644 include/linux/seg6_genl.h - create mode 100644 include/linux/seg6_hmac.h - create mode 100644 include/linux/seg6_iptunnel.h - create mode 100644 include/linux/seg6_local.h - -diff --git a/include/linux/bpf.h b/include/linux/bpf.h -index 178e20c388852..0895a529cc90b 100644 ---- a/include/linux/bpf.h -+++ b/include/linux/bpf.h -@@ -30,9 +30,14 @@ - #define BPF_FROM_LE BPF_TO_LE - #define BPF_FROM_BE BPF_TO_BE - -+/* jmp encodings */ - #define BPF_JNE 0x50 /* jump != */ -+#define BPF_JLT 0xa0 /* LT is unsigned, '<' */ -+#define BPF_JLE 0xb0 /* LE is unsigned, '<=' */ - #define BPF_JSGT 0x60 /* SGT is signed '>', GT in x86 */ - #define BPF_JSGE 0x70 /* SGE is signed '>=', GE in x86 */ -+#define BPF_JSLT 0xc0 /* SLT is signed, '<' */ -+#define BPF_JSLE 0xd0 /* SLE is signed, '<=' */ - #define BPF_CALL 0x80 /* function call */ - #define BPF_EXIT 0x90 /* function return */ - -@@ -81,6 +86,12 @@ enum bpf_cmd { - BPF_OBJ_GET, - BPF_PROG_ATTACH, - BPF_PROG_DETACH, -+ BPF_PROG_TEST_RUN, -+ BPF_PROG_GET_NEXT_ID, -+ BPF_MAP_GET_NEXT_ID, -+ BPF_PROG_GET_FD_BY_ID, -+ BPF_MAP_GET_FD_BY_ID, -+ BPF_OBJ_GET_INFO_BY_FD, - }; - - enum bpf_map_type { -@@ -96,6 +107,10 @@ enum bpf_map_type { - BPF_MAP_TYPE_LRU_HASH, - BPF_MAP_TYPE_LRU_PERCPU_HASH, - BPF_MAP_TYPE_LPM_TRIE, -+ BPF_MAP_TYPE_ARRAY_OF_MAPS, -+ BPF_MAP_TYPE_HASH_OF_MAPS, -+ BPF_MAP_TYPE_DEVMAP, -+ BPF_MAP_TYPE_SOCKMAP, - }; - - enum bpf_prog_type { -@@ -112,12 +127,17 @@ enum bpf_prog_type { - BPF_PROG_TYPE_LWT_IN, - BPF_PROG_TYPE_LWT_OUT, - BPF_PROG_TYPE_LWT_XMIT, -+ BPF_PROG_TYPE_SOCK_OPS, -+ BPF_PROG_TYPE_SK_SKB, - }; - - enum bpf_attach_type { - BPF_CGROUP_INET_INGRESS, - BPF_CGROUP_INET_EGRESS, - BPF_CGROUP_INET_SOCK_CREATE, -+ BPF_CGROUP_SOCK_OPS, -+ BPF_SK_SKB_STREAM_PARSER, -+ BPF_SK_SKB_STREAM_VERDICT, - __MAX_BPF_ATTACH_TYPE - }; - -@@ -129,6 +149,13 @@ enum bpf_attach_type { - */ - #define BPF_F_ALLOW_OVERRIDE (1U << 0) - -+/* If BPF_F_STRICT_ALIGNMENT is used in BPF_PROG_LOAD command, the -+ * verifier will perform strict alignment checking as if the kernel -+ * has been built with CONFIG_EFFICIENT_UNALIGNED_ACCESS not set, -+ * and NET_IP_ALIGN defined to 2. -+ */ -+#define BPF_F_STRICT_ALIGNMENT (1U << 0) -+ - #define BPF_PSEUDO_MAP_FD 1 - - /* flags for BPF_MAP_UPDATE_ELEM command */ -@@ -136,6 +163,7 @@ enum bpf_attach_type { - #define BPF_NOEXIST 1 /* create new element if it didn't exist */ - #define BPF_EXIST 2 /* update existing element */ - -+/* flags for BPF_MAP_CREATE command */ - #define BPF_F_NO_PREALLOC (1U << 0) - /* Instead of having one common LRU list in the - * BPF_MAP_TYPE_LRU_[PERCPU_]HASH map, use a percpu LRU list -@@ -144,6 +172,8 @@ enum bpf_attach_type { - * across different LRU lists. - */ - #define BPF_F_NO_COMMON_LRU (1U << 1) -+/* Specify numa node during map creation */ -+#define BPF_F_NUMA_NODE (1U << 2) - - union bpf_attr { - struct { /* anonymous struct used by BPF_MAP_CREATE command */ -@@ -151,7 +181,13 @@ union bpf_attr { - __u32 key_size; /* size of key in bytes */ - __u32 value_size; /* size of value in bytes */ - __u32 max_entries; /* max number of entries in a map */ -- __u32 map_flags; /* prealloc or not */ -+ __u32 map_flags; /* BPF_MAP_CREATE related -+ * flags defined above. -+ */ -+ __u32 inner_map_fd; /* fd pointing to the inner map */ -+ __u32 numa_node; /* numa node (effective only if -+ * BPF_F_NUMA_NODE is set). -+ */ - }; - - struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */ -@@ -173,6 +209,7 @@ union bpf_attr { - __u32 log_size; /* size of user buffer */ - __aligned_u64 log_buf; /* user supplied buffer */ - __u32 kern_version; /* checked when prog_type=kprobe */ -+ __u32 prog_flags; - }; - - struct { /* anonymous struct used by BPF_OBJ_* commands */ -@@ -186,6 +223,32 @@ union bpf_attr { - __u32 attach_type; - __u32 attach_flags; - }; -+ -+ struct { /* anonymous struct used by BPF_PROG_TEST_RUN command */ -+ __u32 prog_fd; -+ __u32 retval; -+ __u32 data_size_in; -+ __u32 data_size_out; -+ __aligned_u64 data_in; -+ __aligned_u64 data_out; -+ __u32 repeat; -+ __u32 duration; -+ } test; -+ -+ struct { /* anonymous struct used by BPF_*_GET_*_ID */ -+ union { -+ __u32 start_id; -+ __u32 prog_id; -+ __u32 map_id; -+ }; -+ __u32 next_id; -+ }; -+ -+ struct { /* anonymous struct used by BPF_OBJ_GET_INFO_BY_FD */ -+ __u32 bpf_fd; -+ __u32 info_len; -+ __aligned_u64 info; -+ } info; - } __attribute__((aligned(8))); - - /* BPF helper function descriptions: -@@ -290,26 +353,40 @@ union bpf_attr { - * @flags: room for future extensions - * Return: 0 on success or negative error - * -- * u64 bpf_perf_event_read(&map, index) -- * Return: Number events read or error code -+ * u64 bpf_perf_event_read(map, flags) -+ * read perf event counter value -+ * @map: pointer to perf_event_array map -+ * @flags: index of event in the map or bitmask flags -+ * Return: value of perf event counter read or error code - * - * int bpf_redirect(ifindex, flags) - * redirect to another netdev - * @ifindex: ifindex of the net device -- * @flags: bit 0 - if set, redirect to ingress instead of egress -- * other bits - reserved -- * Return: TC_ACT_REDIRECT -+ * @flags: -+ * cls_bpf: -+ * bit 0 - if set, redirect to ingress instead of egress -+ * other bits - reserved -+ * xdp_bpf: -+ * all bits - reserved -+ * Return: cls_bpf: TC_ACT_REDIRECT on success or TC_ACT_SHOT on error -+ * xdp_bfp: XDP_REDIRECT on success or XDP_ABORT on error -+ * int bpf_redirect_map(map, key, flags) -+ * redirect to endpoint in map -+ * @map: pointer to dev map -+ * @key: index in map to lookup -+ * @flags: -- -+ * Return: XDP_REDIRECT on success or XDP_ABORT on error - * - * u32 bpf_get_route_realm(skb) - * retrieve a dst's tclassid - * @skb: pointer to skb - * Return: realm if != 0 - * -- * int bpf_perf_event_output(ctx, map, index, data, size) -+ * int bpf_perf_event_output(ctx, map, flags, data, size) - * output perf raw sample - * @ctx: struct pt_regs* - * @map: pointer to perf_event_array map -- * @index: index of event in the map -+ * @flags: index of event in the map or bitmask flags - * @data: data on stack to be output as raw data - * @size: size of data - * Return: 0 on success or negative error -@@ -456,6 +533,55 @@ union bpf_attr { - * Return: - * > 0 length of the string including the trailing NUL on success - * < 0 error -+ * -+ * u64 bpf_get_socket_cookie(skb) -+ * Get the cookie for the socket stored inside sk_buff. -+ * @skb: pointer to skb -+ * Return: 8 Bytes non-decreasing number on success or 0 if the socket -+ * field is missing inside sk_buff -+ * -+ * u32 bpf_get_socket_uid(skb) -+ * Get the owner uid of the socket stored inside sk_buff. -+ * @skb: pointer to skb -+ * Return: uid of the socket owner on success or overflowuid if failed. -+ * -+ * u32 bpf_set_hash(skb, hash) -+ * Set full skb->hash. -+ * @skb: pointer to skb -+ * @hash: hash to set -+ * -+ * int bpf_setsockopt(bpf_socket, level, optname, optval, optlen) -+ * Calls setsockopt. Not all opts are available, only those with -+ * integer optvals plus TCP_CONGESTION. -+ * Supported levels: SOL_SOCKET and IPROTO_TCP -+ * @bpf_socket: pointer to bpf_socket -+ * @level: SOL_SOCKET or IPROTO_TCP -+ * @optname: option name -+ * @optval: pointer to option value -+ * @optlen: length of optval in byes -+ * Return: 0 or negative error -+ * -+ * int bpf_skb_adjust_room(skb, len_diff, mode, flags) -+ * Grow or shrink room in sk_buff. -+ * @skb: pointer to skb -+ * @len_diff: (signed) amount of room to grow/shrink -+ * @mode: operation mode (enum bpf_adj_room_mode) -+ * @flags: reserved for future use -+ * Return: 0 on success or negative error code -+ * -+ * int bpf_sk_redirect_map(map, key, flags) -+ * Redirect skb to a sock in map using key as a lookup key for the -+ * sock in map. -+ * @map: pointer to sockmap -+ * @key: key to lookup sock in map -+ * @flags: reserved for future use -+ * Return: SK_REDIRECT -+ * -+ * int bpf_sock_map_update(skops, map, key, flags) -+ * @skops: pointer to bpf_sock_ops -+ * @map: pointer to sockmap to update -+ * @key: key to insert/update sock in map -+ * @flags: same flags as map update elem - */ - #define __BPF_FUNC_MAPPER(FN) \ - FN(unspec), \ -@@ -503,7 +629,15 @@ union bpf_attr { - FN(get_numa_node_id), \ - FN(skb_change_head), \ - FN(xdp_adjust_head), \ -- FN(probe_read_str), -+ FN(probe_read_str), \ -+ FN(get_socket_cookie), \ -+ FN(get_socket_uid), \ -+ FN(set_hash), \ -+ FN(setsockopt), \ -+ FN(skb_adjust_room), \ -+ FN(redirect_map), \ -+ FN(sk_redirect_map), \ -+ FN(sock_map_update), \ - - /* integer value in 'imm' field of BPF_CALL instruction selects which helper - * function eBPF program intends to call -@@ -553,6 +687,11 @@ enum bpf_func_id { - /* BPF_FUNC_perf_event_output for sk_buff input context. */ - #define BPF_F_CTXLEN_MASK (0xfffffULL << 32) - -+/* Mode for BPF_FUNC_skb_adjust_room helper. */ -+enum bpf_adj_room_mode { -+ BPF_ADJ_ROOM_NET, -+}; -+ - /* user accessible mirror of in-kernel sk_buff. - * new fields can only be added to the end of this structure - */ -@@ -574,6 +713,16 @@ struct __sk_buff { - __u32 tc_classid; - __u32 data; - __u32 data_end; -+ __u32 napi_id; -+ -+ /* accessed by BPF_PROG_TYPE_sk_skb types */ -+ __u32 family; -+ __u32 remote_ip4; /* Stored in network byte order */ -+ __u32 local_ip4; /* Stored in network byte order */ -+ __u32 remote_ip6[4]; /* Stored in network byte order */ -+ __u32 local_ip6[4]; /* Stored in network byte order */ -+ __u32 remote_port; /* Stored in network byte order */ -+ __u32 local_port; /* stored in host byte order */ - }; - - struct bpf_tunnel_key { -@@ -609,20 +758,23 @@ struct bpf_sock { - __u32 family; - __u32 type; - __u32 protocol; -+ __u32 mark; -+ __u32 priority; - }; - - #define XDP_PACKET_HEADROOM 256 - - /* User return codes for XDP prog type. - * A valid XDP program must return one of these defined values. All other -- * return codes are reserved for future use. Unknown return codes will result -- * in packet drop. -+ * return codes are reserved for future use. Unknown return codes will -+ * result in packet drops and a warning via bpf_warn_invalid_xdp_action(). - */ - enum xdp_action { - XDP_ABORTED = 0, - XDP_DROP, - XDP_PASS, - XDP_TX, -+ XDP_REDIRECT, - }; - - /* user accessible metadata for XDP packet hook -@@ -633,4 +785,83 @@ struct xdp_md { - __u32 data_end; - }; - -+enum sk_action { -+ SK_ABORTED = 0, -+ SK_DROP, -+ SK_REDIRECT, -+}; -+ -+#define BPF_TAG_SIZE 8 -+ -+struct bpf_prog_info { -+ __u32 type; -+ __u32 id; -+ __u8 tag[BPF_TAG_SIZE]; -+ __u32 jited_prog_len; -+ __u32 xlated_prog_len; -+ __aligned_u64 jited_prog_insns; -+ __aligned_u64 xlated_prog_insns; -+} __attribute__((aligned(8))); -+ -+struct bpf_map_info { -+ __u32 type; -+ __u32 id; -+ __u32 key_size; -+ __u32 value_size; -+ __u32 max_entries; -+ __u32 map_flags; -+} __attribute__((aligned(8))); -+ -+/* User bpf_sock_ops struct to access socket values and specify request ops -+ * and their replies. -+ * Some of this fields are in network (bigendian) byte order and may need -+ * to be converted before use (bpf_ntohl() defined in samples/bpf/bpf_endian.h). -+ * New fields can only be added at the end of this structure -+ */ -+struct bpf_sock_ops { -+ __u32 op; -+ union { -+ __u32 reply; -+ __u32 replylong[4]; -+ }; -+ __u32 family; -+ __u32 remote_ip4; /* Stored in network byte order */ -+ __u32 local_ip4; /* Stored in network byte order */ -+ __u32 remote_ip6[4]; /* Stored in network byte order */ -+ __u32 local_ip6[4]; /* Stored in network byte order */ -+ __u32 remote_port; /* Stored in network byte order */ -+ __u32 local_port; /* stored in host byte order */ -+}; -+ -+/* List of known BPF sock_ops operators. -+ * New entries can only be added at the end -+ */ -+enum { -+ BPF_SOCK_OPS_VOID, -+ BPF_SOCK_OPS_TIMEOUT_INIT, /* Should return SYN-RTO value to use or -+ * -1 if default value should be used -+ */ -+ BPF_SOCK_OPS_RWND_INIT, /* Should return initial advertized -+ * window (in packets) or -1 if default -+ * value should be used -+ */ -+ BPF_SOCK_OPS_TCP_CONNECT_CB, /* Calls BPF program right before an -+ * active connection is initialized -+ */ -+ BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB, /* Calls BPF program when an -+ * active connection is -+ * established -+ */ -+ BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB, /* Calls BPF program when a -+ * passive connection is -+ * established -+ */ -+ BPF_SOCK_OPS_NEEDS_ECN, /* If connection's congestion control -+ * needs ECN -+ */ -+}; -+ -+#define TCP_BPF_IW 1001 /* Set TCP initial congestion window */ -+#define TCP_BPF_SNDCWND_CLAMP 1002 /* Set sndcwnd_clamp */ -+ - #endif /* __LINUX_BPF_H__ */ -diff --git a/include/linux/can/vxcan.h b/include/linux/can/vxcan.h -new file mode 100644 -index 0000000000000..5b29e8a7bc274 ---- /dev/null -+++ b/include/linux/can/vxcan.h -@@ -0,0 +1,12 @@ -+#ifndef _CAN_VXCAN_H -+#define _CAN_VXCAN_H -+ -+enum { -+ VXCAN_INFO_UNSPEC, -+ VXCAN_INFO_PEER, -+ -+ __VXCAN_INFO_MAX -+#define VXCAN_INFO_MAX (__VXCAN_INFO_MAX - 1) -+}; -+ -+#endif -diff --git a/include/linux/devlink.h b/include/linux/devlink.h -index 2ad3585b417ae..a62695e2d86e8 100644 ---- a/include/linux/devlink.h -+++ b/include/linux/devlink.h -@@ -65,8 +65,12 @@ enum devlink_command { - #define DEVLINK_CMD_ESWITCH_MODE_SET /* obsolete, never use this! */ \ - DEVLINK_CMD_ESWITCH_SET - -- /* add new commands above here */ -+ DEVLINK_CMD_DPIPE_TABLE_GET, -+ DEVLINK_CMD_DPIPE_ENTRIES_GET, -+ DEVLINK_CMD_DPIPE_HEADERS_GET, -+ DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET, - -+ /* add new commands above here */ - __DEVLINK_CMD_MAX, - DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1 - }; -@@ -115,6 +119,11 @@ enum devlink_eswitch_inline_mode { - DEVLINK_ESWITCH_INLINE_MODE_TRANSPORT, - }; - -+enum devlink_eswitch_encap_mode { -+ DEVLINK_ESWITCH_ENCAP_MODE_NONE, -+ DEVLINK_ESWITCH_ENCAP_MODE_BASIC, -+}; -+ - enum devlink_attr { - /* don't change the order or add anything between, this is ABI! */ - DEVLINK_ATTR_UNSPEC, -@@ -148,10 +157,91 @@ enum devlink_attr { - DEVLINK_ATTR_ESWITCH_MODE, /* u16 */ - DEVLINK_ATTR_ESWITCH_INLINE_MODE, /* u8 */ - -+ DEVLINK_ATTR_DPIPE_TABLES, /* nested */ -+ DEVLINK_ATTR_DPIPE_TABLE, /* nested */ -+ DEVLINK_ATTR_DPIPE_TABLE_NAME, /* string */ -+ DEVLINK_ATTR_DPIPE_TABLE_SIZE, /* u64 */ -+ DEVLINK_ATTR_DPIPE_TABLE_MATCHES, /* nested */ -+ DEVLINK_ATTR_DPIPE_TABLE_ACTIONS, /* nested */ -+ DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED, /* u8 */ -+ -+ DEVLINK_ATTR_DPIPE_ENTRIES, /* nested */ -+ DEVLINK_ATTR_DPIPE_ENTRY, /* nested */ -+ DEVLINK_ATTR_DPIPE_ENTRY_INDEX, /* u64 */ -+ DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES, /* nested */ -+ DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES, /* nested */ -+ DEVLINK_ATTR_DPIPE_ENTRY_COUNTER, /* u64 */ -+ -+ DEVLINK_ATTR_DPIPE_MATCH, /* nested */ -+ DEVLINK_ATTR_DPIPE_MATCH_VALUE, /* nested */ -+ DEVLINK_ATTR_DPIPE_MATCH_TYPE, /* u32 */ -+ -+ DEVLINK_ATTR_DPIPE_ACTION, /* nested */ -+ DEVLINK_ATTR_DPIPE_ACTION_VALUE, /* nested */ -+ DEVLINK_ATTR_DPIPE_ACTION_TYPE, /* u32 */ -+ -+ DEVLINK_ATTR_DPIPE_VALUE, -+ DEVLINK_ATTR_DPIPE_VALUE_MASK, -+ DEVLINK_ATTR_DPIPE_VALUE_MAPPING, /* u32 */ -+ -+ DEVLINK_ATTR_DPIPE_HEADERS, /* nested */ -+ DEVLINK_ATTR_DPIPE_HEADER, /* nested */ -+ DEVLINK_ATTR_DPIPE_HEADER_NAME, /* string */ -+ DEVLINK_ATTR_DPIPE_HEADER_ID, /* u32 */ -+ DEVLINK_ATTR_DPIPE_HEADER_FIELDS, /* nested */ -+ DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, /* u8 */ -+ DEVLINK_ATTR_DPIPE_HEADER_INDEX, /* u32 */ -+ -+ DEVLINK_ATTR_DPIPE_FIELD, /* nested */ -+ DEVLINK_ATTR_DPIPE_FIELD_NAME, /* string */ -+ DEVLINK_ATTR_DPIPE_FIELD_ID, /* u32 */ -+ DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, /* u32 */ -+ DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, /* u32 */ -+ -+ DEVLINK_ATTR_PAD, -+ -+ DEVLINK_ATTR_ESWITCH_ENCAP_MODE, /* u8 */ -+ - /* add new attributes above here, update the policy in devlink.c */ - - __DEVLINK_ATTR_MAX, - DEVLINK_ATTR_MAX = __DEVLINK_ATTR_MAX - 1 - }; - -+/* Mapping between internal resource described by the field and system -+ * structure -+ */ -+enum devlink_dpipe_field_mapping_type { -+ DEVLINK_DPIPE_FIELD_MAPPING_TYPE_NONE, -+ DEVLINK_DPIPE_FIELD_MAPPING_TYPE_IFINDEX, -+}; -+ -+/* Match type - specify the type of the match */ -+enum devlink_dpipe_match_type { -+ DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT, -+}; -+ -+/* Action type - specify the action type */ -+enum devlink_dpipe_action_type { -+ DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY, -+}; -+ -+enum devlink_dpipe_field_ethernet_id { -+ DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC, -+}; -+ -+enum devlink_dpipe_field_ipv4_id { -+ DEVLINK_DPIPE_FIELD_IPV4_DST_IP, -+}; -+ -+enum devlink_dpipe_field_ipv6_id { -+ DEVLINK_DPIPE_FIELD_IPV6_DST_IP, -+}; -+ -+enum devlink_dpipe_header_id { -+ DEVLINK_DPIPE_HEADER_ETHERNET, -+ DEVLINK_DPIPE_HEADER_IPV4, -+ DEVLINK_DPIPE_HEADER_IPV6, -+}; -+ - #endif /* _LINUX_DEVLINK_H_ */ -diff --git a/include/linux/elf-em.h b/include/linux/elf-em.h -index cb5d1a5192027..9cd1de954c0ac 100644 ---- a/include/linux/elf-em.h -+++ b/include/linux/elf-em.h -@@ -42,7 +42,6 @@ - #define EM_TILEGX 191 /* Tilera TILE-Gx */ - #define EM_BPF 247 /* Linux BPF - in-kernel virtual machine */ - #define EM_FRV 0x5441 /* Fujitsu FR-V */ --#define EM_AVR32 0x18ad /* Atmel AVR32 */ - - /* - * This is an interim value that we will use until the committee comes -diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h -index d001bdb276b76..199f253bd1f66 100644 ---- a/include/linux/if_arp.h -+++ b/include/linux/if_arp.h -@@ -59,6 +59,7 @@ - #define ARPHRD_LAPB 516 /* LAPB */ - #define ARPHRD_DDCMP 517 /* Digital's DDCMP protocol */ - #define ARPHRD_RAWHDLC 518 /* Raw HDLC */ -+#define ARPHRD_RAWIP 519 /* Raw IP */ - - #define ARPHRD_TUNNEL 768 /* IPIP tunnel */ - #define ARPHRD_TUNNEL6 769 /* IP6IP6 tunnel */ -@@ -95,6 +96,7 @@ - #define ARPHRD_IP6GRE 823 /* GRE over IPv6 */ - #define ARPHRD_NETLINK 824 /* Netlink header */ - #define ARPHRD_6LOWPAN 825 /* IPv6 over LoWPAN */ -+#define ARPHRD_VSOCKMON 826 /* Vsock monitor header */ - - #define ARPHRD_VOID 0xFFFF /* Void type, nothing is known */ - #define ARPHRD_NONE 0xFFFE /* zero header length */ -diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h -index b7d3beb50ce2d..7dde037a0cca6 100644 ---- a/include/linux/if_ether.h -+++ b/include/linux/if_ether.h -@@ -66,6 +66,7 @@ - #define ETH_P_ATALK 0x809B /* Appletalk DDP */ - #define ETH_P_AARP 0x80F3 /* Appletalk AARP */ - #define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */ -+#define ETH_P_ERSPAN 0x88BE /* ERSPAN type II */ - #define ETH_P_IPX 0x8137 /* IPX over DIX */ - #define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */ - #define ETH_P_PAUSE 0x8808 /* IEEE Pause frames. See 802.3 31B */ -@@ -98,11 +99,13 @@ - #define ETH_P_FIP 0x8914 /* FCoE Initialization Protocol */ - #define ETH_P_80221 0x8917 /* IEEE 802.21 Media Independent Handover Protocol */ - #define ETH_P_HSR 0x892F /* IEC 62439-3 HSRv1 */ -+#define ETH_P_NSH 0x894F /* Network Service Header */ - #define ETH_P_LOOPBACK 0x9000 /* Ethernet loopback packet, per IEEE 802.3 */ - #define ETH_P_QINQ1 0x9100 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */ - #define ETH_P_QINQ2 0x9200 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */ - #define ETH_P_QINQ3 0x9300 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */ - #define ETH_P_EDSA 0xDADA /* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */ -+#define ETH_P_IFE 0xED3E /* ForCES inter-FE LFB type */ - #define ETH_P_AF_IUCV 0xFBFB /* IBM af_iucv [ NOT AN OFFICIALLY REGISTERED ID ] */ - - #define ETH_P_802_3_MIN 0x0600 /* If the value in the ethernet type is less than this value -@@ -137,6 +140,9 @@ - #define ETH_P_IEEE802154 0x00F6 /* IEEE802.15.4 frame */ - #define ETH_P_CAIF 0x00F7 /* ST-Ericsson CAIF protocol */ - #define ETH_P_XDSA 0x00F8 /* Multiplexed DSA protocol */ -+#define ETH_P_MAP 0x00F9 /* Qualcomm multiplexing and -+ * aggregation protocol -+ */ - - /* - * This is an Ethernet frame header. -diff --git a/include/linux/if_link.h b/include/linux/if_link.h -index b0bdbd6e16c04..1f97d0560b6cb 100644 ---- a/include/linux/if_link.h -+++ b/include/linux/if_link.h -@@ -157,6 +157,7 @@ enum { - IFLA_GSO_MAX_SIZE, - IFLA_PAD, - IFLA_XDP, -+ IFLA_EVENT, - __IFLA_MAX - }; - -@@ -321,6 +322,7 @@ enum { - IFLA_BRPORT_MCAST_FLOOD, - IFLA_BRPORT_MCAST_TO_UCAST, - IFLA_BRPORT_VLAN_TUNNEL, -+ IFLA_BRPORT_BCAST_FLOOD, - __IFLA_BRPORT_MAX - }; - #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) -@@ -536,11 +538,18 @@ enum { - #define IFLA_PPP_MAX (__IFLA_PPP_MAX - 1) - - /* GTP section */ -+ -+enum ifla_gtp_role { -+ GTP_ROLE_GGSN = 0, -+ GTP_ROLE_SGSN, -+}; -+ - enum { - IFLA_GTP_UNSPEC, - IFLA_GTP_FD0, - IFLA_GTP_FD1, - IFLA_GTP_PDP_HASHSIZE, -+ IFLA_GTP_ROLE, - __IFLA_GTP_MAX, - }; - #define IFLA_GTP_MAX (__IFLA_GTP_MAX - 1) -@@ -878,16 +887,42 @@ enum { - /* XDP section */ - - #define XDP_FLAGS_UPDATE_IF_NOEXIST (1U << 0) --#define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST) -+#define XDP_FLAGS_SKB_MODE (1U << 1) -+#define XDP_FLAGS_DRV_MODE (1U << 2) -+#define XDP_FLAGS_HW_MODE (1U << 3) -+#define XDP_FLAGS_MODES (XDP_FLAGS_SKB_MODE | \ -+ XDP_FLAGS_DRV_MODE | \ -+ XDP_FLAGS_HW_MODE) -+#define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST | \ -+ XDP_FLAGS_MODES) -+ -+/* These are stored into IFLA_XDP_ATTACHED on dump. */ -+enum { -+ XDP_ATTACHED_NONE = 0, -+ XDP_ATTACHED_DRV, -+ XDP_ATTACHED_SKB, -+ XDP_ATTACHED_HW, -+}; - - enum { - IFLA_XDP_UNSPEC, - IFLA_XDP_FD, - IFLA_XDP_ATTACHED, - IFLA_XDP_FLAGS, -+ IFLA_XDP_PROG_ID, - __IFLA_XDP_MAX, - }; - - #define IFLA_XDP_MAX (__IFLA_XDP_MAX - 1) - -+enum { -+ IFLA_EVENT_NONE, -+ IFLA_EVENT_REBOOT, /* internal reset / reboot */ -+ IFLA_EVENT_FEATURES, /* change in offload features */ -+ IFLA_EVENT_BONDING_FAILOVER, /* change in active slave */ -+ IFLA_EVENT_NOTIFY_PEERS, /* re-sent grat. arp/ndisc */ -+ IFLA_EVENT_IGMP_RESEND, /* re-sent IGMP JOIN */ -+ IFLA_EVENT_BONDING_OPTIONS, /* change in bonding options */ -+}; -+ - #endif /* _LINUX_IF_LINK_H */ -diff --git a/include/linux/if_packet.h b/include/linux/if_packet.h -index 9e7edfd8141e5..4df96a7dd4fae 100644 ---- a/include/linux/if_packet.h -+++ b/include/linux/if_packet.h -@@ -66,6 +66,7 @@ struct sockaddr_ll { - #define PACKET_FANOUT_CBPF 6 - #define PACKET_FANOUT_EBPF 7 - #define PACKET_FANOUT_FLAG_ROLLOVER 0x1000 -+#define PACKET_FANOUT_FLAG_UNIQUEID 0x2000 - #define PACKET_FANOUT_FLAG_DEFRAG 0x8000 - - struct tpacket_stats { -diff --git a/include/linux/if_tunnel.h b/include/linux/if_tunnel.h -index 4f975f5704d8f..21834cac4c0d5 100644 ---- a/include/linux/if_tunnel.h -+++ b/include/linux/if_tunnel.h -@@ -75,6 +75,7 @@ enum { - IFLA_IPTUN_ENCAP_SPORT, - IFLA_IPTUN_ENCAP_DPORT, - IFLA_IPTUN_COLLECT_METADATA, -+ IFLA_IPTUN_FWMARK, - __IFLA_IPTUN_MAX, - }; - #define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1) -@@ -132,6 +133,8 @@ enum { - IFLA_GRE_ENCAP_DPORT, - IFLA_GRE_COLLECT_METADATA, - IFLA_GRE_IGNORE_DF, -+ IFLA_GRE_FWMARK, -+ IFLA_GRE_ERSPAN_INDEX, - __IFLA_GRE_MAX, - }; - -@@ -147,6 +150,7 @@ enum { - IFLA_VTI_OKEY, - IFLA_VTI_LOCAL, - IFLA_VTI_REMOTE, -+ IFLA_VTI_FWMARK, - __IFLA_VTI_MAX, - }; - -diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h -index f7bf7819e9243..bada4d7b6c8e6 100644 ---- a/include/linux/inet_diag.h -+++ b/include/linux/inet_diag.h -@@ -142,6 +142,8 @@ enum { - INET_DIAG_PAD, - INET_DIAG_MARK, - INET_DIAG_BBRINFO, -+ INET_DIAG_CLASS_ID, -+ INET_DIAG_MD5SIG, - __INET_DIAG_MAX, - }; - -diff --git a/include/linux/ipsec.h b/include/linux/ipsec.h -new file mode 100644 -index 0000000000000..d17a6302a0e96 ---- /dev/null -+++ b/include/linux/ipsec.h -@@ -0,0 +1,47 @@ -+#ifndef _LINUX_IPSEC_H -+#define _LINUX_IPSEC_H -+ -+/* The definitions, required to talk to KAME racoon IKE. */ -+ -+#include -+ -+#define IPSEC_PORT_ANY 0 -+#define IPSEC_ULPROTO_ANY 255 -+#define IPSEC_PROTO_ANY 255 -+ -+enum { -+ IPSEC_MODE_ANY = 0, /* We do not support this for SA */ -+ IPSEC_MODE_TRANSPORT = 1, -+ IPSEC_MODE_TUNNEL = 2, -+ IPSEC_MODE_BEET = 3 -+}; -+ -+enum { -+ IPSEC_DIR_ANY = 0, -+ IPSEC_DIR_INBOUND = 1, -+ IPSEC_DIR_OUTBOUND = 2, -+ IPSEC_DIR_FWD = 3, /* It is our own */ -+ IPSEC_DIR_MAX = 4, -+ IPSEC_DIR_INVALID = 5 -+}; -+ -+enum { -+ IPSEC_POLICY_DISCARD = 0, -+ IPSEC_POLICY_NONE = 1, -+ IPSEC_POLICY_IPSEC = 2, -+ IPSEC_POLICY_ENTRUST = 3, -+ IPSEC_POLICY_BYPASS = 4 -+}; -+ -+enum { -+ IPSEC_LEVEL_DEFAULT = 0, -+ IPSEC_LEVEL_USE = 1, -+ IPSEC_LEVEL_REQUIRE = 2, -+ IPSEC_LEVEL_UNIQUE = 3 -+}; -+ -+#define IPSEC_MANUAL_REQID_MAX 0x3fff -+ -+#define IPSEC_REPLAYWSIZE 32 -+ -+#endif /* _LINUX_IPSEC_H */ -diff --git a/include/linux/lwtunnel.h b/include/linux/lwtunnel.h -index faa6eabee2040..329842627162b 100644 ---- a/include/linux/lwtunnel.h -+++ b/include/linux/lwtunnel.h -@@ -11,6 +11,7 @@ enum lwtunnel_encap_types { - LWTUNNEL_ENCAP_IP6, - LWTUNNEL_ENCAP_SEG6, - LWTUNNEL_ENCAP_BPF, -+ LWTUNNEL_ENCAP_SEG6_LOCAL, - __LWTUNNEL_ENCAP_MAX, - }; - -diff --git a/include/linux/magic.h b/include/linux/magic.h -index e230af2e68558..e439565df838a 100644 ---- a/include/linux/magic.h -+++ b/include/linux/magic.h -@@ -42,6 +42,7 @@ - #define MSDOS_SUPER_MAGIC 0x4d44 /* MD */ - #define NCP_SUPER_MAGIC 0x564c /* Guess, what 0x564c is :-) */ - #define NFS_SUPER_MAGIC 0x6969 -+#define OCFS2_SUPER_MAGIC 0x7461636f - #define OPENPROM_SUPER_MAGIC 0x9fa1 - #define QNX4_SUPER_MAGIC 0x002f /* qnx4 fs detection */ - #define QNX6_SUPER_MAGIC 0x68191122 /* qnx6 fs detection */ -@@ -80,6 +81,8 @@ - #define BTRFS_TEST_MAGIC 0x73727279 - #define NSFS_MAGIC 0x6e736673 - #define BPF_FS_MAGIC 0xcafe4a11 -+#define AAFS_MAGIC 0x5a3c69f0 -+ - /* Since UDF 2.01 is ISO 13346 based... */ - #define UDF_SUPER_MAGIC 0x15013346 - #define BALLOON_KVM_MAGIC 0x13661366 -diff --git a/include/linux/mpls_iptunnel.h b/include/linux/mpls_iptunnel.h -index 4132c3c59572b..1a0e57b45a8ce 100644 ---- a/include/linux/mpls_iptunnel.h -+++ b/include/linux/mpls_iptunnel.h -@@ -16,11 +16,13 @@ - /* MPLS tunnel attributes - * [RTA_ENCAP] = { - * [MPLS_IPTUNNEL_DST] -+ * [MPLS_IPTUNNEL_TTL] - * } - */ - enum { - MPLS_IPTUNNEL_UNSPEC, - MPLS_IPTUNNEL_DST, -+ MPLS_IPTUNNEL_TTL, - __MPLS_IPTUNNEL_MAX, - }; - #define MPLS_IPTUNNEL_MAX (__MPLS_IPTUNNEL_MAX - 1) -diff --git a/include/linux/neighbour.h b/include/linux/neighbour.h -index f3d16dbe09d64..3199d28980b35 100644 ---- a/include/linux/neighbour.h -+++ b/include/linux/neighbour.h -@@ -41,6 +41,7 @@ enum { - #define NTF_MASTER 0x04 - #define NTF_PROXY 0x08 /* == ATF_PUBL */ - #define NTF_EXT_LEARNED 0x10 -+#define NTF_OFFLOADED 0x20 - #define NTF_ROUTER 0x80 - - /* -diff --git a/include/linux/netlink.h b/include/linux/netlink.h -index d1e26a2bcdcbb..ec0690b506471 100644 ---- a/include/linux/netlink.h -+++ b/include/linux/netlink.h -@@ -50,12 +50,12 @@ struct nlmsghdr { - - /* Flags values */ - --#define NLM_F_REQUEST 1 /* It is request message. */ --#define NLM_F_MULTI 2 /* Multipart message, terminated by NLMSG_DONE */ --#define NLM_F_ACK 4 /* Reply with ack, with zero or error code */ --#define NLM_F_ECHO 8 /* Echo this request */ --#define NLM_F_DUMP_INTR 16 /* Dump was inconsistent due to sequence change */ --#define NLM_F_DUMP_FILTERED 32 /* Dump was filtered as requested */ -+#define NLM_F_REQUEST 0x01 /* It is request message. */ -+#define NLM_F_MULTI 0x02 /* Multipart message, terminated by NLMSG_DONE */ -+#define NLM_F_ACK 0x04 /* Reply with ack, with zero or error code */ -+#define NLM_F_ECHO 0x08 /* Echo this request */ -+#define NLM_F_DUMP_INTR 0x10 /* Dump was inconsistent due to sequence change */ -+#define NLM_F_DUMP_FILTERED 0x20 /* Dump was filtered as requested */ - - /* Modifiers to GET request */ - #define NLM_F_ROOT 0x100 /* specify tree root */ -@@ -69,6 +69,13 @@ struct nlmsghdr { - #define NLM_F_CREATE 0x400 /* Create, if it does not exist */ - #define NLM_F_APPEND 0x800 /* Add to end of list */ - -+/* Modifiers to DELETE request */ -+#define NLM_F_NONREC 0x100 /* Do not delete recursively */ -+ -+/* Flags for ACK message */ -+#define NLM_F_CAPPED 0x100 /* request was capped */ -+#define NLM_F_ACK_TLVS 0x200 /* extended ACK TVLs were included */ -+ - /* - 4.4BSD ADD NLM_F_CREATE|NLM_F_EXCL - 4.4BSD CHANGE NLM_F_REPLACE -@@ -101,6 +108,37 @@ struct nlmsghdr { - struct nlmsgerr { - int error; - struct nlmsghdr msg; -+ /* -+ * followed by the message contents unless NETLINK_CAP_ACK was set -+ * or the ACK indicates success (error == 0) -+ * message length is aligned with NLMSG_ALIGN() -+ */ -+ /* -+ * followed by TLVs defined in enum nlmsgerr_attrs -+ * if NETLINK_EXT_ACK was set -+ */ -+}; -+ -+/** -+ * enum nlmsgerr_attrs - nlmsgerr attributes -+ * @NLMSGERR_ATTR_UNUSED: unused -+ * @NLMSGERR_ATTR_MSG: error message string (string) -+ * @NLMSGERR_ATTR_OFFS: offset of the invalid attribute in the original -+ * message, counting from the beginning of the header (u32) -+ * @NLMSGERR_ATTR_COOKIE: arbitrary subsystem specific cookie to -+ * be used - in the success case - to identify a created -+ * object or operation or similar (binary) -+ * @__NLMSGERR_ATTR_MAX: number of attributes -+ * @NLMSGERR_ATTR_MAX: highest attribute number -+ */ -+enum nlmsgerr_attrs { -+ NLMSGERR_ATTR_UNUSED, -+ NLMSGERR_ATTR_MSG, -+ NLMSGERR_ATTR_OFFS, -+ NLMSGERR_ATTR_COOKIE, -+ -+ __NLMSGERR_ATTR_MAX, -+ NLMSGERR_ATTR_MAX = __NLMSGERR_ATTR_MAX - 1 - }; - - #define NETLINK_ADD_MEMBERSHIP 1 -@@ -187,5 +225,22 @@ struct nlattr { - #define NLA_ALIGN(len) (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1)) - #define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr))) - -+/* Generic 32 bitflags attribute content sent to the kernel. -+ * -+ * The value is a bitmap that defines the values being set -+ * The selector is a bitmask that defines which value is legit -+ * -+ * Examples: -+ * value = 0x0, and selector = 0x1 -+ * implies we are selecting bit 1 and we want to set its value to 0. -+ * -+ * value = 0x2, and selector = 0x2 -+ * implies we are selecting bit 2 and we want to set its value to 1. -+ * -+ */ -+struct nla_bitfield32 { -+ __u32 value; -+ __u32 selector; -+}; - - #endif /* __LINUX_NETLINK_H */ -diff --git a/include/linux/netlink_diag.h b/include/linux/netlink_diag.h -index defd25fb5f5af..c8c8c7d2e530b 100644 ---- a/include/linux/netlink_diag.h -+++ b/include/linux/netlink_diag.h -@@ -38,6 +38,7 @@ enum { - NETLINK_DIAG_GROUPS, - NETLINK_DIAG_RX_RING, - NETLINK_DIAG_TX_RING, -+ NETLINK_DIAG_FLAGS, - - __NETLINK_DIAG_MAX, - }; -@@ -50,5 +51,14 @@ enum { - #define NDIAG_SHOW_GROUPS 0x00000002 /* show groups of a netlink socket */ - /* deprecated since 4.6 */ - #define NDIAG_SHOW_RING_CFG 0x00000004 /* show ring configuration */ -+#define NDIAG_SHOW_FLAGS 0x00000008 /* show flags of a netlink socket */ -+ -+/* flags */ -+#define NDIAG_FLAG_CB_RUNNING 0x00000001 -+#define NDIAG_FLAG_PKTINFO 0x00000002 -+#define NDIAG_FLAG_BROADCAST_ERROR 0x00000004 -+#define NDIAG_FLAG_NO_ENOBUFS 0x00000008 -+#define NDIAG_FLAG_LISTEN_ALL_NSID 0x00000010 -+#define NDIAG_FLAG_CAP_ACK 0x00000020 - - #endif -diff --git a/include/linux/pfkeyv2.h b/include/linux/pfkeyv2.h -new file mode 100644 -index 0000000000000..ada7f0171cccd ---- /dev/null -+++ b/include/linux/pfkeyv2.h -@@ -0,0 +1,383 @@ -+/* PF_KEY user interface, this is defined by rfc2367 so -+ * do not make arbitrary modifications or else this header -+ * file will not be compliant. -+ */ -+ -+#ifndef _LINUX_PFKEY2_H -+#define _LINUX_PFKEY2_H -+ -+#include -+ -+#define PF_KEY_V2 2 -+#define PFKEYV2_REVISION 199806L -+ -+struct sadb_msg { -+ __u8 sadb_msg_version; -+ __u8 sadb_msg_type; -+ __u8 sadb_msg_errno; -+ __u8 sadb_msg_satype; -+ __u16 sadb_msg_len; -+ __u16 sadb_msg_reserved; -+ __u32 sadb_msg_seq; -+ __u32 sadb_msg_pid; -+} __attribute__((packed)); -+/* sizeof(struct sadb_msg) == 16 */ -+ -+struct sadb_ext { -+ __u16 sadb_ext_len; -+ __u16 sadb_ext_type; -+} __attribute__((packed)); -+/* sizeof(struct sadb_ext) == 4 */ -+ -+struct sadb_sa { -+ __u16 sadb_sa_len; -+ __u16 sadb_sa_exttype; -+ __be32 sadb_sa_spi; -+ __u8 sadb_sa_replay; -+ __u8 sadb_sa_state; -+ __u8 sadb_sa_auth; -+ __u8 sadb_sa_encrypt; -+ __u32 sadb_sa_flags; -+} __attribute__((packed)); -+/* sizeof(struct sadb_sa) == 16 */ -+ -+struct sadb_lifetime { -+ __u16 sadb_lifetime_len; -+ __u16 sadb_lifetime_exttype; -+ __u32 sadb_lifetime_allocations; -+ __u64 sadb_lifetime_bytes; -+ __u64 sadb_lifetime_addtime; -+ __u64 sadb_lifetime_usetime; -+} __attribute__((packed)); -+/* sizeof(struct sadb_lifetime) == 32 */ -+ -+struct sadb_address { -+ __u16 sadb_address_len; -+ __u16 sadb_address_exttype; -+ __u8 sadb_address_proto; -+ __u8 sadb_address_prefixlen; -+ __u16 sadb_address_reserved; -+} __attribute__((packed)); -+/* sizeof(struct sadb_address) == 8 */ -+ -+struct sadb_key { -+ __u16 sadb_key_len; -+ __u16 sadb_key_exttype; -+ __u16 sadb_key_bits; -+ __u16 sadb_key_reserved; -+} __attribute__((packed)); -+/* sizeof(struct sadb_key) == 8 */ -+ -+struct sadb_ident { -+ __u16 sadb_ident_len; -+ __u16 sadb_ident_exttype; -+ __u16 sadb_ident_type; -+ __u16 sadb_ident_reserved; -+ __u64 sadb_ident_id; -+} __attribute__((packed)); -+/* sizeof(struct sadb_ident) == 16 */ -+ -+struct sadb_sens { -+ __u16 sadb_sens_len; -+ __u16 sadb_sens_exttype; -+ __u32 sadb_sens_dpd; -+ __u8 sadb_sens_sens_level; -+ __u8 sadb_sens_sens_len; -+ __u8 sadb_sens_integ_level; -+ __u8 sadb_sens_integ_len; -+ __u32 sadb_sens_reserved; -+} __attribute__((packed)); -+/* sizeof(struct sadb_sens) == 16 */ -+ -+/* followed by: -+ __u64 sadb_sens_bitmap[sens_len]; -+ __u64 sadb_integ_bitmap[integ_len]; */ -+ -+struct sadb_prop { -+ __u16 sadb_prop_len; -+ __u16 sadb_prop_exttype; -+ __u8 sadb_prop_replay; -+ __u8 sadb_prop_reserved[3]; -+} __attribute__((packed)); -+/* sizeof(struct sadb_prop) == 8 */ -+ -+/* followed by: -+ struct sadb_comb sadb_combs[(sadb_prop_len + -+ sizeof(__u64) - sizeof(struct sadb_prop)) / -+ sizeof(struct sadb_comb)]; */ -+ -+struct sadb_comb { -+ __u8 sadb_comb_auth; -+ __u8 sadb_comb_encrypt; -+ __u16 sadb_comb_flags; -+ __u16 sadb_comb_auth_minbits; -+ __u16 sadb_comb_auth_maxbits; -+ __u16 sadb_comb_encrypt_minbits; -+ __u16 sadb_comb_encrypt_maxbits; -+ __u32 sadb_comb_reserved; -+ __u32 sadb_comb_soft_allocations; -+ __u32 sadb_comb_hard_allocations; -+ __u64 sadb_comb_soft_bytes; -+ __u64 sadb_comb_hard_bytes; -+ __u64 sadb_comb_soft_addtime; -+ __u64 sadb_comb_hard_addtime; -+ __u64 sadb_comb_soft_usetime; -+ __u64 sadb_comb_hard_usetime; -+} __attribute__((packed)); -+/* sizeof(struct sadb_comb) == 72 */ -+ -+struct sadb_supported { -+ __u16 sadb_supported_len; -+ __u16 sadb_supported_exttype; -+ __u32 sadb_supported_reserved; -+} __attribute__((packed)); -+/* sizeof(struct sadb_supported) == 8 */ -+ -+/* followed by: -+ struct sadb_alg sadb_algs[(sadb_supported_len + -+ sizeof(__u64) - sizeof(struct sadb_supported)) / -+ sizeof(struct sadb_alg)]; */ -+ -+struct sadb_alg { -+ __u8 sadb_alg_id; -+ __u8 sadb_alg_ivlen; -+ __u16 sadb_alg_minbits; -+ __u16 sadb_alg_maxbits; -+ __u16 sadb_alg_reserved; -+} __attribute__((packed)); -+/* sizeof(struct sadb_alg) == 8 */ -+ -+struct sadb_spirange { -+ __u16 sadb_spirange_len; -+ __u16 sadb_spirange_exttype; -+ __u32 sadb_spirange_min; -+ __u32 sadb_spirange_max; -+ __u32 sadb_spirange_reserved; -+} __attribute__((packed)); -+/* sizeof(struct sadb_spirange) == 16 */ -+ -+struct sadb_x_kmprivate { -+ __u16 sadb_x_kmprivate_len; -+ __u16 sadb_x_kmprivate_exttype; -+ __u32 sadb_x_kmprivate_reserved; -+} __attribute__((packed)); -+/* sizeof(struct sadb_x_kmprivate) == 8 */ -+ -+struct sadb_x_sa2 { -+ __u16 sadb_x_sa2_len; -+ __u16 sadb_x_sa2_exttype; -+ __u8 sadb_x_sa2_mode; -+ __u8 sadb_x_sa2_reserved1; -+ __u16 sadb_x_sa2_reserved2; -+ __u32 sadb_x_sa2_sequence; -+ __u32 sadb_x_sa2_reqid; -+} __attribute__((packed)); -+/* sizeof(struct sadb_x_sa2) == 16 */ -+ -+struct sadb_x_policy { -+ __u16 sadb_x_policy_len; -+ __u16 sadb_x_policy_exttype; -+ __u16 sadb_x_policy_type; -+ __u8 sadb_x_policy_dir; -+ __u8 sadb_x_policy_reserved; -+ __u32 sadb_x_policy_id; -+ __u32 sadb_x_policy_priority; -+} __attribute__((packed)); -+/* sizeof(struct sadb_x_policy) == 16 */ -+ -+struct sadb_x_ipsecrequest { -+ __u16 sadb_x_ipsecrequest_len; -+ __u16 sadb_x_ipsecrequest_proto; -+ __u8 sadb_x_ipsecrequest_mode; -+ __u8 sadb_x_ipsecrequest_level; -+ __u16 sadb_x_ipsecrequest_reserved1; -+ __u32 sadb_x_ipsecrequest_reqid; -+ __u32 sadb_x_ipsecrequest_reserved2; -+} __attribute__((packed)); -+/* sizeof(struct sadb_x_ipsecrequest) == 16 */ -+ -+/* This defines the TYPE of Nat Traversal in use. Currently only one -+ * type of NAT-T is supported, draft-ietf-ipsec-udp-encaps-06 -+ */ -+struct sadb_x_nat_t_type { -+ __u16 sadb_x_nat_t_type_len; -+ __u16 sadb_x_nat_t_type_exttype; -+ __u8 sadb_x_nat_t_type_type; -+ __u8 sadb_x_nat_t_type_reserved[3]; -+} __attribute__((packed)); -+/* sizeof(struct sadb_x_nat_t_type) == 8 */ -+ -+/* Pass a NAT Traversal port (Source or Dest port) */ -+struct sadb_x_nat_t_port { -+ __u16 sadb_x_nat_t_port_len; -+ __u16 sadb_x_nat_t_port_exttype; -+ __be16 sadb_x_nat_t_port_port; -+ __u16 sadb_x_nat_t_port_reserved; -+} __attribute__((packed)); -+/* sizeof(struct sadb_x_nat_t_port) == 8 */ -+ -+/* Generic LSM security context */ -+struct sadb_x_sec_ctx { -+ __u16 sadb_x_sec_len; -+ __u16 sadb_x_sec_exttype; -+ __u8 sadb_x_ctx_alg; /* LSMs: e.g., selinux == 1 */ -+ __u8 sadb_x_ctx_doi; -+ __u16 sadb_x_ctx_len; -+} __attribute__((packed)); -+/* sizeof(struct sadb_sec_ctx) = 8 */ -+ -+/* Used by MIGRATE to pass addresses IKE will use to perform -+ * negotiation with the peer */ -+struct sadb_x_kmaddress { -+ __u16 sadb_x_kmaddress_len; -+ __u16 sadb_x_kmaddress_exttype; -+ __u32 sadb_x_kmaddress_reserved; -+} __attribute__((packed)); -+/* sizeof(struct sadb_x_kmaddress) == 8 */ -+ -+/* To specify the SA dump filter */ -+struct sadb_x_filter { -+ __u16 sadb_x_filter_len; -+ __u16 sadb_x_filter_exttype; -+ __u32 sadb_x_filter_saddr[4]; -+ __u32 sadb_x_filter_daddr[4]; -+ __u16 sadb_x_filter_family; -+ __u8 sadb_x_filter_splen; -+ __u8 sadb_x_filter_dplen; -+} __attribute__((packed)); -+/* sizeof(struct sadb_x_filter) == 40 */ -+ -+/* Message types */ -+#define SADB_RESERVED 0 -+#define SADB_GETSPI 1 -+#define SADB_UPDATE 2 -+#define SADB_ADD 3 -+#define SADB_DELETE 4 -+#define SADB_GET 5 -+#define SADB_ACQUIRE 6 -+#define SADB_REGISTER 7 -+#define SADB_EXPIRE 8 -+#define SADB_FLUSH 9 -+#define SADB_DUMP 10 -+#define SADB_X_PROMISC 11 -+#define SADB_X_PCHANGE 12 -+#define SADB_X_SPDUPDATE 13 -+#define SADB_X_SPDADD 14 -+#define SADB_X_SPDDELETE 15 -+#define SADB_X_SPDGET 16 -+#define SADB_X_SPDACQUIRE 17 -+#define SADB_X_SPDDUMP 18 -+#define SADB_X_SPDFLUSH 19 -+#define SADB_X_SPDSETIDX 20 -+#define SADB_X_SPDEXPIRE 21 -+#define SADB_X_SPDDELETE2 22 -+#define SADB_X_NAT_T_NEW_MAPPING 23 -+#define SADB_X_MIGRATE 24 -+#define SADB_MAX 24 -+ -+/* Security Association flags */ -+#define SADB_SAFLAGS_PFS 1 -+#define SADB_SAFLAGS_NOPMTUDISC 0x20000000 -+#define SADB_SAFLAGS_DECAP_DSCP 0x40000000 -+#define SADB_SAFLAGS_NOECN 0x80000000 -+ -+/* Security Association states */ -+#define SADB_SASTATE_LARVAL 0 -+#define SADB_SASTATE_MATURE 1 -+#define SADB_SASTATE_DYING 2 -+#define SADB_SASTATE_DEAD 3 -+#define SADB_SASTATE_MAX 3 -+ -+/* Security Association types */ -+#define SADB_SATYPE_UNSPEC 0 -+#define SADB_SATYPE_AH 2 -+#define SADB_SATYPE_ESP 3 -+#define SADB_SATYPE_RSVP 5 -+#define SADB_SATYPE_OSPFV2 6 -+#define SADB_SATYPE_RIPV2 7 -+#define SADB_SATYPE_MIP 8 -+#define SADB_X_SATYPE_IPCOMP 9 -+#define SADB_SATYPE_MAX 9 -+ -+/* Authentication algorithms */ -+#define SADB_AALG_NONE 0 -+#define SADB_AALG_MD5HMAC 2 -+#define SADB_AALG_SHA1HMAC 3 -+#define SADB_X_AALG_SHA2_256HMAC 5 -+#define SADB_X_AALG_SHA2_384HMAC 6 -+#define SADB_X_AALG_SHA2_512HMAC 7 -+#define SADB_X_AALG_RIPEMD160HMAC 8 -+#define SADB_X_AALG_AES_XCBC_MAC 9 -+#define SADB_X_AALG_NULL 251 /* kame */ -+#define SADB_AALG_MAX 251 -+ -+/* Encryption algorithms */ -+#define SADB_EALG_NONE 0 -+#define SADB_EALG_DESCBC 2 -+#define SADB_EALG_3DESCBC 3 -+#define SADB_X_EALG_CASTCBC 6 -+#define SADB_X_EALG_BLOWFISHCBC 7 -+#define SADB_EALG_NULL 11 -+#define SADB_X_EALG_AESCBC 12 -+#define SADB_X_EALG_AESCTR 13 -+#define SADB_X_EALG_AES_CCM_ICV8 14 -+#define SADB_X_EALG_AES_CCM_ICV12 15 -+#define SADB_X_EALG_AES_CCM_ICV16 16 -+#define SADB_X_EALG_AES_GCM_ICV8 18 -+#define SADB_X_EALG_AES_GCM_ICV12 19 -+#define SADB_X_EALG_AES_GCM_ICV16 20 -+#define SADB_X_EALG_CAMELLIACBC 22 -+#define SADB_X_EALG_NULL_AES_GMAC 23 -+#define SADB_EALG_MAX 253 /* last EALG */ -+/* private allocations should use 249-255 (RFC2407) */ -+#define SADB_X_EALG_SERPENTCBC 252 /* draft-ietf-ipsec-ciph-aes-cbc-00 */ -+#define SADB_X_EALG_TWOFISHCBC 253 /* draft-ietf-ipsec-ciph-aes-cbc-00 */ -+ -+/* Compression algorithms */ -+#define SADB_X_CALG_NONE 0 -+#define SADB_X_CALG_OUI 1 -+#define SADB_X_CALG_DEFLATE 2 -+#define SADB_X_CALG_LZS 3 -+#define SADB_X_CALG_LZJH 4 -+#define SADB_X_CALG_MAX 4 -+ -+/* Extension Header values */ -+#define SADB_EXT_RESERVED 0 -+#define SADB_EXT_SA 1 -+#define SADB_EXT_LIFETIME_CURRENT 2 -+#define SADB_EXT_LIFETIME_HARD 3 -+#define SADB_EXT_LIFETIME_SOFT 4 -+#define SADB_EXT_ADDRESS_SRC 5 -+#define SADB_EXT_ADDRESS_DST 6 -+#define SADB_EXT_ADDRESS_PROXY 7 -+#define SADB_EXT_KEY_AUTH 8 -+#define SADB_EXT_KEY_ENCRYPT 9 -+#define SADB_EXT_IDENTITY_SRC 10 -+#define SADB_EXT_IDENTITY_DST 11 -+#define SADB_EXT_SENSITIVITY 12 -+#define SADB_EXT_PROPOSAL 13 -+#define SADB_EXT_SUPPORTED_AUTH 14 -+#define SADB_EXT_SUPPORTED_ENCRYPT 15 -+#define SADB_EXT_SPIRANGE 16 -+#define SADB_X_EXT_KMPRIVATE 17 -+#define SADB_X_EXT_POLICY 18 -+#define SADB_X_EXT_SA2 19 -+/* The next four entries are for setting up NAT Traversal */ -+#define SADB_X_EXT_NAT_T_TYPE 20 -+#define SADB_X_EXT_NAT_T_SPORT 21 -+#define SADB_X_EXT_NAT_T_DPORT 22 -+#define SADB_X_EXT_NAT_T_OA 23 -+#define SADB_X_EXT_SEC_CTX 24 -+/* Used with MIGRATE to pass @ to IKE for negotiation */ -+#define SADB_X_EXT_KMADDRESS 25 -+#define SADB_X_EXT_FILTER 26 -+#define SADB_EXT_MAX 26 -+ -+/* Identity Extension values */ -+#define SADB_IDENTTYPE_RESERVED 0 -+#define SADB_IDENTTYPE_PREFIX 1 -+#define SADB_IDENTTYPE_FQDN 2 -+#define SADB_IDENTTYPE_USERFQDN 3 -+#define SADB_IDENTTYPE_MAX 3 -+ -+#endif /* !(_LINUX_PFKEY2_H) */ -diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h -index 7a69f2a4ca0c0..d5e2bf68d0d40 100644 ---- a/include/linux/pkt_cls.h -+++ b/include/linux/pkt_cls.h -@@ -37,7 +37,28 @@ enum { - #define TC_ACT_QUEUED 5 - #define TC_ACT_REPEAT 6 - #define TC_ACT_REDIRECT 7 --#define TC_ACT_JUMP 0x10000000 -+#define TC_ACT_TRAP 8 /* For hw path, this means "trap to cpu" -+ * and don't further process the frame -+ * in hardware. For sw path, this is -+ * equivalent of TC_ACT_STOLEN - drop -+ * the skb and act like everything -+ * is alright. -+ */ -+ -+/* There is a special kind of actions called "extended actions", -+ * which need a value parameter. These have a local opcode located in -+ * the highest nibble, starting from 1. The rest of the bits -+ * are used to carry the value. These two parts together make -+ * a combined opcode. -+ */ -+#define __TC_ACT_EXT_SHIFT 28 -+#define __TC_ACT_EXT(local) ((local) << __TC_ACT_EXT_SHIFT) -+#define TC_ACT_EXT_VAL_MASK ((1 << __TC_ACT_EXT_SHIFT) - 1) -+#define TC_ACT_EXT_CMP(combined, opcode) \ -+ (((combined) & (~TC_ACT_EXT_VAL_MASK)) == opcode) -+ -+#define TC_ACT_JUMP __TC_ACT_EXT(1) -+#define TC_ACT_GOTO_CHAIN __TC_ACT_EXT(2) - - /* Action type identifiers*/ - enum { -@@ -348,6 +369,7 @@ enum { - TCA_BPF_FLAGS, - TCA_BPF_FLAGS_GEN, - TCA_BPF_TAG, -+ TCA_BPF_ID, - __TCA_BPF_MAX, - }; - -@@ -432,6 +454,19 @@ enum { - TCA_FLOWER_KEY_ARP_THA, /* ETH_ALEN */ - TCA_FLOWER_KEY_ARP_THA_MASK, /* ETH_ALEN */ - -+ TCA_FLOWER_KEY_MPLS_TTL, /* u8 - 8 bits */ -+ TCA_FLOWER_KEY_MPLS_BOS, /* u8 - 1 bit */ -+ TCA_FLOWER_KEY_MPLS_TC, /* u8 - 3 bits */ -+ TCA_FLOWER_KEY_MPLS_LABEL, /* be32 - 20 bits */ -+ -+ TCA_FLOWER_KEY_TCP_FLAGS, /* be16 */ -+ TCA_FLOWER_KEY_TCP_FLAGS_MASK, /* be16 */ -+ -+ TCA_FLOWER_KEY_IP_TOS, /* u8 */ -+ TCA_FLOWER_KEY_IP_TOS_MASK, /* u8 */ -+ TCA_FLOWER_KEY_IP_TTL, /* u8 */ -+ TCA_FLOWER_KEY_IP_TTL_MASK, /* u8 */ -+ - __TCA_FLOWER_MAX, - }; - -diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h -index df7451d351311..099bf5528fed3 100644 ---- a/include/linux/pkt_sched.h -+++ b/include/linux/pkt_sched.h -@@ -617,6 +617,14 @@ struct tc_drr_stats { - #define TC_QOPT_BITMASK 15 - #define TC_QOPT_MAX_QUEUE 16 - -+enum { -+ TC_MQPRIO_HW_OFFLOAD_NONE, /* no offload requested */ -+ TC_MQPRIO_HW_OFFLOAD_TCS, /* offload TCs, no queue counts */ -+ __TC_MQPRIO_HW_OFFLOAD_MAX -+}; -+ -+#define TC_MQPRIO_HW_OFFLOAD_MAX (__TC_MQPRIO_HW_OFFLOAD_MAX - 1) -+ - struct tc_mqprio_qopt { - __u8 num_tc; - __u8 prio_tc_map[TC_QOPT_BITMASK + 1]; -diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h -index d42fe83cec694..813e9e0767d33 100644 ---- a/include/linux/rtnetlink.h -+++ b/include/linux/rtnetlink.h -@@ -122,6 +122,8 @@ enum { - - RTM_NEWNETCONF = 80, - #define RTM_NEWNETCONF RTM_NEWNETCONF -+ RTM_DELNETCONF, -+#define RTM_DELNETCONF RTM_DELNETCONF - RTM_GETNETCONF = 82, - #define RTM_GETNETCONF RTM_GETNETCONF - -@@ -144,6 +146,9 @@ enum { - RTM_GETSTATS = 94, - #define RTM_GETSTATS RTM_GETSTATS - -+ RTM_NEWCACHEREPORT = 96, -+#define RTM_NEWCACHEREPORT RTM_NEWCACHEREPORT -+ - __RTM_MAX, - #define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1) - }; -@@ -276,6 +281,7 @@ enum rt_scope_t { - #define RTM_F_EQUALIZE 0x400 /* Multipath equalizer: NI */ - #define RTM_F_PREFIX 0x800 /* Prefix addresses */ - #define RTM_F_LOOKUP_TABLE 0x1000 /* set rtm_table to FIB lookup result */ -+#define RTM_F_FIB_MATCH 0x2000 /* return full fib lookup match */ - - /* Reserved table identifiers */ - -@@ -319,6 +325,7 @@ enum rtattr_type_t { - RTA_EXPIRES, - RTA_PAD, - RTA_UID, -+ RTA_TTL_PROPAGATE, - __RTA_MAX - }; - -@@ -545,6 +552,8 @@ enum { - TCA_STATS2, - TCA_STAB, - TCA_PAD, -+ TCA_DUMP_INVISIBLE, -+ TCA_CHAIN, - __TCA_MAX - }; - -@@ -658,6 +667,10 @@ enum rtnetlink_groups { - #define RTNLGRP_NSID RTNLGRP_NSID - RTNLGRP_MPLS_NETCONF, - #define RTNLGRP_MPLS_NETCONF RTNLGRP_MPLS_NETCONF -+ RTNLGRP_IPV4_MROUTE_R, -+#define RTNLGRP_IPV4_MROUTE_R RTNLGRP_IPV4_MROUTE_R -+ RTNLGRP_IPV6_MROUTE_R, -+#define RTNLGRP_IPV6_MROUTE_R RTNLGRP_IPV6_MROUTE_R - __RTNLGRP_MAX - }; - #define RTNLGRP_MAX (__RTNLGRP_MAX - 1) -@@ -668,10 +681,29 @@ struct tcamsg { - unsigned char tca__pad1; - unsigned short tca__pad2; - }; -+ -+enum { -+ TCA_ROOT_UNSPEC, -+ TCA_ROOT_TAB, -+#define TCA_ACT_TAB TCA_ROOT_TAB -+#define TCAA_MAX TCA_ROOT_TAB -+ TCA_ROOT_FLAGS, -+ TCA_ROOT_COUNT, -+ TCA_ROOT_TIME_DELTA, /* in msecs */ -+ __TCA_ROOT_MAX, -+#define TCA_ROOT_MAX (__TCA_ROOT_MAX - 1) -+}; -+ - #define TA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcamsg)))) - #define TA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcamsg)) --#define TCA_ACT_TAB 1 /* attr type must be >=1 */ --#define TCAA_MAX 1 -+/* tcamsg flags stored in attribute TCA_ROOT_FLAGS -+ * -+ * TCA_FLAG_LARGE_DUMP_ON user->kernel to request for larger than TCA_ACT_MAX_PRIO -+ * actions in a dump. All dump responses will contain the number of actions -+ * being dumped stored in for user app's consumption in TCA_ROOT_COUNT -+ * -+ */ -+#define TCA_FLAG_LARGE_DUMP_ON (1 << 0) - - /* New extended info filters for IFLA_EXT_MASK */ - #define RTEXT_FILTER_VF (1 << 0) -diff --git a/include/linux/sctp.h b/include/linux/sctp.h -index 5e08b3de809eb..fec24c41405b9 100644 ---- a/include/linux/sctp.h -+++ b/include/linux/sctp.h -@@ -115,10 +115,13 @@ typedef __s32 sctp_assoc_t; - #define SCTP_PR_SUPPORTED 113 - #define SCTP_DEFAULT_PRINFO 114 - #define SCTP_PR_ASSOC_STATUS 115 -+#define SCTP_PR_STREAM_STATUS 116 -+#define SCTP_RECONFIG_SUPPORTED 117 - #define SCTP_ENABLE_STREAM_RESET 118 - #define SCTP_RESET_STREAMS 119 - #define SCTP_RESET_ASSOC 120 - #define SCTP_ADD_STREAMS 121 -+#define SCTP_SOCKOPT_PEELOFF_FLAGS 122 - - /* PR-SCTP policies */ - #define SCTP_PR_SCTP_NONE 0x0000 -@@ -502,6 +505,28 @@ struct sctp_stream_reset_event { - __u16 strreset_stream_list[]; - }; - -+#define SCTP_ASSOC_RESET_DENIED 0x0004 -+#define SCTP_ASSOC_RESET_FAILED 0x0008 -+struct sctp_assoc_reset_event { -+ __u16 assocreset_type; -+ __u16 assocreset_flags; -+ __u32 assocreset_length; -+ sctp_assoc_t assocreset_assoc_id; -+ __u32 assocreset_local_tsn; -+ __u32 assocreset_remote_tsn; -+}; -+ -+#define SCTP_ASSOC_CHANGE_DENIED 0x0004 -+#define SCTP_ASSOC_CHANGE_FAILED 0x0008 -+struct sctp_stream_change_event { -+ __u16 strchange_type; -+ __u16 strchange_flags; -+ __u32 strchange_length; -+ sctp_assoc_t strchange_assoc_id; -+ __u16 strchange_instrms; -+ __u16 strchange_outstrms; -+}; -+ - /* - * Described in Section 7.3 - * Ancillary Data and Notification Interest Options -@@ -518,6 +543,8 @@ struct sctp_event_subscribe { - __u8 sctp_authentication_event; - __u8 sctp_sender_dry_event; - __u8 sctp_stream_reset_event; -+ __u8 sctp_assoc_reset_event; -+ __u8 sctp_stream_change_event; - }; - - /* -@@ -543,6 +570,8 @@ union sctp_notification { - struct sctp_authkey_event sn_authkey_event; - struct sctp_sender_dry_event sn_sender_dry_event; - struct sctp_stream_reset_event sn_strreset_event; -+ struct sctp_assoc_reset_event sn_assocreset_event; -+ struct sctp_stream_change_event sn_strchange_event; - }; - - /* Section 5.3.1 -@@ -572,6 +601,10 @@ enum sctp_sn_type { - #define SCTP_SENDER_DRY_EVENT SCTP_SENDER_DRY_EVENT - SCTP_STREAM_RESET_EVENT, - #define SCTP_STREAM_RESET_EVENT SCTP_STREAM_RESET_EVENT -+ SCTP_ASSOC_RESET_EVENT, -+#define SCTP_ASSOC_RESET_EVENT SCTP_ASSOC_RESET_EVENT -+ SCTP_STREAM_CHANGE_EVENT, -+#define SCTP_STREAM_CHANGE_EVENT SCTP_STREAM_CHANGE_EVENT - }; - - /* Notification error codes used to fill up the error fields in some -@@ -940,6 +973,11 @@ typedef struct { - int sd; - } sctp_peeloff_arg_t; - -+typedef struct { -+ sctp_peeloff_arg_t p_arg; -+ unsigned flags; -+} sctp_peeloff_flags_arg_t; -+ - /* - * Peer Address Thresholds socket option - */ -diff --git a/include/linux/seg6.h b/include/linux/seg6.h -new file mode 100644 -index 0000000000000..07152792e61d2 ---- /dev/null -+++ b/include/linux/seg6.h -@@ -0,0 +1,54 @@ -+/* -+ * SR-IPv6 implementation -+ * -+ * Author: -+ * David Lebrun -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#ifndef _LINUX_SEG6_H -+#define _LINUX_SEG6_H -+ -+#include -+#include /* For struct in6_addr. */ -+ -+/* -+ * SRH -+ */ -+struct ipv6_sr_hdr { -+ __u8 nexthdr; -+ __u8 hdrlen; -+ __u8 type; -+ __u8 segments_left; -+ __u8 first_segment; -+ __u8 flags; -+ __u16 reserved; -+ -+ struct in6_addr segments[0]; -+}; -+ -+#define SR6_FLAG1_PROTECTED (1 << 6) -+#define SR6_FLAG1_OAM (1 << 5) -+#define SR6_FLAG1_ALERT (1 << 4) -+#define SR6_FLAG1_HMAC (1 << 3) -+ -+#define SR6_TLV_INGRESS 1 -+#define SR6_TLV_EGRESS 2 -+#define SR6_TLV_OPAQUE 3 -+#define SR6_TLV_PADDING 4 -+#define SR6_TLV_HMAC 5 -+ -+#define sr_has_hmac(srh) ((srh)->flags & SR6_FLAG1_HMAC) -+ -+struct sr6_tlv { -+ __u8 type; -+ __u8 len; -+ __u8 data[0]; -+}; -+ -+#endif -diff --git a/include/linux/seg6_genl.h b/include/linux/seg6_genl.h -new file mode 100644 -index 0000000000000..99382f94fa0a3 ---- /dev/null -+++ b/include/linux/seg6_genl.h -@@ -0,0 +1,32 @@ -+#ifndef _LINUX_SEG6_GENL_H -+#define _LINUX_SEG6_GENL_H -+ -+#define SEG6_GENL_NAME "SEG6" -+#define SEG6_GENL_VERSION 0x1 -+ -+enum { -+ SEG6_ATTR_UNSPEC, -+ SEG6_ATTR_DST, -+ SEG6_ATTR_DSTLEN, -+ SEG6_ATTR_HMACKEYID, -+ SEG6_ATTR_SECRET, -+ SEG6_ATTR_SECRETLEN, -+ SEG6_ATTR_ALGID, -+ SEG6_ATTR_HMACINFO, -+ __SEG6_ATTR_MAX, -+}; -+ -+#define SEG6_ATTR_MAX (__SEG6_ATTR_MAX - 1) -+ -+enum { -+ SEG6_CMD_UNSPEC, -+ SEG6_CMD_SETHMAC, -+ SEG6_CMD_DUMPHMAC, -+ SEG6_CMD_SET_TUNSRC, -+ SEG6_CMD_GET_TUNSRC, -+ __SEG6_CMD_MAX, -+}; -+ -+#define SEG6_CMD_MAX (__SEG6_CMD_MAX - 1) -+ -+#endif -diff --git a/include/linux/seg6_hmac.h b/include/linux/seg6_hmac.h -new file mode 100644 -index 0000000000000..704f93e80b417 ---- /dev/null -+++ b/include/linux/seg6_hmac.h -@@ -0,0 +1,22 @@ -+#ifndef _LINUX_SEG6_HMAC_H -+#define _LINUX_SEG6_HMAC_H -+ -+#include -+#include -+ -+#define SEG6_HMAC_SECRET_LEN 64 -+#define SEG6_HMAC_FIELD_LEN 32 -+ -+struct sr6_tlv_hmac { -+ struct sr6_tlv tlvhdr; -+ __u16 reserved; -+ __be32 hmackeyid; -+ __u8 hmac[SEG6_HMAC_FIELD_LEN]; -+}; -+ -+enum { -+ SEG6_HMAC_ALGO_SHA1 = 1, -+ SEG6_HMAC_ALGO_SHA256 = 2, -+}; -+ -+#endif -diff --git a/include/linux/seg6_iptunnel.h b/include/linux/seg6_iptunnel.h -new file mode 100644 -index 0000000000000..a5dc05a1cbba3 ---- /dev/null -+++ b/include/linux/seg6_iptunnel.h -@@ -0,0 +1,40 @@ -+/* -+ * SR-IPv6 implementation -+ * -+ * Author: -+ * David Lebrun -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#ifndef _LINUX_SEG6_IPTUNNEL_H -+#define _LINUX_SEG6_IPTUNNEL_H -+ -+#include /* For struct ipv6_sr_hdr. */ -+ -+enum { -+ SEG6_IPTUNNEL_UNSPEC, -+ SEG6_IPTUNNEL_SRH, -+ __SEG6_IPTUNNEL_MAX, -+}; -+#define SEG6_IPTUNNEL_MAX (__SEG6_IPTUNNEL_MAX - 1) -+ -+struct seg6_iptunnel_encap { -+ int mode; -+ struct ipv6_sr_hdr srh[0]; -+}; -+ -+#define SEG6_IPTUN_ENCAP_SIZE(x) ((sizeof(*x)) + (((x)->srh->hdrlen + 1) << 3)) -+ -+enum { -+ SEG6_IPTUN_MODE_INLINE, -+ SEG6_IPTUN_MODE_ENCAP, -+ SEG6_IPTUN_MODE_L2ENCAP, -+}; -+ -+ -+#endif -diff --git a/include/linux/seg6_local.h b/include/linux/seg6_local.h -new file mode 100644 -index 0000000000000..76b90d60c7ea7 ---- /dev/null -+++ b/include/linux/seg6_local.h -@@ -0,0 +1,68 @@ -+/* -+ * SR-IPv6 implementation -+ * -+ * Author: -+ * David Lebrun -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#ifndef _LINUX_SEG6_LOCAL_H -+#define _LINUX_SEG6_LOCAL_H -+ -+#include -+ -+enum { -+ SEG6_LOCAL_UNSPEC, -+ SEG6_LOCAL_ACTION, -+ SEG6_LOCAL_SRH, -+ SEG6_LOCAL_TABLE, -+ SEG6_LOCAL_NH4, -+ SEG6_LOCAL_NH6, -+ SEG6_LOCAL_IIF, -+ SEG6_LOCAL_OIF, -+ __SEG6_LOCAL_MAX, -+}; -+#define SEG6_LOCAL_MAX (__SEG6_LOCAL_MAX - 1) -+ -+enum { -+ SEG6_LOCAL_ACTION_UNSPEC = 0, -+ /* node segment */ -+ SEG6_LOCAL_ACTION_END = 1, -+ /* adjacency segment (IPv6 cross-connect) */ -+ SEG6_LOCAL_ACTION_END_X = 2, -+ /* lookup of next seg NH in table */ -+ SEG6_LOCAL_ACTION_END_T = 3, -+ /* decap and L2 cross-connect */ -+ SEG6_LOCAL_ACTION_END_DX2 = 4, -+ /* decap and IPv6 cross-connect */ -+ SEG6_LOCAL_ACTION_END_DX6 = 5, -+ /* decap and IPv4 cross-connect */ -+ SEG6_LOCAL_ACTION_END_DX4 = 6, -+ /* decap and lookup of DA in v6 table */ -+ SEG6_LOCAL_ACTION_END_DT6 = 7, -+ /* decap and lookup of DA in v4 table */ -+ SEG6_LOCAL_ACTION_END_DT4 = 8, -+ /* binding segment with insertion */ -+ SEG6_LOCAL_ACTION_END_B6 = 9, -+ /* binding segment with encapsulation */ -+ SEG6_LOCAL_ACTION_END_B6_ENCAP = 10, -+ /* binding segment with MPLS encap */ -+ SEG6_LOCAL_ACTION_END_BM = 11, -+ /* lookup last seg in table */ -+ SEG6_LOCAL_ACTION_END_S = 12, -+ /* forward to SR-unaware VNF with static proxy */ -+ SEG6_LOCAL_ACTION_END_AS = 13, -+ /* forward to SR-unaware VNF with masquerading */ -+ SEG6_LOCAL_ACTION_END_AM = 14, -+ -+ __SEG6_LOCAL_ACTION_MAX, -+}; -+ -+#define SEG6_LOCAL_ACTION_MAX (__SEG6_LOCAL_ACTION_MAX - 1) -+ -+#endif -diff --git a/include/linux/tc_act/tc_bpf.h b/include/linux/tc_act/tc_bpf.h -index 975b50dc8d1d4..8dc2ac05eecf0 100644 ---- a/include/linux/tc_act/tc_bpf.h -+++ b/include/linux/tc_act/tc_bpf.h -@@ -28,6 +28,7 @@ enum { - TCA_ACT_BPF_NAME, - TCA_ACT_BPF_PAD, - TCA_ACT_BPF_TAG, -+ TCA_ACT_BPF_ID, - __TCA_ACT_BPF_MAX, - }; - #define TCA_ACT_BPF_MAX (__TCA_ACT_BPF_MAX - 1) -diff --git a/include/linux/tc_act/tc_tunnel_key.h b/include/linux/tc_act/tc_tunnel_key.h -index 84ea55e1076b6..afcd4be953e27 100644 ---- a/include/linux/tc_act/tc_tunnel_key.h -+++ b/include/linux/tc_act/tc_tunnel_key.h -@@ -34,6 +34,7 @@ enum { - TCA_TUNNEL_KEY_ENC_KEY_ID, /* be64 */ - TCA_TUNNEL_KEY_PAD, - TCA_TUNNEL_KEY_ENC_DST_PORT, /* be16 */ -+ TCA_TUNNEL_KEY_NO_CSUM, /* u8 */ - __TCA_TUNNEL_KEY_MAX, - }; - -diff --git a/include/linux/tcp.h b/include/linux/tcp.h -index d34fb5c5aa753..8edad3f942686 100644 ---- a/include/linux/tcp.h -+++ b/include/linux/tcp.h -@@ -117,6 +117,8 @@ enum { - #define TCP_SAVED_SYN 28 /* Get SYN headers recorded for connection */ - #define TCP_REPAIR_WINDOW 29 /* Get/set window parameters */ - #define TCP_FASTOPEN_CONNECT 30 /* Attempt FastOpen with connect */ -+#define TCP_ULP 31 /* Attach a ULP to a TCP connection */ -+#define TCP_MD5SIG_EXT 32 /* TCP MD5 Signature with extensions */ - - struct tcp_repair_opt { - __u32 opt_code; -@@ -229,17 +231,38 @@ enum { - TCP_NLA_SNDBUF_LIMITED, /* Time (usec) limited by send buffer */ - TCP_NLA_DATA_SEGS_OUT, /* Data pkts sent including retransmission */ - TCP_NLA_TOTAL_RETRANS, /* Data pkts retransmitted */ -+ TCP_NLA_PACING_RATE, /* Pacing rate in bytes per second */ -+ TCP_NLA_DELIVERY_RATE, /* Delivery rate in bytes per second */ -+ TCP_NLA_SND_CWND, /* Sending congestion window */ -+ TCP_NLA_REORDERING, /* Reordering metric */ -+ TCP_NLA_MIN_RTT, /* minimum RTT */ -+ TCP_NLA_RECUR_RETRANS, /* Recurring retransmits for the current pkt */ -+ TCP_NLA_DELIVERY_RATE_APP_LMT, /* delivery rate application limited ? */ -+ - }; - - /* for TCP_MD5SIG socket option */ - #define TCP_MD5SIG_MAXKEYLEN 80 - -+/* tcp_md5sig extension flags for TCP_MD5SIG_EXT */ -+#define TCP_MD5SIG_FLAG_PREFIX 1 /* address prefix length */ -+ - struct tcp_md5sig { - struct __kernel_sockaddr_storage tcpm_addr; /* address associated */ -- __u16 __tcpm_pad1; /* zero */ -+ __u8 tcpm_flags; /* extension flags */ -+ __u8 tcpm_prefixlen; /* address prefix */ - __u16 tcpm_keylen; /* key length */ -- __u32 __tcpm_pad2; /* zero */ -+ __u32 __tcpm_pad; /* zero */ - __u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN]; /* key (binary) */ - }; - -+/* INET_DIAG_MD5SIG */ -+struct tcp_diag_md5sig { -+ __u8 tcpm_family; -+ __u8 tcpm_prefixlen; -+ __u16 tcpm_keylen; -+ __be32 tcpm_addr[4]; -+ __u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN]; -+}; -+ - #endif /* _LINUX_TCP_H */ -diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h -index d2dd1fd65e77a..5790293b7fc46 100644 ---- a/include/linux/xfrm.h -+++ b/include/linux/xfrm.h -@@ -303,6 +303,8 @@ enum xfrm_attr_type_t { - XFRMA_PROTO, /* __u8 */ - XFRMA_ADDRESS_FILTER, /* struct xfrm_address_filter */ - XFRMA_PAD, -+ XFRMA_OFFLOAD_DEV, /* struct xfrm_state_offload */ -+ XFRMA_OUTPUT_MARK, /* __u32 */ - __XFRMA_MAX - - #define XFRMA_MAX (__XFRMA_MAX - 1) -@@ -494,6 +496,13 @@ struct xfrm_address_filter { - __u8 dplen; - }; - -+struct xfrm_user_offload { -+ int ifindex; -+ __u8 flags; -+}; -+#define XFRM_OFFLOAD_IPV6 1 -+#define XFRM_OFFLOAD_INBOUND 2 -+ - /* backwards compatibility for userspace */ - #define XFRMGRP_ACQUIRE 1 - #define XFRMGRP_EXPIRE 2 --- -2.21.0 - diff --git a/SOURCES/0025-devlink-Change-netlink-attribute-validation.patch b/SOURCES/0025-devlink-Change-netlink-attribute-validation.patch deleted file mode 100644 index 154a8ba..0000000 --- a/SOURCES/0025-devlink-Change-netlink-attribute-validation.patch +++ /dev/null @@ -1,151 +0,0 @@ -From 56a3a027d053ab592a3363a92108c93c150301f5 Mon Sep 17 00:00:00 2001 -From: Kamal Heib -Date: Thu, 9 Nov 2017 04:44:32 -0500 -Subject: [PATCH] devlink: Change netlink attribute validation - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1456539 - -commit 4f10cede93b758785f5b201774ed3e02eaf1a7bb -Author: Arkadi Sharshevsky -Date: Wed May 3 13:25:22 2017 +0200 - - devlink: Change netlink attribute validation - - Currently the netlink attribute resolving is done by a sequence of - if's. Change the attribute resolving to table lookup. - - Signed-off-by: Arkadi Sharshevsky - Signed-off-by: Jiri Pirko - Reviewed-by: Greg Rose - -Signed-off-by: Kamal Heib ---- - devlink/devlink.c | 103 ++++++++++++++-------------------------------- - 1 file changed, 30 insertions(+), 73 deletions(-) - -diff --git a/devlink/devlink.c b/devlink/devlink.c -index e90226e48369b..35220d802a618 100644 ---- a/devlink/devlink.c -+++ b/devlink/devlink.c -@@ -232,88 +232,45 @@ static bool dl_no_arg(struct dl *dl) - return dl_argc(dl) == 0; - } - -+static const enum mnl_attr_data_type devlink_policy[DEVLINK_ATTR_MAX + 1] = { -+ [DEVLINK_ATTR_BUS_NAME] = MNL_TYPE_NUL_STRING, -+ [DEVLINK_ATTR_DEV_NAME] = MNL_TYPE_NUL_STRING, -+ [DEVLINK_ATTR_PORT_INDEX] = MNL_TYPE_U32, -+ [DEVLINK_ATTR_PORT_TYPE] = MNL_TYPE_U16, -+ [DEVLINK_ATTR_PORT_DESIRED_TYPE] = MNL_TYPE_U16, -+ [DEVLINK_ATTR_PORT_NETDEV_IFINDEX] = MNL_TYPE_U32, -+ [DEVLINK_ATTR_PORT_NETDEV_NAME] = MNL_TYPE_NUL_STRING, -+ [DEVLINK_ATTR_PORT_IBDEV_NAME] = MNL_TYPE_NUL_STRING, -+ [DEVLINK_ATTR_SB_INDEX] = MNL_TYPE_U32, -+ [DEVLINK_ATTR_SB_SIZE] = MNL_TYPE_U32, -+ [DEVLINK_ATTR_SB_INGRESS_POOL_COUNT] = MNL_TYPE_U16, -+ [DEVLINK_ATTR_SB_EGRESS_POOL_COUNT] = MNL_TYPE_U16, -+ [DEVLINK_ATTR_SB_INGRESS_TC_COUNT] = MNL_TYPE_U16, -+ [DEVLINK_ATTR_SB_EGRESS_TC_COUNT] = MNL_TYPE_U16, -+ [DEVLINK_ATTR_SB_POOL_INDEX] = MNL_TYPE_U16, -+ [DEVLINK_ATTR_SB_POOL_TYPE] = MNL_TYPE_U8, -+ [DEVLINK_ATTR_SB_POOL_SIZE] = MNL_TYPE_U32, -+ [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = MNL_TYPE_U8, -+ [DEVLINK_ATTR_SB_THRESHOLD] = MNL_TYPE_U32, -+ [DEVLINK_ATTR_SB_TC_INDEX] = MNL_TYPE_U16, -+ [DEVLINK_ATTR_SB_OCC_CUR] = MNL_TYPE_U32, -+ [DEVLINK_ATTR_SB_OCC_MAX] = MNL_TYPE_U32, -+ [DEVLINK_ATTR_ESWITCH_MODE] = MNL_TYPE_U16, -+ [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = MNL_TYPE_U8, -+}; -+ - static int attr_cb(const struct nlattr *attr, void *data) - { - const struct nlattr **tb = data; - int type; - -- type = mnl_attr_get_type(attr); -- - if (mnl_attr_type_valid(attr, DEVLINK_ATTR_MAX) < 0) - return MNL_CB_ERROR; - -- if (type == DEVLINK_ATTR_BUS_NAME && -- mnl_attr_validate(attr, MNL_TYPE_NUL_STRING) < 0) -- return MNL_CB_ERROR; -- if (type == DEVLINK_ATTR_DEV_NAME && -- mnl_attr_validate(attr, MNL_TYPE_NUL_STRING) < 0) -- return MNL_CB_ERROR; -- if (type == DEVLINK_ATTR_PORT_INDEX && -- mnl_attr_validate(attr, MNL_TYPE_U32) < 0) -- return MNL_CB_ERROR; -- if (type == DEVLINK_ATTR_PORT_TYPE && -- mnl_attr_validate(attr, MNL_TYPE_U16) < 0) -- return MNL_CB_ERROR; -- if (type == DEVLINK_ATTR_PORT_DESIRED_TYPE && -- mnl_attr_validate(attr, MNL_TYPE_U16) < 0) -- return MNL_CB_ERROR; -- if (type == DEVLINK_ATTR_PORT_NETDEV_IFINDEX && -- mnl_attr_validate(attr, MNL_TYPE_U32) < 0) -- return MNL_CB_ERROR; -- if (type == DEVLINK_ATTR_PORT_NETDEV_NAME && -- mnl_attr_validate(attr, MNL_TYPE_NUL_STRING) < 0) -- return MNL_CB_ERROR; -- if (type == DEVLINK_ATTR_PORT_IBDEV_NAME && -- mnl_attr_validate(attr, MNL_TYPE_NUL_STRING) < 0) -- return MNL_CB_ERROR; -- if (type == DEVLINK_ATTR_SB_INDEX && -- mnl_attr_validate(attr, MNL_TYPE_U32) < 0) -- return MNL_CB_ERROR; -- if (type == DEVLINK_ATTR_SB_SIZE && -- mnl_attr_validate(attr, MNL_TYPE_U32) < 0) -- return MNL_CB_ERROR; -- if (type == DEVLINK_ATTR_SB_INGRESS_POOL_COUNT && -- mnl_attr_validate(attr, MNL_TYPE_U16) < 0) -- return MNL_CB_ERROR; -- if (type == DEVLINK_ATTR_SB_EGRESS_POOL_COUNT && -- mnl_attr_validate(attr, MNL_TYPE_U16) < 0) -- return MNL_CB_ERROR; -- if (type == DEVLINK_ATTR_SB_INGRESS_TC_COUNT && -- mnl_attr_validate(attr, MNL_TYPE_U16) < 0) -- return MNL_CB_ERROR; -- if (type == DEVLINK_ATTR_SB_EGRESS_TC_COUNT && -- mnl_attr_validate(attr, MNL_TYPE_U16) < 0) -- return MNL_CB_ERROR; -- if (type == DEVLINK_ATTR_SB_POOL_INDEX && -- mnl_attr_validate(attr, MNL_TYPE_U16) < 0) -- return MNL_CB_ERROR; -- if (type == DEVLINK_ATTR_SB_POOL_TYPE && -- mnl_attr_validate(attr, MNL_TYPE_U8) < 0) -- return MNL_CB_ERROR; -- if (type == DEVLINK_ATTR_SB_POOL_SIZE && -- mnl_attr_validate(attr, MNL_TYPE_U32) < 0) -- return MNL_CB_ERROR; -- if (type == DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE && -- mnl_attr_validate(attr, MNL_TYPE_U8) < 0) -- return MNL_CB_ERROR; -- if (type == DEVLINK_ATTR_SB_THRESHOLD && -- mnl_attr_validate(attr, MNL_TYPE_U32) < 0) -- return MNL_CB_ERROR; -- if (type == DEVLINK_ATTR_SB_TC_INDEX && -- mnl_attr_validate(attr, MNL_TYPE_U16) < 0) -- return MNL_CB_ERROR; -- if (type == DEVLINK_ATTR_SB_OCC_CUR && -- mnl_attr_validate(attr, MNL_TYPE_U32) < 0) -- return MNL_CB_ERROR; -- if (type == DEVLINK_ATTR_SB_OCC_MAX && -- mnl_attr_validate(attr, MNL_TYPE_U32) < 0) -- return MNL_CB_ERROR; -- if (type == DEVLINK_ATTR_ESWITCH_MODE && -- mnl_attr_validate(attr, MNL_TYPE_U16) < 0) -- return MNL_CB_ERROR; -- if (type == DEVLINK_ATTR_ESWITCH_INLINE_MODE && -- mnl_attr_validate(attr, MNL_TYPE_U8) < 0) -+ type = mnl_attr_get_type(attr); -+ if (mnl_attr_validate(attr, devlink_policy[type]) < 0) - return MNL_CB_ERROR; -+ - tb[type] = attr; - return MNL_CB_OK; - } --- -2.21.0 - diff --git a/SOURCES/0026-devlink-Add-support-for-pipeline-debug-dpipe.patch b/SOURCES/0026-devlink-Add-support-for-pipeline-debug-dpipe.patch deleted file mode 100644 index a22f666..0000000 --- a/SOURCES/0026-devlink-Add-support-for-pipeline-debug-dpipe.patch +++ /dev/null @@ -1,1597 +0,0 @@ -From 120f9c488ba7d291f899f1ec2f77e0ae33efcd88 Mon Sep 17 00:00:00 2001 -From: Kamal Heib -Date: Thu, 9 Nov 2017 04:44:32 -0500 -Subject: [PATCH] devlink: Add support for pipeline debug (dpipe) - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1456539 - -commit 153c1a9b21e5b7b78e066de2b93a4edb8c3dc498 -Author: Arkadi Sharshevsky -Date: Wed May 3 13:25:23 2017 +0200 - - devlink: Add support for pipeline debug (dpipe) - - Add support for pipeline debug (dpipe). The headers are used both the - gain visibillity into the headers supported by the hardware, and to - build the headers/field database which is used by other commands. - - Examples: - - First we can see the headers supported by the hardware: - - $devlink dpipe header show pci/0000:03:00.0 - - pci/0000:03:00.0: - name mlxsw_meta - field: - name erif_port bitwidth 32 mapping_type ifindex - name l3_forward bitwidth 1 - name l3_drop bitwidth 1 - - Note that mapping_type is presented only if relevant. Also the header/ - field id's are reported by the kernel they are not shown by default. - They can be observed by using the -v option. Also the headers scope - (global/local) is specified. - - $devlink -v dpipe header show pci/0000:03:00.0 - - pci/0000:03:00.0: - name mlxsw_meta id 0 global false - field: - name erif_port id 0 bitwidth 32 mapping_type ifindex - name l3_forward id 1 bitwidth 1 - name l3_drop id 2 bitwidth 1 - - Second we can examine the tables supported by the hardware. In order - to dump all the tables no table name should be provided: - $devlink dpipe table show pci/0000:03:00.0 - - In order to examine specific table its name have to be specified: - $devlink dpipe table show pci/0000:03:00.0 name erif - - pci/0000:03:00.0: - name mlxsw_erif size 800 counters_enabled true - match: - type field_exact header mlxsw_meta field erif_port mapping ifindex - action: - type field_modify header mlxsw_meta field l3_forward - type field_modify header mlxsw_meta field l3_drop - - To enable/disable counters on the table: - $devlink dpipe table set pci/0000:03:00.0 name erif counters enable - $devlink dpipe table set pci/0000:03:00.0 name erif counters disable - - In order to see the current entries in the hardware for specific table: - $devlink dpipe table dump pci/0000:03:00.0 name erif - - pci/0000:03:00.0: - index 0 counter 0 - match_value: - type field_exact header mlxsw_meta field erif_port mapping ifindex mapping_value 383 value 0 - action_value: - type field_modify header mlxsw_meta field l3_forward value 1 - - index 1 counter 0 - match_value: - type field_exact header mlxsw_meta field erif_port mapping ifindex mapping_value 381 value 1 - action_value: - type field_modify header mlxsw_meta field l3_forward value 1 - - In the above example the table contains two entries which does match - on erif port and forwards the packet or drop it (currently only the - forward count is implemented). The counter values are provided for - example. In case the counting is not enabled on the table the counters - will not be available. - - Signed-off-by: Arkadi Sharshevsky - Signed-off-by: Jiri Pirko - -Signed-off-by: Kamal Heib ---- - devlink/devlink.c | 1353 +++++++++++++++++++++++++++++++++++++++++---- - 1 file changed, 1254 insertions(+), 99 deletions(-) - -diff --git a/devlink/devlink.c b/devlink/devlink.c -index 35220d802a618..e22ee0a0e8d83 100644 ---- a/devlink/devlink.c -+++ b/devlink/devlink.c -@@ -34,7 +34,15 @@ - #define ESWITCH_INLINE_MODE_TRANSPORT "transport" - - #define pr_err(args...) fprintf(stderr, ##args) --#define pr_out(args...) fprintf(stdout, ##args) -+#define pr_out(args...) \ -+ do { \ -+ if (g_indent_newline) { \ -+ fprintf(stdout, "%s", g_indent_str); \ -+ g_indent_newline = false; \ -+ } \ -+ fprintf(stdout, ##args); \ -+ } while (0) -+ - #define pr_out_sp(num, args...) \ - do { \ - int ret = fprintf(stdout, ##args); \ -@@ -42,6 +50,35 @@ - fprintf(stdout, "%*s", num - ret, ""); \ - } while (0) - -+static int g_indent_level; -+static bool g_indent_newline; -+#define INDENT_STR_STEP 2 -+#define INDENT_STR_MAXLEN 32 -+static char g_indent_str[INDENT_STR_MAXLEN + 1] = ""; -+ -+static void __pr_out_indent_inc(void) -+{ -+ if (g_indent_level + INDENT_STR_STEP > INDENT_STR_MAXLEN) -+ return; -+ g_indent_level += INDENT_STR_STEP; -+ memset(g_indent_str, ' ', sizeof(g_indent_str)); -+ g_indent_str[g_indent_level] = '\0'; -+} -+ -+static void __pr_out_indent_dec(void) -+{ -+ if (g_indent_level - INDENT_STR_STEP < 0) -+ return; -+ g_indent_level -= INDENT_STR_STEP; -+ g_indent_str[g_indent_level] = '\0'; -+} -+ -+static void __pr_out_newline(void) -+{ -+ pr_out("\n"); -+ g_indent_newline = true; -+} -+ - static int _mnlg_socket_recv_run(struct mnlg_socket *nlg, - mnl_cb_t data_cb, void *data) - { -@@ -137,6 +174,8 @@ static void ifname_map_free(struct ifname_map *ifname_map) - #define DL_OPT_SB_TC BIT(10) - #define DL_OPT_ESWITCH_MODE BIT(11) - #define DL_OPT_ESWITCH_INLINE_MODE BIT(12) -+#define DL_OPT_DPIPE_TABLE_NAME BIT(13) -+#define DL_OPT_DPIPE_TABLE_COUNTERS BIT(14) - - struct dl_opts { - uint32_t present; /* flags of present items */ -@@ -154,6 +193,8 @@ struct dl_opts { - uint16_t sb_tc_index; - enum devlink_eswitch_mode eswitch_mode; - enum devlink_eswitch_inline_mode eswitch_inline_mode; -+ const char *dpipe_table_name; -+ bool dpipe_counters_enable; - }; - - struct dl { -@@ -166,6 +207,7 @@ struct dl { - json_writer_t *jw; - bool json_output; - bool pretty_output; -+ bool verbose; - struct { - bool present; - char *bus_name; -@@ -257,6 +299,38 @@ static const enum mnl_attr_data_type devlink_policy[DEVLINK_ATTR_MAX + 1] = { - [DEVLINK_ATTR_SB_OCC_MAX] = MNL_TYPE_U32, - [DEVLINK_ATTR_ESWITCH_MODE] = MNL_TYPE_U16, - [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = MNL_TYPE_U8, -+ [DEVLINK_ATTR_DPIPE_TABLES] = MNL_TYPE_NESTED, -+ [DEVLINK_ATTR_DPIPE_TABLE] = MNL_TYPE_NESTED, -+ [DEVLINK_ATTR_DPIPE_TABLE_NAME] = MNL_TYPE_STRING, -+ [DEVLINK_ATTR_DPIPE_TABLE_SIZE] = MNL_TYPE_U64, -+ [DEVLINK_ATTR_DPIPE_TABLE_MATCHES] = MNL_TYPE_NESTED, -+ [DEVLINK_ATTR_DPIPE_TABLE_ACTIONS] = MNL_TYPE_NESTED, -+ [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = MNL_TYPE_U8, -+ [DEVLINK_ATTR_DPIPE_ENTRIES] = MNL_TYPE_NESTED, -+ [DEVLINK_ATTR_DPIPE_ENTRY] = MNL_TYPE_NESTED, -+ [DEVLINK_ATTR_DPIPE_ENTRY_INDEX] = MNL_TYPE_U64, -+ [DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES] = MNL_TYPE_NESTED, -+ [DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES] = MNL_TYPE_NESTED, -+ [DEVLINK_ATTR_DPIPE_ENTRY_COUNTER] = MNL_TYPE_U64, -+ [DEVLINK_ATTR_DPIPE_MATCH] = MNL_TYPE_NESTED, -+ [DEVLINK_ATTR_DPIPE_MATCH_VALUE] = MNL_TYPE_NESTED, -+ [DEVLINK_ATTR_DPIPE_MATCH_TYPE] = MNL_TYPE_U32, -+ [DEVLINK_ATTR_DPIPE_ACTION] = MNL_TYPE_NESTED, -+ [DEVLINK_ATTR_DPIPE_ACTION_VALUE] = MNL_TYPE_NESTED, -+ [DEVLINK_ATTR_DPIPE_ACTION_TYPE] = MNL_TYPE_U32, -+ [DEVLINK_ATTR_DPIPE_VALUE_MAPPING] = MNL_TYPE_U32, -+ [DEVLINK_ATTR_DPIPE_HEADERS] = MNL_TYPE_NESTED, -+ [DEVLINK_ATTR_DPIPE_HEADER] = MNL_TYPE_NESTED, -+ [DEVLINK_ATTR_DPIPE_HEADER_NAME] = MNL_TYPE_STRING, -+ [DEVLINK_ATTR_DPIPE_HEADER_ID] = MNL_TYPE_U32, -+ [DEVLINK_ATTR_DPIPE_HEADER_FIELDS] = MNL_TYPE_NESTED, -+ [DEVLINK_ATTR_DPIPE_HEADER_GLOBAL] = MNL_TYPE_U8, -+ [DEVLINK_ATTR_DPIPE_HEADER_INDEX] = MNL_TYPE_U32, -+ [DEVLINK_ATTR_DPIPE_FIELD] = MNL_TYPE_NESTED, -+ [DEVLINK_ATTR_DPIPE_FIELD_NAME] = MNL_TYPE_STRING, -+ [DEVLINK_ATTR_DPIPE_FIELD_ID] = MNL_TYPE_U32, -+ [DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH] = MNL_TYPE_U32, -+ [DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE] = MNL_TYPE_U32, - }; - - static int attr_cb(const struct nlattr *attr, void *data) -@@ -666,6 +740,20 @@ static int eswitch_inline_mode_get(const char *typestr, - return 0; - } - -+static int dpipe_counters_enable_get(const char *typestr, -+ bool *counters_enable) -+{ -+ if (strcmp(typestr, "enable") == 0) { -+ *counters_enable = 1; -+ } else if (strcmp(typestr, "disable") == 0) { -+ *counters_enable = 0; -+ } else { -+ pr_err("Unknown counter_state \"%s\"\n", typestr); -+ return -EINVAL; -+ } -+ return 0; -+} -+ - static int dl_argv_parse(struct dl *dl, uint32_t o_required, - uint32_t o_optional) - { -@@ -800,6 +888,27 @@ static int dl_argv_parse(struct dl *dl, uint32_t o_required, - if (err) - return err; - o_found |= DL_OPT_ESWITCH_INLINE_MODE; -+ } else if (dl_argv_match(dl, "name") && -+ (o_all & DL_OPT_DPIPE_TABLE_NAME)) { -+ dl_arg_inc(dl); -+ err = dl_argv_str(dl, &opts->dpipe_table_name); -+ if (err) -+ return err; -+ o_found |= DL_OPT_DPIPE_TABLE_NAME; -+ } else if (dl_argv_match(dl, "counters") && -+ (o_all & DL_OPT_DPIPE_TABLE_COUNTERS)) { -+ const char *typestr; -+ -+ dl_arg_inc(dl); -+ err = dl_argv_str(dl, &typestr); -+ if (err) -+ return err; -+ err = dpipe_counters_enable_get(typestr, -+ &opts->dpipe_counters_enable); -+ if (err) -+ return err; -+ o_found |= DL_OPT_DPIPE_TABLE_COUNTERS; -+ - } else { - pr_err("Unknown option \"%s\"\n", dl_argv(dl)); - return -EINVAL; -@@ -866,6 +975,17 @@ static int dl_argv_parse(struct dl *dl, uint32_t o_required, - return -EINVAL; - } - -+ if ((o_required & DL_OPT_DPIPE_TABLE_NAME) && -+ !(o_found & DL_OPT_DPIPE_TABLE_NAME)) { -+ pr_err("Dpipe table name expected\n"); -+ return -EINVAL; -+ } -+ -+ if ((o_required & DL_OPT_DPIPE_TABLE_COUNTERS) && -+ !(o_found & DL_OPT_DPIPE_TABLE_COUNTERS)) { -+ pr_err("Dpipe table counter state expected\n"); -+ return -EINVAL; -+ } - return 0; - } - -@@ -915,6 +1035,12 @@ static void dl_opts_put(struct nlmsghdr *nlh, struct dl *dl) - if (opts->present & DL_OPT_ESWITCH_INLINE_MODE) - mnl_attr_put_u8(nlh, DEVLINK_ATTR_ESWITCH_INLINE_MODE, - opts->eswitch_inline_mode); -+ if (opts->present & DL_OPT_DPIPE_TABLE_NAME) -+ mnl_attr_put_strz(nlh, DEVLINK_ATTR_DPIPE_TABLE_NAME, -+ opts->dpipe_table_name); -+ if (opts->present & DL_OPT_DPIPE_TABLE_COUNTERS) -+ mnl_attr_put_u8(nlh, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED, -+ opts->dpipe_counters_enable); - } - - static int dl_argv_parse_put(struct nlmsghdr *nlh, struct dl *dl, -@@ -1033,7 +1159,19 @@ static void __pr_out_handle_start(struct dl *dl, struct nlattr **tb, - jsonw_start_object(dl->jw); - } - } else { -- pr_out("%s%s", buf, content ? ":" : ""); -+ if (array) { -+ if (should_arr_last_handle_end(dl, bus_name, dev_name)) -+ __pr_out_indent_dec(); -+ if (should_arr_last_handle_start(dl, bus_name, -+ dev_name)) { -+ pr_out("%s%s", buf, content ? ":" : ""); -+ __pr_out_newline(); -+ __pr_out_indent_inc(); -+ arr_last_handle_set(dl, bus_name, dev_name); -+ } -+ } else { -+ pr_out("%s%s", buf, content ? ":" : ""); -+ } - } - } - -@@ -1047,7 +1185,7 @@ static void pr_out_handle_end(struct dl *dl) - if (dl->json_output) - jsonw_end_object(dl->jw); - else -- pr_out("\n"); -+ __pr_out_newline(); - } - - static void pr_out_handle(struct dl *dl, struct nlattr **tb) -@@ -1163,18 +1301,26 @@ static void pr_out_port_handle_end(struct dl *dl) - - static void pr_out_str(struct dl *dl, const char *name, const char *val) - { -- if (dl->json_output) -+ if (dl->json_output) { - jsonw_string_field(dl->jw, name, val); -- else -- pr_out(" %s %s", name, val); -+ } else { -+ if (g_indent_newline) -+ pr_out("%s %s", name, val); -+ else -+ pr_out(" %s %s", name, val); -+ } - } - - static void pr_out_uint(struct dl *dl, const char *name, unsigned int val) - { -- if (dl->json_output) -+ if (dl->json_output) { - jsonw_uint_field(dl->jw, name, val); -- else -- pr_out(" %s %u", name, val); -+ } else { -+ if (g_indent_newline) -+ pr_out("%s %u", name, val); -+ else -+ pr_out(" %s %u", name, val); -+ } - } - - static void pr_out_dev(struct dl *dl, struct nlattr **tb) -@@ -1201,6 +1347,42 @@ static void pr_out_section_end(struct dl *dl) - } - } - -+static void pr_out_array_start(struct dl *dl, const char *name) -+{ -+ if (dl->json_output) { -+ jsonw_name(dl->jw, name); -+ jsonw_start_array(dl->jw); -+ } else { -+ if (!g_indent_newline) -+ __pr_out_newline(); -+ pr_out("%s:", name); -+ __pr_out_newline(); -+ __pr_out_indent_inc(); -+ } -+} -+ -+static void pr_out_array_end(struct dl *dl) -+{ -+ if (dl->json_output) -+ jsonw_end_array(dl->jw); -+ else -+ __pr_out_indent_dec(); -+} -+ -+static void pr_out_entry_start(struct dl *dl) -+{ -+ if (dl->json_output) -+ jsonw_start_object(dl->jw); -+} -+ -+static void pr_out_entry_end(struct dl *dl) -+{ -+ if (dl->json_output) -+ jsonw_end_object(dl->jw); -+ else -+ __pr_out_newline(); -+} -+ - static const char *eswitch_mode_name(uint32_t mode) - { - switch (mode) { -@@ -2423,129 +2605,1102 @@ static int cmd_mon(struct dl *dl) - return -ENOENT; - } - --static void help(void) -+struct dpipe_field { -+ char *name; -+ unsigned int id; -+ unsigned int bitwidth; -+ enum devlink_dpipe_field_mapping_type mapping_type; -+}; -+ -+struct dpipe_header { -+ struct list_head list; -+ char *name; -+ unsigned int id; -+ struct dpipe_field *fields; -+ unsigned int fields_count; -+}; -+ -+struct dpipe_ctx { -+ struct dl *dl; -+ int err; -+ struct list_head global_headers; -+ struct list_head local_headers; -+ bool print_headers; -+}; -+ -+static struct dpipe_header *dpipe_header_alloc(unsigned int fields_count) - { -- pr_err("Usage: devlink [ OPTIONS ] OBJECT { COMMAND | help }\n" -- "where OBJECT := { dev | port | sb | monitor }\n" -- " OPTIONS := { -V[ersion] | -n[no-nice-names] | -j[json] | -p[pretty] }\n"); -+ struct dpipe_header *header; -+ -+ header = calloc(1, sizeof(struct dpipe_header)); -+ if (!header) -+ return NULL; -+ header->fields = calloc(fields_count, sizeof(struct dpipe_field)); -+ if (!header->fields) -+ goto err_fields_alloc; -+ header->fields_count = fields_count; -+ return header; -+ -+err_fields_alloc: -+ free(header); -+ return NULL; - } - --static int dl_cmd(struct dl *dl) -+static void dpipe_header_free(struct dpipe_header *header) - { -- if (dl_argv_match(dl, "help") || dl_no_arg(dl)) { -- help(); -- return 0; -- } else if (dl_argv_match(dl, "dev")) { -- dl_arg_inc(dl); -- return cmd_dev(dl); -- } else if (dl_argv_match(dl, "port")) { -- dl_arg_inc(dl); -- return cmd_port(dl); -- } else if (dl_argv_match(dl, "sb")) { -- dl_arg_inc(dl); -- return cmd_sb(dl); -- } else if (dl_argv_match(dl, "monitor")) { -- dl_arg_inc(dl); -- return cmd_mon(dl); -+ free(header->fields); -+ free(header); -+} -+ -+static void dpipe_header_clear(struct dpipe_header *header) -+{ -+ struct dpipe_field *field; -+ int i; -+ -+ for (i = 0; i < header->fields_count; i++) { -+ field = &header->fields[i]; -+ free(field->name); - } -- pr_err("Object \"%s\" not found\n", dl_argv(dl)); -- return -ENOENT; -+ free(header->name); - } - --static int dl_init(struct dl *dl, int argc, char **argv) -+static void dpipe_header_add(struct dpipe_ctx *ctx, -+ struct dpipe_header *header, bool global) - { -- int err; -+ if (global) -+ list_add(&header->list, &ctx->global_headers); -+ else -+ list_add(&header->list, &ctx->local_headers); -+} - -- dl->argc = argc; -- dl->argv = argv; -+static void dpipe_header_del(struct dpipe_header *header) -+{ -+ list_del(&header->list); -+} - -- dl->nlg = mnlg_socket_open(DEVLINK_GENL_NAME, DEVLINK_GENL_VERSION); -- if (!dl->nlg) { -- pr_err("Failed to connect to devlink Netlink\n"); -- return -errno; -+static struct dpipe_ctx *dpipe_ctx_alloc(struct dl *dl) -+{ -+ struct dpipe_ctx *ctx; -+ -+ ctx = calloc(1, sizeof(struct dpipe_ctx)); -+ if (!ctx) -+ return NULL; -+ ctx->dl = dl; -+ INIT_LIST_HEAD(&ctx->global_headers); -+ INIT_LIST_HEAD(&ctx->local_headers); -+ return ctx; -+} -+ -+static void dpipe_ctx_free(struct dpipe_ctx *ctx) -+{ -+ free(ctx); -+} -+ -+static void dpipe_ctx_clear(struct dpipe_ctx *ctx) -+{ -+ struct dpipe_header *header, *tmp; -+ -+ list_for_each_entry_safe(header, tmp, &ctx->global_headers, -+ list) { -+ dpipe_header_del(header); -+ dpipe_header_clear(header); -+ dpipe_header_free(header); -+ } -+ list_for_each_entry_safe(header, tmp, &ctx->local_headers, -+ list) { -+ dpipe_header_del(header); -+ dpipe_header_clear(header); -+ dpipe_header_free(header); - } -+} - -- err = ifname_map_init(dl); -- if (err) { -- pr_err("Failed to create index map\n"); -- goto err_ifname_map_create; -+static const char *dpipe_header_id2s(struct dpipe_ctx *ctx, -+ uint32_t header_id, bool global) -+{ -+ struct list_head *header_list; -+ struct dpipe_header *header; -+ -+ if (global) -+ header_list = &ctx->global_headers; -+ else -+ header_list = &ctx->local_headers; -+ list_for_each_entry(header, header_list, list) { -+ if (header->id != header_id) -+ continue; -+ return header->name; - } -- if (dl->json_output) { -- dl->jw = jsonw_new(stdout); -- if (!dl->jw) { -- pr_err("Failed to create JSON writer\n"); -- goto err_json_new; -- } -- jsonw_pretty(dl->jw, dl->pretty_output); -+ return NULL; -+} -+ -+static const char *dpipe_field_id2s(struct dpipe_ctx *ctx, -+ uint32_t header_id, -+ uint32_t field_id, bool global) -+{ -+ struct list_head *header_list; -+ struct dpipe_header *header; -+ -+ if (global) -+ header_list = &ctx->global_headers; -+ else -+ header_list = &ctx->local_headers; -+ list_for_each_entry(header, header_list, list) { -+ if (header->id != header_id) -+ continue; -+ return header->fields[field_id].name; - } -- return 0; -+ return NULL; -+} - --err_json_new: -- ifname_map_fini(dl); --err_ifname_map_create: -- mnlg_socket_close(dl->nlg); -- return err; -+static const char * -+dpipe_field_mapping_e2s(enum devlink_dpipe_field_mapping_type mapping_type) -+{ -+ switch (mapping_type) { -+ case DEVLINK_DPIPE_FIELD_MAPPING_TYPE_NONE: -+ return NULL; -+ case DEVLINK_DPIPE_FIELD_MAPPING_TYPE_IFINDEX: -+ return "ifindex"; -+ default: -+ return ""; -+ } - } - --static void dl_fini(struct dl *dl) -+static const char * -+dpipe_mapping_get(struct dpipe_ctx *ctx, uint32_t header_id, -+ uint32_t field_id, bool global) - { -- if (dl->json_output) -- jsonw_destroy(&dl->jw); -- ifname_map_fini(dl); -- mnlg_socket_close(dl->nlg); -+ enum devlink_dpipe_field_mapping_type mapping_type; -+ struct list_head *header_list; -+ struct dpipe_header *header; -+ -+ if (global) -+ header_list = &ctx->global_headers; -+ else -+ header_list = &ctx->local_headers; -+ list_for_each_entry(header, header_list, list) { -+ if (header->id != header_id) -+ continue; -+ mapping_type = header->fields[field_id].mapping_type; -+ return dpipe_field_mapping_e2s(mapping_type); -+ } -+ return NULL; - } - --static struct dl *dl_alloc(void) -+static void pr_out_dpipe_fields(struct dpipe_ctx *ctx, -+ struct dpipe_field *fields, -+ unsigned int field_count) - { -- struct dl *dl; -+ struct dpipe_field *field; -+ int i; - -- dl = calloc(1, sizeof(*dl)); -- if (!dl) -- return NULL; -- return dl; -+ for (i = 0; i < field_count; i++) { -+ field = &fields[i]; -+ pr_out_entry_start(ctx->dl); -+ pr_out_str(ctx->dl, "name", field->name); -+ if (ctx->dl->verbose) -+ pr_out_uint(ctx->dl, "id", field->id); -+ pr_out_uint(ctx->dl, "bitwidth", field->bitwidth); -+ if (field->mapping_type) -+ pr_out_str(ctx->dl, "mapping_type", -+ dpipe_field_mapping_e2s(field->mapping_type)); -+ pr_out_entry_end(ctx->dl); -+ } - } - --static void dl_free(struct dl *dl) -+static void -+pr_out_dpipe_header(struct dpipe_ctx *ctx, struct nlattr **tb, -+ struct dpipe_header *header, bool global) - { -- free(dl); -+ pr_out_handle_start_arr(ctx->dl, tb); -+ pr_out_str(ctx->dl, "name", header->name); -+ if (ctx->dl->verbose) { -+ pr_out_uint(ctx->dl, "id", header->id); -+ pr_out_str(ctx->dl, "global", -+ global ? "true" : "false"); -+ } -+ pr_out_array_start(ctx->dl, "field"); -+ pr_out_dpipe_fields(ctx, header->fields, -+ header->fields_count); -+ pr_out_array_end(ctx->dl); -+ pr_out_handle_end(ctx->dl); - } - --int main(int argc, char **argv) -+static void pr_out_dpipe_headers(struct dpipe_ctx *ctx, -+ struct nlattr **tb) - { -- static const struct option long_options[] = { -- { "Version", no_argument, NULL, 'V' }, -- { "no-nice-names", no_argument, NULL, 'n' }, -- { "json", no_argument, NULL, 'j' }, -- { "pretty", no_argument, NULL, 'p' }, -- { NULL, 0, NULL, 0 } -- }; -- struct dl *dl; -- int opt; -+ struct dpipe_header *header; -+ -+ list_for_each_entry(header, &ctx->local_headers, list) -+ pr_out_dpipe_header(ctx, tb, header, false); -+ -+ list_for_each_entry(header, &ctx->global_headers, list) -+ pr_out_dpipe_header(ctx, tb, header, true); -+} -+ -+static int dpipe_header_field_get(struct nlattr *nl, struct dpipe_field *field) -+{ -+ struct nlattr *nla_field[DEVLINK_ATTR_MAX + 1] = {}; -+ const char *name; - int err; -- int ret; - -- dl = dl_alloc(); -- if (!dl) { -- pr_err("Failed to allocate memory for devlink\n"); -- return EXIT_FAILURE; -+ err = mnl_attr_parse_nested(nl, attr_cb, nla_field); -+ if (err != MNL_CB_OK) -+ return -EINVAL; -+ if (!nla_field[DEVLINK_ATTR_DPIPE_FIELD_ID] || -+ !nla_field[DEVLINK_ATTR_DPIPE_FIELD_NAME] || -+ !nla_field[DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH] || -+ !nla_field[DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE]) -+ return -EINVAL; -+ -+ name = mnl_attr_get_str(nla_field[DEVLINK_ATTR_DPIPE_FIELD_NAME]); -+ field->id = mnl_attr_get_u32(nla_field[DEVLINK_ATTR_DPIPE_FIELD_ID]); -+ field->bitwidth = mnl_attr_get_u32(nla_field[DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH]); -+ field->name = strdup(name); -+ if (!field->name) -+ return -ENOMEM; -+ field->mapping_type = mnl_attr_get_u32(nla_field[DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE]); -+ return 0; -+} -+ -+static int dpipe_header_fields_get(struct nlattr *nla_fields, -+ struct dpipe_field *fields) -+{ -+ struct nlattr *nla_field; -+ int count = 0; -+ int err; -+ -+ mnl_attr_for_each_nested(nla_field, nla_fields) { -+ err = dpipe_header_field_get(nla_field, &fields[count]); -+ if (err) -+ return err; -+ count++; - } -+ return 0; -+} - -- while ((opt = getopt_long(argc, argv, "Vnjp", -- long_options, NULL)) >= 0) { -+static unsigned int dpipe_header_field_count_get(struct nlattr *nla_fields) -+{ -+ struct nlattr *nla_field; -+ unsigned int count = 0; - -- switch (opt) { -- case 'V': -- printf("devlink utility, iproute2-ss%s\n", SNAPSHOT); -- ret = EXIT_SUCCESS; -- goto dl_free; -- case 'n': -- dl->no_nice_names = true; -- break; -- case 'j': -- dl->json_output = true; -- break; -- case 'p': -- dl->pretty_output = true; -+ mnl_attr_for_each_nested(nla_field, nla_fields) -+ count++; -+ return count; -+} -+ -+static int dpipe_header_get(struct dpipe_ctx *ctx, struct nlattr *nl) -+{ -+ struct nlattr *nla_header[DEVLINK_ATTR_MAX + 1] = {}; -+ struct dpipe_header *header; -+ unsigned int fields_count; -+ const char *header_name; -+ bool global; -+ int err; -+ -+ err = mnl_attr_parse_nested(nl, attr_cb, nla_header); -+ if (err != MNL_CB_OK) -+ return -EINVAL; -+ -+ if (!nla_header[DEVLINK_ATTR_DPIPE_HEADER_NAME] || -+ !nla_header[DEVLINK_ATTR_DPIPE_HEADER_ID] || -+ !nla_header[DEVLINK_ATTR_DPIPE_HEADER_FIELDS]) -+ return -EINVAL; -+ -+ fields_count = dpipe_header_field_count_get(nla_header[DEVLINK_ATTR_DPIPE_HEADER_FIELDS]); -+ header = dpipe_header_alloc(fields_count); -+ if (!header) -+ return -ENOMEM; -+ -+ header_name = mnl_attr_get_str(nla_header[DEVLINK_ATTR_DPIPE_HEADER_NAME]); -+ header->name = strdup(header_name); -+ header->id = mnl_attr_get_u32(nla_header[DEVLINK_ATTR_DPIPE_HEADER_ID]); -+ header->fields_count = fields_count; -+ global = !!mnl_attr_get_u8(nla_header[DEVLINK_ATTR_DPIPE_HEADER_GLOBAL]); -+ -+ err = dpipe_header_fields_get(nla_header[DEVLINK_ATTR_DPIPE_HEADER_FIELDS], -+ header->fields); -+ if (err) -+ goto err_field_get; -+ dpipe_header_add(ctx, header, global); -+ return 0; -+ -+err_field_get: -+ dpipe_header_free(header); -+ return err; -+} -+ -+static int dpipe_headers_get(struct dpipe_ctx *ctx, struct nlattr **tb) -+{ -+ struct nlattr *nla_headers = tb[DEVLINK_ATTR_DPIPE_HEADERS]; -+ struct nlattr *nla_header; -+ int err; -+ -+ mnl_attr_for_each_nested(nla_header, nla_headers) { -+ err = dpipe_header_get(ctx, nla_header); -+ if (err) -+ return err; -+ } -+ return 0; -+} -+ -+static int cmd_dpipe_header_cb(const struct nlmsghdr *nlh, void *data) -+{ -+ struct dpipe_ctx *ctx = data; -+ struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {}; -+ struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); -+ int err; -+ -+ mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb); -+ if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] || -+ !tb[DEVLINK_ATTR_DPIPE_HEADERS]) -+ return MNL_CB_ERROR; -+ err = dpipe_headers_get(ctx, tb); -+ if (err) { -+ ctx->err = err; -+ return MNL_CB_ERROR; -+ } -+ -+ if (ctx->print_headers) -+ pr_out_dpipe_headers(ctx, tb); -+ return MNL_CB_OK; -+} -+ -+static int cmd_dpipe_headers_show(struct dl *dl) -+{ -+ struct nlmsghdr *nlh; -+ struct dpipe_ctx *ctx; -+ uint16_t flags = NLM_F_REQUEST | NLM_F_ACK; -+ int err; -+ -+ nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_DPIPE_HEADERS_GET, flags); -+ -+ err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLE, 0); -+ if (err) -+ return err; -+ -+ ctx = dpipe_ctx_alloc(dl); -+ if (!ctx) -+ return -ENOMEM; -+ -+ ctx->print_headers = true; -+ -+ pr_out_section_start(dl, "header"); -+ err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_dpipe_header_cb, ctx); -+ if (err) -+ pr_err("error get headers %s\n", strerror(ctx->err)); -+ pr_out_section_end(dl); -+ -+ dpipe_ctx_clear(ctx); -+ dpipe_ctx_free(ctx); -+ return err; -+} -+ -+static void cmd_dpipe_header_help(void) -+{ -+ pr_err("Usage: devlink dpipe headers show DEV\n"); -+} -+ -+static int cmd_dpipe_header(struct dl *dl) -+{ -+ if (dl_argv_match(dl, "help") || dl_no_arg(dl)) { -+ cmd_dpipe_header_help(); -+ return 0; -+ } else if (dl_argv_match(dl, "show")) { -+ dl_arg_inc(dl); -+ return cmd_dpipe_headers_show(dl); -+ } -+ pr_err("Command \"%s\" not found\n", dl_argv(dl)); -+ return -ENOENT; -+} -+ -+static const char -+*dpipe_action_type_e2s(enum devlink_dpipe_action_type action_type) -+{ -+ switch (action_type) { -+ case DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY: -+ return "field_modify"; -+ default: -+ return ""; -+ } -+} -+ -+static void pr_out_dpipe_action(struct dpipe_ctx *ctx, -+ uint32_t header_id, uint32_t field_id, -+ uint32_t action_type, bool global) -+{ -+ const char *mapping; -+ -+ pr_out_str(ctx->dl, "type", dpipe_action_type_e2s(action_type)); -+ pr_out_str(ctx->dl, "header", dpipe_header_id2s(ctx, header_id, -+ global)); -+ pr_out_str(ctx->dl, "field", dpipe_field_id2s(ctx, header_id, field_id, -+ global)); -+ mapping = dpipe_mapping_get(ctx, header_id, field_id, global); -+ if (mapping) -+ pr_out_str(ctx->dl, "mapping", mapping); -+} -+ -+static int dpipe_action_show(struct dpipe_ctx *ctx, struct nlattr *nl) -+{ -+ struct nlattr *nla_action[DEVLINK_ATTR_MAX + 1] = {}; -+ uint32_t header_id, field_id, action_type; -+ bool global; -+ int err; -+ -+ err = mnl_attr_parse_nested(nl, attr_cb, nla_action); -+ if (err != MNL_CB_OK) -+ return -EINVAL; -+ -+ if (!nla_action[DEVLINK_ATTR_DPIPE_ACTION_TYPE] || -+ !nla_action[DEVLINK_ATTR_DPIPE_HEADER_INDEX] || -+ !nla_action[DEVLINK_ATTR_DPIPE_HEADER_ID] || -+ !nla_action[DEVLINK_ATTR_DPIPE_FIELD_ID]) { -+ return -EINVAL; -+ } -+ -+ header_id = mnl_attr_get_u32(nla_action[DEVLINK_ATTR_DPIPE_HEADER_ID]); -+ field_id = mnl_attr_get_u32(nla_action[DEVLINK_ATTR_DPIPE_FIELD_ID]); -+ action_type = mnl_attr_get_u32(nla_action[DEVLINK_ATTR_DPIPE_ACTION_TYPE]); -+ global = !!mnl_attr_get_u8(nla_action[DEVLINK_ATTR_DPIPE_HEADER_GLOBAL]); -+ -+ pr_out_dpipe_action(ctx, header_id, field_id, action_type, global); -+ return 0; -+} -+ -+static int dpipe_table_actions_show(struct dpipe_ctx *ctx, -+ struct nlattr *nla_actions) -+{ -+ struct nlattr *nla_action; -+ -+ mnl_attr_for_each_nested(nla_action, nla_actions) { -+ pr_out_entry_start(ctx->dl); -+ if (dpipe_action_show(ctx, nla_action)) -+ goto err_action_show; -+ pr_out_entry_end(ctx->dl); -+ } -+ return 0; -+ -+err_action_show: -+ pr_out_entry_end(ctx->dl); -+ return -EINVAL; -+} -+ -+static const char * -+dpipe_match_type_e2s(enum devlink_dpipe_match_type match_type) -+{ -+ switch (match_type) { -+ case DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT: -+ return "field_exact"; -+ default: -+ return ""; -+ } -+} -+ -+static void pr_out_dpipe_match(struct dpipe_ctx *ctx, -+ uint32_t header_id, uint32_t field_id, -+ uint32_t match_type, bool global) -+{ -+ const char *mapping; -+ -+ pr_out_str(ctx->dl, "type", dpipe_match_type_e2s(match_type)); -+ pr_out_str(ctx->dl, "header", dpipe_header_id2s(ctx, header_id, -+ global)); -+ pr_out_str(ctx->dl, "field", dpipe_field_id2s(ctx, header_id, field_id, -+ global)); -+ mapping = dpipe_mapping_get(ctx, header_id, field_id, global); -+ if (mapping) -+ pr_out_str(ctx->dl, "mapping", mapping); -+ -+} -+ -+static int dpipe_match_show(struct dpipe_ctx *ctx, struct nlattr *nl) -+{ -+ struct nlattr *nla_match[DEVLINK_ATTR_MAX + 1] = {}; -+ uint32_t header_id, field_id, match_type; -+ bool global; -+ int err; -+ -+ err = mnl_attr_parse_nested(nl, attr_cb, nla_match); -+ if (err != MNL_CB_OK) -+ return -EINVAL; -+ -+ if (!nla_match[DEVLINK_ATTR_DPIPE_MATCH_TYPE] || -+ !nla_match[DEVLINK_ATTR_DPIPE_HEADER_INDEX] || -+ !nla_match[DEVLINK_ATTR_DPIPE_HEADER_ID] || -+ !nla_match[DEVLINK_ATTR_DPIPE_FIELD_ID]) { -+ return -EINVAL; -+ } -+ -+ match_type = mnl_attr_get_u32(nla_match[DEVLINK_ATTR_DPIPE_MATCH_TYPE]); -+ header_id = mnl_attr_get_u32(nla_match[DEVLINK_ATTR_DPIPE_HEADER_ID]); -+ field_id = mnl_attr_get_u32(nla_match[DEVLINK_ATTR_DPIPE_FIELD_ID]); -+ global = !!mnl_attr_get_u8(nla_match[DEVLINK_ATTR_DPIPE_HEADER_GLOBAL]); -+ -+ pr_out_dpipe_match(ctx, header_id, field_id, match_type, global); -+ return 0; -+} -+ -+static int dpipe_table_matches_show(struct dpipe_ctx *ctx, -+ struct nlattr *nla_matches) -+{ -+ struct nlattr *nla_match; -+ -+ mnl_attr_for_each_nested(nla_match, nla_matches) { -+ pr_out_entry_start(ctx->dl); -+ if (dpipe_match_show(ctx, nla_match)) -+ goto err_match_show; -+ pr_out_entry_end(ctx->dl); -+ } -+ return 0; -+ -+err_match_show: -+ pr_out_entry_end(ctx->dl); -+ return -EINVAL; -+} -+ -+static int dpipe_table_show(struct dpipe_ctx *ctx, struct nlattr *nl) -+{ -+ struct nlattr *nla_table[DEVLINK_ATTR_MAX + 1] = {}; -+ bool counters_enabled; -+ const char *name; -+ uint32_t size; -+ int err; -+ -+ err = mnl_attr_parse_nested(nl, attr_cb, nla_table); -+ if (err != MNL_CB_OK) -+ return -EINVAL; -+ -+ if (!nla_table[DEVLINK_ATTR_DPIPE_TABLE_NAME] || -+ !nla_table[DEVLINK_ATTR_DPIPE_TABLE_SIZE] || -+ !nla_table[DEVLINK_ATTR_DPIPE_TABLE_ACTIONS] || -+ !nla_table[DEVLINK_ATTR_DPIPE_TABLE_MATCHES] || -+ !nla_table[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]) { -+ return -EINVAL; -+ } -+ -+ name = mnl_attr_get_str(nla_table[DEVLINK_ATTR_DPIPE_TABLE_NAME]); -+ size = mnl_attr_get_u32(nla_table[DEVLINK_ATTR_DPIPE_TABLE_SIZE]); -+ counters_enabled = !!mnl_attr_get_u8(nla_table[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]); -+ -+ pr_out_str(ctx->dl, "name", name); -+ pr_out_uint(ctx->dl, "size", size); -+ pr_out_str(ctx->dl, "counters_enabled", -+ counters_enabled ? "true" : "false"); -+ -+ pr_out_array_start(ctx->dl, "match"); -+ if (dpipe_table_matches_show(ctx, nla_table[DEVLINK_ATTR_DPIPE_TABLE_MATCHES])) -+ goto err_matches_show; -+ pr_out_array_end(ctx->dl); -+ -+ pr_out_array_start(ctx->dl, "action"); -+ if (dpipe_table_actions_show(ctx, nla_table[DEVLINK_ATTR_DPIPE_TABLE_ACTIONS])) -+ goto err_actions_show; -+ pr_out_array_end(ctx->dl); -+ -+ return 0; -+ -+err_actions_show: -+err_matches_show: -+ pr_out_array_end(ctx->dl); -+ return -EINVAL; -+} -+ -+static int dpipe_tables_show(struct dpipe_ctx *ctx, struct nlattr **tb) -+{ -+ struct nlattr *nla_tables = tb[DEVLINK_ATTR_DPIPE_TABLES]; -+ struct nlattr *nla_table; -+ -+ mnl_attr_for_each_nested(nla_table, nla_tables) { -+ pr_out_handle_start_arr(ctx->dl, tb); -+ if (dpipe_table_show(ctx, nla_table)) -+ goto err_table_show; -+ pr_out_handle_end(ctx->dl); -+ } -+ return 0; -+ -+err_table_show: -+ pr_out_handle_end(ctx->dl); -+ return -EINVAL; -+} -+ -+static int cmd_dpipe_table_show_cb(const struct nlmsghdr *nlh, void *data) -+{ -+ struct dpipe_ctx *ctx = data; -+ struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {}; -+ struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); -+ -+ mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb); -+ if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] || -+ !tb[DEVLINK_ATTR_DPIPE_TABLES]) -+ return MNL_CB_ERROR; -+ -+ if (dpipe_tables_show(ctx, tb)) -+ return MNL_CB_ERROR; -+ return MNL_CB_OK; -+} -+ -+static int cmd_dpipe_table_show(struct dl *dl) -+{ -+ struct nlmsghdr *nlh; -+ struct dpipe_ctx *ctx; -+ uint16_t flags = NLM_F_REQUEST; -+ int err; -+ -+ ctx = dpipe_ctx_alloc(dl); -+ if (!ctx) -+ return -ENOMEM; -+ -+ err = dl_argv_parse(dl, DL_OPT_HANDLE, DL_OPT_DPIPE_TABLE_NAME); -+ if (err) -+ goto out; -+ -+ nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_DPIPE_HEADERS_GET, flags); -+ dl_opts_put(nlh, dl); -+ err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_dpipe_header_cb, ctx); -+ if (err) { -+ pr_err("error get headers %s\n", strerror(ctx->err)); -+ goto out; -+ } -+ -+ flags = NLM_F_REQUEST | NLM_F_ACK; -+ nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_DPIPE_TABLE_GET, flags); -+ dl_opts_put(nlh, dl); -+ -+ pr_out_section_start(dl, "table"); -+ _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_dpipe_table_show_cb, ctx); -+ pr_out_section_end(dl); -+out: -+ dpipe_ctx_clear(ctx); -+ dpipe_ctx_free(ctx); -+ return err; -+} -+ -+static int cmd_dpipe_table_set(struct dl *dl) -+{ -+ struct nlmsghdr *nlh; -+ int err; -+ -+ nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET, -+ NLM_F_REQUEST | NLM_F_ACK); -+ -+ err = dl_argv_parse_put(nlh, dl, -+ DL_OPT_HANDLE | DL_OPT_DPIPE_TABLE_NAME | -+ DL_OPT_DPIPE_TABLE_COUNTERS, 0); -+ if (err) -+ return err; -+ -+ return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL); -+} -+ -+static int dpipe_entry_value_show(struct dpipe_ctx *ctx, -+ struct nlattr **nla_match_value) -+{ -+ uint16_t value_len; -+ bool mask, mapping; -+ -+ mask = !!nla_match_value[DEVLINK_ATTR_DPIPE_VALUE_MASK]; -+ mapping = !!nla_match_value[DEVLINK_ATTR_DPIPE_VALUE_MAPPING]; -+ -+ value_len = mnl_attr_get_payload_len(nla_match_value[DEVLINK_ATTR_DPIPE_VALUE]); -+ if (value_len == sizeof(uint32_t)) { -+ uint32_t value, value_mask, value_mapping; -+ -+ if (mapping) { -+ value_mapping = mnl_attr_get_u32(nla_match_value[DEVLINK_ATTR_DPIPE_VALUE_MAPPING]); -+ pr_out_uint(ctx->dl, "mapping_value", value_mapping); -+ } -+ -+ if (mask) { -+ value_mask = mnl_attr_get_u32(nla_match_value[DEVLINK_ATTR_DPIPE_VALUE_MASK]); -+ pr_out_uint(ctx->dl, "mask_value", value_mask); -+ } -+ -+ value = mnl_attr_get_u32(nla_match_value[DEVLINK_ATTR_DPIPE_VALUE]); -+ pr_out_uint(ctx->dl, "value", value); -+ -+ } else { -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int dpipe_entry_match_value_show(struct dpipe_ctx *ctx, -+ struct nlattr *nl) -+{ -+ struct nlattr *nla_match_value[DEVLINK_ATTR_MAX + 1] = {}; -+ int err; -+ -+ err = mnl_attr_parse_nested(nl, attr_cb, nla_match_value); -+ if (err != MNL_CB_OK) -+ return -EINVAL; -+ -+ if (!nla_match_value[DEVLINK_ATTR_DPIPE_MATCH] || -+ !nla_match_value[DEVLINK_ATTR_DPIPE_VALUE]) { -+ return -EINVAL; -+ } -+ -+ pr_out_entry_start(ctx->dl); -+ if (dpipe_match_show(ctx, nla_match_value[DEVLINK_ATTR_DPIPE_MATCH])) -+ goto err_match_show; -+ if (dpipe_entry_value_show(ctx, nla_match_value)) -+ goto err_value_show; -+ pr_out_entry_end(ctx->dl); -+ -+ return 0; -+ -+err_match_show: -+err_value_show: -+ pr_out_entry_end(ctx->dl); -+ return -EINVAL; -+} -+ -+static int dpipe_entry_action_value_show(struct dpipe_ctx *ctx, -+ struct nlattr *nl) -+{ -+ struct nlattr *nla_action_value[DEVLINK_ATTR_MAX + 1] = {}; -+ int err; -+ -+ err = mnl_attr_parse_nested(nl, attr_cb, nla_action_value); -+ if (err != MNL_CB_OK) -+ return -EINVAL; -+ -+ if (!nla_action_value[DEVLINK_ATTR_DPIPE_ACTION] || -+ !nla_action_value[DEVLINK_ATTR_DPIPE_VALUE]) { -+ return -EINVAL; -+ } -+ -+ pr_out_entry_start(ctx->dl); -+ if (dpipe_action_show(ctx, nla_action_value[DEVLINK_ATTR_DPIPE_ACTION])) -+ goto err_action_show; -+ if (dpipe_entry_value_show(ctx, nla_action_value)) -+ goto err_value_show; -+ pr_out_entry_end(ctx->dl); -+ -+ return 0; -+ -+err_action_show: -+err_value_show: -+ pr_out_entry_end(ctx->dl); -+ return -EINVAL; -+} -+ -+static int -+dpipe_tables_action_values_show(struct dpipe_ctx *ctx, -+ struct nlattr *nla_action_values) -+{ -+ struct nlattr *nla_action_value; -+ -+ mnl_attr_for_each_nested(nla_action_value, nla_action_values) { -+ if (dpipe_entry_action_value_show(ctx, nla_action_value)) -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+static int -+dpipe_tables_match_values_show(struct dpipe_ctx *ctx, -+ struct nlattr *nla_match_values) -+{ -+ struct nlattr *nla_match_value; -+ -+ mnl_attr_for_each_nested(nla_match_value, nla_match_values) { -+ if (dpipe_entry_match_value_show(ctx, nla_match_value)) -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+static int dpipe_entry_show(struct dpipe_ctx *ctx, struct nlattr *nl) -+{ -+ struct nlattr *nla_entry[DEVLINK_ATTR_MAX + 1] = {}; -+ uint32_t entry_index; -+ uint64_t counter; -+ int err; -+ -+ err = mnl_attr_parse_nested(nl, attr_cb, nla_entry); -+ if (err != MNL_CB_OK) -+ return -EINVAL; -+ -+ if (!nla_entry[DEVLINK_ATTR_DPIPE_ENTRY_INDEX] || -+ !nla_entry[DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES] || -+ !nla_entry[DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES]) { -+ return -EINVAL; -+ } -+ -+ entry_index = mnl_attr_get_u32(nla_entry[DEVLINK_ATTR_DPIPE_ENTRY_INDEX]); -+ pr_out_uint(ctx->dl, "index", entry_index); -+ -+ if (nla_entry[DEVLINK_ATTR_DPIPE_ENTRY_COUNTER]) { -+ counter = mnl_attr_get_u64(nla_entry[DEVLINK_ATTR_DPIPE_ENTRY_COUNTER]); -+ pr_out_uint(ctx->dl, "counter", counter); -+ } -+ -+ pr_out_array_start(ctx->dl, "match_value"); -+ if (dpipe_tables_match_values_show(ctx, -+ nla_entry[DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES])) -+ goto err_match_values_show; -+ pr_out_array_end(ctx->dl); -+ -+ pr_out_array_start(ctx->dl, "action_value"); -+ if (dpipe_tables_action_values_show(ctx, -+ nla_entry[DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES])) -+ goto err_action_values_show; -+ pr_out_array_end(ctx->dl); -+ return 0; -+ -+err_action_values_show: -+err_match_values_show: -+ pr_out_array_end(ctx->dl); -+ return -EINVAL; -+} -+ -+static int dpipe_table_entries_show(struct dpipe_ctx *ctx, struct nlattr **tb) -+{ -+ struct nlattr *nla_entries = tb[DEVLINK_ATTR_DPIPE_ENTRIES]; -+ struct nlattr *nla_entry; -+ -+ mnl_attr_for_each_nested(nla_entry, nla_entries) { -+ pr_out_handle_start_arr(ctx->dl, tb); -+ if (dpipe_entry_show(ctx, nla_entry)) -+ goto err_entry_show; -+ pr_out_handle_end(ctx->dl); -+ } -+ return 0; -+ -+err_entry_show: -+ pr_out_handle_end(ctx->dl); -+ return -EINVAL; -+} -+ -+static int cmd_dpipe_table_entry_dump_cb(const struct nlmsghdr *nlh, void *data) -+{ -+ struct dpipe_ctx *ctx = data; -+ struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {}; -+ struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); -+ -+ mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb); -+ if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] || -+ !tb[DEVLINK_ATTR_DPIPE_ENTRIES]) -+ return MNL_CB_ERROR; -+ -+ if (dpipe_table_entries_show(ctx, tb)) -+ return MNL_CB_ERROR; -+ return MNL_CB_OK; -+} -+ -+static int cmd_dpipe_table_dump(struct dl *dl) -+{ -+ struct nlmsghdr *nlh; -+ struct dpipe_ctx *ctx; -+ uint16_t flags = NLM_F_REQUEST; -+ int err; -+ -+ ctx = dpipe_ctx_alloc(dl); -+ if (!ctx) -+ return -ENOMEM; -+ -+ err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_DPIPE_TABLE_NAME, 0); -+ if (err) -+ goto out; -+ -+ nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_DPIPE_HEADERS_GET, flags); -+ dl_opts_put(nlh, dl); -+ err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_dpipe_header_cb, ctx); -+ if (err) { -+ pr_err("error get headers %s\n", strerror(ctx->err)); -+ goto out; -+ } -+ -+ flags = NLM_F_REQUEST | NLM_F_ACK; -+ nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_DPIPE_ENTRIES_GET, flags); -+ dl_opts_put(nlh, dl); -+ -+ pr_out_section_start(dl, "table_entry"); -+ _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_dpipe_table_entry_dump_cb, ctx); -+ pr_out_section_end(dl); -+out: -+ dpipe_ctx_clear(ctx); -+ dpipe_ctx_free(ctx); -+ return err; -+} -+ -+static void cmd_dpipe_table_help(void) -+{ -+ pr_err("Usage: devlink dpipe table [ OBJECT-LIST ]\n" -+ "where OBJECT-LIST := { show | set | dump }\n"); -+} -+ -+static int cmd_dpipe_table(struct dl *dl) -+{ -+ if (dl_argv_match(dl, "help") || dl_no_arg(dl)) { -+ cmd_dpipe_table_help(); -+ return 0; -+ } else if (dl_argv_match(dl, "show")) { -+ dl_arg_inc(dl); -+ return cmd_dpipe_table_show(dl); -+ } else if (dl_argv_match(dl, "set")) { -+ dl_arg_inc(dl); -+ return cmd_dpipe_table_set(dl); -+ } else if (dl_argv_match(dl, "dump")) { -+ dl_arg_inc(dl); -+ return cmd_dpipe_table_dump(dl); -+ } -+ pr_err("Command \"%s\" not found\n", dl_argv(dl)); -+ return -ENOENT; -+} -+ -+static void cmd_dpipe_help(void) -+{ -+ pr_err("Usage: devlink dpipe [ OBJECT-LIST ]\n" -+ "where OBJECT-LIST := { header | table }\n"); -+} -+ -+static int cmd_dpipe(struct dl *dl) -+{ -+ if (dl_argv_match(dl, "help") || dl_no_arg(dl)) { -+ cmd_dpipe_help(); -+ return 0; -+ } else if (dl_argv_match(dl, "header")) { -+ dl_arg_inc(dl); -+ return cmd_dpipe_header(dl); -+ } else if (dl_argv_match(dl, "table")) { -+ dl_arg_inc(dl); -+ return cmd_dpipe_table(dl); -+ } -+ pr_err("Command \"%s\" not found\n", dl_argv(dl)); -+ return -ENOENT; -+} -+ -+static void help(void) -+{ -+ pr_err("Usage: devlink [ OPTIONS ] OBJECT { COMMAND | help }\n" -+ "where OBJECT := { dev | port | sb | monitor | dpipe }\n" -+ " OPTIONS := { -V[ersion] | -n[no-nice-names] | -j[json] | -p[pretty] | -v[verbose] }\n"); -+} -+ -+static int dl_cmd(struct dl *dl) -+{ -+ if (dl_argv_match(dl, "help") || dl_no_arg(dl)) { -+ help(); -+ return 0; -+ } else if (dl_argv_match(dl, "dev")) { -+ dl_arg_inc(dl); -+ return cmd_dev(dl); -+ } else if (dl_argv_match(dl, "port")) { -+ dl_arg_inc(dl); -+ return cmd_port(dl); -+ } else if (dl_argv_match(dl, "sb")) { -+ dl_arg_inc(dl); -+ return cmd_sb(dl); -+ } else if (dl_argv_match(dl, "monitor")) { -+ dl_arg_inc(dl); -+ return cmd_mon(dl); -+ } else if (dl_argv_match(dl, "dpipe")) { -+ dl_arg_inc(dl); -+ return cmd_dpipe(dl); -+ } -+ pr_err("Object \"%s\" not found\n", dl_argv(dl)); -+ return -ENOENT; -+} -+ -+static int dl_init(struct dl *dl, int argc, char **argv) -+{ -+ int err; -+ -+ dl->argc = argc; -+ dl->argv = argv; -+ -+ dl->nlg = mnlg_socket_open(DEVLINK_GENL_NAME, DEVLINK_GENL_VERSION); -+ if (!dl->nlg) { -+ pr_err("Failed to connect to devlink Netlink\n"); -+ return -errno; -+ } -+ -+ err = ifname_map_init(dl); -+ if (err) { -+ pr_err("Failed to create index map\n"); -+ goto err_ifname_map_create; -+ } -+ if (dl->json_output) { -+ dl->jw = jsonw_new(stdout); -+ if (!dl->jw) { -+ pr_err("Failed to create JSON writer\n"); -+ goto err_json_new; -+ } -+ jsonw_pretty(dl->jw, dl->pretty_output); -+ } -+ return 0; -+ -+err_json_new: -+ ifname_map_fini(dl); -+err_ifname_map_create: -+ mnlg_socket_close(dl->nlg); -+ return err; -+} -+ -+static void dl_fini(struct dl *dl) -+{ -+ if (dl->json_output) -+ jsonw_destroy(&dl->jw); -+ ifname_map_fini(dl); -+ mnlg_socket_close(dl->nlg); -+} -+ -+static struct dl *dl_alloc(void) -+{ -+ struct dl *dl; -+ -+ dl = calloc(1, sizeof(*dl)); -+ if (!dl) -+ return NULL; -+ return dl; -+} -+ -+static void dl_free(struct dl *dl) -+{ -+ free(dl); -+} -+ -+int main(int argc, char **argv) -+{ -+ static const struct option long_options[] = { -+ { "Version", no_argument, NULL, 'V' }, -+ { "no-nice-names", no_argument, NULL, 'n' }, -+ { "json", no_argument, NULL, 'j' }, -+ { "pretty", no_argument, NULL, 'p' }, -+ { "verbose", no_argument, NULL, 'v' }, -+ { NULL, 0, NULL, 0 } -+ }; -+ struct dl *dl; -+ int opt; -+ int err; -+ int ret; -+ -+ dl = dl_alloc(); -+ if (!dl) { -+ pr_err("Failed to allocate memory for devlink\n"); -+ return EXIT_FAILURE; -+ } -+ -+ while ((opt = getopt_long(argc, argv, "Vnjpv", -+ long_options, NULL)) >= 0) { -+ -+ switch (opt) { -+ case 'V': -+ printf("devlink utility, iproute2-ss%s\n", SNAPSHOT); -+ ret = EXIT_SUCCESS; -+ goto dl_free; -+ case 'n': -+ dl->no_nice_names = true; -+ break; -+ case 'j': -+ dl->json_output = true; -+ break; -+ case 'p': -+ dl->pretty_output = true; -+ break; -+ case 'v': -+ dl->verbose = true; - break; - default: - pr_err("Unknown option.\n"); --- -2.21.0 - diff --git a/SOURCES/0027-tc-Reflect-HW-offload-status.patch b/SOURCES/0027-tc-Reflect-HW-offload-status.patch deleted file mode 100644 index 4668f67..0000000 --- a/SOURCES/0027-tc-Reflect-HW-offload-status.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 724d67b36f9e6bbbfac88b29fee019c05284a888 Mon Sep 17 00:00:00 2001 -From: Kamal Heib -Date: Thu, 9 Nov 2017 04:44:32 -0500 -Subject: [PATCH] tc: Reflect HW offload status - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1456539 - -commit e57285b81a098ed705d683ce94f9abd1cc53438a -Author: Or Gerlitz -Date: Thu May 4 16:15:15 2017 +0300 - - tc: Reflect HW offload status - - Currently there is no way of querying whether a filter is - offloaded to HW or not when using "both" policy (where none - of skip_sw or skip_hw flags are set by user-space). - - Add two new flags, "in hw" and "not in hw" such that user - space can determine if a filter is actually offloaded to - hw or not. The "in hw" UAPI semantics was chosen so it's - similar to the "skip hw" flag logic. - - If none of these two flags are set, this signals running - over older kernel. - - Signed-off-by: Or Gerlitz - Reviewed-by: Jiri Pirko - Reviewed-by: Simon Horman - -Signed-off-by: Kamal Heib ---- - tc/f_bpf.c | 5 +++++ - tc/f_flower.c | 5 +++++ - tc/f_matchall.c | 5 +++++ - tc/f_u32.c | 5 +++++ - 4 files changed, 20 insertions(+) - -diff --git a/tc/f_bpf.c b/tc/f_bpf.c -index df8a259e18712..75c44c06cc88f 100644 ---- a/tc/f_bpf.c -+++ b/tc/f_bpf.c -@@ -210,6 +210,11 @@ static int bpf_print_opt(struct filter_util *qu, FILE *f, - fprintf(f, "skip_hw "); - if (flags & TCA_CLS_FLAGS_SKIP_SW) - fprintf(f, "skip_sw "); -+ -+ if (flags & TCA_CLS_FLAGS_IN_HW) -+ fprintf(f, "in_hw "); -+ else if (flags & TCA_CLS_FLAGS_NOT_IN_HW) -+ fprintf(f, "not_in_hw "); - } - - if (tb[TCA_BPF_OPS] && tb[TCA_BPF_OPS_LEN]) -diff --git a/tc/f_flower.c b/tc/f_flower.c -index 5aac4a0837f40..ebc63ca6b2a27 100644 ---- a/tc/f_flower.c -+++ b/tc/f_flower.c -@@ -1171,6 +1171,11 @@ static int flower_print_opt(struct filter_util *qu, FILE *f, - fprintf(f, "\n skip_hw"); - if (flags & TCA_CLS_FLAGS_SKIP_SW) - fprintf(f, "\n skip_sw"); -+ -+ if (flags & TCA_CLS_FLAGS_IN_HW) -+ fprintf(f, "\n in_hw"); -+ else if (flags & TCA_CLS_FLAGS_NOT_IN_HW) -+ fprintf(f, "\n not_in_hw"); - } - - if (tb[TCA_FLOWER_ACT]) -diff --git a/tc/f_matchall.c b/tc/f_matchall.c -index ac4863083767d..5a51e7553e82a 100644 ---- a/tc/f_matchall.c -+++ b/tc/f_matchall.c -@@ -137,6 +137,11 @@ static int matchall_print_opt(struct filter_util *qu, FILE *f, - fprintf(f, "\n skip_hw"); - if (flags & TCA_CLS_FLAGS_SKIP_SW) - fprintf(f, "\n skip_sw"); -+ -+ if (flags & TCA_CLS_FLAGS_IN_HW) -+ fprintf(f, "\n in_hw"); -+ else if (flags & TCA_CLS_FLAGS_NOT_IN_HW) -+ fprintf(f, "\n not_in_hw"); - } - - if (tb[TCA_MATCHALL_ACT]) -diff --git a/tc/f_u32.c b/tc/f_u32.c -index 92c1fcd4512c0..ff700e9f4a2d7 100644 ---- a/tc/f_u32.c -+++ b/tc/f_u32.c -@@ -1264,6 +1264,11 @@ static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, - fprintf(f, "skip_hw "); - if (flags & TCA_CLS_FLAGS_SKIP_SW) - fprintf(f, "skip_sw "); -+ -+ if (flags & TCA_CLS_FLAGS_IN_HW) -+ fprintf(f, "in_hw "); -+ else if (flags & TCA_CLS_FLAGS_NOT_IN_HW) -+ fprintf(f, "not_in_hw "); - } - - if (tb[TCA_U32_PCNT]) { --- -2.21.0 - diff --git a/SOURCES/0028-pedit-Fix-a-typo-in-warning.patch b/SOURCES/0028-pedit-Fix-a-typo-in-warning.patch deleted file mode 100644 index bfe6d91..0000000 --- a/SOURCES/0028-pedit-Fix-a-typo-in-warning.patch +++ /dev/null @@ -1,39 +0,0 @@ -From b2e49d92325d876d29e2d4f1a83bd86adfc4bc73 Mon Sep 17 00:00:00 2001 -From: Kamal Heib -Date: Thu, 9 Nov 2017 04:44:32 -0500 -Subject: [PATCH] pedit: Fix a typo in warning - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1456539 - -commit 290cdc058d8bbcae3cfefafe83d8263e02ac5a6f -Author: Amir Vadai -Date: Sun May 14 11:17:43 2017 +0300 - - pedit: Fix a typo in warning - - 'ex' attribute should be placed after 'action pedit' and not after - 'munge'. - - Signed-off-by: Amir Vadai - -Signed-off-by: Kamal Heib ---- - 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 6498dd91b4710..7ef2acc52bce5 100644 ---- a/tc/m_pedit.c -+++ b/tc/m_pedit.c -@@ -146,7 +146,7 @@ int pack_key(struct m_pedit_sel *_sel, struct m_pedit_key *tkey) - if (tkey->htype != TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK || - tkey->cmd != TCA_PEDIT_KEY_EX_CMD_SET) { - fprintf(stderr, -- "Munge parameters not supported. Use 'munge ex'.\n"); -+ "Munge parameters not supported. Use 'pedit ex munge ...'.\n"); - return -1; - } - } --- -2.21.0 - diff --git a/SOURCES/0029-pedit-Do-not-allow-using-retain-for-too-big-fields.patch b/SOURCES/0029-pedit-Do-not-allow-using-retain-for-too-big-fields.patch deleted file mode 100644 index c563617..0000000 --- a/SOURCES/0029-pedit-Do-not-allow-using-retain-for-too-big-fields.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 2bf855b076bbe5aa4665f7efd8bcaf882821cab5 Mon Sep 17 00:00:00 2001 -From: Kamal Heib -Date: Thu, 9 Nov 2017 04:44:32 -0500 -Subject: [PATCH] pedit: Do not allow using retain for too big fields - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1456539 - -commit cdca191862775c47533908301760edd55763e861 -Author: Amir Vadai -Date: Sun May 14 11:17:44 2017 +0300 - - pedit: Do not allow using retain for too big fields - - Using retain for fields longer than 32 bits is not supported. - Do not allow user to do it. - - Signed-off-by: Amir Vadai - -Signed-off-by: Kamal Heib ---- - man/man8/tc-pedit.8 | 3 ++- - tc/m_pedit.c | 6 ++++++ - 2 files changed, 8 insertions(+), 1 deletion(-) - -diff --git a/man/man8/tc-pedit.8 b/man/man8/tc-pedit.8 -index 7f482eafc6c71..9c4d57b972cc8 100644 ---- a/man/man8/tc-pedit.8 -+++ b/man/man8/tc-pedit.8 -@@ -266,7 +266,8 @@ Keep the addressed data as is. - .BI retain " RVAL" - This optional extra part of - .I CMD_SPEC --allows to exclude bits from being changed. -+allows to exclude bits from being changed. Supported only for 32 bits fields -+or smaller. - .TP - .I CONTROL - The following keywords allow to control how the tree of qdisc, classes, -diff --git a/tc/m_pedit.c b/tc/m_pedit.c -index 7ef2acc52bce5..9b74c965932e0 100644 ---- a/tc/m_pedit.c -+++ b/tc/m_pedit.c -@@ -353,6 +353,12 @@ int parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type, __u32 retain, - argv++; - } - -+ if (len > 4 && retain != ~0) { -+ fprintf(stderr, -+ "retain is not supported for fields longer the 32 bits\n"); -+ return -1; -+ } -+ - if (type == TMAC) { - res = pack_mac(sel, tkey, (__u8 *)val); - goto done; --- -2.21.0 - diff --git a/SOURCES/0030-pedit-Check-for-extended-capability-in-protocol-pars.patch b/SOURCES/0030-pedit-Check-for-extended-capability-in-protocol-pars.patch deleted file mode 100644 index 029fafe..0000000 --- a/SOURCES/0030-pedit-Check-for-extended-capability-in-protocol-pars.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 0bc6d74ce3291b669bc05524b404bc6914dab5ba Mon Sep 17 00:00:00 2001 -From: Kamal Heib -Date: Thu, 9 Nov 2017 04:44:32 -0500 -Subject: [PATCH] pedit: Check for extended capability in protocol parser - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1456539 - -commit a13426fe1a2b0fdebacc33820105523934eb355f -Author: Amir Vadai -Date: Sun May 14 11:17:45 2017 +0300 - - pedit: Check for extended capability in protocol parser - - Do not allow using eth and udp header types if non-extended pedit kABI - is being used. Other protocol parsers already have this check. - - Signed-off-by: Amir Vadai - -Signed-off-by: Kamal Heib ---- - tc/p_eth.c | 3 +++ - tc/p_udp.c | 3 +++ - 2 files changed, 6 insertions(+) - -diff --git a/tc/p_eth.c b/tc/p_eth.c -index ad3e28f80eb64..2d2f96ca2f0fb 100644 ---- a/tc/p_eth.c -+++ b/tc/p_eth.c -@@ -34,6 +34,9 @@ parse_eth(int *argc_p, char ***argv_p, - if (argc < 2) - return -1; - -+ if (!sel->extended) -+ return -1; -+ - tkey->htype = TCA_PEDIT_KEY_EX_HDR_TYPE_ETH; - - if (strcmp(*argv, "type") == 0) { -diff --git a/tc/p_udp.c b/tc/p_udp.c -index a56a1b5192542..3916d95860408 100644 ---- a/tc/p_udp.c -+++ b/tc/p_udp.c -@@ -34,6 +34,9 @@ parse_udp(int *argc_p, char ***argv_p, - if (argc < 2) - return -1; - -+ if (!sel->extended) -+ return -1; -+ - tkey->htype = TCA_PEDIT_KEY_EX_HDR_TYPE_UDP; - - if (strcmp(*argv, "sport") == 0) { --- -2.21.0 - diff --git a/SOURCES/0031-pedit-Introduce-ipv6-support.patch b/SOURCES/0031-pedit-Introduce-ipv6-support.patch deleted file mode 100644 index 6a65e73..0000000 --- a/SOURCES/0031-pedit-Introduce-ipv6-support.patch +++ /dev/null @@ -1,304 +0,0 @@ -From 26ab66d7c43c3ef60ab058d4c3da8989a5c1dd46 Mon Sep 17 00:00:00 2001 -From: Kamal Heib -Date: Thu, 9 Nov 2017 04:44:32 -0500 -Subject: [PATCH] pedit: Introduce ipv6 support - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1456539 - -commit f3e1b2448a95baef587965b08f48d49b6e1ec2cb -Author: Amir Vadai -Date: Sun May 14 11:17:46 2017 +0300 - - pedit: Introduce ipv6 support - - Add support for modifying IPv6 headers using pedit. - - Signed-off-by: Amir Vadai - -Signed-off-by: Kamal Heib ---- - man/man8/tc-pedit.8 | 30 +++++++++++++++ - tc/Makefile | 1 + - tc/m_pedit.c | 43 ++++++++++++++++++++- - tc/p_ip.c | 17 +-------- - tc/p_ip6.c | 91 +++++++++++++++++++++++++++++++++++++++++++++ - 5 files changed, 164 insertions(+), 18 deletions(-) - create mode 100644 tc/p_ip6.c - -diff --git a/man/man8/tc-pedit.8 b/man/man8/tc-pedit.8 -index 9c4d57b972cc8..82d4217bc9589 100644 ---- a/man/man8/tc-pedit.8 -+++ b/man/man8/tc-pedit.8 -@@ -33,6 +33,8 @@ pedit - generic packet editor action - | - .BI ip " EX_IPHDR_FIELD" - | -+.BI ip6 " IP6HDR_FIELD" -+| - .BI tcp " TCPHDR_FIELD" - | - .BI udp " UDPHDR_FIELD" -@@ -55,6 +57,12 @@ pedit - generic packet editor action - .IR EX_IPHDR_FIELD " := { " - .BR ttl " }" - -+ -+.ti -8 -+.IR IP6HDR_FIELD " := { " -+.BR src " | " dst " | " flow_lbl " | " payload_len " | " nexthdr " |" -+.BR hoplimit " }" -+ - .ti -8 - .IR TCPHDR_FIELD " := { " - .BR sport " | " dport " | " flags " }" -@@ -211,6 +219,25 @@ are: - .B ttl - .RE - .TP -+.BI ip6 " IP6HDR_FIELD" -+The supported keywords for -+.I IP6HDR_FIELD -+are: -+.RS -+.TP -+.B src -+.TQ -+.B dst -+.TQ -+.B flow_lbl -+.TQ -+.B payload_len -+.TQ -+.B nexthdr -+.TQ -+.B hoplimit -+.RE -+.TP - .BI tcp " TCPHDR_FIELD" - The supported keywords for - .I TCPHDR_FIELD -@@ -329,6 +356,9 @@ tc filter add dev eth0 parent ffff: u32 \\ - tc filter add dev eth0 parent ffff: u32 \\ - match ip sport 22 0xffff \\ - action pedit ex munge ip dst set 192.168.1.199 -+tc filter add dev eth0 parent ffff: u32 \\ -+ match ip sport 22 0xffff \\ -+ action pedit ex munge ip6 dst set fe80::dacb:8aff:fec7:320e - tc filter add dev eth0 parent ffff: u32 \\ - match ip sport 22 0xffff \\ - action pedit ex munge eth dst set 11:22:33:44:55:66 -diff --git a/tc/Makefile b/tc/Makefile -index 446a11391ad70..9a6bb1ddea57e 100644 ---- a/tc/Makefile -+++ b/tc/Makefile -@@ -53,6 +53,7 @@ TCMODULES += m_bpf.o - TCMODULES += m_tunnel_key.o - TCMODULES += m_sample.o - TCMODULES += p_ip.o -+TCMODULES += p_ip6.o - TCMODULES += p_icmp.o - TCMODULES += p_eth.o - TCMODULES += p_tcp.o -diff --git a/tc/m_pedit.c b/tc/m_pedit.c -index 9b74c965932e0..dfa6b2c4835e9 100644 ---- a/tc/m_pedit.c -+++ b/tc/m_pedit.c -@@ -257,6 +257,32 @@ static int pack_mac(struct m_pedit_sel *sel, struct m_pedit_key *tkey, - return ret; - } - -+static int pack_ipv6(struct m_pedit_sel *sel, struct m_pedit_key *tkey, -+ __u32 *ipv6) -+{ -+ int ret = 0; -+ int i; -+ -+ if (tkey->off & 0x3) { -+ fprintf(stderr, -+ "pack_ipv6: IPv6 offsets must begin in 32bit boundaries\n"); -+ return -1; -+ } -+ -+ for (i = 0; i < 4; i++) { -+ tkey->mask = 0; -+ tkey->val = ntohl(ipv6[i]); -+ -+ ret = pack_key32(~0, sel, tkey); -+ if (ret) -+ return ret; -+ -+ tkey->off += 4; -+ } -+ -+ return 0; -+} -+ - int parse_val(int *argc_p, char ***argv_p, __u32 *val, int type) - { - int argc = *argc_p; -@@ -281,8 +307,16 @@ int parse_val(int *argc_p, char ***argv_p, __u32 *val, int type) - return 0; - } - -- if (type == TIPV6) -- return -1; /* not implemented yet */ -+ if (type == TIPV6) { -+ inet_prefix addr; -+ -+ if (get_prefix_1(&addr, *argv, AF_INET6)) -+ return -1; -+ -+ memcpy(val, addr.data, addr.bytelen); -+ -+ return 0; -+ } - - if (type == TMAC) { - #define MAC_ALEN 6 -@@ -364,6 +398,11 @@ int parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type, __u32 retain, - goto done; - } - -+ if (type == TIPV6) { -+ res = pack_ipv6(sel, tkey, val); -+ goto done; -+ } -+ - tkey->val = *v; - tkey->mask = *m; - -diff --git a/tc/p_ip.c b/tc/p_ip.c -index 22fe6505e4271..0272a6eaaf48b 100644 ---- a/tc/p_ip.c -+++ b/tc/p_ip.c -@@ -1,5 +1,5 @@ - /* -- * m_pedit.c packet editor: IPV4/6 header -+ * p_ip.c packet editor: IPV4 header - * - * This program is free software; you can distribute it and/or - * modify it under the terms of the GNU General Public License -@@ -156,23 +156,8 @@ done: - return res; - } - --static int --parse_ip6(int *argc_p, char ***argv_p, -- struct m_pedit_sel *sel, struct m_pedit_key *tkey) --{ -- int res = -1; -- return res; --} -- - struct m_pedit_util p_pedit_ip = { - NULL, - "ip", - parse_ip, - }; -- -- --struct m_pedit_util p_pedit_ip6 = { -- NULL, -- "ip6", -- parse_ip6, --}; -diff --git a/tc/p_ip6.c b/tc/p_ip6.c -new file mode 100644 -index 0000000000000..a4824bda90e81 ---- /dev/null -+++ b/tc/p_ip6.c -@@ -0,0 +1,91 @@ -+/* -+ * p_ip6.c packet editor: IPV6 header -+ * -+ * This program is free software; you can distribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ * -+ * Authors: Amir Vadai -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "utils.h" -+#include "tc_util.h" -+#include "m_pedit.h" -+ -+static int -+parse_ip6(int *argc_p, char ***argv_p, -+ struct m_pedit_sel *sel, struct m_pedit_key *tkey) -+{ -+ int res = -1; -+ int argc = *argc_p; -+ char **argv = *argv_p; -+ -+ if (argc < 2) -+ return -1; -+ -+ if (!sel->extended) -+ return -1; -+ -+ tkey->htype = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6; -+ -+ if (strcmp(*argv, "src") == 0) { -+ NEXT_ARG(); -+ tkey->off = 8; -+ res = parse_cmd(&argc, &argv, 16, TIPV6, RU32, sel, tkey); -+ goto done; -+ } -+ if (strcmp(*argv, "dst") == 0) { -+ NEXT_ARG(); -+ tkey->off = 24; -+ res = parse_cmd(&argc, &argv, 16, TIPV6, RU32, sel, tkey); -+ goto done; -+ } -+ if (strcmp(*argv, "flow_lbl") == 0) { -+ NEXT_ARG(); -+ tkey->off = 0; -+ res = parse_cmd(&argc, &argv, 4, TU32, 0x0007ffff, sel, tkey); -+ goto done; -+ } -+ if (strcmp(*argv, "payload_len") == 0) { -+ NEXT_ARG(); -+ tkey->off = 4; -+ res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey); -+ goto done; -+ } -+ if (strcmp(*argv, "nexthdr") == 0) { -+ NEXT_ARG(); -+ tkey->off = 6; -+ res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey); -+ goto done; -+ } -+ if (strcmp(*argv, "hoplimit") == 0) { -+ NEXT_ARG(); -+ tkey->off = 7; -+ res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey); -+ goto done; -+ } -+ -+ return -1; -+ -+done: -+ *argc_p = argc; -+ *argv_p = argv; -+ return res; -+} -+ -+struct m_pedit_util p_pedit_ip6 = { -+ NULL, -+ "ipv6", -+ parse_ip6, -+}; --- -2.21.0 - diff --git a/SOURCES/0032-devlink-Add-option-to-set-and-show-eswitch-encapsula.patch b/SOURCES/0032-devlink-Add-option-to-set-and-show-eswitch-encapsula.patch deleted file mode 100644 index 97fad96..0000000 --- a/SOURCES/0032-devlink-Add-option-to-set-and-show-eswitch-encapsula.patch +++ /dev/null @@ -1,189 +0,0 @@ -From d9857ffec0266aea1c56ee26369972ade68f501a Mon Sep 17 00:00:00 2001 -From: Kamal Heib -Date: Thu, 9 Nov 2017 04:44:32 -0500 -Subject: [PATCH] devlink: Add option to set and show eswitch encapsulation - support - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1456539 - -commit d315b706e9d4a550096140aa298d46b2aa7733e9 -Author: Roi Dayan -Date: Sun May 21 08:37:27 2017 +0300 - - devlink: Add option to set and show eswitch encapsulation support - - This is an e-switch global knob to enable HW support for applying - encapsulation/decapsulation to VF traffic as part of SRIOV e-switch offloading. - - The actual encap/decap is carried out (along with the matching and other - actions) per offloaded e-switch rules, e.g as done when offloading the TC tunnel - key action. - - Possible values are enable/disable. - - Signed-off-by: Roi Dayan - Reviewed-by: Jiri Pirko - -Signed-off-by: Kamal Heib ---- - devlink/devlink.c | 48 +++++++++++++++++++++++++++++++++++++++++- - man/man8/devlink-dev.8 | 13 ++++++++++++ - 2 files changed, 60 insertions(+), 1 deletion(-) - -diff --git a/devlink/devlink.c b/devlink/devlink.c -index e22ee0a0e8d83..f9bc16c350c40 100644 ---- a/devlink/devlink.c -+++ b/devlink/devlink.c -@@ -176,6 +176,7 @@ static void ifname_map_free(struct ifname_map *ifname_map) - #define DL_OPT_ESWITCH_INLINE_MODE BIT(12) - #define DL_OPT_DPIPE_TABLE_NAME BIT(13) - #define DL_OPT_DPIPE_TABLE_COUNTERS BIT(14) -+#define DL_OPT_ESWITCH_ENCAP_MODE BIT(15) - - struct dl_opts { - uint32_t present; /* flags of present items */ -@@ -195,6 +196,7 @@ struct dl_opts { - enum devlink_eswitch_inline_mode eswitch_inline_mode; - const char *dpipe_table_name; - bool dpipe_counters_enable; -+ bool eswitch_encap_mode; - }; - - struct dl { -@@ -299,6 +301,7 @@ static const enum mnl_attr_data_type devlink_policy[DEVLINK_ATTR_MAX + 1] = { - [DEVLINK_ATTR_SB_OCC_MAX] = MNL_TYPE_U32, - [DEVLINK_ATTR_ESWITCH_MODE] = MNL_TYPE_U16, - [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = MNL_TYPE_U8, -+ [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = MNL_TYPE_U8, - [DEVLINK_ATTR_DPIPE_TABLES] = MNL_TYPE_NESTED, - [DEVLINK_ATTR_DPIPE_TABLE] = MNL_TYPE_NESTED, - [DEVLINK_ATTR_DPIPE_TABLE_NAME] = MNL_TYPE_STRING, -@@ -754,6 +757,19 @@ static int dpipe_counters_enable_get(const char *typestr, - return 0; - } - -+static int eswitch_encap_mode_get(const char *typestr, bool *p_mode) -+{ -+ if (strcmp(typestr, "enable") == 0) { -+ *p_mode = true; -+ } else if (strcmp(typestr, "disable") == 0) { -+ *p_mode = false; -+ } else { -+ pr_err("Unknown eswitch encap mode \"%s\"\n", typestr); -+ return -EINVAL; -+ } -+ return 0; -+} -+ - static int dl_argv_parse(struct dl *dl, uint32_t o_required, - uint32_t o_optional) - { -@@ -908,7 +924,19 @@ static int dl_argv_parse(struct dl *dl, uint32_t o_required, - if (err) - return err; - o_found |= DL_OPT_DPIPE_TABLE_COUNTERS; -+ } else if (dl_argv_match(dl, "encap") && -+ (o_all & DL_OPT_ESWITCH_ENCAP_MODE)) { -+ const char *typestr; - -+ dl_arg_inc(dl); -+ err = dl_argv_str(dl, &typestr); -+ if (err) -+ return err; -+ err = eswitch_encap_mode_get(typestr, -+ &opts->eswitch_encap_mode); -+ if (err) -+ return err; -+ o_found |= DL_OPT_ESWITCH_ENCAP_MODE; - } else { - pr_err("Unknown option \"%s\"\n", dl_argv(dl)); - return -EINVAL; -@@ -986,6 +1014,13 @@ static int dl_argv_parse(struct dl *dl, uint32_t o_required, - pr_err("Dpipe table counter state expected\n"); - return -EINVAL; - } -+ -+ if ((o_required & DL_OPT_ESWITCH_ENCAP_MODE) && -+ !(o_found & DL_OPT_ESWITCH_ENCAP_MODE)) { -+ pr_err("E-Switch encapsulation option expected.\n"); -+ return -EINVAL; -+ } -+ - return 0; - } - -@@ -1041,6 +1076,9 @@ static void dl_opts_put(struct nlmsghdr *nlh, struct dl *dl) - if (opts->present & DL_OPT_DPIPE_TABLE_COUNTERS) - mnl_attr_put_u8(nlh, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED, - opts->dpipe_counters_enable); -+ if (opts->present & DL_OPT_ESWITCH_ENCAP_MODE) -+ mnl_attr_put_u8(nlh, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, -+ opts->eswitch_encap_mode); - } - - static int dl_argv_parse_put(struct nlmsghdr *nlh, struct dl *dl, -@@ -1097,6 +1135,7 @@ static void cmd_dev_help(void) - pr_err("Usage: devlink dev show [ DEV ]\n"); - pr_err(" devlink dev eswitch set DEV [ mode { legacy | switchdev } ]\n"); - pr_err(" [ inline-mode { none | link | network | transport } ]\n"); -+ pr_err(" [ encap { disable | enable } ]\n"); - pr_err(" devlink dev eswitch show DEV\n"); - } - -@@ -1421,6 +1460,12 @@ static void pr_out_eswitch(struct dl *dl, struct nlattr **tb) - eswitch_inline_mode_name(mnl_attr_get_u8( - tb[DEVLINK_ATTR_ESWITCH_INLINE_MODE]))); - -+ if (tb[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) { -+ bool encap_mode = !!mnl_attr_get_u8(tb[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]); -+ -+ pr_out_str(dl, "encap", encap_mode ? "enable" : "disable"); -+ } -+ - pr_out_handle_end(dl); - } - -@@ -1465,7 +1510,8 @@ static int cmd_dev_eswitch_set(struct dl *dl) - - err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLE, - DL_OPT_ESWITCH_MODE | -- DL_OPT_ESWITCH_INLINE_MODE); -+ DL_OPT_ESWITCH_INLINE_MODE | -+ DL_OPT_ESWITCH_ENCAP_MODE); - - if (err) - return err; -diff --git a/man/man8/devlink-dev.8 b/man/man8/devlink-dev.8 -index 6bfe66f87955a..b074d57a19369 100644 ---- a/man/man8/devlink-dev.8 -+++ b/man/man8/devlink-dev.8 -@@ -34,6 +34,9 @@ devlink-dev \- devlink device configuration - .RI "[ " - .BR inline-mode " { " none " | " link " | " network " | " transport " } " - .RI "]" -+.RI "[ " -+.BR encap " { " disable " | " enable " } " -+.RI "]" - - .ti -8 - .BR "devlink dev eswitch show" -@@ -81,6 +84,16 @@ Some HWs need the VF driver to put part of the packet headers on the TX descript - .I transport - - L4 mode - -+.TP -+.BR encap " { " disable " | " enable " } " -+Set eswitch encapsulation support -+ -+.I disable -+- Disable encapsulation support -+ -+.I enable -+- Enable encapsulation support -+ - .SH "EXAMPLES" - .PP - devlink dev show --- -2.21.0 - diff --git a/SOURCES/0033-tc-flower-add-support-for-tcp-flags.patch b/SOURCES/0033-tc-flower-add-support-for-tcp-flags.patch deleted file mode 100644 index 0fe432c..0000000 --- a/SOURCES/0033-tc-flower-add-support-for-tcp-flags.patch +++ /dev/null @@ -1,154 +0,0 @@ -From 7cbf364a5f68ba008c5e0702266fe3dc606b1d6f Mon Sep 17 00:00:00 2001 -From: Kamal Heib -Date: Thu, 9 Nov 2017 04:44:32 -0500 -Subject: [PATCH] tc: flower: add support for tcp flags - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1456539 - -commit 0c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26a -Author: Jiri Pirko -Date: Tue May 23 23:51:39 2017 +0200 - - tc: flower: add support for tcp flags - - Allow user to insert a flower classifier filter rule which includes - match for tcp flags. - - Signed-off-by: Jiri Pirko - -Signed-off-by: Kamal Heib ---- - man/man8/tc-flower.8 | 8 ++++++ - tc/f_flower.c | 62 ++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 70 insertions(+) - -diff --git a/man/man8/tc-flower.8 b/man/man8/tc-flower.8 -index ba290657c2245..76480798d72f9 100644 ---- a/man/man8/tc-flower.8 -+++ b/man/man8/tc-flower.8 -@@ -35,6 +35,8 @@ flower \- flow based traffic control filter - .IR PREFIX " | { " - .BR dst_port " | " src_port " } " - .IR port_number " } | " -+.B tcp_flags -+.IR MASKED_TCP_FLAGS " | " - .B type - .IR MASKED_TYPE " | " - .B code -@@ -136,6 +138,12 @@ Match on layer 4 protocol source or destination port number. Only available for - .BR ip_proto " values " udp ", " tcp " and " sctp - which have to be specified in beforehand. - .TP -+.BI tcp_flags " MASKED_TCP_FLAGS" -+Match on TCP flags represented as 12bit bitfield in in hexadecimal format. -+A mask may be optionally provided to limit the bits which are matched. A mask -+is provided by following the value with a slash and then the mask. If the mask -+is missing then a match on all bits is assumed. -+.TP - .BI type " MASKED_TYPE" - .TQ - .BI code " MASKED_CODE" -diff --git a/tc/f_flower.c b/tc/f_flower.c -index ebc63ca6b2a27..1b6b46ea0177b 100644 ---- a/tc/f_flower.c -+++ b/tc/f_flower.c -@@ -57,6 +57,7 @@ static void explain(void) - " src_ip PREFIX |\n" - " dst_port PORT-NUMBER |\n" - " src_port PORT-NUMBER |\n" -+ " tcp_flags MASKED-TCP_FLAGS |\n" - " type MASKED-ICMP-TYPE |\n" - " code MASKED-ICMP-CODE |\n" - " arp_tip IPV4-PREFIX |\n" -@@ -474,6 +475,41 @@ static int flower_parse_port(char *str, __u8 ip_proto, - return 0; - } - -+#define TCP_FLAGS_MAX_MASK 0xfff -+ -+static int flower_parse_tcp_flags(char *str, int flags_type, int mask_type, -+ struct nlmsghdr *n) -+{ -+ char *slash; -+ int ret, err = -1; -+ __u16 flags; -+ -+ slash = strchr(str, '/'); -+ if (slash) -+ *slash = '\0'; -+ -+ ret = get_u16(&flags, str, 16); -+ if (ret < 0 || flags & ~TCP_FLAGS_MAX_MASK) -+ goto err; -+ -+ addattr16(n, MAX_MSG, flags_type, htons(flags)); -+ -+ if (slash) { -+ ret = get_u16(&flags, slash + 1, 16); -+ if (ret < 0 || flags & ~TCP_FLAGS_MAX_MASK) -+ goto err; -+ } else { -+ flags = TCP_FLAGS_MAX_MASK; -+ } -+ addattr16(n, MAX_MSG, mask_type, htons(flags)); -+ -+ err = 0; -+err: -+ if (slash) -+ *slash = '/'; -+ return err; -+} -+ - static int flower_parse_key_id(const char *str, int type, struct nlmsghdr *n) - { - int ret; -@@ -671,6 +707,16 @@ static int flower_parse_opt(struct filter_util *qu, char *handle, - fprintf(stderr, "Illegal \"src_port\"\n"); - return -1; - } -+ } else if (matches(*argv, "tcp_flags") == 0) { -+ NEXT_ARG(); -+ ret = flower_parse_tcp_flags(*argv, -+ TCA_FLOWER_KEY_TCP_FLAGS, -+ TCA_FLOWER_KEY_TCP_FLAGS_MASK, -+ n); -+ if (ret < 0) { -+ fprintf(stderr, "Illegal \"tcp_flags\"\n"); -+ return -1; -+ } - } else if (matches(*argv, "type") == 0) { - NEXT_ARG(); - ret = flower_parse_icmp(*argv, eth_type, ip_proto, -@@ -1000,6 +1046,19 @@ static void flower_print_port(FILE *f, char *name, struct rtattr *attr) - fprintf(f, "\n %s %d", name, rta_getattr_be16(attr)); - } - -+static void flower_print_tcp_flags(FILE *f, char *name, -+ struct rtattr *flags_attr, -+ struct rtattr *mask_attr) -+{ -+ if (!flags_attr) -+ return; -+ fprintf(f, "\n %s %x", name, rta_getattr_be16(flags_attr)); -+ if (!mask_attr) -+ return; -+ fprintf(f, "/%x", rta_getattr_be16(mask_attr)); -+} -+ -+ - static void flower_print_key_id(FILE *f, const char *name, - struct rtattr *attr) - { -@@ -1110,6 +1169,9 @@ static int flower_print_opt(struct filter_util *qu, FILE *f, - if (nl_type >= 0) - flower_print_port(f, "src_port", tb[nl_type]); - -+ flower_print_tcp_flags(f, "tcp_flags", tb[TCA_FLOWER_KEY_TCP_FLAGS], -+ tb[TCA_FLOWER_KEY_TCP_FLAGS_MASK]); -+ - nl_type = flower_icmp_attr_type(eth_type, ip_proto, - FLOWER_ICMP_FIELD_TYPE); - nl_mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto, --- -2.21.0 - diff --git a/SOURCES/0034-iplink-Update-usage-in-help-message.patch b/SOURCES/0034-iplink-Update-usage-in-help-message.patch deleted file mode 100644 index 7c1e19d..0000000 --- a/SOURCES/0034-iplink-Update-usage-in-help-message.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 41b38afb79a82eec66fea08fc021a35cf1d550fc Mon Sep 17 00:00:00 2001 -From: Kamal Heib -Date: Thu, 9 Nov 2017 04:44:32 -0500 -Subject: [PATCH] iplink: Update usage in help message - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1456539 - -commit 5a3ec4ba64783a640e7716a37faae4be49489e51 -Author: Eli Cohen -Date: Sun Jun 4 15:36:48 2017 +0300 - - iplink: Update usage in help message - - Add to usage message a description of how to configure Infiniband node - and port GUIDs. Also modify the man page to emphasize the GUIDs are - configured for Infiniband VFs. - - Fixes: d91fb3f4c7e4 ("Add support for configuring Infiniband GUIDs") - Signed-off-by: Eli Cohen - Signed-off-by: Tariq Toukan - -Signed-off-by: Kamal Heib ---- - ip/iplink.c | 2 ++ - man/man8/ip-link.8.in | 4 ++-- - 2 files changed, 4 insertions(+), 2 deletions(-) - -diff --git a/ip/iplink.c b/ip/iplink.c -index b08d227d44bee..193997cad2a35 100644 ---- a/ip/iplink.c -+++ b/ip/iplink.c -@@ -91,6 +91,8 @@ void iplink_usage(void) - " [ query_rss { on | off} ]\n" - " [ state { auto | enable | disable} ] ]\n" - " [ trust { on | off} ] ]\n" -+ " [ node_guid { eui64 } ]\n" -+ " [ port_guid { eui64 } ]\n" - " [ xdp { off |\n" - " object FILE [ section NAME ] [ verbose ] |\n" - " pinned FILE } ]\n" -diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in -index a5ddfe7a106e7..48417dbce80aa 100644 ---- a/man/man8/ip-link.8.in -+++ b/man/man8/ip-link.8.in -@@ -1564,10 +1564,10 @@ sent by the VF. - which may impact security and/or performance. (e.g. VF multicast promiscuous mode) - .sp - .BI node_guid " eui64" --- configure node GUID for the VF. -+- configure node GUID for Infiniband VFs. - .sp - .BI port_guid " eui64" --- configure port GUID for the VF. -+- configure port GUID for Infiniband VFs. - .in -8 - - .TP --- -2.21.0 - diff --git a/SOURCES/0035-tc-flower-add-support-for-matching-on-ip-tos-and-ttl.patch b/SOURCES/0035-tc-flower-add-support-for-matching-on-ip-tos-and-ttl.patch deleted file mode 100644 index db1f70a..0000000 --- a/SOURCES/0035-tc-flower-add-support-for-matching-on-ip-tos-and-ttl.patch +++ /dev/null @@ -1,177 +0,0 @@ -From f8e5b20689cdc1f488140d9da4adf6f3ca421d3f Mon Sep 17 00:00:00 2001 -From: Kamal Heib -Date: Thu, 9 Nov 2017 04:44:32 -0500 -Subject: [PATCH] tc: flower: add support for matching on ip tos and ttl - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1456539 - -commit 6ea2c2b1cff676be2d01029a01cbd84d0675213c -Author: Or Gerlitz -Date: Wed Jun 7 15:17:54 2017 +0300 - - tc: flower: add support for matching on ip tos and ttl - - Allow users to set flower classifier filter rules which - include matches for ip tos and ttl. - - Signed-off-by: Or Gerlitz - Reviewed-by: Jiri Pirko - -Signed-off-by: Kamal Heib ---- - man/man8/tc-flower.8 | 17 +++++++++- - tc/f_flower.c | 75 ++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 91 insertions(+), 1 deletion(-) - -diff --git a/man/man8/tc-flower.8 b/man/man8/tc-flower.8 -index 76480798d72f9..be46f0278b4ff 100644 ---- a/man/man8/tc-flower.8 -+++ b/man/man8/tc-flower.8 -@@ -30,7 +30,11 @@ flower \- flow based traffic control filter - .BR vlan_ethtype " { " ipv4 " | " ipv6 " | " - .IR ETH_TYPE " } | " - .BR ip_proto " { " tcp " | " udp " | " sctp " | " icmp " | " icmpv6 " | " --.IR IP_PROTO " } | { " -+.IR IP_PROTO " } | " -+.B ip_tos -+.IR MASKED_IP_TOS " | " -+.B ip_ttl -+.IR MASKED_IP_TTL " | { " - .BR dst_ip " | " src_ip " } " - .IR PREFIX " | { " - .BR dst_port " | " src_port " } " -@@ -122,6 +126,17 @@ may be - .BR tcp ", " udp ", " sctp ", " icmp ", " icmpv6 - or an unsigned 8bit value in hexadecimal format. - .TP -+.BI ip_tos " MASKED_IP_TOS" -+Match on ipv4 TOS or ipv6 traffic-class - eight bits in hexadecimal format. -+A mask may be optionally provided to limit the bits which are matched. A mask -+is provided by following the value with a slash and then the mask. If the mask -+is missing then a match on all bits is assumed. -+.TP -+.BI ip_ttl " MASKED_IP_TTL" -+Match on ipv4 TTL or ipv6 hop-limit - eight bits value in decimal or hexadecimal format. -+A mask may be optionally provided to limit the bits which are matched. Same -+logic is used for the mask as with matching on ip_tos. -+.TP - .BI dst_ip " PREFIX" - .TQ - .BI src_ip " PREFIX" -diff --git a/tc/f_flower.c b/tc/f_flower.c -index 1b6b46ea0177b..5be693ab7f6af 100644 ---- a/tc/f_flower.c -+++ b/tc/f_flower.c -@@ -53,6 +53,8 @@ static void explain(void) - " dst_mac MASKED-LLADDR |\n" - " src_mac MASKED-LLADDR |\n" - " ip_proto [tcp | udp | sctp | icmp | icmpv6 | IP-PROTO ] |\n" -+ " ip_tos MASKED-IP_TOS |\n" -+ " ip_ttl MASKED-IP_TTL |\n" - " dst_ip PREFIX |\n" - " src_ip PREFIX |\n" - " dst_port PORT-NUMBER |\n" -@@ -510,6 +512,41 @@ err: - return err; - } - -+static int flower_parse_ip_tos_ttl(char *str, int key_type, int mask_type, -+ struct nlmsghdr *n) -+{ -+ char *slash; -+ int ret, err = -1; -+ __u8 tos_ttl; -+ -+ slash = strchr(str, '/'); -+ if (slash) -+ *slash = '\0'; -+ -+ ret = get_u8(&tos_ttl, str, 10); -+ if (ret < 0) -+ ret = get_u8(&tos_ttl, str, 16); -+ if (ret < 0) -+ goto err; -+ -+ addattr8(n, MAX_MSG, key_type, tos_ttl); -+ -+ if (slash) { -+ ret = get_u8(&tos_ttl, slash + 1, 16); -+ if (ret < 0) -+ goto err; -+ } else { -+ tos_ttl = 0xff; -+ } -+ addattr8(n, MAX_MSG, mask_type, tos_ttl); -+ -+ err = 0; -+err: -+ if (slash) -+ *slash = '/'; -+ return err; -+} -+ - static int flower_parse_key_id(const char *str, int type, struct nlmsghdr *n) - { - int ret; -@@ -665,6 +702,26 @@ static int flower_parse_opt(struct filter_util *qu, char *handle, - fprintf(stderr, "Illegal \"ip_proto\"\n"); - return -1; - } -+ } else if (matches(*argv, "ip_tos") == 0) { -+ NEXT_ARG(); -+ ret = flower_parse_ip_tos_ttl(*argv, -+ TCA_FLOWER_KEY_IP_TOS, -+ TCA_FLOWER_KEY_IP_TOS_MASK, -+ n); -+ if (ret < 0) { -+ fprintf(stderr, "Illegal \"ip_tos\"\n"); -+ return -1; -+ } -+ } else if (matches(*argv, "ip_ttl") == 0) { -+ NEXT_ARG(); -+ ret = flower_parse_ip_tos_ttl(*argv, -+ TCA_FLOWER_KEY_IP_TTL, -+ TCA_FLOWER_KEY_IP_TTL_MASK, -+ n); -+ if (ret < 0) { -+ fprintf(stderr, "Illegal \"ip_ttl\"\n"); -+ return -1; -+ } - } else if (matches(*argv, "dst_ip") == 0) { - NEXT_ARG(); - ret = flower_parse_ip_addr(*argv, vlan_ethtype ? -@@ -963,6 +1020,19 @@ static void flower_print_ip_proto(FILE *f, __u8 *p_ip_proto, - *p_ip_proto = ip_proto; - } - -+static void flower_print_ip_attr(FILE *f, char *name, -+ struct rtattr *key_attr, -+ struct rtattr *mask_attr) -+{ -+ if (!key_attr) -+ return; -+ -+ fprintf(f, "\n %s %x", name, rta_getattr_u8(key_attr)); -+ if (!mask_attr) -+ return; -+ fprintf(f, "/%x", rta_getattr_u8(mask_attr)); -+} -+ - static void flower_print_matching_flags(FILE *f, char *name, - enum flower_matching_flags type, - struct rtattr *attr, -@@ -1150,6 +1220,11 @@ static int flower_print_opt(struct filter_util *qu, FILE *f, - flower_print_eth_type(f, ð_type, tb[TCA_FLOWER_KEY_ETH_TYPE]); - flower_print_ip_proto(f, &ip_proto, tb[TCA_FLOWER_KEY_IP_PROTO]); - -+ flower_print_ip_attr(f, "ip_tos", tb[TCA_FLOWER_KEY_IP_TOS], -+ tb[TCA_FLOWER_KEY_IP_TOS_MASK]); -+ flower_print_ip_attr(f, "ip_ttl", tb[TCA_FLOWER_KEY_IP_TTL], -+ tb[TCA_FLOWER_KEY_IP_TTL_MASK]); -+ - flower_print_ip_addr(f, "dst_ip", eth_type, - tb[TCA_FLOWER_KEY_IPV4_DST], - tb[TCA_FLOWER_KEY_IPV4_DST_MASK], --- -2.21.0 - diff --git a/SOURCES/0036-iproute-build-more-easily-on-Android.patch b/SOURCES/0036-iproute-build-more-easily-on-Android.patch deleted file mode 100644 index e2dd7c5..0000000 --- a/SOURCES/0036-iproute-build-more-easily-on-Android.patch +++ /dev/null @@ -1,722 +0,0 @@ -From 9b0d1f60b01ac442ee3ec15c47c99d3756938034 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Mon, 13 Nov 2017 18:09:56 +0100 -Subject: [PATCH] iproute: build more easily on Android - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1472759 -Upstream Status: iproute2.git commit 596b1c94aa38e - -commit 596b1c94aa38e21b7a8c8562e8b61ccb744255d2 -Author: Lorenzo Colitti -Date: Tue Oct 3 02:03:37 2017 +0900 - - iproute: build more easily on Android - - iproute2 contains a bunch of kernel headers, including uapi ones. - Android's libc uses uapi headers almost directly, and uses a - script to fix kernel types that don't match what userspace - expects. - - For example: https://issuetracker.google.com/36987220 reports - that our struct ip_mreq_source contains "__be32 imr_multiaddr" - rather than "struct in_addr imr_multiaddr". The script addresses - this by replacing the uapi struct definition with a #include - which contains the traditional userspace - definition. - - Unfortunately, when we compile iproute2, this definition - conflicts with the one in iproute2's linux/in.h. - - Historically we've just solved this problem by running "git rm" - on all the iproute2 include/linux headers that break Android's - libc. However, deleting the files in this way makes it harder to - keep up with upstream, because every upstream change to - an include file causes a merge conflict with the delete. - - This patch fixes the problem by moving the iproute2 linux headers - from include/linux to include/uapi/linux. - - Tested: compiles on ubuntu trusty (glibc) - - Signed-off-by: Elliott Hughes - Signed-off-by: Lorenzo Colitti ---- - Makefile | 2 +- - include/{ => uapi}/linux/atm.h | 0 - include/{ => uapi}/linux/atmapi.h | 0 - include/{ => uapi}/linux/atmarp.h | 0 - include/{ => uapi}/linux/atmdev.h | 0 - include/{ => uapi}/linux/atmioc.h | 0 - include/{ => uapi}/linux/atmsap.h | 0 - include/{ => uapi}/linux/bpf.h | 0 - include/{ => uapi}/linux/bpf_common.h | 0 - include/{ => uapi}/linux/can.h | 0 - include/{ => uapi}/linux/can/netlink.h | 0 - include/{ => uapi}/linux/can/vxcan.h | 0 - include/{ => uapi}/linux/devlink.h | 0 - include/{ => uapi}/linux/elf-em.h | 0 - include/{ => uapi}/linux/fib_rules.h | 0 - include/{ => uapi}/linux/filter.h | 0 - include/{ => uapi}/linux/fou.h | 0 - include/{ => uapi}/linux/gen_stats.h | 0 - include/{ => uapi}/linux/genetlink.h | 0 - include/{ => uapi}/linux/hdlc/ioctl.h | 0 - include/{ => uapi}/linux/icmpv6.h | 0 - include/{ => uapi}/linux/if.h | 0 - include/{ => uapi}/linux/if_addr.h | 0 - include/{ => uapi}/linux/if_addrlabel.h | 0 - include/{ => uapi}/linux/if_alg.h | 0 - include/{ => uapi}/linux/if_arp.h | 0 - include/{ => uapi}/linux/if_bonding.h | 0 - include/{ => uapi}/linux/if_bridge.h | 0 - include/{ => uapi}/linux/if_ether.h | 0 - include/{ => uapi}/linux/if_link.h | 0 - include/{ => uapi}/linux/if_macsec.h | 0 - include/{ => uapi}/linux/if_packet.h | 0 - include/{ => uapi}/linux/if_tun.h | 0 - include/{ => uapi}/linux/if_tunnel.h | 0 - include/{ => uapi}/linux/if_vlan.h | 0 - include/{ => uapi}/linux/ife.h | 0 - include/{ => uapi}/linux/ila.h | 0 - include/{ => uapi}/linux/in.h | 0 - include/{ => uapi}/linux/in6.h | 0 - include/{ => uapi}/linux/in_route.h | 0 - include/{ => uapi}/linux/inet_diag.h | 0 - include/{ => uapi}/linux/ip.h | 0 - include/{ => uapi}/linux/ip6_tunnel.h | 0 - include/{ => uapi}/linux/ipsec.h | 0 - include/{ => uapi}/linux/kernel.h | 0 - include/{ => uapi}/linux/l2tp.h | 0 - include/{ => uapi}/linux/libc-compat.h | 0 - include/{ => uapi}/linux/limits.h | 0 - include/{ => uapi}/linux/lwtunnel.h | 0 - include/{ => uapi}/linux/magic.h | 0 - include/{ => uapi}/linux/mpls.h | 0 - include/{ => uapi}/linux/mpls_iptunnel.h | 0 - include/{ => uapi}/linux/neighbour.h | 0 - include/{ => uapi}/linux/net_namespace.h | 0 - include/{ => uapi}/linux/netconf.h | 0 - include/{ => uapi}/linux/netdevice.h | 0 - include/{ => uapi}/linux/netfilter.h | 0 - include/{ => uapi}/linux/netfilter/ipset/ip_set.h | 0 - include/{ => uapi}/linux/netfilter/x_tables.h | 0 - include/{ => uapi}/linux/netfilter/xt_set.h | 0 - include/{ => uapi}/linux/netfilter/xt_tcpudp.h | 0 - include/{ => uapi}/linux/netfilter_ipv4.h | 0 - include/{ => uapi}/linux/netfilter_ipv4/ip_tables.h | 0 - include/{ => uapi}/linux/netfilter_ipv6.h | 0 - include/{ => uapi}/linux/netfilter_ipv6/ip6_tables.h | 0 - include/{ => uapi}/linux/netlink.h | 0 - include/{ => uapi}/linux/netlink_diag.h | 0 - include/{ => uapi}/linux/packet_diag.h | 0 - include/{ => uapi}/linux/param.h | 0 - include/{ => uapi}/linux/pfkeyv2.h | 0 - include/{ => uapi}/linux/pkt_cls.h | 0 - include/{ => uapi}/linux/pkt_sched.h | 0 - include/{ => uapi}/linux/posix_types.h | 0 - include/{ => uapi}/linux/rtnetlink.h | 0 - include/{ => uapi}/linux/sctp.h | 0 - include/{ => uapi}/linux/seg6.h | 0 - include/{ => uapi}/linux/seg6_genl.h | 0 - include/{ => uapi}/linux/seg6_hmac.h | 0 - include/{ => uapi}/linux/seg6_iptunnel.h | 0 - include/{ => uapi}/linux/seg6_local.h | 0 - include/{ => uapi}/linux/sock_diag.h | 0 - include/{ => uapi}/linux/socket.h | 0 - include/{ => uapi}/linux/sockios.h | 0 - include/{ => uapi}/linux/stddef.h | 0 - include/{ => uapi}/linux/sysinfo.h | 0 - include/{ => uapi}/linux/tc_act/tc_bpf.h | 0 - include/{ => uapi}/linux/tc_act/tc_connmark.h | 0 - include/{ => uapi}/linux/tc_act/tc_csum.h | 0 - include/{ => uapi}/linux/tc_act/tc_defact.h | 0 - include/{ => uapi}/linux/tc_act/tc_gact.h | 0 - include/{ => uapi}/linux/tc_act/tc_ife.h | 0 - include/{ => uapi}/linux/tc_act/tc_ipt.h | 0 - include/{ => uapi}/linux/tc_act/tc_mirred.h | 0 - include/{ => uapi}/linux/tc_act/tc_nat.h | 0 - include/{ => uapi}/linux/tc_act/tc_pedit.h | 0 - include/{ => uapi}/linux/tc_act/tc_sample.h | 0 - include/{ => uapi}/linux/tc_act/tc_skbedit.h | 0 - include/{ => uapi}/linux/tc_act/tc_skbmod.h | 0 - include/{ => uapi}/linux/tc_act/tc_tunnel_key.h | 0 - include/{ => uapi}/linux/tc_act/tc_vlan.h | 0 - include/{ => uapi}/linux/tc_ematch/tc_em_cmp.h | 0 - include/{ => uapi}/linux/tc_ematch/tc_em_meta.h | 0 - include/{ => uapi}/linux/tc_ematch/tc_em_nbyte.h | 0 - include/{ => uapi}/linux/tcp.h | 0 - include/{ => uapi}/linux/tcp_metrics.h | 0 - include/{ => uapi}/linux/tipc.h | 0 - include/{ => uapi}/linux/tipc_netlink.h | 0 - include/{ => uapi}/linux/types.h | 0 - include/{ => uapi}/linux/unix_diag.h | 0 - include/{ => uapi}/linux/veth.h | 0 - include/{ => uapi}/linux/xfrm.h | 0 - 111 files changed, 1 insertion(+), 1 deletion(-) - rename include/{ => uapi}/linux/atm.h (100%) - rename include/{ => uapi}/linux/atmapi.h (100%) - rename include/{ => uapi}/linux/atmarp.h (100%) - rename include/{ => uapi}/linux/atmdev.h (100%) - rename include/{ => uapi}/linux/atmioc.h (100%) - rename include/{ => uapi}/linux/atmsap.h (100%) - rename include/{ => uapi}/linux/bpf.h (100%) - rename include/{ => uapi}/linux/bpf_common.h (100%) - rename include/{ => uapi}/linux/can.h (100%) - rename include/{ => uapi}/linux/can/netlink.h (100%) - rename include/{ => uapi}/linux/can/vxcan.h (100%) - rename include/{ => uapi}/linux/devlink.h (100%) - rename include/{ => uapi}/linux/elf-em.h (100%) - rename include/{ => uapi}/linux/fib_rules.h (100%) - rename include/{ => uapi}/linux/filter.h (100%) - rename include/{ => uapi}/linux/fou.h (100%) - rename include/{ => uapi}/linux/gen_stats.h (100%) - rename include/{ => uapi}/linux/genetlink.h (100%) - rename include/{ => uapi}/linux/hdlc/ioctl.h (100%) - rename include/{ => uapi}/linux/icmpv6.h (100%) - rename include/{ => uapi}/linux/if.h (100%) - rename include/{ => uapi}/linux/if_addr.h (100%) - rename include/{ => uapi}/linux/if_addrlabel.h (100%) - rename include/{ => uapi}/linux/if_alg.h (100%) - rename include/{ => uapi}/linux/if_arp.h (100%) - rename include/{ => uapi}/linux/if_bonding.h (100%) - rename include/{ => uapi}/linux/if_bridge.h (100%) - rename include/{ => uapi}/linux/if_ether.h (100%) - rename include/{ => uapi}/linux/if_link.h (100%) - rename include/{ => uapi}/linux/if_macsec.h (100%) - rename include/{ => uapi}/linux/if_packet.h (100%) - rename include/{ => uapi}/linux/if_tun.h (100%) - rename include/{ => uapi}/linux/if_tunnel.h (100%) - rename include/{ => uapi}/linux/if_vlan.h (100%) - rename include/{ => uapi}/linux/ife.h (100%) - rename include/{ => uapi}/linux/ila.h (100%) - rename include/{ => uapi}/linux/in.h (100%) - rename include/{ => uapi}/linux/in6.h (100%) - rename include/{ => uapi}/linux/in_route.h (100%) - rename include/{ => uapi}/linux/inet_diag.h (100%) - rename include/{ => uapi}/linux/ip.h (100%) - rename include/{ => uapi}/linux/ip6_tunnel.h (100%) - rename include/{ => uapi}/linux/ipsec.h (100%) - rename include/{ => uapi}/linux/kernel.h (100%) - rename include/{ => uapi}/linux/l2tp.h (100%) - rename include/{ => uapi}/linux/libc-compat.h (100%) - rename include/{ => uapi}/linux/limits.h (100%) - rename include/{ => uapi}/linux/lwtunnel.h (100%) - rename include/{ => uapi}/linux/magic.h (100%) - rename include/{ => uapi}/linux/mpls.h (100%) - rename include/{ => uapi}/linux/mpls_iptunnel.h (100%) - rename include/{ => uapi}/linux/neighbour.h (100%) - rename include/{ => uapi}/linux/net_namespace.h (100%) - rename include/{ => uapi}/linux/netconf.h (100%) - rename include/{ => uapi}/linux/netdevice.h (100%) - rename include/{ => uapi}/linux/netfilter.h (100%) - rename include/{ => uapi}/linux/netfilter/ipset/ip_set.h (100%) - rename include/{ => uapi}/linux/netfilter/x_tables.h (100%) - rename include/{ => uapi}/linux/netfilter/xt_set.h (100%) - rename include/{ => uapi}/linux/netfilter/xt_tcpudp.h (100%) - rename include/{ => uapi}/linux/netfilter_ipv4.h (100%) - rename include/{ => uapi}/linux/netfilter_ipv4/ip_tables.h (100%) - rename include/{ => uapi}/linux/netfilter_ipv6.h (100%) - rename include/{ => uapi}/linux/netfilter_ipv6/ip6_tables.h (100%) - rename include/{ => uapi}/linux/netlink.h (100%) - rename include/{ => uapi}/linux/netlink_diag.h (100%) - rename include/{ => uapi}/linux/packet_diag.h (100%) - rename include/{ => uapi}/linux/param.h (100%) - rename include/{ => uapi}/linux/pfkeyv2.h (100%) - rename include/{ => uapi}/linux/pkt_cls.h (100%) - rename include/{ => uapi}/linux/pkt_sched.h (100%) - rename include/{ => uapi}/linux/posix_types.h (100%) - rename include/{ => uapi}/linux/rtnetlink.h (100%) - rename include/{ => uapi}/linux/sctp.h (100%) - rename include/{ => uapi}/linux/seg6.h (100%) - rename include/{ => uapi}/linux/seg6_genl.h (100%) - rename include/{ => uapi}/linux/seg6_hmac.h (100%) - rename include/{ => uapi}/linux/seg6_iptunnel.h (100%) - rename include/{ => uapi}/linux/seg6_local.h (100%) - rename include/{ => uapi}/linux/sock_diag.h (100%) - rename include/{ => uapi}/linux/socket.h (100%) - rename include/{ => uapi}/linux/sockios.h (100%) - rename include/{ => uapi}/linux/stddef.h (100%) - rename include/{ => uapi}/linux/sysinfo.h (100%) - rename include/{ => uapi}/linux/tc_act/tc_bpf.h (100%) - rename include/{ => uapi}/linux/tc_act/tc_connmark.h (100%) - rename include/{ => uapi}/linux/tc_act/tc_csum.h (100%) - rename include/{ => uapi}/linux/tc_act/tc_defact.h (100%) - rename include/{ => uapi}/linux/tc_act/tc_gact.h (100%) - rename include/{ => uapi}/linux/tc_act/tc_ife.h (100%) - rename include/{ => uapi}/linux/tc_act/tc_ipt.h (100%) - rename include/{ => uapi}/linux/tc_act/tc_mirred.h (100%) - rename include/{ => uapi}/linux/tc_act/tc_nat.h (100%) - rename include/{ => uapi}/linux/tc_act/tc_pedit.h (100%) - rename include/{ => uapi}/linux/tc_act/tc_sample.h (100%) - rename include/{ => uapi}/linux/tc_act/tc_skbedit.h (100%) - rename include/{ => uapi}/linux/tc_act/tc_skbmod.h (100%) - rename include/{ => uapi}/linux/tc_act/tc_tunnel_key.h (100%) - rename include/{ => uapi}/linux/tc_act/tc_vlan.h (100%) - rename include/{ => uapi}/linux/tc_ematch/tc_em_cmp.h (100%) - rename include/{ => uapi}/linux/tc_ematch/tc_em_meta.h (100%) - rename include/{ => uapi}/linux/tc_ematch/tc_em_nbyte.h (100%) - rename include/{ => uapi}/linux/tcp.h (100%) - rename include/{ => uapi}/linux/tcp_metrics.h (100%) - rename include/{ => uapi}/linux/tipc.h (100%) - rename include/{ => uapi}/linux/tipc_netlink.h (100%) - rename include/{ => uapi}/linux/types.h (100%) - rename include/{ => uapi}/linux/unix_diag.h (100%) - rename include/{ => uapi}/linux/veth.h (100%) - rename include/{ => uapi}/linux/xfrm.h (100%) - -diff --git a/Makefile b/Makefile -index 18de7dcb315b1..df2fa33630e65 100644 ---- a/Makefile -+++ b/Makefile -@@ -49,7 +49,7 @@ CCOPTS = -O2 - WFLAGS := -Wall -Wstrict-prototypes -Wmissing-prototypes - WFLAGS += -Wmissing-declarations -Wold-style-definition -Wformat=2 - --CFLAGS := $(WFLAGS) $(CCOPTS) -I../include $(DEFINES) $(CFLAGS) -+CFLAGS := $(WFLAGS) $(CCOPTS) -I../include -I../include/uapi $(DEFINES) $(CFLAGS) - YACCFLAGS = -d -t -v - - SUBDIRS=lib ip tc bridge misc netem genl tipc devlink man -diff --git a/include/linux/atm.h b/include/uapi/linux/atm.h -similarity index 100% -rename from include/linux/atm.h -rename to include/uapi/linux/atm.h -diff --git a/include/linux/atmapi.h b/include/uapi/linux/atmapi.h -similarity index 100% -rename from include/linux/atmapi.h -rename to include/uapi/linux/atmapi.h -diff --git a/include/linux/atmarp.h b/include/uapi/linux/atmarp.h -similarity index 100% -rename from include/linux/atmarp.h -rename to include/uapi/linux/atmarp.h -diff --git a/include/linux/atmdev.h b/include/uapi/linux/atmdev.h -similarity index 100% -rename from include/linux/atmdev.h -rename to include/uapi/linux/atmdev.h -diff --git a/include/linux/atmioc.h b/include/uapi/linux/atmioc.h -similarity index 100% -rename from include/linux/atmioc.h -rename to include/uapi/linux/atmioc.h -diff --git a/include/linux/atmsap.h b/include/uapi/linux/atmsap.h -similarity index 100% -rename from include/linux/atmsap.h -rename to include/uapi/linux/atmsap.h -diff --git a/include/linux/bpf.h b/include/uapi/linux/bpf.h -similarity index 100% -rename from include/linux/bpf.h -rename to include/uapi/linux/bpf.h -diff --git a/include/linux/bpf_common.h b/include/uapi/linux/bpf_common.h -similarity index 100% -rename from include/linux/bpf_common.h -rename to include/uapi/linux/bpf_common.h -diff --git a/include/linux/can.h b/include/uapi/linux/can.h -similarity index 100% -rename from include/linux/can.h -rename to include/uapi/linux/can.h -diff --git a/include/linux/can/netlink.h b/include/uapi/linux/can/netlink.h -similarity index 100% -rename from include/linux/can/netlink.h -rename to include/uapi/linux/can/netlink.h -diff --git a/include/linux/can/vxcan.h b/include/uapi/linux/can/vxcan.h -similarity index 100% -rename from include/linux/can/vxcan.h -rename to include/uapi/linux/can/vxcan.h -diff --git a/include/linux/devlink.h b/include/uapi/linux/devlink.h -similarity index 100% -rename from include/linux/devlink.h -rename to include/uapi/linux/devlink.h -diff --git a/include/linux/elf-em.h b/include/uapi/linux/elf-em.h -similarity index 100% -rename from include/linux/elf-em.h -rename to include/uapi/linux/elf-em.h -diff --git a/include/linux/fib_rules.h b/include/uapi/linux/fib_rules.h -similarity index 100% -rename from include/linux/fib_rules.h -rename to include/uapi/linux/fib_rules.h -diff --git a/include/linux/filter.h b/include/uapi/linux/filter.h -similarity index 100% -rename from include/linux/filter.h -rename to include/uapi/linux/filter.h -diff --git a/include/linux/fou.h b/include/uapi/linux/fou.h -similarity index 100% -rename from include/linux/fou.h -rename to include/uapi/linux/fou.h -diff --git a/include/linux/gen_stats.h b/include/uapi/linux/gen_stats.h -similarity index 100% -rename from include/linux/gen_stats.h -rename to include/uapi/linux/gen_stats.h -diff --git a/include/linux/genetlink.h b/include/uapi/linux/genetlink.h -similarity index 100% -rename from include/linux/genetlink.h -rename to include/uapi/linux/genetlink.h -diff --git a/include/linux/hdlc/ioctl.h b/include/uapi/linux/hdlc/ioctl.h -similarity index 100% -rename from include/linux/hdlc/ioctl.h -rename to include/uapi/linux/hdlc/ioctl.h -diff --git a/include/linux/icmpv6.h b/include/uapi/linux/icmpv6.h -similarity index 100% -rename from include/linux/icmpv6.h -rename to include/uapi/linux/icmpv6.h -diff --git a/include/linux/if.h b/include/uapi/linux/if.h -similarity index 100% -rename from include/linux/if.h -rename to include/uapi/linux/if.h -diff --git a/include/linux/if_addr.h b/include/uapi/linux/if_addr.h -similarity index 100% -rename from include/linux/if_addr.h -rename to include/uapi/linux/if_addr.h -diff --git a/include/linux/if_addrlabel.h b/include/uapi/linux/if_addrlabel.h -similarity index 100% -rename from include/linux/if_addrlabel.h -rename to include/uapi/linux/if_addrlabel.h -diff --git a/include/linux/if_alg.h b/include/uapi/linux/if_alg.h -similarity index 100% -rename from include/linux/if_alg.h -rename to include/uapi/linux/if_alg.h -diff --git a/include/linux/if_arp.h b/include/uapi/linux/if_arp.h -similarity index 100% -rename from include/linux/if_arp.h -rename to include/uapi/linux/if_arp.h -diff --git a/include/linux/if_bonding.h b/include/uapi/linux/if_bonding.h -similarity index 100% -rename from include/linux/if_bonding.h -rename to include/uapi/linux/if_bonding.h -diff --git a/include/linux/if_bridge.h b/include/uapi/linux/if_bridge.h -similarity index 100% -rename from include/linux/if_bridge.h -rename to include/uapi/linux/if_bridge.h -diff --git a/include/linux/if_ether.h b/include/uapi/linux/if_ether.h -similarity index 100% -rename from include/linux/if_ether.h -rename to include/uapi/linux/if_ether.h -diff --git a/include/linux/if_link.h b/include/uapi/linux/if_link.h -similarity index 100% -rename from include/linux/if_link.h -rename to include/uapi/linux/if_link.h -diff --git a/include/linux/if_macsec.h b/include/uapi/linux/if_macsec.h -similarity index 100% -rename from include/linux/if_macsec.h -rename to include/uapi/linux/if_macsec.h -diff --git a/include/linux/if_packet.h b/include/uapi/linux/if_packet.h -similarity index 100% -rename from include/linux/if_packet.h -rename to include/uapi/linux/if_packet.h -diff --git a/include/linux/if_tun.h b/include/uapi/linux/if_tun.h -similarity index 100% -rename from include/linux/if_tun.h -rename to include/uapi/linux/if_tun.h -diff --git a/include/linux/if_tunnel.h b/include/uapi/linux/if_tunnel.h -similarity index 100% -rename from include/linux/if_tunnel.h -rename to include/uapi/linux/if_tunnel.h -diff --git a/include/linux/if_vlan.h b/include/uapi/linux/if_vlan.h -similarity index 100% -rename from include/linux/if_vlan.h -rename to include/uapi/linux/if_vlan.h -diff --git a/include/linux/ife.h b/include/uapi/linux/ife.h -similarity index 100% -rename from include/linux/ife.h -rename to include/uapi/linux/ife.h -diff --git a/include/linux/ila.h b/include/uapi/linux/ila.h -similarity index 100% -rename from include/linux/ila.h -rename to include/uapi/linux/ila.h -diff --git a/include/linux/in.h b/include/uapi/linux/in.h -similarity index 100% -rename from include/linux/in.h -rename to include/uapi/linux/in.h -diff --git a/include/linux/in6.h b/include/uapi/linux/in6.h -similarity index 100% -rename from include/linux/in6.h -rename to include/uapi/linux/in6.h -diff --git a/include/linux/in_route.h b/include/uapi/linux/in_route.h -similarity index 100% -rename from include/linux/in_route.h -rename to include/uapi/linux/in_route.h -diff --git a/include/linux/inet_diag.h b/include/uapi/linux/inet_diag.h -similarity index 100% -rename from include/linux/inet_diag.h -rename to include/uapi/linux/inet_diag.h -diff --git a/include/linux/ip.h b/include/uapi/linux/ip.h -similarity index 100% -rename from include/linux/ip.h -rename to include/uapi/linux/ip.h -diff --git a/include/linux/ip6_tunnel.h b/include/uapi/linux/ip6_tunnel.h -similarity index 100% -rename from include/linux/ip6_tunnel.h -rename to include/uapi/linux/ip6_tunnel.h -diff --git a/include/linux/ipsec.h b/include/uapi/linux/ipsec.h -similarity index 100% -rename from include/linux/ipsec.h -rename to include/uapi/linux/ipsec.h -diff --git a/include/linux/kernel.h b/include/uapi/linux/kernel.h -similarity index 100% -rename from include/linux/kernel.h -rename to include/uapi/linux/kernel.h -diff --git a/include/linux/l2tp.h b/include/uapi/linux/l2tp.h -similarity index 100% -rename from include/linux/l2tp.h -rename to include/uapi/linux/l2tp.h -diff --git a/include/linux/libc-compat.h b/include/uapi/linux/libc-compat.h -similarity index 100% -rename from include/linux/libc-compat.h -rename to include/uapi/linux/libc-compat.h -diff --git a/include/linux/limits.h b/include/uapi/linux/limits.h -similarity index 100% -rename from include/linux/limits.h -rename to include/uapi/linux/limits.h -diff --git a/include/linux/lwtunnel.h b/include/uapi/linux/lwtunnel.h -similarity index 100% -rename from include/linux/lwtunnel.h -rename to include/uapi/linux/lwtunnel.h -diff --git a/include/linux/magic.h b/include/uapi/linux/magic.h -similarity index 100% -rename from include/linux/magic.h -rename to include/uapi/linux/magic.h -diff --git a/include/linux/mpls.h b/include/uapi/linux/mpls.h -similarity index 100% -rename from include/linux/mpls.h -rename to include/uapi/linux/mpls.h -diff --git a/include/linux/mpls_iptunnel.h b/include/uapi/linux/mpls_iptunnel.h -similarity index 100% -rename from include/linux/mpls_iptunnel.h -rename to include/uapi/linux/mpls_iptunnel.h -diff --git a/include/linux/neighbour.h b/include/uapi/linux/neighbour.h -similarity index 100% -rename from include/linux/neighbour.h -rename to include/uapi/linux/neighbour.h -diff --git a/include/linux/net_namespace.h b/include/uapi/linux/net_namespace.h -similarity index 100% -rename from include/linux/net_namespace.h -rename to include/uapi/linux/net_namespace.h -diff --git a/include/linux/netconf.h b/include/uapi/linux/netconf.h -similarity index 100% -rename from include/linux/netconf.h -rename to include/uapi/linux/netconf.h -diff --git a/include/linux/netdevice.h b/include/uapi/linux/netdevice.h -similarity index 100% -rename from include/linux/netdevice.h -rename to include/uapi/linux/netdevice.h -diff --git a/include/linux/netfilter.h b/include/uapi/linux/netfilter.h -similarity index 100% -rename from include/linux/netfilter.h -rename to include/uapi/linux/netfilter.h -diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/uapi/linux/netfilter/ipset/ip_set.h -similarity index 100% -rename from include/linux/netfilter/ipset/ip_set.h -rename to include/uapi/linux/netfilter/ipset/ip_set.h -diff --git a/include/linux/netfilter/x_tables.h b/include/uapi/linux/netfilter/x_tables.h -similarity index 100% -rename from include/linux/netfilter/x_tables.h -rename to include/uapi/linux/netfilter/x_tables.h -diff --git a/include/linux/netfilter/xt_set.h b/include/uapi/linux/netfilter/xt_set.h -similarity index 100% -rename from include/linux/netfilter/xt_set.h -rename to include/uapi/linux/netfilter/xt_set.h -diff --git a/include/linux/netfilter/xt_tcpudp.h b/include/uapi/linux/netfilter/xt_tcpudp.h -similarity index 100% -rename from include/linux/netfilter/xt_tcpudp.h -rename to include/uapi/linux/netfilter/xt_tcpudp.h -diff --git a/include/linux/netfilter_ipv4.h b/include/uapi/linux/netfilter_ipv4.h -similarity index 100% -rename from include/linux/netfilter_ipv4.h -rename to include/uapi/linux/netfilter_ipv4.h -diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/uapi/linux/netfilter_ipv4/ip_tables.h -similarity index 100% -rename from include/linux/netfilter_ipv4/ip_tables.h -rename to include/uapi/linux/netfilter_ipv4/ip_tables.h -diff --git a/include/linux/netfilter_ipv6.h b/include/uapi/linux/netfilter_ipv6.h -similarity index 100% -rename from include/linux/netfilter_ipv6.h -rename to include/uapi/linux/netfilter_ipv6.h -diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/uapi/linux/netfilter_ipv6/ip6_tables.h -similarity index 100% -rename from include/linux/netfilter_ipv6/ip6_tables.h -rename to include/uapi/linux/netfilter_ipv6/ip6_tables.h -diff --git a/include/linux/netlink.h b/include/uapi/linux/netlink.h -similarity index 100% -rename from include/linux/netlink.h -rename to include/uapi/linux/netlink.h -diff --git a/include/linux/netlink_diag.h b/include/uapi/linux/netlink_diag.h -similarity index 100% -rename from include/linux/netlink_diag.h -rename to include/uapi/linux/netlink_diag.h -diff --git a/include/linux/packet_diag.h b/include/uapi/linux/packet_diag.h -similarity index 100% -rename from include/linux/packet_diag.h -rename to include/uapi/linux/packet_diag.h -diff --git a/include/linux/param.h b/include/uapi/linux/param.h -similarity index 100% -rename from include/linux/param.h -rename to include/uapi/linux/param.h -diff --git a/include/linux/pfkeyv2.h b/include/uapi/linux/pfkeyv2.h -similarity index 100% -rename from include/linux/pfkeyv2.h -rename to include/uapi/linux/pfkeyv2.h -diff --git a/include/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h -similarity index 100% -rename from include/linux/pkt_cls.h -rename to include/uapi/linux/pkt_cls.h -diff --git a/include/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h -similarity index 100% -rename from include/linux/pkt_sched.h -rename to include/uapi/linux/pkt_sched.h -diff --git a/include/linux/posix_types.h b/include/uapi/linux/posix_types.h -similarity index 100% -rename from include/linux/posix_types.h -rename to include/uapi/linux/posix_types.h -diff --git a/include/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h -similarity index 100% -rename from include/linux/rtnetlink.h -rename to include/uapi/linux/rtnetlink.h -diff --git a/include/linux/sctp.h b/include/uapi/linux/sctp.h -similarity index 100% -rename from include/linux/sctp.h -rename to include/uapi/linux/sctp.h -diff --git a/include/linux/seg6.h b/include/uapi/linux/seg6.h -similarity index 100% -rename from include/linux/seg6.h -rename to include/uapi/linux/seg6.h -diff --git a/include/linux/seg6_genl.h b/include/uapi/linux/seg6_genl.h -similarity index 100% -rename from include/linux/seg6_genl.h -rename to include/uapi/linux/seg6_genl.h -diff --git a/include/linux/seg6_hmac.h b/include/uapi/linux/seg6_hmac.h -similarity index 100% -rename from include/linux/seg6_hmac.h -rename to include/uapi/linux/seg6_hmac.h -diff --git a/include/linux/seg6_iptunnel.h b/include/uapi/linux/seg6_iptunnel.h -similarity index 100% -rename from include/linux/seg6_iptunnel.h -rename to include/uapi/linux/seg6_iptunnel.h -diff --git a/include/linux/seg6_local.h b/include/uapi/linux/seg6_local.h -similarity index 100% -rename from include/linux/seg6_local.h -rename to include/uapi/linux/seg6_local.h -diff --git a/include/linux/sock_diag.h b/include/uapi/linux/sock_diag.h -similarity index 100% -rename from include/linux/sock_diag.h -rename to include/uapi/linux/sock_diag.h -diff --git a/include/linux/socket.h b/include/uapi/linux/socket.h -similarity index 100% -rename from include/linux/socket.h -rename to include/uapi/linux/socket.h -diff --git a/include/linux/sockios.h b/include/uapi/linux/sockios.h -similarity index 100% -rename from include/linux/sockios.h -rename to include/uapi/linux/sockios.h -diff --git a/include/linux/stddef.h b/include/uapi/linux/stddef.h -similarity index 100% -rename from include/linux/stddef.h -rename to include/uapi/linux/stddef.h -diff --git a/include/linux/sysinfo.h b/include/uapi/linux/sysinfo.h -similarity index 100% -rename from include/linux/sysinfo.h -rename to include/uapi/linux/sysinfo.h -diff --git a/include/linux/tc_act/tc_bpf.h b/include/uapi/linux/tc_act/tc_bpf.h -similarity index 100% -rename from include/linux/tc_act/tc_bpf.h -rename to include/uapi/linux/tc_act/tc_bpf.h -diff --git a/include/linux/tc_act/tc_connmark.h b/include/uapi/linux/tc_act/tc_connmark.h -similarity index 100% -rename from include/linux/tc_act/tc_connmark.h -rename to include/uapi/linux/tc_act/tc_connmark.h -diff --git a/include/linux/tc_act/tc_csum.h b/include/uapi/linux/tc_act/tc_csum.h -similarity index 100% -rename from include/linux/tc_act/tc_csum.h -rename to include/uapi/linux/tc_act/tc_csum.h -diff --git a/include/linux/tc_act/tc_defact.h b/include/uapi/linux/tc_act/tc_defact.h -similarity index 100% -rename from include/linux/tc_act/tc_defact.h -rename to include/uapi/linux/tc_act/tc_defact.h -diff --git a/include/linux/tc_act/tc_gact.h b/include/uapi/linux/tc_act/tc_gact.h -similarity index 100% -rename from include/linux/tc_act/tc_gact.h -rename to include/uapi/linux/tc_act/tc_gact.h -diff --git a/include/linux/tc_act/tc_ife.h b/include/uapi/linux/tc_act/tc_ife.h -similarity index 100% -rename from include/linux/tc_act/tc_ife.h -rename to include/uapi/linux/tc_act/tc_ife.h -diff --git a/include/linux/tc_act/tc_ipt.h b/include/uapi/linux/tc_act/tc_ipt.h -similarity index 100% -rename from include/linux/tc_act/tc_ipt.h -rename to include/uapi/linux/tc_act/tc_ipt.h -diff --git a/include/linux/tc_act/tc_mirred.h b/include/uapi/linux/tc_act/tc_mirred.h -similarity index 100% -rename from include/linux/tc_act/tc_mirred.h -rename to include/uapi/linux/tc_act/tc_mirred.h -diff --git a/include/linux/tc_act/tc_nat.h b/include/uapi/linux/tc_act/tc_nat.h -similarity index 100% -rename from include/linux/tc_act/tc_nat.h -rename to include/uapi/linux/tc_act/tc_nat.h -diff --git a/include/linux/tc_act/tc_pedit.h b/include/uapi/linux/tc_act/tc_pedit.h -similarity index 100% -rename from include/linux/tc_act/tc_pedit.h -rename to include/uapi/linux/tc_act/tc_pedit.h -diff --git a/include/linux/tc_act/tc_sample.h b/include/uapi/linux/tc_act/tc_sample.h -similarity index 100% -rename from include/linux/tc_act/tc_sample.h -rename to include/uapi/linux/tc_act/tc_sample.h -diff --git a/include/linux/tc_act/tc_skbedit.h b/include/uapi/linux/tc_act/tc_skbedit.h -similarity index 100% -rename from include/linux/tc_act/tc_skbedit.h -rename to include/uapi/linux/tc_act/tc_skbedit.h -diff --git a/include/linux/tc_act/tc_skbmod.h b/include/uapi/linux/tc_act/tc_skbmod.h -similarity index 100% -rename from include/linux/tc_act/tc_skbmod.h -rename to include/uapi/linux/tc_act/tc_skbmod.h -diff --git a/include/linux/tc_act/tc_tunnel_key.h b/include/uapi/linux/tc_act/tc_tunnel_key.h -similarity index 100% -rename from include/linux/tc_act/tc_tunnel_key.h -rename to include/uapi/linux/tc_act/tc_tunnel_key.h -diff --git a/include/linux/tc_act/tc_vlan.h b/include/uapi/linux/tc_act/tc_vlan.h -similarity index 100% -rename from include/linux/tc_act/tc_vlan.h -rename to include/uapi/linux/tc_act/tc_vlan.h -diff --git a/include/linux/tc_ematch/tc_em_cmp.h b/include/uapi/linux/tc_ematch/tc_em_cmp.h -similarity index 100% -rename from include/linux/tc_ematch/tc_em_cmp.h -rename to include/uapi/linux/tc_ematch/tc_em_cmp.h -diff --git a/include/linux/tc_ematch/tc_em_meta.h b/include/uapi/linux/tc_ematch/tc_em_meta.h -similarity index 100% -rename from include/linux/tc_ematch/tc_em_meta.h -rename to include/uapi/linux/tc_ematch/tc_em_meta.h -diff --git a/include/linux/tc_ematch/tc_em_nbyte.h b/include/uapi/linux/tc_ematch/tc_em_nbyte.h -similarity index 100% -rename from include/linux/tc_ematch/tc_em_nbyte.h -rename to include/uapi/linux/tc_ematch/tc_em_nbyte.h -diff --git a/include/linux/tcp.h b/include/uapi/linux/tcp.h -similarity index 100% -rename from include/linux/tcp.h -rename to include/uapi/linux/tcp.h -diff --git a/include/linux/tcp_metrics.h b/include/uapi/linux/tcp_metrics.h -similarity index 100% -rename from include/linux/tcp_metrics.h -rename to include/uapi/linux/tcp_metrics.h -diff --git a/include/linux/tipc.h b/include/uapi/linux/tipc.h -similarity index 100% -rename from include/linux/tipc.h -rename to include/uapi/linux/tipc.h -diff --git a/include/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h -similarity index 100% -rename from include/linux/tipc_netlink.h -rename to include/uapi/linux/tipc_netlink.h -diff --git a/include/linux/types.h b/include/uapi/linux/types.h -similarity index 100% -rename from include/linux/types.h -rename to include/uapi/linux/types.h -diff --git a/include/linux/unix_diag.h b/include/uapi/linux/unix_diag.h -similarity index 100% -rename from include/linux/unix_diag.h -rename to include/uapi/linux/unix_diag.h -diff --git a/include/linux/veth.h b/include/uapi/linux/veth.h -similarity index 100% -rename from include/linux/veth.h -rename to include/uapi/linux/veth.h -diff --git a/include/linux/xfrm.h b/include/uapi/linux/xfrm.h -similarity index 100% -rename from include/linux/xfrm.h -rename to include/uapi/linux/xfrm.h --- -2.21.0 - diff --git a/SOURCES/0037-uapi-add-include-linux-vm_sockets_diag.h.patch b/SOURCES/0037-uapi-add-include-linux-vm_sockets_diag.h.patch deleted file mode 100644 index c713c95..0000000 --- a/SOURCES/0037-uapi-add-include-linux-vm_sockets_diag.h.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 74e00895532b878a902f9b0477e1b00d1be9df59 Mon Sep 17 00:00:00 2001 -From: Stefano Brivio -Date: Sun, 22 Oct 2017 21:44:25 +0200 -Subject: [PATCH] uapi: add include linux/vm_sockets_diag.h - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1472759 -Upstream Status: iproute2.git commit e9b0d82dfac2 - -commit e9b0d82dfac25912cf757945d9caf6fe2371f526 -Author: Stephen Hemminger -Date: Wed Oct 11 10:49:25 2017 -0700 - - uapi: add include linux/vm_sockets_diag.h - - Signed-off-by: Stephen Hemminger - -Signed-off-by: Stefano Brivio ---- - include/uapi/linux/vm_sockets_diag.h | 33 ++++++++++++++++++++++++++++ - 1 file changed, 33 insertions(+) - create mode 100644 include/uapi/linux/vm_sockets_diag.h - -diff --git a/include/uapi/linux/vm_sockets_diag.h b/include/uapi/linux/vm_sockets_diag.h -new file mode 100644 -index 0000000000000..a732a6f591b97 ---- /dev/null -+++ b/include/uapi/linux/vm_sockets_diag.h -@@ -0,0 +1,33 @@ -+/* AF_VSOCK sock_diag(7) interface for querying open sockets */ -+ -+#ifndef __VM_SOCKETS_DIAG_H__ -+#define __VM_SOCKETS_DIAG_H__ -+ -+#include -+ -+/* Request */ -+struct vsock_diag_req { -+ __u8 sdiag_family; /* must be AF_VSOCK */ -+ __u8 sdiag_protocol; /* must be 0 */ -+ __u16 pad; /* must be 0 */ -+ __u32 vdiag_states; /* query bitmap (e.g. 1 << TCP_LISTEN) */ -+ __u32 vdiag_ino; /* must be 0 (reserved) */ -+ __u32 vdiag_show; /* must be 0 (reserved) */ -+ __u32 vdiag_cookie[2]; -+}; -+ -+/* Response */ -+struct vsock_diag_msg { -+ __u8 vdiag_family; /* AF_VSOCK */ -+ __u8 vdiag_type; /* SOCK_STREAM or SOCK_DGRAM */ -+ __u8 vdiag_state; /* sk_state (e.g. TCP_LISTEN) */ -+ __u8 vdiag_shutdown; /* local RCV_SHUTDOWN | SEND_SHUTDOWN */ -+ __u32 vdiag_src_cid; -+ __u32 vdiag_src_port; -+ __u32 vdiag_dst_cid; -+ __u32 vdiag_dst_port; -+ __u32 vdiag_ino; -+ __u32 vdiag_cookie[2]; -+}; -+ -+#endif /* __VM_SOCKETS_DIAG_H__ */ --- -2.21.0 - diff --git a/SOURCES/0038-ss-allow-AF_FAMILY-constants-32.patch b/SOURCES/0038-ss-allow-AF_FAMILY-constants-32.patch deleted file mode 100644 index e039c2d..0000000 --- a/SOURCES/0038-ss-allow-AF_FAMILY-constants-32.patch +++ /dev/null @@ -1,213 +0,0 @@ -From f59533eb3cb188a23456444aeb19ac3634eddd8c Mon Sep 17 00:00:00 2001 -From: Stefano Brivio -Date: Sun, 22 Oct 2017 21:44:26 +0200 -Subject: [PATCH] ss: allow AF_FAMILY constants >32 - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1472759 -Upstream Status: iproute2.git commit b338a3e7e7d9 - -commit b338a3e7e7d95c9d46de9748604da06287664033 -Author: Stefan Hajnoczi -Date: Fri Oct 6 11:48:39 2017 -0400 - - ss: allow AF_FAMILY constants >32 - - Linux has more than 32 address families defined in . Use - a 64-bit type so all of them can be represented in the filter->families - bitmask. - - It's easy to introduce bugs when using (1 << AF_FAMILY) because the - value is 32-bit. This can produce incorrect results from bitmask - operations so introduce the FAMILY_MASK() macro to eliminate these bugs. - - Signed-off-by: Stefan Hajnoczi - -Signed-off-by: Stefano Brivio ---- - misc/ss.c | 54 ++++++++++++++++++++++++++++-------------------------- - 1 file changed, 28 insertions(+), 26 deletions(-) - -diff --git a/misc/ss.c b/misc/ss.c -index d3fb9a751b3ab..0d6452777f7b6 100644 ---- a/misc/ss.c -+++ b/misc/ss.c -@@ -170,55 +170,57 @@ enum { - struct filter { - int dbs; - int states; -- int families; -+ uint64_t families; - struct ssfilter *f; - bool kill; - }; - -+#define FAMILY_MASK(family) ((uint64_t)1 << (family)) -+ - static const struct filter default_dbs[MAX_DB] = { - [TCP_DB] = { - .states = SS_CONN, -- .families = (1 << AF_INET) | (1 << AF_INET6), -+ .families = FAMILY_MASK(AF_INET) | FAMILY_MASK(AF_INET6), - }, - [DCCP_DB] = { - .states = SS_CONN, -- .families = (1 << AF_INET) | (1 << AF_INET6), -+ .families = FAMILY_MASK(AF_INET) | FAMILY_MASK(AF_INET6), - }, - [UDP_DB] = { - .states = (1 << SS_ESTABLISHED), -- .families = (1 << AF_INET) | (1 << AF_INET6), -+ .families = FAMILY_MASK(AF_INET) | FAMILY_MASK(AF_INET6), - }, - [RAW_DB] = { - .states = (1 << SS_ESTABLISHED), -- .families = (1 << AF_INET) | (1 << AF_INET6), -+ .families = FAMILY_MASK(AF_INET) | FAMILY_MASK(AF_INET6), - }, - [UNIX_DG_DB] = { - .states = (1 << SS_CLOSE), -- .families = (1 << AF_UNIX), -+ .families = FAMILY_MASK(AF_UNIX), - }, - [UNIX_ST_DB] = { - .states = SS_CONN, -- .families = (1 << AF_UNIX), -+ .families = FAMILY_MASK(AF_UNIX), - }, - [UNIX_SQ_DB] = { - .states = SS_CONN, -- .families = (1 << AF_UNIX), -+ .families = FAMILY_MASK(AF_UNIX), - }, - [PACKET_DG_DB] = { - .states = (1 << SS_CLOSE), -- .families = (1 << AF_PACKET), -+ .families = FAMILY_MASK(AF_PACKET), - }, - [PACKET_R_DB] = { - .states = (1 << SS_CLOSE), -- .families = (1 << AF_PACKET), -+ .families = FAMILY_MASK(AF_PACKET), - }, - [NETLINK_DB] = { - .states = (1 << SS_CLOSE), -- .families = (1 << AF_NETLINK), -+ .families = FAMILY_MASK(AF_NETLINK), - }, - [SCTP_DB] = { - .states = SS_CONN, -- .families = (1 << AF_INET) | (1 << AF_INET6), -+ .families = FAMILY_MASK(AF_INET) | FAMILY_MASK(AF_INET6), - }, - }; - -@@ -258,14 +260,14 @@ static void filter_db_set(struct filter *f, int db) - static void filter_af_set(struct filter *f, int af) - { - f->states |= default_afs[af].states; -- f->families |= 1 << af; -+ f->families |= FAMILY_MASK(af); - do_default = 0; - preferred_family = af; - } - - static int filter_af_get(struct filter *f, int af) - { -- return f->families & (1 << af); -+ return !!(f->families & FAMILY_MASK(af)); - } - - static void filter_default_dbs(struct filter *f) -@@ -302,7 +304,7 @@ static void filter_merge_defaults(struct filter *f) - f->families |= default_dbs[db].families; - } - for (af = 0; af < AF_MAX; af++) { -- if (!(f->families & (1 << af))) -+ if (!(f->families & FAMILY_MASK(af))) - continue; - - if (!(default_afs[af].dbs & f->dbs)) -@@ -2599,7 +2601,7 @@ static int show_one_inet_sock(const struct sockaddr_nl *addr, - struct inet_diag_msg *r = NLMSG_DATA(h); - struct sockstat s = {}; - -- if (!(diag_arg->f->families & (1 << r->idiag_family))) -+ if (!(diag_arg->f->families & FAMILY_MASK(r->idiag_family))) - return 0; - - parse_diag_msg(h, &s); -@@ -2785,7 +2787,7 @@ static int tcp_show(struct filter *f) - return -1; - } - -- if (f->families & (1<families & FAMILY_MASK(AF_INET)) { - if ((fp = net_tcp_open()) == NULL) - goto outerr; - -@@ -2795,7 +2797,7 @@ static int tcp_show(struct filter *f) - fclose(fp); - } - -- if ((f->families & (1<families & FAMILY_MASK(AF_INET6)) && - (fp = net_tcp6_open()) != NULL) { - setbuffer(fp, buf, bufsize); - if (generic_record_read(fp, tcp_show_line, f, AF_INET6)) -@@ -2894,7 +2896,7 @@ static int udp_show(struct filter *f) - && inet_show_netlink(f, NULL, IPPROTO_UDP) == 0) - return 0; - -- if (f->families&(1<families&FAMILY_MASK(AF_INET)) { - if ((fp = net_udp_open()) == NULL) - goto outerr; - if (generic_record_read(fp, dgram_show_line, f, AF_INET)) -@@ -2902,7 +2904,7 @@ static int udp_show(struct filter *f) - fclose(fp); - } - -- if ((f->families&(1<families&FAMILY_MASK(AF_INET6)) && - (fp = net_udp6_open()) != NULL) { - if (generic_record_read(fp, dgram_show_line, f, AF_INET6)) - goto outerr; -@@ -2934,7 +2936,7 @@ static int raw_show(struct filter *f) - inet_show_netlink(f, NULL, IPPROTO_RAW) == 0) - return 0; - -- if (f->families&(1<families&FAMILY_MASK(AF_INET)) { - if ((fp = net_raw_open()) == NULL) - goto outerr; - if (generic_record_read(fp, dgram_show_line, f, AF_INET)) -@@ -2942,7 +2944,7 @@ static int raw_show(struct filter *f) - fclose(fp); - } - -- if ((f->families&(1<families&FAMILY_MASK(AF_INET6)) && - (fp = net_raw6_open()) != NULL) { - if (generic_record_read(fp, dgram_show_line, f, AF_INET6)) - goto outerr; -@@ -3682,13 +3684,13 @@ static int handle_follow_request(struct filter *f) - int groups = 0; - struct rtnl_handle rth; - -- if (f->families & (1 << AF_INET) && f->dbs & (1 << TCP_DB)) -+ if (f->families & FAMILY_MASK(AF_INET) && f->dbs & (1 << TCP_DB)) - groups |= 1 << (SKNLGRP_INET_TCP_DESTROY - 1); -- if (f->families & (1 << AF_INET) && f->dbs & (1 << UDP_DB)) -+ if (f->families & FAMILY_MASK(AF_INET) && f->dbs & (1 << UDP_DB)) - groups |= 1 << (SKNLGRP_INET_UDP_DESTROY - 1); -- if (f->families & (1 << AF_INET6) && f->dbs & (1 << TCP_DB)) -+ if (f->families & FAMILY_MASK(AF_INET6) && f->dbs & (1 << TCP_DB)) - groups |= 1 << (SKNLGRP_INET6_TCP_DESTROY - 1); -- if (f->families & (1 << AF_INET6) && f->dbs & (1 << UDP_DB)) -+ if (f->families & FAMILY_MASK(AF_INET6) && f->dbs & (1 << UDP_DB)) - groups |= 1 << (SKNLGRP_INET6_UDP_DESTROY - 1); - - if (groups == 0) --- -2.21.0 - diff --git a/SOURCES/0039-ss-add-AF_VSOCK-support.patch b/SOURCES/0039-ss-add-AF_VSOCK-support.patch deleted file mode 100644 index 8d7c70d..0000000 --- a/SOURCES/0039-ss-add-AF_VSOCK-support.patch +++ /dev/null @@ -1,398 +0,0 @@ -From fe898bd10be2bc527f81421f06afff77e8ba42eb Mon Sep 17 00:00:00 2001 -From: Stefano Brivio -Date: Sun, 22 Oct 2017 21:44:27 +0200 -Subject: [PATCH] ss: add AF_VSOCK support - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1472759 -Upstream Status: iproute2.git commit c759116a0b2b - -commit c759116a0b2b6da8df9687b0a40ac69050132c77 -Author: Stefan Hajnoczi -Date: Fri Oct 6 11:48:41 2017 -0400 - - ss: add AF_VSOCK support - - The AF_VSOCK address family is a host<->guest communications channel - supported by VMware, KVM, and Hyper-V. Initial VMware support was - released in Linux 3.9 in 2013 and transports for other hypervisors were - added later. - - AF_VSOCK addresses are tuples. The 32-bit cid - integer is comparable to an IP address. AF_VSOCK ports work like - TCP/UDP ports. - - Both SOCK_STREAM and SOCK_DGRAM socket types are available. - - This patch adds AF_VSOCK support to ss(8) so that sockets can be - observed. - - Signed-off-by: Stefan Hajnoczi - -Signed-off-by: Stefano Brivio ---- - man/man8/ss.8 | 8 ++- - misc/ss.c | 184 +++++++++++++++++++++++++++++++++++++++++++++++++- - 2 files changed, 188 insertions(+), 4 deletions(-) - -diff --git a/man/man8/ss.8 b/man/man8/ss.8 -index 81de69de8042e..4323eee3c8687 100644 ---- a/man/man8/ss.8 -+++ b/man/man8/ss.8 -@@ -125,14 +125,18 @@ Display Unix domain sockets (alias for -f unix). - .B \-S, \-\-sctp - Display SCTP sockets. - .TP -+.B \-\-vsock -+Display vsock sockets (alias for -f vsock). -+.TP - .B \-f FAMILY, \-\-family=FAMILY - Display sockets of type FAMILY. --Currently the following families are supported: unix, inet, inet6, link, netlink. -+Currently the following families are supported: unix, inet, inet6, link, netlink, vsock. - .TP - .B \-A QUERY, \-\-query=QUERY, \-\-socket=QUERY - 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. -+unix_stream, unix_seqpacket, packet_raw, packet_dgram, dccp, sctp, -+vsock_stream, vsock_dgram. - .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. -diff --git a/misc/ss.c b/misc/ss.c -index 0d6452777f7b6..e92266539e6b5 100644 ---- a/misc/ss.c -+++ b/misc/ss.c -@@ -44,6 +44,7 @@ - #include - #include - #include -+#include - - #define MAGIC_SEQ 123456 - -@@ -126,6 +127,8 @@ enum { - PACKET_R_DB, - NETLINK_DB, - SCTP_DB, -+ VSOCK_ST_DB, -+ VSOCK_DG_DB, - MAX_DB - }; - -@@ -134,6 +137,7 @@ enum { - #define ALL_DB ((1<type); -+ break; - default: - sock_name = "unknown"; - } -@@ -1139,6 +1172,8 @@ static int run_ssfilter(struct ssfilter *f, struct sockstat *s) - return s->lport == 0 && s->local.data[0] == 0; - if (s->local.family == AF_NETLINK) - return s->lport < 0; -+ if (s->local.family == AF_VSOCK) -+ return s->lport > 1023; - - return is_ephemeral(s->lport); - } -@@ -1515,6 +1550,15 @@ void *parse_devcond(char *name) - return res; - } - -+static void vsock_set_inet_prefix(inet_prefix *a, __u32 cid) -+{ -+ *a = (inet_prefix){ -+ .bytelen = sizeof(cid), -+ .family = AF_VSOCK, -+ }; -+ memcpy(a->data, &cid, sizeof(cid)); -+} -+ - void *parse_hostcond(char *addr, bool is_port) - { - char *port = NULL; -@@ -1589,6 +1633,37 @@ void *parse_hostcond(char *addr, bool is_port) - goto out; - } - -+ if (fam == AF_VSOCK || strncmp(addr, "vsock:", 6) == 0) { -+ __u32 cid = ~(__u32)0; -+ -+ a.addr.family = AF_VSOCK; -+ if (strncmp(addr, "vsock:", 6) == 0) -+ addr += 6; -+ -+ if (is_port) -+ port = addr; -+ else { -+ port = strchr(addr, ':'); -+ if (port) { -+ *port = '\0'; -+ port++; -+ } -+ } -+ -+ if (port && strcmp(port, "*") && -+ get_u32((__u32 *)&a.port, port, 0)) -+ return NULL; -+ -+ if (addr[0] && strcmp(addr, "*")) { -+ a.addr.bitlen = 32; -+ if (get_u32(&cid, addr, 0)) -+ return NULL; -+ } -+ vsock_set_inet_prefix(&a.addr, cid); -+ fam = AF_VSOCK; -+ goto out; -+ } -+ - if (fam == AF_INET || !strncmp(addr, "inet:", 5)) { - fam = AF_INET; - if (!strncmp(addr, "inet:", 5)) -@@ -3653,6 +3728,88 @@ static int netlink_show(struct filter *f) - return 0; - } - -+static bool vsock_type_skip(struct sockstat *s, struct filter *f) -+{ -+ if (s->type == SOCK_STREAM && !(f->dbs & (1 << VSOCK_ST_DB))) -+ return true; -+ if (s->type == SOCK_DGRAM && !(f->dbs & (1 << VSOCK_DG_DB))) -+ return true; -+ return false; -+} -+ -+static void vsock_addr_print(inet_prefix *a, __u32 port) -+{ -+ char cid_str[sizeof("4294967295")]; -+ char port_str[sizeof("4294967295")]; -+ __u32 cid; -+ -+ memcpy(&cid, a->data, sizeof(cid)); -+ -+ if (cid == ~(__u32)0) -+ snprintf(cid_str, sizeof(cid_str), "*"); -+ else -+ snprintf(cid_str, sizeof(cid_str), "%u", cid); -+ -+ if (port == ~(__u32)0) -+ snprintf(port_str, sizeof(port_str), "*"); -+ else -+ snprintf(port_str, sizeof(port_str), "%u", port); -+ -+ sock_addr_print(cid_str, ":", port_str, NULL); -+} -+ -+static void vsock_stats_print(struct sockstat *s, struct filter *f) -+{ -+ sock_state_print(s); -+ -+ vsock_addr_print(&s->local, s->lport); -+ vsock_addr_print(&s->remote, s->rport); -+ -+ proc_ctx_print(s); -+ -+ printf("\n"); -+} -+ -+static int vsock_show_sock(const struct sockaddr_nl *addr, -+ struct nlmsghdr *nlh, void *arg) -+{ -+ struct filter *f = (struct filter *)arg; -+ struct vsock_diag_msg *r = NLMSG_DATA(nlh); -+ struct sockstat stat = { -+ .type = r->vdiag_type, -+ .lport = r->vdiag_src_port, -+ .rport = r->vdiag_dst_port, -+ .state = r->vdiag_state, -+ .ino = r->vdiag_ino, -+ }; -+ -+ vsock_set_inet_prefix(&stat.local, r->vdiag_src_cid); -+ vsock_set_inet_prefix(&stat.remote, r->vdiag_dst_cid); -+ -+ if (vsock_type_skip(&stat, f)) -+ return 0; -+ -+ if (f->f && run_ssfilter(f->f, &stat) == 0) -+ return 0; -+ -+ vsock_stats_print(&stat, f); -+ -+ return 0; -+} -+ -+static int vsock_show(struct filter *f) -+{ -+ DIAG_REQUEST(req, struct vsock_diag_req r); -+ -+ if (!filter_af_get(f, AF_VSOCK)) -+ return 0; -+ -+ req.r.sdiag_family = AF_VSOCK; -+ req.r.vdiag_states = f->states; -+ -+ return handle_netlink_request(f, &req.nlh, sizeof(req), vsock_show_sock); -+} -+ - struct sock_diag_msg { - __u8 sdiag_family; - }; -@@ -3673,6 +3830,8 @@ static int generic_show_sock(const struct sockaddr_nl *addr, - return packet_show_sock(addr, nlh, arg); - case AF_NETLINK: - return netlink_show_sock(addr, nlh, arg); -+ case AF_VSOCK: -+ return vsock_show_sock(addr, nlh, arg); - default: - return -1; - } -@@ -3900,14 +4059,15 @@ static void _usage(FILE *dest) - " -d, --dccp display only DCCP sockets\n" - " -w, --raw display only RAW sockets\n" - " -x, --unix display only Unix domain sockets\n" -+" --vsock display only vsock sockets\n" - " -f, --family=FAMILY display sockets of type FAMILY\n" --" FAMILY := {inet|inet6|link|unix|netlink|help}\n" -+" FAMILY := {inet|inet6|link|unix|netlink|vsock|help}\n" - "\n" - " -K, --kill forcibly close sockets, display what was closed\n" - " -H, --no-header Suppress header line\n" - "\n" - " -A, --query=QUERY, --socket=QUERY\n" --" QUERY := {all|inet|tcp|udp|raw|unix|unix_dgram|unix_stream|unix_seqpacket|packet|netlink}[,QUERY]\n" -+" QUERY := {all|inet|tcp|udp|raw|unix|unix_dgram|unix_stream|unix_seqpacket|packet|netlink|vsock_stream|vsock_dgram}[,QUERY]\n" - "\n" - " -D, --diag=FILE Dump raw information about TCP sockets to FILE\n" - " -F, --filter=FILE read filter information from FILE\n" -@@ -3980,6 +4140,9 @@ static int scan_state(const char *state) - exit(-1); - } - -+/* Values 'v' and 'V' are already used so a non-character is used */ -+#define OPT_VSOCK 256 -+ - static const struct option long_opts[] = { - { "numeric", 0, 0, 'n' }, - { "resolve", 0, 0, 'r' }, -@@ -3996,6 +4159,7 @@ static const struct option long_opts[] = { - { "udp", 0, 0, 'u' }, - { "raw", 0, 0, 'w' }, - { "unix", 0, 0, 'x' }, -+ { "vsock", 0, 0, OPT_VSOCK }, - { "all", 0, 0, 'a' }, - { "listening", 0, 0, 'l' }, - { "ipv4", 0, 0, '4' }, -@@ -4081,6 +4245,9 @@ int main(int argc, char *argv[]) - case 'x': - filter_af_set(¤t_filter, AF_UNIX); - break; -+ case OPT_VSOCK: -+ filter_af_set(¤t_filter, AF_VSOCK); -+ break; - case 'a': - state_filter = SS_ALL; - break; -@@ -4107,6 +4274,8 @@ int main(int argc, char *argv[]) - filter_af_set(¤t_filter, AF_UNIX); - else if (strcmp(optarg, "netlink") == 0) - filter_af_set(¤t_filter, AF_NETLINK); -+ else if (strcmp(optarg, "vsock") == 0) -+ filter_af_set(¤t_filter, AF_VSOCK); - else if (strcmp(optarg, "help") == 0) - help(); - else { -@@ -4172,6 +4341,15 @@ int main(int argc, char *argv[]) - filter_db_set(¤t_filter, PACKET_DG_DB); - } else if (strcmp(p, "netlink") == 0) { - filter_db_set(¤t_filter, NETLINK_DB); -+ } else if (strcmp(p, "vsock") == 0) { -+ filter_db_set(¤t_filter, VSOCK_ST_DB); -+ filter_db_set(¤t_filter, VSOCK_DG_DB); -+ } else if (strcmp(p, "vsock_stream") == 0 || -+ strcmp(p, "v_str") == 0) { -+ filter_db_set(¤t_filter, VSOCK_ST_DB); -+ } else if (strcmp(p, "vsock_dgram") == 0 || -+ strcmp(p, "v_dgr") == 0) { -+ filter_db_set(¤t_filter, VSOCK_DG_DB); - } else { - fprintf(stderr, "ss: \"%s\" is illegal socket table id\n", p); - usage(); -@@ -4387,6 +4565,8 @@ int main(int argc, char *argv[]) - dccp_show(¤t_filter); - if (current_filter.dbs & (1< -Date: Wed, 29 Nov 2017 18:36:17 +0100 -Subject: [PATCH] link_gre6: Detect invalid encaplimit values - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1459600 -Upstream Status: iproute2.git commit 56708ae7c9535 - -commit 56708ae7c9535859223c5b68097b35bf0fae677c -Author: Phil Sutter -Date: Tue Nov 28 16:49:58 2017 +0100 - - link_gre6: Detect invalid encaplimit values - - Looks like a typo: get_u8() returns 0 on success and -1 on error, so the - error checking here was ineffective. - - Fixes: a11b7b71a6eba ("link_gre6: really support encaplimit option") - Signed-off-by: Phil Sutter ---- - ip/link_gre6.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ip/link_gre6.c b/ip/link_gre6.c -index 932f9ee96124d..a9d18ee954641 100644 ---- a/ip/link_gre6.c -+++ b/ip/link_gre6.c -@@ -351,7 +351,7 @@ get_failed: - } else { - __u8 uval; - -- if (get_u8(&uval, *argv, 0) < -1) -+ if (get_u8(&uval, *argv, 0)) - invarg("invalid ELIM", *argv); - encap_limit = uval; - flags &= ~IP6_TNL_F_IGN_ENCAP_LIMIT; --- -2.21.0 - diff --git a/SOURCES/0041-man-tc-csum.8-Fix-inconsistency-in-example-descripti.patch b/SOURCES/0041-man-tc-csum.8-Fix-inconsistency-in-example-descripti.patch deleted file mode 100644 index 430f5d7..0000000 --- a/SOURCES/0041-man-tc-csum.8-Fix-inconsistency-in-example-descripti.patch +++ /dev/null @@ -1,42 +0,0 @@ -From f08752c12351c79145e3a6caf346e3d971370a9c Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Wed, 6 Dec 2017 13:21:16 +0100 -Subject: [PATCH] man: tc-csum.8: Fix inconsistency in example description - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1417162 -Upstream Status: iproute2.git commit 6bf156415a588 - -commit 6bf156415a588fa1c975be9a18a1579f63a936a2 -Author: Phil Sutter -Date: Wed Nov 29 18:34:09 2017 +0100 - - man: tc-csum.8: Fix inconsistency in example description - - Commit 6bbe5e6290db5 ("man: tc-csum.8: Fix example") changed both source - and destination IP addresses in example code but missed to update the - example's description accordingly. - - Fixes: 6bbe5e6290db5 ("man: tc-csum.8: Fix example") - Signed-off-by: Phil Sutter ---- - man/man8/tc-csum.8 | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/man/man8/tc-csum.8 b/man/man8/tc-csum.8 -index 409ab71791cce..65724b88d0b68 100644 ---- a/man/man8/tc-csum.8 -+++ b/man/man8/tc-csum.8 -@@ -53,8 +53,8 @@ SCTP header - .B SWEETS - These are merely syntactic sugar and ignored internally. - .SH EXAMPLES --The following performs stateless NAT for incoming packets from 192.168.1.100 to --new destination 18.52.86.120 (0x12345678 in hex). Assuming these are UDP -+The following performs stateless NAT for incoming packets from 192.0.2.100 to -+new destination 198.51.100.1. Assuming these are UDP - packets, both IP and UDP checksums have to be recalculated: - - .RS --- -2.21.0 - diff --git a/SOURCES/0042-tc-fix-command-tc-actions-del-hang-issue.patch b/SOURCES/0042-tc-fix-command-tc-actions-del-hang-issue.patch deleted file mode 100644 index e8782ef..0000000 --- a/SOURCES/0042-tc-fix-command-tc-actions-del-hang-issue.patch +++ /dev/null @@ -1,42 +0,0 @@ -From dbc597c9d1e0e65cc9d989d8057f9a083c2f5779 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Fri, 15 Dec 2017 16:13:46 +0100 -Subject: [PATCH] tc: fix command "tc actions del" hang issue - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1526394 -Upstream Status: iproute2.git commit 83cf5bc73b858 - -commit 83cf5bc73b858608d59c3c6126a9f37e793e15dd -Author: Chris Mi -Date: Thu Dec 14 18:09:00 2017 +0900 - - tc: fix command "tc actions del" hang issue - - If command is RTM_DELACTION, a non-NULL pointer is passed to rtnl_talk(). - Then flag NLM_F_ACK is not set on n->nlmsg_flags and netlink_ack() will - not be called. Command tc will wait for the reply for ever. - - Fixes: 86bf43c7c2fd ("lib/libnetlink: update rtnl_talk to support malloc buff at run time") - Reviewed-by: Jiri Pirko - Signed-off-by: Chris Mi - Signed-off-by: Stephen Hemminger ---- - tc/m_action.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tc/m_action.c b/tc/m_action.c -index 90b2a11e5d9e8..7cfd9e0af145f 100644 ---- a/tc/m_action.c -+++ b/tc/m_action.c -@@ -507,7 +507,7 @@ static int tc_action_gd(int cmd, unsigned int flags, int *argc_p, char ***argv_p - - req.n.nlmsg_seq = rth.dump = ++rth.seq; - -- if (rtnl_talk(&rth, &req.n, &ans) < 0) { -+ if (rtnl_talk(&rth, &req.n, cmd == RTM_DELACTION ? NULL : &ans) < 0) { - fprintf(stderr, "We have an error talking to the kernel\n"); - return 1; - } --- -2.21.0 - diff --git a/SOURCES/0043-ip-link-Fix-use-after-free-in-nl_get_ll_addr_len.patch b/SOURCES/0043-ip-link-Fix-use-after-free-in-nl_get_ll_addr_len.patch deleted file mode 100644 index 6c5497d..0000000 --- a/SOURCES/0043-ip-link-Fix-use-after-free-in-nl_get_ll_addr_len.patch +++ /dev/null @@ -1,43 +0,0 @@ -From dcafeb49b2538cc7118cb64f62c685980c106b48 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Tue, 6 Mar 2018 11:35:28 +0100 -Subject: [PATCH] ip-link: Fix use after free in nl_get_ll_addr_len() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1550097 -Upstream Status: iproute2.git commit 06867c3719587 - -commit 06867c371958773e39b4ccac07cfe3e2fff2ea55 -Author: Phil Sutter -Date: Thu Mar 1 10:35:12 2018 +0100 - - ip-link: Fix use after free in nl_get_ll_addr_len() - - Immediately after freeing the buffer returned from rtnl_talk(), it is - accessed again via pointer in struct rtattr array. This leads to some - builds not allowing to set an interface's MAC address because the - expected length value is garbage. - - Fixes: 86bf43c7c2fdc ("lib/libnetlink: update rtnl_talk to support malloc buff at run time") - Signed-off-by: Phil Sutter ---- - ip/iplink.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/ip/iplink.c b/ip/iplink.c -index 193997cad2a35..db5b2c9645ba8 100644 ---- a/ip/iplink.c -+++ b/ip/iplink.c -@@ -268,8 +268,9 @@ static int nl_get_ll_addr_len(unsigned int dev_index) - return -1; - } - -+ len = RTA_PAYLOAD(tb[IFLA_ADDRESS]); - free(answer); -- return RTA_PAYLOAD(tb[IFLA_ADDRESS]); -+ return len; - } - - static void iplink_parse_vf_vlan_info(int vf, int *argcp, char ***argvp, --- -2.21.0 - diff --git a/SOURCES/0044-tc-m_tunnel_key-reformat-the-usage-text.patch b/SOURCES/0044-tc-m_tunnel_key-reformat-the-usage-text.patch deleted file mode 100644 index 34b2c08..0000000 --- a/SOURCES/0044-tc-m_tunnel_key-reformat-the-usage-text.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 04ecd76fa66c7745529b3b007ad04a307d2b7518 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Wed, 6 Feb 2019 14:31:10 +0100 -Subject: [PATCH] tc: m_tunnel_key: reformat the usage text - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1658506 -Upstream Status: iproute2.git commit 50907a8245ea3 - -commit 50907a8245ea37875fb877d6f21f51a1f247b167 -Author: Jiri Benc -Date: Wed Jun 14 21:29:49 2017 +0200 - - tc: m_tunnel_key: reformat the usage text - - Adding new tunnel key fields would cause the usage line overflow 80 chars. - Make the usage text similar to other commands. - - Signed-off-by: Jiri Benc ---- - tc/m_tunnel_key.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/tc/m_tunnel_key.c b/tc/m_tunnel_key.c -index 3ceec1cba616b..5222c25977e26 100644 ---- a/tc/m_tunnel_key.c -+++ b/tc/m_tunnel_key.c -@@ -22,7 +22,13 @@ - static void explain(void) - { - fprintf(stderr, "Usage: tunnel_key unset\n"); -- fprintf(stderr, " tunnel_key set id TUNNELID src_ip IP dst_ip IP dst_port UDP_PORT\n"); -+ fprintf(stderr, " tunnel_key set \n"); -+ fprintf(stderr, -+ "Where TUNNEL_KEY is a combination of:\n" -+ "id (mandatory)\n" -+ "src_ip (mandatory)\n" -+ "dst_ip (mandatory)\n" -+ "dst_port \n"); - } - - static void usage(void) --- -2.21.0 - diff --git a/SOURCES/0045-tc-m_tunnel_key-Allow-key-less-tunnels.patch b/SOURCES/0045-tc-m_tunnel_key-Allow-key-less-tunnels.patch deleted file mode 100644 index 1a617b1..0000000 --- a/SOURCES/0045-tc-m_tunnel_key-Allow-key-less-tunnels.patch +++ /dev/null @@ -1,88 +0,0 @@ -From f43f500151a6261e24d89674b0a44f2d84c9e207 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Wed, 6 Feb 2019 14:21:09 +0100 -Subject: [PATCH] tc: m_tunnel_key: Allow key-less tunnels - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1658506 -Upstream Status: iproute2.git commit dc0332b1e8e4a -Conflicts: Context change due to missing commit 59eb271d1d259 - ("tc: m_tunnel_key: add csum/nocsum option"). - -commit dc0332b1e8e4ab8771562128993d512986f856e2 -Author: Adi Nissim -Date: Thu Jan 10 15:03:50 2019 +0200 - - tc: m_tunnel_key: Allow key-less tunnels - - Change the id parameter of the tunnel_key set action from mandatory to - optional. - - Some tunneling protocols (e.g. GRE) specify the id as an optional field. - - Signed-off-by: Adi Nissim - Signed-off-by: Stephen Hemminger ---- - man/man8/tc-tunnel_key.8 | 4 ++-- - tc/m_tunnel_key.c | 6 ++---- - 2 files changed, 4 insertions(+), 6 deletions(-) - -diff --git a/man/man8/tc-tunnel_key.8 b/man/man8/tc-tunnel_key.8 -index 2e569730abbb3..52fa585a75c8f 100644 ---- a/man/man8/tc-tunnel_key.8 -+++ b/man/man8/tc-tunnel_key.8 -@@ -56,12 +56,12 @@ above). - .TP - .B set - Set tunnel metadata to be used by the IP tunnel device. Requires --.B id --, - .B src_ip - and - .B dst_ip - options. -+.B id -+, - .B dst_port - is optional. - .RS -diff --git a/tc/m_tunnel_key.c b/tc/m_tunnel_key.c -index 5222c25977e26..acbcfc15cda76 100644 ---- a/tc/m_tunnel_key.c -+++ b/tc/m_tunnel_key.c -@@ -25,7 +25,7 @@ static void explain(void) - fprintf(stderr, " tunnel_key set \n"); - fprintf(stderr, - "Where TUNNEL_KEY is a combination of:\n" -- "id (mandatory)\n" -+ "id \n" - "src_ip (mandatory)\n" - "dst_ip (mandatory)\n" - "dst_port \n"); -@@ -91,7 +91,6 @@ static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p, - int ret; - int has_src_ip = 0; - int has_dst_ip = 0; -- int has_key_id = 0; - - if (matches(*argv, "tunnel_key") != 0) - return -1; -@@ -147,7 +146,6 @@ static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p, - fprintf(stderr, "Illegal \"id\"\n"); - return -1; - } -- has_key_id = 1; - } else if (matches(*argv, "dst_port") == 0) { - NEXT_ARG(); - ret = tunnel_key_parse_dst_port(*argv, -@@ -180,7 +178,7 @@ static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p, - } - - if (action == TCA_TUNNEL_KEY_ACT_SET && -- (!has_src_ip || !has_dst_ip || !has_key_id)) { -+ (!has_src_ip || !has_dst_ip)) { - fprintf(stderr, "set needs tunnel_key parameters\n"); - explain(); - return -1; --- -2.21.0 - diff --git a/SOURCES/0046-tc-include-stdint.h-explicitly-for-UINT16_MAX.patch b/SOURCES/0046-tc-include-stdint.h-explicitly-for-UINT16_MAX.patch deleted file mode 100644 index 7f433a1..0000000 --- a/SOURCES/0046-tc-include-stdint.h-explicitly-for-UINT16_MAX.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 7a77e4df94a48c35f9a4bf1fc3f8e9d1f72a77b7 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Wed, 6 Feb 2019 14:50:24 +0100 -Subject: [PATCH] tc: include stdint.h explicitly for UINT16_MAX - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1641909 -Upstream Status: iproute2.git commit ae717baf15fb4 - -commit ae717baf15fb4d30749ada3948d9445892bac239 -Author: Khem Raj -Date: Sat May 20 14:28:46 2017 -0700 - - tc: include stdint.h explicitly for UINT16_MAX - - Fixes - | tc_core.c:190:29: error: 'UINT16_MAX' undeclared (first use in this function); did you mean '__INT16_MAX__'? - | if ((sz >> s->size_log) > UINT16_MAX) { - | ^~~~~~~~~~ - - Signed-off-by: Khem Raj ---- - tc/tc_core.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/tc/tc_core.c b/tc/tc_core.c -index 7bbe0d733fc75..821b741be17cf 100644 ---- a/tc/tc_core.c -+++ b/tc/tc_core.c -@@ -12,6 +12,7 @@ - - #include - #include -+#include - #include - #include - #include --- -2.21.0 - diff --git a/SOURCES/0047-Update-kernel-headers.patch b/SOURCES/0047-Update-kernel-headers.patch deleted file mode 100644 index 956c9d7..0000000 --- a/SOURCES/0047-Update-kernel-headers.patch +++ /dev/null @@ -1,5651 +0,0 @@ -From 007c76937f34c11c4c827373f081a9c4eebf1fc3 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Wed, 6 Feb 2019 14:50:24 +0100 -Subject: [PATCH] Update kernel headers - -This updates kernel headers to upstream commit -761ec9e29ff867452057f59dc6ca430688b409ea. Update was done via: - -| git checkout 761ec9e29ff867452057f59dc6ca430688b409ea -- include/uapi - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1641909 -Upstream Status: RHEL-only ---- - include/uapi/linux/atm.h | 1 + - include/uapi/linux/atmapi.h | 1 + - include/uapi/linux/atmarp.h | 1 + - include/uapi/linux/atmdev.h | 1 + - include/uapi/linux/atmioc.h | 1 + - include/uapi/linux/atmsap.h | 1 + - include/uapi/linux/bpf.h | 2481 ++++++++++++++--- - include/uapi/linux/bpf_common.h | 8 +- - include/uapi/linux/btf.h | 113 + - include/uapi/linux/can.h | 1 + - include/uapi/linux/can/netlink.h | 2 + - include/uapi/linux/can/vxcan.h | 1 + - include/uapi/linux/devlink.h | 82 + - include/uapi/linux/elf-em.h | 1 + - include/uapi/linux/fib_rules.h | 12 +- - include/uapi/linux/filter.h | 1 + - include/uapi/linux/fou.h | 1 + - include/uapi/linux/gen_stats.h | 1 + - include/uapi/linux/genetlink.h | 1 + - include/uapi/linux/hdlc/ioctl.h | 1 + - include/uapi/linux/icmpv6.h | 1 + - include/uapi/linux/if.h | 1 + - include/uapi/linux/if_addr.h | 2 + - include/uapi/linux/if_addrlabel.h | 1 + - include/uapi/linux/if_alg.h | 1 + - include/uapi/linux/if_arp.h | 1 + - include/uapi/linux/if_bonding.h | 1 + - include/uapi/linux/if_bridge.h | 1 + - include/uapi/linux/if_ether.h | 11 + - include/uapi/linux/if_link.h | 59 + - include/uapi/linux/if_macsec.h | 10 +- - include/uapi/linux/if_packet.h | 1 + - include/uapi/linux/if_tun.h | 5 + - include/uapi/linux/if_tunnel.h | 5 + - include/uapi/linux/if_vlan.h | 1 + - include/uapi/linux/ife.h | 1 + - include/uapi/linux/ila.h | 23 + - include/uapi/linux/in.h | 1 + - include/uapi/linux/in6.h | 2 + - include/uapi/linux/in_route.h | 1 + - include/uapi/linux/inet_diag.h | 3 + - include/uapi/linux/ip.h | 1 + - include/uapi/linux/ip6_tunnel.h | 3 + - include/uapi/linux/ipsec.h | 1 + - include/uapi/linux/kernel.h | 1 + - include/uapi/linux/l2tp.h | 7 +- - include/uapi/linux/libc-compat.h | 56 +- - include/uapi/linux/limits.h | 1 + - include/uapi/linux/lwtunnel.h | 1 + - include/uapi/linux/magic.h | 2 + - include/uapi/linux/mpls.h | 1 + - include/uapi/linux/mpls_iptunnel.h | 1 + - include/uapi/linux/neighbour.h | 1 + - include/uapi/linux/net_namespace.h | 1 + - include/uapi/linux/netconf.h | 1 + - include/uapi/linux/netdevice.h | 1 + - include/uapi/linux/netfilter.h | 1 + - include/uapi/linux/netfilter/ipset/ip_set.h | 1 + - include/uapi/linux/netfilter/x_tables.h | 1 + - include/uapi/linux/netfilter/xt_set.h | 1 + - include/uapi/linux/netfilter/xt_tcpudp.h | 1 + - include/uapi/linux/netfilter_ipv4.h | 2 + - include/uapi/linux/netfilter_ipv4/ip_tables.h | 1 + - include/uapi/linux/netfilter_ipv6.h | 2 + - .../uapi/linux/netfilter_ipv6/ip6_tables.h | 1 + - include/uapi/linux/netlink.h | 1 + - include/uapi/linux/netlink_diag.h | 1 + - include/uapi/linux/packet_diag.h | 1 + - include/uapi/linux/param.h | 1 + - include/uapi/linux/pfkeyv2.h | 1 + - include/uapi/linux/pkt_cls.h | 15 +- - include/uapi/linux/pkt_sched.h | 198 ++ - include/uapi/linux/posix_types.h | 1 + - include/uapi/linux/rtnetlink.h | 24 + - include/uapi/linux/sctp.h | 71 +- - include/uapi/linux/seg6.h | 5 +- - include/uapi/linux/seg6_genl.h | 1 + - include/uapi/linux/seg6_hmac.h | 1 + - include/uapi/linux/seg6_iptunnel.h | 1 + - include/uapi/linux/seg6_local.h | 12 + - include/uapi/linux/sock_diag.h | 1 + - include/uapi/linux/socket.h | 1 + - include/uapi/linux/sockios.h | 1 + - include/uapi/linux/stddef.h | 1 + - include/uapi/linux/sysinfo.h | 1 + - include/uapi/linux/tc_act/tc_bpf.h | 1 + - include/uapi/linux/tc_act/tc_connmark.h | 1 + - include/uapi/linux/tc_act/tc_csum.h | 1 + - include/uapi/linux/tc_act/tc_defact.h | 1 + - include/uapi/linux/tc_act/tc_gact.h | 1 + - include/uapi/linux/tc_act/tc_ife.h | 1 + - include/uapi/linux/tc_act/tc_ipt.h | 1 + - include/uapi/linux/tc_act/tc_mirred.h | 7 +- - include/uapi/linux/tc_act/tc_nat.h | 1 + - include/uapi/linux/tc_act/tc_pedit.h | 10 +- - include/uapi/linux/tc_act/tc_sample.h | 1 + - include/uapi/linux/tc_act/tc_skbedit.h | 3 + - include/uapi/linux/tc_act/tc_skbmod.h | 1 + - include/uapi/linux/tc_act/tc_tunnel_key.h | 29 + - include/uapi/linux/tc_act/tc_vlan.h | 1 + - include/uapi/linux/tc_ematch/tc_em_cmp.h | 1 + - include/uapi/linux/tc_ematch/tc_em_ipt.h | 20 + - include/uapi/linux/tc_ematch/tc_em_meta.h | 1 + - include/uapi/linux/tc_ematch/tc_em_nbyte.h | 1 + - include/uapi/linux/tcp.h | 22 + - include/uapi/linux/tcp_metrics.h | 1 + - include/uapi/linux/tipc.h | 188 +- - include/uapi/linux/tipc_netlink.h | 37 + - include/uapi/linux/tipc_sockets_diag.h | 17 + - include/uapi/linux/types.h | 3 + - include/uapi/linux/unix_diag.h | 1 + - include/uapi/linux/veth.h | 1 + - include/uapi/linux/vm_sockets_diag.h | 1 + - include/uapi/linux/xfrm.h | 1 + - 114 files changed, 3201 insertions(+), 427 deletions(-) - create mode 100644 include/uapi/linux/btf.h - create mode 100644 include/uapi/linux/tc_ematch/tc_em_ipt.h - create mode 100644 include/uapi/linux/tipc_sockets_diag.h - -diff --git a/include/uapi/linux/atm.h b/include/uapi/linux/atm.h -index 08e27bebaacfb..e33ff6b5bf152 100644 ---- a/include/uapi/linux/atm.h -+++ b/include/uapi/linux/atm.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* atm.h - general ATM declarations */ - - /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ -diff --git a/include/uapi/linux/atmapi.h b/include/uapi/linux/atmapi.h -index 8fe54d90d95b1..c9bf5c23a71f6 100644 ---- a/include/uapi/linux/atmapi.h -+++ b/include/uapi/linux/atmapi.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* atmapi.h - ATM API user space/kernel compatibility */ - - /* Written 1999,2000 by Werner Almesberger, EPFL ICA */ -diff --git a/include/uapi/linux/atmarp.h b/include/uapi/linux/atmarp.h -index 231f4bdec730e..8e44d121fde1a 100644 ---- a/include/uapi/linux/atmarp.h -+++ b/include/uapi/linux/atmarp.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* atmarp.h - ATM ARP protocol and kernel-demon interface definitions */ - - /* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ -diff --git a/include/uapi/linux/atmdev.h b/include/uapi/linux/atmdev.h -index 8faa8b94091ce..9bdb96a4bbe04 100644 ---- a/include/uapi/linux/atmdev.h -+++ b/include/uapi/linux/atmdev.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* atmdev.h - ATM device driver declarations and various related items */ - - /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ -diff --git a/include/uapi/linux/atmioc.h b/include/uapi/linux/atmioc.h -index 37f67aa8f1c16..cd7655e40c77a 100644 ---- a/include/uapi/linux/atmioc.h -+++ b/include/uapi/linux/atmioc.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* atmioc.h - ranges for ATM-related ioctl numbers */ - - /* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ -diff --git a/include/uapi/linux/atmsap.h b/include/uapi/linux/atmsap.h -index 799b104515d77..fc052481eae05 100644 ---- a/include/uapi/linux/atmsap.h -+++ b/include/uapi/linux/atmsap.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* atmsap.h - ATM Service Access Point addressing definitions */ - - /* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ -diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h -index 0895a529cc90b..b9a63672b297c 100644 ---- a/include/uapi/linux/bpf.h -+++ b/include/uapi/linux/bpf.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com - * - * This program is free software; you can redistribute it and/or -@@ -16,7 +17,7 @@ - #define BPF_ALU64 0x07 /* alu mode in double word width */ - - /* ld/ldx fields */ --#define BPF_DW 0x18 /* double word */ -+#define BPF_DW 0x18 /* double word (64-bit) */ - #define BPF_XADD 0xc0 /* exclusive add */ - - /* alu/jmp fields */ -@@ -92,6 +93,11 @@ enum bpf_cmd { - BPF_PROG_GET_FD_BY_ID, - BPF_MAP_GET_FD_BY_ID, - BPF_OBJ_GET_INFO_BY_FD, -+ BPF_PROG_QUERY, -+ BPF_RAW_TRACEPOINT_OPEN, -+ BPF_BTF_LOAD, -+ BPF_BTF_GET_FD_BY_ID, -+ BPF_TASK_FD_QUERY, - }; - - enum bpf_map_type { -@@ -111,6 +117,9 @@ enum bpf_map_type { - BPF_MAP_TYPE_HASH_OF_MAPS, - BPF_MAP_TYPE_DEVMAP, - BPF_MAP_TYPE_SOCKMAP, -+ BPF_MAP_TYPE_CPUMAP, -+ BPF_MAP_TYPE_XSKMAP, -+ BPF_MAP_TYPE_SOCKHASH, - }; - - enum bpf_prog_type { -@@ -129,6 +138,12 @@ enum bpf_prog_type { - BPF_PROG_TYPE_LWT_XMIT, - BPF_PROG_TYPE_SOCK_OPS, - BPF_PROG_TYPE_SK_SKB, -+ BPF_PROG_TYPE_CGROUP_DEVICE, -+ BPF_PROG_TYPE_SK_MSG, -+ BPF_PROG_TYPE_RAW_TRACEPOINT, -+ BPF_PROG_TYPE_CGROUP_SOCK_ADDR, -+ BPF_PROG_TYPE_LWT_SEG6LOCAL, -+ BPF_PROG_TYPE_LIRC_MODE2, - }; - - enum bpf_attach_type { -@@ -138,16 +153,63 @@ enum bpf_attach_type { - BPF_CGROUP_SOCK_OPS, - BPF_SK_SKB_STREAM_PARSER, - BPF_SK_SKB_STREAM_VERDICT, -+ BPF_CGROUP_DEVICE, -+ BPF_SK_MSG_VERDICT, -+ BPF_CGROUP_INET4_BIND, -+ BPF_CGROUP_INET6_BIND, -+ BPF_CGROUP_INET4_CONNECT, -+ BPF_CGROUP_INET6_CONNECT, -+ BPF_CGROUP_INET4_POST_BIND, -+ BPF_CGROUP_INET6_POST_BIND, -+ BPF_CGROUP_UDP4_SENDMSG, -+ BPF_CGROUP_UDP6_SENDMSG, -+ BPF_LIRC_MODE2, - __MAX_BPF_ATTACH_TYPE - }; - - #define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE - --/* If BPF_F_ALLOW_OVERRIDE flag is used in BPF_PROG_ATTACH command -- * to the given target_fd cgroup the descendent cgroup will be able to -- * override effective bpf program that was inherited from this cgroup -+/* cgroup-bpf attach flags used in BPF_PROG_ATTACH command -+ * -+ * NONE(default): No further bpf programs allowed in the subtree. -+ * -+ * BPF_F_ALLOW_OVERRIDE: If a sub-cgroup installs some bpf program, -+ * the program in this cgroup yields to sub-cgroup program. -+ * -+ * BPF_F_ALLOW_MULTI: If a sub-cgroup installs some bpf program, -+ * that cgroup program gets run in addition to the program in this cgroup. -+ * -+ * Only one program is allowed to be attached to a cgroup with -+ * NONE or BPF_F_ALLOW_OVERRIDE flag. -+ * Attaching another program on top of NONE or BPF_F_ALLOW_OVERRIDE will -+ * release old program and attach the new one. Attach flags has to match. -+ * -+ * Multiple programs are allowed to be attached to a cgroup with -+ * BPF_F_ALLOW_MULTI flag. They are executed in FIFO order -+ * (those that were attached first, run first) -+ * The programs of sub-cgroup are executed first, then programs of -+ * this cgroup and then programs of parent cgroup. -+ * When children program makes decision (like picking TCP CA or sock bind) -+ * parent program has a chance to override it. -+ * -+ * A cgroup with MULTI or OVERRIDE flag allows any attach flags in sub-cgroups. -+ * A cgroup with NONE doesn't allow any programs in sub-cgroups. -+ * Ex1: -+ * cgrp1 (MULTI progs A, B) -> -+ * cgrp2 (OVERRIDE prog C) -> -+ * cgrp3 (MULTI prog D) -> -+ * cgrp4 (OVERRIDE prog E) -> -+ * cgrp5 (NONE prog F) -+ * the event in cgrp5 triggers execution of F,D,A,B in that order. -+ * if prog F is detached, the execution is E,D,A,B -+ * if prog F and D are detached, the execution is E,A,B -+ * if prog F, E and D are detached, the execution is C,A,B -+ * -+ * All eligible programs are executed regardless of return code from -+ * earlier programs. - */ - #define BPF_F_ALLOW_OVERRIDE (1U << 0) -+#define BPF_F_ALLOW_MULTI (1U << 1) - - /* If BPF_F_STRICT_ALIGNMENT is used in BPF_PROG_LOAD command, the - * verifier will perform strict alignment checking as if the kernel -@@ -156,8 +218,14 @@ enum bpf_attach_type { - */ - #define BPF_F_STRICT_ALIGNMENT (1U << 0) - -+/* when bpf_ldimm64->src_reg == BPF_PSEUDO_MAP_FD, bpf_ldimm64->imm == fd */ - #define BPF_PSEUDO_MAP_FD 1 - -+/* when bpf_call->src_reg == BPF_PSEUDO_CALL, bpf_call->imm == pc-relative -+ * offset to another bpf function -+ */ -+#define BPF_PSEUDO_CALL 1 -+ - /* flags for BPF_MAP_UPDATE_ELEM command */ - #define BPF_ANY 0 /* create new element or update existing */ - #define BPF_NOEXIST 1 /* create new element if it didn't exist */ -@@ -175,6 +243,37 @@ enum bpf_attach_type { - /* Specify numa node during map creation */ - #define BPF_F_NUMA_NODE (1U << 2) - -+/* flags for BPF_PROG_QUERY */ -+#define BPF_F_QUERY_EFFECTIVE (1U << 0) -+ -+#define BPF_OBJ_NAME_LEN 16U -+ -+/* Flags for accessing BPF object */ -+#define BPF_F_RDONLY (1U << 3) -+#define BPF_F_WRONLY (1U << 4) -+ -+/* Flag for stack_map, store build_id+offset instead of pointer */ -+#define BPF_F_STACK_BUILD_ID (1U << 5) -+ -+enum bpf_stack_build_id_status { -+ /* user space need an empty entry to identify end of a trace */ -+ BPF_STACK_BUILD_ID_EMPTY = 0, -+ /* with valid build_id and offset */ -+ BPF_STACK_BUILD_ID_VALID = 1, -+ /* couldn't get build_id, fallback to ip */ -+ BPF_STACK_BUILD_ID_IP = 2, -+}; -+ -+#define BPF_BUILD_ID_SIZE 20 -+struct bpf_stack_build_id { -+ __s32 status; -+ unsigned char build_id[BPF_BUILD_ID_SIZE]; -+ union { -+ __u64 offset; -+ __u64 ip; -+ }; -+}; -+ - union bpf_attr { - struct { /* anonymous struct used by BPF_MAP_CREATE command */ - __u32 map_type; /* one of enum bpf_map_type */ -@@ -188,6 +287,11 @@ union bpf_attr { - __u32 numa_node; /* numa node (effective only if - * BPF_F_NUMA_NODE is set). - */ -+ char map_name[BPF_OBJ_NAME_LEN]; -+ __u32 map_ifindex; /* ifindex of netdev to create on */ -+ __u32 btf_fd; /* fd pointing to a BTF type data */ -+ __u32 btf_key_type_id; /* BTF type_id of the key */ -+ __u32 btf_value_type_id; /* BTF type_id of the value */ - }; - - struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */ -@@ -210,11 +314,19 @@ union bpf_attr { - __aligned_u64 log_buf; /* user supplied buffer */ - __u32 kern_version; /* checked when prog_type=kprobe */ - __u32 prog_flags; -+ char prog_name[BPF_OBJ_NAME_LEN]; -+ __u32 prog_ifindex; /* ifindex of netdev to prep for */ -+ /* For some prog types expected attach type must be known at -+ * load time to verify attach type specific parts of prog -+ * (context accesses, allowed helpers, etc). -+ */ -+ __u32 expected_attach_type; - }; - - struct { /* anonymous struct used by BPF_OBJ_* commands */ - __aligned_u64 pathname; - __u32 bpf_fd; -+ __u32 file_flags; - }; - - struct { /* anonymous struct used by BPF_PROG_ATTACH/DETACH commands */ -@@ -240,8 +352,10 @@ union bpf_attr { - __u32 start_id; - __u32 prog_id; - __u32 map_id; -+ __u32 btf_id; - }; - __u32 next_id; -+ __u32 open_flags; - }; - - struct { /* anonymous struct used by BPF_OBJ_GET_INFO_BY_FD */ -@@ -249,339 +363,1718 @@ union bpf_attr { - __u32 info_len; - __aligned_u64 info; - } info; -+ -+ struct { /* anonymous struct used by BPF_PROG_QUERY command */ -+ __u32 target_fd; /* container object to query */ -+ __u32 attach_type; -+ __u32 query_flags; -+ __u32 attach_flags; -+ __aligned_u64 prog_ids; -+ __u32 prog_cnt; -+ } query; -+ -+ struct { -+ __u64 name; -+ __u32 prog_fd; -+ } raw_tracepoint; -+ -+ struct { /* anonymous struct for BPF_BTF_LOAD */ -+ __aligned_u64 btf; -+ __aligned_u64 btf_log_buf; -+ __u32 btf_size; -+ __u32 btf_log_size; -+ __u32 btf_log_level; -+ }; -+ -+ struct { -+ __u32 pid; /* input: pid */ -+ __u32 fd; /* input: fd */ -+ __u32 flags; /* input: flags */ -+ __u32 buf_len; /* input/output: buf len */ -+ __aligned_u64 buf; /* input/output: -+ * tp_name for tracepoint -+ * symbol for kprobe -+ * filename for uprobe -+ */ -+ __u32 prog_id; /* output: prod_id */ -+ __u32 fd_type; /* output: BPF_FD_TYPE_* */ -+ __u64 probe_offset; /* output: probe_offset */ -+ __u64 probe_addr; /* output: probe_addr */ -+ } task_fd_query; - } __attribute__((aligned(8))); - --/* BPF helper function descriptions: -+/* The description below is an attempt at providing documentation to eBPF -+ * developers about the multiple available eBPF helper functions. It can be -+ * parsed and used to produce a manual page. The workflow is the following, -+ * and requires the rst2man utility: -+ * -+ * $ ./scripts/bpf_helpers_doc.py \ -+ * --filename include/uapi/linux/bpf.h > /tmp/bpf-helpers.rst -+ * $ rst2man /tmp/bpf-helpers.rst > /tmp/bpf-helpers.7 -+ * $ man /tmp/bpf-helpers.7 -+ * -+ * Note that in order to produce this external documentation, some RST -+ * formatting is used in the descriptions to get "bold" and "italics" in -+ * manual pages. Also note that the few trailing white spaces are -+ * intentional, removing them would break paragraphs for rst2man. -+ * -+ * Start of BPF helper function descriptions: -+ * -+ * void *bpf_map_lookup_elem(struct bpf_map *map, const void *key) -+ * Description -+ * Perform a lookup in *map* for an entry associated to *key*. -+ * Return -+ * Map value associated to *key*, or **NULL** if no entry was -+ * found. - * -- * void *bpf_map_lookup_elem(&map, &key) -- * Return: Map value or NULL -+ * int bpf_map_update_elem(struct bpf_map *map, const void *key, const void *value, u64 flags) -+ * Description -+ * Add or update the value of the entry associated to *key* in -+ * *map* with *value*. *flags* is one of: - * -- * int bpf_map_update_elem(&map, &key, &value, flags) -- * Return: 0 on success or negative error -+ * **BPF_NOEXIST** -+ * The entry for *key* must not exist in the map. -+ * **BPF_EXIST** -+ * The entry for *key* must already exist in the map. -+ * **BPF_ANY** -+ * No condition on the existence of the entry for *key*. - * -- * int bpf_map_delete_elem(&map, &key) -- * Return: 0 on success or negative error -+ * Flag value **BPF_NOEXIST** cannot be used for maps of types -+ * **BPF_MAP_TYPE_ARRAY** or **BPF_MAP_TYPE_PERCPU_ARRAY** (all -+ * elements always exist), the helper would return an error. -+ * Return -+ * 0 on success, or a negative error in case of failure. - * -- * int bpf_probe_read(void *dst, int size, void *src) -- * Return: 0 on success or negative error -+ * int bpf_map_delete_elem(struct bpf_map *map, const void *key) -+ * Description -+ * Delete entry with *key* from *map*. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_probe_read(void *dst, u32 size, const void *src) -+ * Description -+ * For tracing programs, safely attempt to read *size* bytes from -+ * address *src* and store the data in *dst*. -+ * Return -+ * 0 on success, or a negative error in case of failure. - * - * u64 bpf_ktime_get_ns(void) -- * Return: current ktime -- * -- * int bpf_trace_printk(const char *fmt, int fmt_size, ...) -- * Return: length of buffer written or negative error -- * -- * u32 bpf_prandom_u32(void) -- * Return: random value -- * -- * u32 bpf_raw_smp_processor_id(void) -- * Return: SMP processor ID -- * -- * int bpf_skb_store_bytes(skb, offset, from, len, flags) -- * store bytes into packet -- * @skb: pointer to skb -- * @offset: offset within packet from skb->mac_header -- * @from: pointer where to copy bytes from -- * @len: number of bytes to store into packet -- * @flags: bit 0 - if true, recompute skb->csum -- * other bits - reserved -- * Return: 0 on success or negative error -- * -- * int bpf_l3_csum_replace(skb, offset, from, to, flags) -- * recompute IP checksum -- * @skb: pointer to skb -- * @offset: offset within packet where IP checksum is located -- * @from: old value of header field -- * @to: new value of header field -- * @flags: bits 0-3 - size of header field -- * other bits - reserved -- * Return: 0 on success or negative error -- * -- * int bpf_l4_csum_replace(skb, offset, from, to, flags) -- * recompute TCP/UDP checksum -- * @skb: pointer to skb -- * @offset: offset within packet where TCP/UDP checksum is located -- * @from: old value of header field -- * @to: new value of header field -- * @flags: bits 0-3 - size of header field -- * bit 4 - is pseudo header -- * other bits - reserved -- * Return: 0 on success or negative error -- * -- * int bpf_tail_call(ctx, prog_array_map, index) -- * jump into another BPF program -- * @ctx: context pointer passed to next program -- * @prog_array_map: pointer to map which type is BPF_MAP_TYPE_PROG_ARRAY -- * @index: index inside array that selects specific program to run -- * Return: 0 on success or negative error -- * -- * int bpf_clone_redirect(skb, ifindex, flags) -- * redirect to another netdev -- * @skb: pointer to skb -- * @ifindex: ifindex of the net device -- * @flags: bit 0 - if set, redirect to ingress instead of egress -- * other bits - reserved -- * Return: 0 on success or negative error -+ * Description -+ * Return the time elapsed since system boot, in nanoseconds. -+ * Return -+ * Current *ktime*. -+ * -+ * int bpf_trace_printk(const char *fmt, u32 fmt_size, ...) -+ * Description -+ * This helper is a "printk()-like" facility for debugging. It -+ * prints a message defined by format *fmt* (of size *fmt_size*) -+ * to file *\/sys/kernel/debug/tracing/trace* from DebugFS, if -+ * available. It can take up to three additional **u64** -+ * arguments (as an eBPF helpers, the total number of arguments is -+ * limited to five). -+ * -+ * Each time the helper is called, it appends a line to the trace. -+ * The format of the trace is customizable, and the exact output -+ * one will get depends on the options set in -+ * *\/sys/kernel/debug/tracing/trace_options* (see also the -+ * *README* file under the same directory). However, it usually -+ * defaults to something like: -+ * -+ * :: -+ * -+ * telnet-470 [001] .N.. 419421.045894: 0x00000001: -+ * -+ * In the above: -+ * -+ * * ``telnet`` is the name of the current task. -+ * * ``470`` is the PID of the current task. -+ * * ``001`` is the CPU number on which the task is -+ * running. -+ * * In ``.N..``, each character refers to a set of -+ * options (whether irqs are enabled, scheduling -+ * options, whether hard/softirqs are running, level of -+ * preempt_disabled respectively). **N** means that -+ * **TIF_NEED_RESCHED** and **PREEMPT_NEED_RESCHED** -+ * are set. -+ * * ``419421.045894`` is a timestamp. -+ * * ``0x00000001`` is a fake value used by BPF for the -+ * instruction pointer register. -+ * * ```` is the message formatted with -+ * *fmt*. -+ * -+ * The conversion specifiers supported by *fmt* are similar, but -+ * more limited than for printk(). They are **%d**, **%i**, -+ * **%u**, **%x**, **%ld**, **%li**, **%lu**, **%lx**, **%lld**, -+ * **%lli**, **%llu**, **%llx**, **%p**, **%s**. No modifier (size -+ * of field, padding with zeroes, etc.) is available, and the -+ * helper will return **-EINVAL** (but print nothing) if it -+ * encounters an unknown specifier. -+ * -+ * Also, note that **bpf_trace_printk**\ () is slow, and should -+ * only be used for debugging purposes. For this reason, a notice -+ * bloc (spanning several lines) is printed to kernel logs and -+ * states that the helper should not be used "for production use" -+ * the first time this helper is used (or more precisely, when -+ * **trace_printk**\ () buffers are allocated). For passing values -+ * to user space, perf events should be preferred. -+ * Return -+ * The number of bytes written to the buffer, or a negative error -+ * in case of failure. -+ * -+ * u32 bpf_get_prandom_u32(void) -+ * Description -+ * Get a pseudo-random number. -+ * -+ * From a security point of view, this helper uses its own -+ * pseudo-random internal state, and cannot be used to infer the -+ * seed of other random functions in the kernel. However, it is -+ * essential to note that the generator used by the helper is not -+ * cryptographically secure. -+ * Return -+ * A random 32-bit unsigned value. -+ * -+ * u32 bpf_get_smp_processor_id(void) -+ * Description -+ * Get the SMP (symmetric multiprocessing) processor id. Note that -+ * all programs run with preemption disabled, which means that the -+ * SMP processor id is stable during all the execution of the -+ * program. -+ * Return -+ * The SMP id of the processor running the program. -+ * -+ * int bpf_skb_store_bytes(struct sk_buff *skb, u32 offset, const void *from, u32 len, u64 flags) -+ * Description -+ * Store *len* bytes from address *from* into the packet -+ * associated to *skb*, at *offset*. *flags* are a combination of -+ * **BPF_F_RECOMPUTE_CSUM** (automatically recompute the -+ * checksum for the packet after storing the bytes) and -+ * **BPF_F_INVALIDATE_HASH** (set *skb*\ **->hash**, *skb*\ -+ * **->swhash** and *skb*\ **->l4hash** to 0). -+ * -+ * A call to this helper is susceptible to change the underlaying -+ * packet buffer. Therefore, at load time, all checks on pointers -+ * previously done by the verifier are invalidated and must be -+ * performed again, if the helper is used in combination with -+ * direct packet access. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_l3_csum_replace(struct sk_buff *skb, u32 offset, u64 from, u64 to, u64 size) -+ * Description -+ * Recompute the layer 3 (e.g. IP) checksum for the packet -+ * associated to *skb*. Computation is incremental, so the helper -+ * must know the former value of the header field that was -+ * modified (*from*), the new value of this field (*to*), and the -+ * number of bytes (2 or 4) for this field, stored in *size*. -+ * Alternatively, it is possible to store the difference between -+ * the previous and the new values of the header field in *to*, by -+ * setting *from* and *size* to 0. For both methods, *offset* -+ * indicates the location of the IP checksum within the packet. -+ * -+ * This helper works in combination with **bpf_csum_diff**\ (), -+ * which does not update the checksum in-place, but offers more -+ * flexibility and can handle sizes larger than 2 or 4 for the -+ * checksum to update. -+ * -+ * A call to this helper is susceptible to change the underlaying -+ * packet buffer. Therefore, at load time, all checks on pointers -+ * previously done by the verifier are invalidated and must be -+ * performed again, if the helper is used in combination with -+ * direct packet access. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_l4_csum_replace(struct sk_buff *skb, u32 offset, u64 from, u64 to, u64 flags) -+ * Description -+ * Recompute the layer 4 (e.g. TCP, UDP or ICMP) checksum for the -+ * packet associated to *skb*. Computation is incremental, so the -+ * helper must know the former value of the header field that was -+ * modified (*from*), the new value of this field (*to*), and the -+ * number of bytes (2 or 4) for this field, stored on the lowest -+ * four bits of *flags*. Alternatively, it is possible to store -+ * the difference between the previous and the new values of the -+ * header field in *to*, by setting *from* and the four lowest -+ * bits of *flags* to 0. For both methods, *offset* indicates the -+ * location of the IP checksum within the packet. In addition to -+ * the size of the field, *flags* can be added (bitwise OR) actual -+ * flags. With **BPF_F_MARK_MANGLED_0**, a null checksum is left -+ * untouched (unless **BPF_F_MARK_ENFORCE** is added as well), and -+ * for updates resulting in a null checksum the value is set to -+ * **CSUM_MANGLED_0** instead. Flag **BPF_F_PSEUDO_HDR** indicates -+ * the checksum is to be computed against a pseudo-header. -+ * -+ * This helper works in combination with **bpf_csum_diff**\ (), -+ * which does not update the checksum in-place, but offers more -+ * flexibility and can handle sizes larger than 2 or 4 for the -+ * checksum to update. -+ * -+ * A call to this helper is susceptible to change the underlaying -+ * packet buffer. Therefore, at load time, all checks on pointers -+ * previously done by the verifier are invalidated and must be -+ * performed again, if the helper is used in combination with -+ * direct packet access. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_tail_call(void *ctx, struct bpf_map *prog_array_map, u32 index) -+ * Description -+ * This special helper is used to trigger a "tail call", or in -+ * other words, to jump into another eBPF program. The same stack -+ * frame is used (but values on stack and in registers for the -+ * caller are not accessible to the callee). This mechanism allows -+ * for program chaining, either for raising the maximum number of -+ * available eBPF instructions, or to execute given programs in -+ * conditional blocks. For security reasons, there is an upper -+ * limit to the number of successive tail calls that can be -+ * performed. -+ * -+ * Upon call of this helper, the program attempts to jump into a -+ * program referenced at index *index* in *prog_array_map*, a -+ * special map of type **BPF_MAP_TYPE_PROG_ARRAY**, and passes -+ * *ctx*, a pointer to the context. -+ * -+ * If the call succeeds, the kernel immediately runs the first -+ * instruction of the new program. This is not a function call, -+ * and it never returns to the previous program. If the call -+ * fails, then the helper has no effect, and the caller continues -+ * to run its subsequent instructions. A call can fail if the -+ * destination program for the jump does not exist (i.e. *index* -+ * is superior to the number of entries in *prog_array_map*), or -+ * if the maximum number of tail calls has been reached for this -+ * chain of programs. This limit is defined in the kernel by the -+ * macro **MAX_TAIL_CALL_CNT** (not accessible to user space), -+ * which is currently set to 32. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_clone_redirect(struct sk_buff *skb, u32 ifindex, u64 flags) -+ * Description -+ * Clone and redirect the packet associated to *skb* to another -+ * net device of index *ifindex*. Both ingress and egress -+ * interfaces can be used for redirection. The **BPF_F_INGRESS** -+ * value in *flags* is used to make the distinction (ingress path -+ * is selected if the flag is present, egress path otherwise). -+ * This is the only flag supported for now. -+ * -+ * In comparison with **bpf_redirect**\ () helper, -+ * **bpf_clone_redirect**\ () has the associated cost of -+ * duplicating the packet buffer, but this can be executed out of -+ * the eBPF program. Conversely, **bpf_redirect**\ () is more -+ * efficient, but it is handled through an action code where the -+ * redirection happens only after the eBPF program has returned. -+ * -+ * A call to this helper is susceptible to change the underlaying -+ * packet buffer. Therefore, at load time, all checks on pointers -+ * previously done by the verifier are invalidated and must be -+ * performed again, if the helper is used in combination with -+ * direct packet access. -+ * Return -+ * 0 on success, or a negative error in case of failure. - * - * u64 bpf_get_current_pid_tgid(void) -- * Return: current->tgid << 32 | current->pid -+ * Return -+ * A 64-bit integer containing the current tgid and pid, and -+ * created as such: -+ * *current_task*\ **->tgid << 32 \|** -+ * *current_task*\ **->pid**. - * - * u64 bpf_get_current_uid_gid(void) -- * Return: current_gid << 32 | current_uid -- * -- * int bpf_get_current_comm(char *buf, int size_of_buf) -- * stores current->comm into buf -- * Return: 0 on success or negative error -- * -- * u32 bpf_get_cgroup_classid(skb) -- * retrieve a proc's classid -- * @skb: pointer to skb -- * Return: classid if != 0 -- * -- * int bpf_skb_vlan_push(skb, vlan_proto, vlan_tci) -- * Return: 0 on success or negative error -- * -- * int bpf_skb_vlan_pop(skb) -- * Return: 0 on success or negative error -- * -- * int bpf_skb_get_tunnel_key(skb, key, size, flags) -- * int bpf_skb_set_tunnel_key(skb, key, size, flags) -- * retrieve or populate tunnel metadata -- * @skb: pointer to skb -- * @key: pointer to 'struct bpf_tunnel_key' -- * @size: size of 'struct bpf_tunnel_key' -- * @flags: room for future extensions -- * Return: 0 on success or negative error -- * -- * u64 bpf_perf_event_read(map, flags) -- * read perf event counter value -- * @map: pointer to perf_event_array map -- * @flags: index of event in the map or bitmask flags -- * Return: value of perf event counter read or error code -- * -- * int bpf_redirect(ifindex, flags) -- * redirect to another netdev -- * @ifindex: ifindex of the net device -- * @flags: -- * cls_bpf: -- * bit 0 - if set, redirect to ingress instead of egress -- * other bits - reserved -- * xdp_bpf: -- * all bits - reserved -- * Return: cls_bpf: TC_ACT_REDIRECT on success or TC_ACT_SHOT on error -- * xdp_bfp: XDP_REDIRECT on success or XDP_ABORT on error -- * int bpf_redirect_map(map, key, flags) -- * redirect to endpoint in map -- * @map: pointer to dev map -- * @key: index in map to lookup -- * @flags: -- -- * Return: XDP_REDIRECT on success or XDP_ABORT on error -- * -- * u32 bpf_get_route_realm(skb) -- * retrieve a dst's tclassid -- * @skb: pointer to skb -- * Return: realm if != 0 -- * -- * int bpf_perf_event_output(ctx, map, flags, data, size) -- * output perf raw sample -- * @ctx: struct pt_regs* -- * @map: pointer to perf_event_array map -- * @flags: index of event in the map or bitmask flags -- * @data: data on stack to be output as raw data -- * @size: size of data -- * Return: 0 on success or negative error -- * -- * int 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 -- * -- * s64 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 or negative error code -- * -- * int bpf_skb_get_tunnel_opt(skb, opt, size) -- * retrieve tunnel options metadata -- * @skb: pointer to skb -- * @opt: pointer to raw tunnel option data -- * @size: size of @opt -- * Return: option size -- * -- * int bpf_skb_set_tunnel_opt(skb, opt, size) -- * populate tunnel options metadata -- * @skb: pointer to skb -- * @opt: pointer to raw tunnel option data -- * @size: size of @opt -- * Return: 0 on success or negative error -- * -- * int bpf_skb_change_proto(skb, proto, flags) -- * Change protocol of the skb. Currently supported is v4 -> v6, -- * v6 -> v4 transitions. The helper will also resize the skb. eBPF -- * program is expected to fill the new headers via skb_store_bytes -- * and lX_csum_replace. -- * @skb: pointer to skb -- * @proto: new skb->protocol type -- * @flags: reserved -- * Return: 0 on success or negative error -- * -- * int bpf_skb_change_type(skb, type) -- * Change packet type of skb. -- * @skb: pointer to skb -- * @type: new skb->pkt_type type -- * Return: 0 on success or negative error -- * -- * int bpf_skb_under_cgroup(skb, map, index) -- * Check cgroup2 membership of skb -- * @skb: pointer to skb -- * @map: pointer to bpf_map in BPF_MAP_TYPE_CGROUP_ARRAY type -- * @index: index of the cgroup in the bpf_map -- * Return: -- * == 0 skb failed the cgroup2 descendant test -- * == 1 skb succeeded the cgroup2 descendant test -- * < 0 error -- * -- * u32 bpf_get_hash_recalc(skb) -- * Retrieve and possibly recalculate skb->hash. -- * @skb: pointer to skb -- * Return: hash -+ * Return -+ * A 64-bit integer containing the current GID and UID, and -+ * created as such: *current_gid* **<< 32 \|** *current_uid*. -+ * -+ * int bpf_get_current_comm(char *buf, u32 size_of_buf) -+ * Description -+ * Copy the **comm** attribute of the current task into *buf* of -+ * *size_of_buf*. The **comm** attribute contains the name of -+ * the executable (excluding the path) for the current task. The -+ * *size_of_buf* must be strictly positive. On success, the -+ * helper makes sure that the *buf* is NUL-terminated. On failure, -+ * it is filled with zeroes. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * u32 bpf_get_cgroup_classid(struct sk_buff *skb) -+ * Description -+ * Retrieve the classid for the current task, i.e. for the net_cls -+ * cgroup to which *skb* belongs. -+ * -+ * This helper can be used on TC egress path, but not on ingress. -+ * -+ * The net_cls cgroup provides an interface to tag network packets -+ * based on a user-provided identifier for all traffic coming from -+ * the tasks belonging to the related cgroup. See also the related -+ * kernel documentation, available from the Linux sources in file -+ * *Documentation/cgroup-v1/net_cls.txt*. -+ * -+ * The Linux kernel has two versions for cgroups: there are -+ * cgroups v1 and cgroups v2. Both are available to users, who can -+ * use a mixture of them, but note that the net_cls cgroup is for -+ * cgroup v1 only. This makes it incompatible with BPF programs -+ * run on cgroups, which is a cgroup-v2-only feature (a socket can -+ * only hold data for one version of cgroups at a time). -+ * -+ * This helper is only available is the kernel was compiled with -+ * the **CONFIG_CGROUP_NET_CLASSID** configuration option set to -+ * "**y**" or to "**m**". -+ * Return -+ * The classid, or 0 for the default unconfigured classid. -+ * -+ * int bpf_skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci) -+ * Description -+ * Push a *vlan_tci* (VLAN tag control information) of protocol -+ * *vlan_proto* to the packet associated to *skb*, then update -+ * the checksum. Note that if *vlan_proto* is different from -+ * **ETH_P_8021Q** and **ETH_P_8021AD**, it is considered to -+ * be **ETH_P_8021Q**. -+ * -+ * A call to this helper is susceptible to change the underlaying -+ * packet buffer. Therefore, at load time, all checks on pointers -+ * previously done by the verifier are invalidated and must be -+ * performed again, if the helper is used in combination with -+ * direct packet access. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_skb_vlan_pop(struct sk_buff *skb) -+ * Description -+ * Pop a VLAN header from the packet associated to *skb*. -+ * -+ * A call to this helper is susceptible to change the underlaying -+ * packet buffer. Therefore, at load time, all checks on pointers -+ * previously done by the verifier are invalidated and must be -+ * performed again, if the helper is used in combination with -+ * direct packet access. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_skb_get_tunnel_key(struct sk_buff *skb, struct bpf_tunnel_key *key, u32 size, u64 flags) -+ * Description -+ * Get tunnel metadata. This helper takes a pointer *key* to an -+ * empty **struct bpf_tunnel_key** of **size**, that will be -+ * filled with tunnel metadata for the packet associated to *skb*. -+ * The *flags* can be set to **BPF_F_TUNINFO_IPV6**, which -+ * indicates that the tunnel is based on IPv6 protocol instead of -+ * IPv4. -+ * -+ * The **struct bpf_tunnel_key** is an object that generalizes the -+ * principal parameters used by various tunneling protocols into a -+ * single struct. This way, it can be used to easily make a -+ * decision based on the contents of the encapsulation header, -+ * "summarized" in this struct. In particular, it holds the IP -+ * address of the remote end (IPv4 or IPv6, depending on the case) -+ * in *key*\ **->remote_ipv4** or *key*\ **->remote_ipv6**. Also, -+ * this struct exposes the *key*\ **->tunnel_id**, which is -+ * generally mapped to a VNI (Virtual Network Identifier), making -+ * it programmable together with the **bpf_skb_set_tunnel_key**\ -+ * () helper. -+ * -+ * Let's imagine that the following code is part of a program -+ * attached to the TC ingress interface, on one end of a GRE -+ * tunnel, and is supposed to filter out all messages coming from -+ * remote ends with IPv4 address other than 10.0.0.1: -+ * -+ * :: -+ * -+ * int ret; -+ * struct bpf_tunnel_key key = {}; -+ * -+ * ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0); -+ * if (ret < 0) -+ * return TC_ACT_SHOT; // drop packet -+ * -+ * if (key.remote_ipv4 != 0x0a000001) -+ * return TC_ACT_SHOT; // drop packet -+ * -+ * return TC_ACT_OK; // accept packet -+ * -+ * This interface can also be used with all encapsulation devices -+ * that can operate in "collect metadata" mode: instead of having -+ * one network device per specific configuration, the "collect -+ * metadata" mode only requires a single device where the -+ * configuration can be extracted from this helper. -+ * -+ * This can be used together with various tunnels such as VXLan, -+ * Geneve, GRE or IP in IP (IPIP). -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_skb_set_tunnel_key(struct sk_buff *skb, struct bpf_tunnel_key *key, u32 size, u64 flags) -+ * Description -+ * Populate tunnel metadata for packet associated to *skb.* The -+ * tunnel metadata is set to the contents of *key*, of *size*. The -+ * *flags* can be set to a combination of the following values: -+ * -+ * **BPF_F_TUNINFO_IPV6** -+ * Indicate that the tunnel is based on IPv6 protocol -+ * instead of IPv4. -+ * **BPF_F_ZERO_CSUM_TX** -+ * For IPv4 packets, add a flag to tunnel metadata -+ * indicating that checksum computation should be skipped -+ * and checksum set to zeroes. -+ * **BPF_F_DONT_FRAGMENT** -+ * Add a flag to tunnel metadata indicating that the -+ * packet should not be fragmented. -+ * **BPF_F_SEQ_NUMBER** -+ * Add a flag to tunnel metadata indicating that a -+ * sequence number should be added to tunnel header before -+ * sending the packet. This flag was added for GRE -+ * encapsulation, but might be used with other protocols -+ * as well in the future. -+ * -+ * Here is a typical usage on the transmit path: -+ * -+ * :: -+ * -+ * struct bpf_tunnel_key key; -+ * populate key ... -+ * bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0); -+ * bpf_clone_redirect(skb, vxlan_dev_ifindex, 0); -+ * -+ * See also the description of the **bpf_skb_get_tunnel_key**\ () -+ * helper for additional information. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * u64 bpf_perf_event_read(struct bpf_map *map, u64 flags) -+ * Description -+ * Read the value of a perf event counter. This helper relies on a -+ * *map* of type **BPF_MAP_TYPE_PERF_EVENT_ARRAY**. The nature of -+ * the perf event counter is selected when *map* is updated with -+ * perf event file descriptors. The *map* is an array whose size -+ * is the number of available CPUs, and each cell contains a value -+ * relative to one CPU. The value to retrieve is indicated by -+ * *flags*, that contains the index of the CPU to look up, masked -+ * with **BPF_F_INDEX_MASK**. Alternatively, *flags* can be set to -+ * **BPF_F_CURRENT_CPU** to indicate that the value for the -+ * current CPU should be retrieved. -+ * -+ * Note that before Linux 4.13, only hardware perf event can be -+ * retrieved. -+ * -+ * Also, be aware that the newer helper -+ * **bpf_perf_event_read_value**\ () is recommended over -+ * **bpf_perf_event_read**\ () in general. The latter has some ABI -+ * quirks where error and counter value are used as a return code -+ * (which is wrong to do since ranges may overlap). This issue is -+ * fixed with **bpf_perf_event_read_value**\ (), which at the same -+ * time provides more features over the **bpf_perf_event_read**\ -+ * () interface. Please refer to the description of -+ * **bpf_perf_event_read_value**\ () for details. -+ * Return -+ * The value of the perf event counter read from the map, or a -+ * negative error code in case of failure. -+ * -+ * int bpf_redirect(u32 ifindex, u64 flags) -+ * Description -+ * Redirect the packet to another net device of index *ifindex*. -+ * This helper is somewhat similar to **bpf_clone_redirect**\ -+ * (), except that the packet is not cloned, which provides -+ * increased performance. -+ * -+ * Except for XDP, both ingress and egress interfaces can be used -+ * for redirection. The **BPF_F_INGRESS** value in *flags* is used -+ * to make the distinction (ingress path is selected if the flag -+ * is present, egress path otherwise). Currently, XDP only -+ * supports redirection to the egress interface, and accepts no -+ * flag at all. -+ * -+ * The same effect can be attained with the more generic -+ * **bpf_redirect_map**\ (), which requires specific maps to be -+ * used but offers better performance. -+ * Return -+ * For XDP, the helper returns **XDP_REDIRECT** on success or -+ * **XDP_ABORTED** on error. For other program types, the values -+ * are **TC_ACT_REDIRECT** on success or **TC_ACT_SHOT** on -+ * error. -+ * -+ * u32 bpf_get_route_realm(struct sk_buff *skb) -+ * Description -+ * Retrieve the realm or the route, that is to say the -+ * **tclassid** field of the destination for the *skb*. The -+ * indentifier retrieved is a user-provided tag, similar to the -+ * one used with the net_cls cgroup (see description for -+ * **bpf_get_cgroup_classid**\ () helper), but here this tag is -+ * held by a route (a destination entry), not by a task. -+ * -+ * Retrieving this identifier works with the clsact TC egress hook -+ * (see also **tc-bpf(8)**), or alternatively on conventional -+ * classful egress qdiscs, but not on TC ingress path. In case of -+ * clsact TC egress hook, this has the advantage that, internally, -+ * the destination entry has not been dropped yet in the transmit -+ * path. Therefore, the destination entry does not need to be -+ * artificially held via **netif_keep_dst**\ () for a classful -+ * qdisc until the *skb* is freed. -+ * -+ * This helper is available only if the kernel was compiled with -+ * **CONFIG_IP_ROUTE_CLASSID** configuration option. -+ * Return -+ * The realm of the route for the packet associated to *skb*, or 0 -+ * if none was found. -+ * -+ * int bpf_perf_event_output(struct pt_reg *ctx, struct bpf_map *map, u64 flags, void *data, u64 size) -+ * Description -+ * Write raw *data* blob into a special BPF perf event held by -+ * *map* of type **BPF_MAP_TYPE_PERF_EVENT_ARRAY**. This perf -+ * event must have the following attributes: **PERF_SAMPLE_RAW** -+ * as **sample_type**, **PERF_TYPE_SOFTWARE** as **type**, and -+ * **PERF_COUNT_SW_BPF_OUTPUT** as **config**. -+ * -+ * The *flags* are used to indicate the index in *map* for which -+ * the value must be put, masked with **BPF_F_INDEX_MASK**. -+ * Alternatively, *flags* can be set to **BPF_F_CURRENT_CPU** -+ * to indicate that the index of the current CPU core should be -+ * used. -+ * -+ * The value to write, of *size*, is passed through eBPF stack and -+ * pointed by *data*. -+ * -+ * The context of the program *ctx* needs also be passed to the -+ * helper. -+ * -+ * On user space, a program willing to read the values needs to -+ * call **perf_event_open**\ () on the perf event (either for -+ * one or for all CPUs) and to store the file descriptor into the -+ * *map*. This must be done before the eBPF program can send data -+ * into it. An example is available in file -+ * *samples/bpf/trace_output_user.c* in the Linux kernel source -+ * tree (the eBPF program counterpart is in -+ * *samples/bpf/trace_output_kern.c*). -+ * -+ * **bpf_perf_event_output**\ () achieves better performance -+ * than **bpf_trace_printk**\ () for sharing data with user -+ * space, and is much better suitable for streaming data from eBPF -+ * programs. -+ * -+ * Note that this helper is not restricted to tracing use cases -+ * and can be used with programs attached to TC or XDP as well, -+ * where it allows for passing data to user space listeners. Data -+ * can be: -+ * -+ * * Only custom structs, -+ * * Only the packet payload, or -+ * * A combination of both. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_skb_load_bytes(const struct sk_buff *skb, u32 offset, void *to, u32 len) -+ * Description -+ * This helper was provided as an easy way to load data from a -+ * packet. It can be used to load *len* bytes from *offset* from -+ * the packet associated to *skb*, into the buffer pointed by -+ * *to*. -+ * -+ * Since Linux 4.7, usage of this helper has mostly been replaced -+ * by "direct packet access", enabling packet data to be -+ * manipulated with *skb*\ **->data** and *skb*\ **->data_end** -+ * pointing respectively to the first byte of packet data and to -+ * the byte after the last byte of packet data. However, it -+ * remains useful if one wishes to read large quantities of data -+ * at once from a packet into the eBPF stack. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_get_stackid(struct pt_reg *ctx, struct bpf_map *map, u64 flags) -+ * Description -+ * Walk a user or a kernel stack and return its id. To achieve -+ * this, the helper needs *ctx*, which is a pointer to the context -+ * on which the tracing program is executed, and a pointer to a -+ * *map* of type **BPF_MAP_TYPE_STACK_TRACE**. -+ * -+ * The last argument, *flags*, holds the number of stack frames to -+ * skip (from 0 to 255), masked with -+ * **BPF_F_SKIP_FIELD_MASK**. The next bits can be used to set -+ * a combination of the following flags: -+ * -+ * **BPF_F_USER_STACK** -+ * Collect a user space stack instead of a kernel stack. -+ * **BPF_F_FAST_STACK_CMP** -+ * Compare stacks by hash only. -+ * **BPF_F_REUSE_STACKID** -+ * If two different stacks hash into the same *stackid*, -+ * discard the old one. -+ * -+ * The stack id retrieved is a 32 bit long integer handle which -+ * can be further combined with other data (including other stack -+ * ids) and used as a key into maps. This can be useful for -+ * generating a variety of graphs (such as flame graphs or off-cpu -+ * graphs). -+ * -+ * For walking a stack, this helper is an improvement over -+ * **bpf_probe_read**\ (), which can be used with unrolled loops -+ * but is not efficient and consumes a lot of eBPF instructions. -+ * Instead, **bpf_get_stackid**\ () can collect up to -+ * **PERF_MAX_STACK_DEPTH** both kernel and user frames. Note that -+ * this limit can be controlled with the **sysctl** program, and -+ * that it should be manually increased in order to profile long -+ * user stacks (such as stacks for Java programs). To do so, use: -+ * -+ * :: -+ * -+ * # sysctl kernel.perf_event_max_stack= -+ * Return -+ * The positive or null stack id on success, or a negative error -+ * in case of failure. -+ * -+ * s64 bpf_csum_diff(__be32 *from, u32 from_size, __be32 *to, u32 to_size, __wsum seed) -+ * Description -+ * Compute a checksum difference, from the raw buffer pointed by -+ * *from*, of length *from_size* (that must be a multiple of 4), -+ * towards the raw buffer pointed by *to*, of size *to_size* -+ * (same remark). An optional *seed* can be added to the value -+ * (this can be cascaded, the seed may come from a previous call -+ * to the helper). -+ * -+ * This is flexible enough to be used in several ways: -+ * -+ * * With *from_size* == 0, *to_size* > 0 and *seed* set to -+ * checksum, it can be used when pushing new data. -+ * * With *from_size* > 0, *to_size* == 0 and *seed* set to -+ * checksum, it can be used when removing data from a packet. -+ * * With *from_size* > 0, *to_size* > 0 and *seed* set to 0, it -+ * can be used to compute a diff. Note that *from_size* and -+ * *to_size* do not need to be equal. -+ * -+ * This helper can be used in combination with -+ * **bpf_l3_csum_replace**\ () and **bpf_l4_csum_replace**\ (), to -+ * which one can feed in the difference computed with -+ * **bpf_csum_diff**\ (). -+ * Return -+ * The checksum result, or a negative error code in case of -+ * failure. -+ * -+ * int bpf_skb_get_tunnel_opt(struct sk_buff *skb, u8 *opt, u32 size) -+ * Description -+ * Retrieve tunnel options metadata for the packet associated to -+ * *skb*, and store the raw tunnel option data to the buffer *opt* -+ * of *size*. -+ * -+ * This helper can be used with encapsulation devices that can -+ * operate in "collect metadata" mode (please refer to the related -+ * note in the description of **bpf_skb_get_tunnel_key**\ () for -+ * more details). A particular example where this can be used is -+ * in combination with the Geneve encapsulation protocol, where it -+ * allows for pushing (with **bpf_skb_get_tunnel_opt**\ () helper) -+ * and retrieving arbitrary TLVs (Type-Length-Value headers) from -+ * the eBPF program. This allows for full customization of these -+ * headers. -+ * Return -+ * The size of the option data retrieved. -+ * -+ * int bpf_skb_set_tunnel_opt(struct sk_buff *skb, u8 *opt, u32 size) -+ * Description -+ * Set tunnel options metadata for the packet associated to *skb* -+ * to the option data contained in the raw buffer *opt* of *size*. -+ * -+ * See also the description of the **bpf_skb_get_tunnel_opt**\ () -+ * helper for additional information. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_skb_change_proto(struct sk_buff *skb, __be16 proto, u64 flags) -+ * Description -+ * Change the protocol of the *skb* to *proto*. Currently -+ * supported are transition from IPv4 to IPv6, and from IPv6 to -+ * IPv4. The helper takes care of the groundwork for the -+ * transition, including resizing the socket buffer. The eBPF -+ * program is expected to fill the new headers, if any, via -+ * **skb_store_bytes**\ () and to recompute the checksums with -+ * **bpf_l3_csum_replace**\ () and **bpf_l4_csum_replace**\ -+ * (). The main case for this helper is to perform NAT64 -+ * operations out of an eBPF program. -+ * -+ * Internally, the GSO type is marked as dodgy so that headers are -+ * checked and segments are recalculated by the GSO/GRO engine. -+ * The size for GSO target is adapted as well. -+ * -+ * All values for *flags* are reserved for future usage, and must -+ * be left at zero. -+ * -+ * A call to this helper is susceptible to change the underlaying -+ * packet buffer. Therefore, at load time, all checks on pointers -+ * previously done by the verifier are invalidated and must be -+ * performed again, if the helper is used in combination with -+ * direct packet access. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_skb_change_type(struct sk_buff *skb, u32 type) -+ * Description -+ * Change the packet type for the packet associated to *skb*. This -+ * comes down to setting *skb*\ **->pkt_type** to *type*, except -+ * the eBPF program does not have a write access to *skb*\ -+ * **->pkt_type** beside this helper. Using a helper here allows -+ * for graceful handling of errors. -+ * -+ * The major use case is to change incoming *skb*s to -+ * **PACKET_HOST** in a programmatic way instead of having to -+ * recirculate via **redirect**\ (..., **BPF_F_INGRESS**), for -+ * example. -+ * -+ * Note that *type* only allows certain values. At this time, they -+ * are: -+ * -+ * **PACKET_HOST** -+ * Packet is for us. -+ * **PACKET_BROADCAST** -+ * Send packet to all. -+ * **PACKET_MULTICAST** -+ * Send packet to group. -+ * **PACKET_OTHERHOST** -+ * Send packet to someone else. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_skb_under_cgroup(struct sk_buff *skb, struct bpf_map *map, u32 index) -+ * Description -+ * Check whether *skb* is a descendant of the cgroup2 held by -+ * *map* of type **BPF_MAP_TYPE_CGROUP_ARRAY**, at *index*. -+ * Return -+ * The return value depends on the result of the test, and can be: -+ * -+ * * 0, if the *skb* failed the cgroup2 descendant test. -+ * * 1, if the *skb* succeeded the cgroup2 descendant test. -+ * * A negative error code, if an error occurred. -+ * -+ * u32 bpf_get_hash_recalc(struct sk_buff *skb) -+ * Description -+ * Retrieve the hash of the packet, *skb*\ **->hash**. If it is -+ * not set, in particular if the hash was cleared due to mangling, -+ * recompute this hash. Later accesses to the hash can be done -+ * directly with *skb*\ **->hash**. -+ * -+ * Calling **bpf_set_hash_invalid**\ (), changing a packet -+ * prototype with **bpf_skb_change_proto**\ (), or calling -+ * **bpf_skb_store_bytes**\ () with the -+ * **BPF_F_INVALIDATE_HASH** are actions susceptible to clear -+ * the hash and to trigger a new computation for the next call to -+ * **bpf_get_hash_recalc**\ (). -+ * Return -+ * The 32-bit hash. - * - * u64 bpf_get_current_task(void) -- * Returns current task_struct -- * Return: current -- * -- * int bpf_probe_write_user(void *dst, void *src, int len) -- * safely attempt to write to a location -- * @dst: destination address in userspace -- * @src: source address on stack -- * @len: number of bytes to copy -- * Return: 0 on success or negative error -- * -- * int bpf_current_task_under_cgroup(map, index) -- * Check cgroup2 membership of current task -- * @map: pointer to bpf_map in BPF_MAP_TYPE_CGROUP_ARRAY type -- * @index: index of the cgroup in the bpf_map -- * Return: -- * == 0 current failed the cgroup2 descendant test -- * == 1 current succeeded the cgroup2 descendant test -- * < 0 error -- * -- * int bpf_skb_change_tail(skb, len, flags) -- * The helper will resize the skb to the given new size, to be used f.e. -- * with control messages. -- * @skb: pointer to skb -- * @len: new skb length -- * @flags: reserved -- * Return: 0 on success or negative error -- * -- * int bpf_skb_pull_data(skb, len) -- * The helper will pull in non-linear data in case the skb is non-linear -- * and not all of len are part of the linear section. Only needed for -- * read/write with direct packet access. -- * @skb: pointer to skb -- * @len: len to make read/writeable -- * Return: 0 on success or negative error -- * -- * s64 bpf_csum_update(skb, csum) -- * Adds csum into skb->csum in case of CHECKSUM_COMPLETE. -- * @skb: pointer to skb -- * @csum: csum to add -- * Return: csum on success or negative error -- * -- * void bpf_set_hash_invalid(skb) -- * Invalidate current skb->hash. -- * @skb: pointer to skb -- * -- * int bpf_get_numa_node_id() -- * Return: Id of current NUMA node. -- * -- * int bpf_skb_change_head() -- * Grows headroom of skb and adjusts MAC header offset accordingly. -- * Will extends/reallocae as required automatically. -- * May change skb data pointer and will thus invalidate any check -- * performed for direct packet access. -- * @skb: pointer to skb -- * @len: length of header to be pushed in front -- * @flags: Flags (unused for now) -- * Return: 0 on success or negative error -- * -- * int bpf_xdp_adjust_head(xdp_md, delta) -- * Adjust the xdp_md.data by delta -- * @xdp_md: pointer to xdp_md -- * @delta: An positive/negative integer to be added to xdp_md.data -- * Return: 0 on success or negative on error -+ * Return -+ * A pointer to the current task struct. -+ * -+ * int bpf_probe_write_user(void *dst, const void *src, u32 len) -+ * Description -+ * Attempt in a safe way to write *len* bytes from the buffer -+ * *src* to *dst* in memory. It only works for threads that are in -+ * user context, and *dst* must be a valid user space address. -+ * -+ * This helper should not be used to implement any kind of -+ * security mechanism because of TOC-TOU attacks, but rather to -+ * debug, divert, and manipulate execution of semi-cooperative -+ * processes. -+ * -+ * Keep in mind that this feature is meant for experiments, and it -+ * has a risk of crashing the system and running programs. -+ * Therefore, when an eBPF program using this helper is attached, -+ * a warning including PID and process name is printed to kernel -+ * logs. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_current_task_under_cgroup(struct bpf_map *map, u32 index) -+ * Description -+ * Check whether the probe is being run is the context of a given -+ * subset of the cgroup2 hierarchy. The cgroup2 to test is held by -+ * *map* of type **BPF_MAP_TYPE_CGROUP_ARRAY**, at *index*. -+ * Return -+ * The return value depends on the result of the test, and can be: -+ * -+ * * 0, if the *skb* task belongs to the cgroup2. -+ * * 1, if the *skb* task does not belong to the cgroup2. -+ * * A negative error code, if an error occurred. -+ * -+ * int bpf_skb_change_tail(struct sk_buff *skb, u32 len, u64 flags) -+ * Description -+ * Resize (trim or grow) the packet associated to *skb* to the -+ * new *len*. The *flags* are reserved for future usage, and must -+ * be left at zero. -+ * -+ * The basic idea is that the helper performs the needed work to -+ * change the size of the packet, then the eBPF program rewrites -+ * the rest via helpers like **bpf_skb_store_bytes**\ (), -+ * **bpf_l3_csum_replace**\ (), **bpf_l3_csum_replace**\ () -+ * and others. This helper is a slow path utility intended for -+ * replies with control messages. And because it is targeted for -+ * slow path, the helper itself can afford to be slow: it -+ * implicitly linearizes, unclones and drops offloads from the -+ * *skb*. -+ * -+ * A call to this helper is susceptible to change the underlaying -+ * packet buffer. Therefore, at load time, all checks on pointers -+ * previously done by the verifier are invalidated and must be -+ * performed again, if the helper is used in combination with -+ * direct packet access. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_skb_pull_data(struct sk_buff *skb, u32 len) -+ * Description -+ * Pull in non-linear data in case the *skb* is non-linear and not -+ * all of *len* are part of the linear section. Make *len* bytes -+ * from *skb* readable and writable. If a zero value is passed for -+ * *len*, then the whole length of the *skb* is pulled. -+ * -+ * This helper is only needed for reading and writing with direct -+ * packet access. -+ * -+ * For direct packet access, testing that offsets to access -+ * are within packet boundaries (test on *skb*\ **->data_end**) is -+ * susceptible to fail if offsets are invalid, or if the requested -+ * data is in non-linear parts of the *skb*. On failure the -+ * program can just bail out, or in the case of a non-linear -+ * buffer, use a helper to make the data available. The -+ * **bpf_skb_load_bytes**\ () helper is a first solution to access -+ * the data. Another one consists in using **bpf_skb_pull_data** -+ * to pull in once the non-linear parts, then retesting and -+ * eventually access the data. -+ * -+ * At the same time, this also makes sure the *skb* is uncloned, -+ * which is a necessary condition for direct write. As this needs -+ * to be an invariant for the write part only, the verifier -+ * detects writes and adds a prologue that is calling -+ * **bpf_skb_pull_data()** to effectively unclone the *skb* from -+ * the very beginning in case it is indeed cloned. -+ * -+ * A call to this helper is susceptible to change the underlaying -+ * packet buffer. Therefore, at load time, all checks on pointers -+ * previously done by the verifier are invalidated and must be -+ * performed again, if the helper is used in combination with -+ * direct packet access. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * s64 bpf_csum_update(struct sk_buff *skb, __wsum csum) -+ * Description -+ * Add the checksum *csum* into *skb*\ **->csum** in case the -+ * driver has supplied a checksum for the entire packet into that -+ * field. Return an error otherwise. This helper is intended to be -+ * used in combination with **bpf_csum_diff**\ (), in particular -+ * when the checksum needs to be updated after data has been -+ * written into the packet through direct packet access. -+ * Return -+ * The checksum on success, or a negative error code in case of -+ * failure. -+ * -+ * void bpf_set_hash_invalid(struct sk_buff *skb) -+ * Description -+ * Invalidate the current *skb*\ **->hash**. It can be used after -+ * mangling on headers through direct packet access, in order to -+ * indicate that the hash is outdated and to trigger a -+ * recalculation the next time the kernel tries to access this -+ * hash or when the **bpf_get_hash_recalc**\ () helper is called. -+ * -+ * int bpf_get_numa_node_id(void) -+ * Description -+ * Return the id of the current NUMA node. The primary use case -+ * for this helper is the selection of sockets for the local NUMA -+ * node, when the program is attached to sockets using the -+ * **SO_ATTACH_REUSEPORT_EBPF** option (see also **socket(7)**), -+ * but the helper is also available to other eBPF program types, -+ * similarly to **bpf_get_smp_processor_id**\ (). -+ * Return -+ * The id of current NUMA node. -+ * -+ * int bpf_skb_change_head(struct sk_buff *skb, u32 len, u64 flags) -+ * Description -+ * Grows headroom of packet associated to *skb* and adjusts the -+ * offset of the MAC header accordingly, adding *len* bytes of -+ * space. It automatically extends and reallocates memory as -+ * required. -+ * -+ * This helper can be used on a layer 3 *skb* to push a MAC header -+ * for redirection into a layer 2 device. -+ * -+ * All values for *flags* are reserved for future usage, and must -+ * be left at zero. -+ * -+ * A call to this helper is susceptible to change the underlaying -+ * packet buffer. Therefore, at load time, all checks on pointers -+ * previously done by the verifier are invalidated and must be -+ * performed again, if the helper is used in combination with -+ * direct packet access. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_xdp_adjust_head(struct xdp_buff *xdp_md, int delta) -+ * Description -+ * Adjust (move) *xdp_md*\ **->data** by *delta* bytes. Note that -+ * it is possible to use a negative value for *delta*. This helper -+ * can be used to prepare the packet for pushing or popping -+ * headers. -+ * -+ * A call to this helper is susceptible to change the underlaying -+ * packet buffer. Therefore, at load time, all checks on pointers -+ * previously done by the verifier are invalidated and must be -+ * performed again, if the helper is used in combination with -+ * direct packet access. -+ * Return -+ * 0 on success, or a negative error in case of failure. - * - * int bpf_probe_read_str(void *dst, int size, const void *unsafe_ptr) -- * Copy a NUL terminated string from unsafe address. In case the string -- * length is smaller than size, the target is not padded with further NUL -- * bytes. In case the string length is larger than size, just count-1 -- * bytes are copied and the last byte is set to NUL. -- * @dst: destination address -- * @size: maximum number of bytes to copy, including the trailing NUL -- * @unsafe_ptr: unsafe address -- * Return: -- * > 0 length of the string including the trailing NUL on success -- * < 0 error -- * -- * u64 bpf_get_socket_cookie(skb) -- * Get the cookie for the socket stored inside sk_buff. -- * @skb: pointer to skb -- * Return: 8 Bytes non-decreasing number on success or 0 if the socket -- * field is missing inside sk_buff -- * -- * u32 bpf_get_socket_uid(skb) -- * Get the owner uid of the socket stored inside sk_buff. -- * @skb: pointer to skb -- * Return: uid of the socket owner on success or overflowuid if failed. -- * -- * u32 bpf_set_hash(skb, hash) -- * Set full skb->hash. -- * @skb: pointer to skb -- * @hash: hash to set -- * -- * int bpf_setsockopt(bpf_socket, level, optname, optval, optlen) -- * Calls setsockopt. Not all opts are available, only those with -- * integer optvals plus TCP_CONGESTION. -- * Supported levels: SOL_SOCKET and IPROTO_TCP -- * @bpf_socket: pointer to bpf_socket -- * @level: SOL_SOCKET or IPROTO_TCP -- * @optname: option name -- * @optval: pointer to option value -- * @optlen: length of optval in byes -- * Return: 0 or negative error -- * -- * int bpf_skb_adjust_room(skb, len_diff, mode, flags) -- * Grow or shrink room in sk_buff. -- * @skb: pointer to skb -- * @len_diff: (signed) amount of room to grow/shrink -- * @mode: operation mode (enum bpf_adj_room_mode) -- * @flags: reserved for future use -- * Return: 0 on success or negative error code -- * -- * int bpf_sk_redirect_map(map, key, flags) -- * Redirect skb to a sock in map using key as a lookup key for the -- * sock in map. -- * @map: pointer to sockmap -- * @key: key to lookup sock in map -- * @flags: reserved for future use -- * Return: SK_REDIRECT -- * -- * int bpf_sock_map_update(skops, map, key, flags) -- * @skops: pointer to bpf_sock_ops -- * @map: pointer to sockmap to update -- * @key: key to insert/update sock in map -- * @flags: same flags as map update elem -+ * Description -+ * Copy a NUL terminated string from an unsafe address -+ * *unsafe_ptr* to *dst*. The *size* should include the -+ * terminating NUL byte. In case the string length is smaller than -+ * *size*, the target is not padded with further NUL bytes. If the -+ * string length is larger than *size*, just *size*-1 bytes are -+ * copied and the last byte is set to NUL. -+ * -+ * On success, the length of the copied string is returned. This -+ * makes this helper useful in tracing programs for reading -+ * strings, and more importantly to get its length at runtime. See -+ * the following snippet: -+ * -+ * :: -+ * -+ * SEC("kprobe/sys_open") -+ * void bpf_sys_open(struct pt_regs *ctx) -+ * { -+ * char buf[PATHLEN]; // PATHLEN is defined to 256 -+ * int res = bpf_probe_read_str(buf, sizeof(buf), -+ * ctx->di); -+ * -+ * // Consume buf, for example push it to -+ * // userspace via bpf_perf_event_output(); we -+ * // can use res (the string length) as event -+ * // size, after checking its boundaries. -+ * } -+ * -+ * In comparison, using **bpf_probe_read()** helper here instead -+ * to read the string would require to estimate the length at -+ * compile time, and would often result in copying more memory -+ * than necessary. -+ * -+ * Another useful use case is when parsing individual process -+ * arguments or individual environment variables navigating -+ * *current*\ **->mm->arg_start** and *current*\ -+ * **->mm->env_start**: using this helper and the return value, -+ * one can quickly iterate at the right offset of the memory area. -+ * Return -+ * On success, the strictly positive length of the string, -+ * including the trailing NUL character. On error, a negative -+ * value. -+ * -+ * u64 bpf_get_socket_cookie(struct sk_buff *skb) -+ * Description -+ * If the **struct sk_buff** pointed by *skb* has a known socket, -+ * retrieve the cookie (generated by the kernel) of this socket. -+ * If no cookie has been set yet, generate a new cookie. Once -+ * generated, the socket cookie remains stable for the life of the -+ * socket. This helper can be useful for monitoring per socket -+ * networking traffic statistics as it provides a unique socket -+ * identifier per namespace. -+ * Return -+ * A 8-byte long non-decreasing number on success, or 0 if the -+ * socket field is missing inside *skb*. -+ * -+ * u32 bpf_get_socket_uid(struct sk_buff *skb) -+ * Return -+ * The owner UID of the socket associated to *skb*. If the socket -+ * is **NULL**, or if it is not a full socket (i.e. if it is a -+ * time-wait or a request socket instead), **overflowuid** value -+ * is returned (note that **overflowuid** might also be the actual -+ * UID value for the socket). -+ * -+ * u32 bpf_set_hash(struct sk_buff *skb, u32 hash) -+ * Description -+ * Set the full hash for *skb* (set the field *skb*\ **->hash**) -+ * to value *hash*. -+ * Return -+ * 0 -+ * -+ * int bpf_setsockopt(struct bpf_sock_ops *bpf_socket, int level, int optname, char *optval, int optlen) -+ * Description -+ * Emulate a call to **setsockopt()** on the socket associated to -+ * *bpf_socket*, which must be a full socket. The *level* at -+ * which the option resides and the name *optname* of the option -+ * must be specified, see **setsockopt(2)** for more information. -+ * The option value of length *optlen* is pointed by *optval*. -+ * -+ * This helper actually implements a subset of **setsockopt()**. -+ * It supports the following *level*\ s: -+ * -+ * * **SOL_SOCKET**, which supports the following *optname*\ s: -+ * **SO_RCVBUF**, **SO_SNDBUF**, **SO_MAX_PACING_RATE**, -+ * **SO_PRIORITY**, **SO_RCVLOWAT**, **SO_MARK**. -+ * * **IPPROTO_TCP**, which supports the following *optname*\ s: -+ * **TCP_CONGESTION**, **TCP_BPF_IW**, -+ * **TCP_BPF_SNDCWND_CLAMP**. -+ * * **IPPROTO_IP**, which supports *optname* **IP_TOS**. -+ * * **IPPROTO_IPV6**, which supports *optname* **IPV6_TCLASS**. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_skb_adjust_room(struct sk_buff *skb, u32 len_diff, u32 mode, u64 flags) -+ * Description -+ * Grow or shrink the room for data in the packet associated to -+ * *skb* by *len_diff*, and according to the selected *mode*. -+ * -+ * There is a single supported mode at this time: -+ * -+ * * **BPF_ADJ_ROOM_NET**: Adjust room at the network layer -+ * (room space is added or removed below the layer 3 header). -+ * -+ * All values for *flags* are reserved for future usage, and must -+ * be left at zero. -+ * -+ * A call to this helper is susceptible to change the underlaying -+ * packet buffer. Therefore, at load time, all checks on pointers -+ * previously done by the verifier are invalidated and must be -+ * performed again, if the helper is used in combination with -+ * direct packet access. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_redirect_map(struct bpf_map *map, u32 key, u64 flags) -+ * Description -+ * Redirect the packet to the endpoint referenced by *map* at -+ * index *key*. Depending on its type, this *map* can contain -+ * references to net devices (for forwarding packets through other -+ * ports), or to CPUs (for redirecting XDP frames to another CPU; -+ * but this is only implemented for native XDP (with driver -+ * support) as of this writing). -+ * -+ * All values for *flags* are reserved for future usage, and must -+ * be left at zero. -+ * -+ * When used to redirect packets to net devices, this helper -+ * provides a high performance increase over **bpf_redirect**\ (). -+ * This is due to various implementation details of the underlying -+ * mechanisms, one of which is the fact that **bpf_redirect_map**\ -+ * () tries to send packet as a "bulk" to the device. -+ * Return -+ * **XDP_REDIRECT** on success, or **XDP_ABORTED** on error. -+ * -+ * int bpf_sk_redirect_map(struct bpf_map *map, u32 key, u64 flags) -+ * Description -+ * Redirect the packet to the socket referenced by *map* (of type -+ * **BPF_MAP_TYPE_SOCKMAP**) at index *key*. Both ingress and -+ * egress interfaces can be used for redirection. The -+ * **BPF_F_INGRESS** value in *flags* is used to make the -+ * distinction (ingress path is selected if the flag is present, -+ * egress path otherwise). This is the only flag supported for now. -+ * Return -+ * **SK_PASS** on success, or **SK_DROP** on error. -+ * -+ * int bpf_sock_map_update(struct bpf_sock_ops *skops, struct bpf_map *map, void *key, u64 flags) -+ * Description -+ * Add an entry to, or update a *map* referencing sockets. The -+ * *skops* is used as a new value for the entry associated to -+ * *key*. *flags* is one of: -+ * -+ * **BPF_NOEXIST** -+ * The entry for *key* must not exist in the map. -+ * **BPF_EXIST** -+ * The entry for *key* must already exist in the map. -+ * **BPF_ANY** -+ * No condition on the existence of the entry for *key*. -+ * -+ * If the *map* has eBPF programs (parser and verdict), those will -+ * be inherited by the socket being added. If the socket is -+ * already attached to eBPF programs, this results in an error. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_xdp_adjust_meta(struct xdp_buff *xdp_md, int delta) -+ * Description -+ * Adjust the address pointed by *xdp_md*\ **->data_meta** by -+ * *delta* (which can be positive or negative). Note that this -+ * operation modifies the address stored in *xdp_md*\ **->data**, -+ * so the latter must be loaded only after the helper has been -+ * called. -+ * -+ * The use of *xdp_md*\ **->data_meta** is optional and programs -+ * are not required to use it. The rationale is that when the -+ * packet is processed with XDP (e.g. as DoS filter), it is -+ * possible to push further meta data along with it before passing -+ * to the stack, and to give the guarantee that an ingress eBPF -+ * program attached as a TC classifier on the same device can pick -+ * this up for further post-processing. Since TC works with socket -+ * buffers, it remains possible to set from XDP the **mark** or -+ * **priority** pointers, or other pointers for the socket buffer. -+ * Having this scratch space generic and programmable allows for -+ * more flexibility as the user is free to store whatever meta -+ * data they need. -+ * -+ * A call to this helper is susceptible to change the underlaying -+ * packet buffer. Therefore, at load time, all checks on pointers -+ * previously done by the verifier are invalidated and must be -+ * performed again, if the helper is used in combination with -+ * direct packet access. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_perf_event_read_value(struct bpf_map *map, u64 flags, struct bpf_perf_event_value *buf, u32 buf_size) -+ * Description -+ * Read the value of a perf event counter, and store it into *buf* -+ * of size *buf_size*. This helper relies on a *map* of type -+ * **BPF_MAP_TYPE_PERF_EVENT_ARRAY**. The nature of the perf event -+ * counter is selected when *map* is updated with perf event file -+ * descriptors. The *map* is an array whose size is the number of -+ * available CPUs, and each cell contains a value relative to one -+ * CPU. The value to retrieve is indicated by *flags*, that -+ * contains the index of the CPU to look up, masked with -+ * **BPF_F_INDEX_MASK**. Alternatively, *flags* can be set to -+ * **BPF_F_CURRENT_CPU** to indicate that the value for the -+ * current CPU should be retrieved. -+ * -+ * This helper behaves in a way close to -+ * **bpf_perf_event_read**\ () helper, save that instead of -+ * just returning the value observed, it fills the *buf* -+ * structure. This allows for additional data to be retrieved: in -+ * particular, the enabled and running times (in *buf*\ -+ * **->enabled** and *buf*\ **->running**, respectively) are -+ * copied. In general, **bpf_perf_event_read_value**\ () is -+ * recommended over **bpf_perf_event_read**\ (), which has some -+ * ABI issues and provides fewer functionalities. -+ * -+ * These values are interesting, because hardware PMU (Performance -+ * Monitoring Unit) counters are limited resources. When there are -+ * more PMU based perf events opened than available counters, -+ * kernel will multiplex these events so each event gets certain -+ * percentage (but not all) of the PMU time. In case that -+ * multiplexing happens, the number of samples or counter value -+ * will not reflect the case compared to when no multiplexing -+ * occurs. This makes comparison between different runs difficult. -+ * Typically, the counter value should be normalized before -+ * comparing to other experiments. The usual normalization is done -+ * as follows. -+ * -+ * :: -+ * -+ * normalized_counter = counter * t_enabled / t_running -+ * -+ * Where t_enabled is the time enabled for event and t_running is -+ * the time running for event since last normalization. The -+ * enabled and running times are accumulated since the perf event -+ * open. To achieve scaling factor between two invocations of an -+ * eBPF program, users can can use CPU id as the key (which is -+ * typical for perf array usage model) to remember the previous -+ * value and do the calculation inside the eBPF program. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_perf_prog_read_value(struct bpf_perf_event_data *ctx, struct bpf_perf_event_value *buf, u32 buf_size) -+ * Description -+ * For en eBPF program attached to a perf event, retrieve the -+ * value of the event counter associated to *ctx* and store it in -+ * the structure pointed by *buf* and of size *buf_size*. Enabled -+ * and running times are also stored in the structure (see -+ * description of helper **bpf_perf_event_read_value**\ () for -+ * more details). -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_getsockopt(struct bpf_sock_ops *bpf_socket, int level, int optname, char *optval, int optlen) -+ * Description -+ * Emulate a call to **getsockopt()** on the socket associated to -+ * *bpf_socket*, which must be a full socket. The *level* at -+ * which the option resides and the name *optname* of the option -+ * must be specified, see **getsockopt(2)** for more information. -+ * The retrieved value is stored in the structure pointed by -+ * *opval* and of length *optlen*. -+ * -+ * This helper actually implements a subset of **getsockopt()**. -+ * It supports the following *level*\ s: -+ * -+ * * **IPPROTO_TCP**, which supports *optname* -+ * **TCP_CONGESTION**. -+ * * **IPPROTO_IP**, which supports *optname* **IP_TOS**. -+ * * **IPPROTO_IPV6**, which supports *optname* **IPV6_TCLASS**. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_override_return(struct pt_reg *regs, u64 rc) -+ * Description -+ * Used for error injection, this helper uses kprobes to override -+ * the return value of the probed function, and to set it to *rc*. -+ * The first argument is the context *regs* on which the kprobe -+ * works. -+ * -+ * This helper works by setting setting the PC (program counter) -+ * to an override function which is run in place of the original -+ * probed function. This means the probed function is not run at -+ * all. The replacement function just returns with the required -+ * value. -+ * -+ * This helper has security implications, and thus is subject to -+ * restrictions. It is only available if the kernel was compiled -+ * with the **CONFIG_BPF_KPROBE_OVERRIDE** configuration -+ * option, and in this case it only works on functions tagged with -+ * **ALLOW_ERROR_INJECTION** in the kernel code. -+ * -+ * Also, the helper is only available for the architectures having -+ * the CONFIG_FUNCTION_ERROR_INJECTION option. As of this writing, -+ * x86 architecture is the only one to support this feature. -+ * Return -+ * 0 -+ * -+ * int bpf_sock_ops_cb_flags_set(struct bpf_sock_ops *bpf_sock, int argval) -+ * Description -+ * Attempt to set the value of the **bpf_sock_ops_cb_flags** field -+ * for the full TCP socket associated to *bpf_sock_ops* to -+ * *argval*. -+ * -+ * The primary use of this field is to determine if there should -+ * be calls to eBPF programs of type -+ * **BPF_PROG_TYPE_SOCK_OPS** at various points in the TCP -+ * code. A program of the same type can change its value, per -+ * connection and as necessary, when the connection is -+ * established. This field is directly accessible for reading, but -+ * this helper must be used for updates in order to return an -+ * error if an eBPF program tries to set a callback that is not -+ * supported in the current kernel. -+ * -+ * The supported callback values that *argval* can combine are: -+ * -+ * * **BPF_SOCK_OPS_RTO_CB_FLAG** (retransmission time out) -+ * * **BPF_SOCK_OPS_RETRANS_CB_FLAG** (retransmission) -+ * * **BPF_SOCK_OPS_STATE_CB_FLAG** (TCP state change) -+ * -+ * Here are some examples of where one could call such eBPF -+ * program: -+ * -+ * * When RTO fires. -+ * * When a packet is retransmitted. -+ * * When the connection terminates. -+ * * When a packet is sent. -+ * * When a packet is received. -+ * Return -+ * Code **-EINVAL** if the socket is not a full TCP socket; -+ * otherwise, a positive number containing the bits that could not -+ * be set is returned (which comes down to 0 if all bits were set -+ * as required). -+ * -+ * int bpf_msg_redirect_map(struct sk_msg_buff *msg, struct bpf_map *map, u32 key, u64 flags) -+ * Description -+ * This helper is used in programs implementing policies at the -+ * socket level. If the message *msg* is allowed to pass (i.e. if -+ * the verdict eBPF program returns **SK_PASS**), redirect it to -+ * the socket referenced by *map* (of type -+ * **BPF_MAP_TYPE_SOCKMAP**) at index *key*. Both ingress and -+ * egress interfaces can be used for redirection. The -+ * **BPF_F_INGRESS** value in *flags* is used to make the -+ * distinction (ingress path is selected if the flag is present, -+ * egress path otherwise). This is the only flag supported for now. -+ * Return -+ * **SK_PASS** on success, or **SK_DROP** on error. -+ * -+ * int bpf_msg_apply_bytes(struct sk_msg_buff *msg, u32 bytes) -+ * Description -+ * For socket policies, apply the verdict of the eBPF program to -+ * the next *bytes* (number of bytes) of message *msg*. -+ * -+ * For example, this helper can be used in the following cases: -+ * -+ * * A single **sendmsg**\ () or **sendfile**\ () system call -+ * contains multiple logical messages that the eBPF program is -+ * supposed to read and for which it should apply a verdict. -+ * * An eBPF program only cares to read the first *bytes* of a -+ * *msg*. If the message has a large payload, then setting up -+ * and calling the eBPF program repeatedly for all bytes, even -+ * though the verdict is already known, would create unnecessary -+ * overhead. -+ * -+ * When called from within an eBPF program, the helper sets a -+ * counter internal to the BPF infrastructure, that is used to -+ * apply the last verdict to the next *bytes*. If *bytes* is -+ * smaller than the current data being processed from a -+ * **sendmsg**\ () or **sendfile**\ () system call, the first -+ * *bytes* will be sent and the eBPF program will be re-run with -+ * the pointer for start of data pointing to byte number *bytes* -+ * **+ 1**. If *bytes* is larger than the current data being -+ * processed, then the eBPF verdict will be applied to multiple -+ * **sendmsg**\ () or **sendfile**\ () calls until *bytes* are -+ * consumed. -+ * -+ * Note that if a socket closes with the internal counter holding -+ * a non-zero value, this is not a problem because data is not -+ * being buffered for *bytes* and is sent as it is received. -+ * Return -+ * 0 -+ * -+ * int bpf_msg_cork_bytes(struct sk_msg_buff *msg, u32 bytes) -+ * Description -+ * For socket policies, prevent the execution of the verdict eBPF -+ * program for message *msg* until *bytes* (byte number) have been -+ * accumulated. -+ * -+ * This can be used when one needs a specific number of bytes -+ * before a verdict can be assigned, even if the data spans -+ * multiple **sendmsg**\ () or **sendfile**\ () calls. The extreme -+ * case would be a user calling **sendmsg**\ () repeatedly with -+ * 1-byte long message segments. Obviously, this is bad for -+ * performance, but it is still valid. If the eBPF program needs -+ * *bytes* bytes to validate a header, this helper can be used to -+ * prevent the eBPF program to be called again until *bytes* have -+ * been accumulated. -+ * Return -+ * 0 -+ * -+ * int bpf_msg_pull_data(struct sk_msg_buff *msg, u32 start, u32 end, u64 flags) -+ * Description -+ * For socket policies, pull in non-linear data from user space -+ * for *msg* and set pointers *msg*\ **->data** and *msg*\ -+ * **->data_end** to *start* and *end* bytes offsets into *msg*, -+ * respectively. -+ * -+ * If a program of type **BPF_PROG_TYPE_SK_MSG** is run on a -+ * *msg* it can only parse data that the (**data**, **data_end**) -+ * pointers have already consumed. For **sendmsg**\ () hooks this -+ * is likely the first scatterlist element. But for calls relying -+ * on the **sendpage** handler (e.g. **sendfile**\ ()) this will -+ * be the range (**0**, **0**) because the data is shared with -+ * user space and by default the objective is to avoid allowing -+ * user space to modify data while (or after) eBPF verdict is -+ * being decided. This helper can be used to pull in data and to -+ * set the start and end pointer to given values. Data will be -+ * copied if necessary (i.e. if data was not linear and if start -+ * and end pointers do not point to the same chunk). -+ * -+ * A call to this helper is susceptible to change the underlaying -+ * packet buffer. Therefore, at load time, all checks on pointers -+ * previously done by the verifier are invalidated and must be -+ * performed again, if the helper is used in combination with -+ * direct packet access. -+ * -+ * All values for *flags* are reserved for future usage, and must -+ * be left at zero. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_bind(struct bpf_sock_addr *ctx, struct sockaddr *addr, int addr_len) -+ * Description -+ * Bind the socket associated to *ctx* to the address pointed by -+ * *addr*, of length *addr_len*. This allows for making outgoing -+ * connection from the desired IP address, which can be useful for -+ * example when all processes inside a cgroup should use one -+ * single IP address on a host that has multiple IP configured. -+ * -+ * This helper works for IPv4 and IPv6, TCP and UDP sockets. The -+ * domain (*addr*\ **->sa_family**) must be **AF_INET** (or -+ * **AF_INET6**). Looking for a free port to bind to can be -+ * expensive, therefore binding to port is not permitted by the -+ * helper: *addr*\ **->sin_port** (or **sin6_port**, respectively) -+ * must be set to zero. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_xdp_adjust_tail(struct xdp_buff *xdp_md, int delta) -+ * Description -+ * Adjust (move) *xdp_md*\ **->data_end** by *delta* bytes. It is -+ * only possible to shrink the packet as of this writing, -+ * therefore *delta* must be a negative integer. -+ * -+ * A call to this helper is susceptible to change the underlaying -+ * packet buffer. Therefore, at load time, all checks on pointers -+ * previously done by the verifier are invalidated and must be -+ * performed again, if the helper is used in combination with -+ * direct packet access. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_skb_get_xfrm_state(struct sk_buff *skb, u32 index, struct bpf_xfrm_state *xfrm_state, u32 size, u64 flags) -+ * Description -+ * Retrieve the XFRM state (IP transform framework, see also -+ * **ip-xfrm(8)**) at *index* in XFRM "security path" for *skb*. -+ * -+ * The retrieved value is stored in the **struct bpf_xfrm_state** -+ * pointed by *xfrm_state* and of length *size*. -+ * -+ * All values for *flags* are reserved for future usage, and must -+ * be left at zero. -+ * -+ * This helper is available only if the kernel was compiled with -+ * **CONFIG_XFRM** configuration option. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_get_stack(struct pt_regs *regs, void *buf, u32 size, u64 flags) -+ * Description -+ * Return a user or a kernel stack in bpf program provided buffer. -+ * To achieve this, the helper needs *ctx*, which is a pointer -+ * to the context on which the tracing program is executed. -+ * To store the stacktrace, the bpf program provides *buf* with -+ * a nonnegative *size*. -+ * -+ * The last argument, *flags*, holds the number of stack frames to -+ * skip (from 0 to 255), masked with -+ * **BPF_F_SKIP_FIELD_MASK**. The next bits can be used to set -+ * the following flags: -+ * -+ * **BPF_F_USER_STACK** -+ * Collect a user space stack instead of a kernel stack. -+ * **BPF_F_USER_BUILD_ID** -+ * Collect buildid+offset instead of ips for user stack, -+ * only valid if **BPF_F_USER_STACK** is also specified. -+ * -+ * **bpf_get_stack**\ () can collect up to -+ * **PERF_MAX_STACK_DEPTH** both kernel and user frames, subject -+ * to sufficient large buffer size. Note that -+ * this limit can be controlled with the **sysctl** program, and -+ * that it should be manually increased in order to profile long -+ * user stacks (such as stacks for Java programs). To do so, use: -+ * -+ * :: -+ * -+ * # sysctl kernel.perf_event_max_stack= -+ * Return -+ * A non-negative value equal to or less than *size* on success, -+ * or a negative error in case of failure. -+ * -+ * int bpf_skb_load_bytes_relative(const struct sk_buff *skb, u32 offset, void *to, u32 len, u32 start_header) -+ * Description -+ * This helper is similar to **bpf_skb_load_bytes**\ () in that -+ * it provides an easy way to load *len* bytes from *offset* -+ * from the packet associated to *skb*, into the buffer pointed -+ * by *to*. The difference to **bpf_skb_load_bytes**\ () is that -+ * a fifth argument *start_header* exists in order to select a -+ * base offset to start from. *start_header* can be one of: -+ * -+ * **BPF_HDR_START_MAC** -+ * Base offset to load data from is *skb*'s mac header. -+ * **BPF_HDR_START_NET** -+ * Base offset to load data from is *skb*'s network header. -+ * -+ * In general, "direct packet access" is the preferred method to -+ * access packet data, however, this helper is in particular useful -+ * in socket filters where *skb*\ **->data** does not always point -+ * to the start of the mac header and where "direct packet access" -+ * is not available. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_fib_lookup(void *ctx, struct bpf_fib_lookup *params, int plen, u32 flags) -+ * Description -+ * Do FIB lookup in kernel tables using parameters in *params*. -+ * If lookup is successful and result shows packet is to be -+ * forwarded, the neighbor tables are searched for the nexthop. -+ * If successful (ie., FIB lookup shows forwarding and nexthop -+ * is resolved), the nexthop address is returned in ipv4_dst -+ * or ipv6_dst based on family, smac is set to mac address of -+ * egress device, dmac is set to nexthop mac address, rt_metric -+ * is set to metric from route (IPv4/IPv6 only), and ifindex -+ * is set to the device index of the nexthop from the FIB lookup. -+ * -+ * *plen* argument is the size of the passed in struct. -+ * *flags* argument can be a combination of one or more of the -+ * following values: -+ * -+ * **BPF_FIB_LOOKUP_DIRECT** -+ * Do a direct table lookup vs full lookup using FIB -+ * rules. -+ * **BPF_FIB_LOOKUP_OUTPUT** -+ * Perform lookup from an egress perspective (default is -+ * ingress). -+ * -+ * *ctx* is either **struct xdp_md** for XDP programs or -+ * **struct sk_buff** tc cls_act programs. -+ * Return -+ * * < 0 if any input argument is invalid -+ * * 0 on success (packet is forwarded, nexthop neighbor exists) -+ * * > 0 one of **BPF_FIB_LKUP_RET_** codes explaining why the -+ * packet is not forwarded or needs assist from full stack -+ * -+ * int bpf_sock_hash_update(struct bpf_sock_ops_kern *skops, struct bpf_map *map, void *key, u64 flags) -+ * Description -+ * Add an entry to, or update a sockhash *map* referencing sockets. -+ * The *skops* is used as a new value for the entry associated to -+ * *key*. *flags* is one of: -+ * -+ * **BPF_NOEXIST** -+ * The entry for *key* must not exist in the map. -+ * **BPF_EXIST** -+ * The entry for *key* must already exist in the map. -+ * **BPF_ANY** -+ * No condition on the existence of the entry for *key*. -+ * -+ * If the *map* has eBPF programs (parser and verdict), those will -+ * be inherited by the socket being added. If the socket is -+ * already attached to eBPF programs, this results in an error. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_msg_redirect_hash(struct sk_msg_buff *msg, struct bpf_map *map, void *key, u64 flags) -+ * Description -+ * This helper is used in programs implementing policies at the -+ * socket level. If the message *msg* is allowed to pass (i.e. if -+ * the verdict eBPF program returns **SK_PASS**), redirect it to -+ * the socket referenced by *map* (of type -+ * **BPF_MAP_TYPE_SOCKHASH**) using hash *key*. Both ingress and -+ * egress interfaces can be used for redirection. The -+ * **BPF_F_INGRESS** value in *flags* is used to make the -+ * distinction (ingress path is selected if the flag is present, -+ * egress path otherwise). This is the only flag supported for now. -+ * Return -+ * **SK_PASS** on success, or **SK_DROP** on error. -+ * -+ * int bpf_sk_redirect_hash(struct sk_buff *skb, struct bpf_map *map, void *key, u64 flags) -+ * Description -+ * This helper is used in programs implementing policies at the -+ * skb socket level. If the sk_buff *skb* is allowed to pass (i.e. -+ * if the verdeict eBPF program returns **SK_PASS**), redirect it -+ * to the socket referenced by *map* (of type -+ * **BPF_MAP_TYPE_SOCKHASH**) using hash *key*. Both ingress and -+ * egress interfaces can be used for redirection. The -+ * **BPF_F_INGRESS** value in *flags* is used to make the -+ * distinction (ingress path is selected if the flag is present, -+ * egress otherwise). This is the only flag supported for now. -+ * Return -+ * **SK_PASS** on success, or **SK_DROP** on error. -+ * -+ * int bpf_lwt_push_encap(struct sk_buff *skb, u32 type, void *hdr, u32 len) -+ * Description -+ * Encapsulate the packet associated to *skb* within a Layer 3 -+ * protocol header. This header is provided in the buffer at -+ * address *hdr*, with *len* its size in bytes. *type* indicates -+ * the protocol of the header and can be one of: -+ * -+ * **BPF_LWT_ENCAP_SEG6** -+ * IPv6 encapsulation with Segment Routing Header -+ * (**struct ipv6_sr_hdr**). *hdr* only contains the SRH, -+ * the IPv6 header is computed by the kernel. -+ * **BPF_LWT_ENCAP_SEG6_INLINE** -+ * Only works if *skb* contains an IPv6 packet. Insert a -+ * Segment Routing Header (**struct ipv6_sr_hdr**) inside -+ * the IPv6 header. -+ * -+ * A call to this helper is susceptible to change the underlaying -+ * packet buffer. Therefore, at load time, all checks on pointers -+ * previously done by the verifier are invalidated and must be -+ * performed again, if the helper is used in combination with -+ * direct packet access. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_lwt_seg6_store_bytes(struct sk_buff *skb, u32 offset, const void *from, u32 len) -+ * Description -+ * Store *len* bytes from address *from* into the packet -+ * associated to *skb*, at *offset*. Only the flags, tag and TLVs -+ * inside the outermost IPv6 Segment Routing Header can be -+ * modified through this helper. -+ * -+ * A call to this helper is susceptible to change the underlaying -+ * packet buffer. Therefore, at load time, all checks on pointers -+ * previously done by the verifier are invalidated and must be -+ * performed again, if the helper is used in combination with -+ * direct packet access. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_lwt_seg6_adjust_srh(struct sk_buff *skb, u32 offset, s32 delta) -+ * Description -+ * Adjust the size allocated to TLVs in the outermost IPv6 -+ * Segment Routing Header contained in the packet associated to -+ * *skb*, at position *offset* by *delta* bytes. Only offsets -+ * after the segments are accepted. *delta* can be as well -+ * positive (growing) as negative (shrinking). -+ * -+ * A call to this helper is susceptible to change the underlaying -+ * packet buffer. Therefore, at load time, all checks on pointers -+ * previously done by the verifier are invalidated and must be -+ * performed again, if the helper is used in combination with -+ * direct packet access. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_lwt_seg6_action(struct sk_buff *skb, u32 action, void *param, u32 param_len) -+ * Description -+ * Apply an IPv6 Segment Routing action of type *action* to the -+ * packet associated to *skb*. Each action takes a parameter -+ * contained at address *param*, and of length *param_len* bytes. -+ * *action* can be one of: -+ * -+ * **SEG6_LOCAL_ACTION_END_X** -+ * End.X action: Endpoint with Layer-3 cross-connect. -+ * Type of *param*: **struct in6_addr**. -+ * **SEG6_LOCAL_ACTION_END_T** -+ * End.T action: Endpoint with specific IPv6 table lookup. -+ * Type of *param*: **int**. -+ * **SEG6_LOCAL_ACTION_END_B6** -+ * End.B6 action: Endpoint bound to an SRv6 policy. -+ * Type of param: **struct ipv6_sr_hdr**. -+ * **SEG6_LOCAL_ACTION_END_B6_ENCAP** -+ * End.B6.Encap action: Endpoint bound to an SRv6 -+ * encapsulation policy. -+ * Type of param: **struct ipv6_sr_hdr**. -+ * -+ * A call to this helper is susceptible to change the underlaying -+ * packet buffer. Therefore, at load time, all checks on pointers -+ * previously done by the verifier are invalidated and must be -+ * performed again, if the helper is used in combination with -+ * direct packet access. -+ * Return -+ * 0 on success, or a negative error in case of failure. -+ * -+ * int bpf_rc_keydown(void *ctx, u32 protocol, u64 scancode, u32 toggle) -+ * Description -+ * This helper is used in programs implementing IR decoding, to -+ * report a successfully decoded key press with *scancode*, -+ * *toggle* value in the given *protocol*. The scancode will be -+ * translated to a keycode using the rc keymap, and reported as -+ * an input key down event. After a period a key up event is -+ * generated. This period can be extended by calling either -+ * **bpf_rc_keydown** () again with the same values, or calling -+ * **bpf_rc_repeat** (). -+ * -+ * Some protocols include a toggle bit, in case the button was -+ * released and pressed again between consecutive scancodes. -+ * -+ * The *ctx* should point to the lirc sample as passed into -+ * the program. -+ * -+ * The *protocol* is the decoded protocol number (see -+ * **enum rc_proto** for some predefined values). -+ * -+ * This helper is only available is the kernel was compiled with -+ * the **CONFIG_BPF_LIRC_MODE2** configuration option set to -+ * "**y**". -+ * Return -+ * 0 -+ * -+ * int bpf_rc_repeat(void *ctx) -+ * Description -+ * This helper is used in programs implementing IR decoding, to -+ * report a successfully decoded repeat key message. This delays -+ * the generation of a key up event for previously generated -+ * key down event. -+ * -+ * Some IR protocols like NEC have a special IR message for -+ * repeating last button, for when a button is held down. -+ * -+ * The *ctx* should point to the lirc sample as passed into -+ * the program. -+ * -+ * This helper is only available is the kernel was compiled with -+ * the **CONFIG_BPF_LIRC_MODE2** configuration option set to -+ * "**y**". -+ * Return -+ * 0 -+ * -+ * uint64_t bpf_skb_cgroup_id(struct sk_buff *skb) -+ * Description -+ * Return the cgroup v2 id of the socket associated with the *skb*. -+ * This is roughly similar to the **bpf_get_cgroup_classid**\ () -+ * helper for cgroup v1 by providing a tag resp. identifier that -+ * can be matched on or used for map lookups e.g. to implement -+ * policy. The cgroup v2 id of a given path in the hierarchy is -+ * exposed in user space through the f_handle API in order to get -+ * to the same 64-bit id. -+ * -+ * This helper can be used on TC egress path, but not on ingress, -+ * and is available only if the kernel was compiled with the -+ * **CONFIG_SOCK_CGROUP_DATA** configuration option. -+ * Return -+ * The id is returned or 0 in case the id could not be retrieved. -+ * -+ * u64 bpf_get_current_cgroup_id(void) -+ * Return -+ * A 64-bit integer containing the current cgroup id based -+ * on the cgroup within which the current task is running. - */ - #define __BPF_FUNC_MAPPER(FN) \ - FN(unspec), \ -@@ -638,6 +2131,33 @@ union bpf_attr { - FN(redirect_map), \ - FN(sk_redirect_map), \ - FN(sock_map_update), \ -+ FN(xdp_adjust_meta), \ -+ FN(perf_event_read_value), \ -+ FN(perf_prog_read_value), \ -+ FN(getsockopt), \ -+ FN(override_return), \ -+ FN(sock_ops_cb_flags_set), \ -+ FN(msg_redirect_map), \ -+ FN(msg_apply_bytes), \ -+ FN(msg_cork_bytes), \ -+ FN(msg_pull_data), \ -+ FN(bind), \ -+ FN(xdp_adjust_tail), \ -+ FN(skb_get_xfrm_state), \ -+ FN(get_stack), \ -+ FN(skb_load_bytes_relative), \ -+ FN(fib_lookup), \ -+ FN(sock_hash_update), \ -+ FN(msg_redirect_hash), \ -+ FN(sk_redirect_hash), \ -+ FN(lwt_push_encap), \ -+ FN(lwt_seg6_store_bytes), \ -+ FN(lwt_seg6_adjust_srh), \ -+ FN(lwt_seg6_action), \ -+ FN(rc_repeat), \ -+ FN(rc_keydown), \ -+ FN(skb_cgroup_id), \ -+ FN(get_current_cgroup_id), - - /* integer value in 'imm' field of BPF_CALL instruction selects which helper - * function eBPF program intends to call -@@ -671,17 +2191,23 @@ enum bpf_func_id { - /* 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. */ -+/* flags for both BPF_FUNC_get_stackid and BPF_FUNC_get_stack. */ - #define BPF_F_SKIP_FIELD_MASK 0xffULL - #define BPF_F_USER_STACK (1ULL << 8) -+/* flags used by BPF_FUNC_get_stackid only. */ - #define BPF_F_FAST_STACK_CMP (1ULL << 9) - #define BPF_F_REUSE_STACKID (1ULL << 10) -+/* flags used by BPF_FUNC_get_stack only. */ -+#define BPF_F_USER_BUILD_ID (1ULL << 11) - - /* BPF_FUNC_skb_set_tunnel_key flags. */ - #define BPF_F_ZERO_CSUM_TX (1ULL << 1) - #define BPF_F_DONT_FRAGMENT (1ULL << 2) -+#define BPF_F_SEQ_NUMBER (1ULL << 3) - --/* BPF_FUNC_perf_event_output and BPF_FUNC_perf_event_read flags. */ -+/* BPF_FUNC_perf_event_output, BPF_FUNC_perf_event_read and -+ * BPF_FUNC_perf_event_read_value flags. -+ */ - #define BPF_F_INDEX_MASK 0xffffffffULL - #define BPF_F_CURRENT_CPU BPF_F_INDEX_MASK - /* BPF_FUNC_perf_event_output for sk_buff input context. */ -@@ -692,6 +2218,18 @@ enum bpf_adj_room_mode { - BPF_ADJ_ROOM_NET, - }; - -+/* Mode for BPF_FUNC_skb_load_bytes_relative helper. */ -+enum bpf_hdr_start_off { -+ BPF_HDR_START_MAC, -+ BPF_HDR_START_NET, -+}; -+ -+/* Encapsulation type for BPF_FUNC_lwt_push_encap helper. */ -+enum bpf_lwt_encap_mode { -+ BPF_LWT_ENCAP_SEG6, -+ BPF_LWT_ENCAP_SEG6_INLINE -+}; -+ - /* user accessible mirror of in-kernel sk_buff. - * new fields can only be added to the end of this structure - */ -@@ -715,7 +2253,7 @@ struct __sk_buff { - __u32 data_end; - __u32 napi_id; - -- /* accessed by BPF_PROG_TYPE_sk_skb types */ -+ /* Accessed by BPF_PROG_TYPE_sk_skb types from here to ... */ - __u32 family; - __u32 remote_ip4; /* Stored in network byte order */ - __u32 local_ip4; /* Stored in network byte order */ -@@ -723,6 +2261,9 @@ struct __sk_buff { - __u32 local_ip6[4]; /* Stored in network byte order */ - __u32 remote_port; /* Stored in network byte order */ - __u32 local_port; /* stored in host byte order */ -+ /* ... here. */ -+ -+ __u32 data_meta; - }; - - struct bpf_tunnel_key { -@@ -733,10 +2274,24 @@ struct bpf_tunnel_key { - }; - __u8 tunnel_tos; - __u8 tunnel_ttl; -- __u16 tunnel_ext; -+ __u16 tunnel_ext; /* Padding, future use. */ - __u32 tunnel_label; - }; - -+/* user accessible mirror of in-kernel xfrm_state. -+ * new fields can only be added to the end of this structure -+ */ -+struct bpf_xfrm_state { -+ __u32 reqid; -+ __u32 spi; /* Stored in network byte order */ -+ __u16 family; -+ __u16 ext; /* Padding, future use. */ -+ union { -+ __u32 remote_ipv4; /* Stored in network byte order */ -+ __u32 remote_ipv6[4]; /* Stored in network byte order */ -+ }; -+}; -+ - /* Generic BPF return codes which all BPF program types may support. - * The values are binary compatible with their TC_ACT_* counter-part to - * provide backwards compatibility with existing SCHED_CLS and SCHED_ACT -@@ -760,6 +2315,15 @@ struct bpf_sock { - __u32 protocol; - __u32 mark; - __u32 priority; -+ __u32 src_ip4; /* Allows 1,2,4-byte read. -+ * Stored in network byte order. -+ */ -+ __u32 src_ip6[4]; /* Allows 1,2,4-byte read. -+ * Stored in network byte order. -+ */ -+ __u32 src_port; /* Allows 4-byte read. -+ * Stored in host byte order -+ */ - }; - - #define XDP_PACKET_HEADROOM 256 -@@ -783,12 +2347,31 @@ enum xdp_action { - struct xdp_md { - __u32 data; - __u32 data_end; -+ __u32 data_meta; -+ /* Below access go through struct xdp_rxq_info */ -+ __u32 ingress_ifindex; /* rxq->dev->ifindex */ -+ __u32 rx_queue_index; /* rxq->queue_index */ - }; - - enum sk_action { -- SK_ABORTED = 0, -- SK_DROP, -- SK_REDIRECT, -+ SK_DROP = 0, -+ SK_PASS, -+}; -+ -+/* user accessible metadata for SK_MSG packet hook, new fields must -+ * be added to the end of this structure -+ */ -+struct sk_msg_md { -+ void *data; -+ void *data_end; -+ -+ __u32 family; -+ __u32 remote_ip4; /* Stored in network byte order */ -+ __u32 local_ip4; /* Stored in network byte order */ -+ __u32 remote_ip6[4]; /* Stored in network byte order */ -+ __u32 local_ip6[4]; /* Stored in network byte order */ -+ __u32 remote_port; /* Stored in network byte order */ -+ __u32 local_port; /* stored in host byte order */ - }; - - #define BPF_TAG_SIZE 8 -@@ -801,6 +2384,19 @@ struct bpf_prog_info { - __u32 xlated_prog_len; - __aligned_u64 jited_prog_insns; - __aligned_u64 xlated_prog_insns; -+ __u64 load_time; /* ns since boottime */ -+ __u32 created_by_uid; -+ __u32 nr_map_ids; -+ __aligned_u64 map_ids; -+ char name[BPF_OBJ_NAME_LEN]; -+ __u32 ifindex; -+ __u32 gpl_compatible:1; -+ __u64 netns_dev; -+ __u64 netns_ino; -+ __u32 nr_jited_ksyms; -+ __u32 nr_jited_func_lens; -+ __aligned_u64 jited_ksyms; -+ __aligned_u64 jited_func_lens; - } __attribute__((aligned(8))); - - struct bpf_map_info { -@@ -810,8 +2406,48 @@ struct bpf_map_info { - __u32 value_size; - __u32 max_entries; - __u32 map_flags; -+ char name[BPF_OBJ_NAME_LEN]; -+ __u32 ifindex; -+ __u32 :32; -+ __u64 netns_dev; -+ __u64 netns_ino; -+ __u32 btf_id; -+ __u32 btf_key_type_id; -+ __u32 btf_value_type_id; -+} __attribute__((aligned(8))); -+ -+struct bpf_btf_info { -+ __aligned_u64 btf; -+ __u32 btf_size; -+ __u32 id; - } __attribute__((aligned(8))); - -+/* User bpf_sock_addr struct to access socket fields and sockaddr struct passed -+ * by user and intended to be used by socket (e.g. to bind to, depends on -+ * attach attach type). -+ */ -+struct bpf_sock_addr { -+ __u32 user_family; /* Allows 4-byte read, but no write. */ -+ __u32 user_ip4; /* Allows 1,2,4-byte read and 4-byte write. -+ * Stored in network byte order. -+ */ -+ __u32 user_ip6[4]; /* Allows 1,2,4-byte read an 4-byte write. -+ * Stored in network byte order. -+ */ -+ __u32 user_port; /* Allows 4-byte read and write. -+ * Stored in network byte order -+ */ -+ __u32 family; /* Allows 4-byte read, but no write */ -+ __u32 type; /* Allows 4-byte read, but no write */ -+ __u32 protocol; /* Allows 4-byte read, but no write */ -+ __u32 msg_src_ip4; /* Allows 1,2,4-byte read an 4-byte write. -+ * Stored in network byte order. -+ */ -+ __u32 msg_src_ip6[4]; /* Allows 1,2,4-byte read an 4-byte write. -+ * Stored in network byte order. -+ */ -+}; -+ - /* User bpf_sock_ops struct to access socket values and specify request ops - * and their replies. - * Some of this fields are in network (bigendian) byte order and may need -@@ -821,8 +2457,9 @@ struct bpf_map_info { - struct bpf_sock_ops { - __u32 op; - union { -- __u32 reply; -- __u32 replylong[4]; -+ __u32 args[4]; /* Optionally passed to bpf program */ -+ __u32 reply; /* Returned by bpf program */ -+ __u32 replylong[4]; /* Optionally returned by bpf prog */ - }; - __u32 family; - __u32 remote_ip4; /* Stored in network byte order */ -@@ -831,8 +2468,45 @@ struct bpf_sock_ops { - __u32 local_ip6[4]; /* Stored in network byte order */ - __u32 remote_port; /* Stored in network byte order */ - __u32 local_port; /* stored in host byte order */ -+ __u32 is_fullsock; /* Some TCP fields are only valid if -+ * there is a full socket. If not, the -+ * fields read as zero. -+ */ -+ __u32 snd_cwnd; -+ __u32 srtt_us; /* Averaged RTT << 3 in usecs */ -+ __u32 bpf_sock_ops_cb_flags; /* flags defined in uapi/linux/tcp.h */ -+ __u32 state; -+ __u32 rtt_min; -+ __u32 snd_ssthresh; -+ __u32 rcv_nxt; -+ __u32 snd_nxt; -+ __u32 snd_una; -+ __u32 mss_cache; -+ __u32 ecn_flags; -+ __u32 rate_delivered; -+ __u32 rate_interval_us; -+ __u32 packets_out; -+ __u32 retrans_out; -+ __u32 total_retrans; -+ __u32 segs_in; -+ __u32 data_segs_in; -+ __u32 segs_out; -+ __u32 data_segs_out; -+ __u32 lost_out; -+ __u32 sacked_out; -+ __u32 sk_txhash; -+ __u64 bytes_received; -+ __u64 bytes_acked; - }; - -+/* Definitions for bpf_sock_ops_cb_flags */ -+#define BPF_SOCK_OPS_RTO_CB_FLAG (1<<0) -+#define BPF_SOCK_OPS_RETRANS_CB_FLAG (1<<1) -+#define BPF_SOCK_OPS_STATE_CB_FLAG (1<<2) -+#define BPF_SOCK_OPS_ALL_CB_FLAGS 0x7 /* Mask of all currently -+ * supported cb flags -+ */ -+ - /* List of known BPF sock_ops operators. - * New entries can only be added at the end - */ -@@ -859,9 +2533,156 @@ enum { - BPF_SOCK_OPS_NEEDS_ECN, /* If connection's congestion control - * needs ECN - */ -+ BPF_SOCK_OPS_BASE_RTT, /* Get base RTT. The correct value is -+ * based on the path and may be -+ * dependent on the congestion control -+ * algorithm. In general it indicates -+ * a congestion threshold. RTTs above -+ * this indicate congestion -+ */ -+ BPF_SOCK_OPS_RTO_CB, /* Called when an RTO has triggered. -+ * Arg1: value of icsk_retransmits -+ * Arg2: value of icsk_rto -+ * Arg3: whether RTO has expired -+ */ -+ BPF_SOCK_OPS_RETRANS_CB, /* Called when skb is retransmitted. -+ * Arg1: sequence number of 1st byte -+ * Arg2: # segments -+ * Arg3: return value of -+ * tcp_transmit_skb (0 => success) -+ */ -+ BPF_SOCK_OPS_STATE_CB, /* Called when TCP changes state. -+ * Arg1: old_state -+ * Arg2: new_state -+ */ -+ BPF_SOCK_OPS_TCP_LISTEN_CB, /* Called on listen(2), right after -+ * socket transition to LISTEN state. -+ */ -+}; -+ -+/* List of TCP states. There is a build check in net/ipv4/tcp.c to detect -+ * changes between the TCP and BPF versions. Ideally this should never happen. -+ * If it does, we need to add code to convert them before calling -+ * the BPF sock_ops function. -+ */ -+enum { -+ BPF_TCP_ESTABLISHED = 1, -+ BPF_TCP_SYN_SENT, -+ BPF_TCP_SYN_RECV, -+ BPF_TCP_FIN_WAIT1, -+ BPF_TCP_FIN_WAIT2, -+ BPF_TCP_TIME_WAIT, -+ BPF_TCP_CLOSE, -+ BPF_TCP_CLOSE_WAIT, -+ BPF_TCP_LAST_ACK, -+ BPF_TCP_LISTEN, -+ BPF_TCP_CLOSING, /* Now a valid state */ -+ BPF_TCP_NEW_SYN_RECV, -+ -+ BPF_TCP_MAX_STATES /* Leave at the end! */ - }; - - #define TCP_BPF_IW 1001 /* Set TCP initial congestion window */ - #define TCP_BPF_SNDCWND_CLAMP 1002 /* Set sndcwnd_clamp */ - -+struct bpf_perf_event_value { -+ __u64 counter; -+ __u64 enabled; -+ __u64 running; -+}; -+ -+#define BPF_DEVCG_ACC_MKNOD (1ULL << 0) -+#define BPF_DEVCG_ACC_READ (1ULL << 1) -+#define BPF_DEVCG_ACC_WRITE (1ULL << 2) -+ -+#define BPF_DEVCG_DEV_BLOCK (1ULL << 0) -+#define BPF_DEVCG_DEV_CHAR (1ULL << 1) -+ -+struct bpf_cgroup_dev_ctx { -+ /* access_type encoded as (BPF_DEVCG_ACC_* << 16) | BPF_DEVCG_DEV_* */ -+ __u32 access_type; -+ __u32 major; -+ __u32 minor; -+}; -+ -+struct bpf_raw_tracepoint_args { -+ __u64 args[0]; -+}; -+ -+/* DIRECT: Skip the FIB rules and go to FIB table associated with device -+ * OUTPUT: Do lookup from egress perspective; default is ingress -+ */ -+#define BPF_FIB_LOOKUP_DIRECT BIT(0) -+#define BPF_FIB_LOOKUP_OUTPUT BIT(1) -+ -+enum { -+ BPF_FIB_LKUP_RET_SUCCESS, /* lookup successful */ -+ BPF_FIB_LKUP_RET_BLACKHOLE, /* dest is blackholed; can be dropped */ -+ BPF_FIB_LKUP_RET_UNREACHABLE, /* dest is unreachable; can be dropped */ -+ BPF_FIB_LKUP_RET_PROHIBIT, /* dest not allowed; can be dropped */ -+ BPF_FIB_LKUP_RET_NOT_FWDED, /* packet is not forwarded */ -+ BPF_FIB_LKUP_RET_FWD_DISABLED, /* fwding is not enabled on ingress */ -+ BPF_FIB_LKUP_RET_UNSUPP_LWT, /* fwd requires encapsulation */ -+ BPF_FIB_LKUP_RET_NO_NEIGH, /* no neighbor entry for nh */ -+ BPF_FIB_LKUP_RET_FRAG_NEEDED, /* fragmentation required to fwd */ -+}; -+ -+struct bpf_fib_lookup { -+ /* input: network family for lookup (AF_INET, AF_INET6) -+ * output: network family of egress nexthop -+ */ -+ __u8 family; -+ -+ /* set if lookup is to consider L4 data - e.g., FIB rules */ -+ __u8 l4_protocol; -+ __be16 sport; -+ __be16 dport; -+ -+ /* total length of packet from network header - used for MTU check */ -+ __u16 tot_len; -+ -+ /* input: L3 device index for lookup -+ * output: device index from FIB lookup -+ */ -+ __u32 ifindex; -+ -+ union { -+ /* inputs to lookup */ -+ __u8 tos; /* AF_INET */ -+ __be32 flowinfo; /* AF_INET6, flow_label + priority */ -+ -+ /* output: metric of fib result (IPv4/IPv6 only) */ -+ __u32 rt_metric; -+ }; -+ -+ union { -+ __be32 ipv4_src; -+ __u32 ipv6_src[4]; /* in6_addr; network order */ -+ }; -+ -+ /* input to bpf_fib_lookup, ipv{4,6}_dst is destination address in -+ * network header. output: bpf_fib_lookup sets to gateway address -+ * if FIB lookup returns gateway route -+ */ -+ union { -+ __be32 ipv4_dst; -+ __u32 ipv6_dst[4]; /* in6_addr; network order */ -+ }; -+ -+ /* output */ -+ __be16 h_vlan_proto; -+ __be16 h_vlan_TCI; -+ __u8 smac[6]; /* ETH_ALEN */ -+ __u8 dmac[6]; /* ETH_ALEN */ -+}; -+ -+enum bpf_task_fd_type { -+ BPF_FD_TYPE_RAW_TRACEPOINT, /* tp name */ -+ BPF_FD_TYPE_TRACEPOINT, /* tp name */ -+ BPF_FD_TYPE_KPROBE, /* (symbol + offset) or addr */ -+ BPF_FD_TYPE_KRETPROBE, /* (symbol + offset) or addr */ -+ BPF_FD_TYPE_UPROBE, /* filename + offset */ -+ BPF_FD_TYPE_URETPROBE, /* filename + offset */ -+}; -+ - #endif /* __LINUX_BPF_H__ */ -diff --git a/include/uapi/linux/bpf_common.h b/include/uapi/linux/bpf_common.h -index afe7433b9891f..f0fe1394971d1 100644 ---- a/include/uapi/linux/bpf_common.h -+++ b/include/uapi/linux/bpf_common.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_BPF_COMMON_H__ - #define __LINUX_BPF_COMMON_H__ - -@@ -14,9 +15,10 @@ - - /* ld/ldx fields */ - #define BPF_SIZE(code) ((code) & 0x18) --#define BPF_W 0x00 --#define BPF_H 0x08 --#define BPF_B 0x10 -+#define BPF_W 0x00 /* 32-bit */ -+#define BPF_H 0x08 /* 16-bit */ -+#define BPF_B 0x10 /* 8-bit */ -+/* eBPF BPF_DW 0x18 64-bit */ - #define BPF_MODE(code) ((code) & 0xe0) - #define BPF_IMM 0x00 - #define BPF_ABS 0x20 -diff --git a/include/uapi/linux/btf.h b/include/uapi/linux/btf.h -new file mode 100644 -index 0000000000000..5dd580a6726cd ---- /dev/null -+++ b/include/uapi/linux/btf.h -@@ -0,0 +1,113 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+/* Copyright (c) 2018 Facebook */ -+#ifndef __LINUX_BTF_H__ -+#define __LINUX_BTF_H__ -+ -+#include -+ -+#define BTF_MAGIC 0xeB9F -+#define BTF_VERSION 1 -+ -+struct btf_header { -+ __u16 magic; -+ __u8 version; -+ __u8 flags; -+ __u32 hdr_len; -+ -+ /* All offsets are in bytes relative to the end of this header */ -+ __u32 type_off; /* offset of type section */ -+ __u32 type_len; /* length of type section */ -+ __u32 str_off; /* offset of string section */ -+ __u32 str_len; /* length of string section */ -+}; -+ -+/* Max # of type identifier */ -+#define BTF_MAX_TYPE 0x0000ffff -+/* Max offset into the string section */ -+#define BTF_MAX_NAME_OFFSET 0x0000ffff -+/* Max # of struct/union/enum members or func args */ -+#define BTF_MAX_VLEN 0xffff -+ -+struct btf_type { -+ __u32 name_off; -+ /* "info" bits arrangement -+ * bits 0-15: vlen (e.g. # of struct's members) -+ * bits 16-23: unused -+ * bits 24-27: kind (e.g. int, ptr, array...etc) -+ * bits 28-31: unused -+ */ -+ __u32 info; -+ /* "size" is used by INT, ENUM, STRUCT and UNION. -+ * "size" tells the size of the type it is describing. -+ * -+ * "type" is used by PTR, TYPEDEF, VOLATILE, CONST and RESTRICT. -+ * "type" is a type_id referring to another type. -+ */ -+ union { -+ __u32 size; -+ __u32 type; -+ }; -+}; -+ -+#define BTF_INFO_KIND(info) (((info) >> 24) & 0x0f) -+#define BTF_INFO_VLEN(info) ((info) & 0xffff) -+ -+#define BTF_KIND_UNKN 0 /* Unknown */ -+#define BTF_KIND_INT 1 /* Integer */ -+#define BTF_KIND_PTR 2 /* Pointer */ -+#define BTF_KIND_ARRAY 3 /* Array */ -+#define BTF_KIND_STRUCT 4 /* Struct */ -+#define BTF_KIND_UNION 5 /* Union */ -+#define BTF_KIND_ENUM 6 /* Enumeration */ -+#define BTF_KIND_FWD 7 /* Forward */ -+#define BTF_KIND_TYPEDEF 8 /* Typedef */ -+#define BTF_KIND_VOLATILE 9 /* Volatile */ -+#define BTF_KIND_CONST 10 /* Const */ -+#define BTF_KIND_RESTRICT 11 /* Restrict */ -+#define BTF_KIND_MAX 11 -+#define NR_BTF_KINDS 12 -+ -+/* For some specific BTF_KIND, "struct btf_type" is immediately -+ * followed by extra data. -+ */ -+ -+/* BTF_KIND_INT is followed by a u32 and the following -+ * is the 32 bits arrangement: -+ */ -+#define BTF_INT_ENCODING(VAL) (((VAL) & 0x0f000000) >> 24) -+#define BTF_INT_OFFSET(VAL) (((VAL & 0x00ff0000)) >> 16) -+#define BTF_INT_BITS(VAL) ((VAL) & 0x0000ffff) -+ -+/* Attributes stored in the BTF_INT_ENCODING */ -+#define BTF_INT_SIGNED (1 << 0) -+#define BTF_INT_CHAR (1 << 1) -+#define BTF_INT_BOOL (1 << 2) -+ -+/* BTF_KIND_ENUM is followed by multiple "struct btf_enum". -+ * The exact number of btf_enum is stored in the vlen (of the -+ * info in "struct btf_type"). -+ */ -+struct btf_enum { -+ __u32 name_off; -+ __s32 val; -+}; -+ -+/* BTF_KIND_ARRAY is followed by one "struct btf_array" */ -+struct btf_array { -+ __u32 type; -+ __u32 index_type; -+ __u32 nelems; -+}; -+ -+/* BTF_KIND_STRUCT and BTF_KIND_UNION are followed -+ * by multiple "struct btf_member". The exact number -+ * of btf_member is stored in the vlen (of the info in -+ * "struct btf_type"). -+ */ -+struct btf_member { -+ __u32 name_off; -+ __u32 type; -+ __u32 offset; /* offset in bits */ -+}; -+ -+#endif /* __LINUX_BTF_H__ */ -diff --git a/include/uapi/linux/can.h b/include/uapi/linux/can.h -index f7a810debb0e8..4d1ab8e7a4984 100644 ---- a/include/uapi/linux/can.h -+++ b/include/uapi/linux/can.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ - /* - * linux/can.h - * -diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netlink.h -index b9214bd7aa2bc..f0c5e58b8ee76 100644 ---- a/include/uapi/linux/can/netlink.h -+++ b/include/uapi/linux/can/netlink.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* - * linux/can/netlink.h - * -@@ -131,6 +132,7 @@ enum { - IFLA_CAN_TERMINATION_CONST, - IFLA_CAN_BITRATE_CONST, - IFLA_CAN_DATA_BITRATE_CONST, -+ IFLA_CAN_BITRATE_MAX, - __IFLA_CAN_MAX - }; - -diff --git a/include/uapi/linux/can/vxcan.h b/include/uapi/linux/can/vxcan.h -index 5b29e8a7bc274..b364d775553c6 100644 ---- a/include/uapi/linux/can/vxcan.h -+++ b/include/uapi/linux/can/vxcan.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _CAN_VXCAN_H - #define _CAN_VXCAN_H - -diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h -index a62695e2d86e8..5ee0e7397591a 100644 ---- a/include/uapi/linux/devlink.h -+++ b/include/uapi/linux/devlink.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ - /* - * include/uapi/linux/devlink.h - Network physical device Netlink interface - * Copyright (c) 2016 Mellanox Technologies. All rights reserved. -@@ -69,6 +70,24 @@ enum devlink_command { - DEVLINK_CMD_DPIPE_ENTRIES_GET, - DEVLINK_CMD_DPIPE_HEADERS_GET, - DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET, -+ DEVLINK_CMD_RESOURCE_SET, -+ DEVLINK_CMD_RESOURCE_DUMP, -+ -+ /* Hot driver reload, makes configuration changes take place. The -+ * devlink instance is not released during the process. -+ */ -+ DEVLINK_CMD_RELOAD, -+ -+ DEVLINK_CMD_PARAM_GET, /* can dump */ -+ DEVLINK_CMD_PARAM_SET, -+ DEVLINK_CMD_PARAM_NEW, -+ DEVLINK_CMD_PARAM_DEL, -+ -+ DEVLINK_CMD_REGION_GET, -+ DEVLINK_CMD_REGION_SET, -+ DEVLINK_CMD_REGION_NEW, -+ DEVLINK_CMD_REGION_DEL, -+ DEVLINK_CMD_REGION_READ, - - /* add new commands above here */ - __DEVLINK_CMD_MAX, -@@ -124,6 +143,26 @@ enum devlink_eswitch_encap_mode { - DEVLINK_ESWITCH_ENCAP_MODE_BASIC, - }; - -+enum devlink_port_flavour { -+ DEVLINK_PORT_FLAVOUR_PHYSICAL, /* Any kind of a port physically -+ * facing the user. -+ */ -+ DEVLINK_PORT_FLAVOUR_CPU, /* CPU port */ -+ DEVLINK_PORT_FLAVOUR_DSA, /* Distributed switch architecture -+ * interconnect port. -+ */ -+}; -+ -+enum devlink_param_cmode { -+ DEVLINK_PARAM_CMODE_RUNTIME, -+ DEVLINK_PARAM_CMODE_DRIVERINIT, -+ DEVLINK_PARAM_CMODE_PERMANENT, -+ -+ /* Add new configuration modes above */ -+ __DEVLINK_PARAM_CMODE_MAX, -+ DEVLINK_PARAM_CMODE_MAX = __DEVLINK_PARAM_CMODE_MAX - 1 -+}; -+ - enum devlink_attr { - /* don't change the order or add anything between, this is ABI! */ - DEVLINK_ATTR_UNSPEC, -@@ -201,6 +240,45 @@ enum devlink_attr { - DEVLINK_ATTR_PAD, - - DEVLINK_ATTR_ESWITCH_ENCAP_MODE, /* u8 */ -+ DEVLINK_ATTR_RESOURCE_LIST, /* nested */ -+ DEVLINK_ATTR_RESOURCE, /* nested */ -+ DEVLINK_ATTR_RESOURCE_NAME, /* string */ -+ DEVLINK_ATTR_RESOURCE_ID, /* u64 */ -+ DEVLINK_ATTR_RESOURCE_SIZE, /* u64 */ -+ DEVLINK_ATTR_RESOURCE_SIZE_NEW, /* u64 */ -+ DEVLINK_ATTR_RESOURCE_SIZE_VALID, /* u8 */ -+ DEVLINK_ATTR_RESOURCE_SIZE_MIN, /* u64 */ -+ DEVLINK_ATTR_RESOURCE_SIZE_MAX, /* u64 */ -+ DEVLINK_ATTR_RESOURCE_SIZE_GRAN, /* u64 */ -+ DEVLINK_ATTR_RESOURCE_UNIT, /* u8 */ -+ DEVLINK_ATTR_RESOURCE_OCC, /* u64 */ -+ DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID, /* u64 */ -+ DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,/* u64 */ -+ -+ DEVLINK_ATTR_PORT_FLAVOUR, /* u16 */ -+ DEVLINK_ATTR_PORT_NUMBER, /* u32 */ -+ DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER, /* u32 */ -+ -+ DEVLINK_ATTR_PARAM, /* nested */ -+ DEVLINK_ATTR_PARAM_NAME, /* string */ -+ DEVLINK_ATTR_PARAM_GENERIC, /* flag */ -+ DEVLINK_ATTR_PARAM_TYPE, /* u8 */ -+ DEVLINK_ATTR_PARAM_VALUES_LIST, /* nested */ -+ DEVLINK_ATTR_PARAM_VALUE, /* nested */ -+ DEVLINK_ATTR_PARAM_VALUE_DATA, /* dynamic */ -+ DEVLINK_ATTR_PARAM_VALUE_CMODE, /* u8 */ -+ -+ DEVLINK_ATTR_REGION_NAME, /* string */ -+ DEVLINK_ATTR_REGION_SIZE, /* u64 */ -+ DEVLINK_ATTR_REGION_SNAPSHOTS, /* nested */ -+ DEVLINK_ATTR_REGION_SNAPSHOT, /* nested */ -+ DEVLINK_ATTR_REGION_SNAPSHOT_ID, /* u32 */ -+ -+ DEVLINK_ATTR_REGION_CHUNKS, /* nested */ -+ DEVLINK_ATTR_REGION_CHUNK, /* nested */ -+ DEVLINK_ATTR_REGION_CHUNK_DATA, /* binary */ -+ DEVLINK_ATTR_REGION_CHUNK_ADDR, /* u64 */ -+ DEVLINK_ATTR_REGION_CHUNK_LEN, /* u64 */ - - /* add new attributes above here, update the policy in devlink.c */ - -@@ -244,4 +322,8 @@ enum devlink_dpipe_header_id { - DEVLINK_DPIPE_HEADER_IPV6, - }; - -+enum devlink_resource_unit { -+ DEVLINK_RESOURCE_UNIT_ENTRY, -+}; -+ - #endif /* _LINUX_DEVLINK_H_ */ -diff --git a/include/uapi/linux/elf-em.h b/include/uapi/linux/elf-em.h -index 9cd1de954c0ac..31aa101783351 100644 ---- a/include/uapi/linux/elf-em.h -+++ b/include/uapi/linux/elf-em.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _LINUX_ELF_EM_H - #define _LINUX_ELF_EM_H - -diff --git a/include/uapi/linux/fib_rules.h b/include/uapi/linux/fib_rules.h -index bbf02a63a0113..232df14e1287a 100644 ---- a/include/uapi/linux/fib_rules.h -+++ b/include/uapi/linux/fib_rules.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_FIB_RULES_H - #define __LINUX_FIB_RULES_H - -@@ -22,7 +23,7 @@ struct fib_rule_hdr { - __u8 tos; - - __u8 table; -- __u8 res1; /* reserved */ -+ __u8 res1; /* reserved */ - __u8 res2; /* reserved */ - __u8 action; - -@@ -34,6 +35,11 @@ struct fib_rule_uid_range { - __u32 end; - }; - -+struct fib_rule_port_range { -+ __u16 start; -+ __u16 end; -+}; -+ - enum { - FRA_UNSPEC, - FRA_DST, /* destination address */ -@@ -57,6 +63,10 @@ enum { - FRA_PAD, - FRA_L3MDEV, /* iif or oif is l3mdev goto its table */ - FRA_UID_RANGE, /* UID range */ -+ FRA_PROTOCOL, /* Originator of the rule */ -+ FRA_IP_PROTO, /* ip proto */ -+ FRA_SPORT_RANGE, /* sport */ -+ FRA_DPORT_RANGE, /* dport */ - __FRA_MAX - }; - -diff --git a/include/uapi/linux/filter.h b/include/uapi/linux/filter.h -index e4f2f74cfc168..eaef459e7bd44 100644 ---- a/include/uapi/linux/filter.h -+++ b/include/uapi/linux/filter.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* - * Linux Socket Filter Data Structures - */ -diff --git a/include/uapi/linux/fou.h b/include/uapi/linux/fou.h -index 744c32380e6dc..bf022c63d5ff6 100644 ---- a/include/uapi/linux/fou.h -+++ b/include/uapi/linux/fou.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* fou.h - FOU Interface */ - - #ifndef _LINUX_FOU_H -diff --git a/include/uapi/linux/gen_stats.h b/include/uapi/linux/gen_stats.h -index 52deccc2128ee..24a861c0d29d3 100644 ---- a/include/uapi/linux/gen_stats.h -+++ b/include/uapi/linux/gen_stats.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_GEN_STATS_H - #define __LINUX_GEN_STATS_H - -diff --git a/include/uapi/linux/genetlink.h b/include/uapi/linux/genetlink.h -index 08239d8ead41d..1317119cbff8f 100644 ---- a/include/uapi/linux/genetlink.h -+++ b/include/uapi/linux/genetlink.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_GENERIC_NETLINK_H - #define __LINUX_GENERIC_NETLINK_H - -diff --git a/include/uapi/linux/hdlc/ioctl.h b/include/uapi/linux/hdlc/ioctl.h -index 04bc0274a1898..0fe4238e82462 100644 ---- a/include/uapi/linux/hdlc/ioctl.h -+++ b/include/uapi/linux/hdlc/ioctl.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __HDLC_IOCTL_H__ - #define __HDLC_IOCTL_H__ - -diff --git a/include/uapi/linux/icmpv6.h b/include/uapi/linux/icmpv6.h -index a2e839ee96485..cb247a5df6ea6 100644 ---- a/include/uapi/linux/icmpv6.h -+++ b/include/uapi/linux/icmpv6.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _LINUX_ICMPV6_H - #define _LINUX_ICMPV6_H - -diff --git a/include/uapi/linux/if.h b/include/uapi/linux/if.h -index b4ba020791f86..495cdd2324428 100644 ---- a/include/uapi/linux/if.h -+++ b/include/uapi/linux/if.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ - /* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket -diff --git a/include/uapi/linux/if_addr.h b/include/uapi/linux/if_addr.h -index 26f0ecff9f13d..a924606f36e56 100644 ---- a/include/uapi/linux/if_addr.h -+++ b/include/uapi/linux/if_addr.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_IF_ADDR_H - #define __LINUX_IF_ADDR_H - -@@ -32,6 +33,7 @@ enum { - IFA_CACHEINFO, - IFA_MULTICAST, - IFA_FLAGS, -+ IFA_RT_PRIORITY, /* u32, priority/metric for prefix route */ - __IFA_MAX, - }; - -diff --git a/include/uapi/linux/if_addrlabel.h b/include/uapi/linux/if_addrlabel.h -index 54580c298187c..d1f5974c76e10 100644 ---- a/include/uapi/linux/if_addrlabel.h -+++ b/include/uapi/linux/if_addrlabel.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* - * if_addrlabel.h - netlink interface for address labels - * -diff --git a/include/uapi/linux/if_alg.h b/include/uapi/linux/if_alg.h -index f2acd2fde1f3a..bc2bcdec377b4 100644 ---- a/include/uapi/linux/if_alg.h -+++ b/include/uapi/linux/if_alg.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ - /* - * if_alg: User-space algorithm interface - * -diff --git a/include/uapi/linux/if_arp.h b/include/uapi/linux/if_arp.h -index 199f253bd1f66..cd136a6f821bb 100644 ---- a/include/uapi/linux/if_arp.h -+++ b/include/uapi/linux/if_arp.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ - /* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket -diff --git a/include/uapi/linux/if_bonding.h b/include/uapi/linux/if_bonding.h -index 9635a62f6f89c..61a1bf6e865e8 100644 ---- a/include/uapi/linux/if_bonding.h -+++ b/include/uapi/linux/if_bonding.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-1.0+ WITH Linux-syscall-note */ - /* - * Bond several ethernet interfaces into a Cisco, running 'Etherchannel'. - * -diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h -index 156f4434ca325..bdfecf9411320 100644 ---- a/include/uapi/linux/if_bridge.h -+++ b/include/uapi/linux/if_bridge.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ - /* - * Linux ethernet bridge - * -diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h -index 7dde037a0cca6..8c36f63e6a38f 100644 ---- a/include/uapi/linux/if_ether.h -+++ b/include/uapi/linux/if_ether.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ - /* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket -@@ -29,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 */ -@@ -46,6 +48,7 @@ - #define ETH_P_PUP 0x0200 /* Xerox PUP packet */ - #define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */ - #define ETH_P_TSN 0x22F0 /* TSN (IEEE 1722) packet */ -+#define ETH_P_ERSPAN2 0x22EB /* ERSPAN version 2 (type III) */ - #define ETH_P_IP 0x0800 /* Internet Protocol packet */ - #define ETH_P_X25 0x0805 /* CCITT X.25 */ - #define ETH_P_ARP 0x0806 /* Address Resolution packet */ -@@ -86,6 +89,7 @@ - #define ETH_P_AOE 0x88A2 /* ATA over Ethernet */ - #define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */ - #define ETH_P_802_EX1 0x88B5 /* 802.1 Local Experimental 1. */ -+#define ETH_P_PREAUTH 0x88C7 /* 802.11 Preauthentication */ - #define ETH_P_TIPC 0x88CA /* TIPC */ - #define ETH_P_MACSEC 0x88E5 /* 802.1ae MACsec */ - #define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */ -@@ -148,11 +152,18 @@ - * This is an Ethernet frame header. - */ - -+/* allow libcs like musl to deactivate this, glibc does not implement this. */ -+#ifndef __UAPI_DEF_ETHHDR -+#define __UAPI_DEF_ETHHDR 1 -+#endif -+ -+#if __UAPI_DEF_ETHHDR - struct ethhdr { - unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ - unsigned char h_source[ETH_ALEN]; /* source ether addr */ - __be16 h_proto; /* packet type ID field */ - } __attribute__((packed)); -+#endif - - - #endif /* _LINUX_IF_ETHER_H */ -diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h -index 1f97d0560b6cb..1c64ed45353d5 100644 ---- a/include/uapi/linux/if_link.h -+++ b/include/uapi/linux/if_link.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _LINUX_IF_LINK_H - #define _LINUX_IF_LINK_H - -@@ -158,6 +159,11 @@ enum { - IFLA_PAD, - IFLA_XDP, - IFLA_EVENT, -+ IFLA_NEW_NETNSID, -+ IFLA_IF_NETNSID, -+ IFLA_CARRIER_UP_COUNT, -+ IFLA_CARRIER_DOWN_COUNT, -+ IFLA_NEW_IFINDEX, - __IFLA_MAX - }; - -@@ -323,6 +329,9 @@ enum { - IFLA_BRPORT_MCAST_TO_UCAST, - IFLA_BRPORT_VLAN_TUNNEL, - IFLA_BRPORT_BCAST_FLOOD, -+ IFLA_BRPORT_GROUP_FWD_MASK, -+ IFLA_BRPORT_NEIGH_SUPPRESS, -+ IFLA_BRPORT_ISOLATED, - __IFLA_BRPORT_MAX - }; - #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) -@@ -460,6 +469,7 @@ enum macsec_validation_type { - enum { - IFLA_IPVLAN_UNSPEC, - IFLA_IPVLAN_MODE, -+ IFLA_IPVLAN_FLAGS, - __IFLA_IPVLAN_MAX - }; - -@@ -472,6 +482,9 @@ enum ipvlan_mode { - IPVLAN_MODE_MAX - }; - -+#define IPVLAN_F_PRIVATE 0x01 -+#define IPVLAN_F_VEPA 0x02 -+ - /* VXLAN section */ - enum { - IFLA_VXLAN_UNSPEC, -@@ -502,6 +515,7 @@ enum { - IFLA_VXLAN_COLLECT_METADATA, - IFLA_VXLAN_LABEL, - IFLA_VXLAN_GPE, -+ IFLA_VXLAN_TTL_INHERIT, - __IFLA_VXLAN_MAX - }; - #define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1) -@@ -721,6 +735,8 @@ enum { - IFLA_VF_STATS_BROADCAST, - IFLA_VF_STATS_MULTICAST, - IFLA_VF_STATS_PAD, -+ IFLA_VF_STATS_RX_DROPPED, -+ IFLA_VF_STATS_TX_DROPPED, - __IFLA_VF_STATS_MAX, - }; - -@@ -902,6 +918,7 @@ enum { - XDP_ATTACHED_DRV, - XDP_ATTACHED_SKB, - XDP_ATTACHED_HW, -+ XDP_ATTACHED_MULTI, - }; - - enum { -@@ -910,6 +927,9 @@ enum { - IFLA_XDP_ATTACHED, - IFLA_XDP_FLAGS, - IFLA_XDP_PROG_ID, -+ IFLA_XDP_DRV_PROG_ID, -+ IFLA_XDP_SKB_PROG_ID, -+ IFLA_XDP_HW_PROG_ID, - __IFLA_XDP_MAX, - }; - -@@ -925,4 +945,43 @@ enum { - IFLA_EVENT_BONDING_OPTIONS, /* change in bonding options */ - }; - -+/* tun section */ -+ -+enum { -+ IFLA_TUN_UNSPEC, -+ IFLA_TUN_OWNER, -+ IFLA_TUN_GROUP, -+ IFLA_TUN_TYPE, -+ IFLA_TUN_PI, -+ IFLA_TUN_VNET_HDR, -+ IFLA_TUN_PERSIST, -+ IFLA_TUN_MULTI_QUEUE, -+ IFLA_TUN_NUM_QUEUES, -+ IFLA_TUN_NUM_DISABLED_QUEUES, -+ __IFLA_TUN_MAX, -+}; -+ -+#define IFLA_TUN_MAX (__IFLA_TUN_MAX - 1) -+ -+/* rmnet section */ -+ -+#define RMNET_FLAGS_INGRESS_DEAGGREGATION (1U << 0) -+#define RMNET_FLAGS_INGRESS_MAP_COMMANDS (1U << 1) -+#define RMNET_FLAGS_INGRESS_MAP_CKSUMV4 (1U << 2) -+#define RMNET_FLAGS_EGRESS_MAP_CKSUMV4 (1U << 3) -+ -+enum { -+ IFLA_RMNET_UNSPEC, -+ IFLA_RMNET_MUX_ID, -+ IFLA_RMNET_FLAGS, -+ __IFLA_RMNET_MAX, -+}; -+ -+#define IFLA_RMNET_MAX (__IFLA_RMNET_MAX - 1) -+ -+struct ifla_rmnet_flags { -+ __u32 flags; -+ __u32 mask; -+}; -+ - #endif /* _LINUX_IF_LINK_H */ -diff --git a/include/uapi/linux/if_macsec.h b/include/uapi/linux/if_macsec.h -index 22939a3ec8ea2..77439932561b9 100644 ---- a/include/uapi/linux/if_macsec.h -+++ b/include/uapi/linux/if_macsec.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ - /* - * include/uapi/linux/if_macsec.h - MACsec device - * -@@ -21,8 +22,13 @@ - - #define MACSEC_KEYID_LEN 16 - --#define MACSEC_DEFAULT_CIPHER_ID 0x0080020001000001ULL --#define MACSEC_DEFAULT_CIPHER_ALT 0x0080C20001000001ULL -+/* cipher IDs as per IEEE802.1AEbn-2011 */ -+#define MACSEC_CIPHER_ID_GCM_AES_128 0x0080C20001000001ULL -+#define MACSEC_CIPHER_ID_GCM_AES_256 0x0080C20001000002ULL -+ -+/* deprecated cipher ID for GCM-AES-128 */ -+#define MACSEC_DEFAULT_CIPHER_ID 0x0080020001000001ULL -+#define MACSEC_DEFAULT_CIPHER_ALT MACSEC_CIPHER_ID_GCM_AES_128 - - #define MACSEC_MIN_ICV_LEN 8 - #define MACSEC_MAX_ICV_LEN 32 -diff --git a/include/uapi/linux/if_packet.h b/include/uapi/linux/if_packet.h -index 4df96a7dd4fae..67b61d91d89bf 100644 ---- a/include/uapi/linux/if_packet.h -+++ b/include/uapi/linux/if_packet.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_IF_PACKET_H - #define __LINUX_IF_PACKET_H - -diff --git a/include/uapi/linux/if_tun.h b/include/uapi/linux/if_tun.h -index d5ecb42541819..be9b744a16458 100644 ---- a/include/uapi/linux/if_tun.h -+++ b/include/uapi/linux/if_tun.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ - /* - * Universal TUN/TAP device driver. - * Copyright (C) 1999-2000 Maxim Krasnyansky -@@ -56,10 +57,14 @@ - */ - #define TUNSETVNETBE _IOW('T', 222, int) - #define TUNGETVNETBE _IOR('T', 223, int) -+#define TUNSETSTEERINGEBPF _IOR('T', 224, int) -+#define TUNSETFILTEREBPF _IOR('T', 225, int) - - /* TUNSETIFF ifr flags */ - #define IFF_TUN 0x0001 - #define IFF_TAP 0x0002 -+#define IFF_NAPI 0x0010 -+#define IFF_NAPI_FRAGS 0x0020 - #define IFF_NO_PI 0x1000 - /* This flag has no real effect */ - #define IFF_ONE_QUEUE 0x2000 -diff --git a/include/uapi/linux/if_tunnel.h b/include/uapi/linux/if_tunnel.h -index 21834cac4c0d5..ecdc76669cfdd 100644 ---- a/include/uapi/linux/if_tunnel.h -+++ b/include/uapi/linux/if_tunnel.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _IF_TUNNEL_H_ - #define _IF_TUNNEL_H_ - -@@ -84,6 +85,7 @@ enum tunnel_encap_types { - TUNNEL_ENCAP_NONE, - TUNNEL_ENCAP_FOU, - TUNNEL_ENCAP_GUE, -+ TUNNEL_ENCAP_MPLS, - }; - - #define TUNNEL_ENCAP_FLAG_CSUM (1<<0) -@@ -135,6 +137,9 @@ enum { - IFLA_GRE_IGNORE_DF, - IFLA_GRE_FWMARK, - IFLA_GRE_ERSPAN_INDEX, -+ IFLA_GRE_ERSPAN_VER, -+ IFLA_GRE_ERSPAN_DIR, -+ IFLA_GRE_ERSPAN_HWID, - __IFLA_GRE_MAX, - }; - -diff --git a/include/uapi/linux/if_vlan.h b/include/uapi/linux/if_vlan.h -index 24ae007160a17..18a15dad5547b 100644 ---- a/include/uapi/linux/if_vlan.h -+++ b/include/uapi/linux/if_vlan.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ - /* - * VLAN An implementation of 802.1Q VLAN tagging. - * -diff --git a/include/uapi/linux/ife.h b/include/uapi/linux/ife.h -index 2954da32e012e..bdd953c67db12 100644 ---- a/include/uapi/linux/ife.h -+++ b/include/uapi/linux/ife.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __UAPI_IFE_H - #define __UAPI_IFE_H - -diff --git a/include/uapi/linux/ila.h b/include/uapi/linux/ila.h -index 7e328d72c518f..6a6c97cf2c40c 100644 ---- a/include/uapi/linux/ila.h -+++ b/include/uapi/linux/ila.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* ila.h - ILA Interface */ - - #ifndef _LINUX_ILA_H -@@ -16,6 +17,8 @@ enum { - ILA_ATTR_DIR, /* u32 */ - ILA_ATTR_PAD, - ILA_ATTR_CSUM_MODE, /* u8 */ -+ ILA_ATTR_IDENT_TYPE, /* u8 */ -+ ILA_ATTR_HOOK_TYPE, /* u8 */ - - __ILA_ATTR_MAX, - }; -@@ -27,6 +30,7 @@ enum { - ILA_CMD_ADD, - ILA_CMD_DEL, - ILA_CMD_GET, -+ ILA_CMD_FLUSH, - - __ILA_CMD_MAX, - }; -@@ -40,6 +44,25 @@ enum { - ILA_CSUM_ADJUST_TRANSPORT, - ILA_CSUM_NEUTRAL_MAP, - ILA_CSUM_NO_ACTION, -+ ILA_CSUM_NEUTRAL_MAP_AUTO, -+}; -+ -+enum { -+ ILA_ATYPE_IID = 0, -+ ILA_ATYPE_LUID, -+ ILA_ATYPE_VIRT_V4, -+ ILA_ATYPE_VIRT_UNI_V6, -+ ILA_ATYPE_VIRT_MULTI_V6, -+ ILA_ATYPE_NONLOCAL_ADDR, -+ ILA_ATYPE_RSVD_1, -+ ILA_ATYPE_RSVD_2, -+ -+ ILA_ATYPE_USE_FORMAT = 32, /* Get type from type field in identifier */ -+}; -+ -+enum { -+ ILA_HOOK_ROUTE_OUTPUT, -+ ILA_HOOK_ROUTE_INPUT, - }; - - #endif /* _LINUX_ILA_H */ -diff --git a/include/uapi/linux/in.h b/include/uapi/linux/in.h -index 9439efaaa0c84..a4f143b301582 100644 ---- a/include/uapi/linux/in.h -+++ b/include/uapi/linux/in.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ - /* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket -diff --git a/include/uapi/linux/in6.h b/include/uapi/linux/in6.h -index 6f3bdee7c0aba..409bb3f3aed67 100644 ---- a/include/uapi/linux/in6.h -+++ b/include/uapi/linux/in6.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ - /* - * Types and definitions for AF_INET6 - * Linux INET6 implementation -@@ -284,6 +285,7 @@ struct in6_flowlabel_req { - #define IPV6_TRANSPARENT 75 - #define IPV6_UNICAST_IF 76 - #define IPV6_RECVFRAGSIZE 77 -+#define IPV6_FREEBIND 78 - - /* - * Multicast Routing: -diff --git a/include/uapi/linux/in_route.h b/include/uapi/linux/in_route.h -index b261b8c915f01..0cc2c23b47f84 100644 ---- a/include/uapi/linux/in_route.h -+++ b/include/uapi/linux/in_route.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _LINUX_IN_ROUTE_H - #define _LINUX_IN_ROUTE_H - -diff --git a/include/uapi/linux/inet_diag.h b/include/uapi/linux/inet_diag.h -index bada4d7b6c8e6..f98d82d4b2c03 100644 ---- a/include/uapi/linux/inet_diag.h -+++ b/include/uapi/linux/inet_diag.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _INET_DIAG_H_ - #define _INET_DIAG_H_ - -@@ -91,6 +92,8 @@ enum { - INET_DIAG_BC_D_COND, - INET_DIAG_BC_DEV_COND, /* u32 ifindex */ - INET_DIAG_BC_MARK_COND, -+ INET_DIAG_BC_S_EQ, -+ INET_DIAG_BC_D_EQ, - }; - - struct inet_diag_hostcond { -diff --git a/include/uapi/linux/ip.h b/include/uapi/linux/ip.h -index 1907284cb3745..883fd334496ab 100644 ---- a/include/uapi/linux/ip.h -+++ b/include/uapi/linux/ip.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ - /* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket -diff --git a/include/uapi/linux/ip6_tunnel.h b/include/uapi/linux/ip6_tunnel.h -index 425926c467d7a..0245269b037c8 100644 ---- a/include/uapi/linux/ip6_tunnel.h -+++ b/include/uapi/linux/ip6_tunnel.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _IP6_TUNNEL_H - #define _IP6_TUNNEL_H - -@@ -20,6 +21,8 @@ - #define IP6_TNL_F_RCV_DSCP_COPY 0x10 - /* copy fwmark from inner packet */ - #define IP6_TNL_F_USE_ORIG_FWMARK 0x20 -+/* allow remote endpoint on the local node */ -+#define IP6_TNL_F_ALLOW_LOCAL_REMOTE 0x40 - - struct ip6_tnl_parm { - char name[IFNAMSIZ]; /* name of tunnel device */ -diff --git a/include/uapi/linux/ipsec.h b/include/uapi/linux/ipsec.h -index d17a6302a0e96..50d8ee1791e2a 100644 ---- a/include/uapi/linux/ipsec.h -+++ b/include/uapi/linux/ipsec.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _LINUX_IPSEC_H - #define _LINUX_IPSEC_H - -diff --git a/include/uapi/linux/kernel.h b/include/uapi/linux/kernel.h -index 527549f5db572..d99ffa1a0abdb 100644 ---- a/include/uapi/linux/kernel.h -+++ b/include/uapi/linux/kernel.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _LINUX_KERNEL_H - #define _LINUX_KERNEL_H - -diff --git a/include/uapi/linux/l2tp.h b/include/uapi/linux/l2tp.h -index 8a80007bb1ec6..1fe52a7dd4a94 100644 ---- a/include/uapi/linux/l2tp.h -+++ b/include/uapi/linux/l2tp.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* - * L2TP-over-IP socket for L2TPv3. - * -@@ -64,7 +65,7 @@ struct sockaddr_l2tpip6 { - * TUNNEL_MODIFY - CONN_ID, udpcsum - * TUNNEL_GETSTATS - CONN_ID, (stats) - * TUNNEL_GET - CONN_ID, (...) -- * SESSION_CREATE - SESSION_ID, PW_TYPE, offset, data_seq, cookie, peer_cookie, offset, l2spec -+ * SESSION_CREATE - SESSION_ID, PW_TYPE, data_seq, cookie, peer_cookie, l2spec - * SESSION_DELETE - SESSION_ID - * SESSION_MODIFY - SESSION_ID, data_seq - * SESSION_GET - SESSION_ID, (...) -@@ -93,10 +94,10 @@ enum { - L2TP_ATTR_NONE, /* no data */ - L2TP_ATTR_PW_TYPE, /* u16, enum l2tp_pwtype */ - L2TP_ATTR_ENCAP_TYPE, /* u16, enum l2tp_encap_type */ -- L2TP_ATTR_OFFSET, /* u16 */ -+ L2TP_ATTR_OFFSET, /* u16 (not used) */ - L2TP_ATTR_DATA_SEQ, /* u16 */ - L2TP_ATTR_L2SPEC_TYPE, /* u8, enum l2tp_l2spec_type */ -- L2TP_ATTR_L2SPEC_LEN, /* u8, enum l2tp_l2spec_type */ -+ L2TP_ATTR_L2SPEC_LEN, /* u8 (not used) */ - L2TP_ATTR_PROTO_VERSION, /* u8 */ - L2TP_ATTR_IFNAME, /* string */ - L2TP_ATTR_CONN_ID, /* u32 */ -diff --git a/include/uapi/linux/libc-compat.h b/include/uapi/linux/libc-compat.h -index f38571dabd8d8..a1599911e7a94 100644 ---- a/include/uapi/linux/libc-compat.h -+++ b/include/uapi/linux/libc-compat.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* - * Compatibility interface for userspace libc header coordination: - * -@@ -167,46 +168,99 @@ - - /* If we did not see any headers from any supported C libraries, - * or we are being included in the kernel, then define everything -- * that we need. */ -+ * that we need. Check for previous __UAPI_* definitions to give -+ * unsupported C libraries a way to opt out of any kernel definition. */ - #else /* !defined(__GLIBC__) */ - - /* Definitions for if.h */ -+#ifndef __UAPI_DEF_IF_IFCONF - #define __UAPI_DEF_IF_IFCONF 1 -+#endif -+#ifndef __UAPI_DEF_IF_IFMAP - #define __UAPI_DEF_IF_IFMAP 1 -+#endif -+#ifndef __UAPI_DEF_IF_IFNAMSIZ - #define __UAPI_DEF_IF_IFNAMSIZ 1 -+#endif -+#ifndef __UAPI_DEF_IF_IFREQ - #define __UAPI_DEF_IF_IFREQ 1 -+#endif - /* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */ -+#ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS - #define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1 -+#endif - /* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */ -+#ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO - #define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1 -+#endif - - /* Definitions for in.h */ -+#ifndef __UAPI_DEF_IN_ADDR - #define __UAPI_DEF_IN_ADDR 1 -+#endif -+#ifndef __UAPI_DEF_IN_IPPROTO - #define __UAPI_DEF_IN_IPPROTO 1 -+#endif -+#ifndef __UAPI_DEF_IN_PKTINFO - #define __UAPI_DEF_IN_PKTINFO 1 -+#endif -+#ifndef __UAPI_DEF_IP_MREQ - #define __UAPI_DEF_IP_MREQ 1 -+#endif -+#ifndef __UAPI_DEF_SOCKADDR_IN - #define __UAPI_DEF_SOCKADDR_IN 1 -+#endif -+#ifndef __UAPI_DEF_IN_CLASS - #define __UAPI_DEF_IN_CLASS 1 -+#endif - - /* Definitions for in6.h */ -+#ifndef __UAPI_DEF_IN6_ADDR - #define __UAPI_DEF_IN6_ADDR 1 -+#endif -+#ifndef __UAPI_DEF_IN6_ADDR_ALT - #define __UAPI_DEF_IN6_ADDR_ALT 1 -+#endif -+#ifndef __UAPI_DEF_SOCKADDR_IN6 - #define __UAPI_DEF_SOCKADDR_IN6 1 -+#endif -+#ifndef __UAPI_DEF_IPV6_MREQ - #define __UAPI_DEF_IPV6_MREQ 1 -+#endif -+#ifndef __UAPI_DEF_IPPROTO_V6 - #define __UAPI_DEF_IPPROTO_V6 1 -+#endif -+#ifndef __UAPI_DEF_IPV6_OPTIONS - #define __UAPI_DEF_IPV6_OPTIONS 1 -+#endif -+#ifndef __UAPI_DEF_IN6_PKTINFO - #define __UAPI_DEF_IN6_PKTINFO 1 -+#endif -+#ifndef __UAPI_DEF_IP6_MTUINFO - #define __UAPI_DEF_IP6_MTUINFO 1 -+#endif - - /* Definitions for ipx.h */ -+#ifndef __UAPI_DEF_SOCKADDR_IPX - #define __UAPI_DEF_SOCKADDR_IPX 1 -+#endif -+#ifndef __UAPI_DEF_IPX_ROUTE_DEFINITION - #define __UAPI_DEF_IPX_ROUTE_DEFINITION 1 -+#endif -+#ifndef __UAPI_DEF_IPX_INTERFACE_DEFINITION - #define __UAPI_DEF_IPX_INTERFACE_DEFINITION 1 -+#endif -+#ifndef __UAPI_DEF_IPX_CONFIG_DATA - #define __UAPI_DEF_IPX_CONFIG_DATA 1 -+#endif -+#ifndef __UAPI_DEF_IPX_ROUTE_DEF - #define __UAPI_DEF_IPX_ROUTE_DEF 1 -+#endif - - /* Definitions for xattr.h */ -+#ifndef __UAPI_DEF_XATTR - #define __UAPI_DEF_XATTR 1 -+#endif - - #endif /* __GLIBC__ */ - -diff --git a/include/uapi/linux/limits.h b/include/uapi/linux/limits.h -index 2d0f94162fb34..c3547f07605c9 100644 ---- a/include/uapi/linux/limits.h -+++ b/include/uapi/linux/limits.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _LINUX_LIMITS_H - #define _LINUX_LIMITS_H - -diff --git a/include/uapi/linux/lwtunnel.h b/include/uapi/linux/lwtunnel.h -index 329842627162b..3f3fe6f30df0b 100644 ---- a/include/uapi/linux/lwtunnel.h -+++ b/include/uapi/linux/lwtunnel.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _LWTUNNEL_H_ - #define _LWTUNNEL_H_ - -diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h -index e439565df838a..1a6fee974116a 100644 ---- a/include/uapi/linux/magic.h -+++ b/include/uapi/linux/magic.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_MAGIC_H__ - #define __LINUX_MAGIC_H__ - -@@ -46,6 +47,7 @@ - #define OPENPROM_SUPER_MAGIC 0x9fa1 - #define QNX4_SUPER_MAGIC 0x002f /* qnx4 fs detection */ - #define QNX6_SUPER_MAGIC 0x68191122 /* qnx6 fs detection */ -+#define AFS_FS_MAGIC 0x6B414653 - - #define REISERFS_SUPER_MAGIC 0x52654973 /* used by gcc */ - /* used by file system utilities that -diff --git a/include/uapi/linux/mpls.h b/include/uapi/linux/mpls.h -index bf5b6259058f1..9effbf99dde6b 100644 ---- a/include/uapi/linux/mpls.h -+++ b/include/uapi/linux/mpls.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _MPLS_H - #define _MPLS_H - -diff --git a/include/uapi/linux/mpls_iptunnel.h b/include/uapi/linux/mpls_iptunnel.h -index 1a0e57b45a8ce..2c69b7ddbc87b 100644 ---- a/include/uapi/linux/mpls_iptunnel.h -+++ b/include/uapi/linux/mpls_iptunnel.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ - /* - * mpls tunnel api - * -diff --git a/include/uapi/linux/neighbour.h b/include/uapi/linux/neighbour.h -index 3199d28980b35..904db61484766 100644 ---- a/include/uapi/linux/neighbour.h -+++ b/include/uapi/linux/neighbour.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_NEIGHBOUR_H - #define __LINUX_NEIGHBOUR_H - -diff --git a/include/uapi/linux/net_namespace.h b/include/uapi/linux/net_namespace.h -index 9a92b7e14a199..6d64d0716800f 100644 ---- a/include/uapi/linux/net_namespace.h -+++ b/include/uapi/linux/net_namespace.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* Copyright (c) 2015 6WIND S.A. - * Author: Nicolas Dichtel - * -diff --git a/include/uapi/linux/netconf.h b/include/uapi/linux/netconf.h -index 4afbd7dbd05de..86ac1eb4c06e3 100644 ---- a/include/uapi/linux/netconf.h -+++ b/include/uapi/linux/netconf.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _LINUX_NETCONF_H_ - #define _LINUX_NETCONF_H_ - -diff --git a/include/uapi/linux/netdevice.h b/include/uapi/linux/netdevice.h -index 66fceb4423392..86d961c91136c 100644 ---- a/include/uapi/linux/netdevice.h -+++ b/include/uapi/linux/netdevice.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ - /* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket -diff --git a/include/uapi/linux/netfilter.h b/include/uapi/linux/netfilter.h -index ff4a4a523c128..36378a0a81399 100644 ---- a/include/uapi/linux/netfilter.h -+++ b/include/uapi/linux/netfilter.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_NETFILTER_H - #define __LINUX_NETFILTER_H - -diff --git a/include/uapi/linux/netfilter/ipset/ip_set.h b/include/uapi/linux/netfilter/ipset/ip_set.h -index a6c96b0024250..13eeada594dbb 100644 ---- a/include/uapi/linux/netfilter/ipset/ip_set.h -+++ b/include/uapi/linux/netfilter/ipset/ip_set.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* Copyright (C) 2000-2002 Joakim Axelsson - * Patrick Schaaf - * Martin Josefsson -diff --git a/include/uapi/linux/netfilter/x_tables.h b/include/uapi/linux/netfilter/x_tables.h -index 4120970072771..ae2fd12799399 100644 ---- a/include/uapi/linux/netfilter/x_tables.h -+++ b/include/uapi/linux/netfilter/x_tables.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _X_TABLES_H - #define _X_TABLES_H - #include -diff --git a/include/uapi/linux/netfilter/xt_set.h b/include/uapi/linux/netfilter/xt_set.h -index d4e02348384c6..8c1ca66c8a060 100644 ---- a/include/uapi/linux/netfilter/xt_set.h -+++ b/include/uapi/linux/netfilter/xt_set.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _XT_SET_H - #define _XT_SET_H - -diff --git a/include/uapi/linux/netfilter/xt_tcpudp.h b/include/uapi/linux/netfilter/xt_tcpudp.h -index 38aa7b399021f..658c169998197 100644 ---- a/include/uapi/linux/netfilter/xt_tcpudp.h -+++ b/include/uapi/linux/netfilter/xt_tcpudp.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _XT_TCPUDP_H - #define _XT_TCPUDP_H - -diff --git a/include/uapi/linux/netfilter_ipv4.h b/include/uapi/linux/netfilter_ipv4.h -index a5f4dc784baa7..074e2c8b923ad 100644 ---- a/include/uapi/linux/netfilter_ipv4.h -+++ b/include/uapi/linux/netfilter_ipv4.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* IPv4-specific defines for netfilter. - * (C)1998 Rusty Russell -- This code is GPL. - */ -@@ -54,6 +55,7 @@ - - enum nf_ip_hook_priorities { - NF_IP_PRI_FIRST = INT_MIN, -+ NF_IP_PRI_RAW_BEFORE_DEFRAG = -450, - NF_IP_PRI_CONNTRACK_DEFRAG = -400, - NF_IP_PRI_RAW = -300, - NF_IP_PRI_SELINUX_FIRST = -225, -diff --git a/include/uapi/linux/netfilter_ipv4/ip_tables.h b/include/uapi/linux/netfilter_ipv4/ip_tables.h -index 456fb863e0fde..409cff71bd238 100644 ---- a/include/uapi/linux/netfilter_ipv4/ip_tables.h -+++ b/include/uapi/linux/netfilter_ipv4/ip_tables.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* - * 25-Jul-1998 Major changes to allow for ip chain table - * -diff --git a/include/uapi/linux/netfilter_ipv6.h b/include/uapi/linux/netfilter_ipv6.h -index 8483d1d415199..92701fe853ada 100644 ---- a/include/uapi/linux/netfilter_ipv6.h -+++ b/include/uapi/linux/netfilter_ipv6.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* IPv6-specific defines for netfilter. - * (C)1998 Rusty Russell -- This code is GPL. - * (C)1999 David Jeffery -@@ -59,6 +60,7 @@ - - enum nf_ip6_hook_priorities { - NF_IP6_PRI_FIRST = INT_MIN, -+ NF_IP6_PRI_RAW_BEFORE_DEFRAG = -450, - NF_IP6_PRI_CONNTRACK_DEFRAG = -400, - NF_IP6_PRI_RAW = -300, - NF_IP6_PRI_SELINUX_FIRST = -225, -diff --git a/include/uapi/linux/netfilter_ipv6/ip6_tables.h b/include/uapi/linux/netfilter_ipv6/ip6_tables.h -index fcc8ccaff94e9..7ae314ba260f3 100644 ---- a/include/uapi/linux/netfilter_ipv6/ip6_tables.h -+++ b/include/uapi/linux/netfilter_ipv6/ip6_tables.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* - * 25-Jul-1998 Major changes to allow for ip chain table - * -diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h -index ec0690b506471..0b2c29bd081fa 100644 ---- a/include/uapi/linux/netlink.h -+++ b/include/uapi/linux/netlink.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_NETLINK_H - #define __LINUX_NETLINK_H - -diff --git a/include/uapi/linux/netlink_diag.h b/include/uapi/linux/netlink_diag.h -index c8c8c7d2e530b..4cd0657859636 100644 ---- a/include/uapi/linux/netlink_diag.h -+++ b/include/uapi/linux/netlink_diag.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __NETLINK_DIAG_H__ - #define __NETLINK_DIAG_H__ - -diff --git a/include/uapi/linux/packet_diag.h b/include/uapi/linux/packet_diag.h -index 0c5d5dd61b6ab..349ddf0a96af5 100644 ---- a/include/uapi/linux/packet_diag.h -+++ b/include/uapi/linux/packet_diag.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __PACKET_DIAG_H__ - #define __PACKET_DIAG_H__ - -diff --git a/include/uapi/linux/param.h b/include/uapi/linux/param.h -index 092e92f67b500..94e0c57a75b7a 100644 ---- a/include/uapi/linux/param.h -+++ b/include/uapi/linux/param.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _LINUX_PARAM_H - #define _LINUX_PARAM_H - -diff --git a/include/uapi/linux/pfkeyv2.h b/include/uapi/linux/pfkeyv2.h -index ada7f0171cccd..d65b117852604 100644 ---- a/include/uapi/linux/pfkeyv2.h -+++ b/include/uapi/linux/pfkeyv2.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* PF_KEY user interface, this is defined by rfc2367 so - * do not make arbitrary modifications or else this header - * file will not be compliant. -diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h -index d5e2bf68d0d40..b4512254036b9 100644 ---- a/include/uapi/linux/pkt_cls.h -+++ b/include/uapi/linux/pkt_cls.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_PKT_CLS_H - #define __LINUX_PKT_CLS_H - -@@ -128,6 +129,7 @@ enum { - #define TCA_CLS_FLAGS_SKIP_SW (1 << 1) /* don't use filter in SW */ - #define TCA_CLS_FLAGS_IN_HW (1 << 2) /* filter is offloaded to HW */ - #define TCA_CLS_FLAGS_NOT_IN_HW (1 << 3) /* filter isn't offloaded to HW */ -+#define TCA_CLS_FLAGS_VERBOSE (1 << 4) /* verbose logging */ - - /* U32 filters */ - -@@ -467,6 +469,15 @@ enum { - TCA_FLOWER_KEY_IP_TTL, /* u8 */ - TCA_FLOWER_KEY_IP_TTL_MASK, /* u8 */ - -+ TCA_FLOWER_KEY_CVLAN_ID, /* be16 */ -+ TCA_FLOWER_KEY_CVLAN_PRIO, /* u8 */ -+ TCA_FLOWER_KEY_CVLAN_ETH_TYPE, /* be16 */ -+ -+ TCA_FLOWER_KEY_ENC_IP_TOS, /* u8 */ -+ TCA_FLOWER_KEY_ENC_IP_TOS_MASK, /* u8 */ -+ TCA_FLOWER_KEY_ENC_IP_TTL, /* u8 */ -+ TCA_FLOWER_KEY_ENC_IP_TTL_MASK, /* u8 */ -+ - __TCA_FLOWER_MAX, - }; - -@@ -474,6 +485,7 @@ enum { - - enum { - TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0), -+ TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST = (1 << 1), - }; - - /* Match-all classifier */ -@@ -554,7 +566,8 @@ enum { - #define TCF_EM_VLAN 6 - #define TCF_EM_CANID 7 - #define TCF_EM_IPSET 8 --#define TCF_EM_MAX 8 -+#define TCF_EM_IPT 9 -+#define TCF_EM_MAX 9 - - enum { - TCF_EM_PROG_TC -diff --git a/include/uapi/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h -index 099bf5528fed3..d9cc9dc4f547c 100644 ---- a/include/uapi/linux/pkt_sched.h -+++ b/include/uapi/linux/pkt_sched.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_PKT_SCHED_H - #define __LINUX_PKT_SCHED_H - -@@ -74,6 +75,7 @@ struct tc_estimator { - #define TC_H_INGRESS (0xFFFFFFF1U) - #define TC_H_CLSACT TC_H_INGRESS - -+#define TC_H_MIN_PRIORITY 0xFFE0U - #define TC_H_MIN_INGRESS 0xFFF2U - #define TC_H_MIN_EGRESS 0xFFF3U - -@@ -534,6 +536,10 @@ enum { - TCA_NETEM_ECN, - TCA_NETEM_RATE64, - TCA_NETEM_PAD, -+ TCA_NETEM_LATENCY64, -+ TCA_NETEM_JITTER64, -+ TCA_NETEM_SLOT, -+ TCA_NETEM_SLOT_DIST, - __TCA_NETEM_MAX, - }; - -@@ -571,6 +577,15 @@ struct tc_netem_rate { - __s32 cell_overhead; - }; - -+struct tc_netem_slot { -+ __s64 min_delay; /* nsec */ -+ __s64 max_delay; -+ __s32 max_packets; -+ __s32 max_bytes; -+ __s64 dist_delay; /* nsec */ -+ __s64 dist_jitter; /* nsec */ -+}; -+ - enum { - NETEM_LOSS_UNSPEC, - NETEM_LOSS_GI, /* General Intuitive - 4 state model */ -@@ -625,6 +640,22 @@ enum { - - #define TC_MQPRIO_HW_OFFLOAD_MAX (__TC_MQPRIO_HW_OFFLOAD_MAX - 1) - -+enum { -+ TC_MQPRIO_MODE_DCB, -+ TC_MQPRIO_MODE_CHANNEL, -+ __TC_MQPRIO_MODE_MAX -+}; -+ -+#define __TC_MQPRIO_MODE_MAX (__TC_MQPRIO_MODE_MAX - 1) -+ -+enum { -+ TC_MQPRIO_SHAPER_DCB, -+ TC_MQPRIO_SHAPER_BW_RATE, /* Add new shapers below */ -+ __TC_MQPRIO_SHAPER_MAX -+}; -+ -+#define __TC_MQPRIO_SHAPER_MAX (__TC_MQPRIO_SHAPER_MAX - 1) -+ - struct tc_mqprio_qopt { - __u8 num_tc; - __u8 prio_tc_map[TC_QOPT_BITMASK + 1]; -@@ -633,6 +664,22 @@ struct tc_mqprio_qopt { - __u16 offset[TC_QOPT_MAX_QUEUE]; - }; - -+#define TC_MQPRIO_F_MODE 0x1 -+#define TC_MQPRIO_F_SHAPER 0x2 -+#define TC_MQPRIO_F_MIN_RATE 0x4 -+#define TC_MQPRIO_F_MAX_RATE 0x8 -+ -+enum { -+ TCA_MQPRIO_UNSPEC, -+ TCA_MQPRIO_MODE, -+ TCA_MQPRIO_SHAPER, -+ TCA_MQPRIO_MIN_RATE64, -+ TCA_MQPRIO_MAX_RATE64, -+ __TCA_MQPRIO_MAX, -+}; -+ -+#define TCA_MQPRIO_MAX (__TCA_MQPRIO_MAX - 1) -+ - /* SFB */ - - enum { -@@ -871,4 +918,155 @@ struct tc_pie_xstats { - __u32 maxq; /* maximum queue size */ - __u32 ecn_mark; /* packets marked with ecn*/ - }; -+ -+/* CBS */ -+struct tc_cbs_qopt { -+ __u8 offload; -+ __u8 _pad[3]; -+ __s32 hicredit; -+ __s32 locredit; -+ __s32 idleslope; -+ __s32 sendslope; -+}; -+ -+enum { -+ TCA_CBS_UNSPEC, -+ TCA_CBS_PARMS, -+ __TCA_CBS_MAX, -+}; -+ -+#define TCA_CBS_MAX (__TCA_CBS_MAX - 1) -+ -+ -+/* ETF */ -+struct tc_etf_qopt { -+ __s32 delta; -+ __s32 clockid; -+ __u32 flags; -+#define TC_ETF_DEADLINE_MODE_ON BIT(0) -+#define TC_ETF_OFFLOAD_ON BIT(1) -+}; -+ -+enum { -+ TCA_ETF_UNSPEC, -+ TCA_ETF_PARMS, -+ __TCA_ETF_MAX, -+}; -+ -+#define TCA_ETF_MAX (__TCA_ETF_MAX - 1) -+ -+ -+/* CAKE */ -+enum { -+ TCA_CAKE_UNSPEC, -+ TCA_CAKE_PAD, -+ TCA_CAKE_BASE_RATE64, -+ TCA_CAKE_DIFFSERV_MODE, -+ TCA_CAKE_ATM, -+ TCA_CAKE_FLOW_MODE, -+ TCA_CAKE_OVERHEAD, -+ TCA_CAKE_RTT, -+ TCA_CAKE_TARGET, -+ TCA_CAKE_AUTORATE, -+ TCA_CAKE_MEMORY, -+ TCA_CAKE_NAT, -+ TCA_CAKE_RAW, -+ TCA_CAKE_WASH, -+ TCA_CAKE_MPU, -+ TCA_CAKE_INGRESS, -+ TCA_CAKE_ACK_FILTER, -+ TCA_CAKE_SPLIT_GSO, -+ __TCA_CAKE_MAX -+}; -+#define TCA_CAKE_MAX (__TCA_CAKE_MAX - 1) -+ -+enum { -+ __TCA_CAKE_STATS_INVALID, -+ TCA_CAKE_STATS_PAD, -+ TCA_CAKE_STATS_CAPACITY_ESTIMATE64, -+ TCA_CAKE_STATS_MEMORY_LIMIT, -+ TCA_CAKE_STATS_MEMORY_USED, -+ TCA_CAKE_STATS_AVG_NETOFF, -+ TCA_CAKE_STATS_MIN_NETLEN, -+ TCA_CAKE_STATS_MAX_NETLEN, -+ TCA_CAKE_STATS_MIN_ADJLEN, -+ TCA_CAKE_STATS_MAX_ADJLEN, -+ TCA_CAKE_STATS_TIN_STATS, -+ TCA_CAKE_STATS_DEFICIT, -+ TCA_CAKE_STATS_COBALT_COUNT, -+ TCA_CAKE_STATS_DROPPING, -+ TCA_CAKE_STATS_DROP_NEXT_US, -+ TCA_CAKE_STATS_P_DROP, -+ TCA_CAKE_STATS_BLUE_TIMER_US, -+ __TCA_CAKE_STATS_MAX -+}; -+#define TCA_CAKE_STATS_MAX (__TCA_CAKE_STATS_MAX - 1) -+ -+enum { -+ __TCA_CAKE_TIN_STATS_INVALID, -+ TCA_CAKE_TIN_STATS_PAD, -+ TCA_CAKE_TIN_STATS_SENT_PACKETS, -+ TCA_CAKE_TIN_STATS_SENT_BYTES64, -+ TCA_CAKE_TIN_STATS_DROPPED_PACKETS, -+ TCA_CAKE_TIN_STATS_DROPPED_BYTES64, -+ TCA_CAKE_TIN_STATS_ACKS_DROPPED_PACKETS, -+ TCA_CAKE_TIN_STATS_ACKS_DROPPED_BYTES64, -+ TCA_CAKE_TIN_STATS_ECN_MARKED_PACKETS, -+ TCA_CAKE_TIN_STATS_ECN_MARKED_BYTES64, -+ TCA_CAKE_TIN_STATS_BACKLOG_PACKETS, -+ TCA_CAKE_TIN_STATS_BACKLOG_BYTES, -+ TCA_CAKE_TIN_STATS_THRESHOLD_RATE64, -+ TCA_CAKE_TIN_STATS_TARGET_US, -+ TCA_CAKE_TIN_STATS_INTERVAL_US, -+ TCA_CAKE_TIN_STATS_WAY_INDIRECT_HITS, -+ TCA_CAKE_TIN_STATS_WAY_MISSES, -+ TCA_CAKE_TIN_STATS_WAY_COLLISIONS, -+ TCA_CAKE_TIN_STATS_PEAK_DELAY_US, -+ TCA_CAKE_TIN_STATS_AVG_DELAY_US, -+ TCA_CAKE_TIN_STATS_BASE_DELAY_US, -+ TCA_CAKE_TIN_STATS_SPARSE_FLOWS, -+ TCA_CAKE_TIN_STATS_BULK_FLOWS, -+ TCA_CAKE_TIN_STATS_UNRESPONSIVE_FLOWS, -+ TCA_CAKE_TIN_STATS_MAX_SKBLEN, -+ TCA_CAKE_TIN_STATS_FLOW_QUANTUM, -+ __TCA_CAKE_TIN_STATS_MAX -+}; -+#define TCA_CAKE_TIN_STATS_MAX (__TCA_CAKE_TIN_STATS_MAX - 1) -+#define TC_CAKE_MAX_TINS (8) -+ -+enum { -+ CAKE_FLOW_NONE = 0, -+ CAKE_FLOW_SRC_IP, -+ CAKE_FLOW_DST_IP, -+ CAKE_FLOW_HOSTS, /* = CAKE_FLOW_SRC_IP | CAKE_FLOW_DST_IP */ -+ CAKE_FLOW_FLOWS, -+ CAKE_FLOW_DUAL_SRC, /* = CAKE_FLOW_SRC_IP | CAKE_FLOW_FLOWS */ -+ CAKE_FLOW_DUAL_DST, /* = CAKE_FLOW_DST_IP | CAKE_FLOW_FLOWS */ -+ CAKE_FLOW_TRIPLE, /* = CAKE_FLOW_HOSTS | CAKE_FLOW_FLOWS */ -+ CAKE_FLOW_MAX, -+}; -+ -+enum { -+ CAKE_DIFFSERV_DIFFSERV3 = 0, -+ CAKE_DIFFSERV_DIFFSERV4, -+ CAKE_DIFFSERV_DIFFSERV8, -+ CAKE_DIFFSERV_BESTEFFORT, -+ CAKE_DIFFSERV_PRECEDENCE, -+ CAKE_DIFFSERV_MAX -+}; -+ -+enum { -+ CAKE_ACK_NONE = 0, -+ CAKE_ACK_FILTER, -+ CAKE_ACK_AGGRESSIVE, -+ CAKE_ACK_MAX -+}; -+ -+enum { -+ CAKE_ATM_NONE = 0, -+ CAKE_ATM_ATM, -+ CAKE_ATM_PTM, -+ CAKE_ATM_MAX -+}; -+ - #endif -diff --git a/include/uapi/linux/posix_types.h b/include/uapi/linux/posix_types.h -index 988f76e636e36..9a7a740b35a2c 100644 ---- a/include/uapi/linux/posix_types.h -+++ b/include/uapi/linux/posix_types.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _LINUX_POSIX_TYPES_H - #define _LINUX_POSIX_TYPES_H - -diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h -index 813e9e0767d33..c3a7d8ecc7b97 100644 ---- a/include/uapi/linux/rtnetlink.h -+++ b/include/uapi/linux/rtnetlink.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_RTNETLINK_H - #define __LINUX_RTNETLINK_H - -@@ -253,6 +254,11 @@ enum { - #define RTPROT_DHCP 16 /* DHCP client */ - #define RTPROT_MROUTED 17 /* Multicast daemon */ - #define RTPROT_BABEL 42 /* Babel daemon */ -+#define RTPROT_BGP 186 /* BGP Routes */ -+#define RTPROT_ISIS 187 /* ISIS Routes */ -+#define RTPROT_OSPF 188 /* OSPF Routes */ -+#define RTPROT_RIP 189 /* RIP Routes */ -+#define RTPROT_EIGRP 192 /* EIGRP Routes */ - - /* rtm_scope - -@@ -326,6 +332,9 @@ enum rtattr_type_t { - RTA_PAD, - RTA_UID, - RTA_TTL_PROPAGATE, -+ RTA_IP_PROTO, -+ RTA_SPORT, -+ RTA_DPORT, - __RTA_MAX - }; - -@@ -430,6 +439,8 @@ enum { - #define RTAX_QUICKACK RTAX_QUICKACK - RTAX_CC_ALGO, - #define RTAX_CC_ALGO RTAX_CC_ALGO -+ RTAX_FASTOPEN_NO_COOKIE, -+#define RTAX_FASTOPEN_NO_COOKIE RTAX_FASTOPEN_NO_COOKIE - __RTAX_MAX - }; - -@@ -538,9 +549,19 @@ struct tcmsg { - int tcm_ifindex; - __u32 tcm_handle; - __u32 tcm_parent; -+/* tcm_block_index is used instead of tcm_parent -+ * in case tcm_ifindex == TCM_IFINDEX_MAGIC_BLOCK -+ */ -+#define tcm_block_index tcm_parent - __u32 tcm_info; - }; - -+/* For manipulation of filters in shared block, tcm_ifindex is set to -+ * TCM_IFINDEX_MAGIC_BLOCK, and tcm_parent is aliased to tcm_block_index -+ * which is the block index. -+ */ -+#define TCM_IFINDEX_MAGIC_BLOCK (0xFFFFFFFFU) -+ - enum { - TCA_UNSPEC, - TCA_KIND, -@@ -554,6 +575,9 @@ enum { - TCA_PAD, - TCA_DUMP_INVISIBLE, - TCA_CHAIN, -+ TCA_HW_OFFLOAD, -+ TCA_INGRESS_BLOCK, -+ TCA_EGRESS_BLOCK, - __TCA_MAX - }; - -diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h -index fec24c41405b9..dd164d7f4f41a 100644 ---- a/include/uapi/linux/sctp.h -+++ b/include/uapi/linux/sctp.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ - /* SCTP kernel implementation - * (C) Copyright IBM Corp. 2001, 2004 - * Copyright (c) 1999-2000 Cisco, Inc. -@@ -98,6 +99,8 @@ typedef __s32 sctp_assoc_t; - #define SCTP_RECVRCVINFO 32 - #define SCTP_RECVNXTINFO 33 - #define SCTP_DEFAULT_SNDINFO 34 -+#define SCTP_AUTH_DEACTIVATE_KEY 35 -+#define SCTP_REUSE_PORT 36 - - /* Internal Socket Options. Some of the sctp library functions are - * implemented using these socket options. -@@ -122,6 +125,10 @@ typedef __s32 sctp_assoc_t; - #define SCTP_RESET_ASSOC 120 - #define SCTP_ADD_STREAMS 121 - #define SCTP_SOCKOPT_PEELOFF_FLAGS 122 -+#define SCTP_STREAM_SCHEDULER 123 -+#define SCTP_STREAM_SCHEDULER_VALUE 124 -+#define SCTP_INTERLEAVING_SUPPORTED 125 -+#define SCTP_SENDMSG_CONNECT 126 - - /* PR-SCTP policies */ - #define SCTP_PR_SCTP_NONE 0x0000 -@@ -256,6 +263,31 @@ struct sctp_nxtinfo { - sctp_assoc_t nxt_assoc_id; - }; - -+/* 5.3.7 SCTP PR-SCTP Information Structure (SCTP_PRINFO) -+ * -+ * This cmsghdr structure specifies SCTP options for sendmsg(). -+ * -+ * cmsg_level cmsg_type cmsg_data[] -+ * ------------ ------------ ------------------- -+ * IPPROTO_SCTP SCTP_PRINFO struct sctp_prinfo -+ */ -+struct sctp_prinfo { -+ __u16 pr_policy; -+ __u32 pr_value; -+}; -+ -+/* 5.3.8 SCTP AUTH Information Structure (SCTP_AUTHINFO) -+ * -+ * This cmsghdr structure specifies SCTP options for sendmsg(). -+ * -+ * cmsg_level cmsg_type cmsg_data[] -+ * ------------ ------------ ------------------- -+ * IPPROTO_SCTP SCTP_AUTHINFO struct sctp_authinfo -+ */ -+struct sctp_authinfo { -+ __u16 auth_keynumber; -+}; -+ - /* - * sinfo_flags: 16 bits (unsigned integer) - * -@@ -267,6 +299,8 @@ enum sctp_sinfo_flags { - SCTP_ADDR_OVER = (1 << 1), /* Override the primary destination. */ - SCTP_ABORT = (1 << 2), /* Send an ABORT message to the peer. */ - SCTP_SACK_IMMEDIATELY = (1 << 3), /* SACK should be sent without delay. */ -+ /* 2 bits here have been used by SCTP_PR_SCTP_MASK */ -+ SCTP_SENDALL = (1 << 6), - SCTP_NOTIFICATION = MSG_NOTIFICATION, /* Next message is not user msg but notification. */ - SCTP_EOF = MSG_FIN, /* Initiate graceful shutdown process. */ - }; -@@ -289,6 +323,14 @@ typedef enum sctp_cmsg_type { - #define SCTP_RCVINFO SCTP_RCVINFO - SCTP_NXTINFO, /* 5.3.6 SCTP Next Receive Information Structure */ - #define SCTP_NXTINFO SCTP_NXTINFO -+ SCTP_PRINFO, /* 5.3.7 SCTP PR-SCTP Information Structure */ -+#define SCTP_PRINFO SCTP_PRINFO -+ SCTP_AUTHINFO, /* 5.3.8 SCTP AUTH Information Structure */ -+#define SCTP_AUTHINFO SCTP_AUTHINFO -+ SCTP_DSTADDRV4, /* 5.3.9 SCTP Destination IPv4 Address Structure */ -+#define SCTP_DSTADDRV4 SCTP_DSTADDRV4 -+ SCTP_DSTADDRV6, /* 5.3.10 SCTP Destination IPv6 Address Structure */ -+#define SCTP_DSTADDRV6 SCTP_DSTADDRV6 - } sctp_cmsg_t; - - /* -@@ -376,7 +418,7 @@ struct sctp_remote_error { - __u16 sre_type; - __u16 sre_flags; - __u32 sre_length; -- __u16 sre_error; -+ __be16 sre_error; - sctp_assoc_t sre_assoc_id; - __u8 sre_data[0]; - }; -@@ -456,6 +498,8 @@ struct sctp_pdapi_event { - __u32 pdapi_length; - __u32 pdapi_indication; - sctp_assoc_t pdapi_assoc_id; -+ __u32 pdapi_stream; -+ __u32 pdapi_seq; - }; - - enum { SCTP_PARTIAL_DELIVERY_ABORTED=0, }; -@@ -476,7 +520,12 @@ struct sctp_authkey_event { - sctp_assoc_t auth_assoc_id; - }; - --enum { SCTP_AUTH_NEWKEY = 0, }; -+enum { -+ SCTP_AUTH_NEW_KEY, -+#define SCTP_AUTH_NEWKEY SCTP_AUTH_NEW_KEY /* compatible with before */ -+ SCTP_AUTH_FREE_KEY, -+ SCTP_AUTH_NO_AUTH, -+}; - - /* - * 6.1.9. SCTP_SENDER_DRY_EVENT -@@ -714,6 +763,8 @@ enum sctp_spp_flags { - SPP_SACKDELAY_DISABLE = 1<<6, /*Disable SACK*/ - SPP_SACKDELAY = SPP_SACKDELAY_ENABLE | SPP_SACKDELAY_DISABLE, - SPP_HB_TIME_IS_ZERO = 1<<7, /* Set HB delay to 0 */ -+ SPP_IPV6_FLOWLABEL = 1<<8, -+ SPP_DSCP = 1<<9, - }; - - struct sctp_paddrparams { -@@ -724,6 +775,8 @@ struct sctp_paddrparams { - __u32 spp_pathmtu; - __u32 spp_sackdelay; - __u32 spp_flags; -+ __u32 spp_ipv6_flowlabel; -+ __u8 spp_dscp; - } __attribute__((packed, aligned(4))); - - /* -@@ -812,6 +865,12 @@ struct sctp_assoc_value { - uint32_t assoc_value; - }; - -+struct sctp_stream_value { -+ sctp_assoc_t assoc_id; -+ uint16_t stream_id; -+ uint16_t stream_value; -+}; -+ - /* - * 7.2.2 Peer Address Information - * -@@ -1082,4 +1141,12 @@ struct sctp_add_streams { - uint16_t sas_outstrms; - }; - -+/* SCTP Stream schedulers */ -+enum sctp_sched_type { -+ SCTP_SS_FCFS, -+ SCTP_SS_PRIO, -+ SCTP_SS_RR, -+ SCTP_SS_MAX = SCTP_SS_RR -+}; -+ - #endif /* _SCTP_H */ -diff --git a/include/uapi/linux/seg6.h b/include/uapi/linux/seg6.h -index 07152792e61d2..329163e4a08d2 100644 ---- a/include/uapi/linux/seg6.h -+++ b/include/uapi/linux/seg6.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ - /* - * SR-IPv6 implementation - * -@@ -25,9 +26,9 @@ struct ipv6_sr_hdr { - __u8 hdrlen; - __u8 type; - __u8 segments_left; -- __u8 first_segment; -+ __u8 first_segment; /* Represents the last_entry field of SRH */ - __u8 flags; -- __u16 reserved; -+ __u16 tag; - - struct in6_addr segments[0]; - }; -diff --git a/include/uapi/linux/seg6_genl.h b/include/uapi/linux/seg6_genl.h -index 99382f94fa0a3..0c230524e0a15 100644 ---- a/include/uapi/linux/seg6_genl.h -+++ b/include/uapi/linux/seg6_genl.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _LINUX_SEG6_GENL_H - #define _LINUX_SEG6_GENL_H - -diff --git a/include/uapi/linux/seg6_hmac.h b/include/uapi/linux/seg6_hmac.h -index 704f93e80b417..3fb3412e1eb2d 100644 ---- a/include/uapi/linux/seg6_hmac.h -+++ b/include/uapi/linux/seg6_hmac.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _LINUX_SEG6_HMAC_H - #define _LINUX_SEG6_HMAC_H - -diff --git a/include/uapi/linux/seg6_iptunnel.h b/include/uapi/linux/seg6_iptunnel.h -index a5dc05a1cbba3..3004e982c23dc 100644 ---- a/include/uapi/linux/seg6_iptunnel.h -+++ b/include/uapi/linux/seg6_iptunnel.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ - /* - * SR-IPv6 implementation - * -diff --git a/include/uapi/linux/seg6_local.h b/include/uapi/linux/seg6_local.h -index 76b90d60c7ea7..5312de80bcfae 100644 ---- a/include/uapi/linux/seg6_local.h -+++ b/include/uapi/linux/seg6_local.h -@@ -25,6 +25,7 @@ enum { - SEG6_LOCAL_NH6, - SEG6_LOCAL_IIF, - SEG6_LOCAL_OIF, -+ SEG6_LOCAL_BPF, - __SEG6_LOCAL_MAX, - }; - #define SEG6_LOCAL_MAX (__SEG6_LOCAL_MAX - 1) -@@ -59,10 +60,21 @@ enum { - SEG6_LOCAL_ACTION_END_AS = 13, - /* forward to SR-unaware VNF with masquerading */ - SEG6_LOCAL_ACTION_END_AM = 14, -+ /* custom BPF action */ -+ SEG6_LOCAL_ACTION_END_BPF = 15, - - __SEG6_LOCAL_ACTION_MAX, - }; - - #define SEG6_LOCAL_ACTION_MAX (__SEG6_LOCAL_ACTION_MAX - 1) - -+enum { -+ SEG6_LOCAL_BPF_PROG_UNSPEC, -+ SEG6_LOCAL_BPF_PROG, -+ SEG6_LOCAL_BPF_PROG_NAME, -+ __SEG6_LOCAL_BPF_PROG_MAX, -+}; -+ -+#define SEG6_LOCAL_BPF_PROG_MAX (__SEG6_LOCAL_BPF_PROG_MAX - 1) -+ - #endif -diff --git a/include/uapi/linux/sock_diag.h b/include/uapi/linux/sock_diag.h -index 901231e648963..a69cf20ff174a 100644 ---- a/include/uapi/linux/sock_diag.h -+++ b/include/uapi/linux/sock_diag.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __SOCK_DIAG_H__ - #define __SOCK_DIAG_H__ - -diff --git a/include/uapi/linux/socket.h b/include/uapi/linux/socket.h -index 8c1e5017741d1..268b9482461a4 100644 ---- a/include/uapi/linux/socket.h -+++ b/include/uapi/linux/socket.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _LINUX_SOCKET_H - #define _LINUX_SOCKET_H - -diff --git a/include/uapi/linux/sockios.h b/include/uapi/linux/sockios.h -index 79d029d253100..d393e9ed39642 100644 ---- a/include/uapi/linux/sockios.h -+++ b/include/uapi/linux/sockios.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ - /* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket -diff --git a/include/uapi/linux/stddef.h b/include/uapi/linux/stddef.h -index 4bb69decd468b..23e025fec0419 100644 ---- a/include/uapi/linux/stddef.h -+++ b/include/uapi/linux/stddef.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - - - #ifndef __always_inline -diff --git a/include/uapi/linux/sysinfo.h b/include/uapi/linux/sysinfo.h -index 934335a22522c..435d5c23f0c0e 100644 ---- a/include/uapi/linux/sysinfo.h -+++ b/include/uapi/linux/sysinfo.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _LINUX_SYSINFO_H - #define _LINUX_SYSINFO_H - -diff --git a/include/uapi/linux/tc_act/tc_bpf.h b/include/uapi/linux/tc_act/tc_bpf.h -index 8dc2ac05eecf0..6e89a5df49a46 100644 ---- a/include/uapi/linux/tc_act/tc_bpf.h -+++ b/include/uapi/linux/tc_act/tc_bpf.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ - /* - * Copyright (c) 2015 Jiri Pirko - * -diff --git a/include/uapi/linux/tc_act/tc_connmark.h b/include/uapi/linux/tc_act/tc_connmark.h -index 62a5e944c5548..80caa47b19334 100644 ---- a/include/uapi/linux/tc_act/tc_connmark.h -+++ b/include/uapi/linux/tc_act/tc_connmark.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __UAPI_TC_CONNMARK_H - #define __UAPI_TC_CONNMARK_H - -diff --git a/include/uapi/linux/tc_act/tc_csum.h b/include/uapi/linux/tc_act/tc_csum.h -index a11bb355dbfb2..0ecf4d29e2f31 100644 ---- a/include/uapi/linux/tc_act/tc_csum.h -+++ b/include/uapi/linux/tc_act/tc_csum.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_TC_CSUM_H - #define __LINUX_TC_CSUM_H - -diff --git a/include/uapi/linux/tc_act/tc_defact.h b/include/uapi/linux/tc_act/tc_defact.h -index d2a3abb77aebd..e3ecd8bf37de2 100644 ---- a/include/uapi/linux/tc_act/tc_defact.h -+++ b/include/uapi/linux/tc_act/tc_defact.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_TC_DEF_H - #define __LINUX_TC_DEF_H - -diff --git a/include/uapi/linux/tc_act/tc_gact.h b/include/uapi/linux/tc_act/tc_gact.h -index 70b536a8f8b26..94273c3b81b0b 100644 ---- a/include/uapi/linux/tc_act/tc_gact.h -+++ b/include/uapi/linux/tc_act/tc_gact.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_TC_GACT_H - #define __LINUX_TC_GACT_H - -diff --git a/include/uapi/linux/tc_act/tc_ife.h b/include/uapi/linux/tc_act/tc_ife.h -index 7c2817866c97e..2f48490ef3867 100644 ---- a/include/uapi/linux/tc_act/tc_ife.h -+++ b/include/uapi/linux/tc_act/tc_ife.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __UAPI_TC_IFE_H - #define __UAPI_TC_IFE_H - -diff --git a/include/uapi/linux/tc_act/tc_ipt.h b/include/uapi/linux/tc_act/tc_ipt.h -index 7c6e155dd981d..b743c8bddd13d 100644 ---- a/include/uapi/linux/tc_act/tc_ipt.h -+++ b/include/uapi/linux/tc_act/tc_ipt.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_TC_IPT_H - #define __LINUX_TC_IPT_H - -diff --git a/include/uapi/linux/tc_act/tc_mirred.h b/include/uapi/linux/tc_act/tc_mirred.h -index 3d7a2b352a62c..5dd671cf57765 100644 ---- a/include/uapi/linux/tc_act/tc_mirred.h -+++ b/include/uapi/linux/tc_act/tc_mirred.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_TC_MIR_H - #define __LINUX_TC_MIR_H - -@@ -9,13 +10,13 @@ - #define TCA_EGRESS_MIRROR 2 /* mirror packet to EGRESS */ - #define TCA_INGRESS_REDIR 3 /* packet redirect to INGRESS*/ - #define TCA_INGRESS_MIRROR 4 /* mirror packet to INGRESS */ -- -+ - struct tc_mirred { - tc_gen; - int eaction; /* one of IN/EGRESS_MIRROR/REDIR */ - __u32 ifindex; /* ifindex of egress port */ - }; -- -+ - enum { - TCA_MIRRED_UNSPEC, - TCA_MIRRED_TM, -@@ -24,5 +25,5 @@ enum { - __TCA_MIRRED_MAX - }; - #define TCA_MIRRED_MAX (__TCA_MIRRED_MAX - 1) -- -+ - #endif -diff --git a/include/uapi/linux/tc_act/tc_nat.h b/include/uapi/linux/tc_act/tc_nat.h -index 923457c9ebf0c..086be842587bd 100644 ---- a/include/uapi/linux/tc_act/tc_nat.h -+++ b/include/uapi/linux/tc_act/tc_nat.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_TC_NAT_H - #define __LINUX_TC_NAT_H - -diff --git a/include/uapi/linux/tc_act/tc_pedit.h b/include/uapi/linux/tc_act/tc_pedit.h -index 143d2b31a3166..24ec792dacc18 100644 ---- a/include/uapi/linux/tc_act/tc_pedit.h -+++ b/include/uapi/linux/tc_act/tc_pedit.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_TC_PED_H - #define __LINUX_TC_PED_H - -@@ -16,13 +17,15 @@ enum { - TCA_PEDIT_KEY_EX, - __TCA_PEDIT_MAX - }; -+ - #define TCA_PEDIT_MAX (__TCA_PEDIT_MAX - 1) -- -+ - enum { - TCA_PEDIT_KEY_EX_HTYPE = 1, - TCA_PEDIT_KEY_EX_CMD = 2, - __TCA_PEDIT_KEY_EX_MAX - }; -+ - #define TCA_PEDIT_KEY_EX_MAX (__TCA_PEDIT_KEY_EX_MAX - 1) - - /* TCA_PEDIT_KEY_EX_HDR_TYPE_NETWROK is a special case for legacy users. It -@@ -37,6 +40,7 @@ enum pedit_header_type { - TCA_PEDIT_KEY_EX_HDR_TYPE_UDP = 5, - __PEDIT_HDR_TYPE_MAX, - }; -+ - #define TCA_PEDIT_HDR_TYPE_MAX (__PEDIT_HDR_TYPE_MAX - 1) - - enum pedit_cmd { -@@ -44,6 +48,7 @@ enum pedit_cmd { - TCA_PEDIT_KEY_EX_CMD_ADD = 1, - __PEDIT_CMD_MAX, - }; -+ - #define TCA_PEDIT_CMD_MAX (__PEDIT_CMD_MAX - 1) - - struct tc_pedit_key { -@@ -54,13 +59,14 @@ struct tc_pedit_key { - __u32 offmask; - __u32 shift; - }; -- -+ - struct tc_pedit_sel { - tc_gen; - unsigned char nkeys; - unsigned char flags; - struct tc_pedit_key keys[0]; - }; -+ - #define tc_pedit tc_pedit_sel - - #endif -diff --git a/include/uapi/linux/tc_act/tc_sample.h b/include/uapi/linux/tc_act/tc_sample.h -index edc9058bb30d3..bd7e9f03abd2e 100644 ---- a/include/uapi/linux/tc_act/tc_sample.h -+++ b/include/uapi/linux/tc_act/tc_sample.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_TC_SAMPLE_H - #define __LINUX_TC_SAMPLE_H - -diff --git a/include/uapi/linux/tc_act/tc_skbedit.h b/include/uapi/linux/tc_act/tc_skbedit.h -index 2884425738ce7..6de6071ebed60 100644 ---- a/include/uapi/linux/tc_act/tc_skbedit.h -+++ b/include/uapi/linux/tc_act/tc_skbedit.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* - * Copyright (c) 2008, Intel Corporation. - * -@@ -29,6 +30,7 @@ - #define SKBEDIT_F_MARK 0x4 - #define SKBEDIT_F_PTYPE 0x8 - #define SKBEDIT_F_MASK 0x10 -+#define SKBEDIT_F_INHERITDSFIELD 0x20 - - struct tc_skbedit { - tc_gen; -@@ -44,6 +46,7 @@ enum { - TCA_SKBEDIT_PAD, - TCA_SKBEDIT_PTYPE, - TCA_SKBEDIT_MASK, -+ TCA_SKBEDIT_FLAGS, - __TCA_SKBEDIT_MAX - }; - #define TCA_SKBEDIT_MAX (__TCA_SKBEDIT_MAX - 1) -diff --git a/include/uapi/linux/tc_act/tc_skbmod.h b/include/uapi/linux/tc_act/tc_skbmod.h -index 10fc07da6c699..38c072f66f2fc 100644 ---- a/include/uapi/linux/tc_act/tc_skbmod.h -+++ b/include/uapi/linux/tc_act/tc_skbmod.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ - /* - * Copyright (c) 2016, Jamal Hadi Salim - * -diff --git a/include/uapi/linux/tc_act/tc_tunnel_key.h b/include/uapi/linux/tc_act/tc_tunnel_key.h -index afcd4be953e27..be384d63e1b56 100644 ---- a/include/uapi/linux/tc_act/tc_tunnel_key.h -+++ b/include/uapi/linux/tc_act/tc_tunnel_key.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ - /* - * Copyright (c) 2016, Amir Vadai - * Copyright (c) 2016, Mellanox Technologies. All rights reserved. -@@ -35,9 +36,37 @@ enum { - TCA_TUNNEL_KEY_PAD, - TCA_TUNNEL_KEY_ENC_DST_PORT, /* be16 */ - TCA_TUNNEL_KEY_NO_CSUM, /* u8 */ -+ TCA_TUNNEL_KEY_ENC_OPTS, /* Nested TCA_TUNNEL_KEY_ENC_OPTS_ -+ * attributes -+ */ -+ TCA_TUNNEL_KEY_ENC_TOS, /* u8 */ -+ TCA_TUNNEL_KEY_ENC_TTL, /* u8 */ - __TCA_TUNNEL_KEY_MAX, - }; - - #define TCA_TUNNEL_KEY_MAX (__TCA_TUNNEL_KEY_MAX - 1) - -+enum { -+ TCA_TUNNEL_KEY_ENC_OPTS_UNSPEC, -+ TCA_TUNNEL_KEY_ENC_OPTS_GENEVE, /* Nested -+ * TCA_TUNNEL_KEY_ENC_OPTS_ -+ * attributes -+ */ -+ __TCA_TUNNEL_KEY_ENC_OPTS_MAX, -+}; -+ -+#define TCA_TUNNEL_KEY_ENC_OPTS_MAX (__TCA_TUNNEL_KEY_ENC_OPTS_MAX - 1) -+ -+enum { -+ TCA_TUNNEL_KEY_ENC_OPT_GENEVE_UNSPEC, -+ TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS, /* be16 */ -+ TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE, /* u8 */ -+ TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA, /* 4 to 128 bytes */ -+ -+ __TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX, -+}; -+ -+#define TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX \ -+ (__TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX - 1) -+ - #endif -diff --git a/include/uapi/linux/tc_act/tc_vlan.h b/include/uapi/linux/tc_act/tc_vlan.h -index bddb272b843f5..0d7b5fd6605b0 100644 ---- a/include/uapi/linux/tc_act/tc_vlan.h -+++ b/include/uapi/linux/tc_act/tc_vlan.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ - /* - * Copyright (c) 2014 Jiri Pirko - * -diff --git a/include/uapi/linux/tc_ematch/tc_em_cmp.h b/include/uapi/linux/tc_ematch/tc_em_cmp.h -index f34bb1bae083e..2549d9d6e0310 100644 ---- a/include/uapi/linux/tc_ematch/tc_em_cmp.h -+++ b/include/uapi/linux/tc_ematch/tc_em_cmp.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_TC_EM_CMP_H - #define __LINUX_TC_EM_CMP_H - -diff --git a/include/uapi/linux/tc_ematch/tc_em_ipt.h b/include/uapi/linux/tc_ematch/tc_em_ipt.h -new file mode 100644 -index 0000000000000..49a65530992c1 ---- /dev/null -+++ b/include/uapi/linux/tc_ematch/tc_em_ipt.h -@@ -0,0 +1,20 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+#ifndef __LINUX_TC_EM_IPT_H -+#define __LINUX_TC_EM_IPT_H -+ -+#include -+#include -+ -+enum { -+ TCA_EM_IPT_UNSPEC, -+ TCA_EM_IPT_HOOK, -+ TCA_EM_IPT_MATCH_NAME, -+ TCA_EM_IPT_MATCH_REVISION, -+ TCA_EM_IPT_NFPROTO, -+ TCA_EM_IPT_MATCH_DATA, -+ __TCA_EM_IPT_MAX -+}; -+ -+#define TCA_EM_IPT_MAX (__TCA_EM_IPT_MAX - 1) -+ -+#endif -diff --git a/include/uapi/linux/tc_ematch/tc_em_meta.h b/include/uapi/linux/tc_ematch/tc_em_meta.h -index b11f8ce2d3c0a..cf30b5bc4eaf2 100644 ---- a/include/uapi/linux/tc_ematch/tc_em_meta.h -+++ b/include/uapi/linux/tc_ematch/tc_em_meta.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_TC_EM_META_H - #define __LINUX_TC_EM_META_H - -diff --git a/include/uapi/linux/tc_ematch/tc_em_nbyte.h b/include/uapi/linux/tc_ematch/tc_em_nbyte.h -index 7172cfb999c15..c76333f7f6f26 100644 ---- a/include/uapi/linux/tc_ematch/tc_em_nbyte.h -+++ b/include/uapi/linux/tc_ematch/tc_em_nbyte.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __LINUX_TC_EM_NBYTE_H - #define __LINUX_TC_EM_NBYTE_H - -diff --git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h -index 8edad3f942686..2e766cf303fbe 100644 ---- a/include/uapi/linux/tcp.h -+++ b/include/uapi/linux/tcp.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ - /* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket -@@ -119,6 +120,12 @@ enum { - #define TCP_FASTOPEN_CONNECT 30 /* Attempt FastOpen with connect */ - #define TCP_ULP 31 /* Attach a ULP to a TCP connection */ - #define TCP_MD5SIG_EXT 32 /* TCP MD5 Signature with extensions */ -+#define TCP_FASTOPEN_KEY 33 /* Set the key for Fast Open (cookie) */ -+#define TCP_FASTOPEN_NO_COOKIE 34 /* Enable TFO without a TFO cookie */ -+#define TCP_ZEROCOPY_RECEIVE 35 -+#define TCP_INQ 36 /* Notify bytes available to read as a cmsg on read */ -+ -+#define TCP_CM_INQ TCP_INQ - - struct tcp_repair_opt { - __u32 opt_code; -@@ -221,6 +228,9 @@ struct tcp_info { - __u64 tcpi_busy_time; /* Time (usec) busy sending data */ - __u64 tcpi_rwnd_limited; /* Time (usec) limited by receive window */ - __u64 tcpi_sndbuf_limited; /* Time (usec) limited by send buffer */ -+ -+ __u32 tcpi_delivered; -+ __u32 tcpi_delivered_ce; - }; - - /* netlink attributes types for SCM_TIMESTAMPING_OPT_STATS */ -@@ -238,6 +248,11 @@ enum { - TCP_NLA_MIN_RTT, /* minimum RTT */ - TCP_NLA_RECUR_RETRANS, /* Recurring retransmits for the current pkt */ - TCP_NLA_DELIVERY_RATE_APP_LMT, /* delivery rate application limited ? */ -+ TCP_NLA_SNDQ_SIZE, /* Data (bytes) pending in send queue */ -+ TCP_NLA_CA_STATE, /* ca_state of socket */ -+ TCP_NLA_SND_SSTHRESH, /* Slow start size threshold */ -+ TCP_NLA_DELIVERED, /* Data pkts delivered incl. out-of-order */ -+ TCP_NLA_DELIVERED_CE, /* Like above but only ones w/ CE marks */ - - }; - -@@ -265,4 +280,11 @@ struct tcp_diag_md5sig { - __u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN]; - }; - -+/* setsockopt(fd, IPPROTO_TCP, TCP_ZEROCOPY_RECEIVE, ...) */ -+ -+struct tcp_zerocopy_receive { -+ __u64 address; /* in: address of mapping */ -+ __u32 length; /* in/out: number of bytes to map/mapped */ -+ __u32 recv_skip_hint; /* out: amount of bytes to skip */ -+}; - #endif /* _LINUX_TCP_H */ -diff --git a/include/uapi/linux/tcp_metrics.h b/include/uapi/linux/tcp_metrics.h -index 80ad90d0cfc23..7cb4a172feeda 100644 ---- a/include/uapi/linux/tcp_metrics.h -+++ b/include/uapi/linux/tcp_metrics.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* tcp_metrics.h - TCP Metrics Interface */ - - #ifndef _LINUX_TCP_METRICS_H -diff --git a/include/uapi/linux/tipc.h b/include/uapi/linux/tipc.h -index 924fb5cf1d468..7a166a0f93802 100644 ---- a/include/uapi/linux/tipc.h -+++ b/include/uapi/linux/tipc.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ - /* - * include/uapi/linux/tipc.h: Header for TIPC socket interface - * -@@ -44,82 +45,38 @@ - * TIPC addressing primitives - */ - --struct tipc_portid { -+struct tipc_socket_addr { - __u32 ref; - __u32 node; - }; - --struct tipc_name { -+struct tipc_service_addr { - __u32 type; - __u32 instance; - }; - --struct tipc_name_seq { -+struct tipc_service_range { - __u32 type; - __u32 lower; - __u32 upper; - }; - --/* TIPC Address Size, Offset, Mask specification for Z.C.N -- */ --#define TIPC_NODE_BITS 12 --#define TIPC_CLUSTER_BITS 12 --#define TIPC_ZONE_BITS 8 -- --#define TIPC_NODE_OFFSET 0 --#define TIPC_CLUSTER_OFFSET TIPC_NODE_BITS --#define TIPC_ZONE_OFFSET (TIPC_CLUSTER_OFFSET + TIPC_CLUSTER_BITS) -- --#define TIPC_NODE_SIZE ((1UL << TIPC_NODE_BITS) - 1) --#define TIPC_CLUSTER_SIZE ((1UL << TIPC_CLUSTER_BITS) - 1) --#define TIPC_ZONE_SIZE ((1UL << TIPC_ZONE_BITS) - 1) -- --#define TIPC_NODE_MASK (TIPC_NODE_SIZE << TIPC_NODE_OFFSET) --#define TIPC_CLUSTER_MASK (TIPC_CLUSTER_SIZE << TIPC_CLUSTER_OFFSET) --#define TIPC_ZONE_MASK (TIPC_ZONE_SIZE << TIPC_ZONE_OFFSET) -- --#define TIPC_ZONE_CLUSTER_MASK (TIPC_ZONE_MASK | TIPC_CLUSTER_MASK) -- --static __inline__ __u32 tipc_addr(unsigned int zone, -- unsigned int cluster, -- unsigned int node) --{ -- return (zone << TIPC_ZONE_OFFSET) | -- (cluster << TIPC_CLUSTER_OFFSET) | -- node; --} -- --static __inline__ unsigned int tipc_zone(__u32 addr) --{ -- return addr >> TIPC_ZONE_OFFSET; --} -- --static __inline__ unsigned int tipc_cluster(__u32 addr) --{ -- return (addr & TIPC_CLUSTER_MASK) >> TIPC_CLUSTER_OFFSET; --} -- --static __inline__ unsigned int tipc_node(__u32 addr) --{ -- return addr & TIPC_NODE_MASK; --} -- - /* -- * Application-accessible port name types -+ * Application-accessible service types - */ - --#define TIPC_CFG_SRV 0 /* configuration service name type */ --#define TIPC_TOP_SRV 1 /* topology service name type */ --#define TIPC_LINK_STATE 2 /* link state name type */ --#define TIPC_RESERVED_TYPES 64 /* lowest user-publishable name type */ -+#define TIPC_NODE_STATE 0 /* node state service type */ -+#define TIPC_TOP_SRV 1 /* topology server service type */ -+#define TIPC_LINK_STATE 2 /* link state service type */ -+#define TIPC_RESERVED_TYPES 64 /* lowest user-allowed service type */ - - /* -- * Publication scopes when binding port names and port name sequences -+ * Publication scopes when binding service / service range - */ -- --#define TIPC_ZONE_SCOPE 1 --#define TIPC_CLUSTER_SCOPE 2 --#define TIPC_NODE_SCOPE 3 -+enum tipc_scope { -+ TIPC_CLUSTER_SCOPE = 2, /* 0 can also be used */ -+ TIPC_NODE_SCOPE = 3 -+}; - - /* - * Limiting values for messages -@@ -151,28 +108,28 @@ static __inline__ unsigned int tipc_node(__u32 addr) - * TIPC topology subscription service definitions - */ - --#define TIPC_SUB_PORTS 0x01 /* filter for port availability */ --#define TIPC_SUB_SERVICE 0x02 /* filter for service availability */ --#define TIPC_SUB_CANCEL 0x04 /* cancel a subscription */ -+#define TIPC_SUB_PORTS 0x01 /* filter: evt at each match */ -+#define TIPC_SUB_SERVICE 0x02 /* filter: evt at first up/last down */ -+#define TIPC_SUB_CANCEL 0x04 /* filter: cancel a subscription */ - - #define TIPC_WAIT_FOREVER (~0) /* timeout for permanent subscription */ - - struct tipc_subscr { -- struct tipc_name_seq seq; /* name sequence of interest */ -+ struct tipc_service_range seq; /* range of interest */ - __u32 timeout; /* subscription duration (in ms) */ - __u32 filter; /* bitmask of filter options */ - char usr_handle[8]; /* available for subscriber use */ - }; - - #define TIPC_PUBLISHED 1 /* publication event */ --#define TIPC_WITHDRAWN 2 /* withdraw event */ -+#define TIPC_WITHDRAWN 2 /* withdrawal event */ - #define TIPC_SUBSCR_TIMEOUT 3 /* subscription timeout event */ - - struct tipc_event { - __u32 event; /* event type */ -- __u32 found_lower; /* matching name seq instances */ -- __u32 found_upper; /* " " " " */ -- struct tipc_portid port; /* associated port */ -+ __u32 found_lower; /* matching range */ -+ __u32 found_upper; /* " " */ -+ struct tipc_socket_addr port; /* associated socket */ - struct tipc_subscr s; /* associated subscription */ - }; - -@@ -192,20 +149,20 @@ struct tipc_event { - #define SOL_TIPC 271 - #endif - --#define TIPC_ADDR_NAMESEQ 1 --#define TIPC_ADDR_MCAST 1 --#define TIPC_ADDR_NAME 2 --#define TIPC_ADDR_ID 3 -+#define TIPC_ADDR_MCAST 1 -+#define TIPC_SERVICE_RANGE 1 -+#define TIPC_SERVICE_ADDR 2 -+#define TIPC_SOCKET_ADDR 3 - - struct sockaddr_tipc { - unsigned short family; - unsigned char addrtype; - signed char scope; - union { -- struct tipc_portid id; -- struct tipc_name_seq nameseq; -+ struct tipc_socket_addr id; -+ struct tipc_service_range nameseq; - struct { -- struct tipc_name name; -+ struct tipc_service_addr name; - __u32 domain; - } name; - } addr; -@@ -231,26 +188,103 @@ struct sockaddr_tipc { - #define TIPC_SOCK_RECVQ_DEPTH 132 /* Default: none (read only) */ - #define TIPC_MCAST_BROADCAST 133 /* Default: TIPC selects. No arg */ - #define TIPC_MCAST_REPLICAST 134 /* Default: TIPC selects. No arg */ -+#define TIPC_GROUP_JOIN 135 /* Takes struct tipc_group_req* */ -+#define TIPC_GROUP_LEAVE 136 /* No argument */ -+ -+/* -+ * Flag values -+ */ -+#define TIPC_GROUP_LOOPBACK 0x1 /* Receive copy of sent msg when match */ -+#define TIPC_GROUP_MEMBER_EVTS 0x2 /* Receive membership events in socket */ -+ -+struct tipc_group_req { -+ __u32 type; /* group id */ -+ __u32 instance; /* member id */ -+ __u32 scope; /* cluster/node */ -+ __u32 flags; -+}; - - /* - * Maximum sizes of TIPC bearer-related names (including terminating NULL) - * The string formatting for each name element is: - * media: media - * interface: media:interface name -- * link: Z.C.N:interface-Z.C.N:interface -- * -+ * link: node:interface-node:interface - */ -- -+#define TIPC_NODEID_LEN 16 - #define TIPC_MAX_MEDIA_NAME 16 - #define TIPC_MAX_IF_NAME 16 - #define TIPC_MAX_BEARER_NAME 32 --#define TIPC_MAX_LINK_NAME 60 -+#define TIPC_MAX_LINK_NAME 68 - --#define SIOCGETLINKNAME SIOCPROTOPRIVATE -+#define SIOCGETLINKNAME SIOCPROTOPRIVATE -+#define SIOCGETNODEID (SIOCPROTOPRIVATE + 1) - - struct tipc_sioc_ln_req { - __u32 peer; - __u32 bearer_id; - char linkname[TIPC_MAX_LINK_NAME]; - }; -+ -+struct tipc_sioc_nodeid_req { -+ __u32 peer; -+ char node_id[TIPC_NODEID_LEN]; -+}; -+ -+/* The macros and functions below are deprecated: -+ */ -+ -+#define TIPC_CFG_SRV 0 -+#define TIPC_ZONE_SCOPE 1 -+ -+#define TIPC_ADDR_NAMESEQ 1 -+#define TIPC_ADDR_NAME 2 -+#define TIPC_ADDR_ID 3 -+ -+#define TIPC_NODE_BITS 12 -+#define TIPC_CLUSTER_BITS 12 -+#define TIPC_ZONE_BITS 8 -+ -+#define TIPC_NODE_OFFSET 0 -+#define TIPC_CLUSTER_OFFSET TIPC_NODE_BITS -+#define TIPC_ZONE_OFFSET (TIPC_CLUSTER_OFFSET + TIPC_CLUSTER_BITS) -+ -+#define TIPC_NODE_SIZE ((1UL << TIPC_NODE_BITS) - 1) -+#define TIPC_CLUSTER_SIZE ((1UL << TIPC_CLUSTER_BITS) - 1) -+#define TIPC_ZONE_SIZE ((1UL << TIPC_ZONE_BITS) - 1) -+ -+#define TIPC_NODE_MASK (TIPC_NODE_SIZE << TIPC_NODE_OFFSET) -+#define TIPC_CLUSTER_MASK (TIPC_CLUSTER_SIZE << TIPC_CLUSTER_OFFSET) -+#define TIPC_ZONE_MASK (TIPC_ZONE_SIZE << TIPC_ZONE_OFFSET) -+ -+#define TIPC_ZONE_CLUSTER_MASK (TIPC_ZONE_MASK | TIPC_CLUSTER_MASK) -+ -+#define tipc_portid tipc_socket_addr -+#define tipc_name tipc_service_addr -+#define tipc_name_seq tipc_service_range -+ -+static __inline__ __u32 tipc_addr(unsigned int zone, -+ unsigned int cluster, -+ unsigned int node) -+{ -+ return (zone << TIPC_ZONE_OFFSET) | -+ (cluster << TIPC_CLUSTER_OFFSET) | -+ node; -+} -+ -+static __inline__ unsigned int tipc_zone(__u32 addr) -+{ -+ return addr >> TIPC_ZONE_OFFSET; -+} -+ -+static __inline__ unsigned int tipc_cluster(__u32 addr) -+{ -+ return (addr & TIPC_CLUSTER_MASK) >> TIPC_CLUSTER_OFFSET; -+} -+ -+static __inline__ unsigned int tipc_node(__u32 addr) -+{ -+ return addr & TIPC_NODE_MASK; -+} -+ - #endif -diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h -index f9edd20fe9ba8..0ebe02ef1a86b 100644 ---- a/include/uapi/linux/tipc_netlink.h -+++ b/include/uapi/linux/tipc_netlink.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ - /* - * Copyright (c) 2014, Ericsson AB - * All rights reserved. -@@ -113,6 +114,14 @@ enum { - TIPC_NLA_SOCK_REF, /* u32 */ - TIPC_NLA_SOCK_CON, /* nest */ - TIPC_NLA_SOCK_HAS_PUBL, /* flag */ -+ TIPC_NLA_SOCK_STAT, /* nest */ -+ TIPC_NLA_SOCK_TYPE, /* u32 */ -+ TIPC_NLA_SOCK_INO, /* u32 */ -+ TIPC_NLA_SOCK_UID, /* u32 */ -+ TIPC_NLA_SOCK_TIPC_STATE, /* u32 */ -+ TIPC_NLA_SOCK_COOKIE, /* u64 */ -+ TIPC_NLA_SOCK_PAD, /* flag */ -+ TIPC_NLA_SOCK_GROUP, /* nest */ - - __TIPC_NLA_SOCK_MAX, - TIPC_NLA_SOCK_MAX = __TIPC_NLA_SOCK_MAX - 1 -@@ -161,6 +170,8 @@ enum { - TIPC_NLA_NET_UNSPEC, - TIPC_NLA_NET_ID, /* u32 */ - TIPC_NLA_NET_ADDR, /* u32 */ -+ TIPC_NLA_NET_NODEID, /* u64 */ -+ TIPC_NLA_NET_NODEID_W1, /* u64 */ - - __TIPC_NLA_NET_MAX, - TIPC_NLA_NET_MAX = __TIPC_NLA_NET_MAX - 1 -@@ -223,6 +234,19 @@ enum { - TIPC_NLA_MON_PEER_MAX = __TIPC_NLA_MON_PEER_MAX - 1 - }; - -+/* Nest, socket group info */ -+enum { -+ TIPC_NLA_SOCK_GROUP_ID, /* u32 */ -+ TIPC_NLA_SOCK_GROUP_OPEN, /* flag */ -+ TIPC_NLA_SOCK_GROUP_NODE_SCOPE, /* flag */ -+ TIPC_NLA_SOCK_GROUP_CLUSTER_SCOPE, /* flag */ -+ TIPC_NLA_SOCK_GROUP_INSTANCE, /* u32 */ -+ TIPC_NLA_SOCK_GROUP_BC_SEND_NEXT, /* u32 */ -+ -+ __TIPC_NLA_SOCK_GROUP_MAX, -+ TIPC_NLA_SOCK_GROUP_MAX = __TIPC_NLA_SOCK_GROUP_MAX - 1 -+}; -+ - /* Nest, connection info */ - enum { - TIPC_NLA_CON_UNSPEC, -@@ -237,6 +261,18 @@ enum { - TIPC_NLA_CON_MAX = __TIPC_NLA_CON_MAX - 1 - }; - -+/* Nest, socket statistics info */ -+enum { -+ TIPC_NLA_SOCK_STAT_RCVQ, /* u32 */ -+ TIPC_NLA_SOCK_STAT_SENDQ, /* u32 */ -+ TIPC_NLA_SOCK_STAT_LINK_CONG, /* flag */ -+ TIPC_NLA_SOCK_STAT_CONN_CONG, /* flag */ -+ TIPC_NLA_SOCK_STAT_DROP, /* u32 */ -+ -+ __TIPC_NLA_SOCK_STAT_MAX, -+ TIPC_NLA_SOCK_STAT_MAX = __TIPC_NLA_SOCK_STAT_MAX - 1 -+}; -+ - /* Nest, link propreties. Valid for link, media and bearer */ - enum { - TIPC_NLA_PROP_UNSPEC, -@@ -244,6 +280,7 @@ enum { - TIPC_NLA_PROP_PRIO, /* u32 */ - TIPC_NLA_PROP_TOL, /* u32 */ - TIPC_NLA_PROP_WIN, /* u32 */ -+ TIPC_NLA_PROP_MTU, /* u32 */ - - __TIPC_NLA_PROP_MAX, - TIPC_NLA_PROP_MAX = __TIPC_NLA_PROP_MAX - 1 -diff --git a/include/uapi/linux/tipc_sockets_diag.h b/include/uapi/linux/tipc_sockets_diag.h -new file mode 100644 -index 0000000000000..21b766ec7e202 ---- /dev/null -+++ b/include/uapi/linux/tipc_sockets_diag.h -@@ -0,0 +1,17 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+/* AF_TIPC sock_diag interface for querying open sockets */ -+ -+#ifndef __TIPC_SOCKETS_DIAG_H__ -+#define __TIPC_SOCKETS_DIAG_H__ -+ -+#include -+#include -+ -+/* Request */ -+struct tipc_sock_diag_req { -+ __u8 sdiag_family; /* must be AF_TIPC */ -+ __u8 sdiag_protocol; /* must be 0 */ -+ __u16 pad; /* must be 0 */ -+ __u32 tidiag_states; /* query*/ -+}; -+#endif /* __TIPC_SOCKETS_DIAG_H__ */ -diff --git a/include/uapi/linux/types.h b/include/uapi/linux/types.h -index c640657a7da33..999cb0fa88ebd 100644 ---- a/include/uapi/linux/types.h -+++ b/include/uapi/linux/types.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _LINUX_TYPES_H - #define _LINUX_TYPES_H - -@@ -43,5 +44,7 @@ typedef __u32 __bitwise __wsum; - #define __aligned_be64 __be64 __attribute__((aligned(8))) - #define __aligned_le64 __le64 __attribute__((aligned(8))) - -+typedef unsigned __bitwise __poll_t; -+ - #endif /* __ASSEMBLY__ */ - #endif /* _LINUX_TYPES_H */ -diff --git a/include/uapi/linux/unix_diag.h b/include/uapi/linux/unix_diag.h -index 1eb0b8dd18308..5c502fdf7a42c 100644 ---- a/include/uapi/linux/unix_diag.h -+++ b/include/uapi/linux/unix_diag.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __UNIX_DIAG_H__ - #define __UNIX_DIAG_H__ - -diff --git a/include/uapi/linux/veth.h b/include/uapi/linux/veth.h -index 3354c1eb424e6..52b58e587e236 100644 ---- a/include/uapi/linux/veth.h -+++ b/include/uapi/linux/veth.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __NET_VETH_H_ - #define __NET_VETH_H_ - -diff --git a/include/uapi/linux/vm_sockets_diag.h b/include/uapi/linux/vm_sockets_diag.h -index a732a6f591b97..6da42f99a425b 100644 ---- a/include/uapi/linux/vm_sockets_diag.h -+++ b/include/uapi/linux/vm_sockets_diag.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - /* AF_VSOCK sock_diag(7) interface for querying open sockets */ - - #ifndef __VM_SOCKETS_DIAG_H__ -diff --git a/include/uapi/linux/xfrm.h b/include/uapi/linux/xfrm.h -index 5790293b7fc46..93fb1920101a2 100644 ---- a/include/uapi/linux/xfrm.h -+++ b/include/uapi/linux/xfrm.h -@@ -1,3 +1,4 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef _LINUX_XFRM_H - #define _LINUX_XFRM_H - --- -2.21.0 - diff --git a/SOURCES/0048-tc-flower-Add-match-on-encapsulating-tos-ttl.patch b/SOURCES/0048-tc-flower-Add-match-on-encapsulating-tos-ttl.patch deleted file mode 100644 index 89cadb5..0000000 --- a/SOURCES/0048-tc-flower-Add-match-on-encapsulating-tos-ttl.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 738c49477eb843b37cb799115e5b562303bfcd9e Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Wed, 6 Feb 2019 14:51:12 +0100 -Subject: [PATCH] tc/flower: Add match on encapsulating tos/ttl - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1641909 -Upstream Status: iproute2.git commit 761ec9e29ff86 -Conflicts: Adjusted code to missing commit e28b88a464c49 - ("tc: jsonify flower filter"). - -commit 761ec9e29ff867452057f59dc6ca430688b409ea -Author: Or Gerlitz -Date: Thu Jul 19 14:02:15 2018 +0300 - - tc/flower: Add match on encapsulating tos/ttl - - Add matching on tos/ttl of the IP tunnel headers. - - For example, here's decap rule that matches on the tunnel tos: - - tc filter add dev vxlan_sys_4789 protocol ip parent ffff: prio 10 flower \ - enc_src_ip 192.168.10.2 enc_dst_ip 192.168.10.1 enc_key_id 100 enc_dst_port 4789 enc_tos 0x30 \ - src_mac e4:11:22:33:44:70 dst_mac e4:11:22:33:44:50 \ - action tunnel_key unset \ - action mirred egress redirect dev eth0_0 - - Signed-off-by: Or Gerlitz - Reviewed-by: Roi Dayan - Acked-by: Jiri Pirko - Signed-off-by: David Ahern ---- - man/man8/tc-flower.8 | 14 +++++++++++++- - tc/f_flower.c | 27 +++++++++++++++++++++++++++ - 2 files changed, 40 insertions(+), 1 deletion(-) - -diff --git a/man/man8/tc-flower.8 b/man/man8/tc-flower.8 -index be46f0278b4ff..af19708d9649e 100644 ---- a/man/man8/tc-flower.8 -+++ b/man/man8/tc-flower.8 -@@ -57,6 +57,10 @@ flower \- flow based traffic control filter - .IR ipv4_address " | " ipv6_address " } | " - .B enc_dst_port - .IR port_number " | " -+.B enc_tos -+.IR TOS " | " -+.B enc_ttl -+.IR TTL " | " - .BR ip_flags - .IR IP_FLAGS - .SH DESCRIPTION -@@ -207,6 +211,10 @@ bits is assumed. - .BI enc_src_ip " PREFIX" - .TQ - .BI enc_dst_port " NUMBER" -+.TQ -+.BI enc_tos " NUMBER" -+.TQ -+.BI enc_ttl " NUMBER" - Match on IP tunnel metadata. Key id - .I NUMBER - is a 32 bit tunnel key id (e.g. VNI for VXLAN tunnel). -@@ -215,7 +223,11 @@ must be a valid IPv4 or IPv6 address optionally followed by a slash and the - prefix length. If the prefix is missing, \fBtc\fR assumes a full-length - host match. Dst port - .I NUMBER --is a 16 bit UDP dst port. -+is a 16 bit UDP dst port. Tos -+.I NUMBER -+is an 8 bit tos (dscp+ecn) value, ttl -+.I NUMBER -+is an 8 bit time-to-live value. - .TP - .BI ip_flags " IP_FLAGS" - .I IP_FLAGS -diff --git a/tc/f_flower.c b/tc/f_flower.c -index 5be693ab7f6af..5f5236ca523f8 100644 ---- a/tc/f_flower.c -+++ b/tc/f_flower.c -@@ -70,6 +70,8 @@ static void explain(void) - " enc_dst_ip [ IPV4-ADDR | IPV6-ADDR ] |\n" - " enc_src_ip [ IPV4-ADDR | IPV6-ADDR ] |\n" - " enc_key_id [ KEY-ID ] |\n" -+ " enc_tos MASKED-IP_TOS |\n" -+ " enc_ttl MASKED-IP_TTL |\n" - " ip_flags IP-FLAGS | \n" - " enc_dst_port [ port_number ] }\n" - " FILTERID := X:Y:Z\n" -@@ -883,6 +885,26 @@ static int flower_parse_opt(struct filter_util *qu, char *handle, - fprintf(stderr, "Illegal \"enc_dst_port\"\n"); - return -1; - } -+ } else if (matches(*argv, "enc_tos") == 0) { -+ NEXT_ARG(); -+ ret = flower_parse_ip_tos_ttl(*argv, -+ TCA_FLOWER_KEY_ENC_IP_TOS, -+ TCA_FLOWER_KEY_ENC_IP_TOS_MASK, -+ n); -+ if (ret < 0) { -+ fprintf(stderr, "Illegal \"enc_tos\"\n"); -+ return -1; -+ } -+ } else if (matches(*argv, "enc_ttl") == 0) { -+ NEXT_ARG(); -+ ret = flower_parse_ip_tos_ttl(*argv, -+ TCA_FLOWER_KEY_ENC_IP_TTL, -+ TCA_FLOWER_KEY_ENC_IP_TTL_MASK, -+ n); -+ if (ret < 0) { -+ fprintf(stderr, "Illegal \"enc_ttl\"\n"); -+ return -1; -+ } - } else if (matches(*argv, "action") == 0) { - NEXT_ARG(); - ret = parse_action(&argc, &argv, TCA_FLOWER_ACT, n); -@@ -1296,6 +1318,11 @@ static int flower_print_opt(struct filter_util *qu, FILE *f, - flower_print_port(f, "enc_dst_port", - tb[TCA_FLOWER_KEY_ENC_UDP_DST_PORT]); - -+ flower_print_ip_attr(f, "enc_tos", tb[TCA_FLOWER_KEY_ENC_IP_TOS], -+ tb[TCA_FLOWER_KEY_ENC_IP_TOS_MASK]); -+ flower_print_ip_attr(f, "enc_ttl", tb[TCA_FLOWER_KEY_ENC_IP_TTL], -+ tb[TCA_FLOWER_KEY_ENC_IP_TTL_MASK]); -+ - flower_print_matching_flags(f, "ip_flags", - FLOWER_IP_FLAGS, - tb[TCA_FLOWER_KEY_FLAGS], --- -2.21.0 - diff --git a/SOURCES/0049-tc-act_tunnel_key-Enable-setup-of-tos-and-ttl.patch b/SOURCES/0049-tc-act_tunnel_key-Enable-setup-of-tos-and-ttl.patch deleted file mode 100644 index 536ccac..0000000 --- a/SOURCES/0049-tc-act_tunnel_key-Enable-setup-of-tos-and-ttl.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 7521695ca299ceb723dc6b17f304b91300b3b16c Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Wed, 6 Feb 2019 14:51:57 +0100 -Subject: [PATCH] tc/act_tunnel_key: Enable setup of tos and ttl - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1641909 -Upstream Status: iproute2.git commit 9f89b0cc0eda2 -Conflicts: -* Context change due to missing commits - 59eb271d1d259 ("tc: m_tunnel_key: add csum/nocsum option") and - 6217917a38268 ("tc: m_tunnel_key: Add tunnel option support to act_tunnel_key"). -* Adjusted tunnel_key_print_tos_ttl() to missing commit 8feb516bfcdd9 - ("tc: jsonify tunnel_key action"). - -commit 9f89b0cc0eda2ef52d8850b0610f3e2e09fd7c1c -Author: Or Gerlitz -Date: Thu Jul 19 14:02:14 2018 +0300 - - tc/act_tunnel_key: Enable setup of tos and ttl - - Allow to set tos and ttl for the tunnel. - - For example, here's encap rule that sets tos to the tunnel: - - tc filter add dev eth0_0 protocol ip parent ffff: prio 10 flower \ - src_mac e4:11:22:33:44:50 dst_mac e4:11:22:33:44:70 \ - action tunnel_key set src_ip 192.168.10.1 dst_ip 192.168.10.2 id 100 dst_port 4789 tos 0x30 \ - action mirred egress redirect dev vxlan_sys_4789 - - Signed-off-by: Or Gerlitz - Reviewed-by: Roi Dayan - Acked-by: Jiri Pirko - Signed-off-by: David Ahern ---- - man/man8/tc-tunnel_key.8 | 8 +++++++ - tc/m_tunnel_key.c | 49 ++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 57 insertions(+) - -diff --git a/man/man8/tc-tunnel_key.8 b/man/man8/tc-tunnel_key.8 -index 52fa585a75c8f..5e93c59d49465 100644 ---- a/man/man8/tc-tunnel_key.8 -+++ b/man/man8/tc-tunnel_key.8 -@@ -16,6 +16,8 @@ tunnel_key - Tunnel metadata manipulation - .IR ADDRESS - .BI id " KEY_ID" - .BI dst_port " UDP_PORT" -+.BI tos " TOS" -+.BI ttl " TTL" - - .SH DESCRIPTION - The -@@ -77,6 +79,12 @@ Outer header destination IP address (IPv4 or IPv6) - .TP - .B dst_port - Outer header destination UDP port -+.TP -+.B tos -+Outer header TOS -+.TP -+.B ttl -+Outer header TTL - .RE - .SH EXAMPLES - The following example encapsulates incoming ICMP packets on eth0 into a vxlan -diff --git a/tc/m_tunnel_key.c b/tc/m_tunnel_key.c -index acbcfc15cda76..60fd1c464e531 100644 ---- a/tc/m_tunnel_key.c -+++ b/tc/m_tunnel_key.c -@@ -80,6 +80,22 @@ static int tunnel_key_parse_dst_port(char *str, int type, struct nlmsghdr *n) - return 0; - } - -+static int tunnel_key_parse_tos_ttl(char *str, int type, struct nlmsghdr *n) -+{ -+ int ret; -+ __u8 val; -+ -+ ret = get_u8(&val, str, 10); -+ if (ret) -+ ret = get_u8(&val, str, 16); -+ if (ret) -+ return -1; -+ -+ addattr8(n, MAX_MSG, type, val); -+ -+ return 0; -+} -+ - static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p, - int tca_id, struct nlmsghdr *n) - { -@@ -154,6 +170,22 @@ static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p, - fprintf(stderr, "Illegal \"dst port\"\n"); - return -1; - } -+ } else if (matches(*argv, "tos") == 0) { -+ NEXT_ARG(); -+ ret = tunnel_key_parse_tos_ttl(*argv, -+ TCA_TUNNEL_KEY_ENC_TOS, n); -+ if (ret < 0) { -+ fprintf(stderr, "Illegal \"tos\"\n"); -+ return -1; -+ } -+ } else if (matches(*argv, "ttl") == 0) { -+ NEXT_ARG(); -+ ret = tunnel_key_parse_tos_ttl(*argv, -+ TCA_TUNNEL_KEY_ENC_TTL, n); -+ if (ret < 0) { -+ fprintf(stderr, "Illegal \"ttl\"\n"); -+ return -1; -+ } - } else if (matches(*argv, "help") == 0) { - usage(); - } else { -@@ -231,6 +263,19 @@ static void tunnel_key_print_dst_port(FILE *f, char *name, - fprintf(f, "\n\t%s %d", name, rta_getattr_be16(attr)); - } - -+static void tunnel_key_print_tos_ttl(FILE *f, char *name, -+ struct rtattr *attr) -+{ -+ if (!attr) -+ return; -+ -+ if (matches(name, "tos") == 0 && rta_getattr_u8(attr) != 0) { -+ fprintf(f, "\n\t%s 0x%x", name, rta_getattr_u8(attr)); -+ } else if (matches(name, "ttl") == 0 && rta_getattr_u8(attr) != 0) { -+ fprintf(f, "\n\t%s %u", name, rta_getattr_u8(attr)); -+ } -+} -+ - static int print_tunnel_key(struct action_util *au, FILE *f, struct rtattr *arg) - { - struct rtattr *tb[TCA_TUNNEL_KEY_MAX + 1]; -@@ -267,6 +312,10 @@ static int print_tunnel_key(struct action_util *au, FILE *f, struct rtattr *arg) - tb[TCA_TUNNEL_KEY_ENC_KEY_ID]); - tunnel_key_print_dst_port(f, "dst_port", - tb[TCA_TUNNEL_KEY_ENC_DST_PORT]); -+ tunnel_key_print_tos_ttl(f, "tos", -+ tb[TCA_TUNNEL_KEY_ENC_TOS]); -+ tunnel_key_print_tos_ttl(f, "ttl", -+ tb[TCA_TUNNEL_KEY_ENC_TTL]); - break; - } - fprintf(f, " %s", action_n2a(parm->action)); --- -2.21.0 - diff --git a/SOURCES/0050-iproute-Abort-if-nexthop-cannot-be-parsed.patch b/SOURCES/0050-iproute-Abort-if-nexthop-cannot-be-parsed.patch deleted file mode 100644 index 309a53f..0000000 --- a/SOURCES/0050-iproute-Abort-if-nexthop-cannot-be-parsed.patch +++ /dev/null @@ -1,52 +0,0 @@ -From d80837df37cb8897769f87f7a2034a9653168221 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 21 Feb 2019 14:38:57 +0100 -Subject: [PATCH] iproute: Abort if nexthop cannot be parsed - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1624656 -Upstream Status: iproute2.git commit ee53b42fd8b0b - -commit ee53b42fd8b0b0cdb857d0f5bf7467e22a3457d9 -Author: Jakub Sitnicki -Date: Wed Apr 11 11:43:11 2018 +0200 - - iproute: Abort if nexthop cannot be parsed - - Attempt to add a multipath route where a nexthop definition refers to a - non-existent device causes 'ip' to crash and burn due to stack buffer - overflow: - - # ip -6 route add fd00::1/64 nexthop dev fake1 - Cannot find device "fake1" - Cannot find device "fake1" - Cannot find device "fake1" - ... - Segmentation fault (core dumped) - - Don't ignore errors from the helper routine that parses the nexthop - definition, and abort immediately if parsing fails. - - Signed-off-by: Jakub Sitnicki ---- - ip/iproute.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/ip/iproute.c b/ip/iproute.c -index 35fdce8a64f35..759032db454ad 100644 ---- a/ip/iproute.c -+++ b/ip/iproute.c -@@ -817,7 +817,10 @@ static int parse_nexthops(struct nlmsghdr *n, struct rtmsg *r, - memset(rtnh, 0, sizeof(*rtnh)); - rtnh->rtnh_len = sizeof(*rtnh); - rta->rta_len += rtnh->rtnh_len; -- parse_one_nh(n, r, rta, rtnh, &argc, &argv); -+ if (parse_one_nh(n, r, rta, rtnh, &argc, &argv)) { -+ fprintf(stderr, "Error: cannot parse nexthop\n"); -+ exit(-1); -+ } - rtnh = RTNH_NEXT(rtnh); - } - --- -2.21.0 - diff --git a/SOURCES/0051-ip-route-Fix-segfault-with-many-nexthops.patch b/SOURCES/0051-ip-route-Fix-segfault-with-many-nexthops.patch deleted file mode 100644 index 7622ced..0000000 --- a/SOURCES/0051-ip-route-Fix-segfault-with-many-nexthops.patch +++ /dev/null @@ -1,388 +0,0 @@ -From 5845a145808162560293cf4f7c55bbb5afc8dce7 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 21 Feb 2019 14:38:57 +0100 -Subject: [PATCH] ip-route: Fix segfault with many nexthops - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1624656 -Upstream Status: iproute2.git commit bd59e5b1517b0 -Conflicts: Context changes due to missing other commits. - -commit bd59e5b1517b09b6f26d59f38fe6077d953c2396 -Author: Phil Sutter -Date: Thu Sep 6 15:31:51 2018 +0200 - - ip-route: Fix segfault with many nexthops - - It was possible to crash ip-route by adding an IPv6 route with 37 - nexthop statements. A simple reproducer is: - - | for i in `seq 37`; do - | nhs="nexthop via 1111::$i "$nhs - | done - | ip -6 route add 3333::/64 $nhs - - The related code was broken in multiple ways: - - * parse_one_nh() assumed that rta points to 4kB of storage but caller - provided just 1kB. Fixed by passing 'len' parameter with the correct - value. - - * Error checking of rta_addattr*() calls in parse_one_nh() and called - functions was completely absent, so with above fix in place output - flood would occur due to parser looping forever. - - While being at it, increase message buffer sizes to 4k. This allows for - at most 144 nexthops. - - Signed-off-by: Phil Sutter - Signed-off-by: Stephen Hemminger ---- - ip/iproute.c | 43 +++++++++++++++++------------ - ip/iproute_lwtunnel.c | 63 +++++++++++++++++++++++++++---------------- - 2 files changed, 66 insertions(+), 40 deletions(-) - -diff --git a/ip/iproute.c b/ip/iproute.c -index 759032db454ad..d4db035fc7b24 100644 ---- a/ip/iproute.c -+++ b/ip/iproute.c -@@ -721,7 +721,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) - } - - static int parse_one_nh(struct nlmsghdr *n, struct rtmsg *r, -- struct rtattr *rta, struct rtnexthop *rtnh, -+ struct rtattr *rta, size_t len, struct rtnexthop *rtnh, - int *argcp, char ***argvp) - { - int argc = *argcp; -@@ -742,11 +742,16 @@ static int parse_one_nh(struct nlmsghdr *n, struct rtmsg *r, - if (r->rtm_family == AF_UNSPEC) - r->rtm_family = addr.family; - if (addr.family == r->rtm_family) { -- rta_addattr_l(rta, 4096, RTA_GATEWAY, &addr.data, addr.bytelen); -- rtnh->rtnh_len += sizeof(struct rtattr) + addr.bytelen; -+ if (rta_addattr_l(rta, len, RTA_GATEWAY, -+ &addr.data, addr.bytelen)) -+ return -1; -+ rtnh->rtnh_len += sizeof(struct rtattr) -+ + addr.bytelen; - } else { -- rta_addattr_l(rta, 4096, RTA_VIA, &addr.family, addr.bytelen+2); -- rtnh->rtnh_len += RTA_SPACE(addr.bytelen+2); -+ if (rta_addattr_l(rta, len, RTA_VIA, -+ &addr.family, addr.bytelen + 2)) -+ return -1; -+ rtnh->rtnh_len += RTA_SPACE(addr.bytelen + 2); - } - } else if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); -@@ -769,13 +774,15 @@ static int parse_one_nh(struct nlmsghdr *n, struct rtmsg *r, - NEXT_ARG(); - if (get_rt_realms_or_raw(&realm, *argv)) - invarg("\"realm\" value is invalid\n", *argv); -- rta_addattr32(rta, 4096, RTA_FLOW, realm); -+ if (rta_addattr32(rta, len, RTA_FLOW, realm)) -+ return -1; - rtnh->rtnh_len += sizeof(struct rtattr) + 4; - } else if (strcmp(*argv, "encap") == 0) { -- int len = rta->rta_len; -+ int old_len = rta->rta_len; - -- lwt_parse_encap(rta, 4096, &argc, &argv); -- rtnh->rtnh_len += rta->rta_len - len; -+ if (lwt_parse_encap(rta, len, &argc, &argv)) -+ return -1; -+ rtnh->rtnh_len += rta->rta_len - old_len; - } else if (strcmp(*argv, "as") == 0) { - inet_prefix addr; - -@@ -783,8 +790,9 @@ static int parse_one_nh(struct nlmsghdr *n, struct rtmsg *r, - if (strcmp(*argv, "to") == 0) - NEXT_ARG(); - get_addr(&addr, *argv, r->rtm_family); -- rta_addattr_l(rta, 4096, RTA_NEWDST, &addr.data, -- addr.bytelen); -+ if (rta_addattr_l(rta, len, RTA_NEWDST, -+ &addr.data, addr.bytelen)) -+ return -1; - rtnh->rtnh_len += sizeof(struct rtattr) + addr.bytelen; - } else - break; -@@ -797,7 +805,7 @@ static int parse_one_nh(struct nlmsghdr *n, struct rtmsg *r, - static int parse_nexthops(struct nlmsghdr *n, struct rtmsg *r, - int argc, char **argv) - { -- char buf[1024]; -+ char buf[4096]; - struct rtattr *rta = (void *)buf; - struct rtnexthop *rtnh; - -@@ -817,7 +825,7 @@ static int parse_nexthops(struct nlmsghdr *n, struct rtmsg *r, - memset(rtnh, 0, sizeof(*rtnh)); - rtnh->rtnh_len = sizeof(*rtnh); - rta->rta_len += rtnh->rtnh_len; -- if (parse_one_nh(n, r, rta, rtnh, &argc, &argv)) { -+ if (parse_one_nh(n, r, rta, 4096, rtnh, &argc, &argv)) { - fprintf(stderr, "Error: cannot parse nexthop\n"); - exit(-1); - } -@@ -825,7 +833,8 @@ static int parse_nexthops(struct nlmsghdr *n, struct rtmsg *r, - } - - if (rta->rta_len > RTA_LENGTH(0)) -- addattr_l(n, 1024, RTA_MULTIPATH, RTA_DATA(rta), RTA_PAYLOAD(rta)); -+ return addattr_l(n, 4096, RTA_MULTIPATH, -+ RTA_DATA(rta), RTA_PAYLOAD(rta)); - return 0; - } - -@@ -834,7 +843,7 @@ static int iproute_modify(int cmd, unsigned int flags, int argc, char **argv) - struct { - struct nlmsghdr n; - struct rtmsg r; -- char buf[1024]; -+ char buf[4096]; - } req = { - .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)), - .n.nlmsg_flags = NLM_F_REQUEST | flags, -@@ -1238,8 +1247,8 @@ static int iproute_modify(int cmd, unsigned int flags, int argc, char **argv) - addattr_l(&req.n, sizeof(req), RTA_METRICS, RTA_DATA(mxrta), RTA_PAYLOAD(mxrta)); - } - -- if (nhs_ok) -- parse_nexthops(&req.n, &req.r, argc, argv); -+ if (nhs_ok && parse_nexthops(&req.n, &req.r, argc, argv)) -+ return -1; - - if (req.r.rtm_family == AF_UNSPEC) - req.r.rtm_family = AF_INET; -diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c -index 0fa1cab0a790f..1a6891267d2e1 100644 ---- a/ip/iproute_lwtunnel.c -+++ b/ip/iproute_lwtunnel.c -@@ -255,8 +255,9 @@ static int parse_encap_mpls(struct rtattr *rta, size_t len, - exit(1); - } - -- rta_addattr_l(rta, len, MPLS_IPTUNNEL_DST, &addr.data, -- addr.bytelen); -+ if (rta_addattr_l(rta, len, MPLS_IPTUNNEL_DST, -+ &addr.data, addr.bytelen)) -+ return -1; - - *argcp = argc; - *argvp = argv; -@@ -270,6 +271,7 @@ static int parse_encap_ip(struct rtattr *rta, size_t len, - int id_ok = 0, dst_ok = 0, tos_ok = 0, ttl_ok = 0; - char **argv = *argvp; - int argc = *argcp; -+ int ret = 0; - - while (argc > 0) { - if (strcmp(*argv, "id") == 0) { -@@ -280,7 +282,7 @@ static int parse_encap_ip(struct rtattr *rta, size_t len, - duparg2("id", *argv); - if (get_be64(&id, *argv, 0)) - invarg("\"id\" value is invalid\n", *argv); -- rta_addattr64(rta, len, LWTUNNEL_IP_ID, id); -+ ret = rta_addattr64(rta, len, LWTUNNEL_IP_ID, id); - } else if (strcmp(*argv, "dst") == 0) { - inet_prefix addr; - -@@ -288,8 +290,8 @@ static int parse_encap_ip(struct rtattr *rta, size_t len, - if (dst_ok++) - duparg2("dst", *argv); - get_addr(&addr, *argv, AF_INET); -- rta_addattr_l(rta, len, LWTUNNEL_IP_DST, -- &addr.data, addr.bytelen); -+ ret = rta_addattr_l(rta, len, LWTUNNEL_IP_DST, -+ &addr.data, addr.bytelen); - } else if (strcmp(*argv, "tos") == 0) { - __u32 tos; - -@@ -298,7 +300,7 @@ static int parse_encap_ip(struct rtattr *rta, size_t len, - duparg2("tos", *argv); - if (rtnl_dsfield_a2n(&tos, *argv)) - invarg("\"tos\" value is invalid\n", *argv); -- rta_addattr8(rta, len, LWTUNNEL_IP_TOS, tos); -+ ret = rta_addattr8(rta, len, LWTUNNEL_IP_TOS, tos); - } else if (strcmp(*argv, "ttl") == 0) { - __u8 ttl; - -@@ -307,10 +309,12 @@ static int parse_encap_ip(struct rtattr *rta, size_t len, - duparg2("ttl", *argv); - if (get_u8(&ttl, *argv, 0)) - invarg("\"ttl\" value is invalid\n", *argv); -- rta_addattr8(rta, len, LWTUNNEL_IP_TTL, ttl); -+ ret = rta_addattr8(rta, len, LWTUNNEL_IP_TTL, ttl); - } else { - break; - } -+ if (ret) -+ break; - argc--; argv++; - } - -@@ -321,7 +325,7 @@ static int parse_encap_ip(struct rtattr *rta, size_t len, - *argcp = argc + 1; - *argvp = argv - 1; - -- return 0; -+ return ret; - } - - static int parse_encap_ila(struct rtattr *rta, size_t len, -@@ -330,6 +334,7 @@ static int parse_encap_ila(struct rtattr *rta, size_t len, - __u64 locator; - int argc = *argcp; - char **argv = *argvp; -+ int ret = 0; - - if (get_addr64(&locator, *argv) < 0) { - fprintf(stderr, "Bad locator: %s\n", *argv); -@@ -338,7 +343,8 @@ static int parse_encap_ila(struct rtattr *rta, size_t len, - - argc--; argv++; - -- rta_addattr64(rta, 1024, ILA_ATTR_LOCATOR, locator); -+ if (rta_addattr64(rta, 1024, ILA_ATTR_LOCATOR, locator)) -+ return -1; - - while (argc > 0) { - if (strcmp(*argv, "csum-mode") == 0) { -@@ -351,12 +357,15 @@ static int parse_encap_ila(struct rtattr *rta, size_t len, - invarg("\"csum-mode\" value is invalid\n", - *argv); - -- rta_addattr8(rta, 1024, ILA_ATTR_CSUM_MODE, csum_mode); -+ ret = rta_addattr8(rta, 1024, ILA_ATTR_CSUM_MODE, -+ (__u8)csum_mode); - - argc--; argv++; - } else { - break; - } -+ if (ret) -+ break; - } - - /* argv is currently the first unparsed argument, -@@ -366,7 +375,7 @@ static int parse_encap_ila(struct rtattr *rta, size_t len, - *argcp = argc + 1; - *argvp = argv - 1; - -- return 0; -+ return ret; - } - - static int parse_encap_ip6(struct rtattr *rta, size_t len, -@@ -375,6 +384,7 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len, - int id_ok = 0, dst_ok = 0, tos_ok = 0, ttl_ok = 0; - char **argv = *argvp; - int argc = *argcp; -+ int ret = 0; - - while (argc > 0) { - if (strcmp(*argv, "id") == 0) { -@@ -385,7 +395,7 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len, - duparg2("id", *argv); - if (get_be64(&id, *argv, 0)) - invarg("\"id\" value is invalid\n", *argv); -- rta_addattr64(rta, len, LWTUNNEL_IP6_ID, id); -+ ret = rta_addattr64(rta, len, LWTUNNEL_IP6_ID, id); - } else if (strcmp(*argv, "dst") == 0) { - inet_prefix addr; - -@@ -393,8 +403,8 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len, - if (dst_ok++) - duparg2("dst", *argv); - get_addr(&addr, *argv, AF_INET6); -- rta_addattr_l(rta, len, LWTUNNEL_IP6_DST, -- &addr.data, addr.bytelen); -+ ret = rta_addattr_l(rta, len, LWTUNNEL_IP6_DST, -+ &addr.data, addr.bytelen); - } else if (strcmp(*argv, "tc") == 0) { - __u32 tc; - -@@ -403,7 +413,7 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len, - duparg2("tc", *argv); - if (rtnl_dsfield_a2n(&tc, *argv)) - invarg("\"tc\" value is invalid\n", *argv); -- rta_addattr8(rta, len, LWTUNNEL_IP6_TC, tc); -+ ret = rta_addattr8(rta, len, LWTUNNEL_IP6_TC, tc); - } else if (strcmp(*argv, "hoplimit") == 0) { - __u8 hoplimit; - -@@ -413,10 +423,13 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len, - if (get_u8(&hoplimit, *argv, 0)) - invarg("\"hoplimit\" value is invalid\n", - *argv); -- rta_addattr8(rta, len, LWTUNNEL_IP6_HOPLIMIT, hoplimit); -+ ret = rta_addattr8(rta, len, LWTUNNEL_IP6_HOPLIMIT, -+ hoplimit); - } else { - break; - } -+ if (ret) -+ break; - argc--; argv++; - } - -@@ -427,7 +440,7 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len, - *argcp = argc + 1; - *argvp = argv - 1; - -- return 0; -+ return ret; - } - - struct lwt_x { -@@ -542,6 +555,7 @@ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp) - int argc = *argcp; - char **argv = *argvp; - __u16 type; -+ int ret = 0; - - NEXT_ARG(); - type = read_encap_type(*argv); -@@ -558,16 +572,16 @@ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp) - nest = rta_nest(rta, 1024, RTA_ENCAP); - switch (type) { - case LWTUNNEL_ENCAP_MPLS: -- parse_encap_mpls(rta, len, &argc, &argv); -+ ret = parse_encap_mpls(rta, len, &argc, &argv); - break; - case LWTUNNEL_ENCAP_IP: -- parse_encap_ip(rta, len, &argc, &argv); -+ ret = parse_encap_ip(rta, len, &argc, &argv); - break; - case LWTUNNEL_ENCAP_ILA: -- parse_encap_ila(rta, len, &argc, &argv); -+ ret = parse_encap_ila(rta, len, &argc, &argv); - break; - case LWTUNNEL_ENCAP_IP6: -- parse_encap_ip6(rta, len, &argc, &argv); -+ ret = parse_encap_ip6(rta, len, &argc, &argv); - break; - case LWTUNNEL_ENCAP_BPF: - if (parse_encap_bpf(rta, len, &argc, &argv) < 0) -@@ -577,12 +591,15 @@ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp) - fprintf(stderr, "Error: unsupported encap type\n"); - break; - } -+ if (ret) -+ return ret; -+ - rta_nest_end(rta, nest); - -- rta_addattr16(rta, 1024, RTA_ENCAP_TYPE, type); -+ ret = rta_addattr16(rta, 1024, RTA_ENCAP_TYPE, type); - - *argcp = argc; - *argvp = argv; - -- return 0; -+ return ret; - } --- -2.21.0 - diff --git a/SOURCES/0052-man-ip-route.8-Document-nexthop-limit.patch b/SOURCES/0052-man-ip-route.8-Document-nexthop-limit.patch deleted file mode 100644 index ff69cfb..0000000 --- a/SOURCES/0052-man-ip-route.8-Document-nexthop-limit.patch +++ /dev/null @@ -1,46 +0,0 @@ -From d511d7e60866060e260ec3f96b51a61c98c2c06f Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 21 Feb 2019 14:39:46 +0100 -Subject: [PATCH] man: ip-route.8: Document nexthop limit - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1624656 -Upstream Status: iproute2.git commit 6cd959bb125c5 - -commit 6cd959bb125c50a04ab6671645fa38c5b07426f4 -Author: Phil Sutter -Date: Tue Nov 13 16:55:13 2018 +0100 - - man: ip-route.8: Document nexthop limit - - Add a note to 'nexthop' description stating the maximum number of - nexthops per command and pointing at 'append' command as a workaround. - - Signed-off-by: Phil Sutter - Signed-off-by: Stephen Hemminger ---- - man/man8/ip-route.8.in | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/man/man8/ip-route.8.in b/man/man8/ip-route.8.in -index d6e06649a4640..d9a547748c017 100644 ---- a/man/man8/ip-route.8.in -+++ b/man/man8/ip-route.8.in -@@ -548,6 +548,15 @@ argument lists: - route reflecting its relative bandwidth or quality. - .in -8 - -+The internal buffer used in iproute2 limits the maximum number of nexthops that -+may be specified in one go. If only -+.I ADDRESS -+is given, the current buffer size allows for 144 IPv6 nexthops and 253 IPv4 -+ones. For IPv4, this effectively limits the number of nexthops possible per -+route. With IPv6, further nexthops may be appended to the same route via -+.B "ip route append" -+command. -+ - .TP - .BI scope " SCOPE_VAL" - the scope of the destinations covered by the route prefix. --- -2.21.0 - diff --git a/SOURCES/0053-ip-route-Fix-nexthop-encap-parsing.patch b/SOURCES/0053-ip-route-Fix-nexthop-encap-parsing.patch deleted file mode 100644 index 79083e7..0000000 --- a/SOURCES/0053-ip-route-Fix-nexthop-encap-parsing.patch +++ /dev/null @@ -1,85 +0,0 @@ -From b83b0767eccfb386406ccb24130b975f1c2b0ee4 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 21 Feb 2019 14:39:47 +0100 -Subject: [PATCH] ip-route: Fix nexthop encap parsing - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1624656 -Upstream Status: iproute2.git commit 05d978e0850a6 -Conflicts: Some chunks dropped due to missing support for - ident-type and hook-type. - -commit 05d978e0850a6a3bae1e6c5392d82f7b1496f86a -Author: Phil Sutter -Date: Tue Nov 13 13:39:04 2018 +0100 - - ip-route: Fix nexthop encap parsing - - When parsing nexthop parameters, a buffer of 4k bytes is provided. Yet, - in lwt_parse_encap() and some functions called by it, buffer size was - assumed to be 1k despite the actual size was provided. This led to - spurious buffer size errors if the buffer was filled by previous nexthop - parameters to exceed that 1k boundary. - - Fixes: 1e5293056a02c ("lwtunnel: Add encapsulation support to ip route") - Fixes: 5866bddd9aa9e ("ila: Add support for ILA lwtunnels") - Fixes: ed67f83806538 ("ila: Support for checksum neutral translation") - Fixes: 86905c8f057c0 ("ila: support for configuring identifier and hook types") - Fixes: b15f440e78373 ("lwt: BPF support for LWT") - Signed-off-by: Phil Sutter - Signed-off-by: Stephen Hemminger ---- - ip/iproute_lwtunnel.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c -index 1a6891267d2e1..b6f08f073ef02 100644 ---- a/ip/iproute_lwtunnel.c -+++ b/ip/iproute_lwtunnel.c -@@ -343,7 +343,7 @@ static int parse_encap_ila(struct rtattr *rta, size_t len, - - argc--; argv++; - -- if (rta_addattr64(rta, 1024, ILA_ATTR_LOCATOR, locator)) -+ if (rta_addattr64(rta, len, ILA_ATTR_LOCATOR, locator)) - return -1; - - while (argc > 0) { -@@ -357,7 +357,7 @@ static int parse_encap_ila(struct rtattr *rta, size_t len, - invarg("\"csum-mode\" value is invalid\n", - *argv); - -- ret = rta_addattr8(rta, 1024, ILA_ATTR_CSUM_MODE, -+ ret = rta_addattr8(rta, len, ILA_ATTR_CSUM_MODE, - (__u8)csum_mode); - - argc--; argv++; -@@ -528,7 +528,7 @@ static int parse_encap_bpf(struct rtattr *rta, size_t len, int *argcp, - if (get_unsigned(&headroom, *argv, 0) || headroom == 0) - invarg("headroom is invalid\n", *argv); - if (!headroom_set) -- rta_addattr32(rta, 1024, LWT_BPF_XMIT_HEADROOM, -+ rta_addattr32(rta, len, LWT_BPF_XMIT_HEADROOM, - headroom); - headroom_set = 1; - } else if (strcmp(*argv, "help") == 0) { -@@ -569,7 +569,7 @@ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp) - exit(-1); - } - -- nest = rta_nest(rta, 1024, RTA_ENCAP); -+ nest = rta_nest(rta, len, RTA_ENCAP); - switch (type) { - case LWTUNNEL_ENCAP_MPLS: - ret = parse_encap_mpls(rta, len, &argc, &argv); -@@ -596,7 +596,7 @@ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp) - - rta_nest_end(rta, nest); - -- ret = rta_addattr16(rta, 1024, RTA_ENCAP_TYPE, type); -+ ret = rta_addattr16(rta, len, RTA_ENCAP_TYPE, type); - - *argcp = argc; - *argvp = argv; --- -2.21.0 - diff --git a/SOURCES/0054-ip-link-Fix-listing-of-alias-interfaces.patch b/SOURCES/0054-ip-link-Fix-listing-of-alias-interfaces.patch deleted file mode 100644 index 04599bf..0000000 --- a/SOURCES/0054-ip-link-Fix-listing-of-alias-interfaces.patch +++ /dev/null @@ -1,57 +0,0 @@ -From eb3be709aece2325f7eafc113120cf5ef8f077de Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Mon, 11 Mar 2019 16:28:41 +0100 -Subject: [PATCH] ip-link: Fix listing of alias interfaces - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1673226 -Upstream Status: RHEL-only -Conflicts: Context change due to missing commit 260137e24d3b7 - ("iplink: Remove flags argument from iplink_get") - -Upstream rejected this patch as the alias notation is neither required -nor wanted by iproute2[1]. With iproute rebase in RHEL7.5 though, we -changed existing behaviour by accident. Therefore we will carry this -patch for RHEL7 lifetime. - -[1] https://marc.info/?l=linux-netdev&m=154964861913609&w=2 - -commit a1259acb3c2037f464e31fad1f21556f8bf58c91 -Author: Phil Sutter -Date: Thu Feb 7 10:18:16 2019 +0100 - - ip-link: Fix listing of alias interfaces - - Commit 50b9950dd9011 ("link dump filter") accidentally broke listing of - links in the old alias interface notation: - - | % ip link show eth0:1 - | RTNETLINK answers: No such device - | Cannot send link get request: No such device - - Prior to the above commit, link lookup was performed via ifindex - returned by if_nametoindex(). The latter uses SIOCGIFINDEX ioctl call - which on kernel side causes the colon-suffix to be dropped before doing - the interface lookup. Netlink API though doesn't care about that at all. - To keep things backward compatible, mimick ioctl API behaviour and drop - the colon-suffix prior to sending the RTM_GETLINK request. - - Fixes: 50b9950dd9011 ("link dump filter") ---- - ip/ipaddress.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/ip/ipaddress.c b/ip/ipaddress.c -index 7492075687a9e..14e9e224dfa87 100644 ---- a/ip/ipaddress.c -+++ b/ip/ipaddress.c -@@ -1707,6 +1707,7 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action) - * the link device - */ - if (filter_dev && filter.group == -1 && do_link == 1) { -+ *strchrnul(filter_dev, ':') = '\0'; - if (iplink_get(0, filter_dev, RTEXT_FILTER_VF) < 0) { - perror("Cannot send link get request"); - exit(1); --- -2.21.0 - diff --git a/SOURCES/0055-ip-Add-violation-counters-to-VF-statisctics.patch b/SOURCES/0055-ip-Add-violation-counters-to-VF-statisctics.patch deleted file mode 100644 index f2f993d..0000000 --- a/SOURCES/0055-ip-Add-violation-counters-to-VF-statisctics.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 1e22b512374d25b547212bdbe1530ac8de1defdf Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 18 Mar 2019 11:23:40 +0100 -Subject: [PATCH] ip: Add violation counters to VF statisctics - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1471680 -Upstream Status: unknown commit 8c7acf3a -Conflicts: manually applied due to JSON support - -commit 8c7acf3a7ac265badc287f064614d60119a8072d -Author: Eran Ben Elisha -Date: Sun Jul 22 13:31:12 2018 +0300 - - ip: Add violation counters to VF statisctics - - Extend VFs statistics by receive and transmit violation counters. - - Example: "ip -s link show dev enp5s0f0" - - 6: enp5s0f0: mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000 - link/ether 24:8a:07:a5:28:f0 brd ff:ff:ff:ff:ff:ff - RX: bytes packets errors dropped overrun mcast - 0 0 0 0 0 2 - TX: bytes packets errors dropped carrier collsns - 1406 17 0 0 0 0 - vf 0 MAC 00:00:ca:fe:ca:fe, vlan 5, spoof checking off, link-state auto, trust off, query_rss off - RX: bytes packets mcast bcast dropped - 1666 29 14 32 0 - TX: bytes packets dropped - 2880 44 2412 - - Signed-off-by: Eran Ben Elisha - Signed-off-by: David Ahern ---- - ip/ipaddress.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/ip/ipaddress.c b/ip/ipaddress.c -index 14e9e224dfa87..44111a27501a9 100644 ---- a/ip/ipaddress.c -+++ b/ip/ipaddress.c -@@ -471,21 +471,31 @@ static void print_vf_stats64(FILE *fp, struct rtattr *vfstats) - - /* RX stats */ - fprintf(fp, "%s", _SL_); -- fprintf(fp, " RX: bytes packets mcast bcast %s", _SL_); -+ fprintf(fp, " RX: bytes packets mcast bcast "); -+ if (vf[IFLA_VF_STATS_RX_DROPPED]) -+ fprintf(fp, " dropped "); -+ fprintf(fp, "%s", _SL_); - fprintf(fp, " "); - - print_num(fp, 10, rta_getattr_u64(vf[IFLA_VF_STATS_RX_BYTES])); - print_num(fp, 8, rta_getattr_u64(vf[IFLA_VF_STATS_RX_PACKETS])); - print_num(fp, 7, rta_getattr_u64(vf[IFLA_VF_STATS_MULTICAST])); - print_num(fp, 7, rta_getattr_u64(vf[IFLA_VF_STATS_BROADCAST])); -+ if (vf[IFLA_VF_STATS_RX_DROPPED]) -+ print_num(fp, 8, rta_getattr_u64(vf[IFLA_VF_STATS_RX_DROPPED])); - - /* TX stats */ - fprintf(fp, "%s", _SL_); -- fprintf(fp, " TX: bytes packets %s", _SL_); -+ fprintf(fp, " TX: bytes packets "); -+ if (vf[IFLA_VF_STATS_TX_DROPPED]) -+ fprintf(fp, " dropped "); -+ fprintf(fp, "%s", _SL_); - fprintf(fp, " "); - - print_num(fp, 10, rta_getattr_u64(vf[IFLA_VF_STATS_TX_BYTES])); - print_num(fp, 8, rta_getattr_u64(vf[IFLA_VF_STATS_TX_PACKETS])); -+ if (vf[IFLA_VF_STATS_TX_DROPPED]) -+ print_num(fp, 8, rta_getattr_u64(vf[IFLA_VF_STATS_TX_DROPPED])); - } - - static void print_link_stats64(FILE *fp, const struct rtnl_link_stats64 *s, --- -2.21.0 - diff --git a/SOURCES/0056-devlink-Add-support-for-devlink-resource-abstraction.patch b/SOURCES/0056-devlink-Add-support-for-devlink-resource-abstraction.patch deleted file mode 100644 index ac2ef23..0000000 --- a/SOURCES/0056-devlink-Add-support-for-devlink-resource-abstraction.patch +++ /dev/null @@ -1,633 +0,0 @@ -From 5190aa430d198420679e53163604f7b6860bcd0f Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 25 Mar 2019 11:40:10 +0100 -Subject: [PATCH] devlink: Add support for devlink resource abstraction - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1644731 -Upstream Status: iproute2.git commit 8cd644095842a -Conflicts: adjusted help printout due to missing commit - 3e897912cbff9 ("devlink: add batch command support") - -commit 8cd644095842af3107320e86eeb01be6af6c77bb -Author: Arkadi Sharshevsky -Date: Wed Feb 14 10:55:18 2018 +0200 - - devlink: Add support for devlink resource abstraction - - Add support for devlink resource abstraction. The resources are - represented by a tree based structure and are identified by a name and - a size. Some resources can present their real time occupancy. - - First the resources exposed by the driver can be observed, for example: - - $devlink resource show pci/0000:03:00.0 - pci/0000:03:00.0: - name kvd size 245760 unit entry - resources: - name linear size 98304 occ 0 unit entry size_min 0 size_max 147456 size_gran 128 - name hash_double size 60416 unit entry size_min 32768 size_max 180224 size_gran 128 - name hash_single size 87040 unit entry size_min 65536 size_max 212992 size_gran 128 - - Some resource's size can be changed. Examples: - - $devlink resource set pci/0000:03:00.0 path /kvd/hash_single size 73088 - $devlink resource set pci/0000:03:00.0 path /kvd/hash_double size 74368 - - The changes do not apply immediately, this can be validate by the 'size_new' - attribute, which represents the pending changed size. For example - - $devlink resource show pci/0000:03:00.0 - pci/0000:03:00.0: - name kvd size 245760 unit entry size_valid false - resources: - name linear size 98304 size_new 147456 occ 0 unit entry size_min 0 size_max 147456 size_gran 128 - name hash_double size 60416 unit entry size_min 32768 size_max 180224 size_gran 128 - name hash_single size 87040 unit entry size_min 65536 size_max 212992 size_gran 128 - - In case of a pending change the nested resources present an indication - for a valid configuration of its children (sum of its children sizes - doesn't exceed the parent's size). - - In order for the changes to take place hot reload is needed. The hot - reload through devlink will be introduced in the following patch. - - Signed-off-by: Arkadi Sharshevsky - Acked-by: Jiri Pirko - Signed-off-by: Stephen Hemminger ---- - devlink/devlink.c | 490 +++++++++++++++++++++++++++++++++++++++++++++- - include/list.h | 5 + - 2 files changed, 494 insertions(+), 1 deletion(-) - -diff --git a/devlink/devlink.c b/devlink/devlink.c -index f9bc16c350c40..7f47b79450094 100644 ---- a/devlink/devlink.c -+++ b/devlink/devlink.c -@@ -177,6 +177,8 @@ static void ifname_map_free(struct ifname_map *ifname_map) - #define DL_OPT_DPIPE_TABLE_NAME BIT(13) - #define DL_OPT_DPIPE_TABLE_COUNTERS BIT(14) - #define DL_OPT_ESWITCH_ENCAP_MODE BIT(15) -+#define DL_OPT_RESOURCE_PATH BIT(16) -+#define DL_OPT_RESOURCE_SIZE BIT(17) - - struct dl_opts { - uint32_t present; /* flags of present items */ -@@ -197,6 +199,10 @@ struct dl_opts { - const char *dpipe_table_name; - bool dpipe_counters_enable; - bool eswitch_encap_mode; -+ const char *resource_path; -+ uint32_t resource_size; -+ uint32_t resource_id; -+ bool resource_id_valid; - }; - - struct dl { -@@ -937,6 +943,20 @@ static int dl_argv_parse(struct dl *dl, uint32_t o_required, - if (err) - return err; - o_found |= DL_OPT_ESWITCH_ENCAP_MODE; -+ } else if (dl_argv_match(dl, "path") && -+ (o_all & DL_OPT_RESOURCE_PATH)) { -+ dl_arg_inc(dl); -+ err = dl_argv_str(dl, &opts->resource_path); -+ if (err) -+ return err; -+ o_found |= DL_OPT_RESOURCE_PATH; -+ } else if (dl_argv_match(dl, "size") && -+ (o_all & DL_OPT_RESOURCE_SIZE)) { -+ dl_arg_inc(dl); -+ err = dl_argv_uint32_t(dl, &opts->resource_size); -+ if (err) -+ return err; -+ o_found |= DL_OPT_RESOURCE_SIZE; - } else { - pr_err("Unknown option \"%s\"\n", dl_argv(dl)); - return -EINVAL; -@@ -1079,6 +1099,12 @@ static void dl_opts_put(struct nlmsghdr *nlh, struct dl *dl) - if (opts->present & DL_OPT_ESWITCH_ENCAP_MODE) - mnl_attr_put_u8(nlh, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, - opts->eswitch_encap_mode); -+ if ((opts->present & DL_OPT_RESOURCE_PATH) && opts->resource_id_valid) -+ mnl_attr_put_u64(nlh, DEVLINK_ATTR_RESOURCE_ID, -+ opts->resource_id); -+ if (opts->present & DL_OPT_RESOURCE_SIZE) -+ mnl_attr_put_u64(nlh, DEVLINK_ATTR_RESOURCE_SIZE, -+ opts->resource_size); - } - - static int dl_argv_parse_put(struct nlmsghdr *nlh, struct dl *dl, -@@ -2666,6 +2692,91 @@ struct dpipe_header { - unsigned int fields_count; - }; - -+struct resource { -+ char *name; -+ uint64_t size; -+ uint64_t size_new; -+ uint64_t size_min; -+ uint64_t size_max; -+ uint64_t size_gran; -+ enum devlink_resource_unit unit; -+ bool size_valid; -+ uint64_t size_occ; -+ bool occ_valid; -+ uint64_t id; -+ struct list_head list; -+ struct list_head resource_list; -+ struct resource *parent; -+}; -+ -+struct resources { -+ struct list_head resource_list; -+}; -+ -+struct resource_ctx { -+ struct dl *dl; -+ int err; -+ struct resources *resources; -+ bool print_resources; -+ bool pending_change; -+}; -+ -+static struct resource *resource_alloc(void) -+{ -+ struct resource *resource; -+ -+ resource = calloc(1, sizeof(struct resource)); -+ if (!resource) -+ return NULL; -+ INIT_LIST_HEAD(&resource->resource_list); -+ return resource; -+} -+ -+static void resource_free(struct resource *resource) -+{ -+ struct resource *child_resource, *tmp; -+ -+ list_for_each_entry_safe(child_resource, tmp, &resource->resource_list, -+ list) { -+ free(child_resource->name); -+ resource_free(child_resource); -+ } -+ free(resource); -+} -+ -+static struct resources *resources_alloc(void) -+{ -+ struct resources *resources; -+ -+ resources = calloc(1, sizeof(struct resources)); -+ if (!resources) -+ return NULL; -+ INIT_LIST_HEAD(&resources->resource_list); -+ return resources; -+} -+ -+static void resources_free(struct resources *resources) -+{ -+ struct resource *resource, *tmp; -+ -+ list_for_each_entry_safe(resource, tmp, &resources->resource_list, list) -+ resource_free(resource); -+} -+ -+static int resource_ctx_init(struct resource_ctx *ctx, struct dl *dl) -+{ -+ ctx->resources = resources_alloc(); -+ if (!ctx->resources) -+ return -ENOMEM; -+ ctx->dl = dl; -+ return 0; -+} -+ -+static void resource_ctx_fini(struct resource_ctx *ctx) -+{ -+ resources_free(ctx->resources); -+} -+ - struct dpipe_ctx { - struct dl *dl; - int err; -@@ -3203,6 +3314,66 @@ err_match_show: - return -EINVAL; - } - -+static struct resource * -+resource_find(struct resources *resources, struct resource *resource, -+ uint64_t resource_id) -+{ -+ struct list_head *list_head; -+ -+ if (!resource) -+ list_head = &resources->resource_list; -+ else -+ list_head = &resource->resource_list; -+ -+ list_for_each_entry(resource, list_head, list) { -+ struct resource *child_resource; -+ -+ if (resource->id == resource_id) -+ return resource; -+ -+ child_resource = resource_find(resources, resource, -+ resource_id); -+ if (child_resource) -+ return child_resource; -+ } -+ return NULL; -+} -+ -+static void -+resource_path_print(struct dl *dl, struct resources *resources, -+ uint64_t resource_id) -+{ -+ struct resource *resource, *parent_resource; -+ const char del[] = "/"; -+ int path_len = 0; -+ char *path; -+ -+ resource = resource_find(resources, NULL, resource_id); -+ if (!resource) -+ return; -+ -+ for (parent_resource = resource; parent_resource; -+ parent_resource = parent_resource->parent) -+ path_len += strlen(parent_resource->name) + 1; -+ -+ path_len++; -+ path = calloc(1, path_len); -+ if (!path) -+ return; -+ -+ path += path_len - 1; -+ for (parent_resource = resource; parent_resource; -+ parent_resource = parent_resource->parent) { -+ path -= strlen(parent_resource->name); -+ memcpy(path, parent_resource->name, -+ strlen(parent_resource->name)); -+ path -= strlen(del); -+ memcpy(path, del, strlen(del)); -+ } -+ pr_out_str(dl, "resource_path", path); -+ free(path); -+} -+ - static int dpipe_table_show(struct dpipe_ctx *ctx, struct nlattr *nl) - { - struct nlattr *nla_table[DEVLINK_ATTR_MAX + 1] = {}; -@@ -3617,10 +3788,324 @@ static int cmd_dpipe(struct dl *dl) - return -ENOENT; - } - -+static int -+resource_parse(struct resource_ctx *ctx, struct resource *resource, -+ struct nlattr **nla_resource) -+{ -+ if (!nla_resource[DEVLINK_ATTR_RESOURCE_NAME] || -+ !nla_resource[DEVLINK_ATTR_RESOURCE_SIZE] || -+ !nla_resource[DEVLINK_ATTR_RESOURCE_ID] || -+ !nla_resource[DEVLINK_ATTR_RESOURCE_UNIT] || -+ !nla_resource[DEVLINK_ATTR_RESOURCE_SIZE_MIN] || -+ !nla_resource[DEVLINK_ATTR_RESOURCE_SIZE_MAX] || -+ !nla_resource[DEVLINK_ATTR_RESOURCE_SIZE_GRAN]) { -+ return -EINVAL; -+ } -+ -+ resource->name = strdup(mnl_attr_get_str(nla_resource[DEVLINK_ATTR_RESOURCE_NAME])); -+ resource->size = mnl_attr_get_u64(nla_resource[DEVLINK_ATTR_RESOURCE_SIZE]); -+ resource->id = mnl_attr_get_u64(nla_resource[DEVLINK_ATTR_RESOURCE_ID]); -+ resource->unit = mnl_attr_get_u8(nla_resource[DEVLINK_ATTR_RESOURCE_UNIT]); -+ resource->size_min = mnl_attr_get_u64(nla_resource[DEVLINK_ATTR_RESOURCE_SIZE_MIN]); -+ resource->size_max = mnl_attr_get_u64(nla_resource[DEVLINK_ATTR_RESOURCE_SIZE_MAX]); -+ resource->size_gran = mnl_attr_get_u64(nla_resource[DEVLINK_ATTR_RESOURCE_SIZE_GRAN]); -+ -+ if (nla_resource[DEVLINK_ATTR_RESOURCE_SIZE_NEW]) -+ resource->size_new = mnl_attr_get_u64(nla_resource[DEVLINK_ATTR_RESOURCE_SIZE_NEW]); -+ else -+ resource->size_new = resource->size; -+ -+ if (nla_resource[DEVLINK_ATTR_RESOURCE_OCC]) { -+ resource->size_occ = mnl_attr_get_u64(nla_resource[DEVLINK_ATTR_RESOURCE_OCC]); -+ resource->occ_valid = true; -+ } -+ -+ if (resource->size_new != resource->size) -+ ctx->pending_change = true; -+ -+ return 0; -+} -+ -+static int -+resource_get(struct resource_ctx *ctx, struct resource *resource, -+ struct resource *parent_resource, struct nlattr *nl) -+{ -+ struct nlattr *nla_resource[DEVLINK_ATTR_MAX + 1] = {}; -+ struct nlattr *nla_child_resource; -+ struct nlattr *nla_resources; -+ bool top = false; -+ int err; -+ -+ if (!resource) { -+ nla_resources = nl; -+ top = true; -+ goto out; -+ } -+ -+ err = mnl_attr_parse_nested(nl, attr_cb, nla_resource); -+ if (err != MNL_CB_OK) -+ return -EINVAL; -+ -+ err = resource_parse(ctx, resource, nla_resource); -+ if (err) -+ return err; -+ -+ resource->parent = parent_resource; -+ if (!nla_resource[DEVLINK_ATTR_RESOURCE_LIST]) -+ return 0; -+ -+ resource->size_valid = !!mnl_attr_get_u8(nla_resource[DEVLINK_ATTR_RESOURCE_SIZE_VALID]); -+ nla_resources = nla_resource[DEVLINK_ATTR_RESOURCE_LIST]; -+out: -+ mnl_attr_for_each_nested(nla_child_resource, nla_resources) { -+ struct resource *child_resource; -+ struct list_head *list; -+ -+ child_resource = resource_alloc(); -+ if (!child_resource) -+ return -ENOMEM; -+ -+ if (top) -+ list = &ctx->resources->resource_list; -+ else -+ list = &resource->resource_list; -+ -+ list_add_tail(&child_resource->list, list); -+ err = resource_get(ctx, child_resource, resource, -+ nla_child_resource); -+ if (err) -+ return err; -+ } -+ -+ return 0; -+} -+ -+static const char *resource_unit_str_get(enum devlink_resource_unit unit) -+{ -+ switch (unit) { -+ case DEVLINK_RESOURCE_UNIT_ENTRY: return "entry"; -+ default: return ""; -+ } -+} -+ -+static void resource_show(struct resource *resource, -+ struct resource_ctx *ctx) -+{ -+ struct resource *child_resource; -+ struct dl *dl = ctx->dl; -+ -+ pr_out_str(dl, "name", resource->name); -+ if (dl->verbose) -+ resource_path_print(dl, ctx->resources, resource->id); -+ pr_out_uint(dl, "size", resource->size); -+ if (resource->size != resource->size_new) -+ pr_out_uint(dl, "size_new", resource->size_new); -+ if (resource->occ_valid) -+ pr_out_uint(dl, "occ", resource->size_occ); -+ pr_out_str(dl, "unit", resource_unit_str_get(resource->unit)); -+ -+ if (resource->size_min != resource->size_max) { -+ pr_out_uint(dl, "size_min", resource->size_min); -+ pr_out_uint(dl, "size_max", resource->size_max); -+ pr_out_uint(dl, "size_gran", resource->size_gran); -+ } -+ -+ if (list_empty(&resource->resource_list)) -+ return; -+ -+ if (ctx->pending_change) -+ pr_out_str(dl, "size_valid", resource->size_valid ? -+ "true" : "false"); -+ pr_out_array_start(dl, "resources"); -+ list_for_each_entry(child_resource, &resource->resource_list, list) { -+ pr_out_entry_start(dl); -+ resource_show(child_resource, ctx); -+ pr_out_entry_end(dl); -+ } -+ pr_out_array_end(dl); -+} -+ -+static void -+resources_show(struct resource_ctx *ctx, struct nlattr **tb) -+{ -+ struct resources *resources = ctx->resources; -+ struct resource *resource; -+ -+ list_for_each_entry(resource, &resources->resource_list, list) { -+ pr_out_handle_start_arr(ctx->dl, tb); -+ resource_show(resource, ctx); -+ pr_out_handle_end(ctx->dl); -+ } -+} -+ -+static int resources_get(struct resource_ctx *ctx, struct nlattr **tb) -+{ -+ return resource_get(ctx, NULL, NULL, tb[DEVLINK_ATTR_RESOURCE_LIST]); -+} -+ -+static int cmd_resource_dump_cb(const struct nlmsghdr *nlh, void *data) -+{ -+ struct resource_ctx *ctx = data; -+ struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {}; -+ struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); -+ int err; -+ -+ mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb); -+ if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] || -+ !tb[DEVLINK_ATTR_RESOURCE_LIST]) -+ return MNL_CB_ERROR; -+ -+ err = resources_get(ctx, tb); -+ if (err) { -+ ctx->err = err; -+ return MNL_CB_ERROR; -+ } -+ -+ if (ctx->print_resources) -+ resources_show(ctx, tb); -+ -+ return MNL_CB_OK; -+} -+ -+static int cmd_resource_show(struct dl *dl) -+{ -+ struct nlmsghdr *nlh; -+ struct resource_ctx ctx = {}; -+ int err; -+ -+ nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_RESOURCE_DUMP, -+ NLM_F_REQUEST | NLM_F_ACK); -+ -+ err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLE, 0); -+ if (err) -+ return err; -+ -+ err = resource_ctx_init(&ctx, dl); -+ if (err) -+ return err; -+ -+ ctx.print_resources = true; -+ pr_out_section_start(dl, "resources"); -+ err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_resource_dump_cb, &ctx); -+ pr_out_section_end(dl); -+ resource_ctx_fini(&ctx); -+ return err; -+} -+ -+static void cmd_resource_help(void) -+{ -+ pr_err("Usage: devlink resource show DEV\n" -+ " devlink resource set DEV path PATH size SIZE\n"); -+} -+ -+static struct resource * -+resource_find_by_name(struct list_head *list, char *name) -+{ -+ struct resource *resource; -+ -+ list_for_each_entry(resource, list, list) { -+ if (!strcmp(resource->name, name)) -+ return resource; -+ } -+ return NULL; -+} -+ -+static int -+resource_path_parse(struct resource_ctx *ctx, const char *resource_path, -+ uint32_t *p_resource_id, bool *p_resource_valid) -+{ -+ struct resource *resource; -+ uint32_t resource_id = 0; -+ char *resource_path_dup; -+ struct list_head *list; -+ const char del[] = "/"; -+ char *resource_name; -+ -+ resource_path_dup = strdup(resource_path); -+ list = &ctx->resources->resource_list; -+ resource_name = strtok(resource_path_dup, del); -+ while (resource_name != NULL) { -+ resource = resource_find_by_name(list, resource_name); -+ if (!resource) -+ goto err_resource_lookup; -+ -+ list = &resource->resource_list; -+ resource_name = strtok(NULL, del); -+ resource_id = resource->id; -+ } -+ free(resource_path_dup); -+ *p_resource_valid = true; -+ *p_resource_id = resource_id; -+ return 0; -+ -+err_resource_lookup: -+ free(resource_path_dup); -+ return -EINVAL; -+} -+ -+static int cmd_resource_set(struct dl *dl) -+{ -+ struct nlmsghdr *nlh; -+ struct resource_ctx ctx = {}; -+ int err; -+ -+ err = resource_ctx_init(&ctx, dl); -+ if (err) -+ return err; -+ -+ ctx.print_resources = false; -+ err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_RESOURCE_PATH | -+ DL_OPT_RESOURCE_SIZE, 0); -+ if (err) -+ goto out; -+ -+ nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_RESOURCE_DUMP, -+ NLM_F_REQUEST); -+ dl_opts_put(nlh, dl); -+ err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_resource_dump_cb, &ctx); -+ if (err) { -+ pr_err("error getting resources %s\n", strerror(ctx.err)); -+ goto out; -+ } -+ -+ err = resource_path_parse(&ctx, dl->opts.resource_path, -+ &dl->opts.resource_id, -+ &dl->opts.resource_id_valid); -+ if (err) { -+ pr_err("error parsing resource path %s\n", strerror(err)); -+ goto out; -+ } -+ -+ nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_RESOURCE_SET, -+ NLM_F_REQUEST | NLM_F_ACK); -+ -+ dl_opts_put(nlh, dl); -+ err = _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL); -+out: -+ resource_ctx_fini(&ctx); -+ return err; -+} -+ -+static int cmd_resource(struct dl *dl) -+{ -+ if (dl_argv_match(dl, "help") || dl_no_arg(dl)) { -+ cmd_resource_help(); -+ return 0; -+ } else if (dl_argv_match(dl, "show")) { -+ dl_arg_inc(dl); -+ return cmd_resource_show(dl); -+ } else if (dl_argv_match(dl, "set")) { -+ dl_arg_inc(dl); -+ return cmd_resource_set(dl); -+ } -+ pr_err("Command \"%s\" not found\n", dl_argv(dl)); -+ return -ENOENT; -+} -+ - static void help(void) - { - pr_err("Usage: devlink [ OPTIONS ] OBJECT { COMMAND | help }\n" -- "where OBJECT := { dev | port | sb | monitor | dpipe }\n" -+ "where OBJECT := { dev | port | sb | monitor | dpipe | resource }\n" - " OPTIONS := { -V[ersion] | -n[no-nice-names] | -j[json] | -p[pretty] | -v[verbose] }\n"); - } - -@@ -3644,6 +4129,9 @@ static int dl_cmd(struct dl *dl) - } else if (dl_argv_match(dl, "dpipe")) { - dl_arg_inc(dl); - return cmd_dpipe(dl); -+ } else if (dl_argv_match(dl, "resource")) { -+ dl_arg_inc(dl); -+ return cmd_resource(dl); - } - pr_err("Object \"%s\" not found\n", dl_argv(dl)); - return -ENOENT; -diff --git a/include/list.h b/include/list.h -index 5b529dc6e5211..b2adf55578449 100644 ---- a/include/list.h -+++ b/include/list.h -@@ -107,6 +107,11 @@ static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) - n->pprev = &h->first; - } - -+static inline int list_empty(const struct list_head *head) -+{ -+ return head->next == head; -+} -+ - #define hlist_for_each(pos, head) \ - for (pos = (head)->first; pos ; pos = pos->next) - --- -2.21.0 - diff --git a/SOURCES/0057-devlink-Add-support-for-hot-reload.patch b/SOURCES/0057-devlink-Add-support-for-hot-reload.patch deleted file mode 100644 index 3cf8b6b..0000000 --- a/SOURCES/0057-devlink-Add-support-for-hot-reload.patch +++ /dev/null @@ -1,81 +0,0 @@ -From ceaa3a5ecffe0c558c990be6c4ba682be5ce85e8 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 25 Mar 2019 11:40:57 +0100 -Subject: [PATCH] devlink: Add support for hot reload - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1644731 -Upstream Status: iproute2.git commit 06dd94f952e50 - -commit 06dd94f952e50edeffe5ea8b7b95b5cd562b9365 -Author: Arkadi Sharshevsky -Date: Wed Feb 14 10:55:19 2018 +0200 - - devlink: Add support for hot reload - - Add support for hot reload. It should be used in order for resource - updates to take place. - - Signed-off-by: Arkadi Sharshevsky - Acked-by: Jiri Pirko - Signed-off-by: Stephen Hemminger ---- - devlink/devlink.c | 29 +++++++++++++++++++++++++++++ - 1 file changed, 29 insertions(+) - -diff --git a/devlink/devlink.c b/devlink/devlink.c -index 7f47b79450094..fc3939e564bc8 100644 ---- a/devlink/devlink.c -+++ b/devlink/devlink.c -@@ -1163,6 +1163,7 @@ static void cmd_dev_help(void) - pr_err(" [ inline-mode { none | link | network | transport } ]\n"); - pr_err(" [ encap { disable | enable } ]\n"); - pr_err(" devlink dev eswitch show DEV\n"); -+ pr_err(" devlink dev reload DEV\n"); - } - - static bool cmp_arr_last_handle(struct dl *dl, const char *bus_name, -@@ -1602,6 +1603,31 @@ static int cmd_dev_show(struct dl *dl) - return err; - } - -+static void cmd_dev_reload_help(void) -+{ -+ pr_err("Usage: devlink dev reload [ DEV ]\n"); -+} -+ -+static int cmd_dev_reload(struct dl *dl) -+{ -+ struct nlmsghdr *nlh; -+ int err; -+ -+ if (dl_argv_match(dl, "help") || dl_no_arg(dl)) { -+ cmd_dev_reload_help(); -+ return 0; -+ } -+ -+ nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_RELOAD, -+ NLM_F_REQUEST | NLM_F_ACK); -+ -+ err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLE, 0); -+ if (err) -+ return err; -+ -+ return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL); -+} -+ - static int cmd_dev(struct dl *dl) - { - if (dl_argv_match(dl, "help")) { -@@ -1614,6 +1640,9 @@ static int cmd_dev(struct dl *dl) - } else if (dl_argv_match(dl, "eswitch")) { - dl_arg_inc(dl); - return cmd_dev_eswitch(dl); -+ } else if (dl_argv_match(dl, "reload")) { -+ dl_arg_inc(dl); -+ return cmd_dev_reload(dl); - } - pr_err("Command \"%s\" not found\n", dl_argv(dl)); - return -ENOENT; --- -2.21.0 - diff --git a/SOURCES/0058-devlink-Update-man-pages-and-add-resource-man.patch b/SOURCES/0058-devlink-Update-man-pages-and-add-resource-man.patch deleted file mode 100644 index 54d574a..0000000 --- a/SOURCES/0058-devlink-Update-man-pages-and-add-resource-man.patch +++ /dev/null @@ -1,165 +0,0 @@ -From edf1a3765c440bdd6a15ca7dd4d52a2264a67f69 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 25 Mar 2019 11:40:57 +0100 -Subject: [PATCH] devlink: Update man pages and add resource man - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1644731 -Upstream Status: iproute2.git commit 58b48c5d75e29 - -commit 58b48c5d75e2960dfcd947975911a170ae765975 -Author: Arkadi Sharshevsky -Date: Wed Feb 14 10:55:22 2018 +0200 - - devlink: Update man pages and add resource man - - Add resource man, and update dev manual for reload command. - - Signed-off-by: Arkadi Sharshevsky - Acked-by: Jiri Pirko - Signed-off-by: Stephen Hemminger ---- - man/man8/devlink-dev.8 | 15 +++++++ - man/man8/devlink-resource.8 | 78 +++++++++++++++++++++++++++++++++++++ - man/man8/devlink.8 | 1 + - 3 files changed, 94 insertions(+) - create mode 100644 man/man8/devlink-resource.8 - -diff --git a/man/man8/devlink-dev.8 b/man/man8/devlink-dev.8 -index b074d57a19369..7c749ddabaeeb 100644 ---- a/man/man8/devlink-dev.8 -+++ b/man/man8/devlink-dev.8 -@@ -42,6 +42,10 @@ devlink-dev \- devlink device configuration - .BR "devlink dev eswitch show" - .IR DEV - -+.ti -8 -+.BR "devlink dev reload" -+.IR DEV -+ - .SH "DESCRIPTION" - .SS devlink dev show - display devlink device attributes - -@@ -94,6 +98,12 @@ Set eswitch encapsulation support - .I enable - - Enable encapsulation support - -+.SS devlink dev reload - perform hot reload of the driver. -+ -+.PP -+.I "DEV" -+- Specifies the devlink device to reload. -+ - .SH "EXAMPLES" - .PP - devlink dev show -@@ -114,6 +124,11 @@ Shows the eswitch mode of specified devlink device. - devlink dev eswitch set pci/0000:01:00.0 mode switchdev - .RS 4 - Sets the eswitch mode of specified devlink device to switchdev. -+.RE -+.PP -+devlink dev reload pci/0000:01:00.0 -+.RS 4 -+Performs hot reload of specified devlink device. - - .SH SEE ALSO - .BR devlink (8), -diff --git a/man/man8/devlink-resource.8 b/man/man8/devlink-resource.8 -new file mode 100644 -index 0000000000000..b8f788060427b ---- /dev/null -+++ b/man/man8/devlink-resource.8 -@@ -0,0 +1,78 @@ -+.TH DEVLINK\-RESOURCE 8 "11 Feb 2018" "iproute2" "Linux" -+.SH NAME -+devlink-resource \- devlink device resource configuration -+.SH SYNOPSIS -+.sp -+.ad l -+.in +8 -+.ti -8 -+.B devlink -+.RI "[ " OPTIONS " ]" -+.B resource -+.RI " { " COMMAND " | " -+.BR help " }" -+.sp -+ -+.ti -8 -+.IR OPTIONS " := { " -+\fB\-v\fR[\fIerbose\fR] } -+ -+.ti -8 -+.B devlink resource show -+.IR DEV -+ -+.ti -8 -+.B devlink resource help -+ -+.ti -8 -+.BR "devlink resource set" -+.IR DEV -+.BI path " RESOURCE_PATH" -+.BI size " RESOURCE_SIZE" -+ -+.SH "DESCRIPTION" -+.SS devlink resource show - display devlink device's resosources -+ -+.PP -+.I "DEV" -+- specifies the devlink device to show. -+ -+.in +4 -+Format is: -+.in +2 -+BUS_NAME/BUS_ADDRESS -+ -+.SS devlink resource set - sets resource size of specific resource -+ -+.PP -+.I "DEV" -+- specifies the devlink device. -+ -+.TP -+.BI path " RESOURCE_PATH" -+Resource's path. -+ -+.TP -+.BI size " RESOURCE_SIZE" -+The new resource's size. -+ -+.SH "EXAMPLES" -+.PP -+devlink resource show pci/0000:01:00.0 -+.RS 4 -+Shows the resources of the specified devlink device. -+.RE -+.PP -+devlink resource set pci/0000:01:00.0 /kvd/linear 98304 -+.RS 4 -+Sets the size of the specified resource for the specified devlink device. -+ -+.SH SEE ALSO -+.BR devlink (8), -+.BR devlink-port (8), -+.BR devlink-sb (8), -+.BR devlink-monitor (8), -+.br -+ -+.SH AUTHOR -+Arkadi Sharshevsky -diff --git a/man/man8/devlink.8 b/man/man8/devlink.8 -index a480766cbbdbe..6bf398274a612 100644 ---- a/man/man8/devlink.8 -+++ b/man/man8/devlink.8 -@@ -87,6 +87,7 @@ Exit status is 0 if command was successful or a positive integer upon failure. - .BR devlink-port (8), - .BR devlink-monitor (8), - .BR devlink-sb (8), -+.BR devlink-resource (8), - .br - - .SH REPORTING BUGS --- -2.21.0 - diff --git a/SOURCES/0059-devlink-Add-param-command-support.patch b/SOURCES/0059-devlink-Add-param-command-support.patch deleted file mode 100644 index 0cf3144..0000000 --- a/SOURCES/0059-devlink-Add-param-command-support.patch +++ /dev/null @@ -1,704 +0,0 @@ -From 8bd31b6df5fd1da612accbb4d131b3c3bcded079 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 25 Mar 2019 11:40:58 +0100 -Subject: [PATCH] devlink: Add param command support - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1644731 -Upstream Status: iproute2.git commit 13925ae9eb38b -Conflicts: context change due to missing commit 844646a52837f - ("devlink: Change empty line indication with indentations") - -commit 13925ae9eb38b99107be1d3fe21a1b73cf40bd97 -Author: Moshe Shemesh -Date: Wed Jul 4 17:12:06 2018 +0300 - - devlink: Add param command support - - Add support for configuration parameters set and show. - Each parameter can be either generic or driver-specific. - The user can retrieve data on these configuration parameters by devlink - param show command and can set new value to a configuration parameter - by devlink param set command. - The configuration parameters can be set in different configuration - modes: - runtime - set while driver is running, no reset required. - driverinit - applied while driver initializes, requires restart - driver by devlink reload command. - permanent - written to device's non-volatile memory, hard reset - required to apply. - - New commands added: - devlink dev param show [DEV name PARAMETER] - devlink dev param set DEV name PARAMETER value VALUE - cmode { permanent | driverinit | runtime } - - Signed-off-by: Moshe Shemesh - Signed-off-by: Jiri Pirko - Signed-off-by: David Ahern ---- - devlink/devlink.c | 454 +++++++++++++++++++++++++++++++++++++++++ - man/man8/devlink-dev.8 | 57 ++++++ - 2 files changed, 511 insertions(+) - -diff --git a/devlink/devlink.c b/devlink/devlink.c -index fc3939e564bc8..92e78c9c8d9f6 100644 ---- a/devlink/devlink.c -+++ b/devlink/devlink.c -@@ -33,6 +33,10 @@ - #define ESWITCH_INLINE_MODE_NETWORK "network" - #define ESWITCH_INLINE_MODE_TRANSPORT "transport" - -+#define PARAM_CMODE_RUNTIME_STR "runtime" -+#define PARAM_CMODE_DRIVERINIT_STR "driverinit" -+#define PARAM_CMODE_PERMANENT_STR "permanent" -+ - #define pr_err(args...) fprintf(stderr, ##args) - #define pr_out(args...) \ - do { \ -@@ -179,6 +183,9 @@ static void ifname_map_free(struct ifname_map *ifname_map) - #define DL_OPT_ESWITCH_ENCAP_MODE BIT(15) - #define DL_OPT_RESOURCE_PATH BIT(16) - #define DL_OPT_RESOURCE_SIZE BIT(17) -+#define DL_OPT_PARAM_NAME BIT(18) -+#define DL_OPT_PARAM_VALUE BIT(19) -+#define DL_OPT_PARAM_CMODE BIT(20) - - struct dl_opts { - uint32_t present; /* flags of present items */ -@@ -203,6 +210,9 @@ struct dl_opts { - uint32_t resource_size; - uint32_t resource_id; - bool resource_id_valid; -+ const char *param_name; -+ const char *param_value; -+ enum devlink_param_cmode cmode; - }; - - struct dl { -@@ -340,6 +350,12 @@ static const enum mnl_attr_data_type devlink_policy[DEVLINK_ATTR_MAX + 1] = { - [DEVLINK_ATTR_DPIPE_FIELD_ID] = MNL_TYPE_U32, - [DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH] = MNL_TYPE_U32, - [DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE] = MNL_TYPE_U32, -+ [DEVLINK_ATTR_PARAM] = MNL_TYPE_NESTED, -+ [DEVLINK_ATTR_PARAM_NAME] = MNL_TYPE_STRING, -+ [DEVLINK_ATTR_PARAM_TYPE] = MNL_TYPE_U8, -+ [DEVLINK_ATTR_PARAM_VALUES_LIST] = MNL_TYPE_NESTED, -+ [DEVLINK_ATTR_PARAM_VALUE] = MNL_TYPE_NESTED, -+ [DEVLINK_ATTR_PARAM_VALUE_CMODE] = MNL_TYPE_U8, - }; - - static int attr_cb(const struct nlattr *attr, void *data) -@@ -506,6 +522,34 @@ static int strtouint16_t(const char *str, uint16_t *p_val) - return 0; - } - -+static int strtouint8_t(const char *str, uint8_t *p_val) -+{ -+ char *endptr; -+ unsigned long int val; -+ -+ val = strtoul(str, &endptr, 10); -+ if (endptr == str || *endptr != '\0') -+ return -EINVAL; -+ if (val > UCHAR_MAX) -+ return -ERANGE; -+ *p_val = val; -+ return 0; -+} -+ -+static int strtobool(const char *str, bool *p_val) -+{ -+ bool val; -+ -+ if (!strcmp(str, "true") || !strcmp(str, "1")) -+ val = true; -+ else if (!strcmp(str, "false") || !strcmp(str, "0")) -+ val = false; -+ else -+ return -EINVAL; -+ *p_val = val; -+ return 0; -+} -+ - static int __dl_argv_handle(char *str, char **p_bus_name, char **p_dev_name) - { - strslashrsplit(str, p_bus_name, p_dev_name); -@@ -776,6 +820,22 @@ static int eswitch_encap_mode_get(const char *typestr, bool *p_mode) - return 0; - } - -+static int param_cmode_get(const char *cmodestr, -+ enum devlink_param_cmode *cmode) -+{ -+ if (strcmp(cmodestr, PARAM_CMODE_RUNTIME_STR) == 0) { -+ *cmode = DEVLINK_PARAM_CMODE_RUNTIME; -+ } else if (strcmp(cmodestr, PARAM_CMODE_DRIVERINIT_STR) == 0) { -+ *cmode = DEVLINK_PARAM_CMODE_DRIVERINIT; -+ } else if (strcmp(cmodestr, PARAM_CMODE_PERMANENT_STR) == 0) { -+ *cmode = DEVLINK_PARAM_CMODE_PERMANENT; -+ } else { -+ pr_err("Unknown configuration mode \"%s\"\n", cmodestr); -+ return -EINVAL; -+ } -+ return 0; -+} -+ - static int dl_argv_parse(struct dl *dl, uint32_t o_required, - uint32_t o_optional) - { -@@ -957,6 +1017,32 @@ static int dl_argv_parse(struct dl *dl, uint32_t o_required, - if (err) - return err; - o_found |= DL_OPT_RESOURCE_SIZE; -+ } else if (dl_argv_match(dl, "name") && -+ (o_all & DL_OPT_PARAM_NAME)) { -+ dl_arg_inc(dl); -+ err = dl_argv_str(dl, &opts->param_name); -+ if (err) -+ return err; -+ o_found |= DL_OPT_PARAM_NAME; -+ } else if (dl_argv_match(dl, "value") && -+ (o_all & DL_OPT_PARAM_VALUE)) { -+ dl_arg_inc(dl); -+ err = dl_argv_str(dl, &opts->param_value); -+ if (err) -+ return err; -+ o_found |= DL_OPT_PARAM_VALUE; -+ } else if (dl_argv_match(dl, "cmode") && -+ (o_all & DL_OPT_PARAM_CMODE)) { -+ const char *cmodestr; -+ -+ dl_arg_inc(dl); -+ err = dl_argv_str(dl, &cmodestr); -+ if (err) -+ return err; -+ err = param_cmode_get(cmodestr, &opts->cmode); -+ if (err) -+ return err; -+ o_found |= DL_OPT_PARAM_CMODE; - } else { - pr_err("Unknown option \"%s\"\n", dl_argv(dl)); - return -EINVAL; -@@ -1041,6 +1127,24 @@ static int dl_argv_parse(struct dl *dl, uint32_t o_required, - return -EINVAL; - } - -+ if ((o_required & DL_OPT_PARAM_NAME) && -+ !(o_found & DL_OPT_PARAM_NAME)) { -+ pr_err("Parameter name expected.\n"); -+ return -EINVAL; -+ } -+ -+ if ((o_required & DL_OPT_PARAM_VALUE) && -+ !(o_found & DL_OPT_PARAM_VALUE)) { -+ pr_err("Value to set expected.\n"); -+ return -EINVAL; -+ } -+ -+ if ((o_required & DL_OPT_PARAM_CMODE) && -+ !(o_found & DL_OPT_PARAM_CMODE)) { -+ pr_err("Configuration mode expected.\n"); -+ return -EINVAL; -+ } -+ - return 0; - } - -@@ -1105,6 +1209,12 @@ static void dl_opts_put(struct nlmsghdr *nlh, struct dl *dl) - if (opts->present & DL_OPT_RESOURCE_SIZE) - mnl_attr_put_u64(nlh, DEVLINK_ATTR_RESOURCE_SIZE, - opts->resource_size); -+ if (opts->present & DL_OPT_PARAM_NAME) -+ mnl_attr_put_strz(nlh, DEVLINK_ATTR_PARAM_NAME, -+ opts->param_name); -+ if (opts->present & DL_OPT_PARAM_CMODE) -+ mnl_attr_put_u8(nlh, DEVLINK_ATTR_PARAM_VALUE_CMODE, -+ opts->cmode); - } - - static int dl_argv_parse_put(struct nlmsghdr *nlh, struct dl *dl, -@@ -1163,6 +1273,8 @@ static void cmd_dev_help(void) - pr_err(" [ inline-mode { none | link | network | transport } ]\n"); - pr_err(" [ encap { disable | enable } ]\n"); - pr_err(" devlink dev eswitch show DEV\n"); -+ pr_err(" devlink dev param set DEV name PARAMETER value VALUE cmode { permanent | driverinit | runtime }\n"); -+ pr_err(" devlink dev param show [DEV name PARAMETER]\n"); - pr_err(" devlink dev reload DEV\n"); - } - -@@ -1377,6 +1489,14 @@ static void pr_out_str(struct dl *dl, const char *name, const char *val) - } - } - -+static void pr_out_bool(struct dl *dl, const char *name, bool val) -+{ -+ if (val) -+ pr_out_str(dl, name, "true"); -+ else -+ pr_out_str(dl, name, "false"); -+} -+ - static void pr_out_uint(struct dl *dl, const char *name, unsigned int val) - { - if (dl->json_output) { -@@ -1449,6 +1569,19 @@ static void pr_out_entry_end(struct dl *dl) - __pr_out_newline(); - } - -+static const char *param_cmode_name(uint8_t cmode) -+{ -+ switch (cmode) { -+ case DEVLINK_PARAM_CMODE_RUNTIME: -+ return PARAM_CMODE_RUNTIME_STR; -+ case DEVLINK_PARAM_CMODE_DRIVERINIT: -+ return PARAM_CMODE_DRIVERINIT_STR; -+ case DEVLINK_PARAM_CMODE_PERMANENT: -+ return PARAM_CMODE_PERMANENT_STR; -+ default: return ""; -+ } -+} -+ - static const char *eswitch_mode_name(uint32_t mode) - { - switch (mode) { -@@ -1567,6 +1700,304 @@ static int cmd_dev_eswitch(struct dl *dl) - return -ENOENT; - } - -+static void pr_out_param_value(struct dl *dl, int nla_type, struct nlattr *nl) -+{ -+ struct nlattr *nla_value[DEVLINK_ATTR_MAX + 1] = {}; -+ struct nlattr *val_attr; -+ int err; -+ -+ err = mnl_attr_parse_nested(nl, attr_cb, nla_value); -+ if (err != MNL_CB_OK) -+ return; -+ -+ if (!nla_value[DEVLINK_ATTR_PARAM_VALUE_CMODE] || -+ (nla_type != MNL_TYPE_FLAG && -+ !nla_value[DEVLINK_ATTR_PARAM_VALUE_DATA])) -+ return; -+ -+ pr_out_str(dl, "cmode", -+ param_cmode_name(mnl_attr_get_u8(nla_value[DEVLINK_ATTR_PARAM_VALUE_CMODE]))); -+ val_attr = nla_value[DEVLINK_ATTR_PARAM_VALUE_DATA]; -+ -+ switch (nla_type) { -+ case MNL_TYPE_U8: -+ pr_out_uint(dl, "value", mnl_attr_get_u8(val_attr)); -+ break; -+ case MNL_TYPE_U16: -+ pr_out_uint(dl, "value", mnl_attr_get_u16(val_attr)); -+ break; -+ case MNL_TYPE_U32: -+ pr_out_uint(dl, "value", mnl_attr_get_u32(val_attr)); -+ break; -+ case MNL_TYPE_STRING: -+ pr_out_str(dl, "value", mnl_attr_get_str(val_attr)); -+ break; -+ case MNL_TYPE_FLAG: -+ pr_out_bool(dl, "value", val_attr ? true : false); -+ break; -+ } -+} -+ -+static void pr_out_param(struct dl *dl, struct nlattr **tb, bool array) -+{ -+ struct nlattr *nla_param[DEVLINK_ATTR_MAX + 1] = {}; -+ struct nlattr *param_value_attr; -+ int nla_type; -+ int err; -+ -+ err = mnl_attr_parse_nested(tb[DEVLINK_ATTR_PARAM], attr_cb, nla_param); -+ if (err != MNL_CB_OK) -+ return; -+ if (!nla_param[DEVLINK_ATTR_PARAM_NAME] || -+ !nla_param[DEVLINK_ATTR_PARAM_TYPE] || -+ !nla_param[DEVLINK_ATTR_PARAM_VALUES_LIST]) -+ return; -+ -+ if (array) -+ pr_out_handle_start_arr(dl, tb); -+ else -+ __pr_out_handle_start(dl, tb, true, false); -+ -+ nla_type = mnl_attr_get_u8(nla_param[DEVLINK_ATTR_PARAM_TYPE]); -+ -+ pr_out_str(dl, "name", -+ mnl_attr_get_str(nla_param[DEVLINK_ATTR_PARAM_NAME])); -+ -+ if (!nla_param[DEVLINK_ATTR_PARAM_GENERIC]) -+ pr_out_str(dl, "type", "driver-specific"); -+ else -+ pr_out_str(dl, "type", "generic"); -+ -+ pr_out_array_start(dl, "values"); -+ mnl_attr_for_each_nested(param_value_attr, -+ nla_param[DEVLINK_ATTR_PARAM_VALUES_LIST]) { -+ pr_out_entry_start(dl); -+ pr_out_param_value(dl, nla_type, param_value_attr); -+ pr_out_entry_end(dl); -+ } -+ pr_out_array_end(dl); -+ pr_out_handle_end(dl); -+} -+ -+static int cmd_dev_param_show_cb(const struct nlmsghdr *nlh, void *data) -+{ -+ struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); -+ struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {}; -+ struct dl *dl = data; -+ -+ mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb); -+ if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] || -+ !tb[DEVLINK_ATTR_PARAM]) -+ return MNL_CB_ERROR; -+ pr_out_param(dl, tb, true); -+ return MNL_CB_OK; -+} -+ -+struct param_ctx { -+ struct dl *dl; -+ int nla_type; -+ union { -+ uint8_t vu8; -+ uint16_t vu16; -+ uint32_t vu32; -+ const char *vstr; -+ bool vbool; -+ } value; -+}; -+ -+static int cmd_dev_param_set_cb(const struct nlmsghdr *nlh, void *data) -+{ -+ struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); -+ struct nlattr *nla_param[DEVLINK_ATTR_MAX + 1] = {}; -+ struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {}; -+ struct nlattr *param_value_attr; -+ enum devlink_param_cmode cmode; -+ struct param_ctx *ctx = data; -+ struct dl *dl = ctx->dl; -+ int nla_type; -+ int err; -+ -+ mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb); -+ if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] || -+ !tb[DEVLINK_ATTR_PARAM]) -+ return MNL_CB_ERROR; -+ -+ err = mnl_attr_parse_nested(tb[DEVLINK_ATTR_PARAM], attr_cb, nla_param); -+ if (err != MNL_CB_OK) -+ return MNL_CB_ERROR; -+ -+ if (!nla_param[DEVLINK_ATTR_PARAM_TYPE] || -+ !nla_param[DEVLINK_ATTR_PARAM_VALUES_LIST]) -+ return MNL_CB_ERROR; -+ -+ nla_type = mnl_attr_get_u8(nla_param[DEVLINK_ATTR_PARAM_TYPE]); -+ mnl_attr_for_each_nested(param_value_attr, -+ nla_param[DEVLINK_ATTR_PARAM_VALUES_LIST]) { -+ struct nlattr *nla_value[DEVLINK_ATTR_MAX + 1] = {}; -+ struct nlattr *val_attr; -+ -+ err = mnl_attr_parse_nested(param_value_attr, -+ attr_cb, nla_value); -+ if (err != MNL_CB_OK) -+ return MNL_CB_ERROR; -+ -+ if (!nla_value[DEVLINK_ATTR_PARAM_VALUE_CMODE] || -+ (nla_type != MNL_TYPE_FLAG && -+ !nla_value[DEVLINK_ATTR_PARAM_VALUE_DATA])) -+ return MNL_CB_ERROR; -+ -+ cmode = mnl_attr_get_u8(nla_value[DEVLINK_ATTR_PARAM_VALUE_CMODE]); -+ if (cmode == dl->opts.cmode) { -+ val_attr = nla_value[DEVLINK_ATTR_PARAM_VALUE_DATA]; -+ switch (nla_type) { -+ case MNL_TYPE_U8: -+ ctx->value.vu8 = mnl_attr_get_u8(val_attr); -+ break; -+ case MNL_TYPE_U16: -+ ctx->value.vu16 = mnl_attr_get_u16(val_attr); -+ break; -+ case MNL_TYPE_U32: -+ ctx->value.vu32 = mnl_attr_get_u32(val_attr); -+ break; -+ case MNL_TYPE_STRING: -+ ctx->value.vstr = mnl_attr_get_str(val_attr); -+ break; -+ case MNL_TYPE_FLAG: -+ ctx->value.vbool = val_attr ? true : false; -+ break; -+ } -+ break; -+ } -+ } -+ ctx->nla_type = nla_type; -+ return MNL_CB_OK; -+} -+ -+static int cmd_dev_param_set(struct dl *dl) -+{ -+ struct param_ctx ctx = {}; -+ struct nlmsghdr *nlh; -+ uint32_t val_u32; -+ uint16_t val_u16; -+ uint8_t val_u8; -+ bool val_bool; -+ int err; -+ -+ err = dl_argv_parse(dl, DL_OPT_HANDLE | -+ DL_OPT_PARAM_NAME | -+ DL_OPT_PARAM_VALUE | -+ DL_OPT_PARAM_CMODE, 0); -+ if (err) -+ return err; -+ -+ /* Get value type */ -+ nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_PARAM_GET, -+ NLM_F_REQUEST | NLM_F_ACK); -+ dl_opts_put(nlh, dl); -+ -+ ctx.dl = dl; -+ err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_dev_param_set_cb, &ctx); -+ if (err) -+ return err; -+ -+ nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_PARAM_SET, -+ NLM_F_REQUEST | NLM_F_ACK); -+ dl_opts_put(nlh, dl); -+ -+ mnl_attr_put_u8(nlh, DEVLINK_ATTR_PARAM_TYPE, ctx.nla_type); -+ switch (ctx.nla_type) { -+ case MNL_TYPE_U8: -+ err = strtouint8_t(dl->opts.param_value, &val_u8); -+ if (err) -+ goto err_param_value_parse; -+ if (val_u8 == ctx.value.vu8) -+ return 0; -+ mnl_attr_put_u8(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, val_u8); -+ break; -+ case MNL_TYPE_U16: -+ err = strtouint16_t(dl->opts.param_value, &val_u16); -+ if (err) -+ goto err_param_value_parse; -+ if (val_u16 == ctx.value.vu16) -+ return 0; -+ mnl_attr_put_u16(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, val_u16); -+ break; -+ case MNL_TYPE_U32: -+ err = strtouint32_t(dl->opts.param_value, &val_u32); -+ if (err) -+ goto err_param_value_parse; -+ if (val_u32 == ctx.value.vu32) -+ return 0; -+ mnl_attr_put_u32(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, val_u32); -+ break; -+ case MNL_TYPE_FLAG: -+ err = strtobool(dl->opts.param_value, &val_bool); -+ if (err) -+ goto err_param_value_parse; -+ if (val_bool == ctx.value.vbool) -+ return 0; -+ if (val_bool) -+ mnl_attr_put(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, -+ 0, NULL); -+ break; -+ case MNL_TYPE_STRING: -+ mnl_attr_put_strz(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, -+ dl->opts.param_value); -+ if (!strcmp(dl->opts.param_value, ctx.value.vstr)) -+ return 0; -+ break; -+ default: -+ printf("Value type not supported\n"); -+ return -ENOTSUP; -+ } -+ return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL); -+ -+err_param_value_parse: -+ pr_err("Value \"%s\" is not a number or not within range\n", -+ dl->opts.param_value); -+ return err; -+} -+ -+static int cmd_dev_param_show(struct dl *dl) -+{ -+ uint16_t flags = NLM_F_REQUEST | NLM_F_ACK; -+ struct nlmsghdr *nlh; -+ int err; -+ -+ if (dl_argc(dl) == 0) -+ flags |= NLM_F_DUMP; -+ -+ nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_PARAM_GET, flags); -+ -+ if (dl_argc(dl) > 0) { -+ err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLE | -+ DL_OPT_PARAM_NAME, 0); -+ if (err) -+ return err; -+ } -+ -+ pr_out_section_start(dl, "param"); -+ err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_dev_param_show_cb, dl); -+ pr_out_section_end(dl); -+ return err; -+} -+ -+static int cmd_dev_param(struct dl *dl) -+{ -+ if (dl_argv_match(dl, "help")) { -+ cmd_dev_help(); -+ return 0; -+ } else if (dl_argv_match(dl, "show") || -+ dl_argv_match(dl, "list") || dl_no_arg(dl)) { -+ dl_arg_inc(dl); -+ return cmd_dev_param_show(dl); -+ } else if (dl_argv_match(dl, "set")) { -+ dl_arg_inc(dl); -+ return cmd_dev_param_set(dl); -+ } -+ pr_err("Command \"%s\" not found\n", dl_argv(dl)); -+ return -ENOENT; -+} - static int cmd_dev_show_cb(const struct nlmsghdr *nlh, void *data) - { - struct dl *dl = data; -@@ -1643,6 +2074,9 @@ static int cmd_dev(struct dl *dl) - } else if (dl_argv_match(dl, "reload")) { - dl_arg_inc(dl); - return cmd_dev_reload(dl); -+ } else if (dl_argv_match(dl, "param")) { -+ dl_arg_inc(dl); -+ return cmd_dev_param(dl); - } - pr_err("Command \"%s\" not found\n", dl_argv(dl)); - return -ENOENT; -@@ -2586,6 +3020,10 @@ static const char *cmd_name(uint8_t cmd) - case DEVLINK_CMD_PORT_SET: return "set"; - case DEVLINK_CMD_PORT_NEW: return "net"; - case DEVLINK_CMD_PORT_DEL: return "del"; -+ case DEVLINK_CMD_PARAM_GET: return "get"; -+ case DEVLINK_CMD_PARAM_SET: return "set"; -+ case DEVLINK_CMD_PARAM_NEW: return "new"; -+ case DEVLINK_CMD_PARAM_DEL: return "del"; - default: return ""; - } - } -@@ -2604,6 +3042,11 @@ static const char *cmd_obj(uint8_t cmd) - case DEVLINK_CMD_PORT_NEW: - case DEVLINK_CMD_PORT_DEL: - return "port"; -+ case DEVLINK_CMD_PARAM_GET: -+ case DEVLINK_CMD_PARAM_SET: -+ case DEVLINK_CMD_PARAM_NEW: -+ case DEVLINK_CMD_PARAM_DEL: -+ return "param"; - default: return ""; - } - } -@@ -2660,6 +3103,17 @@ static int cmd_mon_show_cb(const struct nlmsghdr *nlh, void *data) - pr_out_mon_header(genl->cmd); - pr_out_port(dl, tb); - break; -+ case DEVLINK_CMD_PARAM_GET: /* fall through */ -+ case DEVLINK_CMD_PARAM_SET: /* fall through */ -+ case DEVLINK_CMD_PARAM_NEW: /* fall through */ -+ case DEVLINK_CMD_PARAM_DEL: -+ mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb); -+ if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] || -+ !tb[DEVLINK_ATTR_PARAM]) -+ return MNL_CB_ERROR; -+ pr_out_mon_header(genl->cmd); -+ pr_out_param(dl, tb, false); -+ break; - } - return MNL_CB_OK; - } -diff --git a/man/man8/devlink-dev.8 b/man/man8/devlink-dev.8 -index 7c749ddabaeeb..d985da172aa05 100644 ---- a/man/man8/devlink-dev.8 -+++ b/man/man8/devlink-dev.8 -@@ -42,6 +42,23 @@ devlink-dev \- devlink device configuration - .BR "devlink dev eswitch show" - .IR DEV - -+.ti -8 -+.BR "devlink dev param set" -+.IR DEV -+.BR name -+.IR PARAMETER -+.BR value -+.IR VALUE -+.BR cmode " { " runtime " | " driverinit " | " permanent " } " -+ -+.ti -8 -+.BR "devlink dev param show" -+.RI "[ " -+.IR DEV -+.BR name -+.IR PARAMETER -+.RI "]" -+ - .ti -8 - .BR "devlink dev reload" - .IR DEV -@@ -98,6 +115,36 @@ Set eswitch encapsulation support - .I enable - - Enable encapsulation support - -+.SS devlink dev param set - set new value to devlink device configuration parameter -+ -+.TP -+.BI name " PARAMETER" -+Specify parameter name to set. -+ -+.TP -+.BI value " VALUE" -+New value to set. -+ -+.TP -+.BR cmode " { " runtime " | " driverinit " | " permanent " } " -+Configuration mode in which the new value is set. -+ -+.I runtime -+- Set new value while driver is running. This configuration mode doesn't require any reset to apply the new value. -+ -+.I driverinit -+- Set new value which will be applied during driver initialization. This configuration mode requires restart driver by devlink reload command to apply the new value. -+ -+.I permanent -+- New value is written to device's non-volatile memory. This configuration mode requires hard reset to apply the new value. -+ -+.SS devlink dev param show - display devlink device supported configuration parameters attributes -+ -+.BR name -+.IR PARAMETER -+Specify parameter name to show. -+If this argument is omitted all parameters supported by devlink devices are listed. -+ - .SS devlink dev reload - perform hot reload of the driver. - - .PP -@@ -126,6 +173,16 @@ devlink dev eswitch set pci/0000:01:00.0 mode switchdev - Sets the eswitch mode of specified devlink device to switchdev. - .RE - .PP -+devlink dev param show pci/0000:01:00.0 name max_macs -+.RS 4 -+Shows the parameter max_macs attributes. -+.RE -+.PP -+devlink dev param set pci/0000:01:00.0 name internal_error_reset value true cmode runtime -+.RS 4 -+Sets the parameter internal_error_reset of specified devlink device to true. -+.RE -+.PP - devlink dev reload pci/0000:01:00.0 - .RS 4 - Performs hot reload of specified devlink device. --- -2.21.0 - diff --git a/SOURCES/0060-man-ip-route.8-ssthresh-parameter-is-NUMBER.patch b/SOURCES/0060-man-ip-route.8-ssthresh-parameter-is-NUMBER.patch deleted file mode 100644 index d2f9616..0000000 --- a/SOURCES/0060-man-ip-route.8-ssthresh-parameter-is-NUMBER.patch +++ /dev/null @@ -1,38 +0,0 @@ -From b6de96b49af2751003d67ed4edbf91fd25cee19c Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 25 Mar 2019 11:52:31 +0100 -Subject: [PATCH] man: ip-route.8: ssthresh parameter is NUMBER - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1593628 -Upstream Status: iproute2.git commit 79f49f58aaefe - -commit 79f49f58aaefe11f677c8e072557b834a19f47f3 -Author: Phil Sutter -Date: Thu Mar 22 15:00:38 2018 +0100 - - man: ip-route.8: ssthresh parameter is NUMBER - - Synopsis section was inconsistent with regards to help text and later - description of ssthresh parameter. - - Signed-off-by: Phil Sutter ---- - man/man8/ip-route.8.in | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/man/man8/ip-route.8.in b/man/man8/ip-route.8.in -index d9a547748c017..0616cf01740f3 100644 ---- a/man/man8/ip-route.8.in -+++ b/man/man8/ip-route.8.in -@@ -120,7 +120,7 @@ replace " } " - .B cwnd - .IR NUMBER " ] [ " - .B ssthresh --.IR REALM " ] [ " -+.IR NUMBER " ] [ " - .B realms - .IR REALM " ] [ " - .B rto_min --- -2.21.0 - diff --git a/SOURCES/0061-man-tc-vlan.8-Fix-for-incorrect-example.patch b/SOURCES/0061-man-tc-vlan.8-Fix-for-incorrect-example.patch deleted file mode 100644 index 52a94d4..0000000 --- a/SOURCES/0061-man-tc-vlan.8-Fix-for-incorrect-example.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 58fe50b2e23c1b77ed93d242545d0f274f819681 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 25 Mar 2019 11:57:41 +0100 -Subject: [PATCH] man: tc-vlan.8: Fix for incorrect example - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1593630 -Upstream Status: iproute2.git commit 8ee38d833ccb1 - -commit 8ee38d833ccb1863f06634e12c5236b0ef7c2d76 -Author: Phil Sutter -Date: Fri Mar 23 21:18:56 2018 +0100 - - man: tc-vlan.8: Fix for incorrect example - - This has to be a second match statement to the same u32 filter, not a - second one (which tc-filter doesn't support at all). - - Signed-off-by: Phil Sutter - Signed-off-by: Stephen Hemminger ---- - man/man8/tc-vlan.8 | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/man/man8/tc-vlan.8 b/man/man8/tc-vlan.8 -index af3de1c54e343..a526f66b60b4c 100644 ---- a/man/man8/tc-vlan.8 -+++ b/man/man8/tc-vlan.8 -@@ -103,7 +103,7 @@ into VLAN ID 123: - #tc qdisc add dev eth0 handle ffff: ingress - #tc filter add dev eth0 parent ffff: pref 11 protocol ip \\ - u32 match ip protocol 1 0xff flowid 1:1 \\ -- u32 match ip src 10.0.0.2 flowid 1:1 \\ -+ match ip src 10.0.0.2 flowid 1:1 \\ - action vlan push id 123 - .EE - .RE --- -2.21.0 - diff --git a/SOURCES/0062-tc-flower-Add-support-for-QinQ.patch b/SOURCES/0062-tc-flower-Add-support-for-QinQ.patch deleted file mode 100644 index a7fedc3..0000000 --- a/SOURCES/0062-tc-flower-Add-support-for-QinQ.patch +++ /dev/null @@ -1,274 +0,0 @@ -From dfbec1b67fc02a5af0d5cc30328b918902f20717 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 25 Mar 2019 12:19:05 +0100 -Subject: [PATCH] tc: flower: Add support for QinQ -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1642347 -Upstream Status: iproute2.git commit 1f0a5dfd388cd -Conflicts: context change due to missing commits - 7638ee13c1586 ("tc: flower: support for matching MPLS labels") - e28b88a464c49 ("tc: jsonify flower filter") - also adjust code to use fprintf instead of print_string due to - missing commit d0e720111aad2 ("ip: ipaddress.c: add support for json output") - -commit 1f0a5dfd388cd5c25f6a24247667e04b2346e568 -Author: Jianbo Liu -Date: Sat Jun 30 10:01:33 2018 +0000 - - tc: flower: Add support for QinQ - - To support matching on both outer and inner vlan headers, - we add new cvlan_id/cvlan_prio/cvlan_ethtype for inner vlan header. - - Example: - # tc filter add dev eth0 protocol 802.1ad parent ffff: \ - flower vlan_id 1000 vlan_ethtype 802.1q \ - cvlan_id 100 cvlan_ethtype ipv4 \ - action vlan pop \ - action vlan pop \ - action mirred egress redirect dev eth1 - - # tc filter show dev eth0 ingress - filter protocol 802.1ad pref 1 flower chain 0 - filter protocol 802.1ad pref 1 flower chain 0 handle 0x1 -   vlan_id 1000 -   vlan_ethtype 802.1Q -   cvlan_id 100 -   cvlan_ethtype ip -   eth_type ipv4 -   in_hw - - Signed-off-by: Jianbo Liu - Acked-by: Jiri Pirko - Signed-off-by: David Ahern ---- - man/man8/tc-flower.8 | 23 ++++++++++ - tc/f_flower.c | 99 ++++++++++++++++++++++++++++++++++++++------ - 2 files changed, 110 insertions(+), 12 deletions(-) - -diff --git a/man/man8/tc-flower.8 b/man/man8/tc-flower.8 -index af19708d9649e..387f73f5cd2e9 100644 ---- a/man/man8/tc-flower.8 -+++ b/man/man8/tc-flower.8 -@@ -29,6 +29,12 @@ flower \- flow based traffic control filter - .IR PRIORITY " | " - .BR vlan_ethtype " { " ipv4 " | " ipv6 " | " - .IR ETH_TYPE " } | " -+.B cvlan_id -+.IR VID " | " -+.B cvlan_prio -+.IR PRIORITY " | " -+.BR cvlan_ethtype " { " ipv4 " | " ipv6 " | " -+.IR ETH_TYPE " } | " - .BR ip_proto " { " tcp " | " udp " | " sctp " | " icmp " | " icmpv6 " | " - .IR IP_PROTO " } | " - .B ip_tos -@@ -121,6 +127,23 @@ Match on layer three protocol. - .I VLAN_ETH_TYPE - may be either - .BR ipv4 ", " ipv6 -+or an unsigned 16bit value in hexadecimal format. To match on QinQ packet, it must be 802.1Q or 802.1AD. -+.TP -+.BI cvlan_id " VID" -+Match on QinQ inner vlan tag id. -+.I VID -+is an unsigned 12bit value in decimal format. -+.TP -+.BI cvlan_prio " PRIORITY" -+Match on QinQ inner vlan tag priority. -+.I PRIORITY -+is an unsigned 3bit value in decimal format. -+.TP -+.BI cvlan_ethtype " VLAN_ETH_TYPE" -+Match on QinQ layer three protocol. -+.I VLAN_ETH_TYPE -+may be either -+.BR ipv4 ", " ipv6 - or an unsigned 16bit value in hexadecimal format. - .TP - .BI ip_proto " IP_PROTO" -diff --git a/tc/f_flower.c b/tc/f_flower.c -index 5f5236ca523f8..40dcfbd687a20 100644 ---- a/tc/f_flower.c -+++ b/tc/f_flower.c -@@ -50,6 +50,9 @@ static void explain(void) - " vlan_id VID |\n" - " vlan_prio PRIORITY |\n" - " vlan_ethtype [ ipv4 | ipv6 | ETH-TYPE ] |\n" -+ " cvlan_id VID |\n" -+ " cvlan_prio PRIORITY |\n" -+ " cvlan_ethtype [ ipv4 | ipv6 | ETH-TYPE ] |\n" - " dst_mac MASKED-LLADDR |\n" - " src_mac MASKED-LLADDR |\n" - " ip_proto [tcp | udp | sctp | icmp | icmpv6 | IP-PROTO ] |\n" -@@ -126,15 +129,21 @@ err: - return err; - } - -+static bool eth_type_vlan(__be16 ethertype) -+{ -+ return ethertype == htons(ETH_P_8021Q) || -+ ethertype == htons(ETH_P_8021AD); -+} -+ - static int flower_parse_vlan_eth_type(char *str, __be16 eth_type, int type, - __be16 *p_vlan_eth_type, - struct nlmsghdr *n) - { - __be16 vlan_eth_type; - -- if (eth_type != htons(ETH_P_8021Q)) { -- fprintf(stderr, -- "Can't set \"vlan_ethtype\" if ethertype isn't 802.1Q\n"); -+ if (!eth_type_vlan(eth_type)) { -+ fprintf(stderr, "Can't set \"%s\" if ethertype isn't 802.1Q or 802.1AD\n", -+ type == TCA_FLOWER_KEY_VLAN_ETH_TYPE ? "vlan_ethtype" : "cvlan_ethtype"); - return -1; - } - -@@ -583,6 +592,7 @@ static int flower_parse_opt(struct filter_util *qu, char *handle, - struct rtattr *tail; - __be16 eth_type = TC_H_MIN(t->tcm_info); - __be16 vlan_ethtype = 0; -+ __be16 cvlan_ethtype = 0; - __u8 ip_proto = 0xff; - __u32 flags = 0; - __u32 mtf = 0; -@@ -640,9 +650,8 @@ static int flower_parse_opt(struct filter_util *qu, char *handle, - __u16 vid; - - NEXT_ARG(); -- if (eth_type != htons(ETH_P_8021Q)) { -- fprintf(stderr, -- "Can't set \"vlan_id\" if ethertype isn't 802.1Q\n"); -+ if (!eth_type_vlan(eth_type)) { -+ fprintf(stderr, "Can't set \"vlan_id\" if ethertype isn't 802.1Q or 802.1AD\n"); - return -1; - } - ret = get_u16(&vid, *argv, 10); -@@ -655,9 +664,8 @@ static int flower_parse_opt(struct filter_util *qu, char *handle, - __u8 vlan_prio; - - NEXT_ARG(); -- if (eth_type != htons(ETH_P_8021Q)) { -- fprintf(stderr, -- "Can't set \"vlan_prio\" if ethertype isn't 802.1Q\n"); -+ if (!eth_type_vlan(eth_type)) { -+ fprintf(stderr, "Can't set \"vlan_prio\" if ethertype isn't 802.1Q or 802.1AD\n"); - return -1; - } - ret = get_u8(&vlan_prio, *argv, 10); -@@ -674,6 +682,42 @@ static int flower_parse_opt(struct filter_util *qu, char *handle, - &vlan_ethtype, n); - if (ret < 0) - return -1; -+ } else if (matches(*argv, "cvlan_id") == 0) { -+ __u16 vid; -+ -+ NEXT_ARG(); -+ if (!eth_type_vlan(vlan_ethtype)) { -+ fprintf(stderr, "Can't set \"cvlan_id\" if inner vlan ethertype isn't 802.1Q or 802.1AD\n"); -+ return -1; -+ } -+ ret = get_u16(&vid, *argv, 10); -+ if (ret < 0 || vid & ~0xfff) { -+ fprintf(stderr, "Illegal \"cvlan_id\"\n"); -+ return -1; -+ } -+ addattr16(n, MAX_MSG, TCA_FLOWER_KEY_CVLAN_ID, vid); -+ } else if (matches(*argv, "cvlan_prio") == 0) { -+ __u8 cvlan_prio; -+ -+ NEXT_ARG(); -+ if (!eth_type_vlan(vlan_ethtype)) { -+ fprintf(stderr, "Can't set \"cvlan_prio\" if inner vlan ethertype isn't 802.1Q or 802.1AD\n"); -+ return -1; -+ } -+ ret = get_u8(&cvlan_prio, *argv, 10); -+ if (ret < 0 || cvlan_prio & ~0x7) { -+ fprintf(stderr, "Illegal \"cvlan_prio\"\n"); -+ return -1; -+ } -+ addattr8(n, MAX_MSG, -+ TCA_FLOWER_KEY_CVLAN_PRIO, cvlan_prio); -+ } else if (matches(*argv, "cvlan_ethtype") == 0) { -+ NEXT_ARG(); -+ ret = flower_parse_vlan_eth_type(*argv, vlan_ethtype, -+ TCA_FLOWER_KEY_CVLAN_ETH_TYPE, -+ &cvlan_ethtype, n); -+ if (ret < 0) -+ return -1; - } else if (matches(*argv, "dst_mac") == 0) { - NEXT_ARG(); - ret = flower_parse_eth_addr(*argv, -@@ -696,7 +740,8 @@ static int flower_parse_opt(struct filter_util *qu, char *handle, - } - } else if (matches(*argv, "ip_proto") == 0) { - NEXT_ARG(); -- ret = flower_parse_ip_proto(*argv, vlan_ethtype ? -+ ret = flower_parse_ip_proto(*argv, cvlan_ethtype ? -+ cvlan_ethtype : vlan_ethtype ? - vlan_ethtype : eth_type, - TCA_FLOWER_KEY_IP_PROTO, - &ip_proto, n); -@@ -726,7 +771,8 @@ static int flower_parse_opt(struct filter_util *qu, char *handle, - } - } else if (matches(*argv, "dst_ip") == 0) { - NEXT_ARG(); -- ret = flower_parse_ip_addr(*argv, vlan_ethtype ? -+ ret = flower_parse_ip_addr(*argv, cvlan_ethtype ? -+ cvlan_ethtype : vlan_ethtype ? - vlan_ethtype : eth_type, - TCA_FLOWER_KEY_IPV4_DST, - TCA_FLOWER_KEY_IPV4_DST_MASK, -@@ -739,7 +785,8 @@ static int flower_parse_opt(struct filter_util *qu, char *handle, - } - } else if (matches(*argv, "src_ip") == 0) { - NEXT_ARG(); -- ret = flower_parse_ip_addr(*argv, vlan_ethtype ? -+ ret = flower_parse_ip_addr(*argv, cvlan_ethtype ? -+ cvlan_ethtype : vlan_ethtype ? - vlan_ethtype : eth_type, - TCA_FLOWER_KEY_IPV4_SRC, - TCA_FLOWER_KEY_IPV4_SRC_MASK, -@@ -1234,6 +1281,34 @@ static int flower_print_opt(struct filter_util *qu, FILE *f, - fprintf(f, "\n vlan_prio %d", rta_getattr_u8(attr)); - } - -+ if (tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE]) { -+ SPRINT_BUF(buf); -+ struct rtattr *attr = tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE]; -+ -+ fprintf(f, "\n vlan_ethtype %s", -+ ll_proto_n2a(rta_getattr_u16(attr), buf, sizeof(buf))); -+ } -+ -+ if (tb[TCA_FLOWER_KEY_CVLAN_ID]) { -+ struct rtattr *attr = tb[TCA_FLOWER_KEY_CVLAN_ID]; -+ -+ fprintf(f, "\n cvlan_id %u", rta_getattr_u16(attr)); -+ } -+ -+ if (tb[TCA_FLOWER_KEY_CVLAN_PRIO]) { -+ struct rtattr *attr = tb[TCA_FLOWER_KEY_CVLAN_PRIO]; -+ -+ fprintf(f, "\n cvlan_prio %d", rta_getattr_u8(attr)); -+ } -+ -+ if (tb[TCA_FLOWER_KEY_CVLAN_ETH_TYPE]) { -+ SPRINT_BUF(buf); -+ struct rtattr *attr = tb[TCA_FLOWER_KEY_CVLAN_ETH_TYPE]; -+ -+ fprintf(f, "\n cvlan_ethtype %s", -+ ll_proto_n2a(rta_getattr_u16(attr), buf, sizeof(buf))); -+ } -+ - flower_print_eth_addr(f, "dst_mac", tb[TCA_FLOWER_KEY_ETH_DST], - tb[TCA_FLOWER_KEY_ETH_DST_MASK]); - flower_print_eth_addr(f, "src_mac", tb[TCA_FLOWER_KEY_ETH_SRC], --- -2.21.0 - diff --git a/SOURCES/0063-utils-Move-BIT-macro-to-common-header.patch b/SOURCES/0063-utils-Move-BIT-macro-to-common-header.patch deleted file mode 100644 index 0e33f52..0000000 --- a/SOURCES/0063-utils-Move-BIT-macro-to-common-header.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 42a457a97118379936cdeb20eef1d116e858d4c1 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 25 Mar 2019 13:30:09 +0100 -Subject: [PATCH] utils: Move BIT macro to common header - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1642479 -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1641914 -Upstream Status: iproute2.git commit afdc119410efe - -commit afdc119410efe2a5e826c660446b1e4e1a72793d -Author: Leon Romanovsky -Date: Sun Aug 20 12:58:21 2017 +0300 - - utils: Move BIT macro to common header - - BIT() macro was implemented and used by devlink for now, but following - patches of rdmatool will reuse the same macro, so put it in common - header file. - - Signed-off-by: Leon Romanovsky ---- - devlink/devlink.c | 2 +- - include/utils.h | 2 ++ - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/devlink/devlink.c b/devlink/devlink.c -index 92e78c9c8d9f6..2000db81aabb0 100644 ---- a/devlink/devlink.c -+++ b/devlink/devlink.c -@@ -25,6 +25,7 @@ - #include "list.h" - #include "mnlg.h" - #include "json_writer.h" -+#include "utils.h" - - #define ESWITCH_MODE_LEGACY "legacy" - #define ESWITCH_MODE_SWITCHDEV "switchdev" -@@ -164,7 +165,6 @@ static void ifname_map_free(struct ifname_map *ifname_map) - free(ifname_map); - } - --#define BIT(nr) (1UL << (nr)) - #define DL_OPT_HANDLE BIT(0) - #define DL_OPT_HANDLEP BIT(1) - #define DL_OPT_PORT_TYPE BIT(2) -diff --git a/include/utils.h b/include/utils.h -index 8c12e1e2a60c2..d707a9dacdb85 100644 ---- a/include/utils.h -+++ b/include/utils.h -@@ -208,6 +208,8 @@ static inline void __jiffies_to_tv(struct timeval *tv, unsigned long jiffies) - int print_timestamp(FILE *fp); - void print_nlmsg_timestamp(FILE *fp, const struct nlmsghdr *n); - -+#define BIT(nr) (1UL << (nr)) -+ - #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - - #define BUILD_BUG_ON(cond) ((void)sizeof(char[1 - 2 * !!(cond)])) --- -2.21.0 - diff --git a/SOURCES/0064-lib-make-resolve_hosts-variable-common.patch b/SOURCES/0064-lib-make-resolve_hosts-variable-common.patch deleted file mode 100644 index 503773b..0000000 --- a/SOURCES/0064-lib-make-resolve_hosts-variable-common.patch +++ /dev/null @@ -1,137 +0,0 @@ -From c74a0bcb2e9c88b2ee166afc08574141a6a288b8 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 25 Mar 2019 13:30:43 +0100 -Subject: [PATCH] lib: make resolve_hosts variable common - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1642479 -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1641914 -Upstream Status: iproute2.git commit 6648853975332 - -commit 6648853975332e5f34d03a1e2a6e09f5e1742099 -Author: Ivan Vecera -Date: Fri Nov 10 07:20:13 2017 +0100 - - lib: make resolve_hosts variable common - - Any iproute utility that uses any function from lib/utils.c needs - to declare its own resolve_hosts variable instance although it does - not need/use hostname resolving functionality (currently only 'ip' - and 'ss' commands uses this). - The patch declares single common instance of resolve_hosts directly - in utils.c so the existing ones can be removed (the same approach - that is used for timestamp_short). - - Cc: Jiri Pirko - Cc: Arkadi Sharshevsky - Signed-off-by: Ivan Vecera ---- - bridge/bridge.c | 1 - - genl/genl.c | 1 - - ip/ip.c | 1 - - ip/rtmon.c | 1 - - lib/utils.c | 1 + - misc/arpd.c | 2 -- - misc/ss.c | 1 - - tc/tc.c | 1 - - 8 files changed, 1 insertion(+), 8 deletions(-) - -diff --git a/bridge/bridge.c b/bridge/bridge.c -index 5ff038d672ad2..6658cb8fd801d 100644 ---- a/bridge/bridge.c -+++ b/bridge/bridge.c -@@ -18,7 +18,6 @@ - - struct rtnl_handle rth = { .fd = -1 }; - int preferred_family = AF_UNSPEC; --int resolve_hosts; - int oneline; - int show_stats; - int show_details; -diff --git a/genl/genl.c b/genl/genl.c -index 747074b029a7b..7e4a208d449f2 100644 ---- a/genl/genl.c -+++ b/genl/genl.c -@@ -30,7 +30,6 @@ - int show_stats = 0; - int show_details = 0; - int show_raw = 0; --int resolve_hosts = 0; - - static void *BODY; - static struct genl_util * genl_list; -diff --git a/ip/ip.c b/ip/ip.c -index 07050b07592ac..0c0ad1bde7cb6 100644 ---- a/ip/ip.c -+++ b/ip/ip.c -@@ -30,7 +30,6 @@ int human_readable; - int use_iec; - int show_stats; - int show_details; --int resolve_hosts; - int oneline; - int brief; - int timestamp; -diff --git a/ip/rtmon.c b/ip/rtmon.c -index 1c2981f79d3d1..94baa38e3b7cb 100644 ---- a/ip/rtmon.c -+++ b/ip/rtmon.c -@@ -25,7 +25,6 @@ - #include "utils.h" - #include "libnetlink.h" - --int resolve_hosts; - static int init_phase = 1; - - static void write_stamp(FILE *fp) -diff --git a/lib/utils.c b/lib/utils.c -index 9f55391d3c1ea..fc9c575ba0c7d 100644 ---- a/lib/utils.c -+++ b/lib/utils.c -@@ -35,6 +35,7 @@ - #include "utils.h" - #include "namespace.h" - -+int resolve_hosts; - int timestamp_short; - - int get_hex(char c) -diff --git a/misc/arpd.c b/misc/arpd.c -index bfab44544ee1d..c9d86475e5995 100644 ---- a/misc/arpd.c -+++ b/misc/arpd.c -@@ -38,8 +38,6 @@ - #include "utils.h" - #include "rt_names.h" - --int resolve_hosts; -- - DB *dbase; - char *dbname = "/var/lib/arpd/arpd.db"; - -diff --git a/misc/ss.c b/misc/ss.c -index e92266539e6b5..c0cb33e96d9ec 100644 ---- a/misc/ss.c -+++ b/misc/ss.c -@@ -89,7 +89,6 @@ static int security_get_initial_context(char *name, char **context) - } - #endif - --int resolve_hosts; - int resolve_services = 1; - int preferred_family = AF_UNSPEC; - int show_options; -diff --git a/tc/tc.c b/tc/tc.c -index 360c9f11c235b..11a364fabbbea 100644 ---- a/tc/tc.c -+++ b/tc/tc.c -@@ -39,7 +39,6 @@ int show_graph; - int timestamp; - - int batch_mode; --int resolve_hosts; - int use_iec; - int force; - int ok; --- -2.21.0 - diff --git a/SOURCES/0065-json_writer-add-new-json-handlers-null-float-with-fo.patch b/SOURCES/0065-json_writer-add-new-json-handlers-null-float-with-fo.patch deleted file mode 100644 index 8cfc885..0000000 --- a/SOURCES/0065-json_writer-add-new-json-handlers-null-float-with-fo.patch +++ /dev/null @@ -1,161 +0,0 @@ -From b4b11394d071810d694b66962e8d48cb866af473 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 25 Mar 2019 13:30:53 +0100 -Subject: [PATCH] json_writer: add new json handlers (null, float with format, - lluint, hu) - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1642479 -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1641914 -Upstream Status: iproute2.git commit 7252f16b2d191 - -commit 7252f16b2d1919b31f0a2ec094dd3516b1e33a55 -Author: Julien Fortin -Date: Thu Aug 17 10:35:50 2017 -0700 - - json_writer: add new json handlers (null, float with format, lluint, hu) - - Signed-off-by: Julien Fortin ---- - include/json_writer.h | 9 +++++++++ - lib/json_writer.c | 44 +++++++++++++++++++++++++++++++++++++++---- - 2 files changed, 49 insertions(+), 4 deletions(-) - -diff --git a/include/json_writer.h b/include/json_writer.h -index ab9a008a67994..1516aafba59df 100644 ---- a/include/json_writer.h -+++ b/include/json_writer.h -@@ -33,20 +33,29 @@ void jsonw_pretty(json_writer_t *self, bool on); - void jsonw_name(json_writer_t *self, const char *name); - - /* Add value */ -+void jsonw_printf(json_writer_t *self, const char *fmt, ...); - void jsonw_string(json_writer_t *self, const char *value); - void jsonw_bool(json_writer_t *self, bool value); - void jsonw_float(json_writer_t *self, double number); -+void jsonw_float_fmt(json_writer_t *self, const char *fmt, double num); - void jsonw_uint(json_writer_t *self, uint64_t number); -+void jsonw_hu(json_writer_t *self, unsigned short number); - void jsonw_int(json_writer_t *self, int64_t number); - void jsonw_null(json_writer_t *self); -+void jsonw_lluint(json_writer_t *self, unsigned long long int num); - - /* Useful Combinations of name and value */ - void jsonw_string_field(json_writer_t *self, const char *prop, const char *val); - void jsonw_bool_field(json_writer_t *self, const char *prop, bool value); - void jsonw_float_field(json_writer_t *self, const char *prop, double num); - void jsonw_uint_field(json_writer_t *self, const char *prop, uint64_t num); -+void jsonw_hu_field(json_writer_t *self, const char *prop, unsigned short num); - void jsonw_int_field(json_writer_t *self, const char *prop, int64_t num); - void jsonw_null_field(json_writer_t *self, const char *prop); -+void jsonw_lluint_field(json_writer_t *self, const char *prop, -+ unsigned long long int num); -+void jsonw_float_field_fmt(json_writer_t *self, const char *prop, -+ const char *fmt, double val); - - /* Collections */ - void jsonw_start_object(json_writer_t *self); -diff --git a/lib/json_writer.c b/lib/json_writer.c -index 9fc05e96b605f..6b77d288cce2b 100644 ---- a/lib/json_writer.c -+++ b/lib/json_writer.c -@@ -156,7 +156,7 @@ void jsonw_name(json_writer_t *self, const char *name) - putc(' ', self->out); - } - --static void jsonw_printf(json_writer_t *self, const char *fmt, ...) -+void jsonw_printf(json_writer_t *self, const char *fmt, ...) - { - va_list ap; - -@@ -199,23 +199,38 @@ void jsonw_bool(json_writer_t *self, bool val) - jsonw_printf(self, "%s", val ? "true" : "false"); - } - --#ifdef notused - void jsonw_null(json_writer_t *self) - { - jsonw_printf(self, "null"); - } - -+void jsonw_float_fmt(json_writer_t *self, const char *fmt, double num) -+{ -+ jsonw_printf(self, fmt, num); -+} -+ -+#ifdef notused - void jsonw_float(json_writer_t *self, double num) - { - jsonw_printf(self, "%g", num); - } - #endif - -+void jsonw_hu(json_writer_t *self, unsigned short num) -+{ -+ jsonw_printf(self, "%hu", num); -+} -+ - void jsonw_uint(json_writer_t *self, uint64_t num) - { - jsonw_printf(self, "%"PRIu64, num); - } - -+void jsonw_lluint(json_writer_t *self, unsigned long long int num) -+{ -+ jsonw_printf(self, "%llu", num); -+} -+ - void jsonw_int(json_writer_t *self, int64_t num) - { - jsonw_printf(self, "%"PRId64, num); -@@ -242,25 +257,46 @@ void jsonw_float_field(json_writer_t *self, const char *prop, double val) - } - #endif - -+void jsonw_float_field_fmt(json_writer_t *self, -+ const char *prop, -+ const char *fmt, -+ double val) -+{ -+ jsonw_name(self, prop); -+ jsonw_float_fmt(self, fmt, val); -+} -+ - void jsonw_uint_field(json_writer_t *self, const char *prop, uint64_t num) - { - jsonw_name(self, prop); - jsonw_uint(self, num); - } - -+void jsonw_hu_field(json_writer_t *self, const char *prop, unsigned short num) -+{ -+ jsonw_name(self, prop); -+ jsonw_hu(self, num); -+} -+ -+void jsonw_lluint_field(json_writer_t *self, -+ const char *prop, -+ unsigned long long int num) -+{ -+ jsonw_name(self, prop); -+ jsonw_lluint(self, num); -+} -+ - void jsonw_int_field(json_writer_t *self, const char *prop, int64_t num) - { - jsonw_name(self, prop); - jsonw_int(self, num); - } - --#ifdef notused - void jsonw_null_field(json_writer_t *self, const char *prop) - { - jsonw_name(self, prop); - jsonw_null(self); - } --#endif - - #ifdef TEST - int main(int argc, char **argv) --- -2.21.0 - diff --git a/SOURCES/0066-rdma-Add-MR-resource-tracking-information.patch b/SOURCES/0066-rdma-Add-MR-resource-tracking-information.patch deleted file mode 100644 index 5b7f00f..0000000 --- a/SOURCES/0066-rdma-Add-MR-resource-tracking-information.patch +++ /dev/null @@ -1,90 +0,0 @@ -From a7f1b85b6838bdab705aef188bb0c86626bc3391 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 25 Mar 2019 13:31:02 +0100 -Subject: [PATCH] rdma: Add MR resource tracking information - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1642479 -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1641914 -Upstream Status: iproute2.git commit 8958a15c040e0 -Conflicts: remove rdma chunks due to missing files - -commit 8958a15c040e05f4f2c6f3946322202fdb875348 -Author: Steve Wise -Date: Thu Mar 29 09:10:41 2018 -0700 - - rdma: Add MR resource tracking information - - Sample output: - - Without CAP_NET_ADMIN: - - $ rdma resource show mr mrlen 65536 - dev mlx4_0 mrlen 65536 pid 0 comm [nvme_rdma] - dev cxgb4_0 mrlen 65536 pid 0 comm [nvme_rdma] - - With CAP_NET_ADMIN: - - # rdma resource show mr mrlen 65536 - dev mlx4_0 rkey 0x12702 lkey 0x12702 iova 0x85724a000 mrlen 65536 pid 0 comm [nvme_rdma] - dev cxgb4_0 rkey 0x68fe4e9 lkey 0x68fe4e9 iova 0x835b91000 mrlen 65536 pid 0 comm [nvme_rdma] - - Signed-off-by: Steve Wise - Reviewed-by: Leon Romanovsky - Signed-off-by: David Ahern ---- - include/json_writer.h | 2 ++ - lib/json_writer.c | 11 +++++++++++ - 2 files changed, 13 insertions(+) - -diff --git a/include/json_writer.h b/include/json_writer.h -index 1516aafba59df..34f2ccc2f5423 100644 ---- a/include/json_writer.h -+++ b/include/json_writer.h -@@ -39,6 +39,7 @@ void jsonw_bool(json_writer_t *self, bool value); - void jsonw_float(json_writer_t *self, double number); - void jsonw_float_fmt(json_writer_t *self, const char *fmt, double num); - void jsonw_uint(json_writer_t *self, uint64_t number); -+void jsonw_xint(json_writer_t *self, uint64_t number); - void jsonw_hu(json_writer_t *self, unsigned short number); - void jsonw_int(json_writer_t *self, int64_t number); - void jsonw_null(json_writer_t *self); -@@ -49,6 +50,7 @@ void jsonw_string_field(json_writer_t *self, const char *prop, const char *val); - void jsonw_bool_field(json_writer_t *self, const char *prop, bool value); - void jsonw_float_field(json_writer_t *self, const char *prop, double num); - void jsonw_uint_field(json_writer_t *self, const char *prop, uint64_t num); -+void jsonw_xint_field(json_writer_t *self, const char *prop, uint64_t num); - void jsonw_hu_field(json_writer_t *self, const char *prop, unsigned short num); - void jsonw_int_field(json_writer_t *self, const char *prop, int64_t num); - void jsonw_null_field(json_writer_t *self, const char *prop); -diff --git a/lib/json_writer.c b/lib/json_writer.c -index 6b77d288cce2b..6aaa6b4170711 100644 ---- a/lib/json_writer.c -+++ b/lib/json_writer.c -@@ -226,6 +226,11 @@ void jsonw_uint(json_writer_t *self, uint64_t num) - jsonw_printf(self, "%"PRIu64, num); - } - -+void jsonw_xint(json_writer_t *self, uint64_t num) -+{ -+ jsonw_printf(self, "%"PRIx64, num); -+} -+ - void jsonw_lluint(json_writer_t *self, unsigned long long int num) - { - jsonw_printf(self, "%llu", num); -@@ -272,6 +277,12 @@ void jsonw_uint_field(json_writer_t *self, const char *prop, uint64_t num) - jsonw_uint(self, num); - } - -+void jsonw_xint_field(json_writer_t *self, const char *prop, uint64_t num) -+{ -+ jsonw_name(self, prop); -+ jsonw_xint(self, num); -+} -+ - void jsonw_hu_field(json_writer_t *self, const char *prop, unsigned short num) - { - jsonw_name(self, prop); --- -2.21.0 - diff --git a/SOURCES/0067-rdma-add-infrastructure-for-RDMA-tool.patch b/SOURCES/0067-rdma-add-infrastructure-for-RDMA-tool.patch deleted file mode 100644 index 880a108..0000000 --- a/SOURCES/0067-rdma-add-infrastructure-for-RDMA-tool.patch +++ /dev/null @@ -1,5287 +0,0 @@ -From 6ca04b58fcbaeaa5c8848e77ae0cfcf8b5f4c9ab Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 25 Mar 2019 13:31:34 +0100 -Subject: [PATCH] rdma: add infrastructure for RDMA tool - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1642479 -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1641914 -Upstream Status: RHEL-only - -commit de87313c8cd0399fd803fcaa8dfaa4aa27912f79 -Author: Andrea Claudi -Date: Thu Mar 21 17:24:12 2019 +0100 - - rdma: add infrastructure for RDMA tool - - Checkout to the v5.0.0 upstream tag. - - Conflicts: - - add rdma on base Makefile - - fix config path and libmnl cflags and libs on rdma/Makefile - - Signed-off-by: Andrea Claudi ---- - Makefile | 2 +- - rdma/.gitignore | 1 + - rdma/Makefile | 27 + - rdma/dev.c | 312 ++++++ - rdma/include/uapi/rdma/ib_user_sa.h | 77 ++ - rdma/include/uapi/rdma/ib_user_verbs.h | 1302 ++++++++++++++++++++++++ - rdma/include/uapi/rdma/rdma_netlink.h | 438 ++++++++ - rdma/include/uapi/rdma/rdma_user_cm.h | 324 ++++++ - rdma/link.c | 355 +++++++ - rdma/rdma.c | 203 ++++ - rdma/rdma.h | 131 +++ - rdma/res.c | 1111 ++++++++++++++++++++ - rdma/utils.c | 868 ++++++++++++++++ - 13 files changed, 5150 insertions(+), 1 deletion(-) - create mode 100644 rdma/.gitignore - create mode 100644 rdma/Makefile - create mode 100644 rdma/dev.c - create mode 100644 rdma/include/uapi/rdma/ib_user_sa.h - create mode 100644 rdma/include/uapi/rdma/ib_user_verbs.h - create mode 100644 rdma/include/uapi/rdma/rdma_netlink.h - create mode 100644 rdma/include/uapi/rdma/rdma_user_cm.h - create mode 100644 rdma/link.c - create mode 100644 rdma/rdma.c - create mode 100644 rdma/rdma.h - create mode 100644 rdma/res.c - create mode 100644 rdma/utils.c - -diff --git a/Makefile b/Makefile -index df2fa33630e65..aea12423166cd 100644 ---- a/Makefile -+++ b/Makefile -@@ -52,7 +52,7 @@ WFLAGS += -Wmissing-declarations -Wold-style-definition -Wformat=2 - CFLAGS := $(WFLAGS) $(CCOPTS) -I../include -I../include/uapi $(DEFINES) $(CFLAGS) - YACCFLAGS = -d -t -v - --SUBDIRS=lib ip tc bridge misc netem genl tipc devlink man -+SUBDIRS=lib ip tc bridge misc netem genl tipc devlink rdma man - - LIBNETLINK=../lib/libnetlink.a ../lib/libutil.a - LDLIBS += $(LIBNETLINK) -diff --git a/rdma/.gitignore b/rdma/.gitignore -new file mode 100644 -index 0000000000000..51fb172baa216 ---- /dev/null -+++ b/rdma/.gitignore -@@ -0,0 +1 @@ -+rdma -diff --git a/rdma/Makefile b/rdma/Makefile -new file mode 100644 -index 0000000000000..0830c82f77edb ---- /dev/null -+++ b/rdma/Makefile -@@ -0,0 +1,27 @@ -+# SPDX-License-Identifier: GPL-2.0 -+include ../Config -+ -+TARGETS := -+ -+ifeq ($(HAVE_MNL),y) -+CFLAGS += -I./include/uapi/ -+CFLAGS += $(shell $(PKG_CONFIG) libmnl --cflags) -+LDLIBS += $(shell $(PKG_CONFIG) libmnl --libs) -+ -+RDMA_OBJ = rdma.o utils.o dev.o link.o res.o -+ -+TARGETS += rdma -+endif -+ -+all: $(TARGETS) $(LIBS) -+ -+rdma: $(RDMA_OBJ) $(LIBS) -+ $(QUIET_LINK)$(CC) $^ $(LDFLAGS) $(LDLIBS) -o $@ -+ -+install: all -+ for i in $(TARGETS); \ -+ do install -m 0755 $$i $(DESTDIR)$(SBINDIR); \ -+ done -+ -+clean: -+ rm -f $(RDMA_OBJ) $(TARGETS) -diff --git a/rdma/dev.c b/rdma/dev.c -new file mode 100644 -index 0000000000000..60ff4b31e3204 ---- /dev/null -+++ b/rdma/dev.c -@@ -0,0 +1,312 @@ -+/* -+ * dev.c RDMA tool -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ * -+ * Authors: Leon Romanovsky -+ */ -+ -+#include "rdma.h" -+ -+static int dev_help(struct rd *rd) -+{ -+ pr_out("Usage: %s dev show [DEV]\n", rd->filename); -+ pr_out(" %s dev set [DEV] name DEVNAME\n", rd->filename); -+ return 0; -+} -+ -+static const char *dev_caps_to_str(uint32_t idx) -+{ -+#define RDMA_DEV_FLAGS_LOW(x) \ -+ x(RESIZE_MAX_WR, 0) \ -+ x(BAD_PKEY_CNTR, 1) \ -+ x(BAD_QKEY_CNTR, 2) \ -+ x(RAW_MULTI, 3) \ -+ x(AUTO_PATH_MIG, 4) \ -+ x(CHANGE_PHY_PORT, 5) \ -+ x(UD_AV_PORT_ENFORCE_PORT_ENFORCE, 6) \ -+ x(CURR_QP_STATE_MOD, 7) \ -+ x(SHUTDOWN_PORT, 8) \ -+ x(INIT_TYPE, 9) \ -+ x(PORT_ACTIVE_EVENT, 10) \ -+ x(SYS_IMAGE_GUID, 11) \ -+ x(RC_RNR_NAK_GEN, 12) \ -+ x(SRQ_RESIZE, 13) \ -+ x(N_NOTIFY_CQ, 14) \ -+ x(LOCAL_DMA_LKEY, 15) \ -+ x(MEM_WINDOW, 17) \ -+ x(UD_IP_CSUM, 18) \ -+ x(UD_TSO, 19) \ -+ x(XRC, 20) \ -+ x(MEM_MGT_EXTENSIONS, 21) \ -+ x(BLOCK_MULTICAST_LOOPBACK, 22) \ -+ x(MEM_WINDOW_TYPE_2A, 23) \ -+ x(MEM_WINDOW_TYPE_2B, 24) \ -+ x(RC_IP_CSUM, 25) \ -+ x(RAW_IP_CSUM, 26) \ -+ x(CROSS_CHANNEL, 27) \ -+ x(MANAGED_FLOW_STEERING, 29) \ -+ x(SIGNATURE_HANDOVER, 30) \ -+ x(ON_DEMAND_PAGING, 31) -+ -+#define RDMA_DEV_FLAGS_HIGH(x) \ -+ x(SG_GAPS_REG, 0) \ -+ x(VIRTUAL_FUNCTION, 1) \ -+ x(RAW_SCATTER_FCS, 2) \ -+ x(RDMA_NETDEV_OPA_VNIC, 3) \ -+ x(PCI_WRITE_END_PADDING, 4) -+ -+ /* -+ * Separation below is needed to allow compilation of rdmatool -+ * on 32bits systems. On such systems, C-enum is limited to be -+ * int and can't hold more than 32 bits. -+ */ -+ enum { RDMA_DEV_FLAGS_LOW(RDMA_BITMAP_ENUM) }; -+ enum { RDMA_DEV_FLAGS_HIGH(RDMA_BITMAP_ENUM) }; -+ -+ static const char * const -+ rdma_dev_names_low[] = { RDMA_DEV_FLAGS_LOW(RDMA_BITMAP_NAMES) }; -+ static const char * const -+ rdma_dev_names_high[] = { RDMA_DEV_FLAGS_HIGH(RDMA_BITMAP_NAMES) }; -+ uint32_t high_idx; -+ #undef RDMA_DEV_FLAGS_LOW -+ #undef RDMA_DEV_FLAGS_HIGH -+ -+ if (idx < ARRAY_SIZE(rdma_dev_names_low) && rdma_dev_names_low[idx]) -+ return rdma_dev_names_low[idx]; -+ -+ high_idx = idx - ARRAY_SIZE(rdma_dev_names_low); -+ if (high_idx < ARRAY_SIZE(rdma_dev_names_high) && -+ rdma_dev_names_high[high_idx]) -+ return rdma_dev_names_high[high_idx]; -+ -+ return "UNKNOWN"; -+} -+ -+static void dev_print_caps(struct rd *rd, struct nlattr **tb) -+{ -+ uint64_t caps; -+ uint32_t idx; -+ -+ if (!tb[RDMA_NLDEV_ATTR_CAP_FLAGS]) -+ return; -+ -+ caps = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_CAP_FLAGS]); -+ -+ if (rd->json_output) { -+ jsonw_name(rd->jw, "caps"); -+ jsonw_start_array(rd->jw); -+ } else { -+ pr_out("\n caps: <"); -+ } -+ for (idx = 0; caps; idx++) { -+ if (caps & 0x1) { -+ if (rd->json_output) { -+ jsonw_string(rd->jw, dev_caps_to_str(idx)); -+ } else { -+ pr_out("%s", dev_caps_to_str(idx)); -+ if (caps >> 0x1) -+ pr_out(", "); -+ } -+ } -+ caps >>= 0x1; -+ } -+ -+ if (rd->json_output) -+ jsonw_end_array(rd->jw); -+ else -+ pr_out(">"); -+} -+ -+static void dev_print_fw(struct rd *rd, struct nlattr **tb) -+{ -+ const char *str; -+ if (!tb[RDMA_NLDEV_ATTR_FW_VERSION]) -+ return; -+ -+ str = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_FW_VERSION]); -+ if (rd->json_output) -+ jsonw_string_field(rd->jw, "fw", str); -+ else -+ pr_out("fw %s ", str); -+} -+ -+static void dev_print_node_guid(struct rd *rd, struct nlattr **tb) -+{ -+ uint64_t node_guid; -+ uint16_t vp[4]; -+ char str[32]; -+ -+ if (!tb[RDMA_NLDEV_ATTR_NODE_GUID]) -+ return; -+ -+ node_guid = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_NODE_GUID]); -+ memcpy(vp, &node_guid, sizeof(uint64_t)); -+ snprintf(str, 32, "%04x:%04x:%04x:%04x", vp[3], vp[2], vp[1], vp[0]); -+ if (rd->json_output) -+ jsonw_string_field(rd->jw, "node_guid", str); -+ else -+ pr_out("node_guid %s ", str); -+} -+ -+static void dev_print_sys_image_guid(struct rd *rd, struct nlattr **tb) -+{ -+ uint64_t sys_image_guid; -+ uint16_t vp[4]; -+ char str[32]; -+ -+ if (!tb[RDMA_NLDEV_ATTR_SYS_IMAGE_GUID]) -+ return; -+ -+ sys_image_guid = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_SYS_IMAGE_GUID]); -+ memcpy(vp, &sys_image_guid, sizeof(uint64_t)); -+ snprintf(str, 32, "%04x:%04x:%04x:%04x", vp[3], vp[2], vp[1], vp[0]); -+ if (rd->json_output) -+ jsonw_string_field(rd->jw, "sys_image_guid", str); -+ else -+ pr_out("sys_image_guid %s ", str); -+} -+ -+static const char *node_type_to_str(uint8_t node_type) -+{ -+ static const char * const node_type_str[] = { "unknown", "ca", -+ "switch", "router", -+ "rnic", "usnic", -+ "usnic_dp" }; -+ if (node_type < ARRAY_SIZE(node_type_str)) -+ return node_type_str[node_type]; -+ return "unknown"; -+} -+ -+static void dev_print_node_type(struct rd *rd, struct nlattr **tb) -+{ -+ const char *node_str; -+ uint8_t node_type; -+ -+ if (!tb[RDMA_NLDEV_ATTR_DEV_NODE_TYPE]) -+ return; -+ -+ node_type = mnl_attr_get_u8(tb[RDMA_NLDEV_ATTR_DEV_NODE_TYPE]); -+ node_str = node_type_to_str(node_type); -+ if (rd->json_output) -+ jsonw_string_field(rd->jw, "node_type", node_str); -+ else -+ pr_out("node_type %s ", node_str); -+} -+ -+static int dev_parse_cb(const struct nlmsghdr *nlh, void *data) -+{ -+ struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {}; -+ struct rd *rd = data; -+ const char *name; -+ uint32_t idx; -+ -+ mnl_attr_parse(nlh, 0, rd_attr_cb, tb); -+ if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME]) -+ return MNL_CB_ERROR; -+ -+ idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]); -+ name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]); -+ if (rd->json_output) { -+ jsonw_uint_field(rd->jw, "ifindex", idx); -+ jsonw_string_field(rd->jw, "ifname", name); -+ } else { -+ pr_out("%u: %s: ", idx, name); -+ } -+ -+ dev_print_node_type(rd, tb); -+ dev_print_fw(rd, tb); -+ dev_print_node_guid(rd, tb); -+ dev_print_sys_image_guid(rd, tb); -+ if (rd->show_details) -+ dev_print_caps(rd, tb); -+ -+ if (!rd->json_output) -+ pr_out("\n"); -+ return MNL_CB_OK; -+} -+ -+static int dev_no_args(struct rd *rd) -+{ -+ uint32_t seq; -+ int ret; -+ -+ rd_prepare_msg(rd, RDMA_NLDEV_CMD_GET, -+ &seq, (NLM_F_REQUEST | NLM_F_ACK)); -+ mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx); -+ ret = rd_send_msg(rd); -+ if (ret) -+ return ret; -+ -+ if (rd->json_output) -+ jsonw_start_object(rd->jw); -+ ret = rd_recv_msg(rd, dev_parse_cb, rd, seq); -+ if (rd->json_output) -+ jsonw_end_object(rd->jw); -+ return ret; -+} -+ -+static int dev_one_show(struct rd *rd) -+{ -+ const struct rd_cmd cmds[] = { -+ { NULL, dev_no_args}, -+ { 0 } -+ }; -+ -+ return rd_exec_cmd(rd, cmds, "parameter"); -+} -+ -+static int dev_set_name(struct rd *rd) -+{ -+ uint32_t seq; -+ -+ if (rd_no_arg(rd)) { -+ pr_err("Please provide device new name.\n"); -+ return -EINVAL; -+ } -+ -+ rd_prepare_msg(rd, RDMA_NLDEV_CMD_SET, -+ &seq, (NLM_F_REQUEST | NLM_F_ACK)); -+ mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx); -+ mnl_attr_put_strz(rd->nlh, RDMA_NLDEV_ATTR_DEV_NAME, rd_argv(rd)); -+ -+ return rd_send_msg(rd); -+} -+ -+static int dev_one_set(struct rd *rd) -+{ -+ const struct rd_cmd cmds[] = { -+ { NULL, dev_help}, -+ { "name", dev_set_name}, -+ { 0 } -+ }; -+ -+ return rd_exec_cmd(rd, cmds, "parameter"); -+} -+ -+static int dev_show(struct rd *rd) -+{ -+ return rd_exec_dev(rd, dev_one_show); -+} -+ -+static int dev_set(struct rd *rd) -+{ -+ return rd_exec_require_dev(rd, dev_one_set); -+} -+ -+int cmd_dev(struct rd *rd) -+{ -+ const struct rd_cmd cmds[] = { -+ { NULL, dev_show }, -+ { "show", dev_show }, -+ { "list", dev_show }, -+ { "set", dev_set }, -+ { "help", dev_help }, -+ { 0 } -+ }; -+ -+ return rd_exec_cmd(rd, cmds, "dev command"); -+} -diff --git a/rdma/include/uapi/rdma/ib_user_sa.h b/rdma/include/uapi/rdma/ib_user_sa.h -new file mode 100644 -index 0000000000000..435155d6e1c6a ---- /dev/null -+++ b/rdma/include/uapi/rdma/ib_user_sa.h -@@ -0,0 +1,77 @@ -+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ -+/* -+ * Copyright (c) 2005 Intel Corporation. All rights reserved. -+ * -+ * This software is available to you under a choice of one of two -+ * licenses. You may choose to be licensed under the terms of the GNU -+ * General Public License (GPL) Version 2, available from the file -+ * COPYING in the main directory of this source tree, or the -+ * OpenIB.org BSD license below: -+ * -+ * Redistribution and use in source and binary forms, with or -+ * without modification, are permitted provided that the following -+ * conditions are met: -+ * -+ * - Redistributions of source code must retain the above -+ * copyright notice, this list of conditions and the following -+ * disclaimer. -+ * -+ * - Redistributions in binary form must reproduce the above -+ * copyright notice, this list of conditions and the following -+ * disclaimer in the documentation and/or other materials -+ * provided with the distribution. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -+ * SOFTWARE. -+ */ -+ -+#ifndef IB_USER_SA_H -+#define IB_USER_SA_H -+ -+#include -+ -+enum { -+ IB_PATH_GMP = 1, -+ IB_PATH_PRIMARY = (1<<1), -+ IB_PATH_ALTERNATE = (1<<2), -+ IB_PATH_OUTBOUND = (1<<3), -+ IB_PATH_INBOUND = (1<<4), -+ IB_PATH_INBOUND_REVERSE = (1<<5), -+ IB_PATH_BIDIRECTIONAL = IB_PATH_OUTBOUND | IB_PATH_INBOUND_REVERSE -+}; -+ -+struct ib_path_rec_data { -+ __u32 flags; -+ __u32 reserved; -+ __u32 path_rec[16]; -+}; -+ -+struct ib_user_path_rec { -+ __u8 dgid[16]; -+ __u8 sgid[16]; -+ __be16 dlid; -+ __be16 slid; -+ __u32 raw_traffic; -+ __be32 flow_label; -+ __u32 reversible; -+ __u32 mtu; -+ __be16 pkey; -+ __u8 hop_limit; -+ __u8 traffic_class; -+ __u8 numb_path; -+ __u8 sl; -+ __u8 mtu_selector; -+ __u8 rate_selector; -+ __u8 rate; -+ __u8 packet_life_time_selector; -+ __u8 packet_life_time; -+ __u8 preference; -+}; -+ -+#endif /* IB_USER_SA_H */ -diff --git a/rdma/include/uapi/rdma/ib_user_verbs.h b/rdma/include/uapi/rdma/ib_user_verbs.h -new file mode 100644 -index 0000000000000..480d9a60b68e4 ---- /dev/null -+++ b/rdma/include/uapi/rdma/ib_user_verbs.h -@@ -0,0 +1,1302 @@ -+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ -+/* -+ * Copyright (c) 2005 Topspin Communications. All rights reserved. -+ * Copyright (c) 2005, 2006 Cisco Systems. All rights reserved. -+ * Copyright (c) 2005 PathScale, Inc. All rights reserved. -+ * Copyright (c) 2006 Mellanox Technologies. All rights reserved. -+ * -+ * This software is available to you under a choice of one of two -+ * licenses. You may choose to be licensed under the terms of the GNU -+ * General Public License (GPL) Version 2, available from the file -+ * COPYING in the main directory of this source tree, or the -+ * OpenIB.org BSD license below: -+ * -+ * Redistribution and use in source and binary forms, with or -+ * without modification, are permitted provided that the following -+ * conditions are met: -+ * -+ * - Redistributions of source code must retain the above -+ * copyright notice, this list of conditions and the following -+ * disclaimer. -+ * -+ * - Redistributions in binary form must reproduce the above -+ * copyright notice, this list of conditions and the following -+ * disclaimer in the documentation and/or other materials -+ * provided with the distribution. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -+ * SOFTWARE. -+ */ -+ -+#ifndef IB_USER_VERBS_H -+#define IB_USER_VERBS_H -+ -+#include -+ -+/* -+ * Increment this value if any changes that break userspace ABI -+ * compatibility are made. -+ */ -+#define IB_USER_VERBS_ABI_VERSION 6 -+#define IB_USER_VERBS_CMD_THRESHOLD 50 -+ -+enum ib_uverbs_write_cmds { -+ IB_USER_VERBS_CMD_GET_CONTEXT, -+ IB_USER_VERBS_CMD_QUERY_DEVICE, -+ IB_USER_VERBS_CMD_QUERY_PORT, -+ IB_USER_VERBS_CMD_ALLOC_PD, -+ IB_USER_VERBS_CMD_DEALLOC_PD, -+ IB_USER_VERBS_CMD_CREATE_AH, -+ IB_USER_VERBS_CMD_MODIFY_AH, -+ IB_USER_VERBS_CMD_QUERY_AH, -+ IB_USER_VERBS_CMD_DESTROY_AH, -+ IB_USER_VERBS_CMD_REG_MR, -+ IB_USER_VERBS_CMD_REG_SMR, -+ IB_USER_VERBS_CMD_REREG_MR, -+ IB_USER_VERBS_CMD_QUERY_MR, -+ IB_USER_VERBS_CMD_DEREG_MR, -+ IB_USER_VERBS_CMD_ALLOC_MW, -+ IB_USER_VERBS_CMD_BIND_MW, -+ IB_USER_VERBS_CMD_DEALLOC_MW, -+ IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL, -+ IB_USER_VERBS_CMD_CREATE_CQ, -+ IB_USER_VERBS_CMD_RESIZE_CQ, -+ IB_USER_VERBS_CMD_DESTROY_CQ, -+ IB_USER_VERBS_CMD_POLL_CQ, -+ IB_USER_VERBS_CMD_PEEK_CQ, -+ IB_USER_VERBS_CMD_REQ_NOTIFY_CQ, -+ IB_USER_VERBS_CMD_CREATE_QP, -+ IB_USER_VERBS_CMD_QUERY_QP, -+ IB_USER_VERBS_CMD_MODIFY_QP, -+ IB_USER_VERBS_CMD_DESTROY_QP, -+ IB_USER_VERBS_CMD_POST_SEND, -+ IB_USER_VERBS_CMD_POST_RECV, -+ IB_USER_VERBS_CMD_ATTACH_MCAST, -+ IB_USER_VERBS_CMD_DETACH_MCAST, -+ IB_USER_VERBS_CMD_CREATE_SRQ, -+ IB_USER_VERBS_CMD_MODIFY_SRQ, -+ IB_USER_VERBS_CMD_QUERY_SRQ, -+ IB_USER_VERBS_CMD_DESTROY_SRQ, -+ IB_USER_VERBS_CMD_POST_SRQ_RECV, -+ IB_USER_VERBS_CMD_OPEN_XRCD, -+ IB_USER_VERBS_CMD_CLOSE_XRCD, -+ IB_USER_VERBS_CMD_CREATE_XSRQ, -+ IB_USER_VERBS_CMD_OPEN_QP, -+}; -+ -+enum { -+ IB_USER_VERBS_EX_CMD_QUERY_DEVICE = IB_USER_VERBS_CMD_QUERY_DEVICE, -+ IB_USER_VERBS_EX_CMD_CREATE_CQ = IB_USER_VERBS_CMD_CREATE_CQ, -+ IB_USER_VERBS_EX_CMD_CREATE_QP = IB_USER_VERBS_CMD_CREATE_QP, -+ IB_USER_VERBS_EX_CMD_MODIFY_QP = IB_USER_VERBS_CMD_MODIFY_QP, -+ IB_USER_VERBS_EX_CMD_CREATE_FLOW = IB_USER_VERBS_CMD_THRESHOLD, -+ IB_USER_VERBS_EX_CMD_DESTROY_FLOW, -+ IB_USER_VERBS_EX_CMD_CREATE_WQ, -+ IB_USER_VERBS_EX_CMD_MODIFY_WQ, -+ IB_USER_VERBS_EX_CMD_DESTROY_WQ, -+ IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL, -+ IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL, -+ IB_USER_VERBS_EX_CMD_MODIFY_CQ -+}; -+ -+/* -+ * Make sure that all structs defined in this file remain laid out so -+ * that they pack the same way on 32-bit and 64-bit architectures (to -+ * avoid incompatibility between 32-bit userspace and 64-bit kernels). -+ * Specifically: -+ * - Do not use pointer types -- pass pointers in __u64 instead. -+ * - Make sure that any structure larger than 4 bytes is padded to a -+ * multiple of 8 bytes. Otherwise the structure size will be -+ * different between 32-bit and 64-bit architectures. -+ */ -+ -+struct ib_uverbs_async_event_desc { -+ __aligned_u64 element; -+ __u32 event_type; /* enum ib_event_type */ -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_comp_event_desc { -+ __aligned_u64 cq_handle; -+}; -+ -+struct ib_uverbs_cq_moderation_caps { -+ __u16 max_cq_moderation_count; -+ __u16 max_cq_moderation_period; -+ __u32 reserved; -+}; -+ -+/* -+ * All commands from userspace should start with a __u32 command field -+ * followed by __u16 in_words and out_words fields (which give the -+ * length of the command block and response buffer if any in 32-bit -+ * words). The kernel driver will read these fields first and read -+ * the rest of the command struct based on these value. -+ */ -+ -+#define IB_USER_VERBS_CMD_COMMAND_MASK 0xff -+#define IB_USER_VERBS_CMD_FLAG_EXTENDED 0x80000000u -+ -+struct ib_uverbs_cmd_hdr { -+ __u32 command; -+ __u16 in_words; -+ __u16 out_words; -+}; -+ -+struct ib_uverbs_ex_cmd_hdr { -+ __aligned_u64 response; -+ __u16 provider_in_words; -+ __u16 provider_out_words; -+ __u32 cmd_hdr_reserved; -+}; -+ -+struct ib_uverbs_get_context { -+ __aligned_u64 response; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_get_context_resp { -+ __u32 async_fd; -+ __u32 num_comp_vectors; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_query_device { -+ __aligned_u64 response; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_query_device_resp { -+ __aligned_u64 fw_ver; -+ __be64 node_guid; -+ __be64 sys_image_guid; -+ __aligned_u64 max_mr_size; -+ __aligned_u64 page_size_cap; -+ __u32 vendor_id; -+ __u32 vendor_part_id; -+ __u32 hw_ver; -+ __u32 max_qp; -+ __u32 max_qp_wr; -+ __u32 device_cap_flags; -+ __u32 max_sge; -+ __u32 max_sge_rd; -+ __u32 max_cq; -+ __u32 max_cqe; -+ __u32 max_mr; -+ __u32 max_pd; -+ __u32 max_qp_rd_atom; -+ __u32 max_ee_rd_atom; -+ __u32 max_res_rd_atom; -+ __u32 max_qp_init_rd_atom; -+ __u32 max_ee_init_rd_atom; -+ __u32 atomic_cap; -+ __u32 max_ee; -+ __u32 max_rdd; -+ __u32 max_mw; -+ __u32 max_raw_ipv6_qp; -+ __u32 max_raw_ethy_qp; -+ __u32 max_mcast_grp; -+ __u32 max_mcast_qp_attach; -+ __u32 max_total_mcast_qp_attach; -+ __u32 max_ah; -+ __u32 max_fmr; -+ __u32 max_map_per_fmr; -+ __u32 max_srq; -+ __u32 max_srq_wr; -+ __u32 max_srq_sge; -+ __u16 max_pkeys; -+ __u8 local_ca_ack_delay; -+ __u8 phys_port_cnt; -+ __u8 reserved[4]; -+}; -+ -+struct ib_uverbs_ex_query_device { -+ __u32 comp_mask; -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_odp_caps { -+ __aligned_u64 general_caps; -+ struct { -+ __u32 rc_odp_caps; -+ __u32 uc_odp_caps; -+ __u32 ud_odp_caps; -+ } per_transport_caps; -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_rss_caps { -+ /* Corresponding bit will be set if qp type from -+ * 'enum ib_qp_type' is supported, e.g. -+ * supported_qpts |= 1 << IB_QPT_UD -+ */ -+ __u32 supported_qpts; -+ __u32 max_rwq_indirection_tables; -+ __u32 max_rwq_indirection_table_size; -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_tm_caps { -+ /* Max size of rendezvous request message */ -+ __u32 max_rndv_hdr_size; -+ /* Max number of entries in tag matching list */ -+ __u32 max_num_tags; -+ /* TM flags */ -+ __u32 flags; -+ /* Max number of outstanding list operations */ -+ __u32 max_ops; -+ /* Max number of SGE in tag matching entry */ -+ __u32 max_sge; -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_ex_query_device_resp { -+ struct ib_uverbs_query_device_resp base; -+ __u32 comp_mask; -+ __u32 response_length; -+ struct ib_uverbs_odp_caps odp_caps; -+ __aligned_u64 timestamp_mask; -+ __aligned_u64 hca_core_clock; /* in KHZ */ -+ __aligned_u64 device_cap_flags_ex; -+ struct ib_uverbs_rss_caps rss_caps; -+ __u32 max_wq_type_rq; -+ __u32 raw_packet_caps; -+ struct ib_uverbs_tm_caps tm_caps; -+ struct ib_uverbs_cq_moderation_caps cq_moderation_caps; -+ __aligned_u64 max_dm_size; -+}; -+ -+struct ib_uverbs_query_port { -+ __aligned_u64 response; -+ __u8 port_num; -+ __u8 reserved[7]; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_query_port_resp { -+ __u32 port_cap_flags; /* see ib_uverbs_query_port_cap_flags */ -+ __u32 max_msg_sz; -+ __u32 bad_pkey_cntr; -+ __u32 qkey_viol_cntr; -+ __u32 gid_tbl_len; -+ __u16 pkey_tbl_len; -+ __u16 lid; -+ __u16 sm_lid; -+ __u8 state; -+ __u8 max_mtu; -+ __u8 active_mtu; -+ __u8 lmc; -+ __u8 max_vl_num; -+ __u8 sm_sl; -+ __u8 subnet_timeout; -+ __u8 init_type_reply; -+ __u8 active_width; -+ __u8 active_speed; -+ __u8 phys_state; -+ __u8 link_layer; -+ __u8 flags; /* see ib_uverbs_query_port_flags */ -+ __u8 reserved; -+}; -+ -+struct ib_uverbs_alloc_pd { -+ __aligned_u64 response; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_alloc_pd_resp { -+ __u32 pd_handle; -+ __u32 driver_data[0]; -+}; -+ -+struct ib_uverbs_dealloc_pd { -+ __u32 pd_handle; -+}; -+ -+struct ib_uverbs_open_xrcd { -+ __aligned_u64 response; -+ __u32 fd; -+ __u32 oflags; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_open_xrcd_resp { -+ __u32 xrcd_handle; -+ __u32 driver_data[0]; -+}; -+ -+struct ib_uverbs_close_xrcd { -+ __u32 xrcd_handle; -+}; -+ -+struct ib_uverbs_reg_mr { -+ __aligned_u64 response; -+ __aligned_u64 start; -+ __aligned_u64 length; -+ __aligned_u64 hca_va; -+ __u32 pd_handle; -+ __u32 access_flags; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_reg_mr_resp { -+ __u32 mr_handle; -+ __u32 lkey; -+ __u32 rkey; -+ __u32 driver_data[0]; -+}; -+ -+struct ib_uverbs_rereg_mr { -+ __aligned_u64 response; -+ __u32 mr_handle; -+ __u32 flags; -+ __aligned_u64 start; -+ __aligned_u64 length; -+ __aligned_u64 hca_va; -+ __u32 pd_handle; -+ __u32 access_flags; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_rereg_mr_resp { -+ __u32 lkey; -+ __u32 rkey; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_dereg_mr { -+ __u32 mr_handle; -+}; -+ -+struct ib_uverbs_alloc_mw { -+ __aligned_u64 response; -+ __u32 pd_handle; -+ __u8 mw_type; -+ __u8 reserved[3]; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_alloc_mw_resp { -+ __u32 mw_handle; -+ __u32 rkey; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_dealloc_mw { -+ __u32 mw_handle; -+}; -+ -+struct ib_uverbs_create_comp_channel { -+ __aligned_u64 response; -+}; -+ -+struct ib_uverbs_create_comp_channel_resp { -+ __u32 fd; -+}; -+ -+struct ib_uverbs_create_cq { -+ __aligned_u64 response; -+ __aligned_u64 user_handle; -+ __u32 cqe; -+ __u32 comp_vector; -+ __s32 comp_channel; -+ __u32 reserved; -+ __aligned_u64 driver_data[0]; -+}; -+ -+enum ib_uverbs_ex_create_cq_flags { -+ IB_UVERBS_CQ_FLAGS_TIMESTAMP_COMPLETION = 1 << 0, -+ IB_UVERBS_CQ_FLAGS_IGNORE_OVERRUN = 1 << 1, -+}; -+ -+struct ib_uverbs_ex_create_cq { -+ __aligned_u64 user_handle; -+ __u32 cqe; -+ __u32 comp_vector; -+ __s32 comp_channel; -+ __u32 comp_mask; -+ __u32 flags; /* bitmask of ib_uverbs_ex_create_cq_flags */ -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_create_cq_resp { -+ __u32 cq_handle; -+ __u32 cqe; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_ex_create_cq_resp { -+ struct ib_uverbs_create_cq_resp base; -+ __u32 comp_mask; -+ __u32 response_length; -+}; -+ -+struct ib_uverbs_resize_cq { -+ __aligned_u64 response; -+ __u32 cq_handle; -+ __u32 cqe; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_resize_cq_resp { -+ __u32 cqe; -+ __u32 reserved; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_poll_cq { -+ __aligned_u64 response; -+ __u32 cq_handle; -+ __u32 ne; -+}; -+ -+struct ib_uverbs_wc { -+ __aligned_u64 wr_id; -+ __u32 status; -+ __u32 opcode; -+ __u32 vendor_err; -+ __u32 byte_len; -+ union { -+ __be32 imm_data; -+ __u32 invalidate_rkey; -+ } ex; -+ __u32 qp_num; -+ __u32 src_qp; -+ __u32 wc_flags; -+ __u16 pkey_index; -+ __u16 slid; -+ __u8 sl; -+ __u8 dlid_path_bits; -+ __u8 port_num; -+ __u8 reserved; -+}; -+ -+struct ib_uverbs_poll_cq_resp { -+ __u32 count; -+ __u32 reserved; -+ struct ib_uverbs_wc wc[0]; -+}; -+ -+struct ib_uverbs_req_notify_cq { -+ __u32 cq_handle; -+ __u32 solicited_only; -+}; -+ -+struct ib_uverbs_destroy_cq { -+ __aligned_u64 response; -+ __u32 cq_handle; -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_destroy_cq_resp { -+ __u32 comp_events_reported; -+ __u32 async_events_reported; -+}; -+ -+struct ib_uverbs_global_route { -+ __u8 dgid[16]; -+ __u32 flow_label; -+ __u8 sgid_index; -+ __u8 hop_limit; -+ __u8 traffic_class; -+ __u8 reserved; -+}; -+ -+struct ib_uverbs_ah_attr { -+ struct ib_uverbs_global_route grh; -+ __u16 dlid; -+ __u8 sl; -+ __u8 src_path_bits; -+ __u8 static_rate; -+ __u8 is_global; -+ __u8 port_num; -+ __u8 reserved; -+}; -+ -+struct ib_uverbs_qp_attr { -+ __u32 qp_attr_mask; -+ __u32 qp_state; -+ __u32 cur_qp_state; -+ __u32 path_mtu; -+ __u32 path_mig_state; -+ __u32 qkey; -+ __u32 rq_psn; -+ __u32 sq_psn; -+ __u32 dest_qp_num; -+ __u32 qp_access_flags; -+ -+ struct ib_uverbs_ah_attr ah_attr; -+ struct ib_uverbs_ah_attr alt_ah_attr; -+ -+ /* ib_qp_cap */ -+ __u32 max_send_wr; -+ __u32 max_recv_wr; -+ __u32 max_send_sge; -+ __u32 max_recv_sge; -+ __u32 max_inline_data; -+ -+ __u16 pkey_index; -+ __u16 alt_pkey_index; -+ __u8 en_sqd_async_notify; -+ __u8 sq_draining; -+ __u8 max_rd_atomic; -+ __u8 max_dest_rd_atomic; -+ __u8 min_rnr_timer; -+ __u8 port_num; -+ __u8 timeout; -+ __u8 retry_cnt; -+ __u8 rnr_retry; -+ __u8 alt_port_num; -+ __u8 alt_timeout; -+ __u8 reserved[5]; -+}; -+ -+struct ib_uverbs_create_qp { -+ __aligned_u64 response; -+ __aligned_u64 user_handle; -+ __u32 pd_handle; -+ __u32 send_cq_handle; -+ __u32 recv_cq_handle; -+ __u32 srq_handle; -+ __u32 max_send_wr; -+ __u32 max_recv_wr; -+ __u32 max_send_sge; -+ __u32 max_recv_sge; -+ __u32 max_inline_data; -+ __u8 sq_sig_all; -+ __u8 qp_type; -+ __u8 is_srq; -+ __u8 reserved; -+ __aligned_u64 driver_data[0]; -+}; -+ -+enum ib_uverbs_create_qp_mask { -+ IB_UVERBS_CREATE_QP_MASK_IND_TABLE = 1UL << 0, -+}; -+ -+enum { -+ IB_UVERBS_CREATE_QP_SUP_COMP_MASK = IB_UVERBS_CREATE_QP_MASK_IND_TABLE, -+}; -+ -+enum { -+ /* -+ * This value is equal to IB_QP_DEST_QPN. -+ */ -+ IB_USER_LEGACY_LAST_QP_ATTR_MASK = 1ULL << 20, -+}; -+ -+enum { -+ /* -+ * This value is equal to IB_QP_RATE_LIMIT. -+ */ -+ IB_USER_LAST_QP_ATTR_MASK = 1ULL << 25, -+}; -+ -+struct ib_uverbs_ex_create_qp { -+ __aligned_u64 user_handle; -+ __u32 pd_handle; -+ __u32 send_cq_handle; -+ __u32 recv_cq_handle; -+ __u32 srq_handle; -+ __u32 max_send_wr; -+ __u32 max_recv_wr; -+ __u32 max_send_sge; -+ __u32 max_recv_sge; -+ __u32 max_inline_data; -+ __u8 sq_sig_all; -+ __u8 qp_type; -+ __u8 is_srq; -+ __u8 reserved; -+ __u32 comp_mask; -+ __u32 create_flags; -+ __u32 rwq_ind_tbl_handle; -+ __u32 source_qpn; -+}; -+ -+struct ib_uverbs_open_qp { -+ __aligned_u64 response; -+ __aligned_u64 user_handle; -+ __u32 pd_handle; -+ __u32 qpn; -+ __u8 qp_type; -+ __u8 reserved[7]; -+ __aligned_u64 driver_data[0]; -+}; -+ -+/* also used for open response */ -+struct ib_uverbs_create_qp_resp { -+ __u32 qp_handle; -+ __u32 qpn; -+ __u32 max_send_wr; -+ __u32 max_recv_wr; -+ __u32 max_send_sge; -+ __u32 max_recv_sge; -+ __u32 max_inline_data; -+ __u32 reserved; -+ __u32 driver_data[0]; -+}; -+ -+struct ib_uverbs_ex_create_qp_resp { -+ struct ib_uverbs_create_qp_resp base; -+ __u32 comp_mask; -+ __u32 response_length; -+}; -+ -+/* -+ * This struct needs to remain a multiple of 8 bytes to keep the -+ * alignment of the modify QP parameters. -+ */ -+struct ib_uverbs_qp_dest { -+ __u8 dgid[16]; -+ __u32 flow_label; -+ __u16 dlid; -+ __u16 reserved; -+ __u8 sgid_index; -+ __u8 hop_limit; -+ __u8 traffic_class; -+ __u8 sl; -+ __u8 src_path_bits; -+ __u8 static_rate; -+ __u8 is_global; -+ __u8 port_num; -+}; -+ -+struct ib_uverbs_query_qp { -+ __aligned_u64 response; -+ __u32 qp_handle; -+ __u32 attr_mask; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_query_qp_resp { -+ struct ib_uverbs_qp_dest dest; -+ struct ib_uverbs_qp_dest alt_dest; -+ __u32 max_send_wr; -+ __u32 max_recv_wr; -+ __u32 max_send_sge; -+ __u32 max_recv_sge; -+ __u32 max_inline_data; -+ __u32 qkey; -+ __u32 rq_psn; -+ __u32 sq_psn; -+ __u32 dest_qp_num; -+ __u32 qp_access_flags; -+ __u16 pkey_index; -+ __u16 alt_pkey_index; -+ __u8 qp_state; -+ __u8 cur_qp_state; -+ __u8 path_mtu; -+ __u8 path_mig_state; -+ __u8 sq_draining; -+ __u8 max_rd_atomic; -+ __u8 max_dest_rd_atomic; -+ __u8 min_rnr_timer; -+ __u8 port_num; -+ __u8 timeout; -+ __u8 retry_cnt; -+ __u8 rnr_retry; -+ __u8 alt_port_num; -+ __u8 alt_timeout; -+ __u8 sq_sig_all; -+ __u8 reserved[5]; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_modify_qp { -+ struct ib_uverbs_qp_dest dest; -+ struct ib_uverbs_qp_dest alt_dest; -+ __u32 qp_handle; -+ __u32 attr_mask; -+ __u32 qkey; -+ __u32 rq_psn; -+ __u32 sq_psn; -+ __u32 dest_qp_num; -+ __u32 qp_access_flags; -+ __u16 pkey_index; -+ __u16 alt_pkey_index; -+ __u8 qp_state; -+ __u8 cur_qp_state; -+ __u8 path_mtu; -+ __u8 path_mig_state; -+ __u8 en_sqd_async_notify; -+ __u8 max_rd_atomic; -+ __u8 max_dest_rd_atomic; -+ __u8 min_rnr_timer; -+ __u8 port_num; -+ __u8 timeout; -+ __u8 retry_cnt; -+ __u8 rnr_retry; -+ __u8 alt_port_num; -+ __u8 alt_timeout; -+ __u8 reserved[2]; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_ex_modify_qp { -+ struct ib_uverbs_modify_qp base; -+ __u32 rate_limit; -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_ex_modify_qp_resp { -+ __u32 comp_mask; -+ __u32 response_length; -+}; -+ -+struct ib_uverbs_destroy_qp { -+ __aligned_u64 response; -+ __u32 qp_handle; -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_destroy_qp_resp { -+ __u32 events_reported; -+}; -+ -+/* -+ * The ib_uverbs_sge structure isn't used anywhere, since we assume -+ * the ib_sge structure is packed the same way on 32-bit and 64-bit -+ * architectures in both kernel and user space. It's just here to -+ * document the ABI. -+ */ -+struct ib_uverbs_sge { -+ __aligned_u64 addr; -+ __u32 length; -+ __u32 lkey; -+}; -+ -+enum ib_uverbs_wr_opcode { -+ IB_UVERBS_WR_RDMA_WRITE = 0, -+ IB_UVERBS_WR_RDMA_WRITE_WITH_IMM = 1, -+ IB_UVERBS_WR_SEND = 2, -+ IB_UVERBS_WR_SEND_WITH_IMM = 3, -+ IB_UVERBS_WR_RDMA_READ = 4, -+ IB_UVERBS_WR_ATOMIC_CMP_AND_SWP = 5, -+ IB_UVERBS_WR_ATOMIC_FETCH_AND_ADD = 6, -+ IB_UVERBS_WR_LOCAL_INV = 7, -+ IB_UVERBS_WR_BIND_MW = 8, -+ IB_UVERBS_WR_SEND_WITH_INV = 9, -+ IB_UVERBS_WR_TSO = 10, -+ IB_UVERBS_WR_RDMA_READ_WITH_INV = 11, -+ IB_UVERBS_WR_MASKED_ATOMIC_CMP_AND_SWP = 12, -+ IB_UVERBS_WR_MASKED_ATOMIC_FETCH_AND_ADD = 13, -+ /* Review enum ib_wr_opcode before modifying this */ -+}; -+ -+struct ib_uverbs_send_wr { -+ __aligned_u64 wr_id; -+ __u32 num_sge; -+ __u32 opcode; /* see enum ib_uverbs_wr_opcode */ -+ __u32 send_flags; -+ union { -+ __be32 imm_data; -+ __u32 invalidate_rkey; -+ } ex; -+ union { -+ struct { -+ __aligned_u64 remote_addr; -+ __u32 rkey; -+ __u32 reserved; -+ } rdma; -+ struct { -+ __aligned_u64 remote_addr; -+ __aligned_u64 compare_add; -+ __aligned_u64 swap; -+ __u32 rkey; -+ __u32 reserved; -+ } atomic; -+ struct { -+ __u32 ah; -+ __u32 remote_qpn; -+ __u32 remote_qkey; -+ __u32 reserved; -+ } ud; -+ } wr; -+}; -+ -+struct ib_uverbs_post_send { -+ __aligned_u64 response; -+ __u32 qp_handle; -+ __u32 wr_count; -+ __u32 sge_count; -+ __u32 wqe_size; -+ struct ib_uverbs_send_wr send_wr[0]; -+}; -+ -+struct ib_uverbs_post_send_resp { -+ __u32 bad_wr; -+}; -+ -+struct ib_uverbs_recv_wr { -+ __aligned_u64 wr_id; -+ __u32 num_sge; -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_post_recv { -+ __aligned_u64 response; -+ __u32 qp_handle; -+ __u32 wr_count; -+ __u32 sge_count; -+ __u32 wqe_size; -+ struct ib_uverbs_recv_wr recv_wr[0]; -+}; -+ -+struct ib_uverbs_post_recv_resp { -+ __u32 bad_wr; -+}; -+ -+struct ib_uverbs_post_srq_recv { -+ __aligned_u64 response; -+ __u32 srq_handle; -+ __u32 wr_count; -+ __u32 sge_count; -+ __u32 wqe_size; -+ struct ib_uverbs_recv_wr recv[0]; -+}; -+ -+struct ib_uverbs_post_srq_recv_resp { -+ __u32 bad_wr; -+}; -+ -+struct ib_uverbs_create_ah { -+ __aligned_u64 response; -+ __aligned_u64 user_handle; -+ __u32 pd_handle; -+ __u32 reserved; -+ struct ib_uverbs_ah_attr attr; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_create_ah_resp { -+ __u32 ah_handle; -+ __u32 driver_data[0]; -+}; -+ -+struct ib_uverbs_destroy_ah { -+ __u32 ah_handle; -+}; -+ -+struct ib_uverbs_attach_mcast { -+ __u8 gid[16]; -+ __u32 qp_handle; -+ __u16 mlid; -+ __u16 reserved; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_detach_mcast { -+ __u8 gid[16]; -+ __u32 qp_handle; -+ __u16 mlid; -+ __u16 reserved; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_flow_spec_hdr { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ /* followed by flow_spec */ -+ __aligned_u64 flow_spec_data[0]; -+}; -+ -+struct ib_uverbs_flow_eth_filter { -+ __u8 dst_mac[6]; -+ __u8 src_mac[6]; -+ __be16 ether_type; -+ __be16 vlan_tag; -+}; -+ -+struct ib_uverbs_flow_spec_eth { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+ struct ib_uverbs_flow_eth_filter val; -+ struct ib_uverbs_flow_eth_filter mask; -+}; -+ -+struct ib_uverbs_flow_ipv4_filter { -+ __be32 src_ip; -+ __be32 dst_ip; -+ __u8 proto; -+ __u8 tos; -+ __u8 ttl; -+ __u8 flags; -+}; -+ -+struct ib_uverbs_flow_spec_ipv4 { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+ struct ib_uverbs_flow_ipv4_filter val; -+ struct ib_uverbs_flow_ipv4_filter mask; -+}; -+ -+struct ib_uverbs_flow_tcp_udp_filter { -+ __be16 dst_port; -+ __be16 src_port; -+}; -+ -+struct ib_uverbs_flow_spec_tcp_udp { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+ struct ib_uverbs_flow_tcp_udp_filter val; -+ struct ib_uverbs_flow_tcp_udp_filter mask; -+}; -+ -+struct ib_uverbs_flow_ipv6_filter { -+ __u8 src_ip[16]; -+ __u8 dst_ip[16]; -+ __be32 flow_label; -+ __u8 next_hdr; -+ __u8 traffic_class; -+ __u8 hop_limit; -+ __u8 reserved; -+}; -+ -+struct ib_uverbs_flow_spec_ipv6 { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+ struct ib_uverbs_flow_ipv6_filter val; -+ struct ib_uverbs_flow_ipv6_filter mask; -+}; -+ -+struct ib_uverbs_flow_spec_action_tag { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+ __u32 tag_id; -+ __u32 reserved1; -+}; -+ -+struct ib_uverbs_flow_spec_action_drop { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+}; -+ -+struct ib_uverbs_flow_spec_action_handle { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+ __u32 handle; -+ __u32 reserved1; -+}; -+ -+struct ib_uverbs_flow_spec_action_count { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+ __u32 handle; -+ __u32 reserved1; -+}; -+ -+struct ib_uverbs_flow_tunnel_filter { -+ __be32 tunnel_id; -+}; -+ -+struct ib_uverbs_flow_spec_tunnel { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+ struct ib_uverbs_flow_tunnel_filter val; -+ struct ib_uverbs_flow_tunnel_filter mask; -+}; -+ -+struct ib_uverbs_flow_spec_esp_filter { -+ __u32 spi; -+ __u32 seq; -+}; -+ -+struct ib_uverbs_flow_spec_esp { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+ struct ib_uverbs_flow_spec_esp_filter val; -+ struct ib_uverbs_flow_spec_esp_filter mask; -+}; -+ -+struct ib_uverbs_flow_gre_filter { -+ /* c_ks_res0_ver field is bits 0-15 in offset 0 of a standard GRE header: -+ * bit 0 - C - checksum bit. -+ * bit 1 - reserved. set to 0. -+ * bit 2 - key bit. -+ * bit 3 - sequence number bit. -+ * bits 4:12 - reserved. set to 0. -+ * bits 13:15 - GRE version. -+ */ -+ __be16 c_ks_res0_ver; -+ __be16 protocol; -+ __be32 key; -+}; -+ -+struct ib_uverbs_flow_spec_gre { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+ struct ib_uverbs_flow_gre_filter val; -+ struct ib_uverbs_flow_gre_filter mask; -+}; -+ -+struct ib_uverbs_flow_mpls_filter { -+ /* The field includes the entire MPLS label: -+ * bits 0:19 - label field. -+ * bits 20:22 - traffic class field. -+ * bits 23 - bottom of stack bit. -+ * bits 24:31 - ttl field. -+ */ -+ __be32 label; -+}; -+ -+struct ib_uverbs_flow_spec_mpls { -+ union { -+ struct ib_uverbs_flow_spec_hdr hdr; -+ struct { -+ __u32 type; -+ __u16 size; -+ __u16 reserved; -+ }; -+ }; -+ struct ib_uverbs_flow_mpls_filter val; -+ struct ib_uverbs_flow_mpls_filter mask; -+}; -+ -+struct ib_uverbs_flow_attr { -+ __u32 type; -+ __u16 size; -+ __u16 priority; -+ __u8 num_of_specs; -+ __u8 reserved[2]; -+ __u8 port; -+ __u32 flags; -+ /* Following are the optional layers according to user request -+ * struct ib_flow_spec_xxx -+ * struct ib_flow_spec_yyy -+ */ -+ struct ib_uverbs_flow_spec_hdr flow_specs[0]; -+}; -+ -+struct ib_uverbs_create_flow { -+ __u32 comp_mask; -+ __u32 qp_handle; -+ struct ib_uverbs_flow_attr flow_attr; -+}; -+ -+struct ib_uverbs_create_flow_resp { -+ __u32 comp_mask; -+ __u32 flow_handle; -+}; -+ -+struct ib_uverbs_destroy_flow { -+ __u32 comp_mask; -+ __u32 flow_handle; -+}; -+ -+struct ib_uverbs_create_srq { -+ __aligned_u64 response; -+ __aligned_u64 user_handle; -+ __u32 pd_handle; -+ __u32 max_wr; -+ __u32 max_sge; -+ __u32 srq_limit; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_create_xsrq { -+ __aligned_u64 response; -+ __aligned_u64 user_handle; -+ __u32 srq_type; -+ __u32 pd_handle; -+ __u32 max_wr; -+ __u32 max_sge; -+ __u32 srq_limit; -+ __u32 max_num_tags; -+ __u32 xrcd_handle; -+ __u32 cq_handle; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_create_srq_resp { -+ __u32 srq_handle; -+ __u32 max_wr; -+ __u32 max_sge; -+ __u32 srqn; -+ __u32 driver_data[0]; -+}; -+ -+struct ib_uverbs_modify_srq { -+ __u32 srq_handle; -+ __u32 attr_mask; -+ __u32 max_wr; -+ __u32 srq_limit; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_query_srq { -+ __aligned_u64 response; -+ __u32 srq_handle; -+ __u32 reserved; -+ __aligned_u64 driver_data[0]; -+}; -+ -+struct ib_uverbs_query_srq_resp { -+ __u32 max_wr; -+ __u32 max_sge; -+ __u32 srq_limit; -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_destroy_srq { -+ __aligned_u64 response; -+ __u32 srq_handle; -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_destroy_srq_resp { -+ __u32 events_reported; -+}; -+ -+struct ib_uverbs_ex_create_wq { -+ __u32 comp_mask; -+ __u32 wq_type; -+ __aligned_u64 user_handle; -+ __u32 pd_handle; -+ __u32 cq_handle; -+ __u32 max_wr; -+ __u32 max_sge; -+ __u32 create_flags; /* Use enum ib_wq_flags */ -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_ex_create_wq_resp { -+ __u32 comp_mask; -+ __u32 response_length; -+ __u32 wq_handle; -+ __u32 max_wr; -+ __u32 max_sge; -+ __u32 wqn; -+}; -+ -+struct ib_uverbs_ex_destroy_wq { -+ __u32 comp_mask; -+ __u32 wq_handle; -+}; -+ -+struct ib_uverbs_ex_destroy_wq_resp { -+ __u32 comp_mask; -+ __u32 response_length; -+ __u32 events_reported; -+ __u32 reserved; -+}; -+ -+struct ib_uverbs_ex_modify_wq { -+ __u32 attr_mask; -+ __u32 wq_handle; -+ __u32 wq_state; -+ __u32 curr_wq_state; -+ __u32 flags; /* Use enum ib_wq_flags */ -+ __u32 flags_mask; /* Use enum ib_wq_flags */ -+}; -+ -+/* Prevent memory allocation rather than max expected size */ -+#define IB_USER_VERBS_MAX_LOG_IND_TBL_SIZE 0x0d -+struct ib_uverbs_ex_create_rwq_ind_table { -+ __u32 comp_mask; -+ __u32 log_ind_tbl_size; -+ /* Following are the wq handles according to log_ind_tbl_size -+ * wq_handle1 -+ * wq_handle2 -+ */ -+ __u32 wq_handles[0]; -+}; -+ -+struct ib_uverbs_ex_create_rwq_ind_table_resp { -+ __u32 comp_mask; -+ __u32 response_length; -+ __u32 ind_tbl_handle; -+ __u32 ind_tbl_num; -+}; -+ -+struct ib_uverbs_ex_destroy_rwq_ind_table { -+ __u32 comp_mask; -+ __u32 ind_tbl_handle; -+}; -+ -+struct ib_uverbs_cq_moderation { -+ __u16 cq_count; -+ __u16 cq_period; -+}; -+ -+struct ib_uverbs_ex_modify_cq { -+ __u32 cq_handle; -+ __u32 attr_mask; -+ struct ib_uverbs_cq_moderation attr; -+ __u32 reserved; -+}; -+ -+#define IB_DEVICE_NAME_MAX 64 -+ -+#endif /* IB_USER_VERBS_H */ -diff --git a/rdma/include/uapi/rdma/rdma_netlink.h b/rdma/include/uapi/rdma/rdma_netlink.h -new file mode 100644 -index 0000000000000..04c80cebef49f ---- /dev/null -+++ b/rdma/include/uapi/rdma/rdma_netlink.h -@@ -0,0 +1,438 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+#ifndef _RDMA_NETLINK_H -+#define _RDMA_NETLINK_H -+ -+#include -+ -+enum { -+ RDMA_NL_RDMA_CM = 1, -+ RDMA_NL_IWCM, -+ RDMA_NL_RSVD, -+ RDMA_NL_LS, /* RDMA Local Services */ -+ RDMA_NL_NLDEV, /* RDMA device interface */ -+ RDMA_NL_NUM_CLIENTS -+}; -+ -+enum { -+ RDMA_NL_GROUP_CM = 1, -+ RDMA_NL_GROUP_IWPM, -+ RDMA_NL_GROUP_LS, -+ RDMA_NL_NUM_GROUPS -+}; -+ -+#define RDMA_NL_GET_CLIENT(type) ((type & (((1 << 6) - 1) << 10)) >> 10) -+#define RDMA_NL_GET_OP(type) (type & ((1 << 10) - 1)) -+#define RDMA_NL_GET_TYPE(client, op) ((client << 10) + op) -+ -+enum { -+ RDMA_NL_RDMA_CM_ID_STATS = 0, -+ RDMA_NL_RDMA_CM_NUM_OPS -+}; -+ -+enum { -+ RDMA_NL_RDMA_CM_ATTR_SRC_ADDR = 1, -+ RDMA_NL_RDMA_CM_ATTR_DST_ADDR, -+ RDMA_NL_RDMA_CM_NUM_ATTR, -+}; -+ -+/* iwarp port mapper op-codes */ -+enum { -+ RDMA_NL_IWPM_REG_PID = 0, -+ RDMA_NL_IWPM_ADD_MAPPING, -+ RDMA_NL_IWPM_QUERY_MAPPING, -+ RDMA_NL_IWPM_REMOVE_MAPPING, -+ RDMA_NL_IWPM_REMOTE_INFO, -+ RDMA_NL_IWPM_HANDLE_ERR, -+ RDMA_NL_IWPM_MAPINFO, -+ RDMA_NL_IWPM_MAPINFO_NUM, -+ RDMA_NL_IWPM_NUM_OPS -+}; -+ -+struct rdma_cm_id_stats { -+ __u32 qp_num; -+ __u32 bound_dev_if; -+ __u32 port_space; -+ __s32 pid; -+ __u8 cm_state; -+ __u8 node_type; -+ __u8 port_num; -+ __u8 qp_type; -+}; -+ -+enum { -+ IWPM_NLA_REG_PID_UNSPEC = 0, -+ IWPM_NLA_REG_PID_SEQ, -+ IWPM_NLA_REG_IF_NAME, -+ IWPM_NLA_REG_IBDEV_NAME, -+ IWPM_NLA_REG_ULIB_NAME, -+ IWPM_NLA_REG_PID_MAX -+}; -+ -+enum { -+ IWPM_NLA_RREG_PID_UNSPEC = 0, -+ IWPM_NLA_RREG_PID_SEQ, -+ IWPM_NLA_RREG_IBDEV_NAME, -+ IWPM_NLA_RREG_ULIB_NAME, -+ IWPM_NLA_RREG_ULIB_VER, -+ IWPM_NLA_RREG_PID_ERR, -+ IWPM_NLA_RREG_PID_MAX -+ -+}; -+ -+enum { -+ IWPM_NLA_MANAGE_MAPPING_UNSPEC = 0, -+ IWPM_NLA_MANAGE_MAPPING_SEQ, -+ IWPM_NLA_MANAGE_ADDR, -+ IWPM_NLA_MANAGE_MAPPED_LOC_ADDR, -+ IWPM_NLA_RMANAGE_MAPPING_ERR, -+ IWPM_NLA_RMANAGE_MAPPING_MAX -+}; -+ -+#define IWPM_NLA_MANAGE_MAPPING_MAX 3 -+#define IWPM_NLA_QUERY_MAPPING_MAX 4 -+#define IWPM_NLA_MAPINFO_SEND_MAX 3 -+ -+enum { -+ IWPM_NLA_QUERY_MAPPING_UNSPEC = 0, -+ IWPM_NLA_QUERY_MAPPING_SEQ, -+ IWPM_NLA_QUERY_LOCAL_ADDR, -+ IWPM_NLA_QUERY_REMOTE_ADDR, -+ IWPM_NLA_RQUERY_MAPPED_LOC_ADDR, -+ IWPM_NLA_RQUERY_MAPPED_REM_ADDR, -+ IWPM_NLA_RQUERY_MAPPING_ERR, -+ IWPM_NLA_RQUERY_MAPPING_MAX -+}; -+ -+enum { -+ IWPM_NLA_MAPINFO_REQ_UNSPEC = 0, -+ IWPM_NLA_MAPINFO_ULIB_NAME, -+ IWPM_NLA_MAPINFO_ULIB_VER, -+ IWPM_NLA_MAPINFO_REQ_MAX -+}; -+ -+enum { -+ IWPM_NLA_MAPINFO_UNSPEC = 0, -+ IWPM_NLA_MAPINFO_LOCAL_ADDR, -+ IWPM_NLA_MAPINFO_MAPPED_ADDR, -+ IWPM_NLA_MAPINFO_MAX -+}; -+ -+enum { -+ IWPM_NLA_MAPINFO_NUM_UNSPEC = 0, -+ IWPM_NLA_MAPINFO_SEQ, -+ IWPM_NLA_MAPINFO_SEND_NUM, -+ IWPM_NLA_MAPINFO_ACK_NUM, -+ IWPM_NLA_MAPINFO_NUM_MAX -+}; -+ -+enum { -+ IWPM_NLA_ERR_UNSPEC = 0, -+ IWPM_NLA_ERR_SEQ, -+ IWPM_NLA_ERR_CODE, -+ IWPM_NLA_ERR_MAX -+}; -+ -+/* -+ * Local service operations: -+ * RESOLVE - The client requests the local service to resolve a path. -+ * SET_TIMEOUT - The local service requests the client to set the timeout. -+ * IP_RESOLVE - The client requests the local service to resolve an IP to GID. -+ */ -+enum { -+ RDMA_NL_LS_OP_RESOLVE = 0, -+ RDMA_NL_LS_OP_SET_TIMEOUT, -+ RDMA_NL_LS_OP_IP_RESOLVE, -+ RDMA_NL_LS_NUM_OPS -+}; -+ -+/* Local service netlink message flags */ -+#define RDMA_NL_LS_F_ERR 0x0100 /* Failed response */ -+ -+/* -+ * Local service resolve operation family header. -+ * The layout for the resolve operation: -+ * nlmsg header -+ * family header -+ * attributes -+ */ -+ -+/* -+ * Local service path use: -+ * Specify how the path(s) will be used. -+ * ALL - For connected CM operation (6 pathrecords) -+ * UNIDIRECTIONAL - For unidirectional UD (1 pathrecord) -+ * GMP - For miscellaneous GMP like operation (at least 1 reversible -+ * pathrecord) -+ */ -+enum { -+ LS_RESOLVE_PATH_USE_ALL = 0, -+ LS_RESOLVE_PATH_USE_UNIDIRECTIONAL, -+ LS_RESOLVE_PATH_USE_GMP, -+ LS_RESOLVE_PATH_USE_MAX -+}; -+ -+#define LS_DEVICE_NAME_MAX 64 -+ -+struct rdma_ls_resolve_header { -+ __u8 device_name[LS_DEVICE_NAME_MAX]; -+ __u8 port_num; -+ __u8 path_use; -+}; -+ -+struct rdma_ls_ip_resolve_header { -+ __u32 ifindex; -+}; -+ -+/* Local service attribute type */ -+#define RDMA_NLA_F_MANDATORY (1 << 13) -+#define RDMA_NLA_TYPE_MASK (~(NLA_F_NESTED | NLA_F_NET_BYTEORDER | \ -+ RDMA_NLA_F_MANDATORY)) -+ -+/* -+ * Local service attributes: -+ * Attr Name Size Byte order -+ * ----------------------------------------------------- -+ * PATH_RECORD struct ib_path_rec_data -+ * TIMEOUT u32 cpu -+ * SERVICE_ID u64 cpu -+ * DGID u8[16] BE -+ * SGID u8[16] BE -+ * TCLASS u8 -+ * PKEY u16 cpu -+ * QOS_CLASS u16 cpu -+ * IPV4 u32 BE -+ * IPV6 u8[16] BE -+ */ -+enum { -+ LS_NLA_TYPE_UNSPEC = 0, -+ LS_NLA_TYPE_PATH_RECORD, -+ LS_NLA_TYPE_TIMEOUT, -+ LS_NLA_TYPE_SERVICE_ID, -+ LS_NLA_TYPE_DGID, -+ LS_NLA_TYPE_SGID, -+ LS_NLA_TYPE_TCLASS, -+ LS_NLA_TYPE_PKEY, -+ LS_NLA_TYPE_QOS_CLASS, -+ LS_NLA_TYPE_IPV4, -+ LS_NLA_TYPE_IPV6, -+ LS_NLA_TYPE_MAX -+}; -+ -+/* Local service DGID/SGID attribute: big endian */ -+struct rdma_nla_ls_gid { -+ __u8 gid[16]; -+}; -+ -+enum rdma_nldev_command { -+ RDMA_NLDEV_CMD_UNSPEC, -+ -+ RDMA_NLDEV_CMD_GET, /* can dump */ -+ RDMA_NLDEV_CMD_SET, -+ -+ /* 3 - 4 are free to use */ -+ -+ RDMA_NLDEV_CMD_PORT_GET = 5, /* can dump */ -+ -+ /* 6 - 8 are free to use */ -+ -+ RDMA_NLDEV_CMD_RES_GET = 9, /* can dump */ -+ -+ RDMA_NLDEV_CMD_RES_QP_GET, /* can dump */ -+ -+ RDMA_NLDEV_CMD_RES_CM_ID_GET, /* can dump */ -+ -+ RDMA_NLDEV_CMD_RES_CQ_GET, /* can dump */ -+ -+ RDMA_NLDEV_CMD_RES_MR_GET, /* can dump */ -+ -+ RDMA_NLDEV_CMD_RES_PD_GET, /* can dump */ -+ -+ RDMA_NLDEV_NUM_OPS -+}; -+ -+enum { -+ RDMA_NLDEV_ATTR_ENTRY_STRLEN = 16, -+}; -+ -+enum rdma_nldev_print_type { -+ RDMA_NLDEV_PRINT_TYPE_UNSPEC, -+ RDMA_NLDEV_PRINT_TYPE_HEX, -+}; -+ -+enum rdma_nldev_attr { -+ /* don't change the order or add anything between, this is ABI! */ -+ RDMA_NLDEV_ATTR_UNSPEC, -+ -+ /* Pad attribute for 64b alignment */ -+ RDMA_NLDEV_ATTR_PAD = RDMA_NLDEV_ATTR_UNSPEC, -+ -+ /* Identifier for ib_device */ -+ RDMA_NLDEV_ATTR_DEV_INDEX, /* u32 */ -+ -+ RDMA_NLDEV_ATTR_DEV_NAME, /* string */ -+ /* -+ * Device index together with port index are identifiers -+ * for port/link properties. -+ * -+ * For RDMA_NLDEV_CMD_GET commamnd, port index will return number -+ * of available ports in ib_device, while for port specific operations, -+ * it will be real port index as it appears in sysfs. Port index follows -+ * sysfs notation and starts from 1 for the first port. -+ */ -+ RDMA_NLDEV_ATTR_PORT_INDEX, /* u32 */ -+ -+ /* -+ * Device and port capabilities -+ * -+ * When used for port info, first 32-bits are CapabilityMask followed by -+ * 16-bit CapabilityMask2. -+ */ -+ RDMA_NLDEV_ATTR_CAP_FLAGS, /* u64 */ -+ -+ /* -+ * FW version -+ */ -+ RDMA_NLDEV_ATTR_FW_VERSION, /* string */ -+ -+ /* -+ * Node GUID (in host byte order) associated with the RDMA device. -+ */ -+ RDMA_NLDEV_ATTR_NODE_GUID, /* u64 */ -+ -+ /* -+ * System image GUID (in host byte order) associated with -+ * this RDMA device and other devices which are part of a -+ * single system. -+ */ -+ RDMA_NLDEV_ATTR_SYS_IMAGE_GUID, /* u64 */ -+ -+ /* -+ * Subnet prefix (in host byte order) -+ */ -+ RDMA_NLDEV_ATTR_SUBNET_PREFIX, /* u64 */ -+ -+ /* -+ * Local Identifier (LID), -+ * According to IB specification, It is 16-bit address assigned -+ * by the Subnet Manager. Extended to be 32-bit for OmniPath users. -+ */ -+ RDMA_NLDEV_ATTR_LID, /* u32 */ -+ RDMA_NLDEV_ATTR_SM_LID, /* u32 */ -+ -+ /* -+ * LID mask control (LMC) -+ */ -+ RDMA_NLDEV_ATTR_LMC, /* u8 */ -+ -+ RDMA_NLDEV_ATTR_PORT_STATE, /* u8 */ -+ RDMA_NLDEV_ATTR_PORT_PHYS_STATE, /* u8 */ -+ -+ RDMA_NLDEV_ATTR_DEV_NODE_TYPE, /* u8 */ -+ -+ RDMA_NLDEV_ATTR_RES_SUMMARY, /* nested table */ -+ RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY, /* nested table */ -+ RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME, /* string */ -+ RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR, /* u64 */ -+ -+ RDMA_NLDEV_ATTR_RES_QP, /* nested table */ -+ RDMA_NLDEV_ATTR_RES_QP_ENTRY, /* nested table */ -+ /* -+ * Local QPN -+ */ -+ RDMA_NLDEV_ATTR_RES_LQPN, /* u32 */ -+ /* -+ * Remote QPN, -+ * Applicable for RC and UC only IBTA 11.2.5.3 QUERY QUEUE PAIR -+ */ -+ RDMA_NLDEV_ATTR_RES_RQPN, /* u32 */ -+ /* -+ * Receive Queue PSN, -+ * Applicable for RC and UC only 11.2.5.3 QUERY QUEUE PAIR -+ */ -+ RDMA_NLDEV_ATTR_RES_RQ_PSN, /* u32 */ -+ /* -+ * Send Queue PSN -+ */ -+ RDMA_NLDEV_ATTR_RES_SQ_PSN, /* u32 */ -+ RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE, /* u8 */ -+ /* -+ * QP types as visible to RDMA/core, the reserved QPT -+ * are not exported through this interface. -+ */ -+ RDMA_NLDEV_ATTR_RES_TYPE, /* u8 */ -+ RDMA_NLDEV_ATTR_RES_STATE, /* u8 */ -+ /* -+ * Process ID which created object, -+ * in case of kernel origin, PID won't exist. -+ */ -+ RDMA_NLDEV_ATTR_RES_PID, /* u32 */ -+ /* -+ * The name of process created following resource. -+ * It will exist only for kernel objects. -+ * For user created objects, the user is supposed -+ * to read /proc/PID/comm file. -+ */ -+ RDMA_NLDEV_ATTR_RES_KERN_NAME, /* string */ -+ -+ RDMA_NLDEV_ATTR_RES_CM_ID, /* nested table */ -+ RDMA_NLDEV_ATTR_RES_CM_ID_ENTRY, /* nested table */ -+ /* -+ * rdma_cm_id port space. -+ */ -+ RDMA_NLDEV_ATTR_RES_PS, /* u32 */ -+ /* -+ * Source and destination socket addresses -+ */ -+ RDMA_NLDEV_ATTR_RES_SRC_ADDR, /* __kernel_sockaddr_storage */ -+ RDMA_NLDEV_ATTR_RES_DST_ADDR, /* __kernel_sockaddr_storage */ -+ -+ RDMA_NLDEV_ATTR_RES_CQ, /* nested table */ -+ RDMA_NLDEV_ATTR_RES_CQ_ENTRY, /* nested table */ -+ RDMA_NLDEV_ATTR_RES_CQE, /* u32 */ -+ RDMA_NLDEV_ATTR_RES_USECNT, /* u64 */ -+ RDMA_NLDEV_ATTR_RES_POLL_CTX, /* u8 */ -+ -+ RDMA_NLDEV_ATTR_RES_MR, /* nested table */ -+ RDMA_NLDEV_ATTR_RES_MR_ENTRY, /* nested table */ -+ RDMA_NLDEV_ATTR_RES_RKEY, /* u32 */ -+ RDMA_NLDEV_ATTR_RES_LKEY, /* u32 */ -+ RDMA_NLDEV_ATTR_RES_IOVA, /* u64 */ -+ RDMA_NLDEV_ATTR_RES_MRLEN, /* u64 */ -+ -+ RDMA_NLDEV_ATTR_RES_PD, /* nested table */ -+ RDMA_NLDEV_ATTR_RES_PD_ENTRY, /* nested table */ -+ RDMA_NLDEV_ATTR_RES_LOCAL_DMA_LKEY, /* u32 */ -+ RDMA_NLDEV_ATTR_RES_UNSAFE_GLOBAL_RKEY, /* u32 */ -+ /* -+ * Provides logical name and index of netdevice which is -+ * connected to physical port. This information is relevant -+ * for RoCE and iWARP. -+ * -+ * The netdevices which are associated with containers are -+ * supposed to be exported together with GID table once it -+ * will be exposed through the netlink. Because the -+ * associated netdevices are properties of GIDs. -+ */ -+ RDMA_NLDEV_ATTR_NDEV_INDEX, /* u32 */ -+ RDMA_NLDEV_ATTR_NDEV_NAME, /* string */ -+ /* -+ * driver-specific attributes. -+ */ -+ RDMA_NLDEV_ATTR_DRIVER, /* nested table */ -+ RDMA_NLDEV_ATTR_DRIVER_ENTRY, /* nested table */ -+ RDMA_NLDEV_ATTR_DRIVER_STRING, /* string */ -+ /* -+ * u8 values from enum rdma_nldev_print_type -+ */ -+ RDMA_NLDEV_ATTR_DRIVER_PRINT_TYPE, /* u8 */ -+ RDMA_NLDEV_ATTR_DRIVER_S32, /* s32 */ -+ RDMA_NLDEV_ATTR_DRIVER_U32, /* u32 */ -+ RDMA_NLDEV_ATTR_DRIVER_S64, /* s64 */ -+ RDMA_NLDEV_ATTR_DRIVER_U64, /* u64 */ -+ -+ /* -+ * Always the end -+ */ -+ RDMA_NLDEV_ATTR_MAX -+}; -+#endif /* _RDMA_NETLINK_H */ -diff --git a/rdma/include/uapi/rdma/rdma_user_cm.h b/rdma/include/uapi/rdma/rdma_user_cm.h -new file mode 100644 -index 0000000000000..0d1e78ebad051 ---- /dev/null -+++ b/rdma/include/uapi/rdma/rdma_user_cm.h -@@ -0,0 +1,324 @@ -+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ -+/* -+ * Copyright (c) 2005-2006 Intel Corporation. All rights reserved. -+ * -+ * This software is available to you under a choice of one of two -+ * licenses. You may choose to be licensed under the terms of the GNU -+ * General Public License (GPL) Version 2, available from the file -+ * COPYING in the main directory of this source tree, or the -+ * OpenIB.org BSD license below: -+ * -+ * Redistribution and use in source and binary forms, with or -+ * without modification, are permitted provided that the following -+ * conditions are met: -+ * -+ * - Redistributions of source code must retain the above -+ * copyright notice, this list of conditions and the following -+ * disclaimer. -+ * -+ * - Redistributions in binary form must reproduce the above -+ * copyright notice, this list of conditions and the following -+ * disclaimer in the documentation and/or other materials -+ * provided with the distribution. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -+ * SOFTWARE. -+ */ -+ -+#ifndef RDMA_USER_CM_H -+#define RDMA_USER_CM_H -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define RDMA_USER_CM_ABI_VERSION 4 -+ -+#define RDMA_MAX_PRIVATE_DATA 256 -+ -+enum { -+ RDMA_USER_CM_CMD_CREATE_ID, -+ RDMA_USER_CM_CMD_DESTROY_ID, -+ RDMA_USER_CM_CMD_BIND_IP, -+ RDMA_USER_CM_CMD_RESOLVE_IP, -+ RDMA_USER_CM_CMD_RESOLVE_ROUTE, -+ RDMA_USER_CM_CMD_QUERY_ROUTE, -+ RDMA_USER_CM_CMD_CONNECT, -+ RDMA_USER_CM_CMD_LISTEN, -+ RDMA_USER_CM_CMD_ACCEPT, -+ RDMA_USER_CM_CMD_REJECT, -+ RDMA_USER_CM_CMD_DISCONNECT, -+ RDMA_USER_CM_CMD_INIT_QP_ATTR, -+ RDMA_USER_CM_CMD_GET_EVENT, -+ RDMA_USER_CM_CMD_GET_OPTION, -+ RDMA_USER_CM_CMD_SET_OPTION, -+ RDMA_USER_CM_CMD_NOTIFY, -+ RDMA_USER_CM_CMD_JOIN_IP_MCAST, -+ RDMA_USER_CM_CMD_LEAVE_MCAST, -+ RDMA_USER_CM_CMD_MIGRATE_ID, -+ RDMA_USER_CM_CMD_QUERY, -+ RDMA_USER_CM_CMD_BIND, -+ RDMA_USER_CM_CMD_RESOLVE_ADDR, -+ RDMA_USER_CM_CMD_JOIN_MCAST -+}; -+ -+/* See IBTA Annex A11, servies ID bytes 4 & 5 */ -+enum rdma_ucm_port_space { -+ RDMA_PS_IPOIB = 0x0002, -+ RDMA_PS_IB = 0x013F, -+ RDMA_PS_TCP = 0x0106, -+ RDMA_PS_UDP = 0x0111, -+}; -+ -+/* -+ * command ABI structures. -+ */ -+struct rdma_ucm_cmd_hdr { -+ __u32 cmd; -+ __u16 in; -+ __u16 out; -+}; -+ -+struct rdma_ucm_create_id { -+ __aligned_u64 uid; -+ __aligned_u64 response; -+ __u16 ps; /* use enum rdma_ucm_port_space */ -+ __u8 qp_type; -+ __u8 reserved[5]; -+}; -+ -+struct rdma_ucm_create_id_resp { -+ __u32 id; -+}; -+ -+struct rdma_ucm_destroy_id { -+ __aligned_u64 response; -+ __u32 id; -+ __u32 reserved; -+}; -+ -+struct rdma_ucm_destroy_id_resp { -+ __u32 events_reported; -+}; -+ -+struct rdma_ucm_bind_ip { -+ __aligned_u64 response; -+ struct sockaddr_in6 addr; -+ __u32 id; -+}; -+ -+struct rdma_ucm_bind { -+ __u32 id; -+ __u16 addr_size; -+ __u16 reserved; -+ struct __kernel_sockaddr_storage addr; -+}; -+ -+struct rdma_ucm_resolve_ip { -+ struct sockaddr_in6 src_addr; -+ struct sockaddr_in6 dst_addr; -+ __u32 id; -+ __u32 timeout_ms; -+}; -+ -+struct rdma_ucm_resolve_addr { -+ __u32 id; -+ __u32 timeout_ms; -+ __u16 src_size; -+ __u16 dst_size; -+ __u32 reserved; -+ struct __kernel_sockaddr_storage src_addr; -+ struct __kernel_sockaddr_storage dst_addr; -+}; -+ -+struct rdma_ucm_resolve_route { -+ __u32 id; -+ __u32 timeout_ms; -+}; -+ -+enum { -+ RDMA_USER_CM_QUERY_ADDR, -+ RDMA_USER_CM_QUERY_PATH, -+ RDMA_USER_CM_QUERY_GID -+}; -+ -+struct rdma_ucm_query { -+ __aligned_u64 response; -+ __u32 id; -+ __u32 option; -+}; -+ -+struct rdma_ucm_query_route_resp { -+ __aligned_u64 node_guid; -+ struct ib_user_path_rec ib_route[2]; -+ struct sockaddr_in6 src_addr; -+ struct sockaddr_in6 dst_addr; -+ __u32 num_paths; -+ __u8 port_num; -+ __u8 reserved[3]; -+}; -+ -+struct rdma_ucm_query_addr_resp { -+ __aligned_u64 node_guid; -+ __u8 port_num; -+ __u8 reserved; -+ __u16 pkey; -+ __u16 src_size; -+ __u16 dst_size; -+ struct __kernel_sockaddr_storage src_addr; -+ struct __kernel_sockaddr_storage dst_addr; -+}; -+ -+struct rdma_ucm_query_path_resp { -+ __u32 num_paths; -+ __u32 reserved; -+ struct ib_path_rec_data path_data[0]; -+}; -+ -+struct rdma_ucm_conn_param { -+ __u32 qp_num; -+ __u32 qkey; -+ __u8 private_data[RDMA_MAX_PRIVATE_DATA]; -+ __u8 private_data_len; -+ __u8 srq; -+ __u8 responder_resources; -+ __u8 initiator_depth; -+ __u8 flow_control; -+ __u8 retry_count; -+ __u8 rnr_retry_count; -+ __u8 valid; -+}; -+ -+struct rdma_ucm_ud_param { -+ __u32 qp_num; -+ __u32 qkey; -+ struct ib_uverbs_ah_attr ah_attr; -+ __u8 private_data[RDMA_MAX_PRIVATE_DATA]; -+ __u8 private_data_len; -+ __u8 reserved[7]; -+}; -+ -+struct rdma_ucm_connect { -+ struct rdma_ucm_conn_param conn_param; -+ __u32 id; -+ __u32 reserved; -+}; -+ -+struct rdma_ucm_listen { -+ __u32 id; -+ __u32 backlog; -+}; -+ -+struct rdma_ucm_accept { -+ __aligned_u64 uid; -+ struct rdma_ucm_conn_param conn_param; -+ __u32 id; -+ __u32 reserved; -+}; -+ -+struct rdma_ucm_reject { -+ __u32 id; -+ __u8 private_data_len; -+ __u8 reserved[3]; -+ __u8 private_data[RDMA_MAX_PRIVATE_DATA]; -+}; -+ -+struct rdma_ucm_disconnect { -+ __u32 id; -+}; -+ -+struct rdma_ucm_init_qp_attr { -+ __aligned_u64 response; -+ __u32 id; -+ __u32 qp_state; -+}; -+ -+struct rdma_ucm_notify { -+ __u32 id; -+ __u32 event; -+}; -+ -+struct rdma_ucm_join_ip_mcast { -+ __aligned_u64 response; /* rdma_ucm_create_id_resp */ -+ __aligned_u64 uid; -+ struct sockaddr_in6 addr; -+ __u32 id; -+}; -+ -+/* Multicast join flags */ -+enum { -+ RDMA_MC_JOIN_FLAG_FULLMEMBER, -+ RDMA_MC_JOIN_FLAG_SENDONLY_FULLMEMBER, -+ RDMA_MC_JOIN_FLAG_RESERVED, -+}; -+ -+struct rdma_ucm_join_mcast { -+ __aligned_u64 response; /* rdma_ucma_create_id_resp */ -+ __aligned_u64 uid; -+ __u32 id; -+ __u16 addr_size; -+ __u16 join_flags; -+ struct __kernel_sockaddr_storage addr; -+}; -+ -+struct rdma_ucm_get_event { -+ __aligned_u64 response; -+}; -+ -+struct rdma_ucm_event_resp { -+ __aligned_u64 uid; -+ __u32 id; -+ __u32 event; -+ __u32 status; -+ /* -+ * NOTE: This union is not aligned to 8 bytes so none of the union -+ * members may contain a u64 or anything with higher alignment than 4. -+ */ -+ union { -+ struct rdma_ucm_conn_param conn; -+ struct rdma_ucm_ud_param ud; -+ } param; -+ __u32 reserved; -+}; -+ -+/* Option levels */ -+enum { -+ RDMA_OPTION_ID = 0, -+ RDMA_OPTION_IB = 1 -+}; -+ -+/* Option details */ -+enum { -+ RDMA_OPTION_ID_TOS = 0, -+ RDMA_OPTION_ID_REUSEADDR = 1, -+ RDMA_OPTION_ID_AFONLY = 2, -+ RDMA_OPTION_IB_PATH = 1 -+}; -+ -+struct rdma_ucm_set_option { -+ __aligned_u64 optval; -+ __u32 id; -+ __u32 level; -+ __u32 optname; -+ __u32 optlen; -+}; -+ -+struct rdma_ucm_migrate_id { -+ __aligned_u64 response; -+ __u32 id; -+ __u32 fd; -+}; -+ -+struct rdma_ucm_migrate_resp { -+ __u32 events_reported; -+}; -+ -+#endif /* RDMA_USER_CM_H */ -diff --git a/rdma/link.c b/rdma/link.c -new file mode 100644 -index 0000000000000..c064be627be2c ---- /dev/null -+++ b/rdma/link.c -@@ -0,0 +1,355 @@ -+/* -+ * link.c RDMA tool -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ * -+ * Authors: Leon Romanovsky -+ */ -+ -+#include "rdma.h" -+ -+static int link_help(struct rd *rd) -+{ -+ pr_out("Usage: %s link show [DEV/PORT_INDEX]\n", rd->filename); -+ return 0; -+} -+ -+static const char *caps_to_str(uint32_t idx) -+{ -+#define RDMA_PORT_FLAGS_LOW(x) \ -+ x(RESERVED, 0) \ -+ x(SM, 1) \ -+ x(NOTICE, 2) \ -+ x(TRAP, 3) \ -+ x(OPT_IPD, 4) \ -+ x(AUTO_MIGR, 5) \ -+ x(SL_MAP, 6) \ -+ x(MKEY_NVRAM, 7) \ -+ x(PKEY_NVRAM, 8) \ -+ x(LED_INFO, 9) \ -+ x(SM_DISABLED, 10) \ -+ x(SYS_IMAGE_GUID, 11) \ -+ x(PKEY_SW_EXT_PORT_TRAP, 12) \ -+ x(CABLE_INFO, 13) \ -+ x(EXTENDED_SPEEDS, 14) \ -+ x(CAP_MASK2, 15) \ -+ x(CM, 16) \ -+ x(SNMP_TUNNEL, 17) \ -+ x(REINIT, 18) \ -+ x(DEVICE_MGMT, 19) \ -+ x(VENDOR_CLASS, 20) \ -+ x(DR_NOTICE, 21) \ -+ x(CAP_MASK_NOTICE, 22) \ -+ x(BOOT_MGMT, 23) \ -+ x(LINK_LATENCY, 24) \ -+ x(CLIENT_REG, 25) \ -+ x(OTHER_LOCAL_CHANGES, 26) \ -+ x(LINK_SPPED_WIDTH, 27) \ -+ x(VENDOR_SPECIFIC_MADS, 28) \ -+ x(MULT_PKER_TRAP, 29) \ -+ x(MULT_FDB, 30) \ -+ x(HIERARCHY_INFO, 31) -+ -+#define RDMA_PORT_FLAGS_HIGH(x) \ -+ x(SET_NODE_DESC, 0) \ -+ x(EXT_INFO, 1) \ -+ x(VIRT, 2) \ -+ x(SWITCH_POR_STATE_TABLE, 3) \ -+ x(LINK_WIDTH_2X, 4) \ -+ x(LINK_SPEED_HDR, 5) -+ -+ /* -+ * Separation below is needed to allow compilation of rdmatool -+ * on 32bits systems. On such systems, C-enum is limited to be -+ * int and can't hold more than 32 bits. -+ */ -+ enum { RDMA_PORT_FLAGS_LOW(RDMA_BITMAP_ENUM) }; -+ enum { RDMA_PORT_FLAGS_HIGH(RDMA_BITMAP_ENUM) }; -+ -+ static const char * const -+ rdma_port_names_low[] = { RDMA_PORT_FLAGS_LOW(RDMA_BITMAP_NAMES) }; -+ static const char * const -+ rdma_port_names_high[] = { RDMA_PORT_FLAGS_HIGH(RDMA_BITMAP_NAMES) }; -+ uint32_t high_idx; -+ #undef RDMA_PORT_FLAGS_LOW -+ #undef RDMA_PORT_FLAGS_HIGH -+ -+ if (idx < ARRAY_SIZE(rdma_port_names_low) && rdma_port_names_low[idx]) -+ return rdma_port_names_low[idx]; -+ -+ high_idx = idx - ARRAY_SIZE(rdma_port_names_low); -+ if (high_idx < ARRAY_SIZE(rdma_port_names_high) && -+ rdma_port_names_high[high_idx]) -+ return rdma_port_names_high[high_idx]; -+ -+ return "UNKNOWN"; -+} -+ -+static void link_print_caps(struct rd *rd, struct nlattr **tb) -+{ -+ uint64_t caps; -+ uint32_t idx; -+ -+ if (!tb[RDMA_NLDEV_ATTR_CAP_FLAGS]) -+ return; -+ -+ caps = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_CAP_FLAGS]); -+ -+ if (rd->json_output) { -+ jsonw_name(rd->jw, "caps"); -+ jsonw_start_array(rd->jw); -+ } else { -+ pr_out("\n caps: <"); -+ } -+ for (idx = 0; caps; idx++) { -+ if (caps & 0x1) { -+ if (rd->json_output) { -+ jsonw_string(rd->jw, caps_to_str(idx)); -+ } else { -+ pr_out("%s", caps_to_str(idx)); -+ if (caps >> 0x1) -+ pr_out(", "); -+ } -+ } -+ caps >>= 0x1; -+ } -+ -+ if (rd->json_output) -+ jsonw_end_array(rd->jw); -+ else -+ pr_out(">"); -+} -+ -+static void link_print_subnet_prefix(struct rd *rd, struct nlattr **tb) -+{ -+ uint64_t subnet_prefix; -+ uint16_t vp[4]; -+ char str[32]; -+ -+ if (!tb[RDMA_NLDEV_ATTR_SUBNET_PREFIX]) -+ return; -+ -+ subnet_prefix = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_SUBNET_PREFIX]); -+ memcpy(vp, &subnet_prefix, sizeof(uint64_t)); -+ snprintf(str, 32, "%04x:%04x:%04x:%04x", vp[3], vp[2], vp[1], vp[0]); -+ if (rd->json_output) -+ jsonw_string_field(rd->jw, "subnet_prefix", str); -+ else -+ pr_out("subnet_prefix %s ", str); -+} -+ -+static void link_print_lid(struct rd *rd, struct nlattr **tb) -+{ -+ uint32_t lid; -+ -+ if (!tb[RDMA_NLDEV_ATTR_LID]) -+ return; -+ -+ lid = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_LID]); -+ if (rd->json_output) -+ jsonw_uint_field(rd->jw, "lid", lid); -+ else -+ pr_out("lid %u ", lid); -+} -+ -+static void link_print_sm_lid(struct rd *rd, struct nlattr **tb) -+{ -+ uint32_t sm_lid; -+ -+ if (!tb[RDMA_NLDEV_ATTR_SM_LID]) -+ return; -+ -+ sm_lid = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_SM_LID]); -+ if (rd->json_output) -+ jsonw_uint_field(rd->jw, "sm_lid", sm_lid); -+ else -+ pr_out("sm_lid %u ", sm_lid); -+} -+ -+static void link_print_lmc(struct rd *rd, struct nlattr **tb) -+{ -+ uint8_t lmc; -+ -+ if (!tb[RDMA_NLDEV_ATTR_LMC]) -+ return; -+ -+ lmc = mnl_attr_get_u8(tb[RDMA_NLDEV_ATTR_LMC]); -+ if (rd->json_output) -+ jsonw_uint_field(rd->jw, "lmc", lmc); -+ else -+ pr_out("lmc %u ", lmc); -+} -+ -+static const char *link_state_to_str(uint8_t link_state) -+{ -+ static const char * const link_state_str[] = { "NOP", "DOWN", -+ "INIT", "ARMED", -+ "ACTIVE", -+ "ACTIVE_DEFER" }; -+ if (link_state < ARRAY_SIZE(link_state_str)) -+ return link_state_str[link_state]; -+ return "UNKNOWN"; -+} -+ -+static void link_print_state(struct rd *rd, struct nlattr **tb) -+{ -+ uint8_t state; -+ -+ if (!tb[RDMA_NLDEV_ATTR_PORT_STATE]) -+ return; -+ -+ state = mnl_attr_get_u8(tb[RDMA_NLDEV_ATTR_PORT_STATE]); -+ if (rd->json_output) -+ jsonw_string_field(rd->jw, "state", link_state_to_str(state)); -+ else -+ pr_out("state %s ", link_state_to_str(state)); -+} -+ -+static const char *phys_state_to_str(uint8_t phys_state) -+{ -+ static const char * const phys_state_str[] = { "NOP", "SLEEP", -+ "POLLING", "DISABLED", -+ "ARMED", "LINK_UP", -+ "LINK_ERROR_RECOVER", -+ "PHY_TEST", "UNKNOWN", -+ "OPA_OFFLINE", -+ "UNKNOWN", "OPA_TEST" }; -+ if (phys_state < ARRAY_SIZE(phys_state_str)) -+ return phys_state_str[phys_state]; -+ return "UNKNOWN"; -+}; -+ -+static void link_print_phys_state(struct rd *rd, struct nlattr **tb) -+{ -+ uint8_t phys_state; -+ -+ if (!tb[RDMA_NLDEV_ATTR_PORT_PHYS_STATE]) -+ return; -+ -+ phys_state = mnl_attr_get_u8(tb[RDMA_NLDEV_ATTR_PORT_PHYS_STATE]); -+ if (rd->json_output) -+ jsonw_string_field(rd->jw, "physical_state", -+ phys_state_to_str(phys_state)); -+ else -+ pr_out("physical_state %s ", phys_state_to_str(phys_state)); -+} -+ -+static void link_print_netdev(struct rd *rd, struct nlattr **tb) -+{ -+ const char *netdev_name; -+ uint32_t idx; -+ -+ if (!tb[RDMA_NLDEV_ATTR_NDEV_NAME] || !tb[RDMA_NLDEV_ATTR_NDEV_INDEX]) -+ return; -+ -+ netdev_name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_NDEV_NAME]); -+ idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_NDEV_INDEX]); -+ if (rd->json_output) { -+ jsonw_string_field(rd->jw, "netdev", netdev_name); -+ jsonw_uint_field(rd->jw, "netdev_index", idx); -+ } else { -+ pr_out("netdev %s ", netdev_name); -+ if (rd->show_details) -+ pr_out("netdev_index %u ", idx); -+ } -+} -+ -+static int link_parse_cb(const struct nlmsghdr *nlh, void *data) -+{ -+ struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {}; -+ struct rd *rd = data; -+ uint32_t port, idx; -+ char name[32]; -+ -+ mnl_attr_parse(nlh, 0, rd_attr_cb, tb); -+ if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME]) -+ return MNL_CB_ERROR; -+ -+ if (!tb[RDMA_NLDEV_ATTR_PORT_INDEX]) { -+ pr_err("This tool doesn't support switches yet\n"); -+ return MNL_CB_ERROR; -+ } -+ -+ idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]); -+ port = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_PORT_INDEX]); -+ snprintf(name, 32, "%s/%u", -+ mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]), port); -+ -+ if (rd->json_output) { -+ jsonw_uint_field(rd->jw, "ifindex", idx); -+ jsonw_uint_field(rd->jw, "port", port); -+ jsonw_string_field(rd->jw, "ifname", name); -+ -+ } else { -+ pr_out("%u/%u: %s: ", idx, port, name); -+ } -+ -+ link_print_subnet_prefix(rd, tb); -+ link_print_lid(rd, tb); -+ link_print_sm_lid(rd, tb); -+ link_print_lmc(rd, tb); -+ link_print_state(rd, tb); -+ link_print_phys_state(rd, tb); -+ link_print_netdev(rd, tb); -+ if (rd->show_details) -+ link_print_caps(rd, tb); -+ -+ if (!rd->json_output) -+ pr_out("\n"); -+ return MNL_CB_OK; -+} -+ -+static int link_no_args(struct rd *rd) -+{ -+ uint32_t seq; -+ int ret; -+ -+ rd_prepare_msg(rd, RDMA_NLDEV_CMD_PORT_GET, &seq, -+ (NLM_F_REQUEST | NLM_F_ACK)); -+ mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx); -+ mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_PORT_INDEX, rd->port_idx); -+ ret = rd_send_msg(rd); -+ if (ret) -+ return ret; -+ -+ if (rd->json_output) -+ jsonw_start_object(rd->jw); -+ ret = rd_recv_msg(rd, link_parse_cb, rd, seq); -+ if (rd->json_output) -+ jsonw_end_object(rd->jw); -+ return ret; -+} -+ -+static int link_one_show(struct rd *rd) -+{ -+ const struct rd_cmd cmds[] = { -+ { NULL, link_no_args}, -+ { 0 } -+ }; -+ -+ if (!rd->port_idx) -+ return 0; -+ -+ return rd_exec_cmd(rd, cmds, "parameter"); -+} -+ -+static int link_show(struct rd *rd) -+{ -+ return rd_exec_link(rd, link_one_show, true); -+} -+ -+int cmd_link(struct rd *rd) -+{ -+ const struct rd_cmd cmds[] = { -+ { NULL, link_show }, -+ { "show", link_show }, -+ { "list", link_show }, -+ { "help", link_help }, -+ { 0 } -+ }; -+ -+ return rd_exec_cmd(rd, cmds, "link command"); -+} -diff --git a/rdma/rdma.c b/rdma/rdma.c -new file mode 100644 -index 0000000000000..010e98371ef09 ---- /dev/null -+++ b/rdma/rdma.c -@@ -0,0 +1,203 @@ -+/* -+ * rdma.c RDMA tool -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ * -+ * Authors: Leon Romanovsky -+ */ -+ -+#include "rdma.h" -+#include "SNAPSHOT.h" -+ -+static void help(char *name) -+{ -+ pr_out("Usage: %s [ OPTIONS ] OBJECT { COMMAND | help }\n" -+ " %s [ -f[orce] ] -b[atch] filename\n" -+ "where OBJECT := { dev | link | resource | help }\n" -+ " OPTIONS := { -V[ersion] | -d[etails] | -j[son] | -p[retty]}\n", name, name); -+} -+ -+static int cmd_help(struct rd *rd) -+{ -+ help(rd->filename); -+ return 0; -+} -+ -+static int rd_cmd(struct rd *rd, int argc, char **argv) -+{ -+ const struct rd_cmd cmds[] = { -+ { NULL, cmd_help }, -+ { "help", cmd_help }, -+ { "dev", cmd_dev }, -+ { "link", cmd_link }, -+ { "resource", cmd_res }, -+ { 0 } -+ }; -+ -+ rd->argc = argc; -+ rd->argv = argv; -+ -+ return rd_exec_cmd(rd, cmds, "object"); -+} -+ -+static int rd_batch(struct rd *rd, const char *name, bool force) -+{ -+ char *line = NULL; -+ size_t len = 0; -+ int ret = 0; -+ -+ if (name && strcmp(name, "-") != 0) { -+ if (!freopen(name, "r", stdin)) { -+ pr_err("Cannot open file \"%s\" for reading: %s\n", -+ name, strerror(errno)); -+ return errno; -+ } -+ } -+ -+ cmdlineno = 0; -+ while (getcmdline(&line, &len, stdin) != -1) { -+ char *largv[512]; -+ int largc; -+ -+ largc = makeargs(line, largv, ARRAY_SIZE(largv)); -+ if (!largc) -+ continue; /* blank line */ -+ -+ ret = rd_cmd(rd, largc, largv); -+ if (ret) { -+ pr_err("Command failed %s:%d\n", name, cmdlineno); -+ if (!force) -+ break; -+ } -+ } -+ -+ free(line); -+ -+ return ret; -+} -+ -+static int rd_init(struct rd *rd, char *filename) -+{ -+ uint32_t seq; -+ int ret; -+ -+ rd->filename = filename; -+ INIT_LIST_HEAD(&rd->dev_map_list); -+ INIT_LIST_HEAD(&rd->filter_list); -+ -+ if (rd->json_output) { -+ rd->jw = jsonw_new(stdout); -+ if (!rd->jw) { -+ pr_err("Failed to create JSON writer\n"); -+ return -ENOMEM; -+ } -+ jsonw_pretty(rd->jw, rd->pretty_output); -+ } -+ -+ rd->buff = malloc(MNL_SOCKET_BUFFER_SIZE); -+ if (!rd->buff) -+ return -ENOMEM; -+ -+ rd_prepare_msg(rd, RDMA_NLDEV_CMD_GET, -+ &seq, (NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP)); -+ ret = rd_send_msg(rd); -+ if (ret) -+ return ret; -+ -+ return rd_recv_msg(rd, rd_dev_init_cb, rd, seq); -+} -+ -+static void rd_cleanup(struct rd *rd) -+{ -+ if (rd->json_output) -+ jsonw_destroy(&rd->jw); -+ rd_free(rd); -+} -+ -+int main(int argc, char **argv) -+{ -+ static const struct option long_options[] = { -+ { "version", no_argument, NULL, 'V' }, -+ { "help", no_argument, NULL, 'h' }, -+ { "json", no_argument, NULL, 'j' }, -+ { "pretty", no_argument, NULL, 'p' }, -+ { "details", no_argument, NULL, 'd' }, -+ { "force", no_argument, NULL, 'f' }, -+ { "batch", required_argument, NULL, 'b' }, -+ { NULL, 0, NULL, 0 } -+ }; -+ bool show_driver_details = false; -+ const char *batch_file = NULL; -+ bool pretty_output = false; -+ bool show_details = false; -+ bool json_output = false; -+ bool force = false; -+ struct rd rd = {}; -+ char *filename; -+ int opt; -+ int err; -+ -+ filename = basename(argv[0]); -+ -+ while ((opt = getopt_long(argc, argv, ":Vhdpjfb:", -+ long_options, NULL)) >= 0) { -+ switch (opt) { -+ case 'V': -+ printf("%s utility, iproute2-ss%s\n", -+ filename, SNAPSHOT); -+ return EXIT_SUCCESS; -+ case 'p': -+ pretty_output = true; -+ break; -+ case 'd': -+ if (show_details) -+ show_driver_details = true; -+ else -+ show_details = true; -+ break; -+ case 'j': -+ json_output = true; -+ break; -+ case 'f': -+ force = true; -+ break; -+ case 'b': -+ batch_file = optarg; -+ break; -+ case 'h': -+ help(filename); -+ return EXIT_SUCCESS; -+ case ':': -+ pr_err("-%c option requires an argument\n", optopt); -+ return EXIT_FAILURE; -+ default: -+ pr_err("Unknown option.\n"); -+ help(filename); -+ return EXIT_FAILURE; -+ } -+ } -+ -+ argc -= optind; -+ argv += optind; -+ -+ rd.show_details = show_details; -+ rd.show_driver_details = show_driver_details; -+ rd.json_output = json_output; -+ rd.pretty_output = pretty_output; -+ -+ err = rd_init(&rd, filename); -+ if (err) -+ goto out; -+ -+ if (batch_file) -+ err = rd_batch(&rd, batch_file, force); -+ else -+ err = rd_cmd(&rd, argc, argv); -+out: -+ /* Always cleanup */ -+ rd_cleanup(&rd); -+ return err ? EXIT_FAILURE : EXIT_SUCCESS; -+} -diff --git a/rdma/rdma.h b/rdma/rdma.h -new file mode 100644 -index 0000000000000..547bb5749a39f ---- /dev/null -+++ b/rdma/rdma.h -@@ -0,0 +1,131 @@ -+/* -+ * rdma.c RDMA tool -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ * -+ * Authors: Leon Romanovsky -+ */ -+#ifndef _RDMA_TOOL_H_ -+#define _RDMA_TOOL_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "list.h" -+#include "utils.h" -+#include "json_writer.h" -+ -+#define pr_err(args...) fprintf(stderr, ##args) -+#define pr_out(args...) fprintf(stdout, ##args) -+ -+#define RDMA_BITMAP_ENUM(name, bit_no) RDMA_BITMAP_##name = BIT(bit_no), -+#define RDMA_BITMAP_NAMES(name, bit_no) [bit_no] = #name, -+ -+#define MAX_NUMBER_OF_FILTERS 64 -+struct filters { -+ const char *name; -+ bool is_number; -+}; -+ -+struct filter_entry { -+ struct list_head list; -+ char *key; -+ char *value; -+}; -+ -+struct dev_map { -+ struct list_head list; -+ char *dev_name; -+ uint32_t num_ports; -+ uint32_t idx; -+}; -+ -+struct rd { -+ int argc; -+ char **argv; -+ char *filename; -+ bool show_details; -+ bool show_driver_details; -+ struct list_head dev_map_list; -+ uint32_t dev_idx; -+ uint32_t port_idx; -+ struct mnl_socket *nl; -+ struct nlmsghdr *nlh; -+ char *buff; -+ json_writer_t *jw; -+ bool json_output; -+ bool pretty_output; -+ struct list_head filter_list; -+}; -+ -+struct rd_cmd { -+ const char *cmd; -+ int (*func)(struct rd *rd); -+}; -+ -+/* -+ * Parser interface -+ */ -+bool rd_no_arg(struct rd *rd); -+void rd_arg_inc(struct rd *rd); -+ -+char *rd_argv(struct rd *rd); -+ -+/* -+ * Commands interface -+ */ -+int cmd_dev(struct rd *rd); -+int cmd_link(struct rd *rd); -+int cmd_res(struct rd *rd); -+int rd_exec_cmd(struct rd *rd, const struct rd_cmd *c, const char *str); -+int rd_exec_dev(struct rd *rd, int (*cb)(struct rd *rd)); -+int rd_exec_require_dev(struct rd *rd, int (*cb)(struct rd *rd)); -+int rd_exec_link(struct rd *rd, int (*cb)(struct rd *rd), bool strict_port); -+void rd_free(struct rd *rd); -+int rd_set_arg_to_devname(struct rd *rd); -+int rd_argc(struct rd *rd); -+ -+int strcmpx(const char *str1, const char *str2); -+ -+/* -+ * Device manipulation -+ */ -+struct dev_map *dev_map_lookup(struct rd *rd, bool allow_port_index); -+ -+/* -+ * Filter manipulation -+ */ -+int rd_build_filter(struct rd *rd, const struct filters valid_filters[]); -+bool rd_check_is_filtered(struct rd *rd, const char *key, uint32_t val); -+bool rd_check_is_string_filtered(struct rd *rd, const char *key, const char *val); -+bool rd_check_is_key_exist(struct rd *rd, const char *key); -+/* -+ * Netlink -+ */ -+int rd_send_msg(struct rd *rd); -+int rd_recv_msg(struct rd *rd, mnl_cb_t callback, void *data, uint32_t seq); -+void rd_prepare_msg(struct rd *rd, uint32_t cmd, uint32_t *seq, uint16_t flags); -+int rd_dev_init_cb(const struct nlmsghdr *nlh, void *data); -+int rd_attr_cb(const struct nlattr *attr, void *data); -+int rd_attr_check(const struct nlattr *attr, int *typep); -+ -+/* -+ * Print helpers -+ */ -+void print_driver_table(struct rd *rd, struct nlattr *tb); -+void newline(struct rd *rd); -+void newline_indent(struct rd *rd); -+#define MAX_LINE_LENGTH 80 -+ -+#endif /* _RDMA_TOOL_H_ */ -diff --git a/rdma/res.c b/rdma/res.c -new file mode 100644 -index 0000000000000..cbb2efe6c7235 ---- /dev/null -+++ b/rdma/res.c -@@ -0,0 +1,1111 @@ -+/* -+ * res.c RDMA tool -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ * -+ * Authors: Leon Romanovsky -+ */ -+ -+#include "rdma.h" -+#include -+ -+static int res_help(struct rd *rd) -+{ -+ pr_out("Usage: %s resource\n", rd->filename); -+ pr_out(" resource show [DEV]\n"); -+ pr_out(" resource show [qp|cm_id|pd|mr|cq]\n"); -+ pr_out(" resource show qp link [DEV/PORT]\n"); -+ pr_out(" resource show qp link [DEV/PORT] [FILTER-NAME FILTER-VALUE]\n"); -+ pr_out(" resource show cm_id link [DEV/PORT]\n"); -+ pr_out(" resource show cm_id link [DEV/PORT] [FILTER-NAME FILTER-VALUE]\n"); -+ pr_out(" resource show cq link [DEV/PORT]\n"); -+ pr_out(" resource show cq link [DEV/PORT] [FILTER-NAME FILTER-VALUE]\n"); -+ pr_out(" resource show pd dev [DEV]\n"); -+ pr_out(" resource show pd dev [DEV] [FILTER-NAME FILTER-VALUE]\n"); -+ pr_out(" resource show mr dev [DEV]\n"); -+ pr_out(" resource show mr dev [DEV] [FILTER-NAME FILTER-VALUE]\n"); -+ return 0; -+} -+ -+static int res_print_summary(struct rd *rd, struct nlattr **tb) -+{ -+ struct nlattr *nla_table = tb[RDMA_NLDEV_ATTR_RES_SUMMARY]; -+ struct nlattr *nla_entry; -+ const char *name; -+ uint64_t curr; -+ int err; -+ -+ mnl_attr_for_each_nested(nla_entry, nla_table) { -+ struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {}; -+ char json_name[32]; -+ -+ err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line); -+ if (err != MNL_CB_OK) -+ return -EINVAL; -+ -+ if (!nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME] || -+ !nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR]) { -+ return -EINVAL; -+ } -+ -+ name = mnl_attr_get_str(nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME]); -+ curr = mnl_attr_get_u64(nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR]); -+ if (rd->json_output) { -+ snprintf(json_name, 32, "%s", name); -+ jsonw_lluint_field(rd->jw, json_name, curr); -+ } else { -+ pr_out("%s %"PRId64 " ", name, curr); -+ } -+ } -+ return 0; -+} -+ -+static int res_no_args_parse_cb(const struct nlmsghdr *nlh, void *data) -+{ -+ struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {}; -+ struct rd *rd = data; -+ const char *name; -+ uint32_t idx; -+ -+ mnl_attr_parse(nlh, 0, rd_attr_cb, tb); -+ if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || -+ !tb[RDMA_NLDEV_ATTR_DEV_NAME] || -+ !tb[RDMA_NLDEV_ATTR_RES_SUMMARY]) -+ return MNL_CB_ERROR; -+ -+ idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]); -+ name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]); -+ if (rd->json_output) { -+ jsonw_uint_field(rd->jw, "ifindex", idx); -+ jsonw_string_field(rd->jw, "ifname", name); -+ } else { -+ pr_out("%u: %s: ", idx, name); -+ } -+ -+ res_print_summary(rd, tb); -+ -+ if (!rd->json_output) -+ pr_out("\n"); -+ return MNL_CB_OK; -+} -+ -+static int _res_send_msg(struct rd *rd, uint32_t command, mnl_cb_t callback) -+{ -+ uint32_t flags = NLM_F_REQUEST | NLM_F_ACK; -+ uint32_t seq; -+ int ret; -+ -+ if (command != RDMA_NLDEV_CMD_RES_GET) -+ flags |= NLM_F_DUMP; -+ -+ rd_prepare_msg(rd, command, &seq, flags); -+ mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx); -+ if (rd->port_idx) -+ mnl_attr_put_u32(rd->nlh, -+ RDMA_NLDEV_ATTR_PORT_INDEX, rd->port_idx); -+ -+ ret = rd_send_msg(rd); -+ if (ret) -+ return ret; -+ -+ if (rd->json_output) -+ jsonw_start_object(rd->jw); -+ ret = rd_recv_msg(rd, callback, rd, seq); -+ if (rd->json_output) -+ jsonw_end_object(rd->jw); -+ return ret; -+} -+ -+#define RES_FUNC(name, command, valid_filters, strict_port) \ -+ static int _##name(struct rd *rd)\ -+ { \ -+ return _res_send_msg(rd, command, name##_parse_cb); \ -+ } \ -+ static int name(struct rd *rd) \ -+ {\ -+ int ret = rd_build_filter(rd, valid_filters); \ -+ if (ret) \ -+ return ret; \ -+ if ((uintptr_t)valid_filters != (uintptr_t)NULL) { \ -+ ret = rd_set_arg_to_devname(rd); \ -+ if (ret) \ -+ return ret;\ -+ } \ -+ if (strict_port) \ -+ return rd_exec_dev(rd, _##name); \ -+ else \ -+ return rd_exec_link(rd, _##name, strict_port); \ -+ } -+ -+static const char *path_mig_to_str(uint8_t idx) -+{ -+ static const char * const path_mig_str[] = { "MIGRATED", -+ "REARM", "ARMED" }; -+ -+ if (idx < ARRAY_SIZE(path_mig_str)) -+ return path_mig_str[idx]; -+ return "UNKNOWN"; -+} -+ -+static const char *qp_states_to_str(uint8_t idx) -+{ -+ static const char * const qp_states_str[] = { "RESET", "INIT", -+ "RTR", "RTS", "SQD", -+ "SQE", "ERR" }; -+ -+ if (idx < ARRAY_SIZE(qp_states_str)) -+ return qp_states_str[idx]; -+ return "UNKNOWN"; -+} -+ -+static const char *qp_types_to_str(uint8_t idx) -+{ -+ static const char * const qp_types_str[] = { "SMI", "GSI", "RC", -+ "UC", "UD", "RAW_IPV6", -+ "RAW_ETHERTYPE", -+ "UNKNOWN", "RAW_PACKET", -+ "XRC_INI", "XRC_TGT" }; -+ -+ if (idx < ARRAY_SIZE(qp_types_str)) -+ return qp_types_str[idx]; -+ return "UNKNOWN"; -+} -+ -+static void print_lqpn(struct rd *rd, uint32_t val) -+{ -+ if (rd->json_output) -+ jsonw_uint_field(rd->jw, "lqpn", val); -+ else -+ pr_out("lqpn %u ", val); -+} -+ -+static void print_rqpn(struct rd *rd, uint32_t val, struct nlattr **nla_line) -+{ -+ if (!nla_line[RDMA_NLDEV_ATTR_RES_RQPN]) -+ return; -+ -+ if (rd->json_output) -+ jsonw_uint_field(rd->jw, "rqpn", val); -+ else -+ pr_out("rqpn %u ", val); -+} -+ -+static void print_type(struct rd *rd, uint32_t val) -+{ -+ if (rd->json_output) -+ jsonw_string_field(rd->jw, "type", -+ qp_types_to_str(val)); -+ else -+ pr_out("type %s ", qp_types_to_str(val)); -+} -+ -+static void print_state(struct rd *rd, uint32_t val) -+{ -+ if (rd->json_output) -+ jsonw_string_field(rd->jw, "state", -+ qp_states_to_str(val)); -+ else -+ pr_out("state %s ", qp_states_to_str(val)); -+} -+ -+static void print_rqpsn(struct rd *rd, uint32_t val, struct nlattr **nla_line) -+{ -+ if (!nla_line[RDMA_NLDEV_ATTR_RES_RQ_PSN]) -+ return; -+ -+ if (rd->json_output) -+ jsonw_uint_field(rd->jw, "rq-psn", val); -+ else -+ pr_out("rq-psn %u ", val); -+} -+ -+static void print_sqpsn(struct rd *rd, uint32_t val) -+{ -+ if (rd->json_output) -+ jsonw_uint_field(rd->jw, "sq-psn", val); -+ else -+ pr_out("sq-psn %u ", val); -+} -+ -+static void print_pathmig(struct rd *rd, uint32_t val, -+ struct nlattr **nla_line) -+{ -+ if (!nla_line[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE]) -+ return; -+ -+ if (rd->json_output) -+ jsonw_string_field(rd->jw, -+ "path-mig-state", -+ path_mig_to_str(val)); -+ else -+ pr_out("path-mig-state %s ", path_mig_to_str(val)); -+} -+ -+static void print_pid(struct rd *rd, uint32_t val) -+{ -+ if (rd->json_output) -+ jsonw_uint_field(rd->jw, "pid", val); -+ else -+ pr_out("pid %u ", val); -+} -+ -+static void print_comm(struct rd *rd, const char *str, -+ struct nlattr **nla_line) -+{ -+ char tmp[18]; -+ -+ if (rd->json_output) { -+ /* Don't beatify output in JSON format */ -+ jsonw_string_field(rd->jw, "comm", str); -+ return; -+ } -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) -+ snprintf(tmp, sizeof(tmp), "%s", str); -+ else -+ snprintf(tmp, sizeof(tmp), "[%s]", str); -+ -+ pr_out("comm %s ", tmp); -+} -+ -+static void print_dev(struct rd *rd, uint32_t idx, const char *name) -+{ -+ if (rd->json_output) { -+ jsonw_uint_field(rd->jw, "ifindex", idx); -+ jsonw_string_field(rd->jw, "ifname", name); -+ } else { -+ pr_out("dev %s ", name); -+ } -+} -+ -+static void print_link(struct rd *rd, uint32_t idx, const char *name, -+ uint32_t port, struct nlattr **nla_line) -+{ -+ if (rd->json_output) { -+ jsonw_uint_field(rd->jw, "ifindex", idx); -+ -+ if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]) -+ jsonw_uint_field(rd->jw, "port", port); -+ -+ jsonw_string_field(rd->jw, "ifname", name); -+ } else { -+ if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]) -+ pr_out("link %s/%u ", name, port); -+ else -+ pr_out("link %s/- ", name); -+ } -+} -+ -+static char *get_task_name(uint32_t pid) -+{ -+ char *comm; -+ FILE *f; -+ -+ if (asprintf(&comm, "/proc/%d/comm", pid) < 0) -+ return NULL; -+ -+ f = fopen(comm, "r"); -+ free(comm); -+ if (!f) -+ return NULL; -+ -+ if (fscanf(f, "%ms\n", &comm) != 1) -+ comm = NULL; -+ -+ fclose(f); -+ -+ return comm; -+} -+ -+static int res_qp_parse_cb(const struct nlmsghdr *nlh, void *data) -+{ -+ struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {}; -+ struct nlattr *nla_table, *nla_entry; -+ struct rd *rd = data; -+ const char *name; -+ uint32_t idx; -+ -+ mnl_attr_parse(nlh, 0, rd_attr_cb, tb); -+ if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || -+ !tb[RDMA_NLDEV_ATTR_DEV_NAME] || -+ !tb[RDMA_NLDEV_ATTR_RES_QP]) -+ return MNL_CB_ERROR; -+ -+ name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]); -+ idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]); -+ nla_table = tb[RDMA_NLDEV_ATTR_RES_QP]; -+ -+ mnl_attr_for_each_nested(nla_entry, nla_table) { -+ struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {}; -+ uint32_t lqpn, rqpn = 0, rq_psn = 0, sq_psn; -+ uint8_t type, state, path_mig_state = 0; -+ uint32_t port = 0, pid = 0; -+ char *comm = NULL; -+ int err; -+ -+ err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line); -+ if (err != MNL_CB_OK) -+ return MNL_CB_ERROR; -+ -+ if (!nla_line[RDMA_NLDEV_ATTR_RES_LQPN] || -+ !nla_line[RDMA_NLDEV_ATTR_RES_SQ_PSN] || -+ !nla_line[RDMA_NLDEV_ATTR_RES_TYPE] || -+ !nla_line[RDMA_NLDEV_ATTR_RES_STATE] || -+ (!nla_line[RDMA_NLDEV_ATTR_RES_PID] && -+ !nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])) { -+ return MNL_CB_ERROR; -+ } -+ -+ if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]) -+ port = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]); -+ -+ if (port != rd->port_idx) -+ continue; -+ -+ lqpn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_LQPN]); -+ if (rd_check_is_filtered(rd, "lqpn", lqpn)) -+ continue; -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_RQPN]) { -+ rqpn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_RQPN]); -+ if (rd_check_is_filtered(rd, "rqpn", rqpn)) -+ continue; -+ } else { -+ if (rd_check_is_key_exist(rd, "rqpn")) -+ continue; -+ } -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_RQ_PSN]) { -+ rq_psn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_RQ_PSN]); -+ if (rd_check_is_filtered(rd, "rq-psn", rq_psn)) -+ continue; -+ } else { -+ if (rd_check_is_key_exist(rd, "rq-psn")) -+ continue; -+ } -+ -+ sq_psn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_SQ_PSN]); -+ if (rd_check_is_filtered(rd, "sq-psn", sq_psn)) -+ continue; -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE]) { -+ path_mig_state = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE]); -+ if (rd_check_is_string_filtered(rd, "path-mig-state", path_mig_to_str(path_mig_state))) -+ continue; -+ } else { -+ if (rd_check_is_key_exist(rd, "path-mig-state")) -+ continue; -+ } -+ -+ type = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_TYPE]); -+ if (rd_check_is_string_filtered(rd, "type", qp_types_to_str(type))) -+ continue; -+ -+ state = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_STATE]); -+ if (rd_check_is_string_filtered(rd, "state", qp_states_to_str(state))) -+ continue; -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) { -+ pid = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PID]); -+ comm = get_task_name(pid); -+ } -+ -+ if (rd_check_is_filtered(rd, "pid", pid)) { -+ free(comm); -+ continue; -+ } -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]) -+ /* discard const from mnl_attr_get_str */ -+ comm = (char *)mnl_attr_get_str(nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]); -+ -+ if (rd->json_output) -+ jsonw_start_array(rd->jw); -+ -+ print_link(rd, idx, name, port, nla_line); -+ -+ print_lqpn(rd, lqpn); -+ print_rqpn(rd, rqpn, nla_line); -+ -+ print_type(rd, type); -+ print_state(rd, state); -+ -+ print_rqpsn(rd, rq_psn, nla_line); -+ print_sqpsn(rd, sq_psn); -+ -+ print_pathmig(rd, path_mig_state, nla_line); -+ print_pid(rd, pid); -+ print_comm(rd, comm, nla_line); -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) -+ free(comm); -+ -+ print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]); -+ newline(rd); -+ } -+ return MNL_CB_OK; -+} -+ -+static void print_qp_type(struct rd *rd, uint32_t val) -+{ -+ if (rd->json_output) -+ jsonw_string_field(rd->jw, "qp-type", -+ qp_types_to_str(val)); -+ else -+ pr_out("qp-type %s ", qp_types_to_str(val)); -+} -+ -+static const char *cm_id_state_to_str(uint8_t idx) -+{ -+ static const char * const cm_id_states_str[] = { -+ "IDLE", "ADDR_QUERY", "ADDR_RESOLVED", "ROUTE_QUERY", -+ "ROUTE_RESOLVED", "CONNECT", "DISCONNECT", "ADDR_BOUND", -+ "LISTEN", "DEVICE_REMOVAL", "DESTROYING" }; -+ -+ if (idx < ARRAY_SIZE(cm_id_states_str)) -+ return cm_id_states_str[idx]; -+ return "UNKNOWN"; -+} -+ -+static const char *cm_id_ps_to_str(uint32_t ps) -+{ -+ switch (ps) { -+ case RDMA_PS_IPOIB: -+ return "IPoIB"; -+ case RDMA_PS_IB: -+ return "IPoIB"; -+ case RDMA_PS_TCP: -+ return "TCP"; -+ case RDMA_PS_UDP: -+ return "UDP"; -+ default: -+ return "---"; -+ } -+} -+ -+static void print_cm_id_state(struct rd *rd, uint8_t state) -+{ -+ if (rd->json_output) { -+ jsonw_string_field(rd->jw, "state", cm_id_state_to_str(state)); -+ return; -+ } -+ pr_out("state %s ", cm_id_state_to_str(state)); -+} -+ -+static void print_ps(struct rd *rd, uint32_t ps) -+{ -+ if (rd->json_output) { -+ jsonw_string_field(rd->jw, "ps", cm_id_ps_to_str(ps)); -+ return; -+ } -+ pr_out("ps %s ", cm_id_ps_to_str(ps)); -+} -+ -+static void print_ipaddr(struct rd *rd, const char *key, char *addrstr, -+ uint16_t port) -+{ -+ if (rd->json_output) { -+ int name_size = INET6_ADDRSTRLEN+strlen(":65535"); -+ char json_name[name_size]; -+ -+ snprintf(json_name, name_size, "%s:%u", addrstr, port); -+ jsonw_string_field(rd->jw, key, json_name); -+ return; -+ } -+ pr_out("%s %s:%u ", key, addrstr, port); -+} -+ -+static int ss_ntop(struct nlattr *nla_line, char *addr_str, uint16_t *port) -+{ -+ struct __kernel_sockaddr_storage *addr; -+ -+ addr = (struct __kernel_sockaddr_storage *) -+ mnl_attr_get_payload(nla_line); -+ switch (addr->ss_family) { -+ case AF_INET: { -+ struct sockaddr_in *sin = (struct sockaddr_in *)addr; -+ -+ if (!inet_ntop(AF_INET, (const void *)&sin->sin_addr, addr_str, -+ INET6_ADDRSTRLEN)) -+ return -EINVAL; -+ *port = ntohs(sin->sin_port); -+ break; -+ } -+ case AF_INET6: { -+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr; -+ -+ if (!inet_ntop(AF_INET6, (const void *)&sin6->sin6_addr, -+ addr_str, INET6_ADDRSTRLEN)) -+ return -EINVAL; -+ *port = ntohs(sin6->sin6_port); -+ break; -+ } -+ default: -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+static int res_cm_id_parse_cb(const struct nlmsghdr *nlh, void *data) -+{ -+ struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {}; -+ struct nlattr *nla_table, *nla_entry; -+ struct rd *rd = data; -+ const char *name; -+ int idx; -+ -+ mnl_attr_parse(nlh, 0, rd_attr_cb, tb); -+ if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || -+ !tb[RDMA_NLDEV_ATTR_DEV_NAME] || -+ !tb[RDMA_NLDEV_ATTR_RES_CM_ID]) -+ return MNL_CB_ERROR; -+ -+ name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]); -+ idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]); -+ nla_table = tb[RDMA_NLDEV_ATTR_RES_CM_ID]; -+ mnl_attr_for_each_nested(nla_entry, nla_table) { -+ struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {}; -+ char src_addr_str[INET6_ADDRSTRLEN]; -+ char dst_addr_str[INET6_ADDRSTRLEN]; -+ uint16_t src_port, dst_port; -+ uint32_t port = 0, pid = 0; -+ uint8_t type = 0, state; -+ uint32_t lqpn = 0, ps; -+ char *comm = NULL; -+ int err; -+ -+ err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line); -+ if (err != MNL_CB_OK) -+ return -EINVAL; -+ -+ if (!nla_line[RDMA_NLDEV_ATTR_RES_STATE] || -+ !nla_line[RDMA_NLDEV_ATTR_RES_PS] || -+ (!nla_line[RDMA_NLDEV_ATTR_RES_PID] && -+ !nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])) { -+ return MNL_CB_ERROR; -+ } -+ -+ if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]) -+ port = mnl_attr_get_u32( -+ nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]); -+ -+ if (port && port != rd->port_idx) -+ continue; -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_LQPN]) { -+ lqpn = mnl_attr_get_u32( -+ nla_line[RDMA_NLDEV_ATTR_RES_LQPN]); -+ if (rd_check_is_filtered(rd, "lqpn", lqpn)) -+ continue; -+ } -+ if (nla_line[RDMA_NLDEV_ATTR_RES_TYPE]) { -+ type = mnl_attr_get_u8( -+ nla_line[RDMA_NLDEV_ATTR_RES_TYPE]); -+ if (rd_check_is_string_filtered(rd, "qp-type", -+ qp_types_to_str(type))) -+ continue; -+ } -+ -+ ps = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PS]); -+ if (rd_check_is_string_filtered(rd, "ps", cm_id_ps_to_str(ps))) -+ continue; -+ -+ state = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_STATE]); -+ if (rd_check_is_string_filtered(rd, "state", -+ cm_id_state_to_str(state))) -+ continue; -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR]) { -+ if (ss_ntop(nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR], -+ src_addr_str, &src_port)) -+ continue; -+ if (rd_check_is_string_filtered(rd, "src-addr", -+ src_addr_str)) -+ continue; -+ if (rd_check_is_filtered(rd, "src-port", src_port)) -+ continue; -+ } -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR]) { -+ if (ss_ntop(nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR], -+ dst_addr_str, &dst_port)) -+ continue; -+ if (rd_check_is_string_filtered(rd, "dst-addr", -+ dst_addr_str)) -+ continue; -+ if (rd_check_is_filtered(rd, "dst-port", dst_port)) -+ continue; -+ } -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) { -+ pid = mnl_attr_get_u32( -+ nla_line[RDMA_NLDEV_ATTR_RES_PID]); -+ comm = get_task_name(pid); -+ } -+ -+ if (rd_check_is_filtered(rd, "pid", pid)) { -+ free(comm); -+ continue; -+ } -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]) { -+ /* discard const from mnl_attr_get_str */ -+ comm = (char *)mnl_attr_get_str( -+ nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]); -+ } -+ -+ if (rd->json_output) -+ jsonw_start_array(rd->jw); -+ -+ print_link(rd, idx, name, port, nla_line); -+ if (nla_line[RDMA_NLDEV_ATTR_RES_LQPN]) -+ print_lqpn(rd, lqpn); -+ if (nla_line[RDMA_NLDEV_ATTR_RES_TYPE]) -+ print_qp_type(rd, type); -+ print_cm_id_state(rd, state); -+ print_ps(rd, ps); -+ print_pid(rd, pid); -+ print_comm(rd, comm, nla_line); -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR]) -+ print_ipaddr(rd, "src-addr", src_addr_str, src_port); -+ if (nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR]) -+ print_ipaddr(rd, "dst-addr", dst_addr_str, dst_port); -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) -+ free(comm); -+ -+ print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]); -+ newline(rd); -+ } -+ return MNL_CB_OK; -+} -+ -+static void print_cqe(struct rd *rd, uint32_t val) -+{ -+ if (rd->json_output) -+ jsonw_uint_field(rd->jw, "cqe", val); -+ else -+ pr_out("cqe %u ", val); -+} -+ -+static void print_users(struct rd *rd, uint64_t val) -+{ -+ if (rd->json_output) -+ jsonw_uint_field(rd->jw, "users", val); -+ else -+ pr_out("users %" PRIu64 " ", val); -+} -+ -+static const char *poll_ctx_to_str(uint8_t idx) -+{ -+ static const char * const cm_id_states_str[] = { -+ "DIRECT", "SOFTIRQ", "WORKQUEUE"}; -+ -+ if (idx < ARRAY_SIZE(cm_id_states_str)) -+ return cm_id_states_str[idx]; -+ return "UNKNOWN"; -+} -+ -+static void print_poll_ctx(struct rd *rd, uint8_t poll_ctx) -+{ -+ if (rd->json_output) { -+ jsonw_string_field(rd->jw, "poll-ctx", -+ poll_ctx_to_str(poll_ctx)); -+ return; -+ } -+ pr_out("poll-ctx %s ", poll_ctx_to_str(poll_ctx)); -+} -+ -+static int res_cq_parse_cb(const struct nlmsghdr *nlh, void *data) -+{ -+ struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {}; -+ struct nlattr *nla_table, *nla_entry; -+ struct rd *rd = data; -+ const char *name; -+ uint32_t idx; -+ -+ mnl_attr_parse(nlh, 0, rd_attr_cb, tb); -+ if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || -+ !tb[RDMA_NLDEV_ATTR_DEV_NAME] || -+ !tb[RDMA_NLDEV_ATTR_RES_CQ]) -+ return MNL_CB_ERROR; -+ -+ name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]); -+ idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]); -+ nla_table = tb[RDMA_NLDEV_ATTR_RES_CQ]; -+ -+ mnl_attr_for_each_nested(nla_entry, nla_table) { -+ struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {}; -+ char *comm = NULL; -+ uint32_t pid = 0; -+ uint8_t poll_ctx = 0; -+ uint64_t users; -+ uint32_t cqe; -+ int err; -+ -+ err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line); -+ if (err != MNL_CB_OK) -+ return MNL_CB_ERROR; -+ -+ if (!nla_line[RDMA_NLDEV_ATTR_RES_CQE] || -+ !nla_line[RDMA_NLDEV_ATTR_RES_USECNT] || -+ (!nla_line[RDMA_NLDEV_ATTR_RES_PID] && -+ !nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])) { -+ return MNL_CB_ERROR; -+ } -+ -+ cqe = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_CQE]); -+ -+ users = mnl_attr_get_u64(nla_line[RDMA_NLDEV_ATTR_RES_USECNT]); -+ if (rd_check_is_filtered(rd, "users", users)) -+ continue; -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_POLL_CTX]) { -+ poll_ctx = mnl_attr_get_u8( -+ nla_line[RDMA_NLDEV_ATTR_RES_POLL_CTX]); -+ if (rd_check_is_string_filtered(rd, "poll-ctx", -+ poll_ctx_to_str(poll_ctx))) -+ continue; -+ } -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) { -+ pid = mnl_attr_get_u32( -+ nla_line[RDMA_NLDEV_ATTR_RES_PID]); -+ comm = get_task_name(pid); -+ } -+ -+ if (rd_check_is_filtered(rd, "pid", pid)) { -+ free(comm); -+ continue; -+ } -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]) -+ /* discard const from mnl_attr_get_str */ -+ comm = (char *)mnl_attr_get_str( -+ nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]); -+ -+ if (rd->json_output) -+ jsonw_start_array(rd->jw); -+ -+ print_dev(rd, idx, name); -+ print_cqe(rd, cqe); -+ print_users(rd, users); -+ if (nla_line[RDMA_NLDEV_ATTR_RES_POLL_CTX]) -+ print_poll_ctx(rd, poll_ctx); -+ print_pid(rd, pid); -+ print_comm(rd, comm, nla_line); -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) -+ free(comm); -+ -+ print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]); -+ newline(rd); -+ } -+ return MNL_CB_OK; -+} -+ -+static void print_key(struct rd *rd, const char *name, uint32_t val) -+{ -+ if (rd->json_output) -+ jsonw_xint_field(rd->jw, name, val); -+ else -+ pr_out("%s 0x%x ", name, val); -+} -+ -+static void print_iova(struct rd *rd, uint64_t val) -+{ -+ if (rd->json_output) -+ jsonw_xint_field(rd->jw, "iova", val); -+ else -+ pr_out("iova 0x%" PRIx64 " ", val); -+} -+ -+static void print_mrlen(struct rd *rd, uint64_t val) -+{ -+ if (rd->json_output) -+ jsonw_uint_field(rd->jw, "mrlen", val); -+ else -+ pr_out("mrlen %" PRIu64 " ", val); -+} -+ -+static int res_mr_parse_cb(const struct nlmsghdr *nlh, void *data) -+{ -+ struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {}; -+ struct nlattr *nla_table, *nla_entry; -+ struct rd *rd = data; -+ const char *name; -+ uint32_t idx; -+ -+ mnl_attr_parse(nlh, 0, rd_attr_cb, tb); -+ if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || -+ !tb[RDMA_NLDEV_ATTR_DEV_NAME] || -+ !tb[RDMA_NLDEV_ATTR_RES_MR]) -+ return MNL_CB_ERROR; -+ -+ name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]); -+ idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]); -+ nla_table = tb[RDMA_NLDEV_ATTR_RES_MR]; -+ -+ mnl_attr_for_each_nested(nla_entry, nla_table) { -+ struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {}; -+ uint32_t rkey = 0, lkey = 0; -+ uint64_t iova = 0, mrlen; -+ char *comm = NULL; -+ uint32_t pid = 0; -+ int err; -+ -+ err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line); -+ if (err != MNL_CB_OK) -+ return MNL_CB_ERROR; -+ -+ if (!nla_line[RDMA_NLDEV_ATTR_RES_MRLEN] || -+ (!nla_line[RDMA_NLDEV_ATTR_RES_PID] && -+ !nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])) { -+ return MNL_CB_ERROR; -+ } -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_RKEY]) -+ rkey = mnl_attr_get_u32( -+ nla_line[RDMA_NLDEV_ATTR_RES_RKEY]); -+ if (nla_line[RDMA_NLDEV_ATTR_RES_LKEY]) -+ lkey = mnl_attr_get_u32( -+ nla_line[RDMA_NLDEV_ATTR_RES_LKEY]); -+ if (nla_line[RDMA_NLDEV_ATTR_RES_IOVA]) -+ iova = mnl_attr_get_u64( -+ nla_line[RDMA_NLDEV_ATTR_RES_IOVA]); -+ -+ mrlen = mnl_attr_get_u64(nla_line[RDMA_NLDEV_ATTR_RES_MRLEN]); -+ if (rd_check_is_filtered(rd, "mrlen", mrlen)) -+ continue; -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) { -+ pid = mnl_attr_get_u32( -+ nla_line[RDMA_NLDEV_ATTR_RES_PID]); -+ comm = get_task_name(pid); -+ } -+ -+ if (rd_check_is_filtered(rd, "pid", pid)) { -+ free(comm); -+ continue; -+ } -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]) -+ /* discard const from mnl_attr_get_str */ -+ comm = (char *)mnl_attr_get_str( -+ nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]); -+ -+ if (rd->json_output) -+ jsonw_start_array(rd->jw); -+ -+ print_dev(rd, idx, name); -+ if (nla_line[RDMA_NLDEV_ATTR_RES_RKEY]) -+ print_key(rd, "rkey", rkey); -+ if (nla_line[RDMA_NLDEV_ATTR_RES_LKEY]) -+ print_key(rd, "lkey", lkey); -+ if (nla_line[RDMA_NLDEV_ATTR_RES_IOVA]) -+ print_iova(rd, iova); -+ print_mrlen(rd, mrlen); -+ print_pid(rd, pid); -+ print_comm(rd, comm, nla_line); -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) -+ free(comm); -+ -+ print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]); -+ newline(rd); -+ } -+ return MNL_CB_OK; -+} -+ -+static int res_pd_parse_cb(const struct nlmsghdr *nlh, void *data) -+{ -+ struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {}; -+ struct nlattr *nla_table, *nla_entry; -+ struct rd *rd = data; -+ const char *name; -+ uint32_t idx; -+ -+ mnl_attr_parse(nlh, 0, rd_attr_cb, tb); -+ if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || -+ !tb[RDMA_NLDEV_ATTR_DEV_NAME] || -+ !tb[RDMA_NLDEV_ATTR_RES_PD]) -+ return MNL_CB_ERROR; -+ -+ name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]); -+ idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]); -+ nla_table = tb[RDMA_NLDEV_ATTR_RES_PD]; -+ -+ mnl_attr_for_each_nested(nla_entry, nla_table) { -+ uint32_t local_dma_lkey = 0, unsafe_global_rkey = 0; -+ struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {}; -+ char *comm = NULL; -+ uint32_t pid = 0; -+ uint64_t users; -+ int err; -+ -+ err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line); -+ if (err != MNL_CB_OK) -+ return MNL_CB_ERROR; -+ -+ if (!nla_line[RDMA_NLDEV_ATTR_RES_USECNT] || -+ (!nla_line[RDMA_NLDEV_ATTR_RES_PID] && -+ !nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])) { -+ return MNL_CB_ERROR; -+ } -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_LOCAL_DMA_LKEY]) -+ local_dma_lkey = mnl_attr_get_u32( -+ nla_line[RDMA_NLDEV_ATTR_RES_LOCAL_DMA_LKEY]); -+ -+ users = mnl_attr_get_u64(nla_line[RDMA_NLDEV_ATTR_RES_USECNT]); -+ if (rd_check_is_filtered(rd, "users", users)) -+ continue; -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_UNSAFE_GLOBAL_RKEY]) -+ unsafe_global_rkey = mnl_attr_get_u32( -+ nla_line[RDMA_NLDEV_ATTR_RES_UNSAFE_GLOBAL_RKEY]); -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) { -+ pid = mnl_attr_get_u32( -+ nla_line[RDMA_NLDEV_ATTR_RES_PID]); -+ comm = get_task_name(pid); -+ } -+ -+ if (rd_check_is_filtered(rd, "pid", pid)) -+ continue; -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]) -+ /* discard const from mnl_attr_get_str */ -+ comm = (char *)mnl_attr_get_str( -+ nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]); -+ -+ if (rd->json_output) -+ jsonw_start_array(rd->jw); -+ -+ print_dev(rd, idx, name); -+ if (nla_line[RDMA_NLDEV_ATTR_RES_LOCAL_DMA_LKEY]) -+ print_key(rd, "local_dma_lkey", local_dma_lkey); -+ print_users(rd, users); -+ if (nla_line[RDMA_NLDEV_ATTR_RES_UNSAFE_GLOBAL_RKEY]) -+ print_key(rd, "unsafe_global_rkey", unsafe_global_rkey); -+ print_pid(rd, pid); -+ print_comm(rd, comm, nla_line); -+ -+ if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) -+ free(comm); -+ -+ print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]); -+ newline(rd); -+ } -+ return MNL_CB_OK; -+} -+ -+RES_FUNC(res_no_args, RDMA_NLDEV_CMD_RES_GET, NULL, true); -+ -+static const struct -+filters qp_valid_filters[MAX_NUMBER_OF_FILTERS] = {{ .name = "link", -+ .is_number = false }, -+ { .name = "lqpn", -+ .is_number = true }, -+ { .name = "rqpn", -+ .is_number = true }, -+ { .name = "pid", -+ .is_number = true }, -+ { .name = "sq-psn", -+ .is_number = true }, -+ { .name = "rq-psn", -+ .is_number = true }, -+ { .name = "type", -+ .is_number = false }, -+ { .name = "path-mig-state", -+ .is_number = false }, -+ { .name = "state", -+ .is_number = false } }; -+ -+RES_FUNC(res_qp, RDMA_NLDEV_CMD_RES_QP_GET, qp_valid_filters, false); -+ -+static const -+struct filters cm_id_valid_filters[MAX_NUMBER_OF_FILTERS] = { -+ { .name = "link", .is_number = false }, -+ { .name = "lqpn", .is_number = true }, -+ { .name = "qp-type", .is_number = false }, -+ { .name = "state", .is_number = false }, -+ { .name = "ps", .is_number = false }, -+ { .name = "dev-type", .is_number = false }, -+ { .name = "transport-type", .is_number = false }, -+ { .name = "pid", .is_number = true }, -+ { .name = "src-addr", .is_number = false }, -+ { .name = "src-port", .is_number = true }, -+ { .name = "dst-addr", .is_number = false }, -+ { .name = "dst-port", .is_number = true } -+}; -+ -+RES_FUNC(res_cm_id, RDMA_NLDEV_CMD_RES_CM_ID_GET, cm_id_valid_filters, false); -+ -+static const -+struct filters cq_valid_filters[MAX_NUMBER_OF_FILTERS] = { -+ { .name = "dev", .is_number = false }, -+ { .name = "users", .is_number = true }, -+ { .name = "poll-ctx", .is_number = false }, -+ { .name = "pid", .is_number = true } -+}; -+ -+RES_FUNC(res_cq, RDMA_NLDEV_CMD_RES_CQ_GET, cq_valid_filters, true); -+ -+static const -+struct filters mr_valid_filters[MAX_NUMBER_OF_FILTERS] = { -+ { .name = "dev", .is_number = false }, -+ { .name = "rkey", .is_number = true }, -+ { .name = "lkey", .is_number = true }, -+ { .name = "mrlen", .is_number = true }, -+ { .name = "pid", .is_number = true } -+}; -+ -+RES_FUNC(res_mr, RDMA_NLDEV_CMD_RES_MR_GET, mr_valid_filters, true); -+ -+static const -+struct filters pd_valid_filters[MAX_NUMBER_OF_FILTERS] = { -+ { .name = "dev", .is_number = false }, -+ { .name = "users", .is_number = true }, -+ { .name = "pid", .is_number = true } -+}; -+ -+RES_FUNC(res_pd, RDMA_NLDEV_CMD_RES_PD_GET, pd_valid_filters, true); -+ -+static int res_show(struct rd *rd) -+{ -+ const struct rd_cmd cmds[] = { -+ { NULL, res_no_args }, -+ { "qp", res_qp }, -+ { "cm_id", res_cm_id }, -+ { "cq", res_cq }, -+ { "mr", res_mr }, -+ { "pd", res_pd }, -+ { 0 } -+ }; -+ -+ /* -+ * Special case to support "rdma res show DEV_NAME" -+ */ -+ if (rd_argc(rd) == 1 && dev_map_lookup(rd, false)) -+ return rd_exec_dev(rd, _res_no_args); -+ -+ return rd_exec_cmd(rd, cmds, "parameter"); -+} -+ -+int cmd_res(struct rd *rd) -+{ -+ const struct rd_cmd cmds[] = { -+ { NULL, res_show }, -+ { "show", res_show }, -+ { "list", res_show }, -+ { "help", res_help }, -+ { 0 } -+ }; -+ -+ return rd_exec_cmd(rd, cmds, "resource command"); -+} -diff --git a/rdma/utils.c b/rdma/utils.c -new file mode 100644 -index 0000000000000..069d44fece101 ---- /dev/null -+++ b/rdma/utils.c -@@ -0,0 +1,868 @@ -+/* -+ * utils.c RDMA tool -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ * -+ * Authors: Leon Romanovsky -+ */ -+ -+#include "rdma.h" -+#include -+#include -+ -+int rd_argc(struct rd *rd) -+{ -+ return rd->argc; -+} -+ -+char *rd_argv(struct rd *rd) -+{ -+ if (!rd_argc(rd)) -+ return NULL; -+ return *rd->argv; -+} -+ -+int strcmpx(const char *str1, const char *str2) -+{ -+ if (strlen(str1) > strlen(str2)) -+ return -1; -+ return strncmp(str1, str2, strlen(str1)); -+} -+ -+static bool rd_argv_match(struct rd *rd, const char *pattern) -+{ -+ if (!rd_argc(rd)) -+ return false; -+ return strcmpx(rd_argv(rd), pattern) == 0; -+} -+ -+void rd_arg_inc(struct rd *rd) -+{ -+ if (!rd_argc(rd)) -+ return; -+ rd->argc--; -+ rd->argv++; -+} -+ -+bool rd_no_arg(struct rd *rd) -+{ -+ return rd_argc(rd) == 0; -+} -+ -+/* -+ * Possible input:output -+ * dev/port | first port | is_dump_all -+ * mlx5_1 | 0 | true -+ * mlx5_1/ | 0 | true -+ * mlx5_1/0 | 0 | false -+ * mlx5_1/1 | 1 | false -+ * mlx5_1/- | 0 | false -+ * -+ * In strict mode, /- will return error. -+ */ -+static int get_port_from_argv(struct rd *rd, uint32_t *port, -+ bool *is_dump_all, bool strict_port) -+{ -+ char *slash; -+ -+ *port = 0; -+ *is_dump_all = true; -+ -+ slash = strchr(rd_argv(rd), '/'); -+ /* if no port found, return 0 */ -+ if (slash++) { -+ if (*slash == '-') { -+ if (strict_port) -+ return -EINVAL; -+ *is_dump_all = false; -+ return 0; -+ } -+ -+ if (isdigit(*slash)) { -+ *is_dump_all = false; -+ *port = atoi(slash); -+ } -+ if (!*port && strlen(slash)) -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+static struct dev_map *dev_map_alloc(const char *dev_name) -+{ -+ struct dev_map *dev_map; -+ -+ dev_map = calloc(1, sizeof(*dev_map)); -+ if (!dev_map) -+ return NULL; -+ dev_map->dev_name = strdup(dev_name); -+ if (!dev_map->dev_name) { -+ free(dev_map); -+ return NULL; -+ } -+ -+ return dev_map; -+} -+ -+static void dev_map_cleanup(struct rd *rd) -+{ -+ struct dev_map *dev_map, *tmp; -+ -+ list_for_each_entry_safe(dev_map, tmp, -+ &rd->dev_map_list, list) { -+ list_del(&dev_map->list); -+ free(dev_map->dev_name); -+ free(dev_map); -+ } -+} -+ -+static int add_filter(struct rd *rd, char *key, char *value, -+ const struct filters valid_filters[]) -+{ -+ char cset[] = "1234567890,-"; -+ struct filter_entry *fe; -+ bool key_found = false; -+ int idx = 0; -+ int ret; -+ -+ fe = calloc(1, sizeof(*fe)); -+ if (!fe) -+ return -ENOMEM; -+ -+ while (idx < MAX_NUMBER_OF_FILTERS && valid_filters[idx].name) { -+ if (!strcmpx(key, valid_filters[idx].name)) { -+ key_found = true; -+ break; -+ } -+ idx++; -+ } -+ if (!key_found) { -+ pr_err("Unsupported filter option: %s\n", key); -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ /* -+ * Check the filter validity, not optimal, but works -+ * -+ * Actually, there are three types of filters -+ * numeric - for example PID or QPN -+ * string - for example states -+ * link - user requested to filter on specific link -+ * e.g. mlx5_1/1, mlx5_1/-, mlx5_1 ... -+ */ -+ if (valid_filters[idx].is_number && -+ strspn(value, cset) != strlen(value)) { -+ pr_err("%s filter accepts \"%s\" characters only\n", key, cset); -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ fe->key = strdup(key); -+ fe->value = strdup(value); -+ if (!fe->key || !fe->value) { -+ ret = -ENOMEM; -+ goto err_alloc; -+ } -+ -+ for (idx = 0; idx < strlen(fe->value); idx++) -+ fe->value[idx] = tolower(fe->value[idx]); -+ -+ list_add_tail(&fe->list, &rd->filter_list); -+ return 0; -+ -+err_alloc: -+ free(fe->value); -+ free(fe->key); -+err: -+ free(fe); -+ return ret; -+} -+ -+int rd_build_filter(struct rd *rd, const struct filters valid_filters[]) -+{ -+ int ret = 0; -+ int idx = 0; -+ -+ if (!valid_filters || !rd_argc(rd)) -+ goto out; -+ -+ if (rd_argc(rd) == 1) { -+ pr_err("No filter data was supplied to filter option %s\n", rd_argv(rd)); -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ if (rd_argc(rd) % 2) { -+ pr_err("There is filter option without data\n"); -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ while (idx != rd_argc(rd)) { -+ /* -+ * We can do micro-optimization and skip "dev" -+ * and "link" filters, but it is not worth of it. -+ */ -+ ret = add_filter(rd, *(rd->argv + idx), -+ *(rd->argv + idx + 1), valid_filters); -+ if (ret) -+ goto out; -+ idx += 2; -+ } -+ -+out: -+ return ret; -+} -+ -+bool rd_check_is_key_exist(struct rd *rd, const char *key) -+{ -+ struct filter_entry *fe; -+ -+ list_for_each_entry(fe, &rd->filter_list, list) { -+ if (!strcmpx(fe->key, key)) -+ return true; -+ } -+ -+ return false; -+} -+ -+/* -+ * Check if string entry is filtered: -+ * * key doesn't exist -> user didn't request -> not filtered -+ */ -+bool rd_check_is_string_filtered(struct rd *rd, -+ const char *key, const char *val) -+{ -+ bool key_is_filtered = false; -+ struct filter_entry *fe; -+ char *p = NULL; -+ char *str; -+ -+ list_for_each_entry(fe, &rd->filter_list, list) { -+ if (!strcmpx(fe->key, key)) { -+ /* We found the key */ -+ p = strdup(fe->value); -+ key_is_filtered = true; -+ if (!p) { -+ /* -+ * Something extremely wrong if we fail -+ * to allocate small amount of bytes. -+ */ -+ pr_err("Found key, but failed to allocate memory to store value\n"); -+ return key_is_filtered; -+ } -+ -+ /* -+ * Need to check if value in range -+ * It can come in the following formats -+ * and their permutations: -+ * str -+ * str1,str2 -+ */ -+ str = strtok(p, ","); -+ while (str) { -+ if (strlen(str) == strlen(val) && -+ !strcasecmp(str, val)) { -+ key_is_filtered = false; -+ goto out; -+ } -+ str = strtok(NULL, ","); -+ } -+ goto out; -+ } -+ } -+ -+out: -+ free(p); -+ return key_is_filtered; -+} -+ -+/* -+ * Check if key is filtered: -+ * key doesn't exist -> user didn't request -> not filtered -+ */ -+bool rd_check_is_filtered(struct rd *rd, const char *key, uint32_t val) -+{ -+ bool key_is_filtered = false; -+ struct filter_entry *fe; -+ -+ list_for_each_entry(fe, &rd->filter_list, list) { -+ uint32_t left_val = 0, fe_value = 0; -+ bool range_check = false; -+ char *p = fe->value; -+ -+ if (!strcmpx(fe->key, key)) { -+ /* We found the key */ -+ key_is_filtered = true; -+ /* -+ * Need to check if value in range -+ * It can come in the following formats -+ * (and their permutations): -+ * numb -+ * numb1,numb2 -+ * ,numb1,numb2 -+ * numb1-numb2 -+ * numb1,numb2-numb3,numb4-numb5 -+ */ -+ while (*p) { -+ if (isdigit(*p)) { -+ fe_value = strtol(p, &p, 10); -+ if (fe_value == val || -+ (range_check && left_val < val && -+ val < fe_value)) { -+ key_is_filtered = false; -+ goto out; -+ } -+ range_check = false; -+ } else { -+ if (*p == '-') { -+ left_val = fe_value; -+ range_check = true; -+ } -+ p++; -+ } -+ } -+ goto out; -+ } -+ } -+ -+out: -+ return key_is_filtered; -+} -+ -+static void filters_cleanup(struct rd *rd) -+{ -+ struct filter_entry *fe, *tmp; -+ -+ list_for_each_entry_safe(fe, tmp, -+ &rd->filter_list, list) { -+ list_del(&fe->list); -+ free(fe->key); -+ free(fe->value); -+ free(fe); -+ } -+} -+ -+static const enum mnl_attr_data_type nldev_policy[RDMA_NLDEV_ATTR_MAX] = { -+ [RDMA_NLDEV_ATTR_DEV_INDEX] = MNL_TYPE_U32, -+ [RDMA_NLDEV_ATTR_DEV_NAME] = MNL_TYPE_NUL_STRING, -+ [RDMA_NLDEV_ATTR_PORT_INDEX] = MNL_TYPE_U32, -+ [RDMA_NLDEV_ATTR_CAP_FLAGS] = MNL_TYPE_U64, -+ [RDMA_NLDEV_ATTR_FW_VERSION] = MNL_TYPE_NUL_STRING, -+ [RDMA_NLDEV_ATTR_NODE_GUID] = MNL_TYPE_U64, -+ [RDMA_NLDEV_ATTR_SYS_IMAGE_GUID] = MNL_TYPE_U64, -+ [RDMA_NLDEV_ATTR_LID] = MNL_TYPE_U32, -+ [RDMA_NLDEV_ATTR_SM_LID] = MNL_TYPE_U32, -+ [RDMA_NLDEV_ATTR_LMC] = MNL_TYPE_U8, -+ [RDMA_NLDEV_ATTR_PORT_STATE] = MNL_TYPE_U8, -+ [RDMA_NLDEV_ATTR_PORT_PHYS_STATE] = MNL_TYPE_U8, -+ [RDMA_NLDEV_ATTR_DEV_NODE_TYPE] = MNL_TYPE_U8, -+ [RDMA_NLDEV_ATTR_RES_SUMMARY] = MNL_TYPE_NESTED, -+ [RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY] = MNL_TYPE_NESTED, -+ [RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME] = MNL_TYPE_NUL_STRING, -+ [RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR] = MNL_TYPE_U64, -+ [RDMA_NLDEV_ATTR_RES_QP] = MNL_TYPE_NESTED, -+ [RDMA_NLDEV_ATTR_RES_QP_ENTRY] = MNL_TYPE_NESTED, -+ [RDMA_NLDEV_ATTR_RES_LQPN] = MNL_TYPE_U32, -+ [RDMA_NLDEV_ATTR_RES_RQPN] = MNL_TYPE_U32, -+ [RDMA_NLDEV_ATTR_RES_RQ_PSN] = MNL_TYPE_U32, -+ [RDMA_NLDEV_ATTR_RES_SQ_PSN] = MNL_TYPE_U32, -+ [RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE] = MNL_TYPE_U8, -+ [RDMA_NLDEV_ATTR_RES_TYPE] = MNL_TYPE_U8, -+ [RDMA_NLDEV_ATTR_RES_STATE] = MNL_TYPE_U8, -+ [RDMA_NLDEV_ATTR_RES_PID] = MNL_TYPE_U32, -+ [RDMA_NLDEV_ATTR_RES_KERN_NAME] = MNL_TYPE_NUL_STRING, -+ [RDMA_NLDEV_ATTR_RES_CM_ID] = MNL_TYPE_NESTED, -+ [RDMA_NLDEV_ATTR_RES_CM_ID_ENTRY] = MNL_TYPE_NESTED, -+ [RDMA_NLDEV_ATTR_RES_PS] = MNL_TYPE_U32, -+ [RDMA_NLDEV_ATTR_RES_SRC_ADDR] = MNL_TYPE_UNSPEC, -+ [RDMA_NLDEV_ATTR_RES_DST_ADDR] = MNL_TYPE_UNSPEC, -+ [RDMA_NLDEV_ATTR_RES_CQ] = MNL_TYPE_NESTED, -+ [RDMA_NLDEV_ATTR_RES_CQ_ENTRY] = MNL_TYPE_NESTED, -+ [RDMA_NLDEV_ATTR_RES_CQE] = MNL_TYPE_U32, -+ [RDMA_NLDEV_ATTR_RES_USECNT] = MNL_TYPE_U64, -+ [RDMA_NLDEV_ATTR_RES_POLL_CTX] = MNL_TYPE_U8, -+ [RDMA_NLDEV_ATTR_RES_MR] = MNL_TYPE_NESTED, -+ [RDMA_NLDEV_ATTR_RES_MR_ENTRY] = MNL_TYPE_NESTED, -+ [RDMA_NLDEV_ATTR_RES_RKEY] = MNL_TYPE_U32, -+ [RDMA_NLDEV_ATTR_RES_LKEY] = MNL_TYPE_U32, -+ [RDMA_NLDEV_ATTR_RES_IOVA] = MNL_TYPE_U64, -+ [RDMA_NLDEV_ATTR_RES_MRLEN] = MNL_TYPE_U64, -+ [RDMA_NLDEV_ATTR_NDEV_INDEX] = MNL_TYPE_U32, -+ [RDMA_NLDEV_ATTR_NDEV_NAME] = MNL_TYPE_NUL_STRING, -+ [RDMA_NLDEV_ATTR_DRIVER] = MNL_TYPE_NESTED, -+ [RDMA_NLDEV_ATTR_DRIVER_ENTRY] = MNL_TYPE_NESTED, -+ [RDMA_NLDEV_ATTR_DRIVER_STRING] = MNL_TYPE_NUL_STRING, -+ [RDMA_NLDEV_ATTR_DRIVER_PRINT_TYPE] = MNL_TYPE_U8, -+ [RDMA_NLDEV_ATTR_DRIVER_S32] = MNL_TYPE_U32, -+ [RDMA_NLDEV_ATTR_DRIVER_U32] = MNL_TYPE_U32, -+ [RDMA_NLDEV_ATTR_DRIVER_S64] = MNL_TYPE_U64, -+ [RDMA_NLDEV_ATTR_DRIVER_U64] = MNL_TYPE_U64, -+}; -+ -+int rd_attr_check(const struct nlattr *attr, int *typep) -+{ -+ int type; -+ -+ if (mnl_attr_type_valid(attr, RDMA_NLDEV_ATTR_MAX) < 0) -+ return MNL_CB_ERROR; -+ -+ type = mnl_attr_get_type(attr); -+ -+ if (mnl_attr_validate(attr, nldev_policy[type]) < 0) -+ return MNL_CB_ERROR; -+ -+ *typep = nldev_policy[type]; -+ return MNL_CB_OK; -+} -+ -+int rd_attr_cb(const struct nlattr *attr, void *data) -+{ -+ const struct nlattr **tb = data; -+ int type; -+ -+ if (mnl_attr_type_valid(attr, RDMA_NLDEV_ATTR_MAX - 1) < 0) -+ /* We received unknown attribute */ -+ return MNL_CB_OK; -+ -+ type = mnl_attr_get_type(attr); -+ -+ if (mnl_attr_validate(attr, nldev_policy[type]) < 0) -+ return MNL_CB_ERROR; -+ -+ tb[type] = attr; -+ return MNL_CB_OK; -+} -+ -+int rd_dev_init_cb(const struct nlmsghdr *nlh, void *data) -+{ -+ struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {}; -+ struct dev_map *dev_map; -+ struct rd *rd = data; -+ const char *dev_name; -+ -+ mnl_attr_parse(nlh, 0, rd_attr_cb, tb); -+ if (!tb[RDMA_NLDEV_ATTR_DEV_NAME] || !tb[RDMA_NLDEV_ATTR_DEV_INDEX]) -+ return MNL_CB_ERROR; -+ if (!tb[RDMA_NLDEV_ATTR_PORT_INDEX]) { -+ pr_err("This tool doesn't support switches yet\n"); -+ return MNL_CB_ERROR; -+ } -+ -+ dev_name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]); -+ -+ dev_map = dev_map_alloc(dev_name); -+ if (!dev_map) -+ /* The main function will cleanup the allocations */ -+ return MNL_CB_ERROR; -+ list_add_tail(&dev_map->list, &rd->dev_map_list); -+ -+ dev_map->num_ports = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_PORT_INDEX]); -+ dev_map->idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]); -+ return MNL_CB_OK; -+} -+ -+void rd_free(struct rd *rd) -+{ -+ if (!rd) -+ return; -+ free(rd->buff); -+ dev_map_cleanup(rd); -+ filters_cleanup(rd); -+} -+ -+int rd_set_arg_to_devname(struct rd *rd) -+{ -+ int ret = 0; -+ -+ while (!rd_no_arg(rd)) { -+ if (rd_argv_match(rd, "dev") || rd_argv_match(rd, "link")) { -+ rd_arg_inc(rd); -+ if (rd_no_arg(rd)) { -+ pr_err("No device name was supplied\n"); -+ ret = -EINVAL; -+ } -+ goto out; -+ } -+ rd_arg_inc(rd); -+ } -+out: -+ return ret; -+} -+ -+int rd_exec_link(struct rd *rd, int (*cb)(struct rd *rd), bool strict_port) -+{ -+ struct dev_map *dev_map; -+ uint32_t port; -+ int ret = 0; -+ -+ if (rd->json_output) -+ jsonw_start_array(rd->jw); -+ if (rd_no_arg(rd)) { -+ list_for_each_entry(dev_map, &rd->dev_map_list, list) { -+ rd->dev_idx = dev_map->idx; -+ port = (strict_port) ? 1 : 0; -+ for (; port < dev_map->num_ports + 1; port++) { -+ rd->port_idx = port; -+ ret = cb(rd); -+ if (ret) -+ goto out; -+ } -+ } -+ -+ } else { -+ bool is_dump_all; -+ -+ dev_map = dev_map_lookup(rd, true); -+ ret = get_port_from_argv(rd, &port, &is_dump_all, strict_port); -+ if (!dev_map || port > dev_map->num_ports || (!port && ret)) { -+ pr_err("Wrong device name\n"); -+ ret = -ENOENT; -+ goto out; -+ } -+ rd_arg_inc(rd); -+ rd->dev_idx = dev_map->idx; -+ rd->port_idx = port; -+ for (; rd->port_idx < dev_map->num_ports + 1; rd->port_idx++) { -+ ret = cb(rd); -+ if (ret) -+ goto out; -+ if (!is_dump_all) -+ /* -+ * We got request to show link for devname -+ * with port index. -+ */ -+ break; -+ } -+ } -+ -+out: -+ if (rd->json_output) -+ jsonw_end_array(rd->jw); -+ return ret; -+} -+ -+int rd_exec_dev(struct rd *rd, int (*cb)(struct rd *rd)) -+{ -+ struct dev_map *dev_map; -+ int ret = 0; -+ -+ if (rd->json_output) -+ jsonw_start_array(rd->jw); -+ if (rd_no_arg(rd)) { -+ list_for_each_entry(dev_map, &rd->dev_map_list, list) { -+ rd->dev_idx = dev_map->idx; -+ ret = cb(rd); -+ if (ret) -+ goto out; -+ } -+ } else { -+ dev_map = dev_map_lookup(rd, false); -+ if (!dev_map) { -+ pr_err("Wrong device name - %s\n", rd_argv(rd)); -+ ret = -ENOENT; -+ goto out; -+ } -+ rd_arg_inc(rd); -+ rd->dev_idx = dev_map->idx; -+ ret = cb(rd); -+ } -+out: -+ if (rd->json_output) -+ jsonw_end_array(rd->jw); -+ return ret; -+} -+ -+int rd_exec_require_dev(struct rd *rd, int (*cb)(struct rd *rd)) -+{ -+ if (rd_no_arg(rd)) { -+ pr_err("Please provide device name.\n"); -+ return -EINVAL; -+ } -+ -+ return rd_exec_dev(rd, cb); -+} -+ -+int rd_exec_cmd(struct rd *rd, const struct rd_cmd *cmds, const char *str) -+{ -+ const struct rd_cmd *c; -+ -+ /* First argument in objs table is default variant */ -+ if (rd_no_arg(rd)) -+ return cmds->func(rd); -+ -+ for (c = cmds + 1; c->cmd; ++c) { -+ if (rd_argv_match(rd, c->cmd)) { -+ /* Move to next argument */ -+ rd_arg_inc(rd); -+ return c->func(rd); -+ } -+ } -+ -+ pr_err("Unknown %s '%s'.\n", str, rd_argv(rd)); -+ return 0; -+} -+ -+void rd_prepare_msg(struct rd *rd, uint32_t cmd, uint32_t *seq, uint16_t flags) -+{ -+ *seq = time(NULL); -+ -+ rd->nlh = mnl_nlmsg_put_header(rd->buff); -+ rd->nlh->nlmsg_type = RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, cmd); -+ rd->nlh->nlmsg_seq = *seq; -+ rd->nlh->nlmsg_flags = flags; -+} -+ -+int rd_send_msg(struct rd *rd) -+{ -+ int ret; -+ -+ rd->nl = mnl_socket_open(NETLINK_RDMA); -+ if (!rd->nl) { -+ pr_err("Failed to open NETLINK_RDMA socket\n"); -+ return -ENODEV; -+ } -+ -+ ret = mnl_socket_bind(rd->nl, 0, MNL_SOCKET_AUTOPID); -+ if (ret < 0) { -+ pr_err("Failed to bind socket with err %d\n", ret); -+ goto err; -+ } -+ -+ ret = mnl_socket_sendto(rd->nl, rd->nlh, rd->nlh->nlmsg_len); -+ if (ret < 0) { -+ pr_err("Failed to send to socket with err %d\n", ret); -+ goto err; -+ } -+ return 0; -+ -+err: -+ mnl_socket_close(rd->nl); -+ return ret; -+} -+ -+int rd_recv_msg(struct rd *rd, mnl_cb_t callback, void *data, unsigned int seq) -+{ -+ int ret; -+ unsigned int portid; -+ char buf[MNL_SOCKET_BUFFER_SIZE]; -+ -+ portid = mnl_socket_get_portid(rd->nl); -+ do { -+ ret = mnl_socket_recvfrom(rd->nl, buf, sizeof(buf)); -+ if (ret <= 0) -+ break; -+ -+ ret = mnl_cb_run(buf, ret, seq, portid, callback, data); -+ } while (ret > 0); -+ -+ mnl_socket_close(rd->nl); -+ return ret; -+} -+ -+static struct dev_map *_dev_map_lookup(struct rd *rd, const char *dev_name) -+{ -+ struct dev_map *dev_map; -+ -+ list_for_each_entry(dev_map, &rd->dev_map_list, list) -+ if (strcmp(dev_name, dev_map->dev_name) == 0) -+ return dev_map; -+ -+ return NULL; -+} -+ -+struct dev_map *dev_map_lookup(struct rd *rd, bool allow_port_index) -+{ -+ struct dev_map *dev_map; -+ char *dev_name; -+ char *slash; -+ -+ if (rd_no_arg(rd)) -+ return NULL; -+ -+ dev_name = strdup(rd_argv(rd)); -+ if (allow_port_index) { -+ slash = strrchr(dev_name, '/'); -+ if (slash) -+ *slash = '\0'; -+ } -+ -+ dev_map = _dev_map_lookup(rd, dev_name); -+ free(dev_name); -+ return dev_map; -+} -+ -+#define nla_type(attr) ((attr)->nla_type & NLA_TYPE_MASK) -+ -+void newline(struct rd *rd) -+{ -+ if (rd->json_output) -+ jsonw_end_array(rd->jw); -+ else -+ pr_out("\n"); -+} -+ -+void newline_indent(struct rd *rd) -+{ -+ newline(rd); -+ if (!rd->json_output) -+ pr_out(" "); -+} -+ -+static int print_driver_string(struct rd *rd, const char *key_str, -+ const char *val_str) -+{ -+ if (rd->json_output) { -+ jsonw_string_field(rd->jw, key_str, val_str); -+ return 0; -+ } else { -+ return pr_out("%s %s ", key_str, val_str); -+ } -+} -+ -+static int print_driver_s32(struct rd *rd, const char *key_str, int32_t val, -+ enum rdma_nldev_print_type print_type) -+{ -+ if (rd->json_output) { -+ jsonw_int_field(rd->jw, key_str, val); -+ return 0; -+ } -+ switch (print_type) { -+ case RDMA_NLDEV_PRINT_TYPE_UNSPEC: -+ return pr_out("%s %d ", key_str, val); -+ case RDMA_NLDEV_PRINT_TYPE_HEX: -+ return pr_out("%s 0x%x ", key_str, val); -+ default: -+ return -EINVAL; -+ } -+} -+ -+static int print_driver_u32(struct rd *rd, const char *key_str, uint32_t val, -+ enum rdma_nldev_print_type print_type) -+{ -+ if (rd->json_output) { -+ jsonw_int_field(rd->jw, key_str, val); -+ return 0; -+ } -+ switch (print_type) { -+ case RDMA_NLDEV_PRINT_TYPE_UNSPEC: -+ return pr_out("%s %u ", key_str, val); -+ case RDMA_NLDEV_PRINT_TYPE_HEX: -+ return pr_out("%s 0x%x ", key_str, val); -+ default: -+ return -EINVAL; -+ } -+} -+ -+static int print_driver_s64(struct rd *rd, const char *key_str, int64_t val, -+ enum rdma_nldev_print_type print_type) -+{ -+ if (rd->json_output) { -+ jsonw_int_field(rd->jw, key_str, val); -+ return 0; -+ } -+ switch (print_type) { -+ case RDMA_NLDEV_PRINT_TYPE_UNSPEC: -+ return pr_out("%s %" PRId64 " ", key_str, val); -+ case RDMA_NLDEV_PRINT_TYPE_HEX: -+ return pr_out("%s 0x%" PRIx64 " ", key_str, val); -+ default: -+ return -EINVAL; -+ } -+} -+ -+static int print_driver_u64(struct rd *rd, const char *key_str, uint64_t val, -+ enum rdma_nldev_print_type print_type) -+{ -+ if (rd->json_output) { -+ jsonw_int_field(rd->jw, key_str, val); -+ return 0; -+ } -+ switch (print_type) { -+ case RDMA_NLDEV_PRINT_TYPE_UNSPEC: -+ return pr_out("%s %" PRIu64 " ", key_str, val); -+ case RDMA_NLDEV_PRINT_TYPE_HEX: -+ return pr_out("%s 0x%" PRIx64 " ", key_str, val); -+ default: -+ return -EINVAL; -+ } -+} -+ -+static int print_driver_entry(struct rd *rd, struct nlattr *key_attr, -+ struct nlattr *val_attr, -+ enum rdma_nldev_print_type print_type) -+{ -+ const char *key_str = mnl_attr_get_str(key_attr); -+ int attr_type = nla_type(val_attr); -+ -+ switch (attr_type) { -+ case RDMA_NLDEV_ATTR_DRIVER_STRING: -+ return print_driver_string(rd, key_str, -+ mnl_attr_get_str(val_attr)); -+ case RDMA_NLDEV_ATTR_DRIVER_S32: -+ return print_driver_s32(rd, key_str, -+ mnl_attr_get_u32(val_attr), print_type); -+ case RDMA_NLDEV_ATTR_DRIVER_U32: -+ return print_driver_u32(rd, key_str, -+ mnl_attr_get_u32(val_attr), print_type); -+ case RDMA_NLDEV_ATTR_DRIVER_S64: -+ return print_driver_s64(rd, key_str, -+ mnl_attr_get_u64(val_attr), print_type); -+ case RDMA_NLDEV_ATTR_DRIVER_U64: -+ return print_driver_u64(rd, key_str, -+ mnl_attr_get_u64(val_attr), print_type); -+ } -+ return -EINVAL; -+} -+ -+void print_driver_table(struct rd *rd, struct nlattr *tb) -+{ -+ int print_type = RDMA_NLDEV_PRINT_TYPE_UNSPEC; -+ struct nlattr *tb_entry, *key = NULL, *val; -+ int type, cc = 0; -+ int ret; -+ -+ if (!rd->show_driver_details || !tb) -+ return; -+ -+ if (rd->pretty_output) -+ newline_indent(rd); -+ -+ /* -+ * Driver attrs are tuples of {key, [print-type], value}. -+ * The key must be a string. If print-type is present, it -+ * defines an alternate printf format type vs the native format -+ * for the attribute. And the value can be any available -+ * driver type. -+ */ -+ mnl_attr_for_each_nested(tb_entry, tb) { -+ -+ if (cc > MAX_LINE_LENGTH) { -+ if (rd->pretty_output) -+ newline_indent(rd); -+ cc = 0; -+ } -+ if (rd_attr_check(tb_entry, &type) != MNL_CB_OK) -+ return; -+ if (!key) { -+ if (type != MNL_TYPE_NUL_STRING) -+ return; -+ key = tb_entry; -+ } else if (type == MNL_TYPE_U8) { -+ print_type = mnl_attr_get_u8(tb_entry); -+ } else { -+ val = tb_entry; -+ ret = print_driver_entry(rd, key, val, print_type); -+ if (ret < 0) -+ return; -+ cc += ret; -+ print_type = RDMA_NLDEV_PRINT_TYPE_UNSPEC; -+ key = NULL; -+ } -+ } -+ return; -+} --- -2.21.0 - diff --git a/SOURCES/0068-rdma-add-man-pages-for-RDMA-tool.patch b/SOURCES/0068-rdma-add-man-pages-for-RDMA-tool.patch deleted file mode 100644 index 359615a..0000000 --- a/SOURCES/0068-rdma-add-man-pages-for-RDMA-tool.patch +++ /dev/null @@ -1,422 +0,0 @@ -From 4bee4617fa17405a52e11ed47e21feb20a277cc2 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Thu, 28 Mar 2019 15:00:33 +0100 -Subject: [PATCH] rdma: add man pages for RDMA tool - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1642479 -Upstream Status: RHEL-only - -commit 379afb6274462dee196d5909f6988b1ce5466c0b -Author: Andrea Claudi -Date: Thu Mar 28 13:02:20 2019 +0100 - - rdma: add man pages for RDMA tool - - Checkout to the v5.0.0 upstream tag and update man8 Makefile - - Signed-off-by: Andrea Claudi ---- - man/man8/Makefile | 2 +- - man/man8/rdma-dev.8 | 69 +++++++++++++++++++++++ - man/man8/rdma-link.8 | 56 ++++++++++++++++++ - man/man8/rdma-resource.8 | 109 +++++++++++++++++++++++++++++++++++ - man/man8/rdma.8 | 119 +++++++++++++++++++++++++++++++++++++++ - 5 files changed, 354 insertions(+), 1 deletion(-) - create mode 100644 man/man8/rdma-dev.8 - create mode 100644 man/man8/rdma-link.8 - create mode 100644 man/man8/rdma-resource.8 - create mode 100644 man/man8/rdma.8 - -diff --git a/man/man8/Makefile b/man/man8/Makefile -index f33186446819e..416443f3f5361 100644 ---- a/man/man8/Makefile -+++ b/man/man8/Makefile -@@ -19,7 +19,7 @@ MAN8PAGES = $(TARGETS) ip.8 arpd.8 lnstat.8 routel.8 rtacct.8 rtmon.8 rtpr.8 ss. - tc-simple.8 tc-skbedit.8 tc-vlan.8 tc-xt.8 tc-skbmod.8 tc-ife.8 \ - tc-tunnel_key.8 tc-sample.8 \ - devlink.8 devlink-dev.8 devlink-monitor.8 devlink-port.8 devlink-sb.8 \ -- ifstat.8 -+ ifstat.8 rdma.8 rdma-dev.8 rdma-link.8 rdma-resource.8 - - all: $(TARGETS) - -diff --git a/man/man8/rdma-dev.8 b/man/man8/rdma-dev.8 -new file mode 100644 -index 0000000000000..069f471791904 ---- /dev/null -+++ b/man/man8/rdma-dev.8 -@@ -0,0 +1,69 @@ -+.TH RDMA\-DEV 8 "06 Jul 2017" "iproute2" "Linux" -+.SH NAME -+rdma-dev \- RDMA device configuration -+.SH SYNOPSIS -+.sp -+.ad l -+.in +8 -+.ti -8 -+.B rdma -+.RI "[ " OPTIONS " ]" -+.B dev -+.RI " { " COMMAND " | " -+.BR help " }" -+.sp -+ -+.ti -8 -+.IR OPTIONS " := { " -+\fB\-V\fR[\fIersion\fR] | -+\fB\-d\fR[\fIetails\fR] } -+ -+.ti -8 -+.B rdma dev show -+.RI "[ " DEV " ]" -+ -+.ti -8 -+.B rdma dev set -+.RI "[ " DEV " ]" -+.BR name -+.BR NEWNAME -+ -+.ti -8 -+.B rdma dev help -+ -+.SH "DESCRIPTION" -+.SS rdma dev set - rename rdma device -+ -+.SS rdma dev show - display rdma device attributes -+ -+.PP -+.I "DEV" -+- specifies the RDMA device to show. -+If this argument is omitted all devices are listed. -+ -+.SH "EXAMPLES" -+.PP -+rdma dev -+.RS 4 -+Shows the state of all RDMA devices on the system. -+.RE -+.PP -+rdma dev show mlx5_3 -+.RS 4 -+Shows the state of specified RDMA device. -+.RE -+.PP -+rdma dev set mlx5_3 name rdma_0 -+.RS 4 -+Renames the mlx5_3 device to rdma_0. -+.RE -+.PP -+ -+.SH SEE ALSO -+.BR rdma (8), -+.BR rdma-link (8), -+.BR rdma-resource (8), -+.br -+ -+.SH AUTHOR -+Leon Romanovsky -diff --git a/man/man8/rdma-link.8 b/man/man8/rdma-link.8 -new file mode 100644 -index 0000000000000..bddf34746e8b2 ---- /dev/null -+++ b/man/man8/rdma-link.8 -@@ -0,0 +1,56 @@ -+.TH RDMA\-LINK 8 "06 Jul 2017" "iproute2" "Linux" -+.SH NAME -+rdma-link \- rdma link configuration -+.SH SYNOPSIS -+.sp -+.ad l -+.in +8 -+.ti -8 -+.B devlink -+.RI "[ " OPTIONS " ]" -+.B link -+.RI " { " COMMAND " | " -+.BR help " }" -+.sp -+ -+.ti -8 -+.IR OPTIONS " := { " -+\fB\-V\fR[\fIersion\fR] | -+\fB\-d\fR[\fIetails\fR] } -+ -+.ti -8 -+.B rdma link show -+.RI "[ " DEV/PORT_INDEX " ]" -+ -+.ti -8 -+.B rdma link help -+ -+.SH "DESCRIPTION" -+.SS rdma link show - display rdma link attributes -+ -+.PP -+.I "DEV/PORT_INDEX" -+- specifies the RDMA link to show. -+If this argument is omitted all links are listed. -+ -+.SH "EXAMPLES" -+.PP -+rdma link show -+.RS 4 -+Shows the state of all rdma links on the system. -+.RE -+.PP -+rdma link show mlx5_2/1 -+.RS 4 -+Shows the state of specified rdma link. -+.RE -+.PP -+ -+.SH SEE ALSO -+.BR rdma (8), -+.BR rdma-dev (8), -+.BR rdma-resource (8), -+.br -+ -+.SH AUTHOR -+Leon Romanovsky -diff --git a/man/man8/rdma-resource.8 b/man/man8/rdma-resource.8 -new file mode 100644 -index 0000000000000..40b073dbfcf24 ---- /dev/null -+++ b/man/man8/rdma-resource.8 -@@ -0,0 +1,109 @@ -+.TH RDMA\-RESOURCE 8 "26 Dec 2017" "iproute2" "Linux" -+.SH NAME -+rdma-resource \- rdma resource configuration -+.SH SYNOPSIS -+.sp -+.ad l -+.in +8 -+.ti -8 -+.B rdma -+.RI "[ " OPTIONS " ] " RESOURCE " { " COMMAND " | " -+.BR help " }" -+.sp -+ -+.ti -8 -+.IR RESOURCE " := { " -+.BR cm_id " | " cq " | " mr " | " pd " | " qp " }" -+.sp -+ -+.ti -8 -+.IR OPTIONS " := { " -+\fB\-j\fR[\fIson\fR] | -+\fB\-d\fR[\fIetails\fR] } -+ -+.ti -8 -+.B rdma resource show -+.RI "[ " DEV/PORT_INDEX " ]" -+ -+.ti -8 -+.B rdma resource help -+ -+.SH "DESCRIPTION" -+.SS rdma resource show - display rdma resource tracking information -+ -+.PP -+.I "DEV/PORT_INDEX" -+- specifies the RDMA link to show. -+If this argument is omitted all links are listed. -+ -+.SH "EXAMPLES" -+.PP -+rdma resource show -+.RS 4 -+Shows summary for all devices on the system. -+.RE -+.PP -+rdma resource show mlx5_2 -+.RS 4 -+Shows the state of specified rdma device. -+.RE -+.PP -+rdma res show qp link mlx5_4 -+.RS 4 -+Get all QPs for the specific device. -+.RE -+.PP -+rdma res show qp link mlx5_4/1 -+.RS 4 -+Get QPs of specific port. -+.RE -+.PP -+rdma res show qp link mlx5_4/0 -+.RS 4 -+Provide illegal port number (0 is illegal). -+.RE -+.PP -+rdma res show qp link mlx5_4/- -+.RS 4 -+Get QPs which have not assigned port yet. -+.RE -+.PP -+rdma res show qp link mlx5_4/- -d -+.RS 4 -+Detailed view. -+.RE -+.PP -+rdma res show qp link mlx5_4/- -dd -+.RS 4 -+Detailed view including driver-specific details. -+.RE -+.PP -+rdma res show qp link mlx5_4/1 lqpn 0-6 -+.RS 4 -+Limit to specific Local QPNs. -+.RE -+.PP -+rdma resource show cm_id dst-port 7174 -+.RS 4 -+Show CM_IDs with destination ip port of 7174. -+.RE -+.PP -+rdma resource show cm_id src-addr 172.16.0.100 -+.RS 4 -+Show CM_IDs bound to local ip address 172.16.0.100 -+.RE -+.PP -+rdma resource show cq pid 30489 -+.RS 4 -+Show CQs belonging to pid 30489 -+.RE -+.PP -+ -+.SH SEE ALSO -+.BR rdma (8), -+.BR rdma-dev (8), -+.BR rdma-link (8), -+.br -+ -+.SH AUTHOR -+Leon Romanovsky -diff --git a/man/man8/rdma.8 b/man/man8/rdma.8 -new file mode 100644 -index 0000000000000..b2b5aef866ab0 ---- /dev/null -+++ b/man/man8/rdma.8 -@@ -0,0 +1,119 @@ -+.TH RDMA 8 "28 Mar 2017" "iproute2" "Linux" -+.SH NAME -+rdma \- RDMA tool -+.SH SYNOPSIS -+.sp -+.ad l -+.in +8 -+.ti -8 -+.B rdma -+.RI "[ " OPTIONS " ] " OBJECT " { " COMMAND " | " -+.BR help " }" -+.sp -+ -+.ti -8 -+.B rdma -+.RB "[ " -force " ] " -+.BI "-batch " filename -+.sp -+ -+.ti -8 -+.IR OBJECT " := { " -+.BR dev " | " link " }" -+.sp -+ -+.ti -8 -+.IR OPTIONS " := { " -+\fB\-V\fR[\fIersion\fR] | -+\fB\-d\fR[\fIetails\fR] } -+\fB\-j\fR[\fIson\fR] } -+\fB\-p\fR[\fIretty\fR] } -+ -+.SH OPTIONS -+ -+.TP -+.BR "\-V" , " -Version" -+Print the version of the -+.B rdma -+tool and exit. -+ -+.TP -+.BR "\-b", " \-batch " -+Read commands from provided file or standard input and invoke them. -+First failure will cause termination of rdma. -+ -+.TP -+.BR "\-force" -+Don't terminate rdma on errors in batch mode. -+If there were any errors during execution of the commands, the application return code will be non zero. -+ -+.TP -+.BR "\-d" , " --details" -+Output detailed information. Adding a second \-d includes driver-specific details. -+ -+.TP -+.BR "\-p" , " --pretty" -+When combined with -j generate a pretty JSON output. -+ -+.TP -+.BR "\-j" , " --json" -+Generate JSON output. -+ -+.SS -+.I OBJECT -+ -+.TP -+.B dev -+- RDMA device. -+ -+.TP -+.B link -+- RDMA port related. -+ -+.PP -+The names of all objects may be written in full or -+abbreviated form, for example -+.B stats -+can be abbreviated as -+.B stat -+or just -+.B s. -+ -+.SS -+.I COMMAND -+ -+Specifies the action to perform on the object. -+The set of possible actions depends on the object type. -+As a rule, it is possible to -+.B show -+(or -+.B list -+) objects, but some objects do not allow all of these operations -+or have some additional commands. The -+.B help -+command is available for all objects. It prints -+out a list of available commands and argument syntax conventions. -+.sp -+If no command is given, some default command is assumed. -+Usually it is -+.B list -+or, if the objects of this class cannot be listed, -+.BR "help" . -+ -+.SH EXIT STATUS -+Exit status is 0 if command was successful or a positive integer upon failure. -+ -+.SH SEE ALSO -+.BR rdma-dev (8), -+.BR rdma-link (8), -+.BR rdma-resource (8), -+.br -+ -+.SH REPORTING BUGS -+Report any bugs to the Linux RDMA mailing list -+.B -+where the development and maintenance is primarily done. -+You do not have to be subscribed to the list to send a message there. -+ -+.SH AUTHOR -+Leon Romanovsky --- -2.21.0 - diff --git a/SOURCES/0069-tc-f_flower-Add-support-for-matching-first-frag-pack.patch b/SOURCES/0069-tc-f_flower-Add-support-for-matching-first-frag-pack.patch deleted file mode 100644 index 87a439c..0000000 --- a/SOURCES/0069-tc-f_flower-Add-support-for-matching-first-frag-pack.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 69685a7aa7fb408cce256e469430e10e99a43e2d Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 25 Mar 2019 16:54:31 +0100 -Subject: [PATCH] tc: f_flower: Add support for matching first frag packets - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1559814 -Upstream Status: iproute2.git commit fb4e6abfca2c4 - -commit fb4e6abfca2c48380210d48c1e7f3685f8bb58fd -Author: Pieter Jansen van Vuuren -Date: Fri Mar 9 11:07:22 2018 +0100 - - tc: f_flower: Add support for matching first frag packets - - Add matching support for distinguishing between first and later fragmented - packets. - - # tc filter add dev eth0 protocol ip parent ffff: \ - flower indev eth0 \ - ip_flags firstfrag \ - ip_proto udp \ - action mirred egress redirect dev eth1 - - # tc filter add dev eth0 protocol ip parent ffff: \ - flower indev eth0 \ - ip_flags nofirstfrag \ - ip_proto udp \ - action mirred egress redirect dev eth1 - - Signed-off-by: Pieter Jansen van Vuuren - Reviewed-by: Jakub Kicinski - Signed-off-by: Simon Horman - Signed-off-by: David Ahern ---- - man/man8/tc-flower.8 | 8 ++++++-- - tc/f_flower.c | 1 + - 2 files changed, 7 insertions(+), 2 deletions(-) - -diff --git a/man/man8/tc-flower.8 b/man/man8/tc-flower.8 -index 387f73f5cd2e9..661f42200bdfb 100644 ---- a/man/man8/tc-flower.8 -+++ b/man/man8/tc-flower.8 -@@ -255,8 +255,12 @@ is an 8 bit time-to-live value. - .BI ip_flags " IP_FLAGS" - .I IP_FLAGS - may be either --.BR frag " or " nofrag --to match on fragmented packets or not respectively. -+.BR frag ", " nofrag ", " firstfrag " or " nofirstfrag -+where frag and nofrag could be used to match on fragmented packets or not, -+respectively. firstfrag and nofirstfrag can be used to further distinguish -+fragmented packet. firstfrag can be used to indicate the first fragmented -+packet. nofirstfrag can be used to indicates subsequent fragmented packets -+or non-fragmented packets. - .SH NOTES - As stated above where applicable, matches of a certain layer implicitly depend - on the matches of the next lower layer. Precisely, layer one and two matches -diff --git a/tc/f_flower.c b/tc/f_flower.c -index 40dcfbd687a20..e2c7daa0b8e03 100644 ---- a/tc/f_flower.c -+++ b/tc/f_flower.c -@@ -162,6 +162,7 @@ struct flag_to_string { - - static struct flag_to_string flags_str[] = { - { TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT, FLOWER_IP_FLAGS, "frag" }, -+ { TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST, FLOWER_IP_FLAGS, "firstfrag" }, - }; - - static int flower_parse_matching_flags(char *str, --- -2.21.0 - diff --git a/SOURCES/0070-ss-enclose-IPv6-address-in-brackets.patch b/SOURCES/0070-ss-enclose-IPv6-address-in-brackets.patch deleted file mode 100644 index b0e68ba..0000000 --- a/SOURCES/0070-ss-enclose-IPv6-address-in-brackets.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 765baea7751f7140571dfb0285b1fca974b3450b Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 18:03:01 +0200 -Subject: [PATCH] ss: enclose IPv6 address in brackets - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1588122 -Upstream Status: iproute2.git commit aba9c23a6e1cb - -commit aba9c23a6e1cb134840c998df14888dca469a485 -Author: Stephen Hemminger -Date: Fri Aug 4 12:02:41 2017 -0700 - - ss: enclose IPv6 address in brackets - - Based on patch by Lehner Florian - - Adds support for RFC2732 IPv6 address format with brackets. - - Signed-off-by: Stephen Hemminger ---- - misc/ss.c | 25 +++++++++++++++++++------ - 1 file changed, 19 insertions(+), 6 deletions(-) - -diff --git a/misc/ss.c b/misc/ss.c -index c0cb33e96d9ec..86defc71fabc4 100644 ---- a/misc/ss.c -+++ b/misc/ss.c -@@ -1093,12 +1093,25 @@ static void inet_addr_print(const inet_prefix *a, int port, unsigned int ifindex - ap = format_host(AF_INET, 4, a->data); - } - } else { -- ap = format_host(a->family, 16, a->data); -- est_len = strlen(ap); -- if (est_len <= addr_width) -- est_len = addr_width; -- else -- est_len = addr_width + ((est_len-addr_width+3)/4)*4; -+ if (!memcmp(a->data, &in6addr_any, sizeof(in6addr_any))) { -+ buf[0] = '*'; -+ buf[1] = 0; -+ } else { -+ ap = format_host(a->family, 16, a->data); -+ -+ /* Numeric IPv6 addresses should be bracketed */ -+ if (strchr(ap, ':')) { -+ snprintf(buf, sizeof(buf), -+ "[%s]", ap); -+ ap = buf; -+ } -+ -+ est_len = strlen(ap); -+ if (est_len <= addr_width) -+ est_len = addr_width; -+ else -+ est_len = addr_width + ((est_len-addr_width+3)/4)*4; -+ } - } - - if (ifindex) { --- -2.21.0 - diff --git a/SOURCES/0071-ip-address-Use-correct-max-attribute-value-in-print_.patch b/SOURCES/0071-ip-address-Use-correct-max-attribute-value-in-print_.patch deleted file mode 100644 index d7b7a23..0000000 --- a/SOURCES/0071-ip-address-Use-correct-max-attribute-value-in-print_.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 861fe3293afa0907f9883df005e7a09a5f4b710b Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 18:14:04 +0200 -Subject: [PATCH] ip-address: Use correct max attribute value in - print_vf_stats64() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1679749 -Upstream Status: iproute2.git commit d7cf2416fc3a0 - -commit d7cf2416fc3a08b411beffb93a9e118f6593892d -Author: Phil Sutter -Date: Thu Feb 21 19:37:51 2019 +0100 - - ip-address: Use correct max attribute value in print_vf_stats64() - - IFLA_VF_MAX is larger than the highest valid index in vf array. - - Fixes: a1b99717c7cd7 ("Add displaying VF traffic statistics") - Signed-off-by: Phil Sutter - Signed-off-by: Stephen Hemminger ---- - ip/ipaddress.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ip/ipaddress.c b/ip/ipaddress.c -index 44111a27501a9..bed2d3801809b 100644 ---- a/ip/ipaddress.c -+++ b/ip/ipaddress.c -@@ -467,7 +467,7 @@ static void print_vf_stats64(FILE *fp, struct rtattr *vfstats) - return; - } - -- parse_rtattr_nested(vf, IFLA_VF_MAX, vfstats); -+ parse_rtattr_nested(vf, IFLA_VF_STATS_MAX, vfstats); - - /* RX stats */ - fprintf(fp, "%s", _SL_); --- -2.21.0 - diff --git a/SOURCES/0072-examples-Some-shell-fixes-to-cbq.init.patch b/SOURCES/0072-examples-Some-shell-fixes-to-cbq.init.patch deleted file mode 100644 index 2b8edfb..0000000 --- a/SOURCES/0072-examples-Some-shell-fixes-to-cbq.init.patch +++ /dev/null @@ -1,131 +0,0 @@ -From c1aa1bc599f0ced53b5e9d21d01a03d78ae2b37f Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:05:37 +0200 -Subject: [PATCH] examples: Some shell fixes to cbq.init - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 2313b6bfe4f5e - -commit 2313b6bfe4f5e6b60fcdfaaeaa1eabcfd3f550f4 -Author: Phil Sutter -Date: Thu Aug 17 19:09:31 2017 +0200 - - examples: Some shell fixes to cbq.init - - This addresses the following issues: - - - $@ is an array, so don't use it in quoted strings - use $* instead. - - - Add missing quotes to components of [ ] expressions. These are not - strictly necessary since the output of 'wc -l' should be a single word - only, but in case of errors, bash prints "integer expression expected" - instead of "too many arguments". - - - Use -print0/-0 when piping from find to xargs to allow for filenames - which contain whitespace. - - - Quote arguments to 'eval' to prevent word-splitting. - - Signed-off-by: Phil Sutter ---- - examples/cbq.init-v0.7.3 | 24 ++++++++++++------------ - 1 file changed, 12 insertions(+), 12 deletions(-) - -diff --git a/examples/cbq.init-v0.7.3 b/examples/cbq.init-v0.7.3 -index 1bc0d446f8983..66448d88f0053 100644 ---- a/examples/cbq.init-v0.7.3 -+++ b/examples/cbq.init-v0.7.3 -@@ -532,7 +532,7 @@ cbq_off () { - - ### Prefixed message - cbq_message () { -- echo -e "**CBQ: $@" -+ echo -e "**CBQ: $*" - } # cbq_message - - ### Failure message -@@ -560,15 +560,15 @@ cbq_time2abs () { - ### Display CBQ setup - cbq_show () { - for dev in `cbq_device_list`; do -- [ `tc qdisc show dev $dev| wc -l` -eq 0 ] && continue -+ [ "`tc qdisc show dev $dev| wc -l`" -eq 0 ] && continue - echo -e "### $dev: queueing disciplines\n" - tc $1 qdisc show dev $dev; echo - -- [ `tc class show dev $dev| wc -l` -eq 0 ] && continue -+ [ "`tc class show dev $dev| wc -l`" -eq 0 ] && continue - echo -e "### $dev: traffic classes\n" - tc $1 class show dev $dev; echo - -- [ `tc filter show dev $dev| wc -l` -eq 0 ] && continue -+ [ "`tc filter show dev $dev| wc -l`" -eq 0 ] && continue - echo -e "### $dev: filtering rules\n" - tc $1 filter show dev $dev; echo - done -@@ -585,7 +585,7 @@ cbq_init () { - - ### Gather all DEVICE fields from $1/cbq-* - DEVFIELDS=`find $1 -maxdepth 1 \( -type f -or -type l \) -name 'cbq-*' \ -- -not -name '*~' | xargs sed -n 's/#.*//; \ -+ -not -name '*~' -print0 | xargs -0 sed -n 's/#.*//; \ - s/[[:space:]]//g; /^DEVICE=[^,]*,[^,]*\(,[^,]*\)\?/ \ - { s/.*=//; p; }'| sort -u` - [ -z "$DEVFIELDS" ] && -@@ -593,7 +593,7 @@ cbq_init () { - - ### Check for different DEVICE fields for the same device - DEVICES=`echo "$DEVFIELDS"| sed 's/,.*//'| sort -u` -- [ `echo "$DEVICES"| wc -l` -ne `echo "$DEVFIELDS"| wc -l` ] && -+ [ "`echo "$DEVICES"| wc -l`" -ne "`echo "$DEVFIELDS"| wc -l`" ] && - cbq_failure "different DEVICE fields for single device!\n$DEVFIELDS" - } # cbq_init - -@@ -618,7 +618,7 @@ cbq_load_class () { - PRIO_MARK=$PRIO_MARK_DEFAULT - PRIO_REALM=$PRIO_REALM_DEFAULT - -- eval `echo "$CFILE"| grep -E "^($CBQ_WORDS)="` -+ eval "`echo "$CFILE"| grep -E "^($CBQ_WORDS)="`" - - ### Require RATE/WEIGHT - [ -z "$RATE" -o -z "$WEIGHT" ] && -@@ -661,7 +661,7 @@ if [ "$1" = "compile" ]; then - - ### echo-only version of "tc" command - tc () { -- echo "$TC $@" -+ echo "$TC $*" - } # tc - - elif [ -n "$CBQ_DEBUG" ]; then -@@ -669,13 +669,13 @@ elif [ -n "$CBQ_DEBUG" ]; then - - ### Logging version of "ip" command - ip () { -- echo -e "\n# ip $@" >> $CBQ_DEBUG -+ echo -e "\n# ip $*" >> $CBQ_DEBUG - $IP "$@" 2>&1 | tee -a $CBQ_DEBUG - } # ip - - ### Logging version of "tc" command - tc () { -- echo -e "\n# tc $@" >> $CBQ_DEBUG -+ echo -e "\n# tc $*" >> $CBQ_DEBUG - $TC "$@" 2>&1 | tee -a $CBQ_DEBUG - } # tc - else -@@ -711,8 +711,8 @@ if [ "$1" != "compile" -a "$2" != "nocache" -a -z "$CBQ_DEBUG" ]; then - ### validate the cache - [ "$2" = "invalidate" -o ! -f $CBQ_CACHE ] && VALID=0 - if [ $VALID -eq 1 ]; then -- [ `find $CBQ_PATH -maxdepth 1 -newer $CBQ_CACHE| \ -- wc -l` -gt 0 ] && VALID=0 -+ [ "`find $CBQ_PATH -maxdepth 1 -newer $CBQ_CACHE| \ -+ wc -l`" -gt 0 ] && VALID=0 - fi - - ### compile the config if the cache is invalid --- -2.21.0 - diff --git a/SOURCES/0073-ifcfg-Quote-left-hand-side-of-expression.patch b/SOURCES/0073-ifcfg-Quote-left-hand-side-of-expression.patch deleted file mode 100644 index f807555..0000000 --- a/SOURCES/0073-ifcfg-Quote-left-hand-side-of-expression.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 955ce06f1f4be5a8733e5829e3c8cadf9fc68c40 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:05:37 +0200 -Subject: [PATCH] ifcfg: Quote left-hand side of [ ] expression - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 1e3197e0fdbf2 - -commit 1e3197e0fdbf299fe24cdba7c0d613317ed82063 -Author: Phil Sutter -Date: Thu Aug 17 19:09:32 2017 +0200 - - ifcfg: Quote left-hand side of [ ] expression - - This prevents word-splitting and therefore leads to more accurate error - message in case 'grep -c' prints something other than a number. - - Signed-off-by: Phil Sutter ---- - ip/ifcfg | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ip/ifcfg b/ip/ifcfg -index 083d9df36742f..30a2dc49816cd 100644 ---- a/ip/ifcfg -+++ b/ip/ifcfg -@@ -131,7 +131,7 @@ noarp=$? - - ip route add unreachable 224.0.0.0/24 >& /dev/null - ip route add unreachable 255.255.255.255 >& /dev/null --if [ `ip link ls $dev | grep -c MULTICAST` -ge 1 ]; then -+if [ "`ip link ls $dev | grep -c MULTICAST`" -ge 1 ]; then - ip route add 224.0.0.0/4 dev $dev scope global >& /dev/null - fi - --- -2.21.0 - diff --git a/SOURCES/0074-tipc-node-Fix-socket-fd-check-in-cmd_node_get_addr.patch b/SOURCES/0074-tipc-node-Fix-socket-fd-check-in-cmd_node_get_addr.patch deleted file mode 100644 index 0644d59..0000000 --- a/SOURCES/0074-tipc-node-Fix-socket-fd-check-in-cmd_node_get_addr.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 8743a7a8978270195693441f370cea552f100cae Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:05:38 +0200 -Subject: [PATCH] tipc/node: Fix socket fd check in cmd_node_get_addr() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 436270a45dea2 - -commit 436270a45dea2fe5dbc4680f9c8e31f07d167f20 -Author: Phil Sutter -Date: Thu Aug 17 19:09:32 2017 +0200 - - tipc/node: Fix socket fd check in cmd_node_get_addr() - - socket() returns -1 on error, not 0. - - Signed-off-by: Phil Sutter ---- - tipc/node.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/tipc/node.c b/tipc/node.c -index 201fe1a4df3bd..fe085aec9b4ac 100644 ---- a/tipc/node.c -+++ b/tipc/node.c -@@ -109,7 +109,8 @@ static int cmd_node_get_addr(struct nlmsghdr *nlh, const struct cmd *cmd, - socklen_t sz = sizeof(struct sockaddr_tipc); - struct sockaddr_tipc addr; - -- if (!(sk = socket(AF_TIPC, SOCK_RDM, 0))) { -+ sk = socket(AF_TIPC, SOCK_RDM, 0); -+ if (sk < 0) { - fprintf(stderr, "opening TIPC socket: %s\n", strerror(errno)); - return -1; - } --- -2.21.0 - diff --git a/SOURCES/0075-iproute_lwtunnel-Argument-to-strerror-must-be-positi.patch b/SOURCES/0075-iproute_lwtunnel-Argument-to-strerror-must-be-positi.patch deleted file mode 100644 index 1eedb0f..0000000 --- a/SOURCES/0075-iproute_lwtunnel-Argument-to-strerror-must-be-positi.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 4e55e568493084c458ef96f10a2a3dab93e8464a Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:05:38 +0200 -Subject: [PATCH] iproute_lwtunnel: Argument to strerror must be positive - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 58a15e6c7e7cb - -commit 58a15e6c7e7cb4c0d25e6bb3762ac2b1c94ff523 -Author: Phil Sutter -Date: Thu Aug 17 19:09:31 2017 +0200 - - iproute_lwtunnel: Argument to strerror must be positive - - Signed-off-by: Phil Sutter ---- - ip/iproute_lwtunnel.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c -index b6f08f073ef02..92ea2c87787ec 100644 ---- a/ip/iproute_lwtunnel.c -+++ b/ip/iproute_lwtunnel.c -@@ -480,7 +480,7 @@ static int lwt_parse_bpf(struct rtattr *rta, size_t len, - err = bpf_parse_common(bpf_type, &cfg, &bpf_cb_ops, &x); - if (err < 0) { - fprintf(stderr, "Failed to parse eBPF program: %s\n", -- strerror(err)); -+ strerror(-err)); - return -1; - } - rta_nest_end(rta, nest); --- -2.21.0 - diff --git a/SOURCES/0076-iproute_lwtunnel-csum_mode-value-checking-was-ineffe.patch b/SOURCES/0076-iproute_lwtunnel-csum_mode-value-checking-was-ineffe.patch deleted file mode 100644 index 89b7b36..0000000 --- a/SOURCES/0076-iproute_lwtunnel-csum_mode-value-checking-was-ineffe.patch +++ /dev/null @@ -1,61 +0,0 @@ -From db11067fb37cc3a77cc70fb9233a454102c4854c Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:05:38 +0200 -Subject: [PATCH] iproute_lwtunnel: csum_mode value checking was ineffective - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 08806fb0191e9 -Conflicts: adjust rta_addattr8() call to handle return value - -commit 08806fb0191e9ee8769507dc93b722fd021feb34 -Author: Phil Sutter -Date: Thu Aug 17 19:09:30 2017 +0200 - - iproute_lwtunnel: csum_mode value checking was ineffective - - ila_csum_name2mode() returning -1 on error but being declared as - returning __u8 doesn't make much sense. Change the code to correctly - detect this issue. Checking for __u8 overruns shouldn't be necessary - though since ila_csum_name2mode() return values are well-defined. - - Signed-off-by: Phil Sutter ---- - ip/iproute_lwtunnel.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c -index 92ea2c87787ec..5da3a1b488cbd 100644 ---- a/ip/iproute_lwtunnel.c -+++ b/ip/iproute_lwtunnel.c -@@ -125,7 +125,7 @@ static char *ila_csum_mode2name(__u8 csum_mode) - } - } - --static __u8 ila_csum_name2mode(char *name) -+static int ila_csum_name2mode(char *name) - { - if (strcmp(name, "adj-transport") == 0) - return ILA_CSUM_ADJUST_TRANSPORT; -@@ -348,7 +348,7 @@ static int parse_encap_ila(struct rtattr *rta, size_t len, - - while (argc > 0) { - if (strcmp(*argv, "csum-mode") == 0) { -- __u8 csum_mode; -+ int csum_mode; - - NEXT_ARG(); - -@@ -357,8 +357,8 @@ static int parse_encap_ila(struct rtattr *rta, size_t len, - invarg("\"csum-mode\" value is invalid\n", - *argv); - -- ret = rta_addattr8(rta, len, ILA_ATTR_CSUM_MODE, -- (__u8)csum_mode); -+ ret = rta_addattr8(rta, 1024, ILA_ATTR_CSUM_MODE, -+ (__u8)csum_mode); - - argc--; argv++; - } else { --- -2.21.0 - diff --git a/SOURCES/0077-ss-Don-t-leak-fd-in-tcp_show_netlink_file.patch b/SOURCES/0077-ss-Don-t-leak-fd-in-tcp_show_netlink_file.patch deleted file mode 100644 index e1a8abf..0000000 --- a/SOURCES/0077-ss-Don-t-leak-fd-in-tcp_show_netlink_file.patch +++ /dev/null @@ -1,107 +0,0 @@ -From fa8b9f8fa8a6762bb0151e65a11eca9dca7aca83 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:07:22 +0200 -Subject: [PATCH] ss: Don't leak fd in tcp_show_netlink_file() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 4b45ae221e949 - -commit 4b45ae221e949b604d968a10d5d996c7c7cec1a6 -Author: Phil Sutter -Date: Thu Aug 17 19:09:30 2017 +0200 - - ss: Don't leak fd in tcp_show_netlink_file() - - Signed-off-by: Phil Sutter ---- - misc/ss.c | 32 ++++++++++++++++++++------------ - 1 file changed, 20 insertions(+), 12 deletions(-) - -diff --git a/misc/ss.c b/misc/ss.c -index 86defc71fabc4..eb46e0c4b95fb 100644 ---- a/misc/ss.c -+++ b/misc/ss.c -@@ -2764,41 +2764,44 @@ static int tcp_show_netlink_file(struct filter *f) - { - FILE *fp; - char buf[16384]; -+ int err = -1; - - if ((fp = fopen(getenv("TCPDIAG_FILE"), "r")) == NULL) { - perror("fopen($TCPDIAG_FILE)"); -- return -1; -+ return err; - } - - while (1) { -- int status, err; -+ int status, err2; - struct nlmsghdr *h = (struct nlmsghdr *)buf; - struct sockstat s = {}; - - status = fread(buf, 1, sizeof(*h), fp); - if (status < 0) { - perror("Reading header from $TCPDIAG_FILE"); -- return -1; -+ break; - } - if (status != sizeof(*h)) { - perror("Unexpected EOF reading $TCPDIAG_FILE"); -- return -1; -+ break; - } - - status = fread(h+1, 1, NLMSG_ALIGN(h->nlmsg_len-sizeof(*h)), fp); - - if (status < 0) { - perror("Reading $TCPDIAG_FILE"); -- return -1; -+ break; - } - if (status + sizeof(*h) < h->nlmsg_len) { - perror("Unexpected EOF reading $TCPDIAG_FILE"); -- return -1; -+ break; - } - - /* The only legal exit point */ -- if (h->nlmsg_type == NLMSG_DONE) -- return 0; -+ if (h->nlmsg_type == NLMSG_DONE) { -+ err = 0; -+ break; -+ } - - if (h->nlmsg_type == NLMSG_ERROR) { - struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(h); -@@ -2809,7 +2812,7 @@ static int tcp_show_netlink_file(struct filter *f) - errno = -err->error; - perror("TCPDIAG answered"); - } -- return -1; -+ break; - } - - parse_diag_msg(h, &s); -@@ -2818,10 +2821,15 @@ static int tcp_show_netlink_file(struct filter *f) - if (f && f->f && run_ssfilter(f->f, &s) == 0) - continue; - -- err = inet_show_sock(h, &s); -- if (err < 0) -- return err; -+ err2 = inet_show_sock(h, &s); -+ if (err2 < 0) { -+ err = err2; -+ break; -+ } - } -+ -+ fclose(fp); -+ return err; - } - - static int tcp_show(struct filter *f) --- -2.21.0 - diff --git a/SOURCES/0078-tc-em_ipset-Don-t-leak-sockfd-on-error-path.patch b/SOURCES/0078-tc-em_ipset-Don-t-leak-sockfd-on-error-path.patch deleted file mode 100644 index 8059e72..0000000 --- a/SOURCES/0078-tc-em_ipset-Don-t-leak-sockfd-on-error-path.patch +++ /dev/null @@ -1,34 +0,0 @@ -From d28ee4b622ad9fa10a81d88bb6b5ded02c085acd Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:07:22 +0200 -Subject: [PATCH] tc/em_ipset: Don't leak sockfd on error path - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 3e587d9f43891 - -commit 3e587d9f438910df6c1751c45fd898cec1477ae6 -Author: Phil Sutter -Date: Thu Aug 17 19:09:31 2017 +0200 - - tc/em_ipset: Don't leak sockfd on error path - - Signed-off-by: Phil Sutter ---- - tc/em_ipset.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/tc/em_ipset.c b/tc/em_ipset.c -index fab975f5ea563..b59756515d239 100644 ---- a/tc/em_ipset.c -+++ b/tc/em_ipset.c -@@ -84,6 +84,7 @@ static int get_version(unsigned int *version) - res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req_version, &size); - if (res != 0) { - perror("xt_set getsockopt"); -+ close(sockfd); - return -1; - } - --- -2.21.0 - diff --git a/SOURCES/0079-ipvrf-Fix-error-path-of-vrf_switch.patch b/SOURCES/0079-ipvrf-Fix-error-path-of-vrf_switch.patch deleted file mode 100644 index 03ac8ea..0000000 --- a/SOURCES/0079-ipvrf-Fix-error-path-of-vrf_switch.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 7ea6dbec34ae5166dd93fd4dbfcab35512e86e94 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:07:22 +0200 -Subject: [PATCH] ipvrf: Fix error path of vrf_switch() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 6ac5943bdd5ac - -commit 6ac5943bdd5ac5bb8c22b99f5a1d5907ebbcae2b -Author: Phil Sutter -Date: Thu Aug 17 19:09:27 2017 +0200 - - ipvrf: Fix error path of vrf_switch() - - Apart from trying to close(-1), this also leaked memory. - - Signed-off-by: Phil Sutter ---- - ip/ipvrf.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/ip/ipvrf.c b/ip/ipvrf.c -index 0f611b44b78ab..ae3b48fa81996 100644 ---- a/ip/ipvrf.c -+++ b/ip/ipvrf.c -@@ -369,12 +369,12 @@ static int vrf_switch(const char *name) - - /* -1 on length to add '/' to the end */ - if (ipvrf_get_netns(netns, sizeof(netns) - 1) < 0) -- return -1; -+ goto out; - - if (vrf_path(vpath, sizeof(vpath)) < 0) { - fprintf(stderr, "Failed to get base cgroup path: %s\n", - strerror(errno)); -- return -1; -+ goto out; - } - - /* if path already ends in netns then don't add it again */ -@@ -425,13 +425,14 @@ static int vrf_switch(const char *name) - snprintf(pid, sizeof(pid), "%d", getpid()); - if (write(fd, pid, strlen(pid)) < 0) { - fprintf(stderr, "Failed to join cgroup\n"); -- goto out; -+ goto out2; - } - - rc = 0; -+out2: -+ close(fd); - out: - free(mnt); -- close(fd); - - return rc; - } --- -2.21.0 - diff --git a/SOURCES/0080-ifstat-Fix-memleak-in-error-case.patch b/SOURCES/0080-ifstat-Fix-memleak-in-error-case.patch deleted file mode 100644 index aa0b6c8..0000000 --- a/SOURCES/0080-ifstat-Fix-memleak-in-error-case.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 78ff1fa1a2ff22e6fb7dc0a689e5a4861826431e Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:07:22 +0200 -Subject: [PATCH] ifstat: Fix memleak in error case - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 35f6adefb8f9d - -commit 35f6adefb8f9d56437f5455ac8c0c3cc329e3317 -Author: Phil Sutter -Date: Thu Aug 17 19:09:28 2017 +0200 - - ifstat: Fix memleak in error case - - Signed-off-by: Phil Sutter ---- - misc/ifstat.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/misc/ifstat.c b/misc/ifstat.c -index a853ee6d7e3b3..8fa354265a9a1 100644 ---- a/misc/ifstat.c -+++ b/misc/ifstat.c -@@ -143,8 +143,10 @@ static int get_nlmsg_extended(const struct sockaddr_nl *who, - struct rtattr *attr; - - attr = parse_rtattr_one_nested(sub_type, tb[filter_type]); -- if (attr == NULL) -+ if (attr == NULL) { -+ free(n); - return 0; -+ } - memcpy(&n->val, RTA_DATA(attr), sizeof(n->val)); - } - memset(&n->rate, 0, sizeof(n->rate)); --- -2.21.0 - diff --git a/SOURCES/0081-ifstat-Fix-memleak-in-dump_kern_db-for-json-output.patch b/SOURCES/0081-ifstat-Fix-memleak-in-dump_kern_db-for-json-output.patch deleted file mode 100644 index 09e1453..0000000 --- a/SOURCES/0081-ifstat-Fix-memleak-in-dump_kern_db-for-json-output.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 3f74fdcd943982101775db3b4240a6f953d1198d Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:07:22 +0200 -Subject: [PATCH] ifstat: Fix memleak in dump_kern_db() for json output - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit b530cef0e3bbd - -commit b530cef0e3bbd27510e19f5f720a7ec94f3fa723 -Author: Phil Sutter -Date: Thu Aug 17 19:09:29 2017 +0200 - - ifstat: Fix memleak in dump_kern_db() for json output - - Looks like this was forgotten when converting to common json output - formatter. - - Fixes: fcc16c2287bf8 ("provide common json output formatter") - Signed-off-by: Phil Sutter ---- - misc/ifstat.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/misc/ifstat.c b/misc/ifstat.c -index 8fa354265a9a1..1be21703bf14c 100644 ---- a/misc/ifstat.c -+++ b/misc/ifstat.c -@@ -535,8 +535,12 @@ static void dump_kern_db(FILE *fp) - else - print_one_if(fp, n, n->val); - } -- if (json_output) -- fprintf(fp, "\n} }\n"); -+ if (jw) { -+ jsonw_end_object(jw); -+ -+ jsonw_end_object(jw); -+ jsonw_destroy(&jw); -+ } - } - - static void dump_incr_db(FILE *fp) --- -2.21.0 - diff --git a/SOURCES/0082-ss-Fix-potential-memleak-in-unix_stats_print.patch b/SOURCES/0082-ss-Fix-potential-memleak-in-unix_stats_print.patch deleted file mode 100644 index 7e34ae3..0000000 --- a/SOURCES/0082-ss-Fix-potential-memleak-in-unix_stats_print.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 125c0e845acd690c9dce5702413294304a328fd1 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:07:22 +0200 -Subject: [PATCH] ss: Fix potential memleak in unix_stats_print() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 46131577cf1ba - -commit 46131577cf1ba37198c82e1ce89c9bbca2153ef4 -Author: Phil Sutter -Date: Thu Aug 17 19:09:30 2017 +0200 - - ss: Fix potential memleak in unix_stats_print() - - Fixes: 2d0e538f3e1cd ("ss: Drop list traversal from unix_stats_print()") - Signed-off-by: Phil Sutter ---- - misc/ss.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/misc/ss.c b/misc/ss.c -index eb46e0c4b95fb..c97f05a4c7033 100644 ---- a/misc/ss.c -+++ b/misc/ss.c -@@ -3258,8 +3258,10 @@ static int unix_show(struct filter *f) - - if (name[0]) { - u->name = strdup(name); -- if (!u->name) -+ if (!u->name) { -+ free(u); - break; -+ } - } - - if (u->rport) { --- -2.21.0 - diff --git a/SOURCES/0083-tipc-bearer-Fix-resource-leak-in-error-path.patch b/SOURCES/0083-tipc-bearer-Fix-resource-leak-in-error-path.patch deleted file mode 100644 index dae7399..0000000 --- a/SOURCES/0083-tipc-bearer-Fix-resource-leak-in-error-path.patch +++ /dev/null @@ -1,43 +0,0 @@ -From b6bf156c4d4abab8176112e48a595c3e7bb7f825 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:07:22 +0200 -Subject: [PATCH] tipc/bearer: Fix resource leak in error path - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit be55416addf76 - -commit be55416addf76e76836af6a4dd94b19c4186e1b2 -Author: Phil Sutter -Date: Thu Aug 17 19:09:31 2017 +0200 - - tipc/bearer: Fix resource leak in error path - - Signed-off-by: Phil Sutter ---- - tipc/bearer.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/tipc/bearer.c b/tipc/bearer.c -index 810344f672af1..c3d4491f8f6ef 100644 ---- a/tipc/bearer.c -+++ b/tipc/bearer.c -@@ -163,6 +163,7 @@ static int nl_add_udp_enable_opts(struct nlmsghdr *nlh, struct opt *opts, - if (!remip) { - if (generate_multicast(loc->ai_family, buf, sizeof(buf))) { - fprintf(stderr, "Failed to generate multicast address\n"); -+ freeaddrinfo(loc); - return -EINVAL; - } - remip = buf; -@@ -177,6 +178,8 @@ static int nl_add_udp_enable_opts(struct nlmsghdr *nlh, struct opt *opts, - - if (rem->ai_family != loc->ai_family) { - fprintf(stderr, "UDP local and remote AF mismatch\n"); -+ freeaddrinfo(rem); -+ freeaddrinfo(loc); - return -EINVAL; - } - --- -2.21.0 - diff --git a/SOURCES/0084-devlink-No-need-for-this-self-assignment.patch b/SOURCES/0084-devlink-No-need-for-this-self-assignment.patch deleted file mode 100644 index 9e74159..0000000 --- a/SOURCES/0084-devlink-No-need-for-this-self-assignment.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 1fe740ceabb0b965224678a69a02255e20d5a47a Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:07:22 +0200 -Subject: [PATCH] devlink: No need for this self-assignment - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 8579a398c5ab0 - -commit 8579a398c5ab0d26bce0ed9b4b6b6e5d62fcc89d -Author: Phil Sutter -Date: Thu Aug 17 19:09:25 2017 +0200 - - devlink: No need for this self-assignment - - dl_argv_handle_both() will either assign to handle_bit or error out in - which case the variable is not used by the caller. - - Signed-off-by: Phil Sutter - Acked-by: Jiri Pirko ---- - devlink/devlink.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/devlink/devlink.c b/devlink/devlink.c -index 2000db81aabb0..ae295b5632e8c 100644 ---- a/devlink/devlink.c -+++ b/devlink/devlink.c -@@ -845,7 +845,7 @@ static int dl_argv_parse(struct dl *dl, uint32_t o_required, - int err; - - if (o_required & DL_OPT_HANDLE && o_required & DL_OPT_HANDLEP) { -- uint32_t handle_bit = handle_bit; -+ uint32_t handle_bit; - - err = dl_argv_handle_both(dl, &opts->bus_name, &opts->dev_name, - &opts->port_index, &handle_bit); --- -2.21.0 - diff --git a/SOURCES/0085-ipntable-No-need-to-check-and-assign-to-parms_rta.patch b/SOURCES/0085-ipntable-No-need-to-check-and-assign-to-parms_rta.patch deleted file mode 100644 index 9aca3e5..0000000 --- a/SOURCES/0085-ipntable-No-need-to-check-and-assign-to-parms_rta.patch +++ /dev/null @@ -1,38 +0,0 @@ -From d62d2ffc71194068af509ec3285ecd6823d883fb Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:07:22 +0200 -Subject: [PATCH] ipntable: No need to check and assign to parms_rta - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 2869262144271 - -commit 28692621442710f4a67fe33742f56efc582ee33a -Author: Phil Sutter -Date: Thu Aug 17 19:09:26 2017 +0200 - - ipntable: No need to check and assign to parms_rta - - This variable is initialized at declaration and nowhere else does any - assignment to it happen, so just drop the check. - - Signed-off-by: Phil Sutter ---- - ip/ipntable.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/ip/ipntable.c b/ip/ipntable.c -index 65063321c85f8..ae8c74ead2cb8 100644 ---- a/ip/ipntable.c -+++ b/ip/ipntable.c -@@ -202,8 +202,6 @@ static int ipntable_modify(int cmd, int flags, int argc, char **argv) - if (get_u32(&queue, *argv, 0)) - invarg("\"queue\" value is invalid", *argv); - -- if (!parms_rta) -- parms_rta = (struct rtattr *)&parms_buf; - rta_addattr32(parms_rta, sizeof(parms_buf), - NDTPA_QUEUE_LEN, queue); - parms_change = 1; --- -2.21.0 - diff --git a/SOURCES/0086-iproute-Fix-for-missing-Oifs-display.patch b/SOURCES/0086-iproute-Fix-for-missing-Oifs-display.patch deleted file mode 100644 index cd19db3..0000000 --- a/SOURCES/0086-iproute-Fix-for-missing-Oifs-display.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 2cb971cefe001a66677c2d1d23b1596cbffb3989 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:07:22 +0200 -Subject: [PATCH] iproute: Fix for missing 'Oifs:' display - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 2a866256197f8 - -commit 2a866256197f8b86e61fa1afc99b11d7056d5686 -Author: Phil Sutter -Date: Thu Aug 17 19:09:27 2017 +0200 - - iproute: Fix for missing 'Oifs:' display - - Covscan complained about dead code but after reading it, I assume the - author's intention was to prefix the interface list with 'Oifs: '. - Initializing first to 1 and setting it to 0 after above prefix was - printed should fix it. - - Signed-off-by: Phil Sutter ---- - ip/iproute.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/ip/iproute.c b/ip/iproute.c -index d4db035fc7b24..6ebc6214c45ee 100644 ---- a/ip/iproute.c -+++ b/ip/iproute.c -@@ -618,7 +618,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) - } - if (tb[RTA_MULTIPATH]) { - struct rtnexthop *nh = RTA_DATA(tb[RTA_MULTIPATH]); -- int first = 0; -+ int first = 1; - - len = RTA_PAYLOAD(tb[RTA_MULTIPATH]); - -@@ -628,10 +628,12 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) - if (nh->rtnh_len > len) - break; - if (r->rtm_flags&RTM_F_CLONED && r->rtm_type == RTN_MULTICAST) { -- if (first) -+ if (first) { - fprintf(fp, "Oifs: "); -- else -+ first = 0; -+ } else { - fprintf(fp, " "); -+ } - } else - fprintf(fp, "%s\tnexthop ", _SL_); - if (nh->rtnh_len > sizeof(*nh)) { --- -2.21.0 - diff --git a/SOURCES/0087-lib-rt_names-Drop-dead-code-in-rtnl_rttable_n2a.patch b/SOURCES/0087-lib-rt_names-Drop-dead-code-in-rtnl_rttable_n2a.patch deleted file mode 100644 index 9a87b4d..0000000 --- a/SOURCES/0087-lib-rt_names-Drop-dead-code-in-rtnl_rttable_n2a.patch +++ /dev/null @@ -1,40 +0,0 @@ -From cd4f6a9976a969d4981b3b3d09b60ed311f3e9a5 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:07:22 +0200 -Subject: [PATCH] lib/rt_names: Drop dead code in rtnl_rttable_n2a() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit b3c5f84493d33 - -commit b3c5f84493d3399a546566475203207aa5b64d54 -Author: Phil Sutter -Date: Thu Aug 17 19:09:28 2017 +0200 - - lib/rt_names: Drop dead code in rtnl_rttable_n2a() - - Since 'id' is 32bit unsigned, it can never exceed RT_TABLE_MAX (which is - defined to 0xFFFFFFFF). Therefore drop that never matching conditional. - - Signed-off-by: Phil Sutter ---- - lib/rt_names.c | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/lib/rt_names.c b/lib/rt_names.c -index 04c15ff5b15f8..e5efd78e6f810 100644 ---- a/lib/rt_names.c -+++ b/lib/rt_names.c -@@ -410,10 +410,6 @@ const char *rtnl_rttable_n2a(__u32 id, char *buf, int len) - { - struct rtnl_hash_entry *entry; - -- if (id > RT_TABLE_MAX) { -- snprintf(buf, len, "%u", id); -- return buf; -- } - if (!rtnl_rttable_init) - rtnl_rttable_initialize(); - entry = rtnl_rttable_hash[id & 255]; --- -2.21.0 - diff --git a/SOURCES/0088-ss-Skip-useless-check-in-parse_hostcond.patch b/SOURCES/0088-ss-Skip-useless-check-in-parse_hostcond.patch deleted file mode 100644 index 9f6807f..0000000 --- a/SOURCES/0088-ss-Skip-useless-check-in-parse_hostcond.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 4b2f0a5a479f2714b8b44932ba961ba8cf07e18e Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:07:22 +0200 -Subject: [PATCH] ss: Skip useless check in parse_hostcond() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 44448a90eab34 - -commit 44448a90eab34713af019356926828720c67a268 -Author: Phil Sutter -Date: Thu Aug 17 19:09:29 2017 +0200 - - ss: Skip useless check in parse_hostcond() - - The passed 'addr' parameter is dereferenced by caller before and in - parse_hostcond() multiple times before this check, so assume it is - always true. - - Signed-off-by: Phil Sutter ---- - misc/ss.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/misc/ss.c b/misc/ss.c -index c97f05a4c7033..38f4017e4a8c8 100644 ---- a/misc/ss.c -+++ b/misc/ss.c -@@ -1747,7 +1747,7 @@ void *parse_hostcond(char *addr, bool is_port) - } - } - } -- if (!is_port && addr && *addr && *addr != '*') { -+ if (!is_port && *addr && *addr != '*') { - if (get_prefix_1(&a.addr, addr, fam)) { - if (get_dns_host(&a, addr, fam)) { - fprintf(stderr, "Error: an inet prefix is expected rather than \"%s\".\n", addr); --- -2.21.0 - diff --git a/SOURCES/0089-ss-Drop-useless-assignment.patch b/SOURCES/0089-ss-Drop-useless-assignment.patch deleted file mode 100644 index 945ad89..0000000 --- a/SOURCES/0089-ss-Drop-useless-assignment.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 23e13f60728a68b2c4a5b3656a1ce79affaafc6d Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:07:22 +0200 -Subject: [PATCH] ss: Drop useless assignment - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit e469523e8e8d1 - -commit e469523e8e8d1d31c3b35251105e2a843216d687 -Author: Phil Sutter -Date: Thu Aug 17 19:09:30 2017 +0200 - - ss: Drop useless assignment - - After '*b = *a', 'b->next' already has the same value as 'a->next'. - - Signed-off-by: Phil Sutter ---- - misc/ss.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/misc/ss.c b/misc/ss.c -index 38f4017e4a8c8..cc38fc499c210 100644 ---- a/misc/ss.c -+++ b/misc/ss.c -@@ -1476,7 +1476,6 @@ static int remember_he(struct aafilter *a, struct hostent *he) - if ((b = malloc(sizeof(*b))) == NULL) - return cnt; - *b = *a; -- b->next = a->next; - a->next = b; - } - memcpy(b->addr.data, *ptr, len); --- -2.21.0 - diff --git a/SOURCES/0090-tc-m_gact-Drop-dead-code.patch b/SOURCES/0090-tc-m_gact-Drop-dead-code.patch deleted file mode 100644 index f0d4a13..0000000 --- a/SOURCES/0090-tc-m_gact-Drop-dead-code.patch +++ /dev/null @@ -1,90 +0,0 @@ -From c6e0fc7a5ec0b890c35a3b5d4cc5e1f7794cc47f Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:07:22 +0200 -Subject: [PATCH] tc/m_gact: Drop dead code - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 73aa988868e7e -Conflicts: context change due to missing commits: -* e67aba5595811 ("tc: actions: add helpers to parse and print control actions") -* 18f05d06016d9 ("tc: gact: fix control action parsing") - -commit 73aa988868e7e068b4fc0daaca7cfdb3e07fe744 -Author: Phil Sutter -Date: Thu Aug 17 19:09:31 2017 +0200 - - tc/m_gact: Drop dead code - - The use of 'ok' variable in parse_gact() is ineffective: The second - conditional increments it either if *argv is 'gact' or if - parse_action_control() doesn't fail (in which case exit() is called). - So this is effectively an unconditional increment and since no decrement - happens anywhere, all remaining checks for 'ok != 0' can be dropped. - - Signed-off-by: Phil Sutter ---- - tc/m_gact.c | 18 +++++------------- - 1 file changed, 5 insertions(+), 13 deletions(-) - -diff --git a/tc/m_gact.c b/tc/m_gact.c -index 755a3bee2c2f2..0cb5222fd3817 100644 ---- a/tc/m_gact.c -+++ b/tc/m_gact.c -@@ -86,7 +86,6 @@ parse_gact(struct action_util *a, int *argc_p, char ***argv_p, - { - int argc = *argc_p; - char **argv = *argv_p; -- int ok = 0; - int action = TC_POLICE_RECLASSIFY; - struct tc_gact p = { .action = TC_POLICE_RECLASSIFY }; - #ifdef CONFIG_GACT_PROB -@@ -100,25 +99,22 @@ parse_gact(struct action_util *a, int *argc_p, char ***argv_p, - - - if (matches(*argv, "gact") == 0) { -- ok++; -+ argc--; -+ argv++; - } else { - action = get_act(&argv); - if (action != -10) { - p.action = action; -- ok++; -+ argc--; -+ argv++; - } else { - explain(); - return action; - } - } - -- if (ok) { -- argc--; -- argv++; -- } -- - #ifdef CONFIG_GACT_PROB -- if (ok && argc > 0) { -+ if (argc > 0) { - if (matches(*argv, "random") == 0) { - rd = 1; - NEXT_ARG(); -@@ -167,15 +163,11 @@ parse_gact(struct action_util *a, int *argc_p, char ***argv_p, - } - argc--; - argv++; -- ok++; - } else if (matches(*argv, "help") == 0) { - usage(); - } - } - -- if (!ok) -- return -1; -- - tail = NLMSG_TAIL(n); - addattr_l(n, MAX_MSG, tca_id, NULL, 0); - addattr_l(n, MAX_MSG, TCA_GACT_PARMS, &p, sizeof(p)); --- -2.21.0 - diff --git a/SOURCES/0091-ipaddress-Avoid-accessing-uninitialized-variable-lcl.patch b/SOURCES/0091-ipaddress-Avoid-accessing-uninitialized-variable-lcl.patch deleted file mode 100644 index 6256d2f..0000000 --- a/SOURCES/0091-ipaddress-Avoid-accessing-uninitialized-variable-lcl.patch +++ /dev/null @@ -1,38 +0,0 @@ -From a7150dc1d46b73f65bfedd728aeca1dcf5ec20eb Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:07 +0200 -Subject: [PATCH] ipaddress: Avoid accessing uninitialized variable lcl - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit d044ea3e784d1 - -commit d044ea3e784d1a4f0a61f306b86ce95c9a26b0b5 -Author: Phil Sutter -Date: Mon Aug 21 11:26:59 2017 +0200 - - ipaddress: Avoid accessing uninitialized variable lcl - - If no address was given, ipaddr_modify() accesses uninitialized data - when assigning to req.ifa.ifa_prefixlen. - - Signed-off-by: Phil Sutter ---- - ip/ipaddress.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ip/ipaddress.c b/ip/ipaddress.c -index bed2d3801809b..2c27da3a1f079 100644 ---- a/ip/ipaddress.c -+++ b/ip/ipaddress.c -@@ -1887,7 +1887,7 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv) - char *lcl_arg = NULL; - char *valid_lftp = NULL; - char *preferred_lftp = NULL; -- inet_prefix lcl; -+ inet_prefix lcl = {}; - inet_prefix peer; - int local_len = 0; - int peer_len = 0; --- -2.21.0 - diff --git a/SOURCES/0092-iplink_can-Prevent-overstepping-array-bounds.patch b/SOURCES/0092-iplink_can-Prevent-overstepping-array-bounds.patch deleted file mode 100644 index 00bcb5d..0000000 --- a/SOURCES/0092-iplink_can-Prevent-overstepping-array-bounds.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 4c775c035e2751b1aec52dcc2ca0e4fc99bac793 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:07 +0200 -Subject: [PATCH] iplink_can: Prevent overstepping array bounds - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 258b7c0fa70c2 - -commit 258b7c0fa70c2d6b5f9776cc35c38c80b4ee5752 -Author: Phil Sutter -Date: Mon Aug 21 11:27:00 2017 +0200 - - iplink_can: Prevent overstepping array bounds - - can_state_names array contains at most CAN_STATE_MAX fields, so allowing - an index to it to be equal to that number is wrong. While here, also - make sure the array is indeed that big so nothing bad happens if - CAN_STATE_MAX ever increases. - - Signed-off-by: Phil Sutter ---- - ip/iplink_can.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/ip/iplink_can.c b/ip/iplink_can.c -index 20d4d37d0d087..4133a658a059e 100644 ---- a/ip/iplink_can.c -+++ b/ip/iplink_can.c -@@ -241,7 +241,7 @@ static int can_parse_opt(struct link_util *lu, int argc, char **argv, - return 0; - } - --static const char *can_state_names[] = { -+static const char *can_state_names[CAN_STATE_MAX] = { - [CAN_STATE_ERROR_ACTIVE] = "ERROR-ACTIVE", - [CAN_STATE_ERROR_WARNING] = "ERROR-WARNING", - [CAN_STATE_ERROR_PASSIVE] = "ERROR-PASSIVE", -@@ -265,7 +265,7 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) - if (tb[IFLA_CAN_STATE]) { - uint32_t state = rta_getattr_u32(tb[IFLA_CAN_STATE]); - -- fprintf(f, "state %s ", state <= CAN_STATE_MAX ? -+ fprintf(f, "state %s ", state < CAN_STATE_MAX ? - can_state_names[state] : "UNKNOWN"); - } - --- -2.21.0 - diff --git a/SOURCES/0093-ipmaddr-Avoid-accessing-uninitialized-data.patch b/SOURCES/0093-ipmaddr-Avoid-accessing-uninitialized-data.patch deleted file mode 100644 index 6671cd0..0000000 --- a/SOURCES/0093-ipmaddr-Avoid-accessing-uninitialized-data.patch +++ /dev/null @@ -1,38 +0,0 @@ -From e5d32611010d4694562980b790ed7849342f594b Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:07 +0200 -Subject: [PATCH] ipmaddr: Avoid accessing uninitialized data - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit b48a1161f5f9b - -commit b48a1161f5f9b6a0cda399a224bbbf72eba4a5c6 -Author: Phil Sutter -Date: Mon Aug 21 11:27:01 2017 +0200 - - ipmaddr: Avoid accessing uninitialized data - - Looks like this can only happen if /proc/net/igmp is malformed, but - better be sure. - - Signed-off-by: Phil Sutter ---- - ip/ipmaddr.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ip/ipmaddr.c b/ip/ipmaddr.c -index 4f726fdd976f1..85a69e779563d 100644 ---- a/ip/ipmaddr.c -+++ b/ip/ipmaddr.c -@@ -136,7 +136,7 @@ static void read_igmp(struct ma_info **result_p) - - while (fgets(buf, sizeof(buf), fp)) { - struct ma_info *ma; -- size_t len; -+ size_t len = 0; - - if (buf[0] != '\t') { - sscanf(buf, "%d%s", &m.index, m.name); --- -2.21.0 - diff --git a/SOURCES/0094-ss-Use-C99-initializer-in-netlink_show_one.patch b/SOURCES/0094-ss-Use-C99-initializer-in-netlink_show_one.patch deleted file mode 100644 index b8e1e05..0000000 --- a/SOURCES/0094-ss-Use-C99-initializer-in-netlink_show_one.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 60a5c300c8cd0fbd4c378900d298eb2444c0343d Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:07 +0200 -Subject: [PATCH] ss: Use C99 initializer in netlink_show_one() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 301826beb3baa - -commit 301826beb3baa902e2057d81912d1586459f605f -Author: Phil Sutter -Date: Mon Aug 21 11:27:02 2017 +0200 - - ss: Use C99 initializer in netlink_show_one() - - This has the additional benefit of initializing st.ino to zero which is - used later in is_sctp_assoc() function. - - Signed-off-by: Phil Sutter ---- - misc/ss.c | 13 +++++++------ - 1 file changed, 7 insertions(+), 6 deletions(-) - -diff --git a/misc/ss.c b/misc/ss.c -index cc38fc499c210..7a38e9d830e8d 100644 ---- a/misc/ss.c -+++ b/misc/ss.c -@@ -3567,17 +3567,18 @@ static int netlink_show_one(struct filter *f, - int rq, int wq, - unsigned long long sk, unsigned long long cb) - { -- struct sockstat st; -+ struct sockstat st = { -+ .state = SS_CLOSE, -+ .rq = rq, -+ .wq = wq, -+ .local.family = AF_NETLINK, -+ .remote.family = AF_NETLINK, -+ }; - - SPRINT_BUF(prot_buf) = {}; - const char *prot_name; - char procname[64] = {}; - -- st.state = SS_CLOSE; -- st.rq = rq; -- st.wq = wq; -- st.local.family = st.remote.family = AF_NETLINK; -- - if (f->f) { - st.rport = -1; - st.lport = pid; --- -2.21.0 - diff --git a/SOURCES/0095-netem-maketable-Check-return-value-of-fstat.patch b/SOURCES/0095-netem-maketable-Check-return-value-of-fstat.patch deleted file mode 100644 index 7361e89..0000000 --- a/SOURCES/0095-netem-maketable-Check-return-value-of-fstat.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 56c1a9e6c4d7d54ee27472428bcb33be471b3346 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:07 +0200 -Subject: [PATCH] netem/maketable: Check return value of fstat() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit d304b05c12b3a - -commit d304b05c12b3a0247b627ebc8e4477520bb4b969 -Author: Phil Sutter -Date: Mon Aug 21 11:27:03 2017 +0200 - - netem/maketable: Check return value of fstat() - - Otherwise info.st_size may contain garbage. - - Signed-off-by: Phil Sutter ---- - netem/maketable.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/netem/maketable.c b/netem/maketable.c -index 6aff927be7040..ad660e7d457f0 100644 ---- a/netem/maketable.c -+++ b/netem/maketable.c -@@ -24,8 +24,8 @@ readdoubles(FILE *fp, int *number) - int limit; - int n=0, i; - -- fstat(fileno(fp), &info); -- if (info.st_size > 0) { -+ if (!fstat(fileno(fp), &info) && -+ info.st_size > 0) { - limit = 2*info.st_size/sizeof(double); /* @@ approximate */ - } else { - limit = 10000; --- -2.21.0 - diff --git a/SOURCES/0096-tc-q_multiq-Don-t-pass-garbage-in-TCA_OPTIONS.patch b/SOURCES/0096-tc-q_multiq-Don-t-pass-garbage-in-TCA_OPTIONS.patch deleted file mode 100644 index ec1b907..0000000 --- a/SOURCES/0096-tc-q_multiq-Don-t-pass-garbage-in-TCA_OPTIONS.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 8a115584261b32308d604063b56f25330ce8adaf Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:07 +0200 -Subject: [PATCH] tc/q_multiq: Don't pass garbage in TCA_OPTIONS - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 82ed9ffa2bb86 - -commit 82ed9ffa2bb86eea653f68a0ade945b7708818c9 -Author: Phil Sutter -Date: Mon Aug 21 11:27:04 2017 +0200 - - tc/q_multiq: Don't pass garbage in TCA_OPTIONS - - multiq_parse_opt() doesn't change 'opt' at all. So at least make sure - it doesn't fill TCA_OPTIONS attribute with garbage from stack. - - Signed-off-by: Phil Sutter ---- - tc/q_multiq.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tc/q_multiq.c b/tc/q_multiq.c -index 7823931494563..9c09c9a7748f6 100644 ---- a/tc/q_multiq.c -+++ b/tc/q_multiq.c -@@ -43,7 +43,7 @@ static void explain(void) - static int multiq_parse_opt(struct qdisc_util *qu, int argc, char **argv, - struct nlmsghdr *n) - { -- struct tc_multiq_qopt opt; -+ struct tc_multiq_qopt opt = {}; - - if (argc) { - if (strcmp(*argv, "help") == 0) { --- -2.21.0 - diff --git a/SOURCES/0097-iproute-Check-mark-value-input.patch b/SOURCES/0097-iproute-Check-mark-value-input.patch deleted file mode 100644 index 8a40286..0000000 --- a/SOURCES/0097-iproute-Check-mark-value-input.patch +++ /dev/null @@ -1,46 +0,0 @@ -From ce3460e0a39948054139e5bcf72130e82bf2da8d Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:07 +0200 -Subject: [PATCH] iproute: Check mark value input - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 7c66d89828a6e - -commit 7c66d89828a6ee4c5a4e3f48ef4a4cb07b50013d -Author: Phil Sutter -Date: Mon Aug 21 18:36:50 2017 +0200 - - iproute: Check mark value input - - Signed-off-by: Phil Sutter ---- - ip/iproute.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/ip/iproute.c b/ip/iproute.c -index 6ebc6214c45ee..1d92530fd3421 100644 ---- a/ip/iproute.c -+++ b/ip/iproute.c -@@ -1481,7 +1481,8 @@ static int iproute_list_flush_or_save(int argc, char **argv, int action) - id = *argv; - } else if (strcmp(*argv, "mark") == 0) { - NEXT_ARG(); -- get_unsigned(&mark, *argv, 0); -+ if (get_unsigned(&mark, *argv, 0)) -+ invarg("invalid mark value", *argv); - filter.markmask = -1; - } else if (strcmp(*argv, "via") == 0) { - int family; -@@ -1698,7 +1699,8 @@ static int iproute_get(int argc, char **argv) - idev = *argv; - } else if (matches(*argv, "mark") == 0) { - NEXT_ARG(); -- get_unsigned(&mark, *argv, 0); -+ if (get_unsigned(&mark, *argv, 0)) -+ invarg("invalid mark value", *argv); - } else if (matches(*argv, "oif") == 0 || - strcmp(*argv, "dev") == 0) { - NEXT_ARG(); --- -2.21.0 - diff --git a/SOURCES/0098-iplink_vrf-Complain-if-main-table-is-not-found.patch b/SOURCES/0098-iplink_vrf-Complain-if-main-table-is-not-found.patch deleted file mode 100644 index 44c88ef..0000000 --- a/SOURCES/0098-iplink_vrf-Complain-if-main-table-is-not-found.patch +++ /dev/null @@ -1,38 +0,0 @@ -From b9d228a8c22f1d9069fa0c8f98e6bd94011c5714 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:07 +0200 -Subject: [PATCH] iplink_vrf: Complain if main table is not found - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 84b6a3f4b5720 - -commit 84b6a3f4b5720aaf673c2eaad2cf60f786de077b -Author: Phil Sutter -Date: Mon Aug 21 18:36:51 2017 +0200 - - iplink_vrf: Complain if main table is not found - - Signed-off-by: Phil Sutter - Acked-by: David Ahern ---- - ip/iplink_vrf.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/ip/iplink_vrf.c b/ip/iplink_vrf.c -index 370bb86815a80..9c2de2732a88e 100644 ---- a/ip/iplink_vrf.c -+++ b/ip/iplink_vrf.c -@@ -127,7 +127,9 @@ __u32 ipvrf_get_table(const char *name) - if (rtnl_talk_suppress_rtnl_errmsg(&rth, &req.n, &answer) < 0) { - /* special case "default" vrf to be the main table */ - if (errno == ENODEV && !strcmp(name, "default")) -- rtnl_rttable_a2n(&tb_id, "main"); -+ if (rtnl_rttable_a2n(&tb_id, "main")) -+ fprintf(stderr, -+ "BUG: RTTable \"main\" not found.\n"); - - return tb_id; - } --- -2.21.0 - diff --git a/SOURCES/0099-devlink-Check-return-code-of-strslashrsplit.patch b/SOURCES/0099-devlink-Check-return-code-of-strslashrsplit.patch deleted file mode 100644 index d39c355..0000000 --- a/SOURCES/0099-devlink-Check-return-code-of-strslashrsplit.patch +++ /dev/null @@ -1,62 +0,0 @@ -From ea11b95042171f254fe0127ea0f1f2786d81dc83 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:07 +0200 -Subject: [PATCH] devlink: Check return code of strslashrsplit() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 6e33f7b0f6e04 - -commit 6e33f7b0f6e04dd46bea24c3ab28d61e54625dd7 -Author: Phil Sutter -Date: Mon Aug 21 18:36:52 2017 +0200 - - devlink: Check return code of strslashrsplit() - - This function shouldn't fail because all callers of - __dl_argv_handle_port() make sure the passed string contains enough - slashes already, but better make sure if this changes in future the - function won't access uninitialized data. - - Signed-off-by: Phil Sutter ---- - devlink/devlink.c | 16 ++++++++++++---- - 1 file changed, 12 insertions(+), 4 deletions(-) - -diff --git a/devlink/devlink.c b/devlink/devlink.c -index ae295b5632e8c..082eeafa1146a 100644 ---- a/devlink/devlink.c -+++ b/devlink/devlink.c -@@ -576,18 +576,26 @@ static int __dl_argv_handle_port(char *str, - char **p_bus_name, char **p_dev_name, - uint32_t *p_port_index) - { -- char *handlestr = handlestr; -- char *portstr = portstr; -+ char *handlestr; -+ char *portstr; - int err; - -- strslashrsplit(str, &handlestr, &portstr); -+ err = strslashrsplit(str, &handlestr, &portstr); -+ if (err) { -+ pr_err("Port identification \"%s\" is invalid\n", str); -+ return err; -+ } - err = strtouint32_t(portstr, p_port_index); - if (err) { - pr_err("Port index \"%s\" is not a number or not within range\n", - portstr); - return err; - } -- strslashrsplit(handlestr, p_bus_name, p_dev_name); -+ err = strslashrsplit(handlestr, p_bus_name, p_dev_name); -+ if (err) { -+ pr_err("Port identification \"%s\" is invalid\n", str); -+ return err; -+ } - return 0; - } - --- -2.21.0 - diff --git a/SOURCES/0100-lib-bpf-Don-t-leak-fp-in-bpf_find_mntpt.patch b/SOURCES/0100-lib-bpf-Don-t-leak-fp-in-bpf_find_mntpt.patch deleted file mode 100644 index 036e699..0000000 --- a/SOURCES/0100-lib-bpf-Don-t-leak-fp-in-bpf_find_mntpt.patch +++ /dev/null @@ -1,43 +0,0 @@ -From bafabe7a067e647f97ae0df277bded8b9349db50 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:07 +0200 -Subject: [PATCH] lib/bpf: Don't leak fp in bpf_find_mntpt() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit c3724e4bc3a6c - -commit c3724e4bc3a6c40dc846f0c3b02934d711bf81fb -Author: Phil Sutter -Date: Mon Aug 21 16:46:51 2017 +0200 - - lib/bpf: Don't leak fp in bpf_find_mntpt() - - If fopen() succeeded but len != PATH_MAX, the function leaks the open - FILE pointer. Fix this by checking len value before calling fopen(). - - Signed-off-by: Phil Sutter - Acked-by: Daniel Borkmann ---- - lib/bpf.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/lib/bpf.c b/lib/bpf.c -index 3aabf44d1abf8..33c5288e82187 100644 ---- a/lib/bpf.c -+++ b/lib/bpf.c -@@ -432,8 +432,11 @@ static const char *bpf_find_mntpt(const char *fstype, unsigned long magic, - } - } - -+ if (len != PATH_MAX) -+ return NULL; -+ - fp = fopen("/proc/mounts", "r"); -- if (fp == NULL || len != PATH_MAX) -+ if (fp == NULL) - return NULL; - - while (fscanf(fp, "%*s %" textify(PATH_MAX) "s %99s %*s %*d %*d\n", --- -2.21.0 - diff --git a/SOURCES/0101-ifstat-nstat-Check-fdopen-return-value.patch b/SOURCES/0101-ifstat-nstat-Check-fdopen-return-value.patch deleted file mode 100644 index ee3c06c..0000000 --- a/SOURCES/0101-ifstat-nstat-Check-fdopen-return-value.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 5ae0f31d9c5d40dbf9eaf00435b9df1968109f5e Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:07 +0200 -Subject: [PATCH] ifstat, nstat: Check fdopen() return value - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 6d02518fdc37e - -commit 6d02518fdc37eb12abff67b6f8c741fbd81dce72 -Author: Phil Sutter -Date: Thu Aug 24 11:46:31 2017 +0200 - - ifstat, nstat: Check fdopen() return value - - Prevent passing NULL FILE pointer to fgets() later. - - Fix both tools in a single patch since the code changes are basically - identical. - - Signed-off-by: Phil Sutter ---- - misc/ifstat.c | 16 +++++++++++----- - misc/nstat.c | 16 +++++++++++----- - 2 files changed, 22 insertions(+), 10 deletions(-) - -diff --git a/misc/ifstat.c b/misc/ifstat.c -index 1be21703bf14c..ac3eff6b870a9 100644 ---- a/misc/ifstat.c -+++ b/misc/ifstat.c -@@ -992,12 +992,18 @@ int main(int argc, char *argv[]) - && verify_forging(fd) == 0) { - FILE *sfp = fdopen(fd, "r"); - -- load_raw_table(sfp); -- if (hist_db && source_mismatch) { -- fprintf(stderr, "ifstat: history is stale, ignoring it.\n"); -- hist_db = NULL; -+ if (!sfp) { -+ fprintf(stderr, "ifstat: fdopen failed: %s\n", -+ strerror(errno)); -+ close(fd); -+ } else { -+ load_raw_table(sfp); -+ if (hist_db && source_mismatch) { -+ fprintf(stderr, "ifstat: history is stale, ignoring it.\n"); -+ hist_db = NULL; -+ } -+ fclose(sfp); - } -- fclose(sfp); - } else { - if (fd >= 0) - close(fd); -diff --git a/misc/nstat.c b/misc/nstat.c -index 1212b1f2c8128..a4dd405d43a93 100644 ---- a/misc/nstat.c -+++ b/misc/nstat.c -@@ -706,12 +706,18 @@ int main(int argc, char *argv[]) - && verify_forging(fd) == 0) { - FILE *sfp = fdopen(fd, "r"); - -- load_good_table(sfp); -- if (hist_db && source_mismatch) { -- fprintf(stderr, "nstat: history is stale, ignoring it.\n"); -- hist_db = NULL; -+ if (!sfp) { -+ fprintf(stderr, "nstat: fdopen failed: %s\n", -+ strerror(errno)); -+ close(fd); -+ } else { -+ load_good_table(sfp); -+ if (hist_db && source_mismatch) { -+ fprintf(stderr, "nstat: history is stale, ignoring it.\n"); -+ hist_db = NULL; -+ } -+ fclose(sfp); - } -- fclose(sfp); - } else { - if (fd >= 0) - close(fd); --- -2.21.0 - diff --git a/SOURCES/0102-tc-q_netem-Don-t-dereference-possibly-NULL-pointer.patch b/SOURCES/0102-tc-q_netem-Don-t-dereference-possibly-NULL-pointer.patch deleted file mode 100644 index 5e4162d..0000000 --- a/SOURCES/0102-tc-q_netem-Don-t-dereference-possibly-NULL-pointer.patch +++ /dev/null @@ -1,46 +0,0 @@ -From a7329f9d8681bdbd2d8257b152ae6b4959232e67 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:08 +0200 -Subject: [PATCH] tc/q_netem: Don't dereference possibly NULL pointer - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit a754de3ccd937 - -commit a754de3ccd937500940c6fcd0ad043855f56862d -Author: Phil Sutter -Date: Thu Aug 24 11:46:32 2017 +0200 - - tc/q_netem: Don't dereference possibly NULL pointer - - Assuming 'opt' might be NULL, move the call to RTA_PAYLOAD to after the - check since it dereferences its parameter. - - Signed-off-by: Phil Sutter ---- - tc/q_netem.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/tc/q_netem.c b/tc/q_netem.c -index 0975ae111de97..5a9e747411e85 100644 ---- a/tc/q_netem.c -+++ b/tc/q_netem.c -@@ -538,7 +538,7 @@ static int netem_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) - int *ecn = NULL; - struct tc_netem_qopt qopt; - const struct tc_netem_rate *rate = NULL; -- int len = RTA_PAYLOAD(opt) - sizeof(qopt); -+ int len; - __u64 rate64 = 0; - - SPRINT_BUF(b1); -@@ -546,6 +546,7 @@ static int netem_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) - if (opt == NULL) - return 0; - -+ len = RTA_PAYLOAD(opt) - sizeof(qopt); - if (len < 0) { - fprintf(stderr, "options size error\n"); - return -1; --- -2.21.0 - diff --git a/SOURCES/0103-tc-tc_filter-Make-sure-filter-name-is-not-empty.patch b/SOURCES/0103-tc-tc_filter-Make-sure-filter-name-is-not-empty.patch deleted file mode 100644 index 1b3a4d6..0000000 --- a/SOURCES/0103-tc-tc_filter-Make-sure-filter-name-is-not-empty.patch +++ /dev/null @@ -1,39 +0,0 @@ -From a4c190565a85db814ad1185ada5382e7fb8707a0 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:08 +0200 -Subject: [PATCH] tc/tc_filter: Make sure filter name is not empty - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 75716932a0af2 - -commit 75716932a0af28da207aa57c212794ab28ce9036 -Author: Phil Sutter -Date: Thu Aug 24 11:46:33 2017 +0200 - - tc/tc_filter: Make sure filter name is not empty - - The later check for 'k[0] != 0' requires a non-empty filter name, - otherwise NULL pointer dereference in 'q' might happen. - - Signed-off-by: Phil Sutter ---- - tc/tc_filter.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/tc/tc_filter.c b/tc/tc_filter.c -index e640492b25ba6..a6bb73d12eaba 100644 ---- a/tc/tc_filter.c -+++ b/tc/tc_filter.c -@@ -380,6 +380,9 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv) - usage(); - return 0; - } else { -+ if (!**argv) -+ invarg("invalid filter name", *argv); -+ - strncpy(k, *argv, sizeof(k)-1); - - q = get_filter_kind(k); --- -2.21.0 - diff --git a/SOURCES/0104-tipc-bearer-Prevent-NULL-pointer-dereference.patch b/SOURCES/0104-tipc-bearer-Prevent-NULL-pointer-dereference.patch deleted file mode 100644 index ff49eaf..0000000 --- a/SOURCES/0104-tipc-bearer-Prevent-NULL-pointer-dereference.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 73b2d3ee4bbdbfba7db035d9b89a2bcffc15e1ba Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:08 +0200 -Subject: [PATCH] tipc/bearer: Prevent NULL pointer dereference - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 70a6df3962b84 - -commit 70a6df3962b8448fc9c28d72606828a004ed5b6b -Author: Phil Sutter -Date: Thu Aug 24 11:46:34 2017 +0200 - - tipc/bearer: Prevent NULL pointer dereference - - Signed-off-by: Phil Sutter ---- - tipc/bearer.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tipc/bearer.c b/tipc/bearer.c -index c3d4491f8f6ef..0d84570150624 100644 ---- a/tipc/bearer.c -+++ b/tipc/bearer.c -@@ -439,7 +439,7 @@ static int cmd_bearer_enable(struct nlmsghdr *nlh, const struct cmd *cmd, - return err; - - opt = get_opt(opts, "media"); -- if (strcmp(opt->val, "udp") == 0) { -+ if (opt && strcmp(opt->val, "udp") == 0) { - err = nl_add_udp_enable_opts(nlh, opts, cmdl); - if (err) - return err; --- -2.21.0 - diff --git a/SOURCES/0105-ipntable-Avoid-memory-allocation-for-filter.name.patch b/SOURCES/0105-ipntable-Avoid-memory-allocation-for-filter.name.patch deleted file mode 100644 index 4252a50..0000000 --- a/SOURCES/0105-ipntable-Avoid-memory-allocation-for-filter.name.patch +++ /dev/null @@ -1,58 +0,0 @@ -From c176919cbf8f11f666c2281785e58fd147ecfea0 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:08 +0200 -Subject: [PATCH] ipntable: Avoid memory allocation for filter.name - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 45c2ec9e95fef - -commit 45c2ec9e95fef8eb6f0807d9a7e5f14c14313c7e -Author: Phil Sutter -Date: Thu Aug 24 11:51:45 2017 +0200 - - ipntable: Avoid memory allocation for filter.name - - The original issue was that filter.name might end up unterminated if - user provided string was too long. But in fact it is not necessary to - copy the commandline parameter at all: just make filter.name point to it - instead. - - Signed-off-by: Phil Sutter ---- - ip/ipntable.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/ip/ipntable.c b/ip/ipntable.c -index ae8c74ead2cb8..2f72c989f35df 100644 ---- a/ip/ipntable.c -+++ b/ip/ipntable.c -@@ -37,7 +37,7 @@ static struct - int family; - int index; - #define NONE_DEV (-1) -- char name[1024]; -+ const char *name; - } filter; - - static void usage(void) __attribute__((noreturn)); -@@ -367,7 +367,7 @@ static int print_ntable(const struct sockaddr_nl *who, struct nlmsghdr *n, void - if (tb[NDTA_NAME]) { - const char *name = rta_getattr_str(tb[NDTA_NAME]); - -- if (strlen(filter.name) > 0 && strcmp(filter.name, name)) -+ if (filter.name && strcmp(filter.name, name)) - return 0; - } - if (tb[NDTA_PARMS]) { -@@ -631,7 +631,7 @@ static int ipntable_show(int argc, char **argv) - } else if (strcmp(*argv, "name") == 0) { - NEXT_ARG(); - -- strncpy(filter.name, *argv, sizeof(filter.name)); -+ filter.name = *argv; - } else - invarg("unknown", *argv); - --- -2.21.0 - diff --git a/SOURCES/0106-lib-fs-Fix-format-string-in-find_fs_mount.patch b/SOURCES/0106-lib-fs-Fix-format-string-in-find_fs_mount.patch deleted file mode 100644 index 954ea92..0000000 --- a/SOURCES/0106-lib-fs-Fix-format-string-in-find_fs_mount.patch +++ /dev/null @@ -1,39 +0,0 @@ -From dfc6dc25fcc666ed3fa938bca5ccd87d6cf4a99e Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:08 +0200 -Subject: [PATCH] lib/fs: Fix format string in find_fs_mount() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit eab450789829e - -commit eab450789829e33a64dbd08dced3438d580d5179 -Author: Phil Sutter -Date: Thu Aug 24 11:51:46 2017 +0200 - - lib/fs: Fix format string in find_fs_mount() - - A field width of 4096 allows fscanf() to store that amount of characters - into the given buffer, though that doesn't include the terminating NULL - byte. Decrease the value by one to leave space for it. - - Signed-off-by: Phil Sutter ---- - lib/fs.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lib/fs.c b/lib/fs.c -index c59ac564581d0..1ff881ecfcd8c 100644 ---- a/lib/fs.c -+++ b/lib/fs.c -@@ -45,7 +45,7 @@ static char *find_fs_mount(const char *fs_to_find) - return NULL; - } - -- while (fscanf(fp, "%*s %4096s %127s %*s %*d %*d\n", -+ while (fscanf(fp, "%*s %4095s %127s %*s %*d %*d\n", - path, fstype) == 2) { - if (strcmp(fstype, fs_to_find) == 0) { - mnt = strdup(path); --- -2.21.0 - diff --git a/SOURCES/0107-lib-inet_proto-Review-inet_proto_-a2n-n2a.patch b/SOURCES/0107-lib-inet_proto-Review-inet_proto_-a2n-n2a.patch deleted file mode 100644 index 8f063ea..0000000 --- a/SOURCES/0107-lib-inet_proto-Review-inet_proto_-a2n-n2a.patch +++ /dev/null @@ -1,90 +0,0 @@ -From e47b57df11565c51b9d8a5307a63d93f8e9a061b Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:08 +0200 -Subject: [PATCH] lib/inet_proto: Review inet_proto_{a2n,n2a}() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit cfda500a7d808 - -commit cfda500a7d808a6e0f3eca47abd75c22cfe716e5 -Author: Phil Sutter -Date: Thu Aug 24 11:51:47 2017 +0200 - - lib/inet_proto: Review inet_proto_{a2n,n2a}() - - The original intent was to make sure strings written by those functions - are NUL-terminated at all times, though it was suggested to get rid of - the 15 char protocol name limit as well which this patch accomplishes. - - In addition to that, simplify inet_proto_a2n() a bit: Use the error - checking in get_u8() to find out whether passed 'buf' contains a valid - decimal number instead of checking the first character's value manually. - - Signed-off-by: Phil Sutter ---- - lib/inet_proto.c | 24 +++++++++++++----------- - 1 file changed, 13 insertions(+), 11 deletions(-) - -diff --git a/lib/inet_proto.c b/lib/inet_proto.c -index ceda082b12a2e..53c029039b6d5 100644 ---- a/lib/inet_proto.c -+++ b/lib/inet_proto.c -@@ -25,7 +25,7 @@ - - const char *inet_proto_n2a(int proto, char *buf, int len) - { -- static char ncache[16]; -+ static char *ncache; - static int icache = -1; - struct protoent *pe; - -@@ -34,9 +34,12 @@ const char *inet_proto_n2a(int proto, char *buf, int len) - - pe = getprotobynumber(proto); - if (pe) { -+ if (icache != -1) -+ free(ncache); - icache = proto; -- strncpy(ncache, pe->p_name, 16); -- strncpy(buf, pe->p_name, len); -+ ncache = strdup(pe->p_name); -+ strncpy(buf, pe->p_name, len - 1); -+ buf[len - 1] = '\0'; - return buf; - } - snprintf(buf, len, "ipproto-%d", proto); -@@ -45,24 +48,23 @@ const char *inet_proto_n2a(int proto, char *buf, int len) - - int inet_proto_a2n(const char *buf) - { -- static char ncache[16]; -+ static char *ncache; - static int icache = -1; - struct protoent *pe; -+ __u8 ret; - -- if (icache>=0 && strcmp(ncache, buf) == 0) -+ if (icache != -1 && strcmp(ncache, buf) == 0) - return icache; - -- if (buf[0] >= '0' && buf[0] <= '9') { -- __u8 ret; -- if (get_u8(&ret, buf, 10)) -- return -1; -+ if (!get_u8(&ret, buf, 10)) - return ret; -- } - - pe = getprotobyname(buf); - if (pe) { -+ if (icache != -1) -+ free(ncache); - icache = pe->p_proto; -- strncpy(ncache, pe->p_name, 16); -+ ncache = strdup(pe->p_name); - return pe->p_proto; - } - return -1; --- -2.21.0 - diff --git a/SOURCES/0108-lnstat_util-Simplify-alloc_and_open-a-bit.patch b/SOURCES/0108-lnstat_util-Simplify-alloc_and_open-a-bit.patch deleted file mode 100644 index e7cdb99..0000000 --- a/SOURCES/0108-lnstat_util-Simplify-alloc_and_open-a-bit.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 5cdf4d78d15b127d0f4a7a09e4700d7df16dda19 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:08 +0200 -Subject: [PATCH] lnstat_util: Simplify alloc_and_open() a bit - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit bc27878d21909 - -commit bc27878d21909b110dd21eea0c3505d023f29dc2 -Author: Phil Sutter -Date: Thu Aug 24 11:51:48 2017 +0200 - - lnstat_util: Simplify alloc_and_open() a bit - - Relying upon callers and using unsafe strcpy() is probably not the best - idea. Aside from that, using snprintf() allows to format the string for - lf->path in one go. - - Signed-off-by: Phil Sutter ---- - misc/lnstat_util.c | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - -diff --git a/misc/lnstat_util.c b/misc/lnstat_util.c -index cc54598fe1bef..ec19238c24b94 100644 ---- a/misc/lnstat_util.c -+++ b/misc/lnstat_util.c -@@ -180,11 +180,8 @@ static struct lnstat_file *alloc_and_open(const char *path, const char *file) - } - - /* initialize */ -- /* de->d_name is guaranteed to be <= NAME_MAX */ -- strcpy(lf->basename, file); -- strcpy(lf->path, path); -- strcat(lf->path, "/"); -- strcat(lf->path, lf->basename); -+ snprintf(lf->basename, sizeof(lf->basename), "%s", file); -+ snprintf(lf->path, sizeof(lf->path), "%s/%s", path, file); - - /* initialize to default */ - lf->interval.tv_sec = 1; --- -2.21.0 - diff --git a/SOURCES/0109-tc-m_xt-Fix-for-potential-string-buffer-overflows.patch b/SOURCES/0109-tc-m_xt-Fix-for-potential-string-buffer-overflows.patch deleted file mode 100644 index 07f2309..0000000 --- a/SOURCES/0109-tc-m_xt-Fix-for-potential-string-buffer-overflows.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 8ac8129d710b8a084ce213791874330aa30ec70e Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:08 +0200 -Subject: [PATCH] tc/m_xt: Fix for potential string buffer overflows - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 56270e54661e8 - -commit 56270e54661e8ca51d4b3661b9f9bb12a0a40d95 -Author: Phil Sutter -Date: Thu Aug 24 11:51:49 2017 +0200 - - tc/m_xt: Fix for potential string buffer overflows - - - Use strncpy() when writing to target->t->u.user.name and make sure the - final byte remains untouched (xtables_calloc() set it to zero). - - 'tname' length sanitization was completely wrong: If it's length - exceeded the 16 bytes available in 'k', passing a length value of 16 - to strncpy() would overwrite the previously NULL'ed 'k[15]'. Also, the - sanitization has to happen if 'tname' is exactly 16 bytes long as - well. - - Signed-off-by: Phil Sutter ---- - tc/m_xt.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/tc/m_xt.c b/tc/m_xt.c -index ad52d239caf61..9218b14594403 100644 ---- a/tc/m_xt.c -+++ b/tc/m_xt.c -@@ -95,7 +95,8 @@ build_st(struct xtables_target *target, struct xt_entry_target *t) - if (t == NULL) { - target->t = xtables_calloc(1, size); - target->t->u.target_size = size; -- strcpy(target->t->u.user.name, target->name); -+ strncpy(target->t->u.user.name, target->name, -+ sizeof(target->t->u.user.name) - 1); - target->t->u.user.revision = target->revision; - - if (target->init != NULL) -@@ -277,8 +278,8 @@ static int parse_ipt(struct action_util *a, int *argc_p, - } - fprintf(stdout, " index %d\n", index); - -- if (strlen(tname) > 16) { -- size = 16; -+ if (strlen(tname) >= 16) { -+ size = 15; - k[15] = 0; - } else { - size = 1 + strlen(tname); --- -2.21.0 - diff --git a/SOURCES/0110-lib-ll_map-Choose-size-of-new-cache-items-at-run-tim.patch b/SOURCES/0110-lib-ll_map-Choose-size-of-new-cache-items-at-run-tim.patch deleted file mode 100644 index 3862422..0000000 --- a/SOURCES/0110-lib-ll_map-Choose-size-of-new-cache-items-at-run-tim.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 6ab89ff96d59c90cd6227399a065d52cc38e0ee7 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:08 +0200 -Subject: [PATCH] lib/ll_map: Choose size of new cache items at run-time - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 4b9e91782269f - -commit 4b9e91782269fc871d158ed4f11bfcfe4e3b8bf7 -Author: Phil Sutter -Date: Thu Aug 24 11:51:50 2017 +0200 - - lib/ll_map: Choose size of new cache items at run-time - - Instead of having a fixed buffer of 16 bytes for the interface name, - tailor size of new ll_cache entry using the interface name's actual - length. This also makes sure the following call to strcpy() is safe. - - Signed-off-by: Phil Sutter ---- - lib/ll_map.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/lib/ll_map.c b/lib/ll_map.c -index 4e4556c9ac80b..70684b02042b6 100644 ---- a/lib/ll_map.c -+++ b/lib/ll_map.c -@@ -30,7 +30,7 @@ struct ll_cache { - unsigned flags; - unsigned index; - unsigned short type; -- char name[IFNAMSIZ]; -+ char name[]; - }; - - #define IDXMAP_SIZE 1024 -@@ -120,7 +120,7 @@ int ll_remember_index(const struct sockaddr_nl *who, - return 0; - } - -- im = malloc(sizeof(*im)); -+ im = malloc(sizeof(*im) + strlen(ifname) + 1); - if (im == NULL) - return 0; - im->index = ifi->ifi_index; --- -2.21.0 - diff --git a/SOURCES/0111-ss-Make-struct-tcpstat-fields-timer-and-timeout-unsi.patch b/SOURCES/0111-ss-Make-struct-tcpstat-fields-timer-and-timeout-unsi.patch deleted file mode 100644 index 8a0cf29..0000000 --- a/SOURCES/0111-ss-Make-struct-tcpstat-fields-timer-and-timeout-unsi.patch +++ /dev/null @@ -1,58 +0,0 @@ -From ca6a2e6f21fc48b494216a095f5bd792a0c6e35d Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:08 +0200 -Subject: [PATCH] ss: Make struct tcpstat fields 'timer' and 'timeout' unsigned - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 4cbf5224f2b50 - -commit 4cbf5224f2b50a24e1873508e7a0f1f81cc81a81 -Author: Phil Sutter -Date: Thu Aug 24 11:41:26 2017 +0200 - - ss: Make struct tcpstat fields 'timer' and 'timeout' unsigned - - Both 'timer' and 'timeout' variables of struct tcpstat are either - scanned as unsigned values from /proc/net/tcp{,6} or copied from - 'idiag_timer' and 'idiag_expries' fields of struct inet_diag_msg, which - itself are unsigned. Therefore they may be unsigned as well, which - eliminates the need to check for negative values. - - Signed-off-by: Phil Sutter ---- - misc/ss.c | 8 +++----- - 1 file changed, 3 insertions(+), 5 deletions(-) - -diff --git a/misc/ss.c b/misc/ss.c -index 7a38e9d830e8d..2a981d8b06918 100644 ---- a/misc/ss.c -+++ b/misc/ss.c -@@ -716,8 +716,8 @@ struct dctcpstat { - - struct tcpstat { - struct sockstat ss; -- int timer; -- int timeout; -+ unsigned int timer; -+ unsigned int timeout; - int probes; - char cong_alg[16]; - double rto, ato, rtt, rttvar; -@@ -903,13 +903,11 @@ static void sock_addr_print(const char *addr, char *delim, const char *port, - sock_addr_print_width(addr_width, addr, delim, serv_width, port, ifname); - } - --static const char *print_ms_timer(int timeout) -+static const char *print_ms_timer(unsigned int timeout) - { - static char buf[64]; - int secs, msecs, minutes; - -- if (timeout < 0) -- timeout = 0; - secs = timeout/1000; - minutes = secs/60; - secs = secs%60; --- -2.21.0 - diff --git a/SOURCES/0112-ss-Make-sure-scanned-index-value-to-unix_state_map-i.patch b/SOURCES/0112-ss-Make-sure-scanned-index-value-to-unix_state_map-i.patch deleted file mode 100644 index b68a7b2..0000000 --- a/SOURCES/0112-ss-Make-sure-scanned-index-value-to-unix_state_map-i.patch +++ /dev/null @@ -1,36 +0,0 @@ -From f92edf9b3d088bf8a5619073de43b2f693590be8 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:08 +0200 -Subject: [PATCH] ss: Make sure scanned index value to unix_state_map is sane - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 0aa03350c00d7 - -commit 0aa03350c00d70edbbdab0662a2d8262be2bb68d -Author: Phil Sutter -Date: Thu Aug 24 11:41:27 2017 +0200 - - ss: Make sure scanned index value to unix_state_map is sane - - Signed-off-by: Phil Sutter ---- - misc/ss.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/misc/ss.c b/misc/ss.c -index 2a981d8b06918..fdb00a9f3f696 100644 ---- a/misc/ss.c -+++ b/misc/ss.c -@@ -3236,7 +3236,8 @@ static int unix_show(struct filter *f) - - if (flags & (1 << 16)) { - u->state = SS_LISTEN; -- } else { -+ } else if (u->state > 0 && -+ u->state <= ARRAY_SIZE(unix_state_map)) { - u->state = unix_state_map[u->state-1]; - if (u->type == SOCK_DGRAM && u->state == SS_CLOSE && u->rport) - u->state = SS_ESTABLISHED; --- -2.21.0 - diff --git a/SOURCES/0113-netem-maketable-Check-return-value-of-fscanf.patch b/SOURCES/0113-netem-maketable-Check-return-value-of-fscanf.patch deleted file mode 100644 index b9d33de..0000000 --- a/SOURCES/0113-netem-maketable-Check-return-value-of-fscanf.patch +++ /dev/null @@ -1,37 +0,0 @@ -From d533a60518e79593c6a1813a6f44aa3889045120 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:08 +0200 -Subject: [PATCH] netem/maketable: Check return value of fscanf() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 92963d136de8c - -commit 92963d136de8c370324716add98888b2ce6e6a94 -Author: Phil Sutter -Date: Thu Aug 24 11:41:28 2017 +0200 - - netem/maketable: Check return value of fscanf() - - Signed-off-by: Phil Sutter ---- - netem/maketable.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/netem/maketable.c b/netem/maketable.c -index ad660e7d457f0..ccb8f0c68b062 100644 ---- a/netem/maketable.c -+++ b/netem/maketable.c -@@ -38,8 +38,8 @@ readdoubles(FILE *fp, int *number) - } - - for (i=0; i -Date: Mon, 29 Apr 2019 20:08:08 +0200 -Subject: [PATCH] lib/bpf: Check return value of write() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit b5c78e1b2c868 - -commit b5c78e1b2c8681e82684f47563acd3d383893658 -Author: Phil Sutter -Date: Thu Aug 24 11:41:29 2017 +0200 - - lib/bpf: Check return value of write() - - This is merely to silence the compiler warning. If write to stderr - failed, assume that printing an error message will fail as well so don't - even try. - - Signed-off-by: Phil Sutter ---- - lib/bpf.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/lib/bpf.c b/lib/bpf.c -index 33c5288e82187..7eb754ad7cb56 100644 ---- a/lib/bpf.c -+++ b/lib/bpf.c -@@ -486,7 +486,8 @@ int bpf_trace_pipe(void) - - ret = read(fd, buff, sizeof(buff) - 1); - if (ret > 0) { -- write(2, buff, ret); -+ if (write(STDERR_FILENO, buff, ret) != ret) -+ return -1; - fflush(stderr); - } - } --- -2.21.0 - diff --git a/SOURCES/0115-lib-fs-Fix-and-simplify-make_path.patch b/SOURCES/0115-lib-fs-Fix-and-simplify-make_path.patch deleted file mode 100644 index 85074f3..0000000 --- a/SOURCES/0115-lib-fs-Fix-and-simplify-make_path.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 7ab899539b920609712ad24f871b50a19fd8189f Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:08 +0200 -Subject: [PATCH] lib/fs: Fix and simplify make_path() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit ac3415f5c1b1d - -commit ac3415f5c1b1df2d6a4bf770ad52e2e14c09e58e -Author: Phil Sutter -Date: Thu Aug 24 11:41:30 2017 +0200 - - lib/fs: Fix and simplify make_path() - - Calling stat() before mkdir() is racey: The entry might change in - between. Also, the call to stat() seems to exist only to check if the - directory exists already. So simply call mkdir() unconditionally and - catch only errors other than EEXIST. - - Signed-off-by: Phil Sutter ---- - lib/fs.c | 20 +++++--------------- - 1 file changed, 5 insertions(+), 15 deletions(-) - -diff --git a/lib/fs.c b/lib/fs.c -index 1ff881ecfcd8c..ebe05cd44e11b 100644 ---- a/lib/fs.c -+++ b/lib/fs.c -@@ -102,7 +102,6 @@ out: - int make_path(const char *path, mode_t mode) - { - char *dir, *delim; -- struct stat sbuf; - int rc = -1; - - delim = dir = strdup(path); -@@ -120,20 +119,11 @@ int make_path(const char *path, mode_t mode) - if (delim) - *delim = '\0'; - -- if (stat(dir, &sbuf) != 0) { -- if (errno != ENOENT) { -- fprintf(stderr, -- "stat failed for %s: %s\n", -- dir, strerror(errno)); -- goto out; -- } -- -- if (mkdir(dir, mode) != 0) { -- fprintf(stderr, -- "mkdir failed for %s: %s\n", -- dir, strerror(errno)); -- goto out; -- } -+ rc = mkdir(dir, mode); -+ if (mkdir(dir, mode) != 0 && errno != EEXIST) { -+ fprintf(stderr, "mkdir failed for %s: %s\n", -+ dir, strerror(errno)); -+ goto out; - } - - if (delim == NULL) --- -2.21.0 - diff --git a/SOURCES/0116-lib-libnetlink-Don-t-pass-NULL-parameter-to-memcpy.patch b/SOURCES/0116-lib-libnetlink-Don-t-pass-NULL-parameter-to-memcpy.patch deleted file mode 100644 index db4d66a..0000000 --- a/SOURCES/0116-lib-libnetlink-Don-t-pass-NULL-parameter-to-memcpy.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 8af39fdff4f966d00571bda2610eac8fae2f7482 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:08 +0200 -Subject: [PATCH] lib/libnetlink: Don't pass NULL parameter to memcpy() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 893deac4c43b5 - -commit 893deac4c43b57ae49f736ec050724b6de181062 -Author: Phil Sutter -Date: Thu Aug 24 11:41:31 2017 +0200 - - lib/libnetlink: Don't pass NULL parameter to memcpy() - - Both addattr_l() and rta_addattr_l() may be called with NULL data - pointer and 0 alen parameters. Avoid calling memcpy() in that case. - - Signed-off-by: Phil Sutter ---- - lib/libnetlink.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/lib/libnetlink.c b/lib/libnetlink.c -index 75e20abf0b97f..ff26ddf50552b 100644 ---- a/lib/libnetlink.c -+++ b/lib/libnetlink.c -@@ -898,7 +898,8 @@ int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data, - rta = NLMSG_TAIL(n); - rta->rta_type = type; - rta->rta_len = len; -- memcpy(RTA_DATA(rta), data, alen); -+ if (alen) -+ memcpy(RTA_DATA(rta), data, alen); - n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len); - return 0; - } -@@ -985,7 +986,8 @@ int rta_addattr_l(struct rtattr *rta, int maxlen, int type, - subrta = (struct rtattr *)(((char *)rta) + RTA_ALIGN(rta->rta_len)); - subrta->rta_type = type; - subrta->rta_len = len; -- memcpy(RTA_DATA(subrta), data, alen); -+ if (alen) -+ memcpy(RTA_DATA(subrta), data, alen); - rta->rta_len = NLMSG_ALIGN(rta->rta_len) + RTA_ALIGN(len); - return 0; - } --- -2.21.0 - diff --git a/SOURCES/0117-utils-Implement-strlcpy-and-strlcat.patch b/SOURCES/0117-utils-Implement-strlcpy-and-strlcat.patch deleted file mode 100644 index 48bfa7e..0000000 --- a/SOURCES/0117-utils-Implement-strlcpy-and-strlcat.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 3bcdea42e7402e79a914fe3cbefdcc1caa89464c Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:08 +0200 -Subject: [PATCH] utils: Implement strlcpy() and strlcat() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 8d15e012a3227 - -commit 8d15e012a3227d79295cd95582bb6d8a6f0bdc92 -Author: Phil Sutter -Date: Fri Sep 1 18:52:51 2017 +0200 - - utils: Implement strlcpy() and strlcat() - - By making use of strncpy(), both implementations are really simple so - there is no need to add libbsd as additional dependency. - - Signed-off-by: Phil Sutter ---- - include/utils.h | 3 +++ - lib/utils.c | 19 +++++++++++++++++++ - 2 files changed, 22 insertions(+) - -diff --git a/include/utils.h b/include/utils.h -index d707a9dacdb85..d596a6fc10574 100644 ---- a/include/utils.h -+++ b/include/utils.h -@@ -264,4 +264,7 @@ int make_path(const char *path, mode_t mode); - char *find_cgroup2_mount(void); - int get_command_name(const char *pid, char *comm, size_t len); - -+size_t strlcpy(char *dst, const char *src, size_t size); -+size_t strlcat(char *dst, const char *src, size_t size); -+ - #endif /* __UTILS_H__ */ -diff --git a/lib/utils.c b/lib/utils.c -index fc9c575ba0c7d..c9ba2f332c2a7 100644 ---- a/lib/utils.c -+++ b/lib/utils.c -@@ -1228,3 +1228,22 @@ int get_real_family(int rtm_type, int rtm_family) - - return rtm_family; - } -+ -+size_t strlcpy(char *dst, const char *src, size_t size) -+{ -+ if (size) { -+ strncpy(dst, src, size - 1); -+ dst[size - 1] = '\0'; -+ } -+ return strlen(src); -+} -+ -+size_t strlcat(char *dst, const char *src, size_t size) -+{ -+ size_t dlen = strlen(dst); -+ -+ if (dlen > size) -+ return dlen + strlen(src); -+ -+ return dlen + strlcpy(dst + dlen, src, size - dlen); -+} --- -2.21.0 - diff --git a/SOURCES/0118-Convert-the-obvious-cases-to-strlcpy.patch b/SOURCES/0118-Convert-the-obvious-cases-to-strlcpy.patch deleted file mode 100644 index 958e698..0000000 --- a/SOURCES/0118-Convert-the-obvious-cases-to-strlcpy.patch +++ /dev/null @@ -1,135 +0,0 @@ -From e557cf7984d2f06aff158a9089e714e5f445d3ac Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:08:08 +0200 -Subject: [PATCH] Convert the obvious cases to strlcpy() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 18f156bfecda2 -Conflicts: -* on iproute_lwtunnel.c, due to missing commit - e8493916a8ede ("iproute: add support for SR-IPv6 lwtunnel encapsulation") -* on lib/bpf.c, due to missing commit - 95ae9a4870e7d ("bpf: fix mnt path when from env") - fix bpf_find_mntpt() in this case, instead. - -commit 18f156bfecda20166c2fb543ba8c9c6559edef9c -Author: Phil Sutter -Date: Fri Sep 1 18:52:52 2017 +0200 - - Convert the obvious cases to strlcpy() - - This converts the typical idiom of manually terminating the buffer after - a call to strncpy(). - - Signed-off-by: Phil Sutter ---- - ip/ipnetns.c | 3 +-- - ip/ipvrf.c | 3 +-- - lib/bpf.c | 3 +-- - lib/fs.c | 3 +-- - lib/inet_proto.c | 3 +-- - misc/ss.c | 3 +-- - tc/em_ipset.c | 3 +-- - 7 files changed, 7 insertions(+), 14 deletions(-) - -diff --git a/ip/ipnetns.c b/ip/ipnetns.c -index 1c0ade90dee5e..427b59c57381d 100644 ---- a/ip/ipnetns.c -+++ b/ip/ipnetns.c -@@ -523,8 +523,7 @@ int netns_identify_pid(const char *pidstr, char *name, int len) - - if ((st.st_dev == netst.st_dev) && - (st.st_ino == netst.st_ino)) { -- strncpy(name, entry->d_name, len - 1); -- name[len - 1] = '\0'; -+ strlcpy(name, entry->d_name, len); - } - } - closedir(dir); -diff --git a/ip/ipvrf.c b/ip/ipvrf.c -index ae3b48fa81996..f58c8df728265 100644 ---- a/ip/ipvrf.c -+++ b/ip/ipvrf.c -@@ -333,8 +333,7 @@ static int vrf_path(char *vpath, size_t len) - if (vrf) - *vrf = '\0'; - -- strncpy(vpath, start, len - 1); -- vpath[len - 1] = '\0'; -+ strlcpy(vpath, start, len); - - /* if vrf path is just / then return nothing */ - if (!strcmp(vpath, "/")) -diff --git a/lib/bpf.c b/lib/bpf.c -index 7eb754ad7cb56..e072cba214067 100644 ---- a/lib/bpf.c -+++ b/lib/bpf.c -@@ -424,8 +424,7 @@ static const char *bpf_find_mntpt(const char *fstype, unsigned long magic, - ptr = known_mnts; - while (*ptr) { - if (bpf_valid_mntpt(*ptr, magic) == 0) { -- strncpy(mnt, *ptr, len - 1); -- mnt[len - 1] = 0; -+ strlcpy(mnt, *ptr, len); - return mnt; - } - ptr++; -diff --git a/lib/fs.c b/lib/fs.c -index ebe05cd44e11b..86efd4ed2ed80 100644 ---- a/lib/fs.c -+++ b/lib/fs.c -@@ -172,8 +172,7 @@ int get_command_name(const char *pid, char *comm, size_t len) - if (nl) - *nl = '\0'; - -- strncpy(comm, name, len - 1); -- comm[len - 1] = '\0'; -+ strlcpy(comm, name, len); - break; - } - -diff --git a/lib/inet_proto.c b/lib/inet_proto.c -index 53c029039b6d5..bdfd52fdafe5a 100644 ---- a/lib/inet_proto.c -+++ b/lib/inet_proto.c -@@ -38,8 +38,7 @@ const char *inet_proto_n2a(int proto, char *buf, int len) - free(ncache); - icache = proto; - ncache = strdup(pe->p_name); -- strncpy(buf, pe->p_name, len - 1); -- buf[len - 1] = '\0'; -+ strlcpy(buf, pe->p_name, len); - return buf; - } - snprintf(buf, len, "ipproto-%d", proto); -diff --git a/misc/ss.c b/misc/ss.c -index fdb00a9f3f696..6aaae1b5390e4 100644 ---- a/misc/ss.c -+++ b/misc/ss.c -@@ -444,8 +444,7 @@ static void user_ent_hash_build(void) - - user_ent_hash_build_init = 1; - -- strncpy(name, root, sizeof(name)-1); -- name[sizeof(name)-1] = 0; -+ strlcpy(name, root, sizeof(name)); - - if (strlen(name) == 0 || name[strlen(name)-1] != '/') - strcat(name, "/"); -diff --git a/tc/em_ipset.c b/tc/em_ipset.c -index b59756515d239..48b287f5ba3b2 100644 ---- a/tc/em_ipset.c -+++ b/tc/em_ipset.c -@@ -145,8 +145,7 @@ get_set_byname(const char *setname, struct xt_set_info *info) - int res; - - req.op = IP_SET_OP_GET_BYNAME; -- strncpy(req.set.name, setname, IPSET_MAXNAMELEN); -- req.set.name[IPSET_MAXNAMELEN - 1] = '\0'; -+ strlcpy(req.set.name, setname, IPSET_MAXNAMELEN); - res = do_getsockopt(&req); - if (res != 0) - return -1; --- -2.21.0 - diff --git a/SOURCES/0119-Convert-harmful-calls-to-strncpy-to-strlcpy.patch b/SOURCES/0119-Convert-harmful-calls-to-strncpy-to-strlcpy.patch deleted file mode 100644 index b3c641d..0000000 --- a/SOURCES/0119-Convert-harmful-calls-to-strncpy-to-strlcpy.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 9556150792daf8f2fbea934bcb77b4b74a21b2e1 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:09:12 +0200 -Subject: [PATCH] Convert harmful calls to strncpy() to strlcpy() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 532b8874fe545 - -commit 532b8874fe545acaa8d45c4dd3b54b8f3bb41d9f -Author: Phil Sutter -Date: Fri Sep 1 18:52:53 2017 +0200 - - Convert harmful calls to strncpy() to strlcpy() - - This patch converts spots where manual buffer termination was missing to - strlcpy() since that does what is needed. - - Signed-off-by: Phil Sutter ---- - genl/ctrl.c | 2 +- - ip/ipvrf.c | 2 +- - ip/xfrm_state.c | 2 +- - 3 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/genl/ctrl.c b/genl/ctrl.c -index 21e857cfcfc25..a6d31b04e5679 100644 ---- a/genl/ctrl.c -+++ b/genl/ctrl.c -@@ -317,7 +317,7 @@ static int ctrl_list(int cmd, int argc, char **argv) - - if (matches(*argv, "name") == 0) { - NEXT_ARG(); -- strncpy(d, *argv, sizeof (d) - 1); -+ strlcpy(d, *argv, sizeof(d)); - addattr_l(nlh, 128, CTRL_ATTR_FAMILY_NAME, - d, strlen(d) + 1); - } else if (matches(*argv, "id") == 0) { -diff --git a/ip/ipvrf.c b/ip/ipvrf.c -index f58c8df728265..406cddbcd44ca 100644 ---- a/ip/ipvrf.c -+++ b/ip/ipvrf.c -@@ -71,7 +71,7 @@ static int vrf_identify(pid_t pid, char *name, size_t len) - if (end) - *end = '\0'; - -- strncpy(name, vrf, len - 1); -+ strlcpy(name, vrf, len); - break; - } - } -diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c -index 04ed3492ad3b5..2222737cdd98d 100644 ---- a/ip/xfrm_state.c -+++ b/ip/xfrm_state.c -@@ -123,7 +123,7 @@ static int xfrm_algo_parse(struct xfrm_algo *alg, enum xfrm_attr_type_t type, - fprintf(stderr, "warning: ALGO-NAME/ALGO-KEYMAT values will be sent to the kernel promiscuously! (verifying them isn't implemented yet)\n"); - #endif - -- strncpy(alg->alg_name, name, sizeof(alg->alg_name)); -+ strlcpy(alg->alg_name, name, sizeof(alg->alg_name)); - - if (slen > 2 && strncmp(key, "0x", 2) == 0) { - /* split two chars "0x" from the top */ --- -2.21.0 - diff --git a/SOURCES/0120-ipxfrm-Replace-STRBUF_CAT-macro-with-strlcat.patch b/SOURCES/0120-ipxfrm-Replace-STRBUF_CAT-macro-with-strlcat.patch deleted file mode 100644 index 8c0e27e..0000000 --- a/SOURCES/0120-ipxfrm-Replace-STRBUF_CAT-macro-with-strlcat.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 65d69021e5b8998cec1e7a13b8b297bfc606f9fd Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:09:12 +0200 -Subject: [PATCH] ipxfrm: Replace STRBUF_CAT macro with strlcat() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 44cc6c792a650 - -commit 44cc6c792a6503e024f042c65f35cd44b3283b20 -Author: Phil Sutter -Date: Fri Sep 1 18:52:54 2017 +0200 - - ipxfrm: Replace STRBUF_CAT macro with strlcat() - - Signed-off-by: Phil Sutter ---- - ip/ipxfrm.c | 21 +++++---------------- - 1 file changed, 5 insertions(+), 16 deletions(-) - -diff --git a/ip/ipxfrm.c b/ip/ipxfrm.c -index b0cfac178f8bc..df72a0c0bf88e 100644 ---- a/ip/ipxfrm.c -+++ b/ip/ipxfrm.c -@@ -40,17 +40,6 @@ - #include "ip_common.h" - - #define STRBUF_SIZE (128) --#define STRBUF_CAT(buf, str) \ -- do { \ -- int rest = sizeof(buf) - 1 - strlen(buf); \ -- if (rest > 0) { \ -- int len = strlen(str); \ -- if (len > rest) \ -- len = rest; \ -- strncat(buf, str, len); \ -- buf[sizeof(buf) - 1] = '\0'; \ -- } \ -- } while (0); - - struct xfrm_filter filter; - -@@ -883,8 +872,8 @@ void xfrm_state_info_print(struct xfrm_usersa_info *xsinfo, - prefix, title); - - if (prefix) -- STRBUF_CAT(buf, prefix); -- STRBUF_CAT(buf, "\t"); -+ strlcat(buf, prefix, sizeof(buf)); -+ strlcat(buf, "\t", sizeof(buf)); - - fputs(buf, fp); - fprintf(fp, "replay-window %u ", xsinfo->replay_window); -@@ -925,7 +914,7 @@ void xfrm_state_info_print(struct xfrm_usersa_info *xsinfo, - char sbuf[STRBUF_SIZE]; - - memcpy(sbuf, buf, sizeof(sbuf)); -- STRBUF_CAT(sbuf, "sel "); -+ strlcat(sbuf, "sel ", sizeof(sbuf)); - - xfrm_selector_print(&xsinfo->sel, xsinfo->family, fp, sbuf); - } -@@ -973,8 +962,8 @@ void xfrm_policy_info_print(struct xfrm_userpolicy_info *xpinfo, - } - - if (prefix) -- STRBUF_CAT(buf, prefix); -- STRBUF_CAT(buf, "\t"); -+ strlcat(buf, prefix, sizeof(buf)); -+ strlcat(buf, "\t", sizeof(buf)); - - fputs(buf, fp); - if (xpinfo->dir >= XFRM_POLICY_MAX) { --- -2.21.0 - diff --git a/SOURCES/0121-tc_util-No-need-to-terminate-an-snprintf-ed-buffer.patch b/SOURCES/0121-tc_util-No-need-to-terminate-an-snprintf-ed-buffer.patch deleted file mode 100644 index 13e8e10..0000000 --- a/SOURCES/0121-tc_util-No-need-to-terminate-an-snprintf-ed-buffer.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 42b9cc605f54f2a3ad75a29b5f2fc308bfe5fc61 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:09:12 +0200 -Subject: [PATCH] tc_util: No need to terminate an snprintf'ed buffer - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 9376314b49a47 - -commit 9376314b49a47eb42ade3fc0d41cb51438f8dbc6 -Author: Phil Sutter -Date: Fri Sep 1 18:52:55 2017 +0200 - - tc_util: No need to terminate an snprintf'ed buffer - - snprintf() won't leave the buffer unterminated, so manually terminating - is not necessary here. - - Signed-off-by: Phil Sutter ---- - tc/tc_util.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/tc/tc_util.c b/tc/tc_util.c -index 24ca1f1c1c040..296825ae174e0 100644 ---- a/tc/tc_util.c -+++ b/tc/tc_util.c -@@ -430,7 +430,6 @@ const char *action_n2a(int action) - return "stolen"; - default: - snprintf(buf, 64, "%d", action); -- buf[63] = '\0'; - return buf; - } - } --- -2.21.0 - diff --git a/SOURCES/0122-lnstat_util-Make-sure-buffer-is-NUL-terminated.patch b/SOURCES/0122-lnstat_util-Make-sure-buffer-is-NUL-terminated.patch deleted file mode 100644 index 05636bf..0000000 --- a/SOURCES/0122-lnstat_util-Make-sure-buffer-is-NUL-terminated.patch +++ /dev/null @@ -1,40 +0,0 @@ -From ed508c9ee5991655039d2b080191b1c70680b5c8 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:09:12 +0200 -Subject: [PATCH] lnstat_util: Make sure buffer is NUL-terminated - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit bc4a57b87990b - -commit bc4a57b87990b30c85fdf0efbc1f8f219466daf4 -Author: Phil Sutter -Date: Fri Sep 1 18:52:56 2017 +0200 - - lnstat_util: Make sure buffer is NUL-terminated - - Can't use strlcpy() here since lnstat is not linked against libutil. - - While being at it, fix coding style in that chunk as well. - - Signed-off-by: Phil Sutter ---- - misc/lnstat_util.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/misc/lnstat_util.c b/misc/lnstat_util.c -index ec19238c24b94..c2dc42ec1ff12 100644 ---- a/misc/lnstat_util.c -+++ b/misc/lnstat_util.c -@@ -150,7 +150,8 @@ static int lnstat_scan_compat_rtstat_fields(struct lnstat_file *lf) - { - char buf[FGETS_BUF_SIZE]; - -- strncpy(buf, RTSTAT_COMPAT_LINE, sizeof(buf)-1); -+ strncpy(buf, RTSTAT_COMPAT_LINE, sizeof(buf) - 1); -+ buf[sizeof(buf) - 1] = '\0'; - - return __lnstat_scan_fields(lf, buf); - } --- -2.21.0 - diff --git a/SOURCES/0123-utils-strlcpy-and-strlcat-don-t-clobber-dst.patch b/SOURCES/0123-utils-strlcpy-and-strlcat-don-t-clobber-dst.patch deleted file mode 100644 index 7e0e723..0000000 --- a/SOURCES/0123-utils-strlcpy-and-strlcat-don-t-clobber-dst.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 866b995355894ab8f20d22a554d47322dcf1029a Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:09:13 +0200 -Subject: [PATCH] utils: strlcpy() and strlcat() don't clobber dst - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 50ea3c64384b1 - -commit 50ea3c64384b1d1bfa9c96de86c21ac8e9fef183 -Author: Phil Sutter -Date: Wed Sep 6 18:51:42 2017 +0200 - - utils: strlcpy() and strlcat() don't clobber dst - - As David Laight correctly pointed out, the first version of strlcpy() - modified dst buffer behind the string copied into it. Fix this by - writing NUL to the byte immediately following src string instead of to - the last byte in dst. Doing so also allows to reduce overhead by using - memcpy(). - - Improve strlcat() by avoiding the call to strlcpy() if dst string is - already full, not just as sanity check. - - Signed-off-by: Phil Sutter ---- - lib/utils.c | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - -diff --git a/lib/utils.c b/lib/utils.c -index c9ba2f332c2a7..228d97bfe5e9b 100644 ---- a/lib/utils.c -+++ b/lib/utils.c -@@ -1231,18 +1231,22 @@ int get_real_family(int rtm_type, int rtm_family) - - size_t strlcpy(char *dst, const char *src, size_t size) - { -+ size_t srclen = strlen(src); -+ - if (size) { -- strncpy(dst, src, size - 1); -- dst[size - 1] = '\0'; -+ size_t minlen = min(srclen, size - 1); -+ -+ memcpy(dst, src, minlen); -+ dst[minlen] = '\0'; - } -- return strlen(src); -+ return srclen; - } - - size_t strlcat(char *dst, const char *src, size_t size) - { - size_t dlen = strlen(dst); - -- if (dlen > size) -+ if (dlen >= size) - return dlen + strlen(src); - - return dlen + strlcpy(dst + dlen, src, size - dlen); --- -2.21.0 - diff --git a/SOURCES/0124-ip-6-tunnel-Avoid-copying-user-supplied-interface-na.patch b/SOURCES/0124-ip-6-tunnel-Avoid-copying-user-supplied-interface-na.patch deleted file mode 100644 index 308f8ff..0000000 --- a/SOURCES/0124-ip-6-tunnel-Avoid-copying-user-supplied-interface-na.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 74331750f118690ca3c375e52b10272b992320e7 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:09:13 +0200 -Subject: [PATCH] ip{6, }tunnel: Avoid copying user-supplied interface name - around - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 26111ab1dba82 - -commit 26111ab1dba820421ccaf283ac097a79b95023a2 -Author: Phil Sutter -Date: Mon Oct 2 13:46:35 2017 +0200 - - ip{6, }tunnel: Avoid copying user-supplied interface name around - - In both files' parse_args() functions as well as in iptunnel's do_prl() - and do_6rd() functions, a user-supplied 'dev' parameter is uselessly - copied into a temporary buffer before passing it to ll_name_to_index() - or copying into a struct ifreq. Avoid this by just caching the argv - pointer value until the later lookup/strcpy. - - Signed-off-by: Phil Sutter ---- - ip/ip6tunnel.c | 6 +++--- - ip/iptunnel.c | 22 +++++++++------------- - 2 files changed, 12 insertions(+), 16 deletions(-) - -diff --git a/ip/ip6tunnel.c b/ip/ip6tunnel.c -index b4a7def144226..c12d700e74189 100644 ---- a/ip/ip6tunnel.c -+++ b/ip/ip6tunnel.c -@@ -136,7 +136,7 @@ static void print_tunnel(struct ip6_tnl_parm2 *p) - static int parse_args(int argc, char **argv, int cmd, struct ip6_tnl_parm2 *p) - { - int count = 0; -- char medium[IFNAMSIZ] = {}; -+ const char *medium = NULL; - - while (argc > 0) { - if (strcmp(*argv, "mode") == 0) { -@@ -180,7 +180,7 @@ static int parse_args(int argc, char **argv, int cmd, struct ip6_tnl_parm2 *p) - memcpy(&p->laddr, &laddr.data, sizeof(p->laddr)); - } else if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); -- strncpy(medium, *argv, IFNAMSIZ - 1); -+ medium = *argv; - } else if (strcmp(*argv, "encaplimit") == 0) { - NEXT_ARG(); - if (strcmp(*argv, "none") == 0) { -@@ -285,7 +285,7 @@ static int parse_args(int argc, char **argv, int cmd, struct ip6_tnl_parm2 *p) - count++; - argc--; argv++; - } -- if (medium[0]) { -+ if (medium) { - p->link = ll_name_to_index(medium); - if (p->link == 0) { - fprintf(stderr, "Cannot find device \"%s\"\n", medium); -diff --git a/ip/iptunnel.c b/ip/iptunnel.c -index 105d0f5576f1a..0acfd0793d3cd 100644 ---- a/ip/iptunnel.c -+++ b/ip/iptunnel.c -@@ -60,7 +60,7 @@ static void set_tunnel_proto(struct ip_tunnel_parm *p, int proto) - static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) - { - int count = 0; -- char medium[IFNAMSIZ] = {}; -+ const char *medium = NULL; - int isatap = 0; - - memset(p, 0, sizeof(*p)); -@@ -139,7 +139,7 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) - p->iph.saddr = htonl(INADDR_ANY); - } else if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); -- strncpy(medium, *argv, IFNAMSIZ - 1); -+ medium = *argv; - } else if (strcmp(*argv, "ttl") == 0 || - strcmp(*argv, "hoplimit") == 0 || - strcmp(*argv, "hlim") == 0) { -@@ -216,7 +216,7 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) - } - } - -- if (medium[0]) { -+ if (medium) { - p->link = ll_name_to_index(medium); - if (p->link == 0) { - fprintf(stderr, "Cannot find device \"%s\"\n", medium); -@@ -465,9 +465,8 @@ static int do_prl(int argc, char **argv) - { - struct ip_tunnel_prl p = {}; - int count = 0; -- int devname = 0; - int cmd = 0; -- char medium[IFNAMSIZ] = {}; -+ const char *medium = NULL; - - while (argc > 0) { - if (strcmp(*argv, "prl-default") == 0) { -@@ -488,8 +487,7 @@ static int do_prl(int argc, char **argv) - count++; - } else if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); -- strncpy(medium, *argv, IFNAMSIZ-1); -- devname++; -+ medium = *argv; - } else { - fprintf(stderr, - "Invalid PRL parameter \"%s\"\n", *argv); -@@ -502,7 +500,7 @@ static int do_prl(int argc, char **argv) - } - argc--; argv++; - } -- if (devname == 0) { -+ if (!medium) { - fprintf(stderr, "Must specify device\n"); - exit(-1); - } -@@ -513,9 +511,8 @@ static int do_prl(int argc, char **argv) - static int do_6rd(int argc, char **argv) - { - struct ip_tunnel_6rd ip6rd = {}; -- int devname = 0; - int cmd = 0; -- char medium[IFNAMSIZ] = {}; -+ const char *medium = NULL; - inet_prefix prefix; - - while (argc > 0) { -@@ -537,8 +534,7 @@ static int do_6rd(int argc, char **argv) - cmd = SIOCDEL6RD; - } else if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); -- strncpy(medium, *argv, IFNAMSIZ-1); -- devname++; -+ medium = *argv; - } else { - fprintf(stderr, - "Invalid 6RD parameter \"%s\"\n", *argv); -@@ -546,7 +542,7 @@ static int do_6rd(int argc, char **argv) - } - argc--; argv++; - } -- if (devname == 0) { -+ if (!medium) { - fprintf(stderr, "Must specify device\n"); - exit(-1); - } --- -2.21.0 - diff --git a/SOURCES/0125-tc-flower-No-need-to-cache-indev-arg.patch b/SOURCES/0125-tc-flower-No-need-to-cache-indev-arg.patch deleted file mode 100644 index 980c513..0000000 --- a/SOURCES/0125-tc-flower-No-need-to-cache-indev-arg.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 85bcdf3ca3a76ce3b4f62769aa64adcb1c849082 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:09:13 +0200 -Subject: [PATCH] tc: flower: No need to cache indev arg - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit ee474849c8511 - -commit ee474849c85116ec36e387882447f737ac3fdefb -Author: Phil Sutter -Date: Mon Oct 2 13:46:36 2017 +0200 - - tc: flower: No need to cache indev arg - - Since addattrstrz() will copy the provided string into the attribute - payload, there is no need to cache the data. - - Signed-off-by: Phil Sutter ---- - tc/f_flower.c | 5 +---- - 1 file changed, 1 insertion(+), 4 deletions(-) - -diff --git a/tc/f_flower.c b/tc/f_flower.c -index e2c7daa0b8e03..34249254603ff 100644 ---- a/tc/f_flower.c -+++ b/tc/f_flower.c -@@ -642,11 +642,8 @@ static int flower_parse_opt(struct filter_util *qu, char *handle, - } else if (matches(*argv, "skip_sw") == 0) { - flags |= TCA_CLS_FLAGS_SKIP_SW; - } else if (matches(*argv, "indev") == 0) { -- char ifname[IFNAMSIZ] = {}; -- - NEXT_ARG(); -- strncpy(ifname, *argv, sizeof(ifname) - 1); -- addattrstrz(n, MAX_MSG, TCA_FLOWER_INDEV, ifname); -+ addattrstrz(n, MAX_MSG, TCA_FLOWER_INDEV, *argv); - } else if (matches(*argv, "vlan_id") == 0) { - __u16 vid; - --- -2.21.0 - diff --git a/SOURCES/0126-Check-user-supplied-interface-name-lengths.patch b/SOURCES/0126-Check-user-supplied-interface-name-lengths.patch deleted file mode 100644 index 7ef7771..0000000 --- a/SOURCES/0126-Check-user-supplied-interface-name-lengths.patch +++ /dev/null @@ -1,378 +0,0 @@ -From 358ca205cfc9646aefae6572607a0a1363086e51 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Mon, 29 Apr 2019 20:09:13 +0200 -Subject: [PATCH] Check user supplied interface name lengths - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 625df645b703d - -commit 625df645b703dc858d54784c35beff64464afae2 -Author: Phil Sutter -Date: Mon Oct 2 13:46:37 2017 +0200 - - Check user supplied interface name lengths - - The original problem was that something like: - - | strncpy(ifr.ifr_name, *argv, IFNAMSIZ); - - might leave ifr.ifr_name unterminated if length of *argv exceeds - IFNAMSIZ. In order to fix this, I thought about replacing all those - cases with (equivalent) calls to snprintf() or even introducing - strlcpy(). But as Ulrich Drepper correctly pointed out when rejecting - the latter from being added to glibc, truncating a string without - notifying the user is not to be considered good practice. So let's - excercise what he suggested and reject empty, overlong or otherwise - invalid interface names right from the start - this way calls to - strncpy() like shown above become safe and the user has a chance to - reconsider what he was trying to do. - - Note that this doesn't add calls to check_ifname() to all places where - user supplied interface name is parsed. In many cases, the interface - must exist already and is therefore looked up using ll_name_to_index(), - so if_nametoindex() will perform the necessary checks already. - - Signed-off-by: Phil Sutter ---- - include/utils.h | 2 ++ - ip/ip6tunnel.c | 3 ++- - ip/ipl2tp.c | 4 +++- - ip/iplink.c | 31 ++++++++++++------------------- - ip/ipmaddr.c | 3 ++- - ip/iprule.c | 10 ++++++++-- - ip/iptunnel.c | 7 ++++++- - ip/iptuntap.c | 6 ++++-- - lib/utils.c | 29 +++++++++++++++++++++++++++++ - misc/arpd.c | 3 ++- - tc/f_flower.c | 2 ++ - 11 files changed, 72 insertions(+), 28 deletions(-) - -diff --git a/include/utils.h b/include/utils.h -index d596a6fc10574..0382460136180 100644 ---- a/include/utils.h -+++ b/include/utils.h -@@ -145,6 +145,8 @@ void missarg(const char *) __attribute__((noreturn)); - void invarg(const char *, const char *) __attribute__((noreturn)); - void duparg(const char *, const char *) __attribute__((noreturn)); - void duparg2(const char *, const char *) __attribute__((noreturn)); -+int check_ifname(const char *); -+int get_ifname(char *, const char *); - int matches(const char *arg, const char *pattern); - int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits); - -diff --git a/ip/ip6tunnel.c b/ip/ip6tunnel.c -index c12d700e74189..bc44bef7f030c 100644 ---- a/ip/ip6tunnel.c -+++ b/ip/ip6tunnel.c -@@ -273,7 +273,8 @@ static int parse_args(int argc, char **argv, int cmd, struct ip6_tnl_parm2 *p) - usage(); - if (p->name[0]) - duparg2("name", *argv); -- strncpy(p->name, *argv, IFNAMSIZ - 1); -+ if (get_ifname(p->name, *argv)) -+ invarg("\"name\" not a valid ifname", *argv); - if (cmd == SIOCCHGTUNNEL && count == 0) { - struct ip6_tnl_parm2 old_p = {}; - -diff --git a/ip/ipl2tp.c b/ip/ipl2tp.c -index 742adbe4f9c3a..7c5ed313b186f 100644 ---- a/ip/ipl2tp.c -+++ b/ip/ipl2tp.c -@@ -182,7 +182,7 @@ static int create_session(struct l2tp_parm *p) - if (p->peer_cookie_len) - addattr_l(&req.n, 1024, L2TP_ATTR_PEER_COOKIE, - p->peer_cookie, p->peer_cookie_len); -- if (p->ifname && p->ifname[0]) -+ if (p->ifname) - addattrstrz(&req.n, 1024, L2TP_ATTR_IFNAME, p->ifname); - - if (rtnl_talk(&genl_rth, &req.n, NULL) < 0) -@@ -545,6 +545,8 @@ static int parse_args(int argc, char **argv, int cmd, struct l2tp_parm *p) - } - } else if (strcmp(*argv, "name") == 0) { - NEXT_ARG(); -+ if (check_ifname(*argv)) -+ invarg("\"name\" not a valid ifname", *argv); - p->ifname = *argv; - } else if (strcmp(*argv, "remote") == 0) { - NEXT_ARG(); -diff --git a/ip/iplink.c b/ip/iplink.c -index db5b2c9645ba8..50f1075d94171 100644 ---- a/ip/iplink.c -+++ b/ip/iplink.c -@@ -581,6 +581,8 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, - req->i.ifi_flags &= ~IFF_UP; - } else if (strcmp(*argv, "name") == 0) { - NEXT_ARG(); -+ if (check_ifname(*argv)) -+ invarg("\"name\" not a valid ifname", *argv); - *name = *argv; - } else if (strcmp(*argv, "index") == 0) { - NEXT_ARG(); -@@ -848,6 +850,8 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, - NEXT_ARG(); - if (*dev) - duparg2("dev", *argv); -+ if (check_ifname(*argv)) -+ invarg("\"dev\" not a valid ifname", *argv); - *dev = *argv; - dev_index = ll_name_to_index(*dev); - } -@@ -870,7 +874,6 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, - - static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv) - { -- int len; - char *dev = NULL; - char *name = NULL; - char *link = NULL; -@@ -960,13 +963,8 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv) - } - - if (name) { -- len = strlen(name) + 1; -- if (len == 1) -- invarg("\"\" is not a valid device identifier\n", -- "name"); -- if (len > IFNAMSIZ) -- invarg("\"name\" too long\n", name); -- addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name, len); -+ addattr_l(&req.n, sizeof(req), -+ IFLA_IFNAME, name, strlen(name) + 1); - } - - if (type) { -@@ -1016,7 +1014,6 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv) - - int iplink_get(unsigned int flags, char *name, __u32 filt_mask) - { -- int len; - struct iplink_req req = { - .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)), - .n.nlmsg_flags = NLM_F_REQUEST | flags, -@@ -1026,13 +1023,8 @@ int iplink_get(unsigned int flags, char *name, __u32 filt_mask) - struct nlmsghdr *answer; - - if (name) { -- len = strlen(name) + 1; -- if (len == 1) -- invarg("\"\" is not a valid device identifier\n", -- "name"); -- if (len > IFNAMSIZ) -- invarg("\"name\" too long\n", name); -- addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name, len); -+ addattr_l(&req.n, sizeof(req), -+ IFLA_IFNAME, name, strlen(name) + 1); - } - addattr32(&req.n, sizeof(req), IFLA_EXT_MASK, filt_mask); - -@@ -1256,6 +1248,8 @@ static int do_set(int argc, char **argv) - flags &= ~IFF_UP; - } else if (strcmp(*argv, "name") == 0) { - NEXT_ARG(); -+ if (check_ifname(*argv)) -+ invarg("\"name\" not a valid ifname", *argv); - newname = *argv; - } else if (matches(*argv, "address") == 0) { - NEXT_ARG(); -@@ -1346,6 +1340,8 @@ static int do_set(int argc, char **argv) - - if (dev) - duparg2("dev", *argv); -+ if (check_ifname(*argv)) -+ invarg("\"dev\" not a valid ifname", *argv); - dev = *argv; - } - argc--; argv++; -@@ -1374,9 +1370,6 @@ static int do_set(int argc, char **argv) - } - - if (newname && strcmp(dev, newname)) { -- if (strlen(newname) == 0) -- invarg("\"\" is not a valid device identifier\n", -- "name"); - if (do_changename(dev, newname) < 0) - return -1; - dev = newname; -diff --git a/ip/ipmaddr.c b/ip/ipmaddr.c -index 85a69e779563d..5683f6fa830c1 100644 ---- a/ip/ipmaddr.c -+++ b/ip/ipmaddr.c -@@ -284,7 +284,8 @@ static int multiaddr_modify(int cmd, int argc, char **argv) - NEXT_ARG(); - if (ifr.ifr_name[0]) - duparg("dev", *argv); -- strncpy(ifr.ifr_name, *argv, IFNAMSIZ); -+ if (get_ifname(ifr.ifr_name, *argv)) -+ invarg("\"dev\" not a valid ifname", *argv); - } else { - if (matches(*argv, "address") == 0) { - NEXT_ARG(); -diff --git a/ip/iprule.c b/ip/iprule.c -index e64b4d7db2815..201d3bdc20427 100644 ---- a/ip/iprule.c -+++ b/ip/iprule.c -@@ -472,11 +472,13 @@ static int iprule_list_flush_or_save(int argc, char **argv, int action) - } else if (strcmp(*argv, "dev") == 0 || - strcmp(*argv, "iif") == 0) { - NEXT_ARG(); -- strncpy(filter.iif, *argv, IFNAMSIZ); -+ if (get_ifname(filter.iif, *argv)) -+ invarg("\"iif\"/\"dev\" not a valid ifname", *argv); - filter.iifmask = 1; - } else if (strcmp(*argv, "oif") == 0) { - NEXT_ARG(); -- strncpy(filter.oif, *argv, IFNAMSIZ); -+ if (get_ifname(filter.oif, *argv)) -+ invarg("\"oif\" not a valid ifname", *argv); - filter.oifmask = 1; - } else if (strcmp(*argv, "l3mdev") == 0) { - filter.l3mdev = 1; -@@ -695,10 +697,14 @@ static int iprule_modify(int cmd, int argc, char **argv) - } else if (strcmp(*argv, "dev") == 0 || - strcmp(*argv, "iif") == 0) { - NEXT_ARG(); -+ if (check_ifname(*argv)) -+ invarg("\"iif\"/\"dev\" not a valid ifname", *argv); - addattr_l(&req.n, sizeof(req), FRA_IFNAME, - *argv, strlen(*argv)+1); - } else if (strcmp(*argv, "oif") == 0) { - NEXT_ARG(); -+ if (check_ifname(*argv)) -+ invarg("\"oif\" not a valid ifname", *argv); - addattr_l(&req.n, sizeof(req), FRA_OIFNAME, - *argv, strlen(*argv)+1); - } else if (strcmp(*argv, "l3mdev") == 0) { -diff --git a/ip/iptunnel.c b/ip/iptunnel.c -index 0acfd0793d3cd..208a1f06ab12f 100644 ---- a/ip/iptunnel.c -+++ b/ip/iptunnel.c -@@ -178,7 +178,8 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) - - if (p->name[0]) - duparg2("name", *argv); -- strncpy(p->name, *argv, IFNAMSIZ - 1); -+ if (get_ifname(p->name, *argv)) -+ invarg("\"name\" not a valid ifname", *argv); - if (cmd == SIOCCHGTUNNEL && count == 0) { - struct ip_tunnel_parm old_p = {}; - -@@ -487,6 +488,8 @@ static int do_prl(int argc, char **argv) - count++; - } else if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); -+ if (check_ifname(*argv)) -+ invarg("\"dev\" not a valid ifname", *argv); - medium = *argv; - } else { - fprintf(stderr, -@@ -534,6 +537,8 @@ static int do_6rd(int argc, char **argv) - cmd = SIOCDEL6RD; - } else if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); -+ if (check_ifname(*argv)) -+ invarg("\"dev\" not a valid ifname", *argv); - medium = *argv; - } else { - fprintf(stderr, -diff --git a/ip/iptuntap.c b/ip/iptuntap.c -index 451f7f0eac6bb..b46e452f21278 100644 ---- a/ip/iptuntap.c -+++ b/ip/iptuntap.c -@@ -176,7 +176,8 @@ static int parse_args(int argc, char **argv, - ifr->ifr_flags |= IFF_MULTI_QUEUE; - } else if (matches(*argv, "dev") == 0) { - NEXT_ARG(); -- strncpy(ifr->ifr_name, *argv, IFNAMSIZ-1); -+ if (get_ifname(ifr->ifr_name, *argv)) -+ invarg("\"dev\" not a valid ifname", *argv); - } else { - if (matches(*argv, "name") == 0) { - NEXT_ARG(); -@@ -184,7 +185,8 @@ static int parse_args(int argc, char **argv, - usage(); - if (ifr->ifr_name[0]) - duparg2("name", *argv); -- strncpy(ifr->ifr_name, *argv, IFNAMSIZ); -+ if (get_ifname(ifr->ifr_name, *argv)) -+ invarg("\"name\" not a valid ifname", *argv); - } - count++; - argc--; argv++; -diff --git a/lib/utils.c b/lib/utils.c -index 228d97bfe5e9b..0c56f0b478f23 100644 ---- a/lib/utils.c -+++ b/lib/utils.c -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -697,6 +698,34 @@ void duparg2(const char *key, const char *arg) - exit(-1); - } - -+int check_ifname(const char *name) -+{ -+ /* These checks mimic kernel checks in dev_valid_name */ -+ if (*name == '\0') -+ return -1; -+ if (strlen(name) >= IFNAMSIZ) -+ return -1; -+ -+ while (*name) { -+ if (*name == '/' || isspace(*name)) -+ return -1; -+ ++name; -+ } -+ return 0; -+} -+ -+/* buf is assumed to be IFNAMSIZ */ -+int get_ifname(char *buf, const char *name) -+{ -+ int ret; -+ -+ ret = check_ifname(name); -+ if (ret == 0) -+ strncpy(buf, name, IFNAMSIZ); -+ -+ return ret; -+} -+ - int matches(const char *cmd, const char *pattern) - { - int len = strlen(cmd); -diff --git a/misc/arpd.c b/misc/arpd.c -index c9d86475e5995..67d86b67957b8 100644 ---- a/misc/arpd.c -+++ b/misc/arpd.c -@@ -662,7 +662,8 @@ int main(int argc, char **argv) - struct ifreq ifr = {}; - - for (i = 0; i < ifnum; i++) { -- strncpy(ifr.ifr_name, ifnames[i], IFNAMSIZ); -+ if (get_ifname(ifr.ifr_name, ifnames[i])) -+ invarg("not a valid ifname", ifnames[i]); - if (ioctl(udp_sock, SIOCGIFINDEX, &ifr)) { - perror("ioctl(SIOCGIFINDEX)"); - exit(-1); -diff --git a/tc/f_flower.c b/tc/f_flower.c -index 34249254603ff..f3f8d3427c761 100644 ---- a/tc/f_flower.c -+++ b/tc/f_flower.c -@@ -643,6 +643,8 @@ static int flower_parse_opt(struct filter_util *qu, char *handle, - flags |= TCA_CLS_FLAGS_SKIP_SW; - } else if (matches(*argv, "indev") == 0) { - NEXT_ARG(); -+ if (check_ifname(*argv)) -+ invarg("\"indev\" not a valid ifname", *argv); - addattrstrz(n, MAX_MSG, TCA_FLOWER_INDEV, *argv); - } else if (matches(*argv, "vlan_id") == 0) { - __u16 vid; --- -2.21.0 - diff --git a/SOURCES/0127-bpf-minor-cleanups-for-bpf_trace_pipe.patch b/SOURCES/0127-bpf-minor-cleanups-for-bpf_trace_pipe.patch deleted file mode 100644 index 7f05a35..0000000 --- a/SOURCES/0127-bpf-minor-cleanups-for-bpf_trace_pipe.patch +++ /dev/null @@ -1,73 +0,0 @@ -From edf0ae950c5b9d3c5eed29a40f5669cf657995e6 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Tue, 30 Apr 2019 15:43:03 +0200 -Subject: [PATCH] bpf: minor cleanups for bpf_trace_pipe - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1465646 -Upstream Status: iproute2.git commit 1b736dc469dca - -commit 1b736dc469dcabd4180848a1f1b3d1fef2b84dbc -Author: Daniel Borkmann -Date: Tue Sep 5 02:24:31 2017 +0200 - - bpf: minor cleanups for bpf_trace_pipe - - Just minor nits, e.g. no need to fflush() and instead of returning - right away, just break and close the fd. - - Signed-off-by: Daniel Borkmann ---- - lib/bpf.c | 19 +++++++++---------- - 1 file changed, 9 insertions(+), 10 deletions(-) - -diff --git a/lib/bpf.c b/lib/bpf.c -index e072cba214067..f0e6c6fb732ee 100644 ---- a/lib/bpf.c -+++ b/lib/bpf.c -@@ -461,9 +461,9 @@ int bpf_trace_pipe(void) - "/trace", - 0, - }; -+ int fd_in, fd_out = STDERR_FILENO; - char tpipe[PATH_MAX]; - const char *mnt; -- int fd; - - mnt = bpf_find_mntpt("tracefs", TRACEFS_MAGIC, tracefs_mnt, - sizeof(tracefs_mnt), tracefs_known_mnts); -@@ -474,8 +474,8 @@ int bpf_trace_pipe(void) - - snprintf(tpipe, sizeof(tpipe), "%s/trace_pipe", mnt); - -- fd = open(tpipe, O_RDONLY); -- if (fd < 0) -+ fd_in = open(tpipe, O_RDONLY); -+ if (fd_in < 0) - return -1; - - fprintf(stderr, "Running! Hang up with ^C!\n\n"); -@@ -483,15 +483,14 @@ int bpf_trace_pipe(void) - static char buff[4096]; - ssize_t ret; - -- ret = read(fd, buff, sizeof(buff) - 1); -- if (ret > 0) { -- if (write(STDERR_FILENO, buff, ret) != ret) -- return -1; -- fflush(stderr); -- } -+ ret = read(fd_in, buff, sizeof(buff)); -+ if (ret > 0 && write(fd_out, buff, ret) == ret) -+ continue; -+ break; - } - -- return 0; -+ close(fd_in); -+ return -1; - } - - static int bpf_gen_global(const char *bpf_sub_dir) --- -2.21.0 - diff --git a/SOURCES/0128-ip-tunnel-Use-tnl_parse_key-to-parse-tunnel-key.patch b/SOURCES/0128-ip-tunnel-Use-tnl_parse_key-to-parse-tunnel-key.patch deleted file mode 100644 index 5510d37..0000000 --- a/SOURCES/0128-ip-tunnel-Use-tnl_parse_key-to-parse-tunnel-key.patch +++ /dev/null @@ -1,339 +0,0 @@ -From 8f2338a51859158b8699e0736f84ab1e42a3da97 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Wed, 5 Jun 2019 13:05:04 +0200 -Subject: [PATCH] ip/tunnel: Use tnl_parse_key() to parse tunnel key - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1714660 -Upstream Status: iproute2.git commit 1f44b93744f11 -Conflicts: context change due to missing commit 2a80154fde40b - ("vti6: fix local/remote any addr handling") - -commit 1f44b93744f11f2a8249e3c13751ab7debebaa5f -Author: Serhey Popovych -Date: Mon Dec 18 19:48:03 2017 +0200 - - ip/tunnel: Use tnl_parse_key() to parse tunnel key - - It is added with - commit a7ed1520ee96 ("ip/tunnel: introduce tnl_parse_key()") - to avoid code duplication in ip6?tunnel.c. - - Reuse it for gre/gre6 and vti/vti6 tunnel rtnl - configuration interface with the same purpose - it is used in tunnel ioctl interface in ip6?tunnel.c. - - While there change type of key variables from - unsigned integer to __be32 to reflect nature of the - value they store and place error message in - tnl_parse_key() on a single line to make single - call to fprintf(). - - Signed-off-by: Serhey Popovych - Signed-off-by: Stephen Hemminger ---- - ip/link_gre.c | 45 +++++---------------------------------------- - ip/link_gre6.c | 45 +++++---------------------------------------- - ip/link_vti.c | 45 +++++---------------------------------------- - ip/link_vti6.c | 45 +++++---------------------------------------- - ip/tunnel.c | 5 +++-- - 5 files changed, 23 insertions(+), 162 deletions(-) - -diff --git a/ip/link_gre.c b/ip/link_gre.c -index ced993692e6f6..1376d2e3af7de 100644 ---- a/ip/link_gre.c -+++ b/ip/link_gre.c -@@ -77,8 +77,8 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv, - struct rtattr *greinfo[IFLA_GRE_MAX + 1]; - __u16 iflags = 0; - __u16 oflags = 0; -- unsigned int ikey = 0; -- unsigned int okey = 0; -+ __be32 ikey = 0; -+ __be32 okey = 0; - unsigned int saddr = 0; - unsigned int daddr = 0; - unsigned int link = 0; -@@ -167,53 +167,18 @@ get_failed: - - while (argc > 0) { - if (!matches(*argv, "key")) { -- unsigned int uval; -- - NEXT_ARG(); - iflags |= GRE_KEY; - oflags |= GRE_KEY; -- if (strchr(*argv, '.')) -- uval = get_addr32(*argv); -- else { -- if (get_unsigned(&uval, *argv, 0) < 0) { -- fprintf(stderr, -- "Invalid value for \"key\": \"%s\"; it should be an unsigned integer\n", *argv); -- exit(-1); -- } -- uval = htonl(uval); -- } -- -- ikey = okey = uval; -+ ikey = okey = tnl_parse_key("key", *argv); - } else if (!matches(*argv, "ikey")) { -- unsigned int uval; -- - NEXT_ARG(); - iflags |= GRE_KEY; -- if (strchr(*argv, '.')) -- uval = get_addr32(*argv); -- else { -- if (get_unsigned(&uval, *argv, 0) < 0) { -- fprintf(stderr, "invalid value for \"ikey\": \"%s\"; it should be an unsigned integer\n", *argv); -- exit(-1); -- } -- uval = htonl(uval); -- } -- ikey = uval; -+ ikey = tnl_parse_key("ikey", *argv); - } else if (!matches(*argv, "okey")) { -- unsigned int uval; -- - NEXT_ARG(); - oflags |= GRE_KEY; -- if (strchr(*argv, '.')) -- uval = get_addr32(*argv); -- else { -- if (get_unsigned(&uval, *argv, 0) < 0) { -- fprintf(stderr, "invalid value for \"okey\": \"%s\"; it should be an unsigned integer\n", *argv); -- exit(-1); -- } -- uval = htonl(uval); -- } -- okey = uval; -+ okey = tnl_parse_key("okey", *argv); - } else if (!matches(*argv, "seq")) { - iflags |= GRE_SEQ; - oflags |= GRE_SEQ; -diff --git a/ip/link_gre6.c b/ip/link_gre6.c -index a9d18ee954641..22e6e44aae29b 100644 ---- a/ip/link_gre6.c -+++ b/ip/link_gre6.c -@@ -89,8 +89,8 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv, - struct rtattr *greinfo[IFLA_GRE_MAX + 1]; - __u16 iflags = 0; - __u16 oflags = 0; -- unsigned int ikey = 0; -- unsigned int okey = 0; -+ __be32 ikey = 0; -+ __be32 okey = 0; - struct in6_addr raddr = IN6ADDR_ANY_INIT; - struct in6_addr laddr = IN6ADDR_ANY_INIT; - unsigned int link = 0; -@@ -181,53 +181,18 @@ get_failed: - - while (argc > 0) { - if (!matches(*argv, "key")) { -- unsigned int uval; -- - NEXT_ARG(); - iflags |= GRE_KEY; - oflags |= GRE_KEY; -- if (strchr(*argv, '.')) -- uval = get_addr32(*argv); -- else { -- if (get_unsigned(&uval, *argv, 0) < 0) { -- fprintf(stderr, -- "Invalid value for \"key\"\n"); -- exit(-1); -- } -- uval = htonl(uval); -- } -- -- ikey = okey = uval; -+ ikey = okey = tnl_parse_key("key", *argv); - } else if (!matches(*argv, "ikey")) { -- unsigned int uval; -- - NEXT_ARG(); - iflags |= GRE_KEY; -- if (strchr(*argv, '.')) -- uval = get_addr32(*argv); -- else { -- if (get_unsigned(&uval, *argv, 0) < 0) { -- fprintf(stderr, "invalid value of \"ikey\"\n"); -- exit(-1); -- } -- uval = htonl(uval); -- } -- ikey = uval; -+ ikey = tnl_parse_key("ikey", *argv); - } else if (!matches(*argv, "okey")) { -- unsigned int uval; -- - NEXT_ARG(); - oflags |= GRE_KEY; -- if (strchr(*argv, '.')) -- uval = get_addr32(*argv); -- else { -- if (get_unsigned(&uval, *argv, 0) < 0) { -- fprintf(stderr, "invalid value of \"okey\"\n"); -- exit(-1); -- } -- uval = htonl(uval); -- } -- okey = uval; -+ okey = tnl_parse_key("okey", *argv); - } else if (!matches(*argv, "seq")) { - iflags |= GRE_SEQ; - oflags |= GRE_SEQ; -diff --git a/ip/link_vti.c b/ip/link_vti.c -index d2aacbe78ded1..6e4234170bb50 100644 ---- a/ip/link_vti.c -+++ b/ip/link_vti.c -@@ -62,8 +62,8 @@ static int vti_parse_opt(struct link_util *lu, int argc, char **argv, - struct rtattr *tb[IFLA_MAX + 1]; - struct rtattr *linkinfo[IFLA_INFO_MAX+1]; - struct rtattr *vtiinfo[IFLA_VTI_MAX + 1]; -- unsigned int ikey = 0; -- unsigned int okey = 0; -+ __be32 ikey = 0; -+ __be32 okey = 0; - unsigned int saddr = 0; - unsigned int daddr = 0; - unsigned int link = 0; -@@ -116,49 +116,14 @@ get_failed: - - while (argc > 0) { - if (!matches(*argv, "key")) { -- unsigned int uval; -- - NEXT_ARG(); -- if (strchr(*argv, '.')) -- uval = get_addr32(*argv); -- else { -- if (get_unsigned(&uval, *argv, 0) < 0) { -- fprintf(stderr, -- "Invalid value for \"key\": \"%s\"; it should be an unsigned integer\n", *argv); -- exit(-1); -- } -- uval = htonl(uval); -- } -- -- ikey = okey = uval; -+ ikey = okey = tnl_parse_key("key", *argv); - } else if (!matches(*argv, "ikey")) { -- unsigned int uval; -- - NEXT_ARG(); -- if (strchr(*argv, '.')) -- uval = get_addr32(*argv); -- else { -- if (get_unsigned(&uval, *argv, 0) < 0) { -- fprintf(stderr, "invalid value for \"ikey\": \"%s\"; it should be an unsigned integer\n", *argv); -- exit(-1); -- } -- uval = htonl(uval); -- } -- ikey = uval; -+ ikey = tnl_parse_key("ikey", *argv); - } else if (!matches(*argv, "okey")) { -- unsigned int uval; -- - NEXT_ARG(); -- if (strchr(*argv, '.')) -- uval = get_addr32(*argv); -- else { -- if (get_unsigned(&uval, *argv, 0) < 0) { -- fprintf(stderr, "invalid value for \"okey\": \"%s\"; it should be an unsigned integer\n", *argv); -- exit(-1); -- } -- uval = htonl(uval); -- } -- okey = uval; -+ okey = tnl_parse_key("okey", *argv); - } else if (!matches(*argv, "remote")) { - NEXT_ARG(); - if (!strcmp(*argv, "any")) { -diff --git a/ip/link_vti6.c b/ip/link_vti6.c -index aedfbeaeea0e1..e246cedbcb7a7 100644 ---- a/ip/link_vti6.c -+++ b/ip/link_vti6.c -@@ -59,8 +59,8 @@ static int vti6_parse_opt(struct link_util *lu, int argc, char **argv, - struct rtattr *vtiinfo[IFLA_VTI_MAX + 1]; - struct in6_addr saddr; - struct in6_addr daddr; -- unsigned int ikey = 0; -- unsigned int okey = 0; -+ __be32 ikey = 0; -+ __be32 okey = 0; - unsigned int link = 0; - int len; - -@@ -111,49 +111,14 @@ get_failed: - - while (argc > 0) { - if (!matches(*argv, "key")) { -- unsigned int uval; -- - NEXT_ARG(); -- if (strchr(*argv, '.')) -- uval = get_addr32(*argv); -- else { -- if (get_unsigned(&uval, *argv, 0) < 0) { -- fprintf(stderr, -- "Invalid value for \"key\": \"%s\"; it should be an unsigned integer\n", *argv); -- exit(-1); -- } -- uval = htonl(uval); -- } -- -- ikey = okey = uval; -+ ikey = okey = tnl_parse_key("key", *argv); - } else if (!matches(*argv, "ikey")) { -- unsigned int uval; -- - NEXT_ARG(); -- if (strchr(*argv, '.')) -- uval = get_addr32(*argv); -- else { -- if (get_unsigned(&uval, *argv, 0) < 0) { -- fprintf(stderr, "invalid value for \"ikey\": \"%s\"; it should be an unsigned integer\n", *argv); -- exit(-1); -- } -- uval = htonl(uval); -- } -- ikey = uval; -+ ikey = tnl_parse_key("ikey", *argv); - } else if (!matches(*argv, "okey")) { -- unsigned int uval; -- - NEXT_ARG(); -- if (strchr(*argv, '.')) -- uval = get_addr32(*argv); -- else { -- if (get_unsigned(&uval, *argv, 0) < 0) { -- fprintf(stderr, "invalid value for \"okey\": \"%s\"; it should be an unsigned integer\n", *argv); -- exit(-1); -- } -- uval = htonl(uval); -- } -- okey = uval; -+ okey = tnl_parse_key("okey", *argv); - } else if (!matches(*argv, "remote")) { - NEXT_ARG(); - if (!strcmp(*argv, "any")) { -diff --git a/ip/tunnel.c b/ip/tunnel.c -index 7956d71aa7334..3967d5df3ca1c 100644 ---- a/ip/tunnel.c -+++ b/ip/tunnel.c -@@ -189,8 +189,9 @@ __be32 tnl_parse_key(const char *name, const char *key) - return get_addr32(key); - - if (get_unsigned(&uval, key, 0) < 0) { -- fprintf(stderr, "invalid value for \"%s\": \"%s\";", name, key); -- fprintf(stderr, " it should be an unsigned integer\n"); -+ fprintf(stderr, -+ "invalid value for \"%s\": \"%s\"; it should be an unsigned integer\n", -+ name, key); - exit(-1); - } - return htonl(uval); --- -2.21.0 - diff --git a/SOURCES/0129-man-ip-link-document-GRE-tunnels.patch b/SOURCES/0129-man-ip-link-document-GRE-tunnels.patch deleted file mode 100644 index c10f982..0000000 --- a/SOURCES/0129-man-ip-link-document-GRE-tunnels.patch +++ /dev/null @@ -1,218 +0,0 @@ -From 266b19dec4b79c4f63118dd6151c1b0a80f521f7 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Wed, 5 Jun 2019 13:08:00 +0200 -Subject: [PATCH] man: ip link: document GRE tunnels - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1714660 -Upstream Status: iproute2.git commit d21c028cf7414 -Conflicts: context change due to missing commit 1eccc5734148c - ("ip: add vxcan/veth to ip-link man page") - -commit d21c028cf74147360c530a4c53063bbe677dbe73 -Author: Sabrina Dubroca -Date: Fri Apr 20 10:31:59 2018 +0200 - - man: ip link: document GRE tunnels - - GRE tunnels are currently only documented together with IPIP and SIT - tunnels, but they actually have very different configuration - options. Let's separate them. - - Signed-off-by: Sabrina Dubroca - Signed-off-by: David Ahern ---- - man/man8/ip-link.8.in | 152 ++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 148 insertions(+), 4 deletions(-) - -diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in -index 48417dbce80aa..cfea1bdfdc030 100644 ---- a/man/man8/ip-link.8.in -+++ b/man/man8/ip-link.8.in -@@ -643,15 +643,88 @@ keyword. - .in -8 - - .TP --GRE, IPIP, SIT Type Support --For a link of types --.I GRE/IPIP/SIT -+IPIP, SIT Type Support -+For a link of type -+.IR IPIP or SIT -+the following additional arguments are supported: -+ -+.BI "ip link add " DEVICE -+.BR type " { " ipip " | " sit " }" -+.BI " remote " ADDR " local " ADDR -+[ -+.BR encap " { " fou " | " gue " | " none " }" -+] [ -+.BR encap-sport " { " \fIPORT " | " auto " }" -+] [ -+.BI "encap-dport " PORT -+] [ -+.RB [ no ] encap-csum -+] [ -+.RB [ no ] encap-remcsum -+] -+ -+.in +8 -+.sp -+.BI remote " ADDR " -+- specifies the remote address of the tunnel. -+ -+.sp -+.BI local " ADDR " -+- specifies the fixed local address for tunneled packets. -+It must be an address on another interface on this host. -+ -+.sp -+.BR encap " { " fou " | " gue " | " none " }" -+- specifies type of secondary UDP encapsulation. "fou" indicates -+Foo-Over-UDP, "gue" indicates Generic UDP Encapsulation. -+ -+.sp -+.BR encap-sport " { " \fIPORT " | " auto " }" -+- specifies the source port in UDP encapsulation. -+.IR PORT -+indicates the port by number, "auto" -+indicates that the port number should be chosen automatically -+(the kernel picks a flow based on the flow hash of the -+encapsulated packet). -+ -+.sp -+.RB [ no ] encap-csum -+- specifies if UDP checksums are enabled in the secondary -+encapsulation. -+ -+.sp -+.RB [ no ] encap-remcsum -+- specifies if Remote Checksum Offload is enabled. This is only -+applicable for Generic UDP Encapsulation. -+ -+.in -8 -+.TP -+GRE Type Support -+For a link of type -+.IR GRE " or " GRETAP - the following additional arguments are supported: - - .BI "ip link add " DEVICE --.BR type " { " gre " | " ipip " | " sit " }" -+.BR type " { " gre " | " gretap " }" - .BI " remote " ADDR " local " ADDR - [ -+.RB [ i | o ] seq -+] [ -+.RB [ i | o ] key -+.I KEY -+] [ -+.RB [ i | o ] csum -+] [ -+.BI ttl " TTL " -+] [ -+.BI tos " TOS " -+] [ -+.RB [ no ] pmtudisc -+] [ -+.RB [ no ] ignore-df -+] [ -+.BI dev " PHYS_DEV " -+] [ - .BR encap " { " fou " | " gue " | " none " }" - ] [ - .BR encap-sport " { " \fIPORT " | " auto " }" -@@ -661,6 +734,8 @@ the following additional arguments are supported: - .RB [ no ] encap-csum - ] [ - .RB [ no ] encap-remcsum -+] [ -+.BR external - ] - - .in +8 -@@ -673,6 +748,70 @@ the following additional arguments are supported: - - specifies the fixed local address for tunneled packets. - It must be an address on another interface on this host. - -+.sp -+.RB [ i | o ] seq -+- serialize packets. -+The -+.B oseq -+flag enables sequencing of outgoing packets. -+The -+.B iseq -+flag requires that all input packets are serialized. -+ -+.sp -+.RB [ i | o ] key -+.I KEY -+- use keyed GRE with key -+.IR KEY ". "KEY -+is either a number or an IPv4 address-like dotted quad. -+The -+.B key -+parameter specifies the same key to use in both directions. -+The -+.BR ikey " and " okey -+parameters specify different keys for input and output. -+ -+.sp -+.RB [ i | o ] csum -+- generate/require checksums for tunneled packets. -+The -+.B ocsum -+flag calculates checksums for outgoing packets. -+The -+.B icsum -+flag requires that all input packets have the correct -+checksum. The -+.B csum -+flag is equivalent to the combination -+.B "icsum ocsum" . -+ -+.sp -+.BI ttl " TTL" -+- specifies the TTL value to use in outgoing packets. -+ -+.sp -+.BI tos " TOS" -+- specifies the TOS value to use in outgoing packets. -+ -+.sp -+.RB [ no ] pmtudisc -+- enables/disables Path MTU Discovery on this tunnel. -+It is enabled by default. Note that a fixed ttl is incompatible -+with this option: tunneling with a fixed ttl always makes pmtu -+discovery. -+ -+.sp -+.RB [ no ] ignore-df -+- enables/disables IPv4 DF suppression on this tunnel. -+Normally datagrams that exceed the MTU will be fragmented; the presence -+of the DF flag inhibits this, resulting instead in an ICMP Unreachable -+(Fragmentation Required) message. Enabling this attribute casues the -+DF flag to be ignored. -+ -+.sp -+.BI dev " PHYS_DEV" -+- specifies the physical device to use for tunnel endpoint communication. -+ - .sp - .BR encap " { " fou " | " gue " | " none " }" - - specifies type of secondary UDP encapsulation. "fou" indicates -@@ -697,6 +836,11 @@ encapsulation. - - specifies if Remote Checksum Offload is enabled. This is only - applicable for Generic UDP Encapsulation. - -+.sp -+.BR external -+- make this tunnel externally controlled -+.RB "(e.g. " "ip route encap" ). -+ - .in -8 - - .TP --- -2.21.0 - diff --git a/SOURCES/0130-gre-gre6-allow-clearing-i-o-key-seq-csum-flags.patch b/SOURCES/0130-gre-gre6-allow-clearing-i-o-key-seq-csum-flags.patch deleted file mode 100644 index bdc406a..0000000 --- a/SOURCES/0130-gre-gre6-allow-clearing-i-o-key-seq-csum-flags.patch +++ /dev/null @@ -1,268 +0,0 @@ -From 24eec64aa52b65b606d8cc0b03619f3974f12484 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Wed, 5 Jun 2019 13:08:41 +0200 -Subject: [PATCH] gre/gre6: allow clearing {,i,o}{key,seq,csum} flags - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1714660 -Upstream Status: iproute2.git commit 7f520601f59ee -Conflicts: context change on ip/link_gre?.c due to missing commit - ae91205c4d2a7 ("gre/gre6: Unify gre_print_help()") - -commit 7f520601f59ee35da2fc48b3f1b39ed2b80c9efa -Author: Sabrina Dubroca -Date: Fri Apr 20 10:32:00 2018 +0200 - - gre/gre6: allow clearing {,i,o}{key,seq,csum} flags - - Currently, iproute allows setting those flags, but it's impossible to - clear them, since their current value is fetched from the kernel and - then we OR in the additional flags passed on the command line. - - Add no* variants to allow clearing them. - - Signed-off-by: Sabrina Dubroca - Signed-off-by: David Ahern ---- - ip/link_gre.c | 30 +++++++++++++++++++++++++++--- - ip/link_gre6.c | 30 +++++++++++++++++++++++++++--- - man/man8/ip-link.8.in | 27 ++++++++++++++++++--------- - 3 files changed, 72 insertions(+), 15 deletions(-) - -diff --git a/ip/link_gre.c b/ip/link_gre.c -index 1376d2e3af7de..41e2edbedb6eb 100644 ---- a/ip/link_gre.c -+++ b/ip/link_gre.c -@@ -28,9 +28,9 @@ static void print_usage(FILE *f) - fprintf(f, - "Usage: ... { gre | gretap } [ remote ADDR ]\n" - " [ local ADDR ]\n" -- " [ [i|o]seq ]\n" -- " [ [i|o]key KEY ]\n" -- " [ [i|o]csum ]\n" -+ " [ [no][i|o]seq ]\n" -+ " [ [i|o]key KEY | no[i|o]key ]\n" -+ " [ [no][i|o]csum ]\n" - " [ ttl TTL ]\n" - " [ tos TOS ]\n" - " [ [no]pmtudisc ]\n" -@@ -171,28 +171,52 @@ get_failed: - iflags |= GRE_KEY; - oflags |= GRE_KEY; - ikey = okey = tnl_parse_key("key", *argv); -+ } else if (!matches(*argv, "nokey")) { -+ iflags &= ~GRE_KEY; -+ oflags &= ~GRE_KEY; -+ ikey = okey = 0; - } else if (!matches(*argv, "ikey")) { - NEXT_ARG(); - iflags |= GRE_KEY; - ikey = tnl_parse_key("ikey", *argv); -+ } else if (!matches(*argv, "noikey")) { -+ iflags &= ~GRE_KEY; -+ ikey = 0; - } else if (!matches(*argv, "okey")) { - NEXT_ARG(); - oflags |= GRE_KEY; - okey = tnl_parse_key("okey", *argv); -+ } else if (!matches(*argv, "nookey")) { -+ oflags &= ~GRE_KEY; -+ okey = 0; - } else if (!matches(*argv, "seq")) { - iflags |= GRE_SEQ; - oflags |= GRE_SEQ; -+ } else if (!matches(*argv, "noseq")) { -+ iflags &= ~GRE_SEQ; -+ oflags &= ~GRE_SEQ; - } else if (!matches(*argv, "iseq")) { - iflags |= GRE_SEQ; -+ } else if (!matches(*argv, "noiseq")) { -+ iflags &= ~GRE_SEQ; - } else if (!matches(*argv, "oseq")) { - oflags |= GRE_SEQ; -+ } else if (!matches(*argv, "nooseq")) { -+ oflags &= ~GRE_SEQ; - } else if (!matches(*argv, "csum")) { - iflags |= GRE_CSUM; - oflags |= GRE_CSUM; -+ } else if (!matches(*argv, "nocsum")) { -+ iflags &= ~GRE_CSUM; -+ oflags &= ~GRE_CSUM; - } else if (!matches(*argv, "icsum")) { - iflags |= GRE_CSUM; -+ } else if (!matches(*argv, "noicsum")) { -+ iflags &= ~GRE_CSUM; - } else if (!matches(*argv, "ocsum")) { - oflags |= GRE_CSUM; -+ } else if (!matches(*argv, "noocsum")) { -+ oflags &= ~GRE_CSUM; - } else if (!matches(*argv, "nopmtudisc")) { - pmtudisc = 0; - } else if (!matches(*argv, "pmtudisc")) { -diff --git a/ip/link_gre6.c b/ip/link_gre6.c -index 22e6e44aae29b..127e51de4ab73 100644 ---- a/ip/link_gre6.c -+++ b/ip/link_gre6.c -@@ -35,9 +35,9 @@ static void print_usage(FILE *f) - fprintf(f, - "Usage: ... { ip6gre | ip6gretap } [ remote ADDR ]\n" - " [ local ADDR ]\n" -- " [ [i|o]seq ]\n" -- " [ [i|o]key KEY ]\n" -- " [ [i|o]csum ]\n" -+ " [ [no][i|o]seq ]\n" -+ " [ [i|o]key KEY | no[i|o]key ]\n" -+ " [ [no][i|o]csum ]\n" - " [ hoplimit TTL ]\n" - " [ encaplimit ELIM ]\n" - " [ tclass TCLASS ]\n" -@@ -185,28 +185,52 @@ get_failed: - iflags |= GRE_KEY; - oflags |= GRE_KEY; - ikey = okey = tnl_parse_key("key", *argv); -+ } else if (!matches(*argv, "nokey")) { -+ iflags &= ~GRE_KEY; -+ oflags &= ~GRE_KEY; -+ ikey = okey = 0; - } else if (!matches(*argv, "ikey")) { - NEXT_ARG(); - iflags |= GRE_KEY; - ikey = tnl_parse_key("ikey", *argv); -+ } else if (!matches(*argv, "noikey")) { -+ iflags &= ~GRE_KEY; -+ ikey = 0; - } else if (!matches(*argv, "okey")) { - NEXT_ARG(); - oflags |= GRE_KEY; - okey = tnl_parse_key("okey", *argv); -+ } else if (!matches(*argv, "nookey")) { -+ oflags &= ~GRE_KEY; -+ okey = 0; - } else if (!matches(*argv, "seq")) { - iflags |= GRE_SEQ; - oflags |= GRE_SEQ; -+ } else if (!matches(*argv, "noseq")) { -+ iflags &= ~GRE_SEQ; -+ oflags &= ~GRE_SEQ; - } else if (!matches(*argv, "iseq")) { - iflags |= GRE_SEQ; -+ } else if (!matches(*argv, "noiseq")) { -+ iflags &= ~GRE_SEQ; - } else if (!matches(*argv, "oseq")) { - oflags |= GRE_SEQ; -+ } else if (!matches(*argv, "nooseq")) { -+ oflags &= ~GRE_SEQ; - } else if (!matches(*argv, "csum")) { - iflags |= GRE_CSUM; - oflags |= GRE_CSUM; -+ } else if (!matches(*argv, "nocsum")) { -+ iflags &= ~GRE_CSUM; -+ oflags &= ~GRE_CSUM; - } else if (!matches(*argv, "icsum")) { - iflags |= GRE_CSUM; -+ } else if (!matches(*argv, "noicsum")) { -+ iflags &= ~GRE_CSUM; - } else if (!matches(*argv, "ocsum")) { - oflags |= GRE_CSUM; -+ } else if (!matches(*argv, "noocsum")) { -+ oflags &= ~GRE_CSUM; - } else if (!matches(*argv, "remote")) { - inet_prefix addr; - -diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in -index cfea1bdfdc030..8be5d5e1e9fd6 100644 ---- a/man/man8/ip-link.8.in -+++ b/man/man8/ip-link.8.in -@@ -708,12 +708,14 @@ the following additional arguments are supported: - .BR type " { " gre " | " gretap " }" - .BI " remote " ADDR " local " ADDR - [ --.RB [ i | o ] seq -+.RB [ no ] "" [ i | o ] seq - ] [ - .RB [ i | o ] key - .I KEY -+| -+.BR no [ i | o ] key - ] [ --.RB [ i | o ] csum -+.RB [ no ] "" [ i | o ] csum - ] [ - .BI ttl " TTL " - ] [ -@@ -749,7 +751,7 @@ the following additional arguments are supported: - It must be an address on another interface on this host. - - .sp --.RB [ i | o ] seq -+.RB [ no ] "" [ i | o ] seq - - serialize packets. - The - .B oseq -@@ -761,6 +763,8 @@ flag requires that all input packets are serialized. - .sp - .RB [ i | o ] key - .I KEY -+| -+.BR no [ i | o ] key - - use keyed GRE with key - .IR KEY ". "KEY - is either a number or an IPv4 address-like dotted quad. -@@ -772,7 +776,7 @@ The - parameters specify different keys for input and output. - - .sp --.RB [ i | o ] csum -+.RB [ no ] "" [ i | o ] csum - - generate/require checksums for tunneled packets. - The - .B ocsum -@@ -853,12 +857,14 @@ the following additional arguments are supported: - .BR type " { " ip6gre " | " ip6gretap " }" - .BI remote " ADDR " local " ADDR" - [ --.RB [ i | o ] seq -+.RB [ no ] "" [ i | o ] seq - ] [ - .RB [ i | o ] key - .I KEY -+| -+.BR no [ i | o ] key - ] [ --.RB [ i | o ] csum -+.RB [ no ] "" [ i | o ] csum - ] [ - .BI hoplimit " TTL " - ] [ -@@ -884,7 +890,7 @@ the following additional arguments are supported: - It must be an address on another interface on this host. - - .sp --.RB [ i | o ] seq -+.RB [ no ] "" [ i | o ] seq - - serialize packets. - The - .B oseq -@@ -894,7 +900,10 @@ The - flag requires that all input packets are serialized. - - .sp --.RB [ i | o ] key " \fIKEY" -+.RB [ i | o ] key -+.I KEY -+| -+.BR no [ i | o ] key - - use keyed GRE with key - .IR KEY ". "KEY - is either a number or an IPv4 address-like dotted quad. -@@ -906,7 +915,7 @@ The - parameters specify different keys for input and output. - - .sp --.RB [ i | o ] csum -+.RB [ no ] "" [ i | o ] csum - - generate/require checksums for tunneled packets. - The - .B ocsum --- -2.21.0 - diff --git a/SOURCES/0131-tc_filter-add-support-for-chain-index.patch b/SOURCES/0131-tc_filter-add-support-for-chain-index.patch deleted file mode 100644 index b5b69c3..0000000 --- a/SOURCES/0131-tc_filter-add-support-for-chain-index.patch +++ /dev/null @@ -1,250 +0,0 @@ -From 55c511b5caab0bfb9997bca9031947a45fe7854b Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Wed, 5 Jun 2019 13:09:39 +0200 -Subject: [PATCH] tc_filter: add support for chain index - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1714660 -Upstream Status: iproute2.git commit 732f03461bc48 - -commit 732f03461bc48cf94946ee3cc92ab5832862b989 -Author: Jiri Pirko -Date: Tue May 16 19:29:35 2017 +0200 - - tc_filter: add support for chain index - - Allow user to put filter to a specific chain identified by index. - - Signed-off-by: Jiri Pirko ---- - tc/tc_filter.c | 87 +++++++++++++++++++++++++++++++++++++++++--------- - 1 file changed, 72 insertions(+), 15 deletions(-) - -diff --git a/tc/tc_filter.c b/tc/tc_filter.c -index a6bb73d12eaba..8dbebf1ffa32a 100644 ---- a/tc/tc_filter.c -+++ b/tc/tc_filter.c -@@ -31,7 +31,7 @@ static void usage(void) - fprintf(stderr, - "Usage: tc filter [ add | del | change | replace | show ] dev STRING\n" - "Usage: tc filter get dev STRING parent CLASSID protocol PROTO handle FILTERID pref PRIO FILTER_TYPE\n" -- " [ pref PRIO ] protocol PROTO\n" -+ " [ pref PRIO ] protocol PROTO [ chain CHAIN_INDEX ]\n" - " [ estimator INTERVAL TIME_CONSTANT ]\n" - " [ root | ingress | egress | parent CLASSID ]\n" - " [ handle FILTERID ] [ [ FILTER_TYPE ] [ help | OPTIONS ] ]\n" -@@ -59,6 +59,8 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv) - __u32 prio = 0; - __u32 protocol = 0; - int protocol_set = 0; -+ __u32 chain_index; -+ int chain_index_set = 0; - char *fhandle = NULL; - char d[16] = {}; - char k[16] = {}; -@@ -127,6 +129,13 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv) - invarg("invalid protocol", *argv); - protocol = id; - protocol_set = 1; -+ } else if (matches(*argv, "chain") == 0) { -+ NEXT_ARG(); -+ if (chain_index_set) -+ duparg("chain", *argv); -+ if (get_u32(&chain_index, *argv, 0)) -+ invarg("invalid chain index value", *argv); -+ chain_index_set = 1; - } else if (matches(*argv, "estimator") == 0) { - if (parse_estimator(&argc, &argv, &est) < 0) - return -1; -@@ -146,6 +155,9 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv) - - req.t.tcm_info = TC_H_MAKE(prio<<16, protocol); - -+ if (chain_index_set) -+ addattr32(&req.n, sizeof(req), TCA_CHAIN, chain_index); -+ - if (k[0]) - addattr_l(&req.n, sizeof(req), TCA_KIND, k, strlen(k)+1); - -@@ -167,6 +179,7 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv) - return -1; - } - } -+ - if (est.ewma_log) - addattr_l(&req.n, sizeof(req), TCA_RATE, &est, sizeof(est)); - -@@ -193,6 +206,8 @@ static __u32 filter_parent; - static int filter_ifindex; - static __u32 filter_prio; - static __u32 filter_protocol; -+static __u32 filter_chain_index; -+static int filter_chain_index_set; - __u16 f_proto; - - int print_filter(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) -@@ -270,6 +285,15 @@ int print_filter(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) - } - } - fprintf(fp, "%s ", rta_getattr_str(tb[TCA_KIND])); -+ -+ if (tb[TCA_CHAIN]) { -+ __u32 chain_index = rta_getattr_u32(tb[TCA_CHAIN]); -+ -+ if (!filter_chain_index_set || -+ filter_chain_index != chain_index) -+ fprintf(fp, "chain %u ", chain_index); -+ } -+ - q = get_filter_kind(RTA_DATA(tb[TCA_KIND])); - if (tb[TCA_OPTIONS]) { - if (q) -@@ -312,6 +336,8 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv) - __u32 prio = 0; - __u32 protocol = 0; - int protocol_set = 0; -+ __u32 chain_index; -+ int chain_index_set = 0; - __u32 parent_handle = 0; - char *fhandle = NULL; - char d[16] = {}; -@@ -376,6 +402,13 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv) - invarg("invalid protocol", *argv); - protocol = id; - protocol_set = 1; -+ } else if (matches(*argv, "chain") == 0) { -+ NEXT_ARG(); -+ if (chain_index_set) -+ duparg("chain", *argv); -+ if (get_u32(&chain_index, *argv, 0)) -+ invarg("invalid chain index value", *argv); -+ chain_index_set = 1; - } else if (matches(*argv, "help") == 0) { - usage(); - return 0; -@@ -405,6 +438,9 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv) - - req.t.tcm_info = TC_H_MAKE(prio<<16, protocol); - -+ if (chain_index_set) -+ addattr32(&req.n, sizeof(req), TCA_CHAIN, chain_index); -+ - if (req.t.tcm_parent == TC_H_UNSPEC) { - fprintf(stderr, "Must specify filter parent\n"); - return -1; -@@ -462,10 +498,20 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv) - - static int tc_filter_list(int argc, char **argv) - { -- struct tcmsg t = { .tcm_family = AF_UNSPEC }; -+ struct { -+ struct nlmsghdr n; -+ struct tcmsg t; -+ char buf[MAX_MSG]; -+ } req = { -+ .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg)), -+ .n.nlmsg_type = RTM_GETTFILTER, -+ .t.tcm_parent = TC_H_UNSPEC, -+ .t.tcm_family = AF_UNSPEC, -+ }; - char d[16] = {}; - __u32 prio = 0; - __u32 protocol = 0; -+ __u32 chain_index; - char *fhandle = NULL; - - while (argc > 0) { -@@ -475,39 +521,39 @@ static int tc_filter_list(int argc, char **argv) - duparg("dev", *argv); - strncpy(d, *argv, sizeof(d)-1); - } else if (strcmp(*argv, "root") == 0) { -- if (t.tcm_parent) { -+ if (req.t.tcm_parent) { - fprintf(stderr, - "Error: \"root\" is duplicate parent ID\n"); - return -1; - } -- filter_parent = t.tcm_parent = TC_H_ROOT; -+ filter_parent = req.t.tcm_parent = TC_H_ROOT; - } else if (strcmp(*argv, "ingress") == 0) { -- if (t.tcm_parent) { -+ if (req.t.tcm_parent) { - fprintf(stderr, - "Error: \"ingress\" is duplicate parent ID\n"); - return -1; - } - filter_parent = TC_H_MAKE(TC_H_CLSACT, - TC_H_MIN_INGRESS); -- t.tcm_parent = filter_parent; -+ req.t.tcm_parent = filter_parent; - } else if (strcmp(*argv, "egress") == 0) { -- if (t.tcm_parent) { -+ if (req.t.tcm_parent) { - fprintf(stderr, - "Error: \"egress\" is duplicate parent ID\n"); - return -1; - } - filter_parent = TC_H_MAKE(TC_H_CLSACT, - TC_H_MIN_EGRESS); -- t.tcm_parent = filter_parent; -+ req.t.tcm_parent = filter_parent; - } else if (strcmp(*argv, "parent") == 0) { - __u32 handle; - - NEXT_ARG(); -- if (t.tcm_parent) -+ if (req.t.tcm_parent) - duparg("parent", *argv); - if (get_tc_classid(&handle, *argv)) - invarg("invalid parent ID", *argv); -- filter_parent = t.tcm_parent = handle; -+ filter_parent = req.t.tcm_parent = handle; - } else if (strcmp(*argv, "handle") == 0) { - NEXT_ARG(); - if (fhandle) -@@ -531,6 +577,14 @@ static int tc_filter_list(int argc, char **argv) - invarg("invalid protocol", *argv); - protocol = res; - filter_protocol = protocol; -+ } else if (matches(*argv, "chain") == 0) { -+ NEXT_ARG(); -+ if (filter_chain_index_set) -+ duparg("chain", *argv); -+ if (get_u32(&chain_index, *argv, 0)) -+ invarg("invalid chain index value", *argv); -+ filter_chain_index_set = 1; -+ filter_chain_index = chain_index; - } else if (matches(*argv, "help") == 0) { - usage(); - } else { -@@ -543,20 +597,23 @@ static int tc_filter_list(int argc, char **argv) - argc--; argv++; - } - -- t.tcm_info = TC_H_MAKE(prio<<16, protocol); -+ req.t.tcm_info = TC_H_MAKE(prio<<16, protocol); - - ll_init_map(&rth); - - if (d[0]) { -- t.tcm_ifindex = ll_name_to_index(d); -- if (t.tcm_ifindex == 0) { -+ req.t.tcm_ifindex = ll_name_to_index(d); -+ if (req.t.tcm_ifindex == 0) { - fprintf(stderr, "Cannot find device \"%s\"\n", d); - return 1; - } -- filter_ifindex = t.tcm_ifindex; -+ filter_ifindex = req.t.tcm_ifindex; - } - -- if (rtnl_dump_request(&rth, RTM_GETTFILTER, &t, sizeof(t)) < 0) { -+ if (filter_chain_index_set) -+ addattr32(&req.n, sizeof(req), TCA_CHAIN, chain_index); -+ -+ if (rtnl_dump_request_n(&rth, &req.n) < 0) { - perror("Cannot send dump request"); - return 1; - } --- -2.21.0 - diff --git a/SOURCES/0132-tc-actions-add-helpers-to-parse-and-print-control-ac.patch b/SOURCES/0132-tc-actions-add-helpers-to-parse-and-print-control-ac.patch deleted file mode 100644 index c8de5de..0000000 --- a/SOURCES/0132-tc-actions-add-helpers-to-parse-and-print-control-ac.patch +++ /dev/null @@ -1,772 +0,0 @@ -From 23f1822fa8129326de4709d643f41cf26b6bae88 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Wed, 5 Jun 2019 13:09:39 +0200 -Subject: [PATCH] tc: actions: add helpers to parse and print control actions - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1714660 -Upstream Status: iproute2.git commit e67aba5595811 -Conflicts: context change due to out-of-order cherry-pick of - commit 73aa988868e7e ("tc/m_gact: Drop dead code") - -commit e67aba559581143f9bc34f0706b0c3feeeab08fa -Author: Jiri Pirko -Date: Tue May 16 19:29:36 2017 +0200 - - tc: actions: add helpers to parse and print control actions - - Each tc action is terminated by a control action. Each action parses and - prints then intividually. Introduce set of helpers and allow to share - this code. - - Signed-off-by: Jiri Pirko ---- - tc/m_bpf.c | 8 +-- - tc/m_connmark.c | 4 +- - tc/m_csum.c | 9 ++- - tc/m_gact.c | 45 ++++----------- - tc/m_ife.c | 10 ++-- - tc/m_mirred.c | 10 ++-- - tc/m_nat.c | 11 ++-- - tc/m_pedit.c | 8 +-- - tc/m_police.c | 50 +++++------------ - tc/m_sample.c | 4 +- - tc/m_simple.c | 3 - - tc/m_skbedit.c | 7 +-- - tc/m_skbmod.c | 30 +--------- - tc/m_tunnel_key.c | 8 +-- - tc/m_vlan.c | 9 ++- - tc/tc_util.c | 137 +++++++++++++++++++++++++++++++++++++++++++++- - tc/tc_util.h | 11 +++- - 17 files changed, 209 insertions(+), 155 deletions(-) - -diff --git a/tc/m_bpf.c b/tc/m_bpf.c -index 1ddc334f2f21b..57283030a35f5 100644 ---- a/tc/m_bpf.c -+++ b/tc/m_bpf.c -@@ -75,7 +75,7 @@ static int bpf_parse_opt(struct action_util *a, int *ptr_argc, char ***ptr_argv, - int tca_id, struct nlmsghdr *n) - { - const char *bpf_obj = NULL, *bpf_uds_name = NULL; -- struct tc_act_bpf parm = { .action = TC_ACT_PIPE }; -+ struct tc_act_bpf parm = {}; - struct bpf_cfg_in cfg = {}; - bool seen_run = false; - struct rtattr *tail; -@@ -123,8 +123,8 @@ opt_bpf: - NEXT_ARG_FWD(); - } - -- if (argc && !action_a2n(*argv, &parm.action, false)) -- NEXT_ARG_FWD(); -+ parse_action_control_dflt(&argc, &argv, &parm.action, -+ false, TC_ACT_PIPE); - - if (argc) { - if (matches(*argv, "index") == 0) { -@@ -186,7 +186,7 @@ static int bpf_print_opt(struct action_util *au, FILE *f, struct rtattr *arg) - b, sizeof(b))); - } - -- fprintf(f, "default-action %s\n", action_n2a(parm->action)); -+ print_action_control(f, "default-action ", parm->action, "\n"); - fprintf(f, "\tindex %u ref %d bind %d", parm->index, parm->refcnt, - parm->bindcnt); - -diff --git a/tc/m_connmark.c b/tc/m_connmark.c -index 295f90d52eefd..3c2274bc0d2af 100644 ---- a/tc/m_connmark.c -+++ b/tc/m_connmark.c -@@ -80,9 +80,7 @@ parse_connmark(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, - } - } - -- sel.action = TC_ACT_PIPE; -- if (argc && !action_a2n(*argv, &sel.action, false)) -- NEXT_ARG_FWD(); -+ parse_action_control_dflt(&argc, &argv, &sel.action, false, TC_ACT_PIPE); - - if (argc) { - if (matches(*argv, "index") == 0) { -diff --git a/tc/m_csum.c b/tc/m_csum.c -index 0ee8cad3fbe4c..7b156734f64c5 100644 ---- a/tc/m_csum.c -+++ b/tc/m_csum.c -@@ -123,8 +123,7 @@ parse_csum(struct action_util *a, int *argc_p, - return -1; - } - -- if (argc && !action_a2n(*argv, &sel.action, false)) -- NEXT_ARG_FWD(); -+ parse_action_control_dflt(&argc, &argv, &sel.action, false, TC_ACT_OK); - - if (argc) { - if (matches(*argv, "index") == 0) { -@@ -200,10 +199,10 @@ print_csum(struct action_util *au, FILE *f, struct rtattr *arg) - uflag_1 = "?empty"; - } - -- fprintf(f, "csum (%s%s%s%s%s%s%s) action %s\n", -+ fprintf(f, "csum (%s%s%s%s%s%s%s) ", - uflag_1, uflag_2, uflag_3, -- uflag_4, uflag_5, uflag_6, uflag_7, -- action_n2a(sel->action)); -+ uflag_4, uflag_5, uflag_6, uflag_7); -+ print_action_control(f, "action ", sel->action, "\n"); - fprintf(f, "\tindex %u ref %d bind %d", sel->index, sel->refcnt, - sel->bindcnt); - -diff --git a/tc/m_gact.c b/tc/m_gact.c -index 0cb5222fd3817..bc3860bbe4441 100644 ---- a/tc/m_gact.c -+++ b/tc/m_gact.c -@@ -68,26 +68,13 @@ usage(void) - exit(-1); - } - --static int --get_act(char ***argv_p) --{ -- int n; -- -- if (action_a2n(**argv_p, &n, false)) { -- fprintf(stderr, "bad action type %s\n", **argv_p); -- return -10; -- } -- return n; --} -- - static int - parse_gact(struct action_util *a, int *argc_p, char ***argv_p, - int tca_id, struct nlmsghdr *n) - { - int argc = *argc_p; - char **argv = *argv_p; -- int action = TC_POLICE_RECLASSIFY; -- struct tc_gact p = { .action = TC_POLICE_RECLASSIFY }; -+ struct tc_gact p = { 0 }; - #ifdef CONFIG_GACT_PROB - int rd = 0; - struct tc_gact_p pp; -@@ -101,16 +88,8 @@ parse_gact(struct action_util *a, int *argc_p, char ***argv_p, - if (matches(*argv, "gact") == 0) { - argc--; - argv++; -- } else { -- action = get_act(&argv); -- if (action != -10) { -- p.action = action; -- argc--; -- argv++; -- } else { -- explain(); -- return action; -- } -+ } else if (parse_action_control(&argc, &argv, &p.action, false) == -1) { -+ usage(); - } - - #ifdef CONFIG_GACT_PROB -@@ -129,13 +108,9 @@ parse_gact(struct action_util *a, int *argc_p, char ***argv_p, - return -1; - } - -- action = get_act(&argv); -- if (action != -10) { /* FIXME */ -- pp.paction = action; -- } else { -- explain(); -- return -1; -- } -+ if (parse_action_control(&argc, &argv, -+ &pp.paction, false) == -1) -+ usage(); - argc--; - argv++; - if (get_u16(&pp.pval, *argv, 10)) { -@@ -204,7 +179,8 @@ print_gact(struct action_util *au, FILE * f, struct rtattr *arg) - } - p = RTA_DATA(tb[TCA_GACT_PARMS]); - -- fprintf(f, "gact action %s", action_n2a(p->action)); -+ fprintf(f, "gact "); -+ print_action_control(f, "action ", p->action, ""); - #ifdef CONFIG_GACT_PROB - if (tb[TCA_GACT_PROB] != NULL) { - pp = RTA_DATA(tb[TCA_GACT_PROB]); -@@ -213,8 +189,9 @@ print_gact(struct action_util *au, FILE * f, struct rtattr *arg) - memset(&pp_dummy, 0, sizeof(pp_dummy)); - pp = &pp_dummy; - } -- fprintf(f, "\n\t random type %s %s val %d", -- prob_n2a(pp->ptype), action_n2a(pp->paction), pp->pval); -+ fprintf(f, "\n\t random type %s", prob_n2a(pp->ptype)); -+ print_action_control(f, " ", pp->paction, " "); -+ fprintf(f, "val %d", pp->pval); - #endif - fprintf(f, "\n\t index %u ref %d bind %d", p->index, p->refcnt, - p->bindcnt); -diff --git a/tc/m_ife.c b/tc/m_ife.c -index f6131b1332324..e3521e62c178c 100644 ---- a/tc/m_ife.c -+++ b/tc/m_ife.c -@@ -57,7 +57,7 @@ static int parse_ife(struct action_util *a, int *argc_p, char ***argv_p, - int argc = *argc_p; - char **argv = *argv_p; - int ok = 0; -- struct tc_ife p = { .action = TC_ACT_PIPE }; /* good default */ -+ struct tc_ife p = { 0 }; - struct rtattr *tail; - struct rtattr *tail2; - char dbuf[ETH_ALEN]; -@@ -156,8 +156,7 @@ static int parse_ife(struct action_util *a, int *argc_p, char ***argv_p, - argv++; - } - -- if (argc && !action_a2n(*argv, &p.action, false)) -- NEXT_ARG_FWD(); -+ parse_action_control_dflt(&argc, &argv, &p.action, false, TC_ACT_PIPE); - - if (argc) { - if (matches(*argv, "index") == 0) { -@@ -245,9 +244,8 @@ static int print_ife(struct action_util *au, FILE *f, struct rtattr *arg) - } - p = RTA_DATA(tb[TCA_IFE_PARMS]); - -- fprintf(f, "ife %s action %s ", -- (p->flags & IFE_ENCODE) ? "encode" : "decode", -- action_n2a(p->action)); -+ fprintf(f, "ife %s ", p->flags & IFE_ENCODE ? "encode" : "decode"); -+ print_action_control(f, "action ", p->action, " "); - - if (tb[TCA_IFE_TYPE]) { - ife_type = rta_getattr_u16(tb[TCA_IFE_TYPE]); -diff --git a/tc/m_mirred.c b/tc/m_mirred.c -index e9438904fdf50..2384bda1ff045 100644 ---- a/tc/m_mirred.c -+++ b/tc/m_mirred.c -@@ -170,10 +170,8 @@ parse_direction(struct action_util *a, int *argc_p, char ***argv_p, - } - - -- if (argc && -- (p.eaction == TCA_EGRESS_MIRROR || p.eaction == TCA_INGRESS_MIRROR) -- && !action_a2n(*argv, &p.action, false)) -- NEXT_ARG(); -+ if (p.eaction == TCA_EGRESS_MIRROR || p.eaction == TCA_INGRESS_MIRROR) -+ parse_action_control(&argc, &argv, &p.action, false); - - if (argc) { - if (iok && matches(*argv, "index") == 0) { -@@ -272,8 +270,8 @@ print_mirred(struct action_util *au, FILE * f, struct rtattr *arg) - return -1; - } - -- fprintf(f, "mirred (%s to device %s) %s", -- mirred_n2a(p->eaction), dev, action_n2a(p->action)); -+ fprintf(f, "mirred (%s to device %s)", mirred_n2a(p->eaction), dev); -+ print_action_control(f, " ", p->action, ""); - - fprintf(f, "\n "); - fprintf(f, "\tindex %u ref %d bind %d", p->index, p->refcnt, -diff --git a/tc/m_nat.c b/tc/m_nat.c -index 525f185e2c082..31b68fb6bd784 100644 ---- a/tc/m_nat.c -+++ b/tc/m_nat.c -@@ -115,8 +115,7 @@ parse_nat(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, struct - return -1; - } - -- if (argc && !action_a2n(*argv, &sel.action, false)) -- NEXT_ARG_FWD(); -+ parse_action_control_dflt(&argc, &argv, &sel.action, false, TC_ACT_OK); - - if (argc) { - if (matches(*argv, "index") == 0) { -@@ -164,12 +163,12 @@ print_nat(struct action_util *au, FILE * f, struct rtattr *arg) - len = ffs(sel->mask); - len = len ? 33 - len : 0; - -- fprintf(f, " nat %s %s/%d %s %s", sel->flags & TCA_NAT_FLAG_EGRESS ? -- "egress" : "ingress", -+ fprintf(f, " nat %s %s/%d %s", sel->flags & TCA_NAT_FLAG_EGRESS ? -+ "egress" : "ingress", - format_host_r(AF_INET, 4, &sel->old_addr, buf1, sizeof(buf1)), - len, -- format_host_r(AF_INET, 4, &sel->new_addr, buf2, sizeof(buf2)), -- action_n2a(sel->action)); -+ format_host_r(AF_INET, 4, &sel->new_addr, buf2, sizeof(buf2))); -+ print_action_control(f, " ", sel->action, ""); - - if (show_stats) { - if (tb[TCA_NAT_TM]) { -diff --git a/tc/m_pedit.c b/tc/m_pedit.c -index dfa6b2c4835e9..b7d26b4540beb 100644 ---- a/tc/m_pedit.c -+++ b/tc/m_pedit.c -@@ -670,8 +670,7 @@ int parse_pedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, - return -1; - } - -- if (argc && !action_a2n(*argv, &sel.sel.action, false)) -- NEXT_ARG(); -+ parse_action_control_dflt(&argc, &argv, &sel.sel.action, false, TC_ACT_OK); - - if (argc) { - if (matches(*argv, "index") == 0) { -@@ -776,8 +775,9 @@ int print_pedit(struct action_util *au, FILE *f, struct rtattr *arg) - } - } - -- fprintf(f, " pedit action %s keys %d\n ", -- action_n2a(sel->action), sel->nkeys); -+ fprintf(f, " pedit "); -+ print_action_control(f, "action ", sel->action, " "); -+ fprintf(f,"keys %d\n ", sel->nkeys); - fprintf(f, "\t index %u ref %d bind %d", sel->index, sel->refcnt, - sel->bindcnt); - -diff --git a/tc/m_police.c b/tc/m_police.c -index 226e20e4e8005..2b73969de5daf 100644 ---- a/tc/m_police.c -+++ b/tc/m_police.c -@@ -50,27 +50,6 @@ static void explain1(char *arg) - fprintf(stderr, "Illegal \"%s\"\n", arg); - } - --static int get_police_result(int *action, int *result, char *arg) --{ -- char *p = strchr(arg, '/'); -- -- if (p) -- *p = 0; -- -- if (action_a2n(arg, action, true)) { -- if (p) -- *p = '/'; -- return -1; -- } -- -- if (p) { -- *p = '/'; -- if (action_a2n(p+1, result, true)) -- return -1; -- } -- return 0; --} -- - int act_parse_police(struct action_util *a, int *argc_p, char ***argv_p, - int tca_id, struct nlmsghdr *n) - { -@@ -166,23 +145,19 @@ int act_parse_police(struct action_util *a, int *argc_p, char ***argv_p, - explain1("peakrate"); - return -1; - } -- } else if (matches(*argv, "reclassify") == 0) { -- p.action = TC_POLICE_RECLASSIFY; -- } else if (matches(*argv, "drop") == 0 || -- matches(*argv, "shot") == 0) { -- p.action = TC_POLICE_SHOT; -- } else if (matches(*argv, "continue") == 0) { -- p.action = TC_POLICE_UNSPEC; -- } else if (matches(*argv, "pass") == 0) { -- p.action = TC_POLICE_OK; -- } else if (matches(*argv, "pipe") == 0) { -- p.action = TC_POLICE_PIPE; -+ } else if (matches(*argv, "reclassify") == 0 || -+ matches(*argv, "drop") == 0 || -+ matches(*argv, "shot") == 0 || -+ matches(*argv, "continue") == 0 || -+ matches(*argv, "pass") == 0 || -+ matches(*argv, "pipe") == 0) { -+ if (parse_action_control(&argc, &argv, &p.action, false)) -+ return -1; - } else if (strcmp(*argv, "conform-exceed") == 0) { - NEXT_ARG(); -- if (get_police_result(&p.action, &presult, *argv)) { -- fprintf(stderr, "Illegal \"action\"\n"); -+ if (parse_action_control_slash(&argc, &argv, &p.action, -+ &presult, true)) - return -1; -- } - } else if (matches(*argv, "overhead") == 0) { - NEXT_ARG(); - if (get_u16(&overhead, *argv, 10)) { -@@ -318,12 +293,13 @@ int print_police(struct action_util *a, FILE *f, struct rtattr *arg) - fprintf(f, "avrate %s ", - sprint_rate(rta_getattr_u32(tb[TCA_POLICE_AVRATE]), - b1)); -- fprintf(f, "action %s", action_n2a(p->action)); -+ -+ print_action_control(f, "action ", p->action, ""); - - if (tb[TCA_POLICE_RESULT]) { - __u32 action = rta_getattr_u32(tb[TCA_POLICE_RESULT]); - -- fprintf(f, "/%s ", action_n2a(action)); -+ print_action_control(f, "/", action, " "); - } else - fprintf(f, " "); - -diff --git a/tc/m_sample.c b/tc/m_sample.c -index 9291109071a89..ff5ee6bd1ef63 100644 ---- a/tc/m_sample.c -+++ b/tc/m_sample.c -@@ -98,9 +98,7 @@ static int parse_sample(struct action_util *a, int *argc_p, char ***argv_p, - NEXT_ARG_FWD(); - } - -- p.action = TC_ACT_PIPE; -- if (argc && !action_a2n(*argv, &p.action, false)) -- NEXT_ARG_FWD(); -+ parse_action_control_dflt(&argc, &argv, &p.action, false, TC_ACT_PIPE); - - if (argc) { - if (matches(*argv, "index") == 0) { -diff --git a/tc/m_simple.c b/tc/m_simple.c -index 65e48addf161b..f8937bcabb7ae 100644 ---- a/tc/m_simple.c -+++ b/tc/m_simple.c -@@ -120,9 +120,6 @@ parse_simple(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, - } - } - -- if (argc && !action_a2n(*argv, &sel.action, false)) -- NEXT_ARG_FWD(); -- - if (argc) { - if (matches(*argv, "index") == 0) { - NEXT_ARG(); -diff --git a/tc/m_skbedit.c b/tc/m_skbedit.c -index 638715f679d37..aa374fcb33ed9 100644 ---- a/tc/m_skbedit.c -+++ b/tc/m_skbedit.c -@@ -120,9 +120,8 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, - argv++; - } - -- sel.action = TC_ACT_PIPE; -- if (argc && !action_a2n(*argv, &sel.action, false)) -- NEXT_ARG(); -+ parse_action_control_dflt(&argc, &argv, &sel.action, -+ false, TC_ACT_PIPE); - - if (argc) { - if (matches(*argv, "index") == 0) { -@@ -214,7 +213,7 @@ static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg) - fprintf(f, " ptype %d", *ptype); - } - -- fprintf(f, " %s", action_n2a(p->action)); -+ print_action_control(f, " ", p->action, ""); - - fprintf(f, "\n\t index %u ref %d bind %d", - p->index, p->refcnt, p->bindcnt); -diff --git a/tc/m_skbmod.c b/tc/m_skbmod.c -index acb7771d2901b..1ccd474309348 100644 ---- a/tc/m_skbmod.c -+++ b/tc/m_skbmod.c -@@ -61,7 +61,6 @@ static int parse_skbmod(struct action_util *a, int *argc_p, char ***argv_p, - char *saddr = NULL; - - memset(&p, 0, sizeof(p)); -- p.action = TC_ACT_PIPE; /* good default */ - - if (argc <= 0) - return -1; -@@ -123,31 +122,7 @@ static int parse_skbmod(struct action_util *a, int *argc_p, char ***argv_p, - argv++; - } - -- if (argc) { -- if (matches(*argv, "reclassify") == 0) { -- p.action = TC_ACT_RECLASSIFY; -- argc--; -- argv++; -- } else if (matches(*argv, "pipe") == 0) { -- p.action = TC_ACT_PIPE; -- argc--; -- argv++; -- } else if (matches(*argv, "drop") == 0 || -- matches(*argv, "shot") == 0) { -- p.action = TC_ACT_SHOT; -- argc--; -- argv++; -- } else if (matches(*argv, "continue") == 0) { -- p.action = TC_ACT_UNSPEC; -- argc--; -- argv++; -- } else if (matches(*argv, "pass") == 0 || -- matches(*argv, "ok") == 0) { -- p.action = TC_ACT_OK; -- argc--; -- argv++; -- } -- } -+ parse_action_control_dflt(&argc, &argv, &p.action, false, TC_ACT_PIPE); - - if (argc) { - if (matches(*argv, "index") == 0) { -@@ -206,7 +181,8 @@ static int print_skbmod(struct action_util *au, FILE *f, struct rtattr *arg) - - p = RTA_DATA(tb[TCA_SKBMOD_PARMS]); - -- fprintf(f, "skbmod action %s ", action_n2a(p->action)); -+ fprintf(f, "skbmod "); -+ print_action_control(f, "", p->action, " "); - - if (tb[TCA_SKBMOD_ETYPE]) { - skbmod_etype = rta_getattr_u16(tb[TCA_SKBMOD_ETYPE]); -diff --git a/tc/m_tunnel_key.c b/tc/m_tunnel_key.c -index 60fd1c464e531..cdde64a15b929 100644 ---- a/tc/m_tunnel_key.c -+++ b/tc/m_tunnel_key.c -@@ -99,7 +99,7 @@ static int tunnel_key_parse_tos_ttl(char *str, int type, struct nlmsghdr *n) - static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p, - int tca_id, struct nlmsghdr *n) - { -- struct tc_tunnel_key parm = { .action = TC_ACT_PIPE }; -+ struct tc_tunnel_key parm = {}; - char **argv = *argv_p; - int argc = *argc_p; - struct rtattr *tail; -@@ -194,8 +194,8 @@ static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p, - NEXT_ARG_FWD(); - } - -- if (argc && !action_a2n(*argv, &parm.action, false)) -- NEXT_ARG_FWD(); -+ parse_action_control_dflt(&argc, &argv, &parm.action, -+ false, TC_ACT_PIPE); - - if (argc) { - if (matches(*argv, "index") == 0) { -@@ -318,7 +318,7 @@ static int print_tunnel_key(struct action_util *au, FILE *f, struct rtattr *arg) - tb[TCA_TUNNEL_KEY_ENC_TTL]); - break; - } -- fprintf(f, " %s", action_n2a(parm->action)); -+ print_action_control(f, " ", parm->action, ""); - - fprintf(f, "\n\tindex %d ref %d bind %d", parm->index, parm->refcnt, - parm->bindcnt); -diff --git a/tc/m_vlan.c b/tc/m_vlan.c -index 44b9375966da3..2441b06847ecd 100644 ---- a/tc/m_vlan.c -+++ b/tc/m_vlan.c -@@ -59,7 +59,7 @@ static int parse_vlan(struct action_util *a, int *argc_p, char ***argv_p, - int proto_set = 0; - __u8 prio; - int prio_set = 0; -- struct tc_vlan parm = { 0 }; -+ struct tc_vlan parm = {}; - - if (matches(*argv, "vlan") != 0) - return -1; -@@ -133,9 +133,8 @@ static int parse_vlan(struct action_util *a, int *argc_p, char ***argv_p, - argv++; - } - -- parm.action = TC_ACT_PIPE; -- if (argc && !action_a2n(*argv, &parm.action, false)) -- NEXT_ARG_FWD(); -+ parse_action_control_dflt(&argc, &argv, &parm.action, -+ false, TC_ACT_PIPE); - - if (argc) { - if (matches(*argv, "index") == 0) { -@@ -224,7 +223,7 @@ static int print_vlan(struct action_util *au, FILE *f, struct rtattr *arg) - } - break; - } -- fprintf(f, " %s", action_n2a(parm->action)); -+ print_action_control(f, " ", parm->action, ""); - - fprintf(f, "\n\t index %u ref %d bind %d", parm->index, parm->refcnt, - parm->bindcnt); -diff --git a/tc/tc_util.c b/tc/tc_util.c -index 296825ae174e0..840222832690b 100644 ---- a/tc/tc_util.c -+++ b/tc/tc_util.c -@@ -411,7 +411,7 @@ char *sprint_qdisc_handle(__u32 h, char *buf) - return buf; - } - --const char *action_n2a(int action) -+static const char *action_n2a(int action) - { - static char buf[64]; - -@@ -443,7 +443,7 @@ const char *action_n2a(int action) - * - * In error case, returns -1 and does not touch @result. Otherwise returns 0. - */ --int action_a2n(char *arg, int *result, bool allow_num) -+static int action_a2n(char *arg, int *result, bool allow_num) - { - int n; - char dummy; -@@ -474,6 +474,139 @@ int action_a2n(char *arg, int *result, bool allow_num) - return 0; - } - -+/* Parse action control including possible options. -+ * -+ * Parameters: -+ * @argc_p - pointer to argc to parse -+ * @argv_p - pointer to argv to parse -+ * @result_p - pointer to output variable -+ * @allow_num - whether action may be in numeric format already -+ * -+ * In error case, returns -1 and does not touch @result_1p. Otherwise returns 0. -+ */ -+int parse_action_control(int *argc_p, char ***argv_p, -+ int *result_p, bool allow_num) -+{ -+ int argc = *argc_p; -+ char **argv = *argv_p; -+ int result; -+ -+ if (!argc) -+ return -1; -+ if (action_a2n(*argv, &result, allow_num) == -1) { -+ fprintf(stderr, "Bad action type %s\n", *argv); -+ return -1; -+ } -+ NEXT_ARG_FWD(); -+ *argc_p = argc; -+ *argv_p = argv; -+ *result_p = result; -+ return 0; -+} -+ -+/* Parse action control including possible options. -+ * -+ * Parameters: -+ * @argc_p - pointer to argc to parse -+ * @argv_p - pointer to argv to parse -+ * @result_p - pointer to output variable -+ * @allow_num - whether action may be in numeric format already -+ * @default_result - set as a result in case of parsing error -+ * -+ * In case there is an error during parsing, the default result is used. -+ */ -+void parse_action_control_dflt(int *argc_p, char ***argv_p, -+ int *result_p, bool allow_num, -+ int default_result) -+{ -+ if (parse_action_control(argc_p, argv_p, result_p, allow_num)) -+ *result_p = default_result; -+} -+ -+static int parse_action_control_slash_spaces(int *argc_p, char ***argv_p, -+ int *result1_p, int *result2_p, -+ bool allow_num) -+{ -+ int argc = *argc_p; -+ char **argv = *argv_p; -+ int result1, result2; -+ int *result_p = &result1; -+ int ok = 0; -+ int ret; -+ -+ while (argc > 0) { -+ switch (ok) { -+ case 1: -+ if (strcmp(*argv, "/") != 0) -+ goto out; -+ result_p = &result2; -+ NEXT_ARG(); -+ /* fall-through */ -+ case 0: /* fall-through */ -+ case 2: -+ ret = parse_action_control(&argc, &argv, -+ result_p, allow_num); -+ if (ret) -+ return ret; -+ ok++; -+ break; -+ default: -+ goto out; -+ } -+ } -+out: -+ *result1_p = result1; -+ if (ok == 2) -+ *result2_p = result2; -+ *argc_p = argc; -+ *argv_p = argv; -+ return 0; -+} -+ -+/* Parse action control with slash including possible options. -+ * -+ * Parameters: -+ * @argc_p - pointer to argc to parse -+ * @argv_p - pointer to argv to parse -+ * @result1_p - pointer to the first (before slash) output variable -+ * @result2_p - pointer to the second (after slash) output variable -+ * @allow_num - whether action may be in numeric format already -+ * -+ * In error case, returns -1 and does not touch @result*. Otherwise returns 0. -+ */ -+int parse_action_control_slash(int *argc_p, char ***argv_p, -+ int *result1_p, int *result2_p, bool allow_num) -+{ -+ char **argv = *argv_p; -+ int result1, result2; -+ char *p = strchr(*argv, '/'); -+ -+ if (!p) -+ return parse_action_control_slash_spaces(argc_p, argv_p, -+ result1_p, result2_p, -+ allow_num); -+ *p = 0; -+ if (action_a2n(*argv, &result1, allow_num)) { -+ if (p) -+ *p = '/'; -+ return -1; -+ } -+ -+ *p = '/'; -+ if (action_a2n(p + 1, &result2, allow_num)) -+ return -1; -+ -+ *result1_p = result1; -+ *result2_p = result2; -+ return 0; -+} -+ -+void print_action_control(FILE *f, const char *prefix, -+ int action, const char *suffix) -+{ -+ fprintf(f, "%s%s%s", prefix, action_n2a(action), suffix); -+} -+ - int get_linklayer(unsigned int *val, const char *arg) - { - int res; -diff --git a/tc/tc_util.h b/tc/tc_util.h -index 4db26c6d5e25b..5c54ad384eae6 100644 ---- a/tc/tc_util.h -+++ b/tc/tc_util.h -@@ -100,8 +100,15 @@ char *sprint_tc_classid(__u32 h, char *buf); - int tc_print_police(FILE *f, struct rtattr *tb); - int parse_police(int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n); - --const char *action_n2a(int action); --int action_a2n(char *arg, int *result, bool allow_num); -+int parse_action_control(int *argc_p, char ***argv_p, -+ int *result_p, bool allow_num); -+void parse_action_control_dflt(int *argc_p, char ***argv_p, -+ int *result_p, bool allow_num, -+ int default_result); -+int parse_action_control_slash(int *argc_p, char ***argv_p, -+ int *result1_p, int *result2_p, bool allow_num); -+void print_action_control(FILE *f, const char *prefix, -+ int action, const char *suffix); - int act_parse_police(struct action_util *a, int *argc_p, - char ***argv_p, int tca_id, struct nlmsghdr *n); - int print_police(struct action_util *a, FILE *f, struct rtattr *tb); --- -2.21.0 - diff --git a/SOURCES/0133-tc-actions-introduce-support-for-goto-chain-action.patch b/SOURCES/0133-tc-actions-introduce-support-for-goto-chain-action.patch deleted file mode 100644 index 637f75c..0000000 --- a/SOURCES/0133-tc-actions-introduce-support-for-goto-chain-action.patch +++ /dev/null @@ -1,247 +0,0 @@ -From eaccce1b85efafbea1607ff88d7259541f311ee2 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Wed, 5 Jun 2019 13:10:31 +0200 -Subject: [PATCH] tc/actions: introduce support for goto chain action - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1714660 -Upstream Status: iproute2.git commit d19f72f7898a7 - -commit d19f72f7898a78ef76628833c204afb96f9a05cd -Author: Jiri Pirko -Date: Tue May 16 19:29:37 2017 +0200 - - tc/actions: introduce support for goto chain action - - Allow user to set control action "goto" with filter chain index as - a parameter. - - Signed-off-by: Jiri Pirko ---- - man/man8/tc-ife.8 | 2 +- - man/man8/tc-pedit.8 | 2 +- - man/man8/tc-police.8 | 2 +- - man/man8/tc-vlan.8 | 2 +- - tc/m_connmark.c | 3 ++- - tc/m_gact.c | 6 ++++-- - tc/m_pedit.c | 3 ++- - tc/m_police.c | 6 ++++-- - tc/m_skbmod.c | 3 ++- - tc/m_vlan.c | 3 ++- - tc/tc_util.c | 24 +++++++++++++++++++++++- - 11 files changed, 43 insertions(+), 13 deletions(-) - -diff --git a/man/man8/tc-ife.8 b/man/man8/tc-ife.8 -index a8f1f287d1502..24595cc6d615c 100644 ---- a/man/man8/tc-ife.8 -+++ b/man/man8/tc-ife.8 -@@ -34,7 +34,7 @@ IFE - encapsulate/decapsulate metadata - - .ti -8 - .IR CONTROL " := { " --.BR reclassify " | " use " | " pipe " | " drop " | " continue " | " ok " }" -+.BR reclassify " | " use " | " pipe " | " drop " | " continue " | " ok " | " goto " " chain " " CHAIN_INDEX " }" - .SH DESCRIPTION - The - .B ife -diff --git a/man/man8/tc-pedit.8 b/man/man8/tc-pedit.8 -index 82d4217bc9589..bbd725c4d0ba1 100644 ---- a/man/man8/tc-pedit.8 -+++ b/man/man8/tc-pedit.8 -@@ -82,7 +82,7 @@ pedit - generic packet editor action - - .ti -8 - .IR CONTROL " := {" --.BR reclassify " | " pipe " | " drop " | " shot " | " continue " | " pass " }" -+.BR reclassify " | " pipe " | " drop " | " shot " | " continue " | " pass " | " goto " " chain " " CHAIN_INDEX " }" - .SH DESCRIPTION - The - .B pedit -diff --git a/man/man8/tc-police.8 b/man/man8/tc-police.8 -index 620c28813fc7e..bcc5f438825d1 100644 ---- a/man/man8/tc-police.8 -+++ b/man/man8/tc-police.8 -@@ -30,7 +30,7 @@ police - policing action - - .ti -8 - .IR EXCEEDACT/NOTEXCEEDACT " := { " --.BR pipe " | " ok " | " reclassify " | " drop " | " continue " }" -+.BR pipe " | " ok " | " reclassify " | " drop " | " continue " | " goto " " chain " " CHAIN_INDEX " }" - .SH DESCRIPTION - The - .B police -diff --git a/man/man8/tc-vlan.8 b/man/man8/tc-vlan.8 -index a526f66b60b4c..f5ffc25f054ed 100644 ---- a/man/man8/tc-vlan.8 -+++ b/man/man8/tc-vlan.8 -@@ -26,7 +26,7 @@ vlan - vlan manipulation module - - .ti -8 - .IR CONTROL " := { " --.BR reclassify " | " pipe " | " drop " | " continue " | " pass " }" -+.BR reclassify " | " pipe " | " drop " | " continue " | " pass " | " goto " " chain " " CHAIN_INDEX " }" - .SH DESCRIPTION - The - .B vlan -diff --git a/tc/m_connmark.c b/tc/m_connmark.c -index 3c2274bc0d2af..37d7185415490 100644 ---- a/tc/m_connmark.c -+++ b/tc/m_connmark.c -@@ -30,7 +30,8 @@ explain(void) - fprintf(stderr, "Usage: ... connmark [zone ZONE] [CONTROL] [index ]\n"); - fprintf(stderr, "where :\n" - "\tZONE is the conntrack zone\n" -- "\tCONTROL := reclassify|pipe|drop|continue|ok\n"); -+ "\tCONTROL := reclassify | pipe | drop | continue | ok |\n" -+ "\t goto chain \n"); - } - - static void -diff --git a/tc/m_gact.c b/tc/m_gact.c -index bc3860bbe4441..c04c00bbded3c 100644 ---- a/tc/m_gact.c -+++ b/tc/m_gact.c -@@ -45,7 +45,8 @@ explain(void) - #ifdef CONFIG_GACT_PROB - fprintf(stderr, "Usage: ... gact [RAND] [INDEX]\n"); - fprintf(stderr, -- "Where: \tACTION := reclassify | drop | continue | pass | pipe\n" -+ "Where: \tACTION := reclassify | drop | continue | pass | pipe |\n" -+ " \t goto chain \n" - "\tRAND := random \n" - "\tRANDTYPE := netrand | determ\n" - "\tVAL : = value not exceeding 10000\n" -@@ -54,7 +55,8 @@ explain(void) - #else - fprintf(stderr, "Usage: ... gact [INDEX]\n"); - fprintf(stderr, -- "Where: \tACTION := reclassify | drop | continue | pass | pipe\n" -+ "Where: \tACTION := reclassify | drop | continue | pass | pipe |\n" -+ " \t goto chain \n" - "\tINDEX := index value used\n" - "\n"); - #endif -diff --git a/tc/m_pedit.c b/tc/m_pedit.c -index b7d26b4540beb..5d89ab1d832ab 100644 ---- a/tc/m_pedit.c -+++ b/tc/m_pedit.c -@@ -45,7 +45,8 @@ static void explain(void) - "\t\tCMD:= clear | invert | set | add | retain\n" - "\t:= ip | ip6 \n" - " \t\t| udp | tcp | icmp \n" -- "\tCONTROL:= reclassify | pipe | drop | continue | pass\n" -+ "\tCONTROL:= reclassify | pipe | drop | continue | pass |\n" -+ "\t goto chain \n" - "\tNOTE: if 'ex' is set, extended functionality will be supported (kernel >= 4.11)\n" - "For Example usage look at the examples directory\n"); - -diff --git a/tc/m_police.c b/tc/m_police.c -index 2b73969de5daf..86117db0482ec 100644 ---- a/tc/m_police.c -+++ b/tc/m_police.c -@@ -41,7 +41,8 @@ static void usage(void) - fprintf(stderr, "Where: CONTROL := conform-exceed [/NOTEXCEEDACT]\n"); - fprintf(stderr, " Define how to handle packets which exceed ()\n"); - fprintf(stderr, " or conform () the configured bandwidth limit.\n"); -- fprintf(stderr, " EXCEEDACT/NOTEXCEEDACT := { pipe | ok | reclassify | drop | continue }\n"); -+ fprintf(stderr, " EXCEEDACT/NOTEXCEEDACT := { pipe | ok | reclassify | drop | continue |\n"); -+ fprintf(stderr, " goto chain }\n"); - exit(-1); - } - -@@ -150,7 +151,8 @@ int act_parse_police(struct action_util *a, int *argc_p, char ***argv_p, - matches(*argv, "shot") == 0 || - matches(*argv, "continue") == 0 || - matches(*argv, "pass") == 0 || -- matches(*argv, "pipe") == 0) { -+ matches(*argv, "pipe") == 0 || -+ matches(*argv, "goto") == 0) { - if (parse_action_control(&argc, &argv, &p.action, false)) - return -1; - } else if (strcmp(*argv, "conform-exceed") == 0) { -diff --git a/tc/m_skbmod.c b/tc/m_skbmod.c -index 1ccd474309348..ba79308ba8354 100644 ---- a/tc/m_skbmod.c -+++ b/tc/m_skbmod.c -@@ -36,7 +36,8 @@ static void skbmod_explain(void) - "\tDMAC := 6 byte Destination MAC address\n" - "\tSMAC := optional 6 byte Source MAC address\n" - "\tETYPE := optional 16 bit ethertype\n" -- "\tCONTROL := reclassify|pipe|drop|continue|ok\n" -+ "\tCONTROL := reclassify | pipe | drop | continue | ok |\n" -+ "\t goto chain \n" - "\tINDEX := skbmod index value to use\n"); - } - -diff --git a/tc/m_vlan.c b/tc/m_vlan.c -index 2441b06847ecd..cccb4996b05f3 100644 ---- a/tc/m_vlan.c -+++ b/tc/m_vlan.c -@@ -32,7 +32,8 @@ static void explain(void) - fprintf(stderr, " vlan modify [ protocol VLANPROTO ] id VLANID [ priority VLANPRIO ] [CONTROL]\n"); - fprintf(stderr, " VLANPROTO is one of 802.1Q or 802.1AD\n"); - fprintf(stderr, " with default: 802.1Q\n"); -- fprintf(stderr, " CONTROL := reclassify | pipe | drop | continue | pass\n"); -+ fprintf(stderr, " CONTROL := reclassify | pipe | drop | continue | pass |\n"); -+ fprintf(stderr, " goto chain \n"); - } - - static void usage(void) -diff --git a/tc/tc_util.c b/tc/tc_util.c -index 840222832690b..194185a0fa1d8 100644 ---- a/tc/tc_util.c -+++ b/tc/tc_util.c -@@ -415,6 +415,8 @@ static const char *action_n2a(int action) - { - static char buf[64]; - -+ if (TC_ACT_EXT_CMP(action, TC_ACT_GOTO_CHAIN)) -+ return "goto"; - switch (action) { - case TC_ACT_UNSPEC: - return "continue"; -@@ -458,6 +460,7 @@ static int action_a2n(char *arg, int *result, bool allow_num) - {"ok", TC_ACT_OK}, - {"reclassify", TC_ACT_RECLASSIFY}, - {"pipe", TC_ACT_PIPE}, -+ {"goto", TC_ACT_GOTO_CHAIN}, - { NULL }, - }, *iter; - -@@ -497,6 +500,22 @@ int parse_action_control(int *argc_p, char ***argv_p, - fprintf(stderr, "Bad action type %s\n", *argv); - return -1; - } -+ if (result == TC_ACT_GOTO_CHAIN) { -+ __u32 chain_index; -+ -+ NEXT_ARG(); -+ if (matches(*argv, "chain") != 0) { -+ fprintf(stderr, "\"chain index\" expected\n"); -+ return -1; -+ } -+ NEXT_ARG(); -+ if (get_u32(&chain_index, *argv, 10) || -+ chain_index > TC_ACT_EXT_VAL_MASK) { -+ fprintf(stderr, "Illegal \"chain index\"\n"); -+ return -1; -+ } -+ result |= chain_index; -+ } - NEXT_ARG_FWD(); - *argc_p = argc; - *argv_p = argv; -@@ -604,7 +623,10 @@ int parse_action_control_slash(int *argc_p, char ***argv_p, - void print_action_control(FILE *f, const char *prefix, - int action, const char *suffix) - { -- fprintf(f, "%s%s%s", prefix, action_n2a(action), suffix); -+ fprintf(f, "%s%s", prefix, action_n2a(action)); -+ if (TC_ACT_EXT_CMP(action, TC_ACT_GOTO_CHAIN)) -+ fprintf(f, " chain %u", action & TC_ACT_EXT_VAL_MASK); -+ fprintf(f, "%s", suffix); - } - - int get_linklayer(unsigned int *val, const char *arg) --- -2.21.0 - diff --git a/SOURCES/0134-tc-gact-fix-control-action-parsing.patch b/SOURCES/0134-tc-gact-fix-control-action-parsing.patch deleted file mode 100644 index bde9bf3..0000000 --- a/SOURCES/0134-tc-gact-fix-control-action-parsing.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 46ce82dd840a158c8fe80842ac808b1df425e216 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Wed, 5 Jun 2019 13:10:31 +0200 -Subject: [PATCH] tc: gact: fix control action parsing - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1714660 -Upstream Status: iproute2.git commit 18f05d06016d9 -Conflicts: context change due to out-of-order cherry-pick of - commit 73aa988868e7e ("tc/m_gact: Drop dead code") - -commit 18f05d06016d9492c87fd105d831de0d6d858f43 -Author: Jiri Pirko -Date: Mon Jun 5 16:22:03 2017 +0200 - - tc: gact: fix control action parsing - - parse_action_control helper does advancing of the arg inside. So don't - do it outside. - - Fixes: e67aba559581 ("tc: actions: add helpers to parse and print control actions") - Signed-off-by: Jiri Pirko ---- - tc/m_gact.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/tc/m_gact.c b/tc/m_gact.c -index c04c00bbded3c..73346d4e9333b 100644 ---- a/tc/m_gact.c -+++ b/tc/m_gact.c -@@ -113,8 +113,6 @@ parse_gact(struct action_util *a, int *argc_p, char ***argv_p, - if (parse_action_control(&argc, &argv, - &pp.paction, false) == -1) - usage(); -- argc--; -- argv++; - if (get_u16(&pp.pval, *argv, 10)) { - fprintf(stderr, "Illegal probability val 0x%x\n", pp.pval); - return -1; --- -2.21.0 - diff --git a/SOURCES/0135-tc-don-t-print-error-message-on-miss-when-parsing-ac.patch b/SOURCES/0135-tc-don-t-print-error-message-on-miss-when-parsing-ac.patch deleted file mode 100644 index ce98b1a..0000000 --- a/SOURCES/0135-tc-don-t-print-error-message-on-miss-when-parsing-ac.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 8efbb8de949eedd4341d075175f932245a9f142c Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Wed, 5 Jun 2019 13:11:03 +0200 -Subject: [PATCH] tc: don't print error message on miss when parsing action - with default - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1714660 -Upstream Status: iproute2.git commit c794b7b179026 - -commit c794b7b17902627b19ddc00699d89ea7b6b1edf7 -Author: Jiri Pirko -Date: Thu Jun 15 14:10:51 2017 +0200 - - tc: don't print error message on miss when parsing action with default - - In case default control action parsing takes place, it is ok to miss. - So don't print error message. - - Fixes: e67aba559581 ("tc: actions: add helpers to parse and print control actions") - Reported-by: Jiri Benc - Signed-off-by: Jiri Pirko - Tested-by: Jiri Benc ---- - tc/tc_util.c | 36 ++++++++++++++++++++++-------------- - 1 file changed, 22 insertions(+), 14 deletions(-) - -diff --git a/tc/tc_util.c b/tc/tc_util.c -index 194185a0fa1d8..cdc23477ada53 100644 ---- a/tc/tc_util.c -+++ b/tc/tc_util.c -@@ -477,18 +477,8 @@ static int action_a2n(char *arg, int *result, bool allow_num) - return 0; - } - --/* Parse action control including possible options. -- * -- * Parameters: -- * @argc_p - pointer to argc to parse -- * @argv_p - pointer to argv to parse -- * @result_p - pointer to output variable -- * @allow_num - whether action may be in numeric format already -- * -- * In error case, returns -1 and does not touch @result_1p. Otherwise returns 0. -- */ --int parse_action_control(int *argc_p, char ***argv_p, -- int *result_p, bool allow_num) -+static int __parse_action_control(int *argc_p, char ***argv_p, int *result_p, -+ bool allow_num, bool ignore_a2n_miss) - { - int argc = *argc_p; - char **argv = *argv_p; -@@ -497,7 +487,8 @@ int parse_action_control(int *argc_p, char ***argv_p, - if (!argc) - return -1; - if (action_a2n(*argv, &result, allow_num) == -1) { -- fprintf(stderr, "Bad action type %s\n", *argv); -+ if (!ignore_a2n_miss) -+ fprintf(stderr, "Bad action type %s\n", *argv); - return -1; - } - if (result == TC_ACT_GOTO_CHAIN) { -@@ -523,6 +514,23 @@ int parse_action_control(int *argc_p, char ***argv_p, - return 0; - } - -+/* Parse action control including possible options. -+ * -+ * Parameters: -+ * @argc_p - pointer to argc to parse -+ * @argv_p - pointer to argv to parse -+ * @result_p - pointer to output variable -+ * @allow_num - whether action may be in numeric format already -+ * -+ * In error case, returns -1 and does not touch @result_1p. Otherwise returns 0. -+ */ -+int parse_action_control(int *argc_p, char ***argv_p, -+ int *result_p, bool allow_num) -+{ -+ return __parse_action_control(argc_p, argv_p, result_p, -+ allow_num, false); -+} -+ - /* Parse action control including possible options. - * - * Parameters: -@@ -538,7 +546,7 @@ void parse_action_control_dflt(int *argc_p, char ***argv_p, - int *result_p, bool allow_num, - int default_result) - { -- if (parse_action_control(argc_p, argv_p, result_p, allow_num)) -+ if (__parse_action_control(argc_p, argv_p, result_p, allow_num, true)) - *result_p = default_result; - } - --- -2.21.0 - diff --git a/SOURCES/0136-tc-util-Don-t-call-NEXT_ARG_FWD-in-__parse_action_co.patch b/SOURCES/0136-tc-util-Don-t-call-NEXT_ARG_FWD-in-__parse_action_co.patch deleted file mode 100644 index 83d8db4..0000000 --- a/SOURCES/0136-tc-util-Don-t-call-NEXT_ARG_FWD-in-__parse_action_co.patch +++ /dev/null @@ -1,235 +0,0 @@ -From 1a12c7c90330410171007ada7513247fda5a1c57 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Wed, 5 Jun 2019 13:11:03 +0200 -Subject: [PATCH] tc: util: Don't call NEXT_ARG_FWD() in - __parse_action_control() - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1714660 -Upstream Status: iproute2.git commit 3572e01a090a2 -Conflicts: context change mainly due to missing commit 35f2a7639dca4 - ("tc/actions: introduce support for jump action") - -commit 3572e01a090a298e2f4c4f796bad6639b652e031 -Author: Michal Privoznik -Date: Fri Dec 8 11:18:07 2017 +0100 - - tc: util: Don't call NEXT_ARG_FWD() in __parse_action_control() - - Not all callers want parse_action_control*() to advance the - arguments. For instance act_parse_police() does the argument - advancing itself. - - Fixes: e67aba559581 ("tc: actions: add helpers to parse and print control actions") - Signed-off-by: Michal Privoznik ---- - tc/m_bpf.c | 1 + - tc/m_connmark.c | 1 + - tc/m_csum.c | 1 + - tc/m_gact.c | 12 ++++++------ - tc/m_ife.c | 1 + - tc/m_mirred.c | 4 +++- - tc/m_nat.c | 1 + - tc/m_pedit.c | 1 + - tc/m_sample.c | 1 + - tc/m_skbedit.c | 1 + - tc/m_skbmod.c | 1 + - tc/m_tunnel_key.c | 1 + - tc/m_vlan.c | 1 + - tc/tc_util.c | 1 - - 14 files changed, 20 insertions(+), 8 deletions(-) - -diff --git a/tc/m_bpf.c b/tc/m_bpf.c -index 57283030a35f5..c2bad5640707c 100644 ---- a/tc/m_bpf.c -+++ b/tc/m_bpf.c -@@ -125,6 +125,7 @@ opt_bpf: - - parse_action_control_dflt(&argc, &argv, &parm.action, - false, TC_ACT_PIPE); -+ NEXT_ARG_FWD(); - - if (argc) { - if (matches(*argv, "index") == 0) { -diff --git a/tc/m_connmark.c b/tc/m_connmark.c -index 37d7185415490..47c7a8c2b17e7 100644 ---- a/tc/m_connmark.c -+++ b/tc/m_connmark.c -@@ -82,6 +82,7 @@ parse_connmark(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, - } - - parse_action_control_dflt(&argc, &argv, &sel.action, false, TC_ACT_PIPE); -+ NEXT_ARG_FWD(); - - if (argc) { - if (matches(*argv, "index") == 0) { -diff --git a/tc/m_csum.c b/tc/m_csum.c -index 7b156734f64c5..e1352c0820f69 100644 ---- a/tc/m_csum.c -+++ b/tc/m_csum.c -@@ -124,6 +124,7 @@ parse_csum(struct action_util *a, int *argc_p, - } - - parse_action_control_dflt(&argc, &argv, &sel.action, false, TC_ACT_OK); -+ NEXT_ARG_FWD(); - - if (argc) { - if (matches(*argv, "index") == 0) { -diff --git a/tc/m_gact.c b/tc/m_gact.c -index 73346d4e9333b..dd9542a5cc644 100644 ---- a/tc/m_gact.c -+++ b/tc/m_gact.c -@@ -86,14 +86,13 @@ parse_gact(struct action_util *a, int *argc_p, char ***argv_p, - if (argc < 0) - return -1; - -- -- if (matches(*argv, "gact") == 0) { -- argc--; -- argv++; -- } else if (parse_action_control(&argc, &argv, &p.action, false) == -1) { -- usage(); -+ if (matches(*argv, "gact") != 0 && -+ parse_action_control(&argc, &argv, &p.action, false) == -1) { -+ usage(); /* does not return */ - } - -+ NEXT_ARG_FWD(); -+ - #ifdef CONFIG_GACT_PROB - if (argc > 0) { - if (matches(*argv, "random") == 0) { -@@ -113,6 +112,7 @@ parse_gact(struct action_util *a, int *argc_p, char ***argv_p, - if (parse_action_control(&argc, &argv, - &pp.paction, false) == -1) - usage(); -+ NEXT_ARG_FWD(); - if (get_u16(&pp.pval, *argv, 10)) { - fprintf(stderr, "Illegal probability val 0x%x\n", pp.pval); - return -1; -diff --git a/tc/m_ife.c b/tc/m_ife.c -index e3521e62c178c..54fad8f70e73a 100644 ---- a/tc/m_ife.c -+++ b/tc/m_ife.c -@@ -158,6 +158,7 @@ static int parse_ife(struct action_util *a, int *argc_p, char ***argv_p, - - parse_action_control_dflt(&argc, &argv, &p.action, false, TC_ACT_PIPE); - -+ NEXT_ARG_FWD(); - if (argc) { - if (matches(*argv, "index") == 0) { - NEXT_ARG(); -diff --git a/tc/m_mirred.c b/tc/m_mirred.c -index 2384bda1ff045..b09b016c2ca39 100644 ---- a/tc/m_mirred.c -+++ b/tc/m_mirred.c -@@ -170,8 +170,10 @@ parse_direction(struct action_util *a, int *argc_p, char ***argv_p, - } - - -- if (p.eaction == TCA_EGRESS_MIRROR || p.eaction == TCA_INGRESS_MIRROR) -+ if (p.eaction == TCA_EGRESS_MIRROR || p.eaction == TCA_INGRESS_MIRROR) { - parse_action_control(&argc, &argv, &p.action, false); -+ NEXT_ARG_FWD(); -+ } - - if (argc) { - if (iok && matches(*argv, "index") == 0) { -diff --git a/tc/m_nat.c b/tc/m_nat.c -index 31b68fb6bd784..bb455f080b3a4 100644 ---- a/tc/m_nat.c -+++ b/tc/m_nat.c -@@ -117,6 +117,7 @@ parse_nat(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, struct - - parse_action_control_dflt(&argc, &argv, &sel.action, false, TC_ACT_OK); - -+ NEXT_ARG_FWD(); - if (argc) { - if (matches(*argv, "index") == 0) { - NEXT_ARG(); -diff --git a/tc/m_pedit.c b/tc/m_pedit.c -index 5d89ab1d832ab..3391be95da38c 100644 ---- a/tc/m_pedit.c -+++ b/tc/m_pedit.c -@@ -673,6 +673,7 @@ int parse_pedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, - - parse_action_control_dflt(&argc, &argv, &sel.sel.action, false, TC_ACT_OK); - -+ NEXT_ARG_FWD(); - if (argc) { - if (matches(*argv, "index") == 0) { - NEXT_ARG(); -diff --git a/tc/m_sample.c b/tc/m_sample.c -index ff5ee6bd1ef63..31774c0e806b4 100644 ---- a/tc/m_sample.c -+++ b/tc/m_sample.c -@@ -100,6 +100,7 @@ static int parse_sample(struct action_util *a, int *argc_p, char ***argv_p, - - parse_action_control_dflt(&argc, &argv, &p.action, false, TC_ACT_PIPE); - -+ NEXT_ARG_FWD(); - if (argc) { - if (matches(*argv, "index") == 0) { - NEXT_ARG(); -diff --git a/tc/m_skbedit.c b/tc/m_skbedit.c -index aa374fcb33ed9..c41a7bb082dad 100644 ---- a/tc/m_skbedit.c -+++ b/tc/m_skbedit.c -@@ -123,6 +123,7 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, - parse_action_control_dflt(&argc, &argv, &sel.action, - false, TC_ACT_PIPE); - -+ NEXT_ARG_FWD(); - if (argc) { - if (matches(*argv, "index") == 0) { - NEXT_ARG(); -diff --git a/tc/m_skbmod.c b/tc/m_skbmod.c -index ba79308ba8354..00318d42642a5 100644 ---- a/tc/m_skbmod.c -+++ b/tc/m_skbmod.c -@@ -125,6 +125,7 @@ static int parse_skbmod(struct action_util *a, int *argc_p, char ***argv_p, - - parse_action_control_dflt(&argc, &argv, &p.action, false, TC_ACT_PIPE); - -+ NEXT_ARG_FWD(); - if (argc) { - if (matches(*argv, "index") == 0) { - NEXT_ARG(); -diff --git a/tc/m_tunnel_key.c b/tc/m_tunnel_key.c -index cdde64a15b929..0ff3f1a2b9876 100644 ---- a/tc/m_tunnel_key.c -+++ b/tc/m_tunnel_key.c -@@ -197,6 +197,7 @@ static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p, - parse_action_control_dflt(&argc, &argv, &parm.action, - false, TC_ACT_PIPE); - -+ NEXT_ARG_FWD(); - if (argc) { - if (matches(*argv, "index") == 0) { - NEXT_ARG(); -diff --git a/tc/m_vlan.c b/tc/m_vlan.c -index cccb4996b05f3..0b2966ce82e53 100644 ---- a/tc/m_vlan.c -+++ b/tc/m_vlan.c -@@ -137,6 +137,7 @@ static int parse_vlan(struct action_util *a, int *argc_p, char ***argv_p, - parse_action_control_dflt(&argc, &argv, &parm.action, - false, TC_ACT_PIPE); - -+ NEXT_ARG_FWD(); - if (argc) { - if (matches(*argv, "index") == 0) { - NEXT_ARG(); -diff --git a/tc/tc_util.c b/tc/tc_util.c -index cdc23477ada53..4584d4a448fb4 100644 ---- a/tc/tc_util.c -+++ b/tc/tc_util.c -@@ -507,7 +507,6 @@ static int __parse_action_control(int *argc_p, char ***argv_p, int *result_p, - } - result |= chain_index; - } -- NEXT_ARG_FWD(); - *argc_p = argc; - *argv_p = argv; - *result_p = result; --- -2.21.0 - diff --git a/SOURCES/0137-tc-fix-parsing-of-the-control-action.patch b/SOURCES/0137-tc-fix-parsing-of-the-control-action.patch deleted file mode 100644 index f8797f5..0000000 --- a/SOURCES/0137-tc-fix-parsing-of-the-control-action.patch +++ /dev/null @@ -1,321 +0,0 @@ -From cb73324026eb3f9c315735b9020890f43eeaac43 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Wed, 5 Jun 2019 13:12:06 +0200 -Subject: [PATCH] tc: fix parsing of the control action - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1714660 -Upstream Status: iproute2.git commit 75ef7b18d2a13 -Conflicts: context change due to missing commit 35f2a7639dca4 - ("tc/actions: introduce support for jump action") - -commit 75ef7b18d2a13657056706895bf8d8dd3ac93e46 -Author: Davide Caratti -Date: Fri Mar 2 19:36:16 2018 +0100 - - tc: fix parsing of the control action - - If the user didn't specify any control action, don't pop the command line - arguments: otherwise, parsing of the next argument (tipically the 'index' - keyword) results in an error, causing the following 'tc-testing' failures: - - Test a6d6: Add skbedit action with index - Test 38f3: Delete skbedit action - Test a568: Add action with ife type - Test b983: Add action without ife type - Test 7d50: Add skbmod action to set destination mac - Test 9b29: Add skbmod action to set source mac - Test e93a: Delete an skbmod action - - Also, add missing parse for 'ok' control action to m_police, to fix the - following 'tc-testing' failure: - - Test 8dd5: Add police action with control ok - - tested with: - # ./tdc.py - - test results: - all tests ok using kernel 4.16-rc2, except 9aa8 "Get a single skbmod - action from a list" (which is failing also before this commit) - - Fixes: 3572e01a090a ("tc: util: Don't call NEXT_ARG_FWD() in __parse_action_control()") - Cc: Michal Privoznik - Cc: Wolfgang Bumiller - Signed-off-by: Davide Caratti - Signed-off-by: Stephen Hemminger ---- - tc/m_bpf.c | 1 - - tc/m_connmark.c | 1 - - tc/m_csum.c | 1 - - tc/m_gact.c | 9 +++------ - tc/m_ife.c | 1 - - tc/m_mirred.c | 5 ++--- - tc/m_nat.c | 1 - - tc/m_pedit.c | 1 - - tc/m_police.c | 16 ++++++++++------ - tc/m_sample.c | 1 - - tc/m_skbedit.c | 1 - - tc/m_skbmod.c | 1 - - tc/m_tunnel_key.c | 1 - - tc/m_vlan.c | 1 - - tc/tc_util.c | 6 +++++- - 15 files changed, 20 insertions(+), 27 deletions(-) - -diff --git a/tc/m_bpf.c b/tc/m_bpf.c -index c2bad5640707c..57283030a35f5 100644 ---- a/tc/m_bpf.c -+++ b/tc/m_bpf.c -@@ -125,7 +125,6 @@ opt_bpf: - - parse_action_control_dflt(&argc, &argv, &parm.action, - false, TC_ACT_PIPE); -- NEXT_ARG_FWD(); - - if (argc) { - if (matches(*argv, "index") == 0) { -diff --git a/tc/m_connmark.c b/tc/m_connmark.c -index 47c7a8c2b17e7..37d7185415490 100644 ---- a/tc/m_connmark.c -+++ b/tc/m_connmark.c -@@ -82,7 +82,6 @@ parse_connmark(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, - } - - parse_action_control_dflt(&argc, &argv, &sel.action, false, TC_ACT_PIPE); -- NEXT_ARG_FWD(); - - if (argc) { - if (matches(*argv, "index") == 0) { -diff --git a/tc/m_csum.c b/tc/m_csum.c -index e1352c0820f69..7b156734f64c5 100644 ---- a/tc/m_csum.c -+++ b/tc/m_csum.c -@@ -124,7 +124,6 @@ parse_csum(struct action_util *a, int *argc_p, - } - - parse_action_control_dflt(&argc, &argv, &sel.action, false, TC_ACT_OK); -- NEXT_ARG_FWD(); - - if (argc) { - if (matches(*argv, "index") == 0) { -diff --git a/tc/m_gact.c b/tc/m_gact.c -index dd9542a5cc644..45eecf7ea1647 100644 ---- a/tc/m_gact.c -+++ b/tc/m_gact.c -@@ -86,12 +86,10 @@ parse_gact(struct action_util *a, int *argc_p, char ***argv_p, - if (argc < 0) - return -1; - -- if (matches(*argv, "gact") != 0 && -- parse_action_control(&argc, &argv, &p.action, false) == -1) { -+ if (!matches(*argv, "gact")) -+ NEXT_ARG_FWD(); -+ if (parse_action_control(&argc, &argv, &p.action, false)) - usage(); /* does not return */ -- } -- -- NEXT_ARG_FWD(); - - #ifdef CONFIG_GACT_PROB - if (argc > 0) { -@@ -112,7 +110,6 @@ parse_gact(struct action_util *a, int *argc_p, char ***argv_p, - if (parse_action_control(&argc, &argv, - &pp.paction, false) == -1) - usage(); -- NEXT_ARG_FWD(); - if (get_u16(&pp.pval, *argv, 10)) { - fprintf(stderr, "Illegal probability val 0x%x\n", pp.pval); - return -1; -diff --git a/tc/m_ife.c b/tc/m_ife.c -index 54fad8f70e73a..e3521e62c178c 100644 ---- a/tc/m_ife.c -+++ b/tc/m_ife.c -@@ -158,7 +158,6 @@ static int parse_ife(struct action_util *a, int *argc_p, char ***argv_p, - - parse_action_control_dflt(&argc, &argv, &p.action, false, TC_ACT_PIPE); - -- NEXT_ARG_FWD(); - if (argc) { - if (matches(*argv, "index") == 0) { - NEXT_ARG(); -diff --git a/tc/m_mirred.c b/tc/m_mirred.c -index b09b016c2ca39..b1f45f1e6ecb0 100644 ---- a/tc/m_mirred.c -+++ b/tc/m_mirred.c -@@ -76,6 +76,7 @@ parse_direction(struct action_util *a, int *argc_p, char ***argv_p, - while (argc > 0) { - - if (matches(*argv, "action") == 0) { -+ NEXT_ARG(); - break; - } else if (!egress && matches(*argv, "egress") == 0) { - egress = 1; -@@ -170,10 +171,8 @@ parse_direction(struct action_util *a, int *argc_p, char ***argv_p, - } - - -- if (p.eaction == TCA_EGRESS_MIRROR || p.eaction == TCA_INGRESS_MIRROR) { -+ if (p.eaction == TCA_EGRESS_MIRROR || p.eaction == TCA_INGRESS_MIRROR) - parse_action_control(&argc, &argv, &p.action, false); -- NEXT_ARG_FWD(); -- } - - if (argc) { - if (iok && matches(*argv, "index") == 0) { -diff --git a/tc/m_nat.c b/tc/m_nat.c -index bb455f080b3a4..31b68fb6bd784 100644 ---- a/tc/m_nat.c -+++ b/tc/m_nat.c -@@ -117,7 +117,6 @@ parse_nat(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, struct - - parse_action_control_dflt(&argc, &argv, &sel.action, false, TC_ACT_OK); - -- NEXT_ARG_FWD(); - if (argc) { - if (matches(*argv, "index") == 0) { - NEXT_ARG(); -diff --git a/tc/m_pedit.c b/tc/m_pedit.c -index 3391be95da38c..5d89ab1d832ab 100644 ---- a/tc/m_pedit.c -+++ b/tc/m_pedit.c -@@ -673,7 +673,6 @@ int parse_pedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, - - parse_action_control_dflt(&argc, &argv, &sel.sel.action, false, TC_ACT_OK); - -- NEXT_ARG_FWD(); - if (argc) { - if (matches(*argv, "index") == 0) { - NEXT_ARG(); -diff --git a/tc/m_police.c b/tc/m_police.c -index 86117db0482ec..b79545961f4d7 100644 ---- a/tc/m_police.c -+++ b/tc/m_police.c -@@ -151,15 +151,18 @@ int act_parse_police(struct action_util *a, int *argc_p, char ***argv_p, - matches(*argv, "shot") == 0 || - matches(*argv, "continue") == 0 || - matches(*argv, "pass") == 0 || -+ matches(*argv, "ok") == 0 || - matches(*argv, "pipe") == 0 || - matches(*argv, "goto") == 0) { -- if (parse_action_control(&argc, &argv, &p.action, false)) -- return -1; -+ if (!parse_action_control(&argc, &argv, &p.action, false)) -+ goto action_ctrl_ok; -+ return -1; - } else if (strcmp(*argv, "conform-exceed") == 0) { - NEXT_ARG(); -- if (parse_action_control_slash(&argc, &argv, &p.action, -- &presult, true)) -- return -1; -+ if (!parse_action_control_slash(&argc, &argv, &p.action, -+ &presult, true)) -+ goto action_ctrl_ok; -+ return -1; - } else if (matches(*argv, "overhead") == 0) { - NEXT_ARG(); - if (get_u16(&overhead, *argv, 10)) { -@@ -175,8 +178,9 @@ int act_parse_police(struct action_util *a, int *argc_p, char ***argv_p, - } else { - break; - } -+ NEXT_ARG_FWD(); -+action_ctrl_ok: - ok++; -- argc--; argv++; - } - - if (!ok) -diff --git a/tc/m_sample.c b/tc/m_sample.c -index 31774c0e806b4..ff5ee6bd1ef63 100644 ---- a/tc/m_sample.c -+++ b/tc/m_sample.c -@@ -100,7 +100,6 @@ static int parse_sample(struct action_util *a, int *argc_p, char ***argv_p, - - parse_action_control_dflt(&argc, &argv, &p.action, false, TC_ACT_PIPE); - -- NEXT_ARG_FWD(); - if (argc) { - if (matches(*argv, "index") == 0) { - NEXT_ARG(); -diff --git a/tc/m_skbedit.c b/tc/m_skbedit.c -index c41a7bb082dad..aa374fcb33ed9 100644 ---- a/tc/m_skbedit.c -+++ b/tc/m_skbedit.c -@@ -123,7 +123,6 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, - parse_action_control_dflt(&argc, &argv, &sel.action, - false, TC_ACT_PIPE); - -- NEXT_ARG_FWD(); - if (argc) { - if (matches(*argv, "index") == 0) { - NEXT_ARG(); -diff --git a/tc/m_skbmod.c b/tc/m_skbmod.c -index 00318d42642a5..ba79308ba8354 100644 ---- a/tc/m_skbmod.c -+++ b/tc/m_skbmod.c -@@ -125,7 +125,6 @@ static int parse_skbmod(struct action_util *a, int *argc_p, char ***argv_p, - - parse_action_control_dflt(&argc, &argv, &p.action, false, TC_ACT_PIPE); - -- NEXT_ARG_FWD(); - if (argc) { - if (matches(*argv, "index") == 0) { - NEXT_ARG(); -diff --git a/tc/m_tunnel_key.c b/tc/m_tunnel_key.c -index 0ff3f1a2b9876..cdde64a15b929 100644 ---- a/tc/m_tunnel_key.c -+++ b/tc/m_tunnel_key.c -@@ -197,7 +197,6 @@ static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p, - parse_action_control_dflt(&argc, &argv, &parm.action, - false, TC_ACT_PIPE); - -- NEXT_ARG_FWD(); - if (argc) { - if (matches(*argv, "index") == 0) { - NEXT_ARG(); -diff --git a/tc/m_vlan.c b/tc/m_vlan.c -index 0b2966ce82e53..cccb4996b05f3 100644 ---- a/tc/m_vlan.c -+++ b/tc/m_vlan.c -@@ -137,7 +137,6 @@ static int parse_vlan(struct action_util *a, int *argc_p, char ***argv_p, - parse_action_control_dflt(&argc, &argv, &parm.action, - false, TC_ACT_PIPE); - -- NEXT_ARG_FWD(); - if (argc) { - if (matches(*argv, "index") == 0) { - NEXT_ARG(); -diff --git a/tc/tc_util.c b/tc/tc_util.c -index 4584d4a448fb4..65695ea592ed8 100644 ---- a/tc/tc_util.c -+++ b/tc/tc_util.c -@@ -507,6 +507,7 @@ static int __parse_action_control(int *argc_p, char ***argv_p, int *result_p, - } - result |= chain_index; - } -+ NEXT_ARG_FWD(); - *argc_p = argc; - *argv_p = argv; - *result_p = result; -@@ -603,8 +604,8 @@ out: - int parse_action_control_slash(int *argc_p, char ***argv_p, - int *result1_p, int *result2_p, bool allow_num) - { -+ int result1, result2, argc = *argc_p; - char **argv = *argv_p; -- int result1, result2; - char *p = strchr(*argv, '/'); - - if (!p) -@@ -624,6 +625,9 @@ int parse_action_control_slash(int *argc_p, char ***argv_p, - - *result1_p = result1; - *result2_p = result2; -+ NEXT_ARG_FWD(); -+ *argc_p = argc; -+ *argv_p = argv; - return 0; - } - --- -2.21.0 - diff --git a/SOURCES/0138-m_mirred-don-t-bail-if-the-control-action-is-missing.patch b/SOURCES/0138-m_mirred-don-t-bail-if-the-control-action-is-missing.patch deleted file mode 100644 index a56bbbb..0000000 --- a/SOURCES/0138-m_mirred-don-t-bail-if-the-control-action-is-missing.patch +++ /dev/null @@ -1,46 +0,0 @@ -From e4526cbbfb6151e87e493a7fecfe2384a3751100 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Wed, 5 Jun 2019 13:12:49 +0200 -Subject: [PATCH] m_mirred: don't bail if the control action is missing - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1714660 -Upstream Status: iproute2.git commit 6eccf7ecdb010 - -commit 6eccf7ecdb010a90e5271942748ef4338ddb61ae -Author: Paolo Abeni -Date: Mon May 20 11:56:52 2019 +0200 - - m_mirred: don't bail if the control action is missing - - The mirred act admits an optional control action, defaulting - to TC_ACT_PIPE. The parsing code currently emits an error message - if the control action is not provided on the command line, even - if the command itself completes with no error. - - This change shuts down the error message, using the appropriate - parsing helper. - - Fixes: e67aba559581 ("tc: actions: add helpers to parse and print control actions") - Signed-off-by: Paolo Abeni - Signed-off-by: Stephen Hemminger ---- - tc/m_mirred.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/tc/m_mirred.c b/tc/m_mirred.c -index b1f45f1e6ecb0..90d0b633c1318 100644 ---- a/tc/m_mirred.c -+++ b/tc/m_mirred.c -@@ -172,7 +172,8 @@ parse_direction(struct action_util *a, int *argc_p, char ***argv_p, - - - if (p.eaction == TCA_EGRESS_MIRROR || p.eaction == TCA_INGRESS_MIRROR) -- parse_action_control(&argc, &argv, &p.action, false); -+ parse_action_control_dflt(&argc, &argv, &p.action, false, -+ TC_ACT_PIPE); - - if (argc) { - if (iok && matches(*argv, "index") == 0) { --- -2.21.0 - diff --git a/SOURCES/0139-tc-m_tunnel_key-add-csum-nocsum-option.patch b/SOURCES/0139-tc-m_tunnel_key-add-csum-nocsum-option.patch deleted file mode 100644 index 7649aca..0000000 --- a/SOURCES/0139-tc-m_tunnel_key-add-csum-nocsum-option.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 0152070641c58eccf6c6d9981a33f17ada23996f Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Wed, 5 Jun 2019 13:12:49 +0200 -Subject: [PATCH] tc: m_tunnel_key: add csum/nocsum option - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1714660 -Upstream Status: iproute2.git commit 59eb271d1d259 -Conflicts: context change due to out-of-order cherry-pick of - commit 9f89b0cc0eda2 ("tc/act_tunnel_key: Enable - setup of tos and ttl") - -commit 59eb271d1d259da21372d222a2d995e57ef648a9 -Author: Jiri Benc -Date: Wed Jun 14 21:30:18 2017 +0200 - - tc: m_tunnel_key: add csum/nocsum option - - Allows control of UDP zero checksum. - - Signed-off-by: Jiri Benc ---- - man/man8/tc-tunnel_key.8 | 18 ++++++++++++++++++ - tc/m_tunnel_key.c | 21 ++++++++++++++++++++- - 2 files changed, 38 insertions(+), 1 deletion(-) - -diff --git a/man/man8/tc-tunnel_key.8 b/man/man8/tc-tunnel_key.8 -index 5e93c59d49465..0cd792a66d185 100644 ---- a/man/man8/tc-tunnel_key.8 -+++ b/man/man8/tc-tunnel_key.8 -@@ -18,6 +18,7 @@ tunnel_key - Tunnel metadata manipulation - .BI dst_port " UDP_PORT" - .BI tos " TOS" - .BI ttl " TTL" -+.RB "[ " csum " | " nocsum " ]" - - .SH DESCRIPTION - The -@@ -85,6 +86,23 @@ Outer header TOS - .TP - .B ttl - Outer header TTL -+.TP -+.RB [ no ] csum -+Controlls outer UDP checksum. When set to -+.B csum -+(which is default), the outer UDP checksum is calculated and included in the -+packets. When set to -+.BR nocsum , -+outer UDP checksum is zero. Note that when using zero UDP checksums with -+IPv6, the other tunnel endpoint must be configured to accept such packets. -+In Linux, this would be the -+.B udp6zerocsumrx -+option for the VXLAN tunnel interface. -+.IP -+If using -+.B nocsum -+with IPv6, be sure you know what you are doing. Zero UDP checksums provide -+weaker protection against corrupted packets. See RFC6935 for details. - .RE - .SH EXAMPLES - The following example encapsulates incoming ICMP packets on eth0 into a vxlan -diff --git a/tc/m_tunnel_key.c b/tc/m_tunnel_key.c -index cdde64a15b929..992adc51c28ab 100644 ---- a/tc/m_tunnel_key.c -+++ b/tc/m_tunnel_key.c -@@ -28,7 +28,8 @@ static void explain(void) - "id \n" - "src_ip (mandatory)\n" - "dst_ip (mandatory)\n" -- "dst_port \n"); -+ "dst_port \n" -+ "csum | nocsum (default is \"csum\")\n"); - } - - static void usage(void) -@@ -107,6 +108,7 @@ static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p, - int ret; - int has_src_ip = 0; - int has_dst_ip = 0; -+ int csum = 1; - - if (matches(*argv, "tunnel_key") != 0) - return -1; -@@ -186,6 +188,10 @@ static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p, - fprintf(stderr, "Illegal \"ttl\"\n"); - return -1; - } -+ } else if (matches(*argv, "csum") == 0) { -+ csum = 1; -+ } else if (matches(*argv, "nocsum") == 0) { -+ csum = 0; - } else if (matches(*argv, "help") == 0) { - usage(); - } else { -@@ -194,6 +200,8 @@ static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p, - NEXT_ARG_FWD(); - } - -+ addattr8(n, MAX_MSG, TCA_TUNNEL_KEY_NO_CSUM, !csum); -+ - parse_action_control_dflt(&argc, &argv, &parm.action, - false, TC_ACT_PIPE); - -@@ -276,6 +284,15 @@ static void tunnel_key_print_tos_ttl(FILE *f, char *name, - } - } - -+static void tunnel_key_print_flag(FILE *f, const char *name_on, -+ const char *name_off, -+ struct rtattr *attr) -+{ -+ if (!attr) -+ return; -+ fprintf(f, "\n\t%s", rta_getattr_u8(attr) ? name_on : name_off); -+} -+ - static int print_tunnel_key(struct action_util *au, FILE *f, struct rtattr *arg) - { - struct rtattr *tb[TCA_TUNNEL_KEY_MAX + 1]; -@@ -312,6 +329,8 @@ static int print_tunnel_key(struct action_util *au, FILE *f, struct rtattr *arg) - tb[TCA_TUNNEL_KEY_ENC_KEY_ID]); - tunnel_key_print_dst_port(f, "dst_port", - tb[TCA_TUNNEL_KEY_ENC_DST_PORT]); -+ tunnel_key_print_flag(f, "nocsum", "csum", -+ tb[TCA_TUNNEL_KEY_NO_CSUM]); - tunnel_key_print_tos_ttl(f, "tos", - tb[TCA_TUNNEL_KEY_ENC_TOS]); - tunnel_key_print_tos_ttl(f, "ttl", --- -2.21.0 - diff --git a/SOURCES/0140-gre6-add-collect-metadata-support.patch b/SOURCES/0140-gre6-add-collect-metadata-support.patch deleted file mode 100644 index ac44613..0000000 --- a/SOURCES/0140-gre6-add-collect-metadata-support.patch +++ /dev/null @@ -1,160 +0,0 @@ -From b9961cdb54c22fa1b3f1eac5446a008fde7532e6 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Wed, 5 Jun 2019 13:13:31 +0200 -Subject: [PATCH] gre6: add collect metadata support - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1714660 -Upstream Status: iproute2.git commit 6231c5bec6d25 -Conflicts: -* Context change due to missing commit - ad4b1425c3182 ("iplink: Expose IFLA_*_FWMARK attributes for supported link types") -* Adjusted gre_print_opt() to missing commit 6856fb65484ba - ("ip: link_gre6.c: add json output support") - -commit 6231c5bec6d256f7861f39d3a578f5259f274cc4 -Author: William Tu -Date: Tue Dec 12 18:22:52 2017 -0800 - - gre6: add collect metadata support - - The patch adds 'external' option to support collect metadata - gre6 tunnel. The 'external' keyword is already used to set the - device into collect metadata mode such as vxlan, geneve, ipip, - etc. This patch extends support for ipv6 gre and gretap. - Example of L3 and L2 gre device: - bash:~# ip link add dev ip6gre123 type ip6gre external - bash:~# ip link add dev ip6gretap123 type ip6gretap external - - Signed-off-by: William Tu - Cc: Daniel Borkmann ---- - ip/link_gre6.c | 49 ++++++++++++++++++++++++++++--------------- - man/man8/ip-link.8.in | 17 +++++++++++++++ - 2 files changed, 49 insertions(+), 17 deletions(-) - -diff --git a/ip/link_gre6.c b/ip/link_gre6.c -index 127e51de4ab73..ea42fb1a9f664 100644 ---- a/ip/link_gre6.c -+++ b/ip/link_gre6.c -@@ -102,6 +102,7 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv, - __u16 encapflags = TUNNEL_ENCAP_FLAG_CSUM6; - __u16 encapsport = 0; - __u16 encapdport = 0; -+ __u8 metadata = 0; - int len; - - if (!(n->nlmsg_flags & NLM_F_CREATE)) { -@@ -173,6 +174,9 @@ get_failed: - if (greinfo[IFLA_GRE_ENCAP_SPORT]) - encapsport = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_SPORT]); - -+ if (greinfo[IFLA_GRE_COLLECT_METADATA]) -+ metadata = 1; -+ - if (greinfo[IFLA_GRE_ENCAP_DPORT]) - encapdport = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_DPORT]); - -@@ -333,6 +337,8 @@ get_failed: - encapflags |= TUNNEL_ENCAP_FLAG_REMCSUM; - } else if (strcmp(*argv, "noencap-remcsum") == 0) { - encapflags &= ~TUNNEL_ENCAP_FLAG_REMCSUM; -+ } else if (strcmp(*argv, "external") == 0) { -+ metadata = 1; - } else if (strcmp(*argv, "encaplimit") == 0) { - NEXT_ARG(); - if (strcmp(*argv, "none") == 0) { -@@ -350,23 +356,27 @@ get_failed: - argc--; argv++; - } - -- addattr32(n, 1024, IFLA_GRE_IKEY, ikey); -- addattr32(n, 1024, IFLA_GRE_OKEY, okey); -- addattr_l(n, 1024, IFLA_GRE_IFLAGS, &iflags, 2); -- addattr_l(n, 1024, IFLA_GRE_OFLAGS, &oflags, 2); -- addattr_l(n, 1024, IFLA_GRE_LOCAL, &laddr, sizeof(laddr)); -- addattr_l(n, 1024, IFLA_GRE_REMOTE, &raddr, sizeof(raddr)); -- if (link) -- addattr32(n, 1024, IFLA_GRE_LINK, link); -- addattr_l(n, 1024, IFLA_GRE_TTL, &hop_limit, 1); -- addattr_l(n, 1024, IFLA_GRE_ENCAP_LIMIT, &encap_limit, 1); -- addattr_l(n, 1024, IFLA_GRE_FLOWINFO, &flowinfo, 4); -- addattr32(n, 1024, IFLA_GRE_FLAGS, flags); -- -- addattr16(n, 1024, IFLA_GRE_ENCAP_TYPE, encaptype); -- addattr16(n, 1024, IFLA_GRE_ENCAP_FLAGS, encapflags); -- addattr16(n, 1024, IFLA_GRE_ENCAP_SPORT, htons(encapsport)); -- addattr16(n, 1024, IFLA_GRE_ENCAP_DPORT, htons(encapdport)); -+ if (!metadata) { -+ addattr32(n, 1024, IFLA_GRE_IKEY, ikey); -+ addattr32(n, 1024, IFLA_GRE_OKEY, okey); -+ addattr_l(n, 1024, IFLA_GRE_IFLAGS, &iflags, 2); -+ addattr_l(n, 1024, IFLA_GRE_OFLAGS, &oflags, 2); -+ addattr_l(n, 1024, IFLA_GRE_LOCAL, &laddr, sizeof(laddr)); -+ addattr_l(n, 1024, IFLA_GRE_REMOTE, &raddr, sizeof(raddr)); -+ if (link) -+ addattr32(n, 1024, IFLA_GRE_LINK, link); -+ addattr_l(n, 1024, IFLA_GRE_TTL, &hop_limit, 1); -+ addattr_l(n, 1024, IFLA_GRE_ENCAP_LIMIT, &encap_limit, 1); -+ addattr_l(n, 1024, IFLA_GRE_FLOWINFO, &flowinfo, 4); -+ addattr32(n, 1024, IFLA_GRE_FLAGS, flags); -+ -+ addattr16(n, 1024, IFLA_GRE_ENCAP_TYPE, encaptype); -+ addattr16(n, 1024, IFLA_GRE_ENCAP_FLAGS, encapflags); -+ addattr16(n, 1024, IFLA_GRE_ENCAP_SPORT, htons(encapsport)); -+ addattr16(n, 1024, IFLA_GRE_ENCAP_DPORT, htons(encapdport)); -+ } else { -+ addattr_l(n, 1024, IFLA_GRE_COLLECT_METADATA, NULL, 0); -+ } - - return 0; - } -@@ -385,6 +395,11 @@ static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) - if (!tb) - return; - -+ if (tb[IFLA_GRE_COLLECT_METADATA]) { -+ fprintf(f, "external"); -+ return; -+ } -+ - if (tb[IFLA_GRE_FLAGS]) - flags = rta_getattr_u32(tb[IFLA_GRE_FLAGS]); - -diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in -index 8be5d5e1e9fd6..612bd8ce92696 100644 ---- a/man/man8/ip-link.8.in -+++ b/man/man8/ip-link.8.in -@@ -877,6 +877,8 @@ the following additional arguments are supported: - .BI "dscp inherit" - ] [ - .BI dev " PHYS_DEV " -+] [ -+.RB external - ] - - .in +8 -@@ -958,6 +960,21 @@ or - .IR 00 ".." ff - when tunneling non-IP packets. The default value is 00. - -+.sp -+.RB external -+- make this tunnel externally controlled (or not, which is the default). -+In the kernel, this is referred to as collect metadata mode. This flag is -+mutually exclusive with the -+.BR remote , -+.BR local , -+.BR seq , -+.BR key, -+.BR csum, -+.BR hoplimit, -+.BR encaplimit, -+.BR flowlabel " and " tclass -+options. -+ - .in -8 - - .TP --- -2.21.0 - diff --git a/SOURCES/0141-tc_util-Silence-spurious-compiler-warning.patch b/SOURCES/0141-tc_util-Silence-spurious-compiler-warning.patch deleted file mode 100644 index 962a81c..0000000 --- a/SOURCES/0141-tc_util-Silence-spurious-compiler-warning.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 774b1c35d4515434e979d9090960ad3293bfe12e Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Wed, 5 Jun 2019 13:18:27 +0200 -Subject: [PATCH] tc_util: Silence spurious compiler warning - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1714660 -Upstream Status: iproute2.git commit 66942e522e54d - -commit 66942e522e54d9f96153590b7c1c7830b8f73f5c -Author: Phil Sutter -Date: Wed Nov 15 15:01:31 2017 +0100 - - tc_util: Silence spurious compiler warning - - GCC version 7.2.1 complains that 'result1' may be used uninitialized in - parse_action_control_slash_spaces(). This should not be possible in - practice, so the actual value 'result1' is initialized with does not - matter. - - Signed-off-by: Phil Sutter ---- - tc/tc_util.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tc/tc_util.c b/tc/tc_util.c -index 65695ea592ed8..e115e5a70e3a1 100644 ---- a/tc/tc_util.c -+++ b/tc/tc_util.c -@@ -556,7 +556,7 @@ static int parse_action_control_slash_spaces(int *argc_p, char ***argv_p, - { - int argc = *argc_p; - char **argv = *argv_p; -- int result1, result2; -+ int result1 = -1, result2; - int *result_p = &result1; - int ok = 0; - int ret; --- -2.21.0 - diff --git a/SOURCES/0142-ss-use-for-any-address-any-family-sockets.patch b/SOURCES/0142-ss-use-for-any-address-any-family-sockets.patch deleted file mode 100644 index 83316f4..0000000 --- a/SOURCES/0142-ss-use-for-any-address-any-family-sockets.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 6837e43a9fb249e83a55a88e0523b3fab6db4dc6 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Wed, 12 Jun 2019 15:00:33 +0200 -Subject: [PATCH] ss: use [::] for any address/any family sockets - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1588122 -Upstream Status: RHEL-only - -commit d981824803999a339f4b8fb9ad36d9d5990d9eab -Author: Andrea Claudi -Date: Wed Jun 12 14:49:07 2019 +0200 - - ss: use [::] for any address/any family sockets - - commit aba9c23a6e1cb ("ss: enclose IPv6 address in brackets") - brings in the unintended side effect of showing as "*" sockets - listening to any address in any family. This is consistent with - upstream iproute and RHEL 8 iproute version, but not with - previous versions of RHEL 7 iproute. - - This commit partially reverts aba9c23a6e1cb using "[::]" for - any family sockets when -f inet6 is used. - - Tested with - # ss -ln -f inet6 ---- - misc/ss.c | 29 ++++++++++++----------------- - 1 file changed, 12 insertions(+), 17 deletions(-) - -diff --git a/misc/ss.c b/misc/ss.c -index 6aaae1b5390e4..8f184fb929d31 100644 ---- a/misc/ss.c -+++ b/misc/ss.c -@@ -1090,25 +1090,20 @@ static void inet_addr_print(const inet_prefix *a, int port, unsigned int ifindex - ap = format_host(AF_INET, 4, a->data); - } - } else { -- if (!memcmp(a->data, &in6addr_any, sizeof(in6addr_any))) { -- buf[0] = '*'; -- buf[1] = 0; -- } else { -- ap = format_host(a->family, 16, a->data); -- -- /* Numeric IPv6 addresses should be bracketed */ -- if (strchr(ap, ':')) { -- snprintf(buf, sizeof(buf), -- "[%s]", ap); -- ap = buf; -- } -+ ap = format_host(a->family, 16, a->data); - -- est_len = strlen(ap); -- if (est_len <= addr_width) -- est_len = addr_width; -- else -- est_len = addr_width + ((est_len-addr_width+3)/4)*4; -+ /* Numeric IPv6 addresses should be bracketed */ -+ if (strchr(ap, ':')) { -+ snprintf(buf, sizeof(buf), -+ "[%s]", ap); -+ ap = buf; - } -+ -+ est_len = strlen(ap); -+ if (est_len <= addr_width) -+ est_len = addr_width; -+ else -+ est_len = addr_width + ((est_len-addr_width+3)/4)*4; - } - - if (ifindex) { --- -2.21.0 - diff --git a/SOURCES/0143-tc-introduce-tc_qdisc_block_exists-helper.patch b/SOURCES/0143-tc-introduce-tc_qdisc_block_exists-helper.patch deleted file mode 100644 index 4814dc8..0000000 --- a/SOURCES/0143-tc-introduce-tc_qdisc_block_exists-helper.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 2e2ac620670997b59d65a73b0af3e77431be3c18 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Tue, 18 Jun 2019 20:01:45 +0200 -Subject: [PATCH] tc: introduce tc_qdisc_block_exists helper - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1721291 -Upstream Status: iproute2.git commit d0bcedd549566 -Conflicts: context change due to missing commit 6f7df6b2a1fef - ("tc: Optimize gact action lookup") - -commit d0bcedd549566a87354aa804df3be6be80681ee9 -Author: Jiri Pirko -Date: Sat Jan 20 11:00:27 2018 +0100 - - tc: introduce tc_qdisc_block_exists helper - - This hepler used qdisc dump to list all qdisc and find if block index in - question is used by any of them. That means the block with specified - index exists. - - Signed-off-by: Jiri Pirko - Signed-off-by: David Ahern ---- - tc/tc_qdisc.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++ - tc/tc_util.h | 2 ++ - 2 files changed, 63 insertions(+) - -diff --git a/tc/tc_qdisc.c b/tc/tc_qdisc.c -index 8b0c5c72dbad1..f8e06ccf205a0 100644 ---- a/tc/tc_qdisc.c -+++ b/tc/tc_qdisc.c -@@ -366,3 +366,64 @@ int do_qdisc(int argc, char **argv) - fprintf(stderr, "Command \"%s\" is unknown, try \"tc qdisc help\".\n", *argv); - return -1; - } -+ -+struct tc_qdisc_block_exists_ctx { -+ __u32 block_index; -+ bool found; -+}; -+ -+static int tc_qdisc_block_exists_cb(const struct sockaddr_nl *who, -+ struct nlmsghdr *n, void *arg) -+{ -+ struct tc_qdisc_block_exists_ctx *ctx = arg; -+ struct tcmsg *t = NLMSG_DATA(n); -+ struct rtattr *tb[TCA_MAX+1]; -+ int len = n->nlmsg_len; -+ -+ if (n->nlmsg_type != RTM_NEWQDISC) -+ return 0; -+ -+ len -= NLMSG_LENGTH(sizeof(*t)); -+ if (len < 0) -+ return -1; -+ -+ parse_rtattr(tb, TCA_MAX, TCA_RTA(t), len); -+ -+ if (tb[TCA_KIND] == NULL) -+ return -1; -+ -+ if (tb[TCA_INGRESS_BLOCK] && -+ RTA_PAYLOAD(tb[TCA_INGRESS_BLOCK]) >= sizeof(__u32)) { -+ __u32 block = rta_getattr_u32(tb[TCA_INGRESS_BLOCK]); -+ -+ if (block == ctx->block_index) -+ ctx->found = true; -+ } -+ -+ if (tb[TCA_EGRESS_BLOCK] && -+ RTA_PAYLOAD(tb[TCA_EGRESS_BLOCK]) >= sizeof(__u32)) { -+ __u32 block = rta_getattr_u32(tb[TCA_EGRESS_BLOCK]); -+ -+ if (block == ctx->block_index) -+ ctx->found = true; -+ } -+ return 0; -+} -+ -+bool tc_qdisc_block_exists(__u32 block_index) -+{ -+ struct tc_qdisc_block_exists_ctx ctx = { .block_index = block_index }; -+ struct tcmsg t = { .tcm_family = AF_UNSPEC }; -+ -+ if (rtnl_dump_request(&rth, RTM_GETQDISC, &t, sizeof(t)) < 0) { -+ perror("Cannot send dump request"); -+ return false; -+ } -+ -+ if (rtnl_dump_filter(&rth, tc_qdisc_block_exists_cb, &ctx) < 0) { -+ perror("Dump terminated\n"); -+ return false; -+ } -+ -+ return ctx.found; -+} -diff --git a/tc/tc_util.h b/tc/tc_util.h -index 5c54ad384eae6..8344c11833ee8 100644 ---- a/tc/tc_util.h -+++ b/tc/tc_util.h -@@ -122,4 +122,6 @@ int prio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt); - int cls_names_init(char *path); - void cls_names_uninit(void); - -+bool tc_qdisc_block_exists(__u32 block_index); -+ - #endif --- -2.21.0 - diff --git a/SOURCES/0144-tc_filter-resolve-device-name-before-parsing-filter.patch b/SOURCES/0144-tc_filter-resolve-device-name-before-parsing-filter.patch deleted file mode 100644 index 413f461..0000000 --- a/SOURCES/0144-tc_filter-resolve-device-name-before-parsing-filter.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 83b78ff645260a51ff5d643169009faeb3032d3c Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Tue, 18 Jun 2019 20:02:54 +0200 -Subject: [PATCH] tc_filter: resolve device name before parsing filter - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1721291 -Upstream Status: iproute2.git commit 01ea76b1cf545 - -commit 01ea76b1cf54516c71a9a54fba672410ada2cccb -Author: Jakub Kicinski -Date: Thu Nov 23 18:12:06 2017 -0800 - - tc_filter: resolve device name before parsing filter - - Move resolving device name into an ifindex before calling filter - specific callbacks. This way if filters need the ifindex, they - can read it from the request. - - Signed-off-by: Jakub Kicinski - Reviewed-by: Quentin Monnet - Acked-by: Daniel Borkmann ---- - tc/tc_filter.c | 50 ++++++++++++++++++++++++-------------------------- - 1 file changed, 24 insertions(+), 26 deletions(-) - -diff --git a/tc/tc_filter.c b/tc/tc_filter.c -index 8dbebf1ffa32a..e479039159df6 100644 ---- a/tc/tc_filter.c -+++ b/tc/tc_filter.c -@@ -161,6 +161,16 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv) - if (k[0]) - addattr_l(&req.n, sizeof(req), TCA_KIND, k, strlen(k)+1); - -+ if (d[0]) { -+ ll_init_map(&rth); -+ -+ req.t.tcm_ifindex = ll_name_to_index(d); -+ if (req.t.tcm_ifindex == 0) { -+ fprintf(stderr, "Cannot find device \"%s\"\n", d); -+ return 1; -+ } -+ } -+ - if (q) { - if (q->parse_fopt(q, fhandle, argc, argv, &req.n)) - return 1; -@@ -183,17 +193,6 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv) - if (est.ewma_log) - addattr_l(&req.n, sizeof(req), TCA_RATE, &est, sizeof(est)); - -- -- if (d[0]) { -- ll_init_map(&rth); -- -- req.t.tcm_ifindex = ll_name_to_index(d); -- if (req.t.tcm_ifindex == 0) { -- fprintf(stderr, "Cannot find device \"%s\"\n", d); -- return 1; -- } -- } -- - if (rtnl_talk(&rth, &req.n, NULL) < 0) { - fprintf(stderr, "We have an error talking to the kernel\n"); - return 2; -@@ -453,10 +452,23 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv) - return -1; - } - -+ if (d[0]) { -+ ll_init_map(&rth); -+ -+ req.t.tcm_ifindex = ll_name_to_index(d); -+ if (req.t.tcm_ifindex == 0) { -+ fprintf(stderr, "Cannot find device \"%s\"\n", d); -+ return 1; -+ } -+ filter_ifindex = req.t.tcm_ifindex; -+ } else { -+ fprintf(stderr, "Must specify netdevice \"dev\"\n"); -+ return -1; -+ } -+ - if (q->parse_fopt(q, fhandle, argc, argv, &req.n)) - return 1; - -- - if (!fhandle) { - fprintf(stderr, "Must specify filter \"handle\"\n"); - return -1; -@@ -471,20 +483,6 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv) - return -1; - } - -- if (d[0]) { -- ll_init_map(&rth); -- -- req.t.tcm_ifindex = ll_name_to_index(d); -- if (req.t.tcm_ifindex == 0) { -- fprintf(stderr, "Cannot find device \"%s\"\n", d); -- return 1; -- } -- filter_ifindex = req.t.tcm_ifindex; -- } else { -- fprintf(stderr, "Must specify netdevice \"dev\"\n"); -- return -1; -- } -- - if (rtnl_talk(&rth, &req.n, &answer) < 0) { - fprintf(stderr, "We have an error talking to the kernel\n"); - return 2; --- -2.21.0 - diff --git a/SOURCES/0145-tc-introduce-support-for-block-handle-for-filter-ope.patch b/SOURCES/0145-tc-introduce-support-for-block-handle-for-filter-ope.patch deleted file mode 100644 index 51eb874..0000000 --- a/SOURCES/0145-tc-introduce-support-for-block-handle-for-filter-ope.patch +++ /dev/null @@ -1,269 +0,0 @@ -From 13e1ae7b588c723091f81538bb5834b274f0b0c7 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Tue, 18 Jun 2019 20:02:54 +0200 -Subject: [PATCH] tc: introduce support for block-handle for filter operations - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1721291 -Upstream Status: iproute2.git commit 0c7cef9669a82 -Conflicts: context change due to missing commit 485d0c6001c4a - ("tc: Add batchsize feature for filter and actions"), - also adjust code to use fprintf instead of print_string - due to missing commit 249284ff5a44a ("tc: jsonify filter core") - -commit 0c7cef9669a82d4ad0438922f7ce57c18100d6b8 -Author: Jiri Pirko -Date: Sat Jan 20 11:00:28 2018 +0100 - - tc: introduce support for block-handle for filter operations - - So far, qdisc was the only handle that could be used to manipulate - filters. Kernel added support for using block to manipulate it. So add - the support to use block index to manipulate filters. The magic - TCM_IFINDEX_MAGIC_BLOCK indicates the block index is in use. - - Signed-off-by: Jiri Pirko - Signed-off-by: David Ahern ---- - man/man8/tc.8 | 18 +++++++++ - tc/tc_filter.c | 102 +++++++++++++++++++++++++++++++++++++++++-------- - 2 files changed, 104 insertions(+), 16 deletions(-) - -diff --git a/man/man8/tc.8 b/man/man8/tc.8 -index a341a8f995f85..c493ccfa7c900 100644 ---- a/man/man8/tc.8 -+++ b/man/man8/tc.8 -@@ -41,6 +41,19 @@ tc \- show / manipulate traffic control settings - .B flowid - \fIflow-id\fR - -+.B tc -+.RI "[ " OPTIONS " ]" -+.B filter [ add | change | replace | delete | get ] block -+\fIBLOCK_INDEX\fR -+.B [ handle \fIfilter-id\fR ] -+.B protocol -+\fIprotocol\fR -+.B prio -+\fIpriority\fR filtertype -+[ filtertype specific parameters ] -+.B flowid -+\fIflow-id\fR -+ - .B tc - .RI "[ " OPTIONS " ]" - .RI "[ " FORMAT " ]" -@@ -58,6 +71,11 @@ tc \- show / manipulate traffic control settings - .RI "[ " OPTIONS " ]" - .B filter show dev - \fIDEV\fR -+.P -+.B tc -+.RI "[ " OPTIONS " ]" -+.B filter show block -+\fIBLOCK_INDEX\fR - - .P - .ti 8 -diff --git a/tc/tc_filter.c b/tc/tc_filter.c -index e479039159df6..5676ed3a74383 100644 ---- a/tc/tc_filter.c -+++ b/tc/tc_filter.c -@@ -29,14 +29,17 @@ - static void usage(void) - { - fprintf(stderr, -- "Usage: tc filter [ add | del | change | replace | show ] dev STRING\n" -- "Usage: tc filter get dev STRING parent CLASSID protocol PROTO handle FILTERID pref PRIO FILTER_TYPE\n" -+ "Usage: tc filter [ add | del | change | replace | show ] [ dev STRING ]\n" -+ " tc filter [ add | del | change | replace | show ] [ block BLOCK_INDEX ]\n" -+ " tc filter get dev STRING parent CLASSID protocol PROTO handle FILTERID pref PRIO FILTER_TYPE\n" -+ " tc filter get block BLOCK_INDEX protocol PROTO handle FILTERID pref PRIO FILTER_TYPE\n" - " [ pref PRIO ] protocol PROTO [ chain CHAIN_INDEX ]\n" - " [ estimator INTERVAL TIME_CONSTANT ]\n" - " [ root | ingress | egress | parent CLASSID ]\n" - " [ handle FILTERID ] [ [ FILTER_TYPE ] [ help | OPTIONS ] ]\n" - "\n" - " tc filter show [ dev STRING ] [ root | ingress | egress | parent CLASSID ]\n" -+ " tc filter show [ block BLOCK_INDEX ]\n" - "Where:\n" - "FILTER_TYPE := { rsvp | u32 | bpf | fw | route | etc. }\n" - "FILTERID := ... format depends on classifier, see there\n" -@@ -61,6 +64,7 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv) - int protocol_set = 0; - __u32 chain_index; - int chain_index_set = 0; -+ __u32 block_index = 0; - char *fhandle = NULL; - char d[16] = {}; - char k[16] = {}; -@@ -74,7 +78,21 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv) - NEXT_ARG(); - if (d[0]) - duparg("dev", *argv); -+ if (block_index) { -+ fprintf(stderr, "Error: \"dev\" and \"block\" are mutually exlusive\n"); -+ return -1; -+ } - strncpy(d, *argv, sizeof(d)-1); -+ } else if (matches(*argv, "block") == 0) { -+ NEXT_ARG(); -+ if (block_index) -+ duparg("block", *argv); -+ if (d[0]) { -+ fprintf(stderr, "Error: \"dev\" and \"block\" are mutually exlusive\n"); -+ return -1; -+ } -+ if (get_u32(&block_index, *argv, 0) || !block_index) -+ invarg("invalid block index value", *argv); - } else if (strcmp(*argv, "root") == 0) { - if (req.t.tcm_parent) { - fprintf(stderr, -@@ -169,6 +187,9 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv) - fprintf(stderr, "Cannot find device \"%s\"\n", d); - return 1; - } -+ } else if (block_index) { -+ req.t.tcm_ifindex = TCM_IFINDEX_MAGIC_BLOCK; -+ req.t.tcm_block_index = block_index; - } - - if (q) { -@@ -207,6 +228,7 @@ static __u32 filter_prio; - static __u32 filter_protocol; - static __u32 filter_chain_index; - static int filter_chain_index_set; -+static __u32 filter_block_index; - __u16 f_proto; - - int print_filter(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) -@@ -251,19 +273,25 @@ int print_filter(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) - fprintf(fp, "added "); - - fprintf(fp, "filter "); -- if (!filter_ifindex || filter_ifindex != t->tcm_ifindex) -- fprintf(fp, "dev %s ", ll_index_to_name(t->tcm_ifindex)); -- -- if (!filter_parent || filter_parent != t->tcm_parent) { -- if (t->tcm_parent == TC_H_ROOT) -- fprintf(fp, "root "); -- else if (t->tcm_parent == TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_INGRESS)) -- fprintf(fp, "ingress "); -- else if (t->tcm_parent == TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_EGRESS)) -- fprintf(fp, "egress "); -- else { -- print_tc_classid(abuf, sizeof(abuf), t->tcm_parent); -- fprintf(fp, "parent %s ", abuf); -+ if (t->tcm_ifindex == TCM_IFINDEX_MAGIC_BLOCK) { -+ if (!filter_block_index || -+ filter_block_index != t->tcm_block_index) -+ fprintf(fp, "block %u ", t->tcm_block_index); -+ } else { -+ if (!filter_ifindex || filter_ifindex != t->tcm_ifindex) -+ fprintf(fp, "dev %s ", ll_index_to_name(t->tcm_ifindex)); -+ -+ if (!filter_parent || filter_parent != t->tcm_parent) { -+ if (t->tcm_parent == TC_H_ROOT) -+ fprintf(fp, "root "); -+ else if (t->tcm_parent == TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_INGRESS)) -+ fprintf(fp, "ingress "); -+ else if (t->tcm_parent == TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_EGRESS)) -+ fprintf(fp, "egress "); -+ else { -+ print_tc_classid(abuf, sizeof(abuf), t->tcm_parent); -+ fprintf(fp, "parent %s ", abuf); -+ } - } - } - -@@ -337,6 +365,7 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv) - int protocol_set = 0; - __u32 chain_index; - int chain_index_set = 0; -+ __u32 block_index = 0; - __u32 parent_handle = 0; - char *fhandle = NULL; - char d[16] = {}; -@@ -347,7 +376,21 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv) - NEXT_ARG(); - if (d[0]) - duparg("dev", *argv); -+ if (block_index) { -+ fprintf(stderr, "Error: \"dev\" and \"block\" are mutually exlusive\n"); -+ return -1; -+ } - strncpy(d, *argv, sizeof(d)-1); -+ } else if (matches(*argv, "block") == 0) { -+ NEXT_ARG(); -+ if (block_index) -+ duparg("block", *argv); -+ if (d[0]) { -+ fprintf(stderr, "Error: \"dev\" and \"block\" are mutually exlusive\n"); -+ return -1; -+ } -+ if (get_u32(&block_index, *argv, 0) || !block_index) -+ invarg("invalid block index value", *argv); - } else if (strcmp(*argv, "root") == 0) { - if (req.t.tcm_parent) { - fprintf(stderr, -@@ -461,8 +504,12 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv) - return 1; - } - filter_ifindex = req.t.tcm_ifindex; -+ } else if (block_index) { -+ req.t.tcm_ifindex = TCM_IFINDEX_MAGIC_BLOCK; -+ req.t.tcm_block_index = block_index; -+ filter_block_index = block_index; - } else { -- fprintf(stderr, "Must specify netdevice \"dev\"\n"); -+ fprintf(stderr, "Must specify netdevice \"dev\" or block index \"block\"\n"); - return -1; - } - -@@ -510,6 +557,7 @@ static int tc_filter_list(int argc, char **argv) - __u32 prio = 0; - __u32 protocol = 0; - __u32 chain_index; -+ __u32 block_index = 0; - char *fhandle = NULL; - - while (argc > 0) { -@@ -517,7 +565,21 @@ static int tc_filter_list(int argc, char **argv) - NEXT_ARG(); - if (d[0]) - duparg("dev", *argv); -+ if (block_index) { -+ fprintf(stderr, "Error: \"dev\" cannot be used in the same time as \"block\"\n"); -+ return -1; -+ } - strncpy(d, *argv, sizeof(d)-1); -+ } else if (matches(*argv, "block") == 0) { -+ NEXT_ARG(); -+ if (block_index) -+ duparg("block", *argv); -+ if (d[0]) { -+ fprintf(stderr, "Error: \"block\" cannot be used in the same time as \"dev\"\n"); -+ return -1; -+ } -+ if (get_u32(&block_index, *argv, 0) || !block_index) -+ invarg("invalid block index value", *argv); - } else if (strcmp(*argv, "root") == 0) { - if (req.t.tcm_parent) { - fprintf(stderr, -@@ -606,6 +668,14 @@ static int tc_filter_list(int argc, char **argv) - return 1; - } - filter_ifindex = req.t.tcm_ifindex; -+ } else if (block_index) { -+ if (!tc_qdisc_block_exists(block_index)) { -+ fprintf(stderr, "Cannot find block \"%u\"\n", block_index); -+ return 1; -+ } -+ req.t.tcm_ifindex = TCM_IFINDEX_MAGIC_BLOCK; -+ req.t.tcm_block_index = block_index; -+ filter_block_index = block_index; - } - - if (filter_chain_index_set) --- -2.21.0 - diff --git a/SOURCES/0146-tc-implement-ingress-egress-block-index-attributes-f.patch b/SOURCES/0146-tc-implement-ingress-egress-block-index-attributes-f.patch deleted file mode 100644 index 52f91ca..0000000 --- a/SOURCES/0146-tc-implement-ingress-egress-block-index-attributes-f.patch +++ /dev/null @@ -1,121 +0,0 @@ -From f38f33f8693ed7a4f883b18862e47f822ff8a62d Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Tue, 18 Jun 2019 20:04:42 +0200 -Subject: [PATCH] tc: implement ingress/egress block index attributes for - qdiscs - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1721291 -Upstream Status: iproute2.git commit 063463efd7f0d -Conflicts: adjust the code to make it compile due to missing - commit c91d262f414d2 ("tc: jsonify qdisc core") - -commit 063463efd7f0d91b7372b089a7b7aff7fc9ac0f6 -Author: Jiri Pirko -Date: Sat Jan 20 11:00:29 2018 +0100 - - tc: implement ingress/egress block index attributes for qdiscs - - During qdisc creation it is possible to specify shared block for bot - ingress and egress. Pass this values to kernel according to the command - line options. - - Signed-off-by: Jiri Pirko - Signed-off-by: David Ahern ---- - man/man8/tc.8 | 6 +++++- - tc/tc_qdisc.c | 34 ++++++++++++++++++++++++++++++++++ - 2 files changed, 39 insertions(+), 1 deletion(-) - -diff --git a/man/man8/tc.8 b/man/man8/tc.8 -index c493ccfa7c900..c89a7a8ecf83b 100644 ---- a/man/man8/tc.8 -+++ b/man/man8/tc.8 -@@ -11,7 +11,11 @@ tc \- show / manipulate traffic control settings - \fIqdisc-id\fR - .B | root ] - .B [ handle --\fIqdisc-id\fR ] qdisc -+\fIqdisc-id\fR ] -+.B [ ingress_block -+\fIBLOCK_INDEX\fR ] -+.B [ egress_block -+\fIBLOCK_INDEX\fR ] qdisc - [ qdisc specific parameters ] - .P - -diff --git a/tc/tc_qdisc.c b/tc/tc_qdisc.c -index f8e06ccf205a0..26d23f43007ae 100644 ---- a/tc/tc_qdisc.c -+++ b/tc/tc_qdisc.c -@@ -32,6 +32,7 @@ static int usage(void) - fprintf(stderr, " [ handle QHANDLE ] [ root | ingress | clsact | parent CLASSID ]\n"); - fprintf(stderr, " [ estimator INTERVAL TIME_CONSTANT ]\n"); - fprintf(stderr, " [ stab [ help | STAB_OPTIONS] ]\n"); -+ fprintf(stderr, " [ ingress_block BLOCK_INDEX ] [ egress_block BLOCK_INDEX ]\n"); - fprintf(stderr, " [ [ QDISC_KIND ] [ help | OPTIONS ] ]\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " tc qdisc show [ dev STRING ] [ ingress | clsact ]\n"); -@@ -62,6 +63,8 @@ static int tc_qdisc_modify(int cmd, unsigned int flags, int argc, char **argv) - .n.nlmsg_type = cmd, - .t.tcm_family = AF_UNSPEC, - }; -+ __u32 ingress_block = 0; -+ __u32 egress_block = 0; - - while (argc > 0) { - if (strcmp(*argv, "dev") == 0) { -@@ -122,6 +125,14 @@ static int tc_qdisc_modify(int cmd, unsigned int flags, int argc, char **argv) - if (parse_size_table(&argc, &argv, &stab.szopts) < 0) - return -1; - continue; -+ } else if (matches(*argv, "ingress_block") == 0) { -+ NEXT_ARG(); -+ if (get_u32(&ingress_block, *argv, 0) || !ingress_block) -+ invarg("invalid ingress block index value", *argv); -+ } else if (matches(*argv, "egress_block") == 0) { -+ NEXT_ARG(); -+ if (get_u32(&egress_block, *argv, 0) || !egress_block) -+ invarg("invalid egress block index value", *argv); - } else if (matches(*argv, "help") == 0) { - usage(); - } else { -@@ -139,6 +150,13 @@ static int tc_qdisc_modify(int cmd, unsigned int flags, int argc, char **argv) - if (est.ewma_log) - addattr_l(&req.n, sizeof(req), TCA_RATE, &est, sizeof(est)); - -+ if (ingress_block) -+ addattr32(&req.n, sizeof(req), -+ TCA_INGRESS_BLOCK, ingress_block); -+ if (egress_block) -+ addattr32(&req.n, sizeof(req), -+ TCA_EGRESS_BLOCK, egress_block); -+ - if (q) { - if (q->parse_qopt) { - if (q->parse_qopt(q, argc, argv, &req.n)) -@@ -252,6 +270,22 @@ int print_qdisc(const struct sockaddr_nl *who, - if (t->tcm_info != 1) - fprintf(fp, "refcnt %d ", t->tcm_info); - -+ if (tb[TCA_INGRESS_BLOCK] && -+ RTA_PAYLOAD(tb[TCA_INGRESS_BLOCK]) >= sizeof(__u32)) { -+ __u32 block = rta_getattr_u32(tb[TCA_INGRESS_BLOCK]); -+ -+ if (block) -+ fprintf(fp, "ingress_block %u ", block); -+ } -+ -+ if (tb[TCA_EGRESS_BLOCK] && -+ RTA_PAYLOAD(tb[TCA_EGRESS_BLOCK]) >= sizeof(__u32)) { -+ __u32 block = rta_getattr_u32(tb[TCA_EGRESS_BLOCK]); -+ -+ if (block) -+ fprintf(fp, "egress_block %u ", block); -+ } -+ - /* pfifo_fast is generic enough to warrant the hardcoding --JHS */ - if (strcmp("pfifo_fast", RTA_DATA(tb[TCA_KIND])) == 0) - q = get_qdisc_kind("prio"); --- -2.21.0 - diff --git a/SOURCES/0147-netns-make-var-run-netns-bind-mount-recursive.patch b/SOURCES/0147-netns-make-var-run-netns-bind-mount-recursive.patch deleted file mode 100644 index 0001595..0000000 --- a/SOURCES/0147-netns-make-var-run-netns-bind-mount-recursive.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 1e13fc4c604f91c5d38b889824e2dfee1bd17c34 Mon Sep 17 00:00:00 2001 -From: Andrea Claudi -Date: Fri, 15 Nov 2019 12:02:31 +0100 -Subject: [PATCH] netns: make /var/run/netns bind-mount recursive - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1772827 -Upstream Status: iproute2.git commit d6a4076b6ba65 - -commit d6a4076b6ba6547d7e52c377a7c58c56eb5ea16e -Author: Casey Callendrello -Date: Tue Aug 1 17:46:09 2017 +0200 - - netns: make /var/run/netns bind-mount recursive - - When ip netns {add|delete} is first run, it bind-mounts /var/run/netns - on top of itself, then marks it as shared. However, if there are already - bind-mounts in the directory from other tools, these would not be - propagated. Fix this by recursively bind-mounting. - - Signed-off-by: Casey Callendrello - Acked-by: "Eric W. Biederman" ---- - ip/ipnetns.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ip/ipnetns.c b/ip/ipnetns.c -index 427b59c57381d..c8e22e9b6e952 100644 ---- a/ip/ipnetns.c -+++ b/ip/ipnetns.c -@@ -640,7 +640,7 @@ static int netns_add(int argc, char **argv) - } - - /* Upgrade NETNS_RUN_DIR to a mount point */ -- if (mount(NETNS_RUN_DIR, NETNS_RUN_DIR, "none", MS_BIND, NULL)) { -+ if (mount(NETNS_RUN_DIR, NETNS_RUN_DIR, "none", MS_BIND | MS_REC, NULL)) { - fprintf(stderr, "mount --bind %s %s failed: %s\n", - NETNS_RUN_DIR, NETNS_RUN_DIR, strerror(errno)); - return -1; --- -2.21.0 - diff --git a/SPECS/iproute.spec b/SPECS/iproute.spec index b31917a..ee418f1 100644 --- a/SPECS/iproute.spec +++ b/SPECS/iproute.spec @@ -1,8 +1,8 @@ %global cbq_version v0.7.3 %define rpmversion 4.11.0 -%define baserelease 0.el7 -%define specrelease 25%{?dist}.2 +%define baserelease 25.el7 +%define specrelease 30%{?dist} %define pkg_release %{specrelease}%{?buildid} Summary: Advanced IP routing and network device configuration tools @@ -15,153 +15,19 @@ Source0: %{name}-%{rpmversion}-%{baserelease}.tar.xz Source1: cbq-0000.example Source2: avpkt Source3: rt_dsfield.deprecated -Patch0: 0001-Confirm-success-for-each-tc-batch-command.patch -Patch1: 0002-Really-fix-get_addr-and-get_prefix-error-messages.patch -Patch2: 0003-tc-simple-Fix-documentation.patch -Patch3: 0004-tc-fix-m_simple-usage.patch -Patch4: 0005-bpf-Make-bytecode-file-reading-a-little-more-robust.patch -Patch5: 0006-ss-Fix-for-added-diag-support-check.patch -Patch6: 0007-tc-simple.8-Fix-reference-to-non-existing-tc-actions.patch -Patch7: 0008-lib-bpf-Fix-bytecode-file-parsing.patch -Patch8: 0009-tc-simple.8-Fix-one-more-reference-to-non-existing-t.patch -Patch9: 0010-tc-m_xt-Prevent-a-segfault-in-libipt.patch -Patch10: 0011-link_gre6-really-support-encaplimit-option.patch -Patch11: 0012-tc-fix-typo-in-manpage.patch -Patch12: 0013-ip-neigh-allow-flush-FAILED-neighbour-entry.patch -Patch13: 0014-netns-avoid-directory-traversal.patch -Patch14: 0015-utils-return-default-family-when-rtm_family-is-not-R.patch -Patch15: 0016-link_gre6-Fix-for-changing-tclass-flowlabel.patch -Patch16: 0017-netlink-Change-rtnl_dump_done-to-always-show-error.patch -Patch17: 0018-libnetlink-drop-unused-parameter-to-rtnl_dump_done.patch -Patch18: 0019-iproute-Add-support-for-extended-ack-to-rtnl_talk.patch -Patch19: 0020-iplink-check-for-message-truncation-in-iplink_get.patch -Patch20: 0021-iplink-double-the-buffer-size-also-in-iplink_get.patch -Patch21: 0022-lib-libnetlink-re-malloc-buff-if-size-is-not-enough.patch -Patch22: 0023-lib-libnetlink-update-rtnl_talk-to-support-malloc-bu.patch -Patch23: 0024-Update-linux-headers.patch -Patch24: 0025-devlink-Change-netlink-attribute-validation.patch -Patch25: 0026-devlink-Add-support-for-pipeline-debug-dpipe.patch -Patch26: 0027-tc-Reflect-HW-offload-status.patch -Patch27: 0028-pedit-Fix-a-typo-in-warning.patch -Patch28: 0029-pedit-Do-not-allow-using-retain-for-too-big-fields.patch -Patch29: 0030-pedit-Check-for-extended-capability-in-protocol-pars.patch -Patch30: 0031-pedit-Introduce-ipv6-support.patch -Patch31: 0032-devlink-Add-option-to-set-and-show-eswitch-encapsula.patch -Patch32: 0033-tc-flower-add-support-for-tcp-flags.patch -Patch33: 0034-iplink-Update-usage-in-help-message.patch -Patch34: 0035-tc-flower-add-support-for-matching-on-ip-tos-and-ttl.patch -Patch35: 0036-iproute-build-more-easily-on-Android.patch -Patch36: 0037-uapi-add-include-linux-vm_sockets_diag.h.patch -Patch37: 0038-ss-allow-AF_FAMILY-constants-32.patch -Patch38: 0039-ss-add-AF_VSOCK-support.patch -Patch39: 0040-link_gre6-Detect-invalid-encaplimit-values.patch -Patch40: 0041-man-tc-csum.8-Fix-inconsistency-in-example-descripti.patch -Patch41: 0042-tc-fix-command-tc-actions-del-hang-issue.patch -Patch42: 0043-ip-link-Fix-use-after-free-in-nl_get_ll_addr_len.patch -Patch43: 0044-tc-m_tunnel_key-reformat-the-usage-text.patch -Patch44: 0045-tc-m_tunnel_key-Allow-key-less-tunnels.patch -Patch45: 0046-tc-include-stdint.h-explicitly-for-UINT16_MAX.patch -Patch46: 0047-Update-kernel-headers.patch -Patch47: 0048-tc-flower-Add-match-on-encapsulating-tos-ttl.patch -Patch48: 0049-tc-act_tunnel_key-Enable-setup-of-tos-and-ttl.patch -Patch49: 0050-iproute-Abort-if-nexthop-cannot-be-parsed.patch -Patch50: 0051-ip-route-Fix-segfault-with-many-nexthops.patch -Patch51: 0052-man-ip-route.8-Document-nexthop-limit.patch -Patch52: 0053-ip-route-Fix-nexthop-encap-parsing.patch -Patch53: 0054-ip-link-Fix-listing-of-alias-interfaces.patch -Patch54: 0055-ip-Add-violation-counters-to-VF-statisctics.patch -Patch55: 0056-devlink-Add-support-for-devlink-resource-abstraction.patch -Patch56: 0057-devlink-Add-support-for-hot-reload.patch -Patch57: 0058-devlink-Update-man-pages-and-add-resource-man.patch -Patch58: 0059-devlink-Add-param-command-support.patch -Patch59: 0060-man-ip-route.8-ssthresh-parameter-is-NUMBER.patch -Patch60: 0061-man-tc-vlan.8-Fix-for-incorrect-example.patch -Patch61: 0062-tc-flower-Add-support-for-QinQ.patch -Patch62: 0063-utils-Move-BIT-macro-to-common-header.patch -Patch63: 0064-lib-make-resolve_hosts-variable-common.patch -Patch64: 0065-json_writer-add-new-json-handlers-null-float-with-fo.patch -Patch65: 0066-rdma-Add-MR-resource-tracking-information.patch -Patch66: 0067-rdma-add-infrastructure-for-RDMA-tool.patch -Patch67: 0068-rdma-add-man-pages-for-RDMA-tool.patch -Patch68: 0069-tc-f_flower-Add-support-for-matching-first-frag-pack.patch -Patch69: 0070-ss-enclose-IPv6-address-in-brackets.patch -Patch70: 0071-ip-address-Use-correct-max-attribute-value-in-print_.patch -Patch71: 0072-examples-Some-shell-fixes-to-cbq.init.patch -Patch72: 0073-ifcfg-Quote-left-hand-side-of-expression.patch -Patch73: 0074-tipc-node-Fix-socket-fd-check-in-cmd_node_get_addr.patch -Patch74: 0075-iproute_lwtunnel-Argument-to-strerror-must-be-positi.patch -Patch75: 0076-iproute_lwtunnel-csum_mode-value-checking-was-ineffe.patch -Patch76: 0077-ss-Don-t-leak-fd-in-tcp_show_netlink_file.patch -Patch77: 0078-tc-em_ipset-Don-t-leak-sockfd-on-error-path.patch -Patch78: 0079-ipvrf-Fix-error-path-of-vrf_switch.patch -Patch79: 0080-ifstat-Fix-memleak-in-error-case.patch -Patch80: 0081-ifstat-Fix-memleak-in-dump_kern_db-for-json-output.patch -Patch81: 0082-ss-Fix-potential-memleak-in-unix_stats_print.patch -Patch82: 0083-tipc-bearer-Fix-resource-leak-in-error-path.patch -Patch83: 0084-devlink-No-need-for-this-self-assignment.patch -Patch84: 0085-ipntable-No-need-to-check-and-assign-to-parms_rta.patch -Patch85: 0086-iproute-Fix-for-missing-Oifs-display.patch -Patch86: 0087-lib-rt_names-Drop-dead-code-in-rtnl_rttable_n2a.patch -Patch87: 0088-ss-Skip-useless-check-in-parse_hostcond.patch -Patch88: 0089-ss-Drop-useless-assignment.patch -Patch89: 0090-tc-m_gact-Drop-dead-code.patch -Patch90: 0091-ipaddress-Avoid-accessing-uninitialized-variable-lcl.patch -Patch91: 0092-iplink_can-Prevent-overstepping-array-bounds.patch -Patch92: 0093-ipmaddr-Avoid-accessing-uninitialized-data.patch -Patch93: 0094-ss-Use-C99-initializer-in-netlink_show_one.patch -Patch94: 0095-netem-maketable-Check-return-value-of-fstat.patch -Patch95: 0096-tc-q_multiq-Don-t-pass-garbage-in-TCA_OPTIONS.patch -Patch96: 0097-iproute-Check-mark-value-input.patch -Patch97: 0098-iplink_vrf-Complain-if-main-table-is-not-found.patch -Patch98: 0099-devlink-Check-return-code-of-strslashrsplit.patch -Patch99: 0100-lib-bpf-Don-t-leak-fp-in-bpf_find_mntpt.patch -Patch100: 0101-ifstat-nstat-Check-fdopen-return-value.patch -Patch101: 0102-tc-q_netem-Don-t-dereference-possibly-NULL-pointer.patch -Patch102: 0103-tc-tc_filter-Make-sure-filter-name-is-not-empty.patch -Patch103: 0104-tipc-bearer-Prevent-NULL-pointer-dereference.patch -Patch104: 0105-ipntable-Avoid-memory-allocation-for-filter.name.patch -Patch105: 0106-lib-fs-Fix-format-string-in-find_fs_mount.patch -Patch106: 0107-lib-inet_proto-Review-inet_proto_-a2n-n2a.patch -Patch107: 0108-lnstat_util-Simplify-alloc_and_open-a-bit.patch -Patch108: 0109-tc-m_xt-Fix-for-potential-string-buffer-overflows.patch -Patch109: 0110-lib-ll_map-Choose-size-of-new-cache-items-at-run-tim.patch -Patch110: 0111-ss-Make-struct-tcpstat-fields-timer-and-timeout-unsi.patch -Patch111: 0112-ss-Make-sure-scanned-index-value-to-unix_state_map-i.patch -Patch112: 0113-netem-maketable-Check-return-value-of-fscanf.patch -Patch113: 0114-lib-bpf-Check-return-value-of-write.patch -Patch114: 0115-lib-fs-Fix-and-simplify-make_path.patch -Patch115: 0116-lib-libnetlink-Don-t-pass-NULL-parameter-to-memcpy.patch -Patch116: 0117-utils-Implement-strlcpy-and-strlcat.patch -Patch117: 0118-Convert-the-obvious-cases-to-strlcpy.patch -Patch118: 0119-Convert-harmful-calls-to-strncpy-to-strlcpy.patch -Patch119: 0120-ipxfrm-Replace-STRBUF_CAT-macro-with-strlcat.patch -Patch120: 0121-tc_util-No-need-to-terminate-an-snprintf-ed-buffer.patch -Patch121: 0122-lnstat_util-Make-sure-buffer-is-NUL-terminated.patch -Patch122: 0123-utils-strlcpy-and-strlcat-don-t-clobber-dst.patch -Patch123: 0124-ip-6-tunnel-Avoid-copying-user-supplied-interface-na.patch -Patch124: 0125-tc-flower-No-need-to-cache-indev-arg.patch -Patch125: 0126-Check-user-supplied-interface-name-lengths.patch -Patch126: 0127-bpf-minor-cleanups-for-bpf_trace_pipe.patch -Patch127: 0128-ip-tunnel-Use-tnl_parse_key-to-parse-tunnel-key.patch -Patch128: 0129-man-ip-link-document-GRE-tunnels.patch -Patch129: 0130-gre-gre6-allow-clearing-i-o-key-seq-csum-flags.patch -Patch130: 0131-tc_filter-add-support-for-chain-index.patch -Patch131: 0132-tc-actions-add-helpers-to-parse-and-print-control-ac.patch -Patch132: 0133-tc-actions-introduce-support-for-goto-chain-action.patch -Patch133: 0134-tc-gact-fix-control-action-parsing.patch -Patch134: 0135-tc-don-t-print-error-message-on-miss-when-parsing-ac.patch -Patch135: 0136-tc-util-Don-t-call-NEXT_ARG_FWD-in-__parse_action_co.patch -Patch136: 0137-tc-fix-parsing-of-the-control-action.patch -Patch137: 0138-m_mirred-don-t-bail-if-the-control-action-is-missing.patch -Patch138: 0139-tc-m_tunnel_key-add-csum-nocsum-option.patch -Patch139: 0140-gre6-add-collect-metadata-support.patch -Patch140: 0141-tc_util-Silence-spurious-compiler-warning.patch -Patch141: 0142-ss-use-for-any-address-any-family-sockets.patch -Patch142: 0143-tc-introduce-tc_qdisc_block_exists-helper.patch -Patch143: 0144-tc_filter-resolve-device-name-before-parsing-filter.patch -Patch144: 0145-tc-introduce-support-for-block-handle-for-filter-ope.patch -Patch145: 0146-tc-implement-ingress-egress-block-index-attributes-f.patch -Patch146: 0147-netns-make-var-run-netns-bind-mount-recursive.patch +Patch0: 0001-netns-make-var-run-netns-bind-mount-recursive.patch +Patch1: 0002-nstat-print-useful-error-messages-in-abort-cases.patch +Patch2: 0003-tc-Add-support-for-the-CBS-qdisc.patch +Patch3: 0004-man-Add-initial-manpage-for-tc-cbs-8.patch +Patch4: 0005-man-Clarify-idleslope-calculation-for-tc-cbs.patch +Patch5: 0006-Update-kernel-headers.patch +Patch6: 0007-uapi-update-bpf-headers.patch +Patch7: 0008-Update-kernel-headers.patch +Patch8: 0009-tc_util-Add-support-for-showing-TCA_STATS_BASIC_HW-s.patch +Patch9: 0010-ss-fix-NULL-pointer-access-when-parsing-unix-sockets.patch +Patch10: 0011-xfrm-not-try-to-delete-ipcomp-states-when-using-dele.patch +Patch11: 0012-xfrm-also-check-for-ipv6-state-in-xfrm_state_keep.patch +Patch12: 0013-tc_util-Fix-format-of-TCA_STATS_BASIC_HW-statistics.patch License: GPLv2+ and Public Domain BuildRequires: bison BuildRequires: flex @@ -274,8 +140,28 @@ cat %{SOURCE3} >>%{buildroot}%{_sysconfdir}/iproute2/rt_dsfield %{_includedir}/iproute2/bpf_elf.h %changelog -* Fri Nov 15 2019 Andrea Claudi [4.11.0-25.el7_7.1] -- netns: make /var/run/netns bind-mount recursive (Andrea Claudi) [1772827] +* Mon Jun 08 2020 Andrea Claudi [4.11.0-30.el7] +- tc_util: Fix format of TCA_STATS_BASIC_HW statistics (Andrea Claudi) [1637437] + +* Thu Apr 30 2020 Andrea Claudi [4.11.0-29.el7] +- xfrm: also check for ipv6 state in xfrm_state_keep (Andrea Claudi) [1828034] + +* Thu Apr 23 2020 Andrea Claudi [4.11.0-28.el7] +- xfrm: not try to delete ipcomp states when using deleteall (Andrea Claudi) [1767328] + +* Wed Apr 22 2020 Andrea Claudi [4.11.0-27.el7] +- ss: fix NULL pointer access when parsing unix sockets with oldformat (Andrea Claudi) [1795891] +- tc_util: Add support for showing TCA_STATS_BASIC_HW statistics (Andrea Claudi) [1637437] +- Update kernel headers (Andrea Claudi) [1637437] +- uapi: update bpf headers (Andrea Claudi) [1637437] +- Update kernel headers (Andrea Claudi) [1637437] +- man: Clarify idleslope calculation for tc-cbs (Andrea Claudi) [1557461] +- man: Add initial manpage for tc-cbs(8) (Andrea Claudi) [1557461] +- tc: Add support for the CBS qdisc (Andrea Claudi) [1557461] +- nstat: print useful error messages in abort() cases (Andrea Claudi) [1792908] + +* Wed Nov 13 2019 Andrea Claudi [4.11.0-26.el7] +- netns: make /var/run/netns bind-mount recursive (Andrea Claudi) [1771556] * Fri Jun 21 2019 Andrea Claudi [4.11.0-25.el7] - tc: implement ingress/egress block index attributes for qdiscs (Andrea Claudi) [1721291]