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 <psutter@redhat.com>
-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ř <ppisar@redhat.com>
-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ř <ppisar@redhat.com>
-
-Signed-off-by: Phil Sutter <psutter@redhat.com>
----
- 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 " <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 <aclaudi@redhat.com>
+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 <casey.callendrello@coreos.com>
+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 <casey.callendrello@coreos.com>
+    Acked-by: "Eric W. Biederman" <ebiederm@xmission.com>
+---
+ 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 <psutter@redhat.com>
-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 <phil@nwl.cc>
-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 <jaster@redhat.com>
-    Fixes: 334af76143368 ("fix get_addr() and get_prefix() error messages")
-    Signed-off-by: Phil Sutter <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
+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 <aclaudi@redhat.com>
+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 <rmetrich@redhat.com>
+    Signed-off-by: Andrea Claudi <aclaudi@redhat.com>
+    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
+---
+ 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 <aclaudi@redhat.com>
+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 <vinicius.gomes@intel.com>
+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 <LOCREDIT>
+                    hicredit <HICREDIT> sendslope <SENDSLOPE>
+                    idleslope <IDLESLOPE>
+
+    (The order is not important)
+
+    Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+    Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
+---
+ 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 <vinicius.gomes@intel.com>
++ *
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <syslog.h>
++#include <fcntl.h>
++#include <sys/socket.h>
++#include <netinet/in.h>
++#include <arpa/inet.h>
++#include <string.h>
++
++#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 <psutter@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
+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 <vinicius.gomes@intel.com>
+Date:   Thu Oct 26 10:17:49 2017 -0700
+
+    man: Add initial manpage for tc-cbs(8)
+
+    Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+    Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
+---
+ 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 <vinicius.gomes@intel.com>
+-- 
+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 <psutter@redhat.com>
-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 <stephen@networkplumber.org>
-Date:   Thu Aug 3 16:10:18 2017 -0700
-
-    tc: fix m_simple usage
-
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
----
- 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 <psutter@redhat.com>
-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 <phil@nwl.cc>
-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 <daniel@iogearbox.net>
-    Signed-off-by: Phil Sutter <phil@nwl.cc>
-    Acked-by: Daniel Borkmann <daniel@iogearbox.net>
----
- 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 <aclaudi@redhat.com>
+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 <jesus.sanchez-palencia@intel.com>
+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 <jesus.sanchez-palencia@intel.com>
+---
+ 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 <aclaudi@redhat.com>
+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 <dsahern@gmail.com>
+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 <dsahern@gmail.com>
+---
+ 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 <psutter@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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<<UDP_DB))
- 		udp_show(&current_filter);
- 	if (current_filter.dbs & (1<<TCP_DB))
--		tcp_show(&current_filter, IPPROTO_TCP);
-+		tcp_show(&current_filter);
- 	if (current_filter.dbs & (1<<DCCP_DB))
--		tcp_show(&current_filter, IPPROTO_DCCP);
-+		dccp_show(&current_filter);
- 	if (current_filter.dbs & (1<<SCTP_DB))
- 		sctp_show(&current_filter);
- 
--- 
-2.21.0
-
diff --git a/SOURCES/0007-tc-simple.8-Fix-reference-to-non-existing-tc-actions.patch b/SOURCES/0007-tc-simple.8-Fix-reference-to-non-existing-tc-actions.patch
deleted file mode 100644
index 6a5dd67..0000000
--- a/SOURCES/0007-tc-simple.8-Fix-reference-to-non-existing-tc-actions.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 4917021d1ebea2b75cdcf31272452aa5cc3ff7ec Mon Sep 17 00:00:00 2001
-From: Phil Sutter <psutter@redhat.com>
-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 <aclaudi@redhat.com>
+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 <stephen@networkplumber.org>
+Date:   Thu Aug 30 07:55:49 2018 -0700
+
+    uapi: update bpf headers
+
+    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
+---
+ 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 <aclaudi@redhat.com>
+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 <dsahern@gmail.com>
+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 <dsahern@gmail.com>
+---
+ 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 <psutter@redhat.com>
-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 <phil@nwl.cc>
-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 <daniel@iogearbox.net>
-    Signed-off-by: Phil Sutter <phil@nwl.cc>
-    Acked-by: Daniel Borkmann <daniel@iogearbox.net>
----
- 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 <psutter@redhat.com>
-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 <aclaudi@redhat.com>
+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 <echaudro@redhat.com>
+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 <echaudro@redhat.com>
+    Signed-off-by: David Ahern <dsahern@gmail.com>
+---
+ 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 <aclaudi@redhat.com>
+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 <a@unstable.cc>
+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 <sbrivio@redhat.com>
+    Cc: Stephen Hemminger <stephen@networkplumber.org>
+    Signed-off-by: Antonio Quartulli <a@unstable.cc>
+    Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
+---
+ 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 <psutter@redhat.com>
-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 <psutter@redhat.com>
-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 <phil@nwl.cc>
----
- 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 <psutter@redhat.com>
-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 <nicolas.dichtel@6wind.com>
-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 <nicolas.dichtel@6wind.com>
----
- 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 <aclaudi@redhat.com>
+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 <lucien.xin@gmail.com>
+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 <lucien.xin@gmail.com>
+    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
+---
+ 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 <psutter@redhat.com>
-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 <mcroce@redhat.com>
-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 <mcroce@redhat.com>
----
- 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 <aclaudi@redhat.com>
+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 <lucien.xin@gmail.com>
+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 <xmu@redhat.com>
+    Signed-off-by: Xin Long <lucien.xin@gmail.com>
+    Acked-by: Andrea Claudi <aclaudi@redhat.com>
+    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
+---
+ 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 <mcroce@redhat.com>
-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 <liuhangbin@gmail.com>
-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 <liuhangbin@gmail.com>
-
-Signed-off-by: Matteo Croce <mcroce@redhat.com>
----
- 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 <aclaudi@redhat.com>
+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 <aclaudi@redhat.com>
+---
+ 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 <psutter@redhat.com>
-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 <mcroce@redhat.com>
-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/<namespace>. 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 <mcroce@redhat.com>
----
- 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 <sbrivio@redhat.com>
-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 <liuhangbin@gmail.com>
-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 <liuhangbin@gmail.com>
-    Acked-by: Phil Sutter <phil@nwl.cc>
-
-Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
----
- 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 <psutter@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <haliu@redhat.com>
-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 <dsahern@gmail.com>
-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 <dsahern@gmail.com>
-
-Signed-off-by: Hangbin Liu <haliu@redhat.com>
----
- 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 <haliu@redhat.com>
-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 <stephen@networkplumber.org>
-Date:   Thu Aug 24 15:02:32 2017 -0700
-
-    libnetlink: drop unused parameter to rtnl_dump_done
-
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
-
-Signed-off-by: Hangbin Liu <haliu@redhat.com>
----
- 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 <haliu@redhat.com>
-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 <stephen@networkplumber.org>
-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 <stephen@networkplumber.org>
-
-Signed-off-by: Hangbin Liu <haliu@redhat.com>
-
-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 <libmnl/libmnl.h>
-+
-+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 <haliu@redhat.com>
-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 <mkubecek@suse.cz>
-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 <mkubecek@suse.cz>
-
-Signed-off-by: Hangbin Liu <haliu@redhat.com>
----
- 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 <haliu@redhat.com>
-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 <mkubecek@suse.cz>
-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 <mkubecek@suse.cz>
-
-Signed-off-by: Hangbin Liu <haliu@redhat.com>
----
- 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 <haliu@redhat.com>
-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 <liuhangbin@gmail.com>
-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 <liuhangbin@gmail.com>
-    Signed-off-by: Phil Sutter <phil@nwl.cc>
-
-Signed-off-by: Hangbin Liu <haliu@redhat.com>
----
- 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 <haliu@redhat.com>
-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 <liuhangbin@gmail.com>
-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 <liuhangbin@gmail.com>
-    Signed-off-by: Phil Sutter <phil@nwl.cc>
-
-Signed-off-by: Hangbin Liu <haliu@redhat.com>
----
- 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 <psutter@redhat.com>
-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 <linux/pfkeyv2.h>
-+
-+#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 <linux/types.h>
-+
-+#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 <david.lebrun@uclouvain.be>
-+ *
-+ *
-+ *  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 <linux/types.h>
-+#include <linux/in6.h>		/* 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 <linux/types.h>
-+#include <linux/seg6.h>
-+
-+#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 <david.lebrun@uclouvain.be>
-+ *
-+ *
-+ *  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 <linux/seg6.h>		/* 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 <david.lebrun@uclouvain.be>
-+ *
-+ *
-+ *  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 <linux/seg6.h>
-+
-+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 <kheib@redhat.com>
-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 <arkadis@mellanox.com>
-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 <arkadis@mellanox.com>
-    Signed-off-by: Jiri Pirko <jiri@mellanox.com>
-    Reviewed-by: Greg Rose <gvrose8192@gmail.com>
-
-Signed-off-by: Kamal Heib <kheib@redhat.com>
----
- 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 <kheib@redhat.com>
-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 <arkadis@mellanox.com>
-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 <arkadis@mellanox.com>
-    Signed-off-by: Jiri Pirko <jiri@mellanox.com>
-
-Signed-off-by: Kamal Heib <kheib@redhat.com>
----
- 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 "<unknown>";
-+	}
- }
- 
--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 "<unknown>";
-+	}
-+}
-+
-+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 "<unknown>";
-+	}
-+}
-+
-+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 <kheib@redhat.com>
-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 <ogerlitz@mellanox.com>
-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 <ogerlitz@mellanox.com>
-    Reviewed-by: Jiri Pirko <jiri@mellanox.com>
-    Reviewed-by: Simon Horman <simon.horman@netronome.com>
-
-Signed-off-by: Kamal Heib <kheib@redhat.com>
----
- 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 <kheib@redhat.com>
-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 <amir@vadai.me>
-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 <amir@vadai.me>
-
-Signed-off-by: Kamal Heib <kheib@redhat.com>
----
- 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 <kheib@redhat.com>
-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 <amir@vadai.me>
-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 <amir@vadai.me>
-
-Signed-off-by: Kamal Heib <kheib@redhat.com>
----
- 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 <kheib@redhat.com>
-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 <amir@vadai.me>
-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 <amir@vadai.me>
-
-Signed-off-by: Kamal Heib <kheib@redhat.com>
----
- 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 <kheib@redhat.com>
-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 <amir@vadai.me>
-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 <amir@vadai.me>
-
-Signed-off-by: Kamal Heib <kheib@redhat.com>
----
- 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 <amir@vadai.me>
-+ *
-+ */
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <syslog.h>
-+#include <fcntl.h>
-+#include <sys/socket.h>
-+#include <netinet/in.h>
-+#include <arpa/inet.h>
-+#include <string.h>
-+#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 <kheib@redhat.com>
-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 <roid@mellanox.com>
-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 <roid@mellanox.com>
-    Reviewed-by: Jiri Pirko <jiri@mellanox.com>
-
-Signed-off-by: Kamal Heib <kheib@redhat.com>
----
- 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 <kheib@redhat.com>
-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 <jiri@mellanox.com>
-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 <jiri@mellanox.com>
-
-Signed-off-by: Kamal Heib <kheib@redhat.com>
----
- 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 <kheib@redhat.com>
-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 <eli@mellanox.com>
-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 <eli@mellanox.com>
-    Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
-
-Signed-off-by: Kamal Heib <kheib@redhat.com>
----
- 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 <kheib@redhat.com>
-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 <ogerlitz@mellanox.com>
-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 <ogerlitz@mellanox.com>
-    Reviewed-by: Jiri Pirko <jiri@mellanox.com>
-
-Signed-off-by: Kamal Heib <kheib@redhat.com>
----
- 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, &eth_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 <psutter@redhat.com>
-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 <lorenzo@google.com>
-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
-    <bits/ip_mreq.h> 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 <enh@google.com>
-    Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
----
- 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 <sbrivio@redhat.com>
-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 <stephen@networkplumber.org>
-Date:   Wed Oct 11 10:49:25 2017 -0700
-
-    uapi: add include linux/vm_sockets_diag.h
-
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
-
-Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
----
- 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 <linux/types.h>
-+
-+/* 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 <sbrivio@redhat.com>
-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 <stefanha@redhat.com>
-Date:   Fri Oct 6 11:48:39 2017 -0400
-
-    ss: allow AF_FAMILY constants >32
-
-    Linux has more than 32 address families defined in <bits/socket.h>.  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 <stefanha@redhat.com>
-
-Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
----
- 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<<AF_INET)) {
-+	if (f->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<<AF_INET6)) &&
-+	if ((f->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<<AF_INET)) {
-+	if (f->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<<AF_INET6)) &&
-+	if ((f->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<<AF_INET)) {
-+	if (f->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<<AF_INET6)) &&
-+	if ((f->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 <sbrivio@redhat.com>
-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 <stefanha@redhat.com>
-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 <u32 cid, u32 port> 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 <stefanha@redhat.com>
-
-Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
----
- 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 <linux/packet_diag.h>
- #include <linux/netlink_diag.h>
- #include <linux/sctp.h>
-+#include <linux/vm_sockets_diag.h>
- 
- #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<<MAX_DB)-1)
- #define INET_L4_DBM ((1<<TCP_DB)|(1<<UDP_DB)|(1<<DCCP_DB)|(1<<SCTP_DB))
- #define INET_DBM (INET_L4_DBM | (1<<RAW_DB))
-+#define VSOCK_DBM ((1<<VSOCK_ST_DB)|(1<<VSOCK_DG_DB))
- 
- enum {
- 	SS_UNKNOWN,
-@@ -222,6 +226,14 @@ static const struct filter default_dbs[MAX_DB] = {
- 		.states   = SS_CONN,
- 		.families = FAMILY_MASK(AF_INET) | FAMILY_MASK(AF_INET6),
- 	},
-+	[VSOCK_ST_DB] = {
-+		.states   = SS_CONN,
-+		.families = FAMILY_MASK(AF_VSOCK),
-+	},
-+	[VSOCK_DG_DB] = {
-+		.states   = SS_CONN,
-+		.families = FAMILY_MASK(AF_VSOCK),
-+	},
- };
- 
- static const struct filter default_afs[AF_MAX] = {
-@@ -245,6 +257,10 @@ static const struct filter default_afs[AF_MAX] = {
- 		.dbs    = (1 << NETLINK_DB),
- 		.states = (1 << SS_CLOSE),
- 	},
-+	[AF_VSOCK] = {
-+		.dbs    = VSOCK_DBM,
-+		.states = SS_CONN,
-+	},
- };
- 
- static int do_default = 1;
-@@ -283,6 +299,8 @@ static void filter_default_dbs(struct filter *f)
- 	filter_db_set(f, PACKET_DG_DB);
- 	filter_db_set(f, NETLINK_DB);
- 	filter_db_set(f, SCTP_DB);
-+	filter_db_set(f, VSOCK_ST_DB);
-+	filter_db_set(f, VSOCK_DG_DB);
- }
- 
- static void filter_states_set(struct filter *f, int states)
-@@ -792,6 +810,18 @@ static const char *proto_name(int protocol)
- 	return "???";
- }
- 
-+static const char *vsock_netid_name(int type)
-+{
-+	switch (type) {
-+	case SOCK_STREAM:
-+		return "v_str";
-+	case SOCK_DGRAM:
-+		return "v_dgr";
-+	default:
-+		return "???";
-+	}
-+}
-+
- static void sock_state_print(struct sockstat *s)
- {
- 	const char *sock_name;
-@@ -824,6 +854,9 @@ static void sock_state_print(struct sockstat *s)
- 	case AF_NETLINK:
- 		sock_name = "nl";
- 		break;
-+	case AF_VSOCK:
-+		sock_name = vsock_netid_name(s->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(&current_filter, AF_UNIX);
- 			break;
-+		case OPT_VSOCK:
-+			filter_af_set(&current_filter, AF_VSOCK);
-+			break;
- 		case 'a':
- 			state_filter = SS_ALL;
- 			break;
-@@ -4107,6 +4274,8 @@ int main(int argc, char *argv[])
- 				filter_af_set(&current_filter, AF_UNIX);
- 			else if (strcmp(optarg, "netlink") == 0)
- 				filter_af_set(&current_filter, AF_NETLINK);
-+			else if (strcmp(optarg, "vsock") == 0)
-+				filter_af_set(&current_filter, AF_VSOCK);
- 			else if (strcmp(optarg, "help") == 0)
- 				help();
- 			else {
-@@ -4172,6 +4341,15 @@ int main(int argc, char *argv[])
- 					filter_db_set(&current_filter, PACKET_DG_DB);
- 				} else if (strcmp(p, "netlink") == 0) {
- 					filter_db_set(&current_filter, NETLINK_DB);
-+				} else if (strcmp(p, "vsock") == 0) {
-+					filter_db_set(&current_filter, VSOCK_ST_DB);
-+					filter_db_set(&current_filter, VSOCK_DG_DB);
-+				} else if (strcmp(p, "vsock_stream") == 0 ||
-+					   strcmp(p, "v_str") == 0) {
-+					filter_db_set(&current_filter, VSOCK_ST_DB);
-+				} else if (strcmp(p, "vsock_dgram") == 0 ||
-+					   strcmp(p, "v_dgr") == 0) {
-+					filter_db_set(&current_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(&current_filter);
- 	if (current_filter.dbs & (1<<SCTP_DB))
- 		sctp_show(&current_filter);
-+	if (current_filter.dbs & VSOCK_DBM)
-+		vsock_show(&current_filter);
- 
- 	if (show_users || show_proc_ctx || show_sock_ctx)
- 		user_ent_destroy();
--- 
-2.21.0
-
diff --git a/SOURCES/0040-link_gre6-Detect-invalid-encaplimit-values.patch b/SOURCES/0040-link_gre6-Detect-invalid-encaplimit-values.patch
deleted file mode 100644
index 996807f..0000000
--- a/SOURCES/0040-link_gre6-Detect-invalid-encaplimit-values.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 90a1430fca8d5165e1909de9f009aa9f4d6430ef Mon Sep 17 00:00:00 2001
-From: Phil Sutter <psutter@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <psutter@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <psutter@redhat.com>
-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 <chrism@mellanox.com>
-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 <jiri@mellanox.com>
-    Signed-off-by: Chris Mi <chrism@mellanox.com>
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
----
- 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 <psutter@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <psutter@redhat.com>
-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 <jbenc@redhat.com>
-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 <jbenc@redhat.com>
----
- 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 <TUNNEL_KEY>\n");
-+	fprintf(stderr,
-+		"Where TUNNEL_KEY is a combination of:\n"
-+		"id <TUNNELID> (mandatory)\n"
-+		"src_ip <IP> (mandatory)\n"
-+		"dst_ip <IP> (mandatory)\n"
-+		"dst_port <UDP_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 <psutter@redhat.com>
-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 <adin@mellanox.com>
-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 <adin@mellanox.com>
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
----
- 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 <TUNNEL_KEY>\n");
- 	fprintf(stderr,
- 		"Where TUNNEL_KEY is a combination of:\n"
--		"id <TUNNELID> (mandatory)\n"
-+		"id <TUNNELID>\n"
- 		"src_ip <IP> (mandatory)\n"
- 		"dst_ip <IP> (mandatory)\n"
- 		"dst_port <UDP_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 <psutter@redhat.com>
-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 <raj.khem@gmail.com>
-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 <raj.khem@gmail.com>
----
- 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 <stdio.h>
- #include <stdlib.h>
-+#include <stdint.h>
- #include <unistd.h>
- #include <syslog.h>
- #include <fcntl.h>
--- 
-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 <psutter@redhat.com>
-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: <formatted msg>
-+ *
-+ * 		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.
-+ * 			* ``<formatted msg>`` 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=<new value>
-+ * 	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=<new value>
-+ * 	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 <linux/types.h>
-+
-+#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 <max_mk@yahoo.com>
-@@ -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 <nicolas.dichtel@6wind.com>
-  *
-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 <gozem@linux.nu>
-  *                         Patrick Schaaf <bof@bof.de>
-  *                         Martin Josefsson <gandalf@wlug.westbo.se>
-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 <linux/kernel.h>
-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 <jiri@resnulli.us>
-  *
-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 <amir@vadai.me>
-  * 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 <jiri@resnulli.us>
-  *
-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 <linux/types.h>
-+#include <linux/pkt_cls.h>
-+
-+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 <linux/types.h>
-+#include <linux/sock_diag.h>
-+
-+/* 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 <psutter@redhat.com>
-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 <ogerlitz@mellanox.com>
-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 <ogerlitz@mellanox.com>
-    Reviewed-by: Roi Dayan <roid@mellanox.com>
-    Acked-by: Jiri Pirko <jiri@mellanox.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- 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 <psutter@redhat.com>
-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 <ogerlitz@mellanox.com>
-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 <ogerlitz@mellanox.com>
-    Reviewed-by: Roi Dayan <roid@mellanox.com>
-    Acked-by: Jiri Pirko <jiri@mellanox.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- 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 <psutter@redhat.com>
-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 <jkbs@redhat.com>
-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 <jkbs@redhat.com>
----
- 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 <psutter@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
----
- 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 <psutter@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
----
- 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 <psutter@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
----
- 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 <psutter@redhat.com>
-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 <phil@nwl.cc>
-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 <aclaudi@redhat.com>
-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 <eranbe@mellanox.com>
-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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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 <eranbe@mellanox.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- 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 <aclaudi@redhat.com>
-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 <arkadis@mellanox.com>
-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 <arkadis@mellanox.com>
-    Acked-by: Jiri Pirko <jiri@mellanox.com>
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
----
- 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 "<unknown unit>";
-+	}
-+}
-+
-+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 <aclaudi@redhat.com>
-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 <arkadis@mellanox.com>
-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 <arkadis@mellanox.com>
-    Acked-by: Jiri Pirko <jiri@mellanox.com>
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
----
- 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 <aclaudi@redhat.com>
-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 <arkadis@mellanox.com>
-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 <arkadis@mellanox.com>
-    Acked-by: Jiri Pirko <jiri@mellanox.com>
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
----
- 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 <arkadis@mellanox.com>
-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 <aclaudi@redhat.com>
-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 <moshe@mellanox.com>
-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 <moshe@mellanox.com>
-    Signed-off-by: Jiri Pirko <jiri@mellanox.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- 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 "<unknown type>";
-+	}
-+}
-+
- 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 "<unknown cmd>";
- 	}
- }
-@@ -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 "<unknown obj>";
- 	}
- }
-@@ -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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
----
- 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 <aclaudi@redhat.com>
-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 <jianbol@mellanox.com>
-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 <jianbol@mellanox.com>
-    Acked-by: Jiri Pirko <jiri@mellanox.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- 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 <aclaudi@redhat.com>
-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 <leonro@mellanox.com>
-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 <leonro@mellanox.com>
----
- 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 <aclaudi@redhat.com>
-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 <ivecera@redhat.com>
-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 <jiri@mellanox.com>
-    Cc: Arkadi Sharshevsky <arkadis@mellanox.com>
-    Signed-off-by: Ivan Vecera <ivecera@redhat.com>
----
- 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 <aclaudi@redhat.com>
-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 <julien@cumulusnetworks.com>
-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 <julien@cumulusnetworks.com>
----
- 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 <aclaudi@redhat.com>
-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 <swise@opengridcomputing.com>
-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 <swise@opengridcomputing.com>
-    Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- 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 <aclaudi@redhat.com>
-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 <aclaudi@redhat.com>
-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 <aclaudi@redhat.com>
----
- 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 <leonro@mellanox.com>
-+ */
-+
-+#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 <linux/types.h>
-+
-+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 <linux/types.h>
-+
-+/*
-+ * 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 <linux/types.h>
-+
-+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 <linux/types.h>
-+#include <linux/socket.h>
-+#include <linux/in6.h>
-+#include <rdma/ib_user_verbs.h>
-+#include <rdma/ib_user_sa.h>
-+
-+#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 <leonro@mellanox.com>
-+ */
-+
-+#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 <leonro@mellanox.com>
-+ */
-+
-+#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 <leonro@mellanox.com>
-+ */
-+#ifndef _RDMA_TOOL_H_
-+#define _RDMA_TOOL_H_
-+
-+#include <stdlib.h>
-+#include <string.h>
-+#include <errno.h>
-+#include <getopt.h>
-+#include <netinet/in.h>
-+#include <libmnl/libmnl.h>
-+#include <rdma/rdma_netlink.h>
-+#include <rdma/rdma_user_cm.h>
-+#include <time.h>
-+#include <net/if_arp.h>
-+
-+#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 <leonro@mellanox.com>
-+ */
-+
-+#include "rdma.h"
-+#include <inttypes.h>
-+
-+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 <leonro@mellanox.com>
-+ */
-+
-+#include "rdma.h"
-+#include <ctype.h>
-+#include <inttypes.h>
-+
-+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 <aclaudi@redhat.com>
-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 <aclaudi@redhat.com>
-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 <aclaudi@redhat.com>
----
- 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 <leonro@mellanox.com>
-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 <leonro@mellanox.com>
-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 <leonro@mellanox.com>
-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 " <FILENAME>
-+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 <linux-rdma@vger.kernel.org>
-+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 <leonro@mellanox.com>
--- 
-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 <aclaudi@redhat.com>
-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 <pieter.jansenvanvuuren@netronome.com>
-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 <pieter.jansenvanvuuren@netronome.com>
-    Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
-    Signed-off-by: Simon Horman <simon.horman@netronome.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- 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 <aclaudi@redhat.com>
-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 <stephen@networkplumber.org>
-Date:   Fri Aug 4 12:02:41 2017 -0700
-
-    ss: enclose IPv6 address in brackets
-
-    Based on patch by Lehner Florian <dev@der-flo.net>
-
-    Adds support for RFC2732 IPv6 address format with brackets.
-
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-Date:   Thu Aug 17 19:09:31 2017 +0200
-
-    iproute_lwtunnel: Argument to strerror must be positive
-
-    Signed-off-by: Phil Sutter <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-Date:   Thu Aug 17 19:09:30 2017 +0200
-
-    ss: Don't leak fd in tcp_show_netlink_file()
-
-    Signed-off-by: Phil Sutter <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-Date:   Thu Aug 17 19:09:31 2017 +0200
-
-    tc/em_ipset: Don't leak sockfd on error path
-
-    Signed-off-by: Phil Sutter <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-Date:   Thu Aug 17 19:09:28 2017 +0200
-
-    ifstat: Fix memleak in error case
-
-    Signed-off-by: Phil Sutter <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-Date:   Thu Aug 17 19:09:31 2017 +0200
-
-    tipc/bearer: Fix resource leak in error path
-
-    Signed-off-by: Phil Sutter <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
-    Acked-by: Jiri Pirko <jiri@mellanox.com>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-Date:   Mon Aug 21 18:36:50 2017 +0200
-
-    iproute: Check mark value input
-
-    Signed-off-by: Phil Sutter <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-Date:   Mon Aug 21 18:36:51 2017 +0200
-
-    iplink_vrf: Complain if main table is not found
-
-    Signed-off-by: Phil Sutter <phil@nwl.cc>
-    Acked-by: David Ahern <dsahern@gmail.com>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
-    Acked-by: Daniel Borkmann <daniel@iogearbox.net>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-Date:   Thu Aug 24 11:46:34 2017 +0200
-
-    tipc/bearer: Prevent NULL pointer dereference
-
-    Signed-off-by: Phil Sutter <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-Date:   Thu Aug 24 11:41:28 2017 +0200
-
-    netem/maketable: Check return value of fscanf()
-
-    Signed-off-by: Phil Sutter <phil@nwl.cc>
----
- 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<limit; ++i){
--		fscanf(fp, "%lf", &x[i]);
--		if (feof(fp))
-+		if (fscanf(fp, "%lf", &x[i]) != 1 ||
-+		    feof(fp))
- 			break;
- 		++n;
- 	}
--- 
-2.21.0
-
diff --git a/SOURCES/0114-lib-bpf-Check-return-value-of-write.patch b/SOURCES/0114-lib-bpf-Check-return-value-of-write.patch
deleted file mode 100644
index 485b2ae..0000000
--- a/SOURCES/0114-lib-bpf-Check-return-value-of-write.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 78f4b87c3f014e378377d3ecc55d1ec46cd57b51 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-Date:   Fri Sep 1 18:52:54 2017 +0200
-
-    ipxfrm: Replace STRBUF_CAT macro with strlcat()
-
-    Signed-off-by: Phil Sutter <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <sys/socket.h>
- #include <netinet/in.h>
- #include <string.h>
-+#include <ctype.h>
- #include <netdb.h>
- #include <arpa/inet.h>
- #include <asm/types.h>
-@@ -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 <aclaudi@redhat.com>
-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 <daniel@iogearbox.net>
-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 <daniel@iogearbox.net>
----
- 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 <aclaudi@redhat.com>
-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 <serhe.popovych@gmail.com>
-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 <serhe.popovych@gmail.com>
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
----
- 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 <aclaudi@redhat.com>
-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 <sd@queasysnail.net>
-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 <sd@queasysnail.net>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- 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 <aclaudi@redhat.com>
-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 <sd@queasysnail.net>
-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 <sd@queasysnail.net>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- 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 <aclaudi@redhat.com>
-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 <jiri@mellanox.com>
-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 <jiri@mellanox.com>
----
- 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 <aclaudi@redhat.com>
-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 <jiri@mellanox.com>
-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 <jiri@mellanox.com>
----
- 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 <aclaudi@redhat.com>
-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 <jiri@mellanox.com>
-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 <jiri@mellanox.com>
----
- 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 <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 <CHAIN_INDEX>\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 <ACTION> [RAND] [INDEX]\n");
- 	fprintf(stderr,
--		"Where: \tACTION := reclassify | drop | continue | pass | pipe\n"
-+		"Where: \tACTION := reclassify | drop | continue | pass | pipe |\n"
-+		"       \t          goto chain <CHAIN_INDEX>\n"
- 			"\tRAND := random <RANDTYPE> <ACTION> <VAL>\n"
- 			"\tRANDTYPE := netrand | determ\n"
- 			"\tVAL : = value not exceeding 10000\n"
-@@ -54,7 +55,8 @@ explain(void)
- #else
- 	fprintf(stderr, "Usage: ... gact <ACTION> [INDEX]\n");
- 	fprintf(stderr,
--		"Where: \tACTION := reclassify | drop | continue | pass | pipe\n"
-+		"Where: \tACTION := reclassify | drop | continue | pass | pipe |\n"
-+		"       \t          goto chain <CHAIN_INDEX>\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 <setval>| add <addval> | retain\n"
- 		"\t<LAYERED>:= ip <ipdata> | ip6 <ip6data>\n"
- 		" \t\t| udp <udpdata> | tcp <tcpdata> | icmp <icmpdata>\n"
--		"\tCONTROL:= reclassify | pipe | drop | continue | pass\n"
-+		"\tCONTROL:= reclassify | pipe | drop | continue | pass |\n"
-+		"\t          goto chain <CHAIN_INDEX>\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 <EXCEEDACT>[/NOTEXCEEDACT]\n");
- 	fprintf(stderr, "                  Define how to handle packets which exceed (<EXCEEDACT>)\n");
- 	fprintf(stderr, "                  or conform (<NOTEXCEEDACT>) 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 <CHAIN_INDEX> }\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 <CHAIN_INDEX>\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 <CHAIN_INDEX>\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 <aclaudi@redhat.com>
-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 <jiri@mellanox.com>
-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 <jiri@mellanox.com>
----
- 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 <aclaudi@redhat.com>
-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 <jiri@mellanox.com>
-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 <jbenc@redhat.com>
-    Signed-off-by: Jiri Pirko <jiri@mellanox.com>
-    Tested-by: Jiri Benc <jbenc@redhat.com>
----
- 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 <aclaudi@redhat.com>
-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 <mprivozn@redhat.com>
-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 <mprivozn@redhat.com>
----
- 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 <aclaudi@redhat.com>
-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 <dcaratti@redhat.com>
-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 <mprivozn@redhat.com>
-    Cc: Wolfgang Bumiller <w.bumiller@proxmox.com>
-    Signed-off-by: Davide Caratti <dcaratti@redhat.com>
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
----
- 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 <aclaudi@redhat.com>
-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 <pabeni@redhat.com>
-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 <pabeni@redhat.com>
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
----
- 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 <aclaudi@redhat.com>
-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 <jbenc@redhat.com>
-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 <jbenc@redhat.com>
----
- 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 <TUNNELID>\n"
- 		"src_ip <IP> (mandatory)\n"
- 		"dst_ip <IP> (mandatory)\n"
--		"dst_port <UDP_PORT>\n");
-+		"dst_port <UDP_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 <aclaudi@redhat.com>
-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 <u9012063@gmail.com>
-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 <u9012063@gmail.com>
-    Cc: Daniel Borkmann <daniel@iogearbox.net>
----
- 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 <aclaudi@redhat.com>
-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 <phil@nwl.cc>
-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 <phil@nwl.cc>
----
- 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 <aclaudi@redhat.com>
-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 <aclaudi@redhat.com>
-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 <aclaudi@redhat.com>
-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 <jiri@mellanox.com>
-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 <jiri@mellanox.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- 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 <aclaudi@redhat.com>
-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 <jakub.kicinski@netronome.com>
-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 <jakub.kicinski@netronome.com>
-    Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com>
-    Acked-by: Daniel Borkmann <daniel@iogearbox.net>
----
- 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 <aclaudi@redhat.com>
-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 <jiri@mellanox.com>
-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 <jiri@mellanox.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- 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 <aclaudi@redhat.com>
-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 <jiri@mellanox.com>
-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 <jiri@mellanox.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- 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 <aclaudi@redhat.com>
-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 <casey.callendrello@coreos.com>
-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 <casey.callendrello@coreos.com>
-    Acked-by: "Eric W. Biederman" <ebiederm@xmission.com>
----
- 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 <aclaudi@redhat.com> [4.11.0-25.el7_7.1]
-- netns: make /var/run/netns bind-mount recursive (Andrea Claudi) [1772827]
+* Mon Jun 08 2020 Andrea Claudi <aclaudi@redhat.com> [4.11.0-30.el7]
+- tc_util: Fix format of TCA_STATS_BASIC_HW statistics (Andrea Claudi) [1637437]
+
+* Thu Apr 30 2020 Andrea Claudi <aclaudi@redhat.com> [4.11.0-29.el7]
+- xfrm: also check for ipv6 state in xfrm_state_keep (Andrea Claudi) [1828034]
+
+* Thu Apr 23 2020 Andrea Claudi <aclaudi@redhat.com> [4.11.0-28.el7]
+- xfrm: not try to delete ipcomp states when using deleteall (Andrea Claudi) [1767328]
+
+* Wed Apr 22 2020 Andrea Claudi <aclaudi@redhat.com> [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 <aclaudi@redhat.com> [4.11.0-26.el7]
+- netns: make /var/run/netns bind-mount recursive (Andrea Claudi) [1771556]
 
 * Fri Jun 21 2019 Andrea Claudi <aclaudi@redhat.com> [4.11.0-25.el7]
 - tc: implement ingress/egress block index attributes for qdiscs (Andrea Claudi) [1721291]