diff --git a/.gitignore b/.gitignore
index 52768d1..581167a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-SOURCES/iproute2-5.3.0.tar.xz
+SOURCES/iproute2-5.9.0.tar.xz
diff --git a/.iproute.metadata b/.iproute.metadata
index a48b873..3b76ec4 100644
--- a/.iproute.metadata
+++ b/.iproute.metadata
@@ -1 +1 @@
-fb5e623678688304a42d29d27d22287dcca12135 SOURCES/iproute2-5.3.0.tar.xz
+c9e0ca453307ce7c221ccffc10939f4136b4ad5d SOURCES/iproute2-5.9.0.tar.xz
diff --git a/SOURCES/0001-Update-kernel-headers.patch b/SOURCES/0001-Update-kernel-headers.patch
deleted file mode 100644
index 4d6f5d2..0000000
--- a/SOURCES/0001-Update-kernel-headers.patch
+++ /dev/null
@@ -1,226 +0,0 @@
-From 4cd2ea662ae3255713a7de44e496e6ed32ade0c9 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 16 Apr 2020 12:41:48 +0200
-Subject: [PATCH] Update kernel headers
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1770671
-Upstream Status: iproute2.git commit e3af717a8d410
-
-commit e3af717a8d410c97d9e0b985219ab8fc9ff18b79
-Author: David Ahern <dsahern@gmail.com>
-Date:   Sun Aug 18 11:48:02 2019 -0700
-
-    Update kernel headers
-
-    Update kernel headers to commit:
-        d83d508b74c4 ("Merge branch 'stmmac-next'")
-
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- include/uapi/linux/bpf.h         | 37 ++++++++++++++++++-
- include/uapi/linux/can/netlink.h |  6 ++--
- include/uapi/linux/devlink.h     | 62 ++++++++++++++++++++++++++++++++
- include/uapi/linux/if_bridge.h   |  1 +
- 4 files changed, 102 insertions(+), 4 deletions(-)
-
-diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
-index 1e08475275702..79701d3e66f0b 100644
---- a/include/uapi/linux/bpf.h
-+++ b/include/uapi/linux/bpf.h
-@@ -134,6 +134,7 @@ enum bpf_map_type {
- 	BPF_MAP_TYPE_QUEUE,
- 	BPF_MAP_TYPE_STACK,
- 	BPF_MAP_TYPE_SK_STORAGE,
-+	BPF_MAP_TYPE_DEVMAP_HASH,
- };
- 
- /* Note that tracing related programs such as
-@@ -2713,6 +2714,33 @@ union bpf_attr {
-  *		**-EPERM** if no permission to send the *sig*.
-  *
-  *		**-EAGAIN** if bpf program can try again.
-+ *
-+ * s64 bpf_tcp_gen_syncookie(struct bpf_sock *sk, void *iph, u32 iph_len, struct tcphdr *th, u32 th_len)
-+ *	Description
-+ *		Try to issue a SYN cookie for the packet with corresponding
-+ *		IP/TCP headers, *iph* and *th*, on the listening socket in *sk*.
-+ *
-+ *		*iph* points to the start of the IPv4 or IPv6 header, while
-+ *		*iph_len* contains **sizeof**\ (**struct iphdr**) or
-+ *		**sizeof**\ (**struct ip6hdr**).
-+ *
-+ *		*th* points to the start of the TCP header, while *th_len*
-+ *		contains the length of the TCP header.
-+ *
-+ *	Return
-+ *		On success, lower 32 bits hold the generated SYN cookie in
-+ *		followed by 16 bits which hold the MSS value for that cookie,
-+ *		and the top 16 bits are unused.
-+ *
-+ *		On failure, the returned value is one of the following:
-+ *
-+ *		**-EINVAL** SYN cookie cannot be issued due to error
-+ *
-+ *		**-ENOENT** SYN cookie should not be issued (no SYN flood)
-+ *
-+ *		**-EOPNOTSUPP** kernel configuration does not enable SYN cookies
-+ *
-+ *		**-EPROTONOSUPPORT** IP packet version is not 4 or 6
-  */
- #define __BPF_FUNC_MAPPER(FN)		\
- 	FN(unspec),			\
-@@ -2824,7 +2852,8 @@ union bpf_attr {
- 	FN(strtoul),			\
- 	FN(sk_storage_get),		\
- 	FN(sk_storage_delete),		\
--	FN(send_signal),
-+	FN(send_signal),		\
-+	FN(tcp_gen_syncookie),
- 
- /* integer value in 'imm' field of BPF_CALL instruction selects which helper
-  * function eBPF program intends to call
-@@ -3507,6 +3536,10 @@ enum bpf_task_fd_type {
- 	BPF_FD_TYPE_URETPROBE,		/* filename + offset */
- };
- 
-+#define BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG		(1U << 0)
-+#define BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL		(1U << 1)
-+#define BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP		(1U << 2)
-+
- struct bpf_flow_keys {
- 	__u16	nhoff;
- 	__u16	thoff;
-@@ -3528,6 +3561,8 @@ struct bpf_flow_keys {
- 			__u32	ipv6_dst[4];	/* in6_addr; network order */
- 		};
- 	};
-+	__u32	flags;
-+	__be32	flow_label;
- };
- 
- struct bpf_func_info {
-diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netlink.h
-index f0c5e58b8ee76..c1f62640e87bc 100644
---- a/include/uapi/linux/can/netlink.h
-+++ b/include/uapi/linux/can/netlink.h
-@@ -40,15 +40,15 @@ struct can_bittiming {
- };
- 
- /*
-- * CAN harware-dependent bit-timing constant
-+ * CAN hardware-dependent bit-timing constant
-  *
-  * Used for calculating and checking bit-timing parameters
-  */
- struct can_bittiming_const {
- 	char name[16];		/* Name of the CAN controller hardware */
--	__u32 tseg1_min;	/* Time segement 1 = prop_seg + phase_seg1 */
-+	__u32 tseg1_min;	/* Time segment 1 = prop_seg + phase_seg1 */
- 	__u32 tseg1_max;
--	__u32 tseg2_min;	/* Time segement 2 = phase_seg2 */
-+	__u32 tseg2_min;	/* Time segment 2 = phase_seg2 */
- 	__u32 tseg2_max;
- 	__u32 sjw_max;		/* Synchronisation jump width */
- 	__u32 brp_min;		/* Bit-rate prescaler */
-diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
-index fc195cbd66f45..3fb683bee6ba1 100644
---- a/include/uapi/linux/devlink.h
-+++ b/include/uapi/linux/devlink.h
-@@ -107,6 +107,16 @@ enum devlink_command {
- 	DEVLINK_CMD_FLASH_UPDATE_END,		/* notification only */
- 	DEVLINK_CMD_FLASH_UPDATE_STATUS,	/* notification only */
- 
-+	DEVLINK_CMD_TRAP_GET,		/* can dump */
-+	DEVLINK_CMD_TRAP_SET,
-+	DEVLINK_CMD_TRAP_NEW,
-+	DEVLINK_CMD_TRAP_DEL,
-+
-+	DEVLINK_CMD_TRAP_GROUP_GET,	/* can dump */
-+	DEVLINK_CMD_TRAP_GROUP_SET,
-+	DEVLINK_CMD_TRAP_GROUP_NEW,
-+	DEVLINK_CMD_TRAP_GROUP_DEL,
-+
- 	/* add new commands above here */
- 	__DEVLINK_CMD_MAX,
- 	DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
-@@ -194,6 +204,47 @@ enum devlink_param_fw_load_policy_value {
- 	DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_FLASH,
- };
- 
-+enum {
-+	DEVLINK_ATTR_STATS_RX_PACKETS,		/* u64 */
-+	DEVLINK_ATTR_STATS_RX_BYTES,		/* u64 */
-+
-+	__DEVLINK_ATTR_STATS_MAX,
-+	DEVLINK_ATTR_STATS_MAX = __DEVLINK_ATTR_STATS_MAX - 1
-+};
-+
-+/**
-+ * enum devlink_trap_action - Packet trap action.
-+ * @DEVLINK_TRAP_ACTION_DROP: Packet is dropped by the device and a copy is not
-+ *                            sent to the CPU.
-+ * @DEVLINK_TRAP_ACTION_TRAP: The sole copy of the packet is sent to the CPU.
-+ */
-+enum devlink_trap_action {
-+	DEVLINK_TRAP_ACTION_DROP,
-+	DEVLINK_TRAP_ACTION_TRAP,
-+};
-+
-+/**
-+ * enum devlink_trap_type - Packet trap type.
-+ * @DEVLINK_TRAP_TYPE_DROP: Trap reason is a drop. Trapped packets are only
-+ *                          processed by devlink and not injected to the
-+ *                          kernel's Rx path.
-+ * @DEVLINK_TRAP_TYPE_EXCEPTION: Trap reason is an exception. Packet was not
-+ *                               forwarded as intended due to an exception
-+ *                               (e.g., missing neighbour entry) and trapped to
-+ *                               control plane for resolution. Trapped packets
-+ *                               are processed by devlink and injected to
-+ *                               the kernel's Rx path.
-+ */
-+enum devlink_trap_type {
-+	DEVLINK_TRAP_TYPE_DROP,
-+	DEVLINK_TRAP_TYPE_EXCEPTION,
-+};
-+
-+enum {
-+	/* Trap can report input port as metadata */
-+	DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT,
-+};
-+
- enum devlink_attr {
- 	/* don't change the order or add anything between, this is ABI! */
- 	DEVLINK_ATTR_UNSPEC,
-@@ -348,6 +399,17 @@ enum devlink_attr {
- 	DEVLINK_ATTR_PORT_PCI_PF_NUMBER,	/* u16 */
- 	DEVLINK_ATTR_PORT_PCI_VF_NUMBER,	/* u16 */
- 
-+	DEVLINK_ATTR_STATS,				/* nested */
-+
-+	DEVLINK_ATTR_TRAP_NAME,				/* string */
-+	/* enum devlink_trap_action */
-+	DEVLINK_ATTR_TRAP_ACTION,			/* u8 */
-+	/* enum devlink_trap_type */
-+	DEVLINK_ATTR_TRAP_TYPE,				/* u8 */
-+	DEVLINK_ATTR_TRAP_GENERIC,			/* flag */
-+	DEVLINK_ATTR_TRAP_METADATA,			/* nested */
-+	DEVLINK_ATTR_TRAP_GROUP_NAME,			/* string */
-+
- 	/* add new attributes above here, update the policy in devlink.c */
- 
- 	__DEVLINK_ATTR_MAX,
-diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h
-index 04f763cf53029..31fc51bdedb3c 100644
---- a/include/uapi/linux/if_bridge.h
-+++ b/include/uapi/linux/if_bridge.h
-@@ -237,6 +237,7 @@ struct br_mdb_entry {
- #define MDB_PERMANENT 1
- 	__u8 state;
- #define MDB_FLAGS_OFFLOAD	(1 << 0)
-+#define MDB_FLAGS_FAST_LEAVE	(1 << 1)
- 	__u8 flags;
- 	__u16 vid;
- 	struct {
--- 
-2.25.4
-
diff --git a/SOURCES/0001-v5.9.0.patch b/SOURCES/0001-v5.9.0.patch
new file mode 100644
index 0000000..f0868bb
--- /dev/null
+++ b/SOURCES/0001-v5.9.0.patch
@@ -0,0 +1,20 @@
+From cb7ce51cc1abd7b98370b903ec96205ebfe48661 Mon Sep 17 00:00:00 2001
+Message-Id: <cb7ce51cc1abd7b98370b903ec96205ebfe48661.1611877215.git.aclaudi@redhat.com>
+From: Stephen Hemminger <stephen@networkplumber.org>
+Date: Thu, 15 Oct 2020 15:18:35 -0700
+Subject: [PATCH] v5.9.0
+
+---
+ include/version.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/version.h b/include/version.h
+index 0088493d..89d05974 100644
+--- a/include/version.h
++++ b/include/version.h
+@@ -1 +1 @@
+-static const char version[] = "5.8.0";
++static const char version[] = "5.9.0";
+-- 
+2.29.2
+
diff --git a/SOURCES/0002-Update-kernel-headers.patch b/SOURCES/0002-Update-kernel-headers.patch
index 3ffe6a3..60a94f4 100644
--- a/SOURCES/0002-Update-kernel-headers.patch
+++ b/SOURCES/0002-Update-kernel-headers.patch
@@ -1,140 +1,308 @@
-From 864c5a906ccfe205f886aa4bfb69f738a9a4fb45 Mon Sep 17 00:00:00 2001
+From 1b8a3c04bf8d115e2d427d41a437be03ecf34ce8 Mon Sep 17 00:00:00 2001
+Message-Id: <1b8a3c04bf8d115e2d427d41a437be03ecf34ce8.1611877215.git.aclaudi@redhat.com>
+In-Reply-To: <cb7ce51cc1abd7b98370b903ec96205ebfe48661.1611877215.git.aclaudi@redhat.com>
+References: <cb7ce51cc1abd7b98370b903ec96205ebfe48661.1611877215.git.aclaudi@redhat.com>
 From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 16 Apr 2020 12:41:49 +0200
+Date: Fri, 29 Jan 2021 00:34:34 +0100
 Subject: [PATCH] Update kernel headers
 
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1770671
-Upstream Status: iproute2.git commit 17a948c80af57
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1885770
+Upstream Status: unknown commit 34be2d26
+Conflicts: on include/uapi/linux/bpf.h, due to missing commits:
+  - c8eb4b52c1b1 ("Update kernel headers")
+  - f481515c89fa ("Update kernel headers")
 
-commit 17a948c80af57da2fa86a8e34153f755f86e9c9c
+commit 34be2d2619e29836605a7d1669d642f892fc725e
 Author: David Ahern <dsahern@gmail.com>
-Date:   Sat Nov 2 07:43:01 2019 -0700
+Date:   Wed Oct 7 00:01:26 2020 -0600
 
     Update kernel headers
 
     Update kernel headers to commit:
-        c23fcbbc6aa4 ("tc-testing: added tests with cookie for conntrack TC action")
+        9faebeb2d800 ("Merge branch 'ethtool-allow-dumping-policies-to-user-space'")
 
     Signed-off-by: David Ahern <dsahern@gmail.com>
 ---
- include/uapi/linux/bpf.h     | 28 +++++++++++++++++++++++++++-
- include/uapi/linux/pkt_cls.h |  5 +++++
- include/uapi/linux/tcp.h     | 10 +++++++++-
- include/uapi/linux/tipc.h    |  1 +
- 4 files changed, 42 insertions(+), 2 deletions(-)
+ include/uapi/linux/bpf.h            | 64 +++++++++++++++++++++++++----
+ include/uapi/linux/devlink.h        |  5 +++
+ include/uapi/linux/genetlink.h      | 11 +++++
+ include/uapi/linux/l2tp.h           |  1 +
+ include/uapi/linux/netlink.h        |  2 +
+ include/uapi/linux/tc_act/tc_mpls.h |  1 +
+ include/uapi/linux/tc_act/tc_vlan.h |  4 ++
+ 7 files changed, 79 insertions(+), 9 deletions(-)
 
 diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
-index 79701d3e66f0b..3e195ff43fa01 100644
+index b21cc6af..36e5bc2d 100644
 --- a/include/uapi/linux/bpf.h
 +++ b/include/uapi/linux/bpf.h
-@@ -413,6 +413,7 @@ union bpf_attr {
- 		__u32		line_info_rec_size;	/* userspace bpf_line_info size */
- 		__aligned_u64	line_info;	/* line info */
- 		__u32		line_info_cnt;	/* number of bpf_line_info records */
-+		__u32		attach_btf_id;	/* in-kernel BTF type id to attach to */
- 	};
- 
- 	struct { /* anonymous struct used by BPF_OBJ_* commands */
-@@ -2741,6 +2742,30 @@ union bpf_attr {
-  *		**-EOPNOTSUPP** kernel configuration does not enable SYN cookies
-  *
-  *		**-EPROTONOSUPPORT** IP packet version is not 4 or 6
-+ *
-+ * int bpf_skb_output(void *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*.
-+ *
-+ * 		*ctx* is a pointer to in-kernel struct sk_buff.
-+ *
-+ * 		This helper is similar to **bpf_perf_event_output**\ () but
-+ * 		restricted to raw_tracepoint bpf programs.
-+ * 	Return
-+ * 		0 on success, or a negative error in case of failure.
+@@ -404,6 +404,9 @@ enum {
+ 
+ /* Enable memory-mapping BPF map */
+ 	BPF_F_MMAPABLE		= (1U << 10),
++
++/* Share perf_event among processes */
++	BPF_F_PRESERVE_ELEMS	= (1U << 11),
+ };
+ 
+ /* Flags for BPF_PROG_QUERY. */
+@@ -414,6 +417,11 @@ enum {
   */
- #define __BPF_FUNC_MAPPER(FN)		\
- 	FN(unspec),			\
-@@ -2853,7 +2878,8 @@ union bpf_attr {
- 	FN(sk_storage_get),		\
- 	FN(sk_storage_delete),		\
- 	FN(send_signal),		\
--	FN(tcp_gen_syncookie),
-+	FN(tcp_gen_syncookie),		\
-+	FN(skb_output),
- 
- /* integer value in 'imm' field of BPF_CALL instruction selects which helper
-  * function eBPF program intends to call
-diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
-index b057aeeb63386..0a9ab625cba7b 100644
---- a/include/uapi/linux/pkt_cls.h
-+++ b/include/uapi/linux/pkt_cls.h
-@@ -16,9 +16,14 @@ enum {
- 	TCA_ACT_STATS,
- 	TCA_ACT_PAD,
- 	TCA_ACT_COOKIE,
-+	TCA_ACT_FLAGS,
- 	__TCA_ACT_MAX
+ #define BPF_F_QUERY_EFFECTIVE	(1U << 0)
+ 
++/* Flags for BPF_PROG_TEST_RUN */
++
++/* If set, run the test on the cpu specified by bpf_attr.test.cpu */
++#define BPF_F_TEST_RUN_ON_CPU	(1U << 0)
++
+ /* type for BPF_ENABLE_STATS */
+ enum bpf_stats_type {
+ 	/* enabled run_time_ns and run_cnt */
+@@ -556,6 +564,8 @@ union bpf_attr {
+ 						 */
+ 		__aligned_u64	ctx_in;
+ 		__aligned_u64	ctx_out;
++		__u32		flags;
++		__u32		cpu;
+ 	} test;
+ 
+ 	struct { /* anonymous struct used by BPF_*_GET_*_ID */
+@@ -622,8 +632,13 @@ union bpf_attr {
+ 		};
+ 		__u32		attach_type;	/* attach type */
+ 		__u32		flags;		/* extra flags */
+-		__aligned_u64	iter_info;	/* extra bpf_iter_link_info */
+-		__u32		iter_info_len;	/* iter_info length */
++		union {
++			__u32		target_btf_id;	/* btf_id of target to attach to */
++			struct {
++				__aligned_u64	iter_info;	/* extra bpf_iter_link_info */
++				__u32		iter_info_len;	/* iter_info length */
++			};
++		};
+ 	} link_create;
+ 
+ 	struct { /* struct used by BPF_LINK_UPDATE command */
+@@ -2496,7 +2511,7 @@ union bpf_attr {
+  *		result is from *reuse*\ **->socks**\ [] using the hash of the
+  *		tuple.
+  *
+- * long bpf_sk_release(struct bpf_sock *sock)
++ * long bpf_sk_release(void *sock)
+  *	Description
+  *		Release the reference held by *sock*. *sock* must be a
+  *		non-**NULL** pointer that was returned from
+@@ -2676,7 +2691,7 @@ union bpf_attr {
+  *		result is from *reuse*\ **->socks**\ [] using the hash of the
+  *		tuple.
+  *
+- * long bpf_tcp_check_syncookie(struct bpf_sock *sk, void *iph, u32 iph_len, struct tcphdr *th, u32 th_len)
++ * long bpf_tcp_check_syncookie(void *sk, void *iph, u32 iph_len, struct tcphdr *th, u32 th_len)
+  * 	Description
+  * 		Check whether *iph* and *th* contain a valid SYN cookie ACK for
+  * 		the listening socket in *sk*.
+@@ -2842,6 +2857,7 @@ union bpf_attr {
+  *		0 on success.
+  *
+  *		**-ENOENT** if the bpf-local-storage cannot be found.
++ *		**-EINVAL** if sk is not a fullsock (e.g. a request_sock).
+  *
+  * long bpf_send_signal(u32 sig)
+  *	Description
+@@ -2858,7 +2874,7 @@ union bpf_attr {
+  *
+  *		**-EAGAIN** if bpf program can try again.
+  *
+- * s64 bpf_tcp_gen_syncookie(struct bpf_sock *sk, void *iph, u32 iph_len, struct tcphdr *th, u32 th_len)
++ * s64 bpf_tcp_gen_syncookie(void *sk, void *iph, u32 iph_len, struct tcphdr *th, u32 th_len)
+  *	Description
+  *		Try to issue a SYN cookie for the packet with corresponding
+  *		IP/TCP headers, *iph* and *th*, on the listening socket in *sk*.
+@@ -3087,7 +3103,7 @@ union bpf_attr {
+  * 	Return
+  * 		The id is returned or 0 in case the id could not be retrieved.
+  *
+- * long bpf_sk_assign(struct sk_buff *skb, struct bpf_sock *sk, u64 flags)
++ * long bpf_sk_assign(struct sk_buff *skb, void *sk, u64 flags)
+  *	Description
+  *		Helper is overloaded depending on BPF program type. This
+  *		description applies to **BPF_PROG_TYPE_SCHED_CLS** and
+@@ -3215,11 +3231,11 @@ union bpf_attr {
+  *
+  *		**-EOVERFLOW** if an overflow happened: The same object will be tried again.
+  *
+- * u64 bpf_sk_cgroup_id(struct bpf_sock *sk)
++ * u64 bpf_sk_cgroup_id(void *sk)
+  *	Description
+  *		Return the cgroup v2 id of the socket *sk*.
+  *
+- *		*sk* must be a non-**NULL** pointer to a full socket, e.g. one
++ *		*sk* must be a non-**NULL** pointer to a socket, e.g. one
+  *		returned from **bpf_sk_lookup_xxx**\ (),
+  *		**bpf_sk_fullsock**\ (), etc. The format of returned id is
+  *		same as in **bpf_skb_cgroup_id**\ ().
+@@ -3229,7 +3245,7 @@ union bpf_attr {
+  *	Return
+  *		The id is returned or 0 in case the id could not be retrieved.
+  *
+- * u64 bpf_sk_ancestor_cgroup_id(struct bpf_sock *sk, int ancestor_level)
++ * u64 bpf_sk_ancestor_cgroup_id(void *sk, int ancestor_level)
+  *	Description
+  *		Return id of cgroup v2 that is ancestor of cgroup associated
+  *		with the *sk* at the *ancestor_level*.  The root cgroup is at
+@@ -4447,4 +4463,34 @@ struct bpf_sk_lookup {
+ 	__u32 local_port;	/* Host byte order */
  };
  
-+#define TCA_ACT_FLAGS_NO_PERCPU_STATS 1 /* Don't use percpu allocator for
-+					 * actions stats.
-+					 */
++/*
++ * struct btf_ptr is used for typed pointer representation; the
++ * type id is used to render the pointer data as the appropriate type
++ * via the bpf_snprintf_btf() helper described above.  A flags field -
++ * potentially to specify additional details about the BTF pointer
++ * (rather than its mode of display) - is included for future use.
++ * Display flags - BTF_F_* - are passed to bpf_snprintf_btf separately.
++ */
++struct btf_ptr {
++	void *ptr;
++	__u32 type_id;
++	__u32 flags;		/* BTF ptr flags; unused at present. */
++};
++
++/*
++ * Flags to control bpf_snprintf_btf() behaviour.
++ *     - BTF_F_COMPACT: no formatting around type information
++ *     - BTF_F_NONAME: no struct/union member names/types
++ *     - BTF_F_PTR_RAW: show raw (unobfuscated) pointer values;
++ *       equivalent to %px.
++ *     - BTF_F_ZERO: show zero-valued struct/union members; they
++ *       are not displayed by default
++ */
++enum {
++	BTF_F_COMPACT	=	(1ULL << 0),
++	BTF_F_NONAME	=	(1ULL << 1),
++	BTF_F_PTR_RAW	=	(1ULL << 2),
++	BTF_F_ZERO	=	(1ULL << 3),
++};
++
+ #endif /* __LINUX_BPF_H__ */
+diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
+index b7f23faa..e5586fa0 100644
+--- a/include/uapi/linux/devlink.h
++++ b/include/uapi/linux/devlink.h
+@@ -13,6 +13,8 @@
+ #ifndef _LINUX_DEVLINK_H_
+ #define _LINUX_DEVLINK_H_
+ 
++#include <linux/const.h>
 +
- #define TCA_ACT_MAX __TCA_ACT_MAX
- #define TCA_OLD_COMPAT (TCA_ACT_MAX+1)
- #define TCA_ACT_MAX_PRIO 32
-diff --git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h
-index 3fd9b29146b17..acb15ca8558c0 100644
---- a/include/uapi/linux/tcp.h
-+++ b/include/uapi/linux/tcp.h
-@@ -155,6 +155,14 @@ enum {
- 	TCP_QUEUES_NR,
+ #define DEVLINK_GENL_NAME "devlink"
+ #define DEVLINK_GENL_VERSION 0x1
+ #define DEVLINK_GENL_MCGRP_CONFIG_NAME "config"
+@@ -193,6 +195,9 @@ enum devlink_port_flavour {
+ 				      * port that faces the PCI VF.
+ 				      */
+ 	DEVLINK_PORT_FLAVOUR_VIRTUAL, /* Any virtual port facing the user. */
++	DEVLINK_PORT_FLAVOUR_UNUSED, /* Port which exists in the switch, but
++				      * is not used in any way.
++				      */
+ };
+ 
+ enum devlink_param_cmode {
+diff --git a/include/uapi/linux/genetlink.h b/include/uapi/linux/genetlink.h
+index 7c6c390c..9fa720ee 100644
+--- a/include/uapi/linux/genetlink.h
++++ b/include/uapi/linux/genetlink.h
+@@ -64,6 +64,8 @@ enum {
+ 	CTRL_ATTR_OPS,
+ 	CTRL_ATTR_MCAST_GROUPS,
+ 	CTRL_ATTR_POLICY,
++	CTRL_ATTR_OP_POLICY,
++	CTRL_ATTR_OP,
+ 	__CTRL_ATTR_MAX,
+ };
+ 
+@@ -85,6 +87,15 @@ enum {
+ 	__CTRL_ATTR_MCAST_GRP_MAX,
  };
  
-+/* why fastopen failed from client perspective */
-+enum tcp_fastopen_client_fail {
-+	TFO_STATUS_UNSPEC, /* catch-all */
-+	TFO_COOKIE_UNAVAILABLE, /* if not in TFO_CLIENT_NO_COOKIE mode */
-+	TFO_DATA_NOT_ACKED, /* SYN-ACK did not ack SYN data */
-+	TFO_SYN_RETRANSMITTED, /* SYN-ACK did not ack SYN data after timeout */
++enum {
++	CTRL_ATTR_POLICY_UNSPEC,
++	CTRL_ATTR_POLICY_DO,
++	CTRL_ATTR_POLICY_DUMP,
++
++	__CTRL_ATTR_POLICY_DUMP_MAX,
++	CTRL_ATTR_POLICY_DUMP_MAX = __CTRL_ATTR_POLICY_DUMP_MAX - 1
 +};
 +
- /* for TCP_INFO socket option */
- #define TCPI_OPT_TIMESTAMPS	1
- #define TCPI_OPT_SACK		2
-@@ -211,7 +219,7 @@ struct tcp_info {
- 	__u8	tcpi_backoff;
- 	__u8	tcpi_options;
- 	__u8	tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
--	__u8	tcpi_delivery_rate_app_limited:1;
-+	__u8	tcpi_delivery_rate_app_limited:1, tcpi_fastopen_client_fail:2;
- 
- 	__u32	tcpi_rto;
- 	__u32	tcpi_ato;
-diff --git a/include/uapi/linux/tipc.h b/include/uapi/linux/tipc.h
-index e16cb4e2af587..0f6f28b2e3010 100644
---- a/include/uapi/linux/tipc.h
-+++ b/include/uapi/linux/tipc.h
-@@ -191,6 +191,7 @@ struct sockaddr_tipc {
- #define TIPC_GROUP_JOIN         135     /* Takes struct tipc_group_req* */
- #define TIPC_GROUP_LEAVE        136     /* No argument */
- #define TIPC_SOCK_RECVQ_USED    137     /* Default: none (read only) */
-+#define TIPC_NODELAY            138     /* Default: false */
- 
- /*
-  * Flag values
+ #define CTRL_ATTR_MCAST_GRP_MAX (__CTRL_ATTR_MCAST_GRP_MAX - 1)
+ 
+ 
+diff --git a/include/uapi/linux/l2tp.h b/include/uapi/linux/l2tp.h
+index 131c3a26..abc0fc81 100644
+--- a/include/uapi/linux/l2tp.h
++++ b/include/uapi/linux/l2tp.h
+@@ -144,6 +144,7 @@ enum {
+ 	L2TP_ATTR_RX_OOS_PACKETS,	/* u64 */
+ 	L2TP_ATTR_RX_ERRORS,		/* u64 */
+ 	L2TP_ATTR_STATS_PAD,
++	L2TP_ATTR_RX_COOKIE_DISCARDS,	/* u64 */
+ 	__L2TP_ATTR_STATS_MAX,
+ };
+ 
+diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h
+index 695c88e3..f7749205 100644
+--- a/include/uapi/linux/netlink.h
++++ b/include/uapi/linux/netlink.h
+@@ -327,6 +327,7 @@ enum netlink_attribute_type {
+  *	the index, if limited inside the nesting (U32)
+  * @NL_POLICY_TYPE_ATTR_BITFIELD32_MASK: valid mask for the
+  *	bitfield32 type (U32)
++ * @NL_POLICY_TYPE_ATTR_MASK: mask of valid bits for unsigned integers (U64)
+  * @NL_POLICY_TYPE_ATTR_PAD: pad attribute for 64-bit alignment
+  */
+ enum netlink_policy_type_attr {
+@@ -342,6 +343,7 @@ enum netlink_policy_type_attr {
+ 	NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE,
+ 	NL_POLICY_TYPE_ATTR_BITFIELD32_MASK,
+ 	NL_POLICY_TYPE_ATTR_PAD,
++	NL_POLICY_TYPE_ATTR_MASK,
+ 
+ 	/* keep last */
+ 	__NL_POLICY_TYPE_ATTR_MAX,
+diff --git a/include/uapi/linux/tc_act/tc_mpls.h b/include/uapi/linux/tc_act/tc_mpls.h
+index 9360e952..9e4e8f52 100644
+--- a/include/uapi/linux/tc_act/tc_mpls.h
++++ b/include/uapi/linux/tc_act/tc_mpls.h
+@@ -10,6 +10,7 @@
+ #define TCA_MPLS_ACT_PUSH	2
+ #define TCA_MPLS_ACT_MODIFY	3
+ #define TCA_MPLS_ACT_DEC_TTL	4
++#define TCA_MPLS_ACT_MAC_PUSH	5
+ 
+ struct tc_mpls {
+ 	tc_gen;		/* generic TC action fields. */
+diff --git a/include/uapi/linux/tc_act/tc_vlan.h b/include/uapi/linux/tc_act/tc_vlan.h
+index 168995b5..5b306fe8 100644
+--- a/include/uapi/linux/tc_act/tc_vlan.h
++++ b/include/uapi/linux/tc_act/tc_vlan.h
+@@ -16,6 +16,8 @@
+ #define TCA_VLAN_ACT_POP	1
+ #define TCA_VLAN_ACT_PUSH	2
+ #define TCA_VLAN_ACT_MODIFY	3
++#define TCA_VLAN_ACT_POP_ETH	4
++#define TCA_VLAN_ACT_PUSH_ETH	5
+ 
+ struct tc_vlan {
+ 	tc_gen;
+@@ -30,6 +32,8 @@ enum {
+ 	TCA_VLAN_PUSH_VLAN_PROTOCOL,
+ 	TCA_VLAN_PAD,
+ 	TCA_VLAN_PUSH_VLAN_PRIORITY,
++	TCA_VLAN_PUSH_ETH_DST,
++	TCA_VLAN_PUSH_ETH_SRC,
+ 	__TCA_VLAN_MAX,
+ };
+ #define TCA_VLAN_MAX (__TCA_VLAN_MAX - 1)
 -- 
-2.25.4
+2.29.2
 
diff --git a/SOURCES/0003-m_vlan-add-pop_eth-and-push_eth-actions.patch b/SOURCES/0003-m_vlan-add-pop_eth-and-push_eth-actions.patch
new file mode 100644
index 0000000..fa1b401
--- /dev/null
+++ b/SOURCES/0003-m_vlan-add-pop_eth-and-push_eth-actions.patch
@@ -0,0 +1,343 @@
+From cac52dd831b6982f6b27b02c26243edbe0b7d747 Mon Sep 17 00:00:00 2001
+Message-Id: <cac52dd831b6982f6b27b02c26243edbe0b7d747.1611877215.git.aclaudi@redhat.com>
+In-Reply-To: <cb7ce51cc1abd7b98370b903ec96205ebfe48661.1611877215.git.aclaudi@redhat.com>
+References: <cb7ce51cc1abd7b98370b903ec96205ebfe48661.1611877215.git.aclaudi@redhat.com>
+From: Andrea Claudi <aclaudi@redhat.com>
+Date: Fri, 29 Jan 2021 00:35:03 +0100
+Subject: [PATCH] m_vlan: add pop_eth and push_eth actions
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1885770
+Upstream Status: unknown commit d61167dd
+
+commit d61167dd88b45832843b1458cd156f3b85c8ff16
+Author: Guillaume Nault <gnault@redhat.com>
+Date:   Mon Oct 19 17:23:01 2020 +0200
+
+    m_vlan: add pop_eth and push_eth actions
+
+    Add support for the new TCA_VLAN_ACT_POP_ETH and TCA_VLAN_ACT_PUSH_ETH
+    actions (kernel commit 19fbcb36a39e ("net/sched: act_vlan:
+    Add {POP,PUSH}_ETH actions"). These action let TC remove or add the
+    Ethernet at the head of a frame.
+
+    Drop an Ethernet header:
+     # tc filter add dev ethX matchall action vlan pop_eth
+
+    Push an Ethernet header (the original frame must have no MAC header):
+     # tc filter add dev ethX matchall action vlan \
+           push_eth dst_mac 0a:00:00:00:00:02 src_mac 0a:00:00:00:00:01
+
+    Also add a test suite for m_vlan, which covers these new actions and
+    the pre-existing ones.
+
+    Signed-off-by: Guillaume Nault <gnault@redhat.com>
+    Signed-off-by: David Ahern <dsahern@gmail.com>
+---
+ man/man8/tc-vlan.8        | 39 +++++++++++++++++-
+ tc/m_vlan.c               | 69 +++++++++++++++++++++++++++++++
+ testsuite/tests/tc/vlan.t | 86 +++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 192 insertions(+), 2 deletions(-)
+ create mode 100755 testsuite/tests/tc/vlan.t
+
+diff --git a/man/man8/tc-vlan.8 b/man/man8/tc-vlan.8
+index f5ffc25f..5c2808b1 100644
+--- a/man/man8/tc-vlan.8
++++ b/man/man8/tc-vlan.8
+@@ -5,8 +5,8 @@ vlan - vlan manipulation module
+ .SH SYNOPSIS
+ .in +8
+ .ti -8
+-.BR tc " ... " "action vlan" " { " pop " |"
+-.IR PUSH " | " MODIFY " } [ " CONTROL " ]"
++.BR tc " ... " "action vlan" " { " pop " | " pop_eth " |"
++.IR PUSH " | " MODIFY " | " PUSH_ETH " } [ " CONTROL " ]"
+ 
+ .ti -8
+ .IR PUSH " := "
+@@ -24,6 +24,11 @@ vlan - vlan manipulation module
+ .IR VLANPRIO " ] "
+ .BI id " VLANID"
+ 
++.ti -8
++.IR PUSH_ETH " := "
++.B push_eth
++.BI dst_mac " LLADDR " src_mac " LLADDR "
++
+ .ti -8
+ .IR CONTROL " := { "
+ .BR reclassify " | " pipe " | " drop " | " continue " | " pass " | " goto " " chain " " CHAIN_INDEX " }"
+@@ -43,6 +48,20 @@ modes require at least a
+ and allow to optionally choose the
+ .I VLANPROTO
+ to use.
++
++The
++.B vlan
++action can also be used to add or remove the base Ethernet header. The
++.B pop_eth
++mode, which takes no argument, is used to remove the base Ethernet header. All
++existing VLANs must have been previously dropped. The opposite operation,
++adding a base Ethernet header, is done with the
++.B push_eth
++mode. In that case, the packet must have no MAC header (stacking MAC headers is
++not permitted). This mode is mostly useful when a previous action has
++encapsulated the whole original frame behind a network header and one needs
++to prepend an Ethernet header before forwarding the resulting packet.
++
+ .SH OPTIONS
+ .TP
+ .B pop
+@@ -58,6 +77,16 @@ Replace mode. Existing 802.1Q tag is replaced. Requires at least
+ .B id
+ option.
+ .TP
++.B pop_eth
++Ethernet header decapsulation mode. Only works on a plain Ethernet header:
++VLANs, if any, must be removed first.
++.TP
++.B push_eth
++Ethernet header encapsulation mode. The Ethertype is automatically set
++using the network header type. Chaining Ethernet headers is not allowed: the
++packet must have no MAC header when using this mode. Requires the
++.BR "dst_mac " and " src_mac " options.
++.TP
+ .BI id " VLANID"
+ Specify the VLAN ID to encapsulate into.
+ .I VLANID
+@@ -73,6 +102,12 @@ Choose the VLAN protocol to use. At the time of writing, the kernel accepts only
+ .BI priority " VLANPRIO"
+ Choose the VLAN priority to use. Decimal number in range of 0-7.
+ .TP
++.BI dst_mac " LLADDR"
++Choose the destination MAC address to use.
++.TP
++.BI src_mac " LLADDR"
++Choose the source MAC address to use.
++.TP
+ .I CONTROL
+ How to continue after executing this action.
+ .RS
+diff --git a/tc/m_vlan.c b/tc/m_vlan.c
+index 1096ba0f..e6b21330 100644
+--- a/tc/m_vlan.c
++++ b/tc/m_vlan.c
+@@ -23,6 +23,8 @@ static const char * const action_names[] = {
+ 	[TCA_VLAN_ACT_POP] = "pop",
+ 	[TCA_VLAN_ACT_PUSH] = "push",
+ 	[TCA_VLAN_ACT_MODIFY] = "modify",
++	[TCA_VLAN_ACT_POP_ETH] = "pop_eth",
++	[TCA_VLAN_ACT_PUSH_ETH] = "push_eth",
+ };
+ 
+ static void explain(void)
+@@ -31,6 +33,8 @@ static void explain(void)
+ 		"Usage: vlan pop\n"
+ 		"       vlan push [ protocol VLANPROTO ] id VLANID [ priority VLANPRIO ] [CONTROL]\n"
+ 		"       vlan modify [ protocol VLANPROTO ] id VLANID [ priority VLANPRIO ] [CONTROL]\n"
++		"       vlan pop_eth [CONTROL]\n"
++		"       vlan push_eth dst_mac LLADDR src_mac LLADDR [CONTROL]\n"
+ 		"       VLANPROTO is one of 802.1Q or 802.1AD\n"
+ 		"            with default: 802.1Q\n"
+ 		"       CONTROL := reclassify | pipe | drop | continue | pass |\n"
+@@ -63,6 +67,10 @@ static int parse_vlan(struct action_util *a, int *argc_p, char ***argv_p,
+ 	char **argv = *argv_p;
+ 	struct rtattr *tail;
+ 	int action = 0;
++	char dst_mac[ETH_ALEN] = {};
++	int dst_mac_set = 0;
++	char src_mac[ETH_ALEN] = {};
++	int src_mac_set = 0;
+ 	__u16 id;
+ 	int id_set = 0;
+ 	__u16 proto;
+@@ -95,6 +103,18 @@ static int parse_vlan(struct action_util *a, int *argc_p, char ***argv_p,
+ 				return -1;
+ 			}
+ 			action = TCA_VLAN_ACT_MODIFY;
++		} else if (matches(*argv, "pop_eth") == 0) {
++			if (action) {
++				unexpected(*argv);
++				return -1;
++			}
++			action = TCA_VLAN_ACT_POP_ETH;
++		} else if (matches(*argv, "push_eth") == 0) {
++			if (action) {
++				unexpected(*argv);
++				return -1;
++			}
++			action = TCA_VLAN_ACT_PUSH_ETH;
+ 		} else if (matches(*argv, "id") == 0) {
+ 			if (!has_push_attribs(action))
+ 				invarg("only valid for push/modify", *argv);
+@@ -119,6 +139,22 @@ static int parse_vlan(struct action_util *a, int *argc_p, char ***argv_p,
+ 			if (get_u8(&prio, *argv, 0) || (prio & ~0x7))
+ 				invarg("prio is invalid", *argv);
+ 			prio_set = 1;
++		} else if (matches(*argv, "dst_mac") == 0) {
++			if (action != TCA_VLAN_ACT_PUSH_ETH)
++				invarg("only valid for push_eth", *argv);
++
++			NEXT_ARG();
++			if (ll_addr_a2n(dst_mac, sizeof(dst_mac), *argv) < 0)
++				invarg("dst_mac is invalid", *argv);
++			dst_mac_set = 1;
++		} else if (matches(*argv, "src_mac") == 0) {
++			if (action != TCA_VLAN_ACT_PUSH_ETH)
++				invarg("only valid for push_eth", *argv);
++
++			NEXT_ARG();
++			if (ll_addr_a2n(src_mac, sizeof(src_mac), *argv) < 0)
++				invarg("src_mac is invalid", *argv);
++			src_mac_set = 1;
+ 		} else if (matches(*argv, "help") == 0) {
+ 			usage();
+ 		} else {
+@@ -150,6 +186,20 @@ static int parse_vlan(struct action_util *a, int *argc_p, char ***argv_p,
+ 		return -1;
+ 	}
+ 
++	if (action == TCA_VLAN_ACT_PUSH_ETH) {
++		if (!dst_mac_set) {
++			fprintf(stderr, "dst_mac needs to be set for %s\n",
++				action_names[action]);
++			explain();
++			return -1;
++		} else if (!src_mac_set) {
++			fprintf(stderr, "src_mac needs to be set for %s\n",
++				action_names[action]);
++			explain();
++			return -1;
++		}
++	}
++
+ 	parm.v_action = action;
+ 	tail = addattr_nest(n, MAX_MSG, tca_id);
+ 	addattr_l(n, MAX_MSG, TCA_VLAN_PARMS, &parm, sizeof(parm));
+@@ -167,6 +217,12 @@ static int parse_vlan(struct action_util *a, int *argc_p, char ***argv_p,
+ 	}
+ 	if (prio_set)
+ 		addattr8(n, MAX_MSG, TCA_VLAN_PUSH_VLAN_PRIORITY, prio);
++	if (dst_mac_set)
++		addattr_l(n, MAX_MSG, TCA_VLAN_PUSH_ETH_DST, dst_mac,
++			  sizeof(dst_mac));
++	if (src_mac_set)
++		addattr_l(n, MAX_MSG, TCA_VLAN_PUSH_ETH_SRC, src_mac,
++			  sizeof(src_mac));
+ 
+ 	addattr_nest_end(n, tail);
+ 
+@@ -216,6 +272,19 @@ static int print_vlan(struct action_util *au, FILE *f, struct rtattr *arg)
+ 			print_uint(PRINT_ANY, "priority", " priority %u", val);
+ 		}
+ 		break;
++	case TCA_VLAN_ACT_PUSH_ETH:
++		if (tb[TCA_VLAN_PUSH_ETH_DST] &&
++		    RTA_PAYLOAD(tb[TCA_VLAN_PUSH_ETH_DST]) == ETH_ALEN) {
++			ll_addr_n2a(RTA_DATA(tb[TCA_VLAN_PUSH_ETH_DST]),
++				    ETH_ALEN, 0, b1, sizeof(b1));
++			print_string(PRINT_ANY, "dst_mac", " dst_mac %s", b1);
++		}
++		if (tb[TCA_VLAN_PUSH_ETH_SRC &&
++		       RTA_PAYLOAD(tb[TCA_VLAN_PUSH_ETH_SRC]) == ETH_ALEN]) {
++			ll_addr_n2a(RTA_DATA(tb[TCA_VLAN_PUSH_ETH_SRC]),
++				    ETH_ALEN, 0, b1, sizeof(b1));
++			print_string(PRINT_ANY, "src_mac", " src_mac %s", b1);
++		}
+ 	}
+ 	print_action_control(f, " ", parm->action, "");
+ 
+diff --git a/testsuite/tests/tc/vlan.t b/testsuite/tests/tc/vlan.t
+new file mode 100755
+index 00000000..b86dc364
+--- /dev/null
++++ b/testsuite/tests/tc/vlan.t
+@@ -0,0 +1,86 @@
++#!/bin/sh
++
++. lib/generic.sh
++
++DEV="$(rand_dev)"
++ts_ip "$0" "Add $DEV dummy interface" link add dev $DEV up type dummy
++ts_tc "$0" "Add ingress qdisc" qdisc add dev $DEV ingress
++
++reset_qdisc()
++{
++	ts_tc "$0" "Remove ingress qdisc" qdisc del dev $DEV ingress
++	ts_tc "$0" "Add ingress qdisc" qdisc add dev $DEV ingress
++}
++
++ts_tc "$0" "Add vlan action pop" \
++	filter add dev $DEV ingress matchall action vlan pop
++ts_tc "$0" "Show ingress filters" filter show dev $DEV ingress
++test_on "vlan"
++test_on "pop"
++test_on "pipe"
++
++reset_qdisc
++ts_tc "$0" "Add vlan action push (default parameters)" \
++	filter add dev $DEV ingress matchall action vlan push id 5
++ts_tc "$0" "Show ingress filters" filter show dev $DEV ingress
++test_on "vlan"
++test_on "push"
++test_on "id 5"
++test_on "protocol 802.1Q"
++test_on "priority 0"
++test_on "pipe"
++
++reset_qdisc
++ts_tc "$0" "Add vlan action push (explicit parameters)" \
++	filter add dev $DEV ingress matchall            \
++	action vlan push id 5 protocol 802.1ad priority 2
++ts_tc "$0" "Show ingress filters" filter show dev $DEV ingress
++test_on "vlan"
++test_on "push"
++test_on "id 5"
++test_on "protocol 802.1ad"
++test_on "priority 2"
++test_on "pipe"
++
++reset_qdisc
++ts_tc "$0" "Add vlan action modify (default parameters)" \
++	filter add dev $DEV ingress matchall action vlan modify id 5
++ts_tc "$0" "Show ingress filters" filter show dev $DEV ingress
++test_on "vlan"
++test_on "modify"
++test_on "id 5"
++test_on "protocol 802.1Q"
++test_on "priority 0"
++test_on "pipe"
++
++reset_qdisc
++ts_tc "$0" "Add vlan action modify (explicit parameters)" \
++	filter add dev $DEV ingress matchall              \
++	action vlan modify id 5 protocol 802.1ad priority 2
++ts_tc "$0" "Show ingress filters" filter show dev $DEV ingress
++test_on "vlan"
++test_on "modify"
++test_on "id 5"
++test_on "protocol 802.1ad"
++test_on "priority 2"
++test_on "pipe"
++
++reset_qdisc
++ts_tc "$0" "Add vlan action pop_eth" \
++	filter add dev $DEV ingress matchall action vlan pop_eth
++ts_tc "$0" "Show ingress filters" filter show dev $DEV ingress
++test_on "vlan"
++test_on "pop_eth"
++test_on "pipe"
++
++reset_qdisc
++ts_tc "$0" "Add vlan action push_eth"                  \
++	filter add dev $DEV ingress matchall           \
++	action vlan push_eth dst_mac 02:00:00:00:00:02 \
++	src_mac 02:00:00:00:00:01
++ts_tc "$0" "Show ingress filters" filter show dev $DEV ingress
++test_on "vlan"
++test_on "push_eth"
++test_on "dst_mac 02:00:00:00:00:02"
++test_on "src_mac 02:00:00:00:00:01"
++test_on "pipe"
+-- 
+2.29.2
+
diff --git a/SOURCES/0003-tc-implement-support-for-action-flags.patch b/SOURCES/0003-tc-implement-support-for-action-flags.patch
deleted file mode 100644
index aef92b7..0000000
--- a/SOURCES/0003-tc-implement-support-for-action-flags.patch
+++ /dev/null
@@ -1,116 +0,0 @@
-From a3d12445422afa12a67a7cd121b7add89f6c7d67 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 16 Apr 2020 12:41:49 +0200
-Subject: [PATCH] tc: implement support for action flags
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1770671
-Upstream Status: iproute2.git commit fb2e033add073
-
-commit fb2e033add073893dea71bb483353790fe8c5354
-Author: Vlad Buslov <vladbu@mellanox.com>
-Date:   Wed Oct 30 16:20:40 2019 +0200
-
-    tc: implement support for action flags
-
-    Implement setting and printing of action flags with single available flag
-    value "no_percpu" that translates to kernel UAPI TCA_ACT_FLAGS value
-    TCA_ACT_FLAGS_NO_PERCPU_STATS. Update man page with information regarding
-    usage of action flags.
-
-    Example usage:
-
-     # tc actions add action gact drop no_percpu
-     # sudo tc actions list action gact
-     total acts 1
-
-            action order 0: gact action drop
-             random type none pass val 0
-             index 1 ref 1 bind 0
-            no_percpu
-
-    Signed-off-by: Vlad Buslov <vladbu@mellanox.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- man/man8/tc-actions.8 | 14 ++++++++++++++
- tc/m_action.c         | 19 +++++++++++++++++++
- 2 files changed, 33 insertions(+)
-
-diff --git a/man/man8/tc-actions.8 b/man/man8/tc-actions.8
-index f46166e3f6859..bee59f7247fae 100644
---- a/man/man8/tc-actions.8
-+++ b/man/man8/tc-actions.8
-@@ -47,6 +47,8 @@ actions \- independently defined actions in tc
- ] [
- .I COOKIESPEC
- ] [
-+.I FLAGS
-+] [
- .I CONTROL
- ]
- 
-@@ -71,6 +73,10 @@ ACTNAME
- :=
- .BI cookie " COOKIE"
- 
-+.I FLAGS
-+:=
-+.I no_percpu
-+
- .I ACTDETAIL
- :=
- .I ACTNAME ACTPARAMS
-@@ -186,6 +192,14 @@ As such, it can be used as a correlating value for maintaining user state.
- The value to be stored is completely arbitrary and does not require a specific
- format. It is stored inside the action structure itself.
- 
-+.TP
-+.I FLAGS
-+Action-specific flags. Currently, the only supported flag is
-+.I no_percpu
-+which indicates that action is expected to have minimal software data-path
-+traffic and doesn't need to allocate stat counters with percpu allocator.
-+This option is intended to be used by hardware-offloaded actions.
-+
- .TP
- .BI since " MSTIME"
- When dumping large number of actions, a millisecond time-filter can be
-diff --git a/tc/m_action.c b/tc/m_action.c
-index bdc62720879c1..c46aeaafa8ebf 100644
---- a/tc/m_action.c
-+++ b/tc/m_action.c
-@@ -249,6 +249,16 @@ done0:
- 				addattr_l(n, MAX_MSG, TCA_ACT_COOKIE,
- 					  &act_ck, act_ck_len);
- 
-+			if (*argv && strcmp(*argv, "no_percpu") == 0) {
-+				struct nla_bitfield32 flags =
-+					{ TCA_ACT_FLAGS_NO_PERCPU_STATS,
-+					  TCA_ACT_FLAGS_NO_PERCPU_STATS };
-+
-+				addattr_l(n, MAX_MSG, TCA_ACT_FLAGS, &flags,
-+					  sizeof(struct nla_bitfield32));
-+				NEXT_ARG_FWD();
-+			}
-+
- 			addattr_nest_end(n, tail);
- 			ok++;
- 		}
-@@ -317,6 +327,15 @@ static int tc_print_one_action(FILE *f, struct rtattr *arg)
- 					   strsz, b1, sizeof(b1)));
- 		print_string(PRINT_FP, NULL, "%s", _SL_);
- 	}
-+	if (tb[TCA_ACT_FLAGS]) {
-+		struct nla_bitfield32 *flags = RTA_DATA(tb[TCA_ACT_FLAGS]);
-+
-+		if (flags->selector & TCA_ACT_FLAGS_NO_PERCPU_STATS)
-+			print_bool(PRINT_ANY, "no_percpu", "\tno_percpu",
-+				   flags->value &
-+				   TCA_ACT_FLAGS_NO_PERCPU_STATS);
-+		print_string(PRINT_FP, NULL, "%s", _SL_);
-+	}
- 
- 	return 0;
- }
--- 
-2.25.4
-
diff --git a/SOURCES/0004-m_mpls-add-mac_push-action.patch b/SOURCES/0004-m_mpls-add-mac_push-action.patch
new file mode 100644
index 0000000..54c1c3c
--- /dev/null
+++ b/SOURCES/0004-m_mpls-add-mac_push-action.patch
@@ -0,0 +1,342 @@
+From 0afe12a4a9471ed1343693338ec6350dc66ba295 Mon Sep 17 00:00:00 2001
+Message-Id: <0afe12a4a9471ed1343693338ec6350dc66ba295.1611877215.git.aclaudi@redhat.com>
+In-Reply-To: <cb7ce51cc1abd7b98370b903ec96205ebfe48661.1611877215.git.aclaudi@redhat.com>
+References: <cb7ce51cc1abd7b98370b903ec96205ebfe48661.1611877215.git.aclaudi@redhat.com>
+From: Andrea Claudi <aclaudi@redhat.com>
+Date: Fri, 29 Jan 2021 00:35:03 +0100
+Subject: [PATCH] m_mpls: add mac_push action
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1885770
+Upstream Status: unknown commit 02a261b5
+
+commit 02a261b5ba1c8580ac2a35bc6c87faa2ec9f5c96
+Author: Guillaume Nault <gnault@redhat.com>
+Date:   Mon Oct 19 17:23:08 2020 +0200
+
+    m_mpls: add mac_push action
+
+    Add support for the new TCA_MPLS_ACT_MAC_PUSH action (kernel commit
+    a45294af9e96 ("net/sched: act_mpls: Add action to push MPLS LSE before
+    Ethernet header")). This action let TC push an MPLS header before the
+    MAC header of a frame.
+
+    Example (encapsulate all outgoing frames with label 20, then add an
+    outer Ethernet header):
+     # tc filter add dev ethX matchall \
+           action mpls mac_push label 20 ttl 64 \
+           action vlan push_eth dst_mac 0a:00:00:00:00:02 \
+                                src_mac 0a:00:00:00:00:01
+
+    This patch also adds an alias for ETH_P_TEB, since it is useful when
+    decapsulating MPLS packets that contain an Ethernet frame.
+
+    With MAC_PUSH, there's no previous Ethertype to modify. However, the
+    "protocol" option is still needed, because the kernel uses it to set
+    skb->protocol. So rename can_modify_ethtype() to can_set_ethtype().
+
+    Also add a test suite for m_mpls, which covers the new action and the
+    pre-existing ones.
+
+    Signed-off-by: Guillaume Nault <gnault@redhat.com>
+    Signed-off-by: David Ahern <dsahern@gmail.com>
+---
+ lib/ll_proto.c            |  1 +
+ man/man8/tc-mpls.8        | 44 +++++++++++++++++++++++--
+ man/man8/tc-vlan.8        |  5 ++-
+ tc/m_mpls.c               | 43 ++++++++++++++++--------
+ testsuite/tests/tc/mpls.t | 69 +++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 145 insertions(+), 17 deletions(-)
+ create mode 100755 testsuite/tests/tc/mpls.t
+
+diff --git a/lib/ll_proto.c b/lib/ll_proto.c
+index 2a0c1cb3..78179311 100644
+--- a/lib/ll_proto.c
++++ b/lib/ll_proto.c
+@@ -80,6 +80,7 @@ __PF(8021Q,802.1Q)
+ __PF(8021AD,802.1ad)
+ __PF(MPLS_UC,mpls_uc)
+ __PF(MPLS_MC,mpls_mc)
++__PF(TEB,teb)
+ 
+ { 0x8100, "802.1Q" },
+ { 0x88cc, "LLDP" },
+diff --git a/man/man8/tc-mpls.8 b/man/man8/tc-mpls.8
+index 84ef2ef1..9e563e98 100644
+--- a/man/man8/tc-mpls.8
++++ b/man/man8/tc-mpls.8
+@@ -17,7 +17,7 @@ mpls - mpls manipulation module
+ 
+ .ti -8
+ .IR PUSH " := "
+-.BR push " [ " protocol
++.RB "{ " push " | " mac_push " } [ " protocol
+ .IR MPLS_PROTO " ]"
+ .RB " [ " tc
+ .IR MPLS_TC " ] "
+@@ -64,7 +64,14 @@ requires no arguments and simply subtracts 1 from the MPLS header TTL field.
+ Decapsulation mode. Requires the protocol of the next header.
+ .TP
+ .B push
+-Encapsulation mode. Requires at least the
++Encapsulation mode. Adds the MPLS header between the MAC and the network
++headers. Requires at least the
++.B label
++option.
++.TP
++.B mac_push
++Encapsulation mode. Adds the MPLS header before the MAC header. Requires at
++least the
+ .B label
+ option.
+ .TP
+@@ -152,5 +159,36 @@ ip packets and output to eth1:
+ .EE
+ .RE
+ 
++Here is another example, where incoming Ethernet frames are encapsulated into
++MPLS with label 123 and TTL 64. Then, an outer Ethernet header is added and the
++resulting frame is finally sent on eth1:
++
++.RS
++.EX
++#tc qdisc add dev eth0 ingress
++#tc filter add dev eth0 ingress matchall \\
++	action mpls mac_push label 123 ttl 64 \\
++	action vlan push_eth \\
++		dst_mac 02:00:00:00:00:02 \\
++		src_mac 02:00:00:00:00:01 \\
++	action mirred egress redirect dev eth1
++.EE
++.RE
++
++The following example assumes that incoming MPLS packets with label 123
++transport Ethernet frames. The outer Ethernet and the MPLS headers are
++stripped, then the inner Ethernet frame is sent on eth1:
++
++.RS
++.EX
++#tc qdisc add dev eth0 ingress
++#tc filter add dev eth0 ingress protocol mpls_uc \\
++	flower mpls_label 123 mpls_bos 1 \\
++	action vlan pop_eth \\
++	action mpls pop protocol teb \\
++	action mirred egress redirect dev eth1
++.EE
++.RE
++
+ .SH SEE ALSO
+-.BR tc (8)
++.BR tc "(8), " tc-mirred "(8), " tc-vlan (8)
+diff --git a/man/man8/tc-vlan.8 b/man/man8/tc-vlan.8
+index 5c2808b1..264053d3 100644
+--- a/man/man8/tc-vlan.8
++++ b/man/man8/tc-vlan.8
+@@ -157,5 +157,8 @@ process then restarted for the plain packet:
+ .EE
+ .RE
+ 
++For an example of the
++.BR pop_eth " and " push_eth " modes, see " tc-mpls (8).
++
+ .SH SEE ALSO
+-.BR tc (8)
++.BR tc "(8), " tc-mpls (8)
+diff --git a/tc/m_mpls.c b/tc/m_mpls.c
+index 3d5d9b25..cb8019b1 100644
+--- a/tc/m_mpls.c
++++ b/tc/m_mpls.c
+@@ -17,6 +17,7 @@ static const char * const action_names[] = {
+ 	[TCA_MPLS_ACT_PUSH] = "push",
+ 	[TCA_MPLS_ACT_MODIFY] = "modify",
+ 	[TCA_MPLS_ACT_DEC_TTL] = "dec_ttl",
++	[TCA_MPLS_ACT_MAC_PUSH] = "mac_push",
+ };
+ 
+ static void explain(void)
+@@ -25,9 +26,11 @@ static void explain(void)
+ 		"Usage: mpls pop [ protocol MPLS_PROTO ]\n"
+ 		"       mpls push [ protocol MPLS_PROTO ] [ label MPLS_LABEL ] [ tc MPLS_TC ]\n"
+ 		"                 [ ttl MPLS_TTL ] [ bos MPLS_BOS ] [CONTROL]\n"
++		"       mpls mac_push [ protocol MPLS_PROTO ] [ label MPLS_LABEL ] [ tc MPLS_TC ]\n"
++		"                     [ ttl MPLS_TTL ] [ bos MPLS_BOS ] [CONTROL]\n"
+ 		"       mpls modify [ label MPLS_LABEL ] [ tc MPLS_TC ] [ ttl MPLS_TTL ] [CONTROL]\n"
+-		"           for pop MPLS_PROTO is next header of packet - e.g. ip or mpls_uc\n"
+-		"           for push MPLS_PROTO is one of mpls_uc or mpls_mc\n"
++		"           for pop, MPLS_PROTO is next header of packet - e.g. ip or mpls_uc\n"
++		"           for push and mac_push, MPLS_PROTO is one of mpls_uc or mpls_mc\n"
+ 		"               with default: mpls_uc\n"
+ 		"       CONTROL := reclassify | pipe | drop | continue | pass |\n"
+ 		"                  goto chain <CHAIN_INDEX>\n");
+@@ -41,12 +44,14 @@ static void usage(void)
+ 
+ static bool can_modify_mpls_fields(unsigned int action)
+ {
+-	return action == TCA_MPLS_ACT_PUSH || action == TCA_MPLS_ACT_MODIFY;
++	return action == TCA_MPLS_ACT_PUSH || action == TCA_MPLS_ACT_MAC_PUSH ||
++		action == TCA_MPLS_ACT_MODIFY;
+ }
+ 
+-static bool can_modify_ethtype(unsigned int action)
++static bool can_set_ethtype(unsigned int action)
+ {
+-	return action == TCA_MPLS_ACT_PUSH || action == TCA_MPLS_ACT_POP;
++	return action == TCA_MPLS_ACT_PUSH || action == TCA_MPLS_ACT_MAC_PUSH ||
++		action == TCA_MPLS_ACT_POP;
+ }
+ 
+ static bool is_valid_label(__u32 label)
+@@ -94,6 +99,10 @@ static int parse_mpls(struct action_util *a, int *argc_p, char ***argv_p,
+ 			if (check_double_action(action, *argv))
+ 				return -1;
+ 			action = TCA_MPLS_ACT_PUSH;
++		} else if (matches(*argv, "mac_push") == 0) {
++			if (check_double_action(action, *argv))
++				return -1;
++			action = TCA_MPLS_ACT_MAC_PUSH;
+ 		} else if (matches(*argv, "modify") == 0) {
+ 			if (check_double_action(action, *argv))
+ 				return -1;
+@@ -104,31 +113,36 @@ static int parse_mpls(struct action_util *a, int *argc_p, char ***argv_p,
+ 			action = TCA_MPLS_ACT_DEC_TTL;
+ 		} else if (matches(*argv, "label") == 0) {
+ 			if (!can_modify_mpls_fields(action))
+-				invarg("only valid for push/modify", *argv);
++				invarg("only valid for push, mac_push and modify",
++				       *argv);
+ 			NEXT_ARG();
+ 			if (get_u32(&label, *argv, 0) || !is_valid_label(label))
+ 				invarg("label must be <=0xFFFFF", *argv);
+ 		} else if (matches(*argv, "tc") == 0) {
+ 			if (!can_modify_mpls_fields(action))
+-				invarg("only valid for push/modify", *argv);
++				invarg("only valid for push, mac_push and modify",
++				       *argv);
+ 			NEXT_ARG();
+ 			if (get_u8(&tc, *argv, 0) || (tc & ~0x7))
+ 				invarg("tc field is 3 bits max", *argv);
+ 		} else if (matches(*argv, "ttl") == 0) {
+ 			if (!can_modify_mpls_fields(action))
+-				invarg("only valid for push/modify", *argv);
++				invarg("only valid for push, mac_push and modify",
++				       *argv);
+ 			NEXT_ARG();
+ 			if (get_u8(&ttl, *argv, 0) || !ttl)
+ 				invarg("ttl must be >0 and <=255", *argv);
+ 		} else if (matches(*argv, "bos") == 0) {
+ 			if (!can_modify_mpls_fields(action))
+-				invarg("only valid for push/modify", *argv);
++				invarg("only valid for push, mac_push and modify",
++				       *argv);
+ 			NEXT_ARG();
+ 			if (get_u8(&bos, *argv, 0) || (bos & ~0x1))
+ 				invarg("bos must be 0 or 1", *argv);
+ 		} else if (matches(*argv, "protocol") == 0) {
+-			if (!can_modify_ethtype(action))
+-				invarg("only valid for push/pop", *argv);
++			if (!can_set_ethtype(action))
++				invarg("only valid for push, mac_push and pop",
++				       *argv);
+ 			NEXT_ARG();
+ 			if (ll_proto_a2n(&proto, *argv))
+ 				invarg("protocol is invalid", *argv);
+@@ -159,10 +173,12 @@ static int parse_mpls(struct action_util *a, int *argc_p, char ***argv_p,
+ 	if (action == TCA_MPLS_ACT_PUSH && label == 0xffffffff)
+ 		missarg("label");
+ 
+-	if (action == TCA_MPLS_ACT_PUSH && proto &&
++	if ((action == TCA_MPLS_ACT_PUSH || action == TCA_MPLS_ACT_MAC_PUSH) &&
++	    proto &&
+ 	    proto != htons(ETH_P_MPLS_UC) && proto != htons(ETH_P_MPLS_MC)) {
+ 		fprintf(stderr,
+-			"invalid push protocol \"0x%04x\" - use mpls_(uc|mc)\n",
++			"invalid %spush protocol \"0x%04x\" - use mpls_(uc|mc)\n",
++			action == TCA_MPLS_ACT_MAC_PUSH ? "mac_" : "",
+ 			ntohs(proto));
+ 		return -1;
+ 	}
+@@ -223,6 +239,7 @@ static int print_mpls(struct action_util *au, FILE *f, struct rtattr *arg)
+ 		}
+ 		break;
+ 	case TCA_MPLS_ACT_PUSH:
++	case TCA_MPLS_ACT_MAC_PUSH:
+ 		if (tb[TCA_MPLS_PROTO]) {
+ 			__u16 proto;
+ 
+diff --git a/testsuite/tests/tc/mpls.t b/testsuite/tests/tc/mpls.t
+new file mode 100755
+index 00000000..cb25f361
+--- /dev/null
++++ b/testsuite/tests/tc/mpls.t
+@@ -0,0 +1,69 @@
++#!/bin/sh
++
++. lib/generic.sh
++
++DEV="$(rand_dev)"
++ts_ip "$0" "Add $DEV dummy interface" link add dev $DEV up type dummy
++ts_tc "$0" "Add ingress qdisc" qdisc add dev $DEV ingress
++
++reset_qdisc()
++{
++	ts_tc "$0" "Remove ingress qdisc" qdisc del dev $DEV ingress
++	ts_tc "$0" "Add ingress qdisc" qdisc add dev $DEV ingress
++}
++
++ts_tc "$0" "Add mpls action pop"                              \
++	filter add dev $DEV ingress protocol mpls_uc matchall \
++	action mpls pop protocol ip
++ts_tc "$0" "Show ingress filters" filter show dev $DEV ingress
++test_on "mpls"
++test_on "pop protocol ip pipe"
++
++reset_qdisc
++ts_tc "$0" "Add mpls action push"                        \
++	filter add dev $DEV ingress protocol ip matchall \
++	action mpls push protocol mpls_uc label 20 tc 3 bos 1 ttl 64
++ts_tc "$0" "Show ingress filters" filter show dev $DEV ingress
++test_on "mpls"
++test_on "push"
++test_on "protocol mpls_uc"
++test_on "label 20"
++test_on "tc 3"
++test_on "bos 1"
++test_on "ttl 64"
++test_on "pipe"
++
++reset_qdisc
++ts_tc "$0" "Add mpls action mac_push"        \
++	filter add dev $DEV ingress matchall \
++	action mpls mac_push protocol mpls_uc label 20 tc 3 bos 1 ttl 64
++ts_tc "$0" "Show ingress filters" filter show dev $DEV ingress
++test_on "mpls"
++test_on "mac_push"
++test_on "protocol mpls_uc"
++test_on "label 20"
++test_on "tc 3"
++test_on "bos 1"
++test_on "ttl 64"
++test_on "pipe"
++
++reset_qdisc
++ts_tc "$0" "Add mpls action modify"                           \
++	filter add dev $DEV ingress protocol mpls_uc matchall \
++	action mpls modify label 20 tc 3 ttl 64
++ts_tc "$0" "Show ingress filters" filter show dev $DEV ingress
++test_on "mpls"
++test_on "modify"
++test_on "label 20"
++test_on "tc 3"
++test_on "ttl 64"
++test_on "pipe"
++
++reset_qdisc
++ts_tc "$0" "Add mpls action dec_ttl"                          \
++	filter add dev $DEV ingress protocol mpls_uc matchall \
++	action mpls dec_ttl
++ts_tc "$0" "Show ingress filters" filter show dev $DEV ingress
++test_on "mpls"
++test_on "dec_ttl"
++test_on "pipe"
+-- 
+2.29.2
+
diff --git a/SOURCES/0004-man-rdma-statistic-Add-filter-description.patch b/SOURCES/0004-man-rdma-statistic-Add-filter-description.patch
deleted file mode 100644
index 9b805b9..0000000
--- a/SOURCES/0004-man-rdma-statistic-Add-filter-description.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-From f0596659bb2ba71bbe6ec80df9d54ea02775f40f Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 23 Apr 2020 12:47:12 +0200
-Subject: [PATCH] man: rdma-statistic: Add filter description
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1786565
-Upstream Status: iproute2.git commit 31824e2299bf5
-
-commit 31824e2299bf5dc609026436db629b0c25cc1a10
-Author: Andrea Claudi <aclaudi@redhat.com>
-Date:   Fri Feb 28 18:36:25 2020 +0100
-
-    man: rdma-statistic: Add filter description
-
-    Add description for filters on rdma statistics show command.
-    Also add a filter description on the help message of the command.
-    Additionally, fix some whitespace issue in the man page.
-
-    Reported-by: Zhaojuan Guo <zguo@redhat.com>
-    Signed-off-by: Andrea Claudi <aclaudi@redhat.com>
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
----
- man/man8/rdma-statistic.8 | 16 ++++++++++++----
- rdma/stat.c               |  1 +
- 2 files changed, 13 insertions(+), 4 deletions(-)
-
-diff --git a/man/man8/rdma-statistic.8 b/man/man8/rdma-statistic.8
-index dea6ff24b499b..cd85ca46993a0 100644
---- a/man/man8/rdma-statistic.8
-+++ b/man/man8/rdma-statistic.8
-@@ -9,7 +9,7 @@ rdma-statistic \- RDMA statistic counter configuration
- .B rdma
- .RI "[ " OPTIONS " ]"
- .B statistic
--.RI  " { " COMMAND " | "
-+.RI  "{ " COMMAND " | "
- .BR help " }"
- .sp
- 
-@@ -23,6 +23,7 @@ rdma-statistic \- RDMA statistic counter configuration
- .RI "[ " OBJECT " ]"
- .B show link
- .RI "[ " DEV/PORT_INDX " ]"
-+.RI "[ " FILTER_NAME " " FILTER_VALUE " ]"
- 
- .ti -8
- .B rdma statistic
-@@ -34,7 +35,7 @@ rdma-statistic \- RDMA statistic counter configuration
- .IR OBJECT
- .B set
- .IR COUNTER_SCOPE
--.RI "[ " DEV/PORT_INDEX "]"
-+.RI "[ " DEV/PORT_INDEX " ]"
- .B auto
- .RI "{ " CRITERIA " | "
- .BR off " }"
-@@ -44,7 +45,7 @@ rdma-statistic \- RDMA statistic counter configuration
- .IR OBJECT
- .B bind
- .IR COUNTER_SCOPE
--.RI "[ " DEV/PORT_INDEX "]"
-+.RI "[ " DEV/PORT_INDEX " ]"
- .RI "[ " OBJECT-ID " ]"
- .RI "[ " COUNTER-ID " ]"
- 
-@@ -53,7 +54,7 @@ rdma-statistic \- RDMA statistic counter configuration
- .IR OBJECT
- .B unbind
- .IR COUNTER_SCOPE
--.RI "[ " DEV/PORT_INDEX "]"
-+.RI "[ " DEV/PORT_INDEX " ]"
- .RI "[ " COUNTER-ID " ]"
- .RI "[ " OBJECT-ID " ]"
- 
-@@ -69,6 +70,10 @@ rdma-statistic \- RDMA statistic counter configuration
- .IR CRITERIA " := "
- .RB "{ " type " }"
- 
-+.ti -8
-+.IR FILTER_NAME " := "
-+.RB "{ " cntn " | " lqpn " | " pid " }"
-+
- .SH "DESCRIPTION"
- .SS rdma statistic [object] show - Queries the specified RDMA device for RDMA and driver-specific statistics. Show the default hw counters if object is not specified
- 
-@@ -79,6 +84,9 @@ rdma-statistic \- RDMA statistic counter configuration
- .I "PORT_INDEX"
- - specifies counters on this RDMA port to show.
- 
-+.I "FILTER_NAME
-+- specifies a filter to show only the results matching it.
-+
- .SS rdma statistic <object> set - configure counter statistic auto-mode for a specific device/port
- In auto mode all objects belong to one category are bind automatically to a single counter set.
- 
-diff --git a/rdma/stat.c b/rdma/stat.c
-index ef0bbcf147a70..cd99b7ace73fc 100644
---- a/rdma/stat.c
-+++ b/rdma/stat.c
-@@ -22,6 +22,7 @@ static int stat_help(struct rd *rd)
- 	pr_out("where  OBJECT: = { qp }\n");
- 	pr_out("       CRITERIA : = { type }\n");
- 	pr_out("       COUNTER_SCOPE: = { link | dev }\n");
-+	pr_out("       FILTER_NAME: = { cntn | lqpn | pid }\n");
- 	pr_out("Examples:\n");
- 	pr_out("       %s statistic qp show\n", rd->filename);
- 	pr_out("       %s statistic qp show link mlx5_2/1\n", rd->filename);
--- 
-2.25.4
-
diff --git a/SOURCES/0005-m_mpls-test-the-mac_push-action-after-modify.patch b/SOURCES/0005-m_mpls-test-the-mac_push-action-after-modify.patch
new file mode 100644
index 0000000..197b3d6
--- /dev/null
+++ b/SOURCES/0005-m_mpls-test-the-mac_push-action-after-modify.patch
@@ -0,0 +1,58 @@
+From 8c66f562e88887d2bf1c1064117496c4cb862b11 Mon Sep 17 00:00:00 2001
+Message-Id: <8c66f562e88887d2bf1c1064117496c4cb862b11.1611877215.git.aclaudi@redhat.com>
+In-Reply-To: <cb7ce51cc1abd7b98370b903ec96205ebfe48661.1611877215.git.aclaudi@redhat.com>
+References: <cb7ce51cc1abd7b98370b903ec96205ebfe48661.1611877215.git.aclaudi@redhat.com>
+From: Andrea Claudi <aclaudi@redhat.com>
+Date: Fri, 29 Jan 2021 00:35:03 +0100
+Subject: [PATCH] m_mpls: test the 'mac_push' action after 'modify'
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1885770
+Upstream Status: unknown commit f1298d76
+
+commit f1298d76606a581cf3ab9ec45a92b41e72a6b4f0
+Author: Guillaume Nault <gnault@redhat.com>
+Date:   Thu Oct 22 11:11:44 2020 +0200
+
+    m_mpls: test the 'mac_push' action after 'modify'
+
+    Commit 02a261b5ba1c ("m_mpls: add mac_push action") added a matches()
+    test for the "mac_push" string before the test for "modify".
+    This changes the previous behaviour as 'action m' used to match
+    "modify" while it now matches "mac_push".
+
+    Revert to the original behaviour by moving the "mac_push" test after
+    "modify".
+
+    Fixes: 02a261b5ba1c ("m_mpls: add mac_push action")
+    Signed-off-by: Guillaume Nault <gnault@redhat.com>
+    Signed-off-by: David Ahern <dsahern@gmail.com>
+---
+ tc/m_mpls.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/tc/m_mpls.c b/tc/m_mpls.c
+index cb8019b1..2c3752ba 100644
+--- a/tc/m_mpls.c
++++ b/tc/m_mpls.c
+@@ -99,14 +99,14 @@ static int parse_mpls(struct action_util *a, int *argc_p, char ***argv_p,
+ 			if (check_double_action(action, *argv))
+ 				return -1;
+ 			action = TCA_MPLS_ACT_PUSH;
+-		} else if (matches(*argv, "mac_push") == 0) {
+-			if (check_double_action(action, *argv))
+-				return -1;
+-			action = TCA_MPLS_ACT_MAC_PUSH;
+ 		} else if (matches(*argv, "modify") == 0) {
+ 			if (check_double_action(action, *argv))
+ 				return -1;
+ 			action = TCA_MPLS_ACT_MODIFY;
++		} else if (matches(*argv, "mac_push") == 0) {
++			if (check_double_action(action, *argv))
++				return -1;
++			action = TCA_MPLS_ACT_MAC_PUSH;
+ 		} else if (matches(*argv, "dec_ttl") == 0) {
+ 			if (check_double_action(action, *argv))
+ 				return -1;
+-- 
+2.29.2
+
diff --git a/SOURCES/0005-man-rdma.8-Add-missing-resource-subcommand-descripti.patch b/SOURCES/0005-man-rdma.8-Add-missing-resource-subcommand-descripti.patch
deleted file mode 100644
index 2a64a79..0000000
--- a/SOURCES/0005-man-rdma.8-Add-missing-resource-subcommand-descripti.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From 44362b42a40ed0f3a3598f55318ed4b0c9f8eb94 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 23 Apr 2020 12:49:03 +0200
-Subject: [PATCH] man: rdma.8: Add missing resource subcommand description
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1786576
-Upstream Status: iproute2.git commit 8f1c9d4a3c0d4
-
-commit 8f1c9d4a3c0d4e720026b942c922372b3c12e110
-Author: Andrea Claudi <aclaudi@redhat.com>
-Date:   Fri Feb 28 18:36:24 2020 +0100
-
-    man: rdma.8: Add missing resource subcommand description
-
-    Add resource subcommand in the OBJECT section and a short
-    description for it.
-
-    Reported-by: Zhaojuan Guo <zguo@redhat.com>
-    Signed-off-by: Andrea Claudi <aclaudi@redhat.com>
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
----
- man/man8/rdma.8 | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
-diff --git a/man/man8/rdma.8 b/man/man8/rdma.8
-index ef29b1c633644..221bf3343bf4c 100644
---- a/man/man8/rdma.8
-+++ b/man/man8/rdma.8
-@@ -19,7 +19,7 @@ rdma \- RDMA tool
- 
- .ti -8
- .IR OBJECT " := { "
--.BR dev " | " link " | " system " | " statistic " }"
-+.BR dev " | " link " | " resource " | " system " | " statistic " }"
- .sp
- 
- .ti -8
-@@ -70,6 +70,10 @@ Generate JSON output.
- .B link
- - RDMA port related.
- 
-+.TP
-+.B resource
-+- RDMA resource configuration.
-+
- .TP
- .B sys
- - RDMA subsystem related.
--- 
-2.25.4
-
diff --git a/SOURCES/0006-ip-xfrm-Fix-help-messages.patch b/SOURCES/0006-ip-xfrm-Fix-help-messages.patch
deleted file mode 100644
index 11858c1..0000000
--- a/SOURCES/0006-ip-xfrm-Fix-help-messages.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From 028ce3bafd9c8415a0cd72ff135f9498d833db21 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Wed, 15 Apr 2020 19:09:48 +0200
-Subject: [PATCH] ip-xfrm: Fix help messages
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1796045
-Upstream Status: iproute2.git commit 38dd041bfe773
-
-commit 38dd041bfe773e481ebf9c8250e49c665af2e215
-Author: Andrea Claudi <aclaudi@redhat.com>
-Date:   Wed Jan 29 15:56:40 2020 +0100
-
-    ip-xfrm: Fix help messages
-
-    After commit 8589eb4efdf2a ("treewide: refactor help messages") help
-    messages for xfrm state and policy are broken, printing many times the
-    same protocol in UPSPEC section:
-
-    $ ip xfrm state help
-    [...]
-    UPSPEC := proto { { tcp | tcp | tcp | tcp } [ sport PORT ] [ dport PORT ] |
-                      { icmp | icmp | icmp } [ type NUMBER ] [ code NUMBER ] |
-                      gre [ key { DOTTED-QUAD | NUMBER } ] | PROTO }
-
-    This happens because strxf_proto function is non-reentrant and gets called
-    multiple times in the same fprintf instruction.
-
-    This commit fix the issue avoiding calls to strxf_proto() with a constant
-    param, just hardcoding strings for protocol names.
-
-    Fixes: 8589eb4efdf2a ("treewide: refactor help messages")
-    Signed-off-by: Andrea Claudi <aclaudi@redhat.com>
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
----
- ip/xfrm_policy.c | 21 +++------------------
- ip/xfrm_state.c  | 24 +++---------------------
- 2 files changed, 6 insertions(+), 39 deletions(-)
-
-diff --git a/ip/xfrm_policy.c b/ip/xfrm_policy.c
-index 7c0233c182902..d3c706d3225f0 100644
---- a/ip/xfrm_policy.c
-+++ b/ip/xfrm_policy.c
-@@ -66,24 +66,9 @@ static void usage(void)
- 		"Usage: ip xfrm policy count\n"
- 		"Usage: ip xfrm policy set [ hthresh4 LBITS RBITS ] [ hthresh6 LBITS RBITS ]\n"
- 		"SELECTOR := [ src ADDR[/PLEN] ] [ dst ADDR[/PLEN] ] [ dev DEV ] [ UPSPEC ]\n"
--		"UPSPEC := proto { { ");
--	fprintf(stderr, "%s | %s | %s | %s } ",
--		strxf_proto(IPPROTO_TCP),
--		strxf_proto(IPPROTO_UDP),
--		strxf_proto(IPPROTO_SCTP),
--		strxf_proto(IPPROTO_DCCP));
--	fprintf(stderr,
--		"[ sport PORT ] [ dport PORT ] |\n"
--		"                  { %s | %s | %s } ",
--		strxf_proto(IPPROTO_ICMP),
--		strxf_proto(IPPROTO_ICMPV6),
--		strxf_proto(IPPROTO_MH));
--	fprintf(stderr,
--		"[ type NUMBER ] [ code NUMBER ] |\n"
--		"                  %s",
--		strxf_proto(IPPROTO_GRE));
--	fprintf(stderr,
--		" [ key { DOTTED-QUAD | NUMBER } ] | PROTO }\n"
-+		"UPSPEC := proto { { tcp | udp | sctp | dccp } [ sport PORT ] [ dport PORT ] |\n"
-+		"                  { icmp | ipv6-icmp | mobility-header } [ type NUMBER ] [ code NUMBER ] |\n"
-+		"                  gre [ key { DOTTED-QUAD | NUMBER } ] | PROTO }\n"
- 		"DIR := in | out | fwd\n"
- 		"PTYPE := main | sub\n"
- 		"ACTION := allow | block\n"
-diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c
-index b03ccc5807e90..7b413cd9b9a22 100644
---- a/ip/xfrm_state.c
-+++ b/ip/xfrm_state.c
-@@ -106,27 +106,9 @@ static void usage(void)
- 		"EXTRA-FLAG-LIST := [ EXTRA-FLAG-LIST ] EXTRA-FLAG\n"
- 		"EXTRA-FLAG := dont-encap-dscp\n"
- 		"SELECTOR := [ src ADDR[/PLEN] ] [ dst ADDR[/PLEN] ] [ dev DEV ] [ UPSPEC ]\n"
--		"UPSPEC := proto { { ");
--	fprintf(stderr,
--		"%s | %s | %s | %s",
--		strxf_proto(IPPROTO_TCP),
--		strxf_proto(IPPROTO_UDP),
--		strxf_proto(IPPROTO_SCTP),
--		strxf_proto(IPPROTO_DCCP));
--	fprintf(stderr,
--		" } [ sport PORT ] [ dport PORT ] |\n"
--		"                  { ");
--	fprintf(stderr,
--		"%s | %s | %s",
--		strxf_proto(IPPROTO_ICMP),
--		strxf_proto(IPPROTO_ICMPV6),
--		strxf_proto(IPPROTO_MH));
--	fprintf(stderr,
--		" } [ type NUMBER ] [ code NUMBER ] |\n");
--	fprintf(stderr,
--		"                  %s", strxf_proto(IPPROTO_GRE));
--	fprintf(stderr,
--		" [ key { DOTTED-QUAD | NUMBER } ] | PROTO }\n"
-+		"UPSPEC := proto { { tcp | udp | sctp | dccp } [ sport PORT ] [ dport PORT ] |\n"
-+		"                  { icmp | ipv6-icmp | mobility-header } [ type NUMBER ] [ code NUMBER ] |\n"
-+		"                  gre [ key { DOTTED-QUAD | NUMBER } ] | PROTO }\n"
- 		"LIMIT-LIST := [ LIMIT-LIST ] limit LIMIT\n"
- 		"LIMIT := { time-soft | time-hard | time-use-soft | time-use-hard } SECONDS |\n"
- 		"         { byte-soft | byte-hard } SIZE | { packet-soft | packet-hard } COUNT\n"
--- 
-2.25.4
-
diff --git a/SOURCES/0006-tc-vlan-fix-help-and-error-message-strings.patch b/SOURCES/0006-tc-vlan-fix-help-and-error-message-strings.patch
new file mode 100644
index 0000000..a70ac17
--- /dev/null
+++ b/SOURCES/0006-tc-vlan-fix-help-and-error-message-strings.patch
@@ -0,0 +1,52 @@
+From cdb8197d0e7380b3679ded6bab398883aead92dc Mon Sep 17 00:00:00 2001
+Message-Id: <cdb8197d0e7380b3679ded6bab398883aead92dc.1611877215.git.aclaudi@redhat.com>
+In-Reply-To: <cb7ce51cc1abd7b98370b903ec96205ebfe48661.1611877215.git.aclaudi@redhat.com>
+References: <cb7ce51cc1abd7b98370b903ec96205ebfe48661.1611877215.git.aclaudi@redhat.com>
+From: Andrea Claudi <aclaudi@redhat.com>
+Date: Fri, 29 Jan 2021 00:35:03 +0100
+Subject: [PATCH] tc-vlan: fix help and error message strings
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1885770
+Upstream Status: unknown commit 7c7a0fe0
+
+commit 7c7a0fe0c81cdff258c4314c629d7a52ae331dc4
+Author: Guillaume Nault <gnault@redhat.com>
+Date:   Mon Nov 2 11:59:46 2020 +0100
+
+    tc-vlan: fix help and error message strings
+
+    * "vlan pop" can be followed by a CONTROL keyword.
+
+     * Add missing space in error message.
+
+    Signed-off-by: Guillaume Nault <gnault@redhat.com>
+    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
+---
+ tc/m_vlan.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tc/m_vlan.c b/tc/m_vlan.c
+index e6b21330..57722b73 100644
+--- a/tc/m_vlan.c
++++ b/tc/m_vlan.c
+@@ -30,7 +30,7 @@ static const char * const action_names[] = {
+ static void explain(void)
+ {
+ 	fprintf(stderr,
+-		"Usage: vlan pop\n"
++		"Usage: vlan pop [CONTROL]\n"
+ 		"       vlan push [ protocol VLANPROTO ] id VLANID [ priority VLANPRIO ] [CONTROL]\n"
+ 		"       vlan modify [ protocol VLANPROTO ] id VLANID [ priority VLANPRIO ] [CONTROL]\n"
+ 		"       vlan pop_eth [CONTROL]\n"
+@@ -244,7 +244,7 @@ static int print_vlan(struct action_util *au, FILE *f, struct rtattr *arg)
+ 	parse_rtattr_nested(tb, TCA_VLAN_MAX, arg);
+ 
+ 	if (!tb[TCA_VLAN_PARMS]) {
+-		fprintf(stderr, "Missing vlanparameters\n");
++		fprintf(stderr, "Missing vlan parameters\n");
+ 		return -1;
+ 	}
+ 	parm = RTA_DATA(tb[TCA_VLAN_PARMS]);
+-- 
+2.29.2
+
diff --git a/SOURCES/0007-tc-mpls-fix-manpage-example-and-help-message-string.patch b/SOURCES/0007-tc-mpls-fix-manpage-example-and-help-message-string.patch
new file mode 100644
index 0000000..a53a799
--- /dev/null
+++ b/SOURCES/0007-tc-mpls-fix-manpage-example-and-help-message-string.patch
@@ -0,0 +1,82 @@
+From 8953735b551d5f3c18c9523ea24055f4a7f9b927 Mon Sep 17 00:00:00 2001
+Message-Id: <8953735b551d5f3c18c9523ea24055f4a7f9b927.1611877215.git.aclaudi@redhat.com>
+In-Reply-To: <cb7ce51cc1abd7b98370b903ec96205ebfe48661.1611877215.git.aclaudi@redhat.com>
+References: <cb7ce51cc1abd7b98370b903ec96205ebfe48661.1611877215.git.aclaudi@redhat.com>
+From: Andrea Claudi <aclaudi@redhat.com>
+Date: Fri, 29 Jan 2021 00:35:03 +0100
+Subject: [PATCH] tc-mpls: fix manpage example and help message string
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1885770
+Upstream Status: unknown commit 8682f588
+
+commit 8682f588bfed7862233a22626562696d662ca60c
+Author: Guillaume Nault <gnault@redhat.com>
+Date:   Mon Nov 2 12:24:25 2020 +0100
+
+    tc-mpls: fix manpage example and help message string
+
+    Manpage:
+     * Remove the extra "and to ip packets" part from command description
+       to make it more understandable.
+
+     * Redirect packets to eth1, instead of eth0, as told in the
+       description.
+
+    Help string:
+     * "mpls pop" can be followed by a CONTROL keyword.
+
+     * "mpls modify" can also set the MPLS_BOS field.
+
+    Signed-off-by: Guillaume Nault <gnault@redhat.com>
+    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
+---
+ man/man8/tc-mpls.8 | 6 +++---
+ tc/m_mpls.c        | 5 +++--
+ 2 files changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/man/man8/tc-mpls.8 b/man/man8/tc-mpls.8
+index 9e563e98..7f8be221 100644
+--- a/man/man8/tc-mpls.8
++++ b/man/man8/tc-mpls.8
+@@ -147,15 +147,15 @@ a label 123 and sends them out eth1:
+ .EE
+ .RE
+ 
+-In this example, incoming MPLS unicast packets on eth0 are decapsulated and to
+-ip packets and output to eth1:
++In this example, incoming MPLS unicast packets on eth0 are decapsulated
++and redirected to eth1:
+ 
+ .RS
+ .EX
+ #tc qdisc add dev eth0 handle ffff: ingress
+ #tc filter add dev eth0 protocol mpls_uc parent ffff: flower \\
+ 	action mpls pop protocol ipv4  \\
+-	action mirred egress redirect dev eth0
++	action mirred egress redirect dev eth1
+ .EE
+ .RE
+ 
+diff --git a/tc/m_mpls.c b/tc/m_mpls.c
+index 2c3752ba..9fee22e3 100644
+--- a/tc/m_mpls.c
++++ b/tc/m_mpls.c
+@@ -23,12 +23,13 @@ static const char * const action_names[] = {
+ static void explain(void)
+ {
+ 	fprintf(stderr,
+-		"Usage: mpls pop [ protocol MPLS_PROTO ]\n"
++		"Usage: mpls pop [ protocol MPLS_PROTO ] [CONTROL]\n"
+ 		"       mpls push [ protocol MPLS_PROTO ] [ label MPLS_LABEL ] [ tc MPLS_TC ]\n"
+ 		"                 [ ttl MPLS_TTL ] [ bos MPLS_BOS ] [CONTROL]\n"
+ 		"       mpls mac_push [ protocol MPLS_PROTO ] [ label MPLS_LABEL ] [ tc MPLS_TC ]\n"
+ 		"                     [ ttl MPLS_TTL ] [ bos MPLS_BOS ] [CONTROL]\n"
+-		"       mpls modify [ label MPLS_LABEL ] [ tc MPLS_TC ] [ ttl MPLS_TTL ] [CONTROL]\n"
++		"       mpls modify [ label MPLS_LABEL ] [ tc MPLS_TC ] [ ttl MPLS_TTL ]\n"
++		"                   [ bos MPLS_BOS ] [CONTROL]\n"
+ 		"           for pop, MPLS_PROTO is next header of packet - e.g. ip or mpls_uc\n"
+ 		"           for push and mac_push, MPLS_PROTO is one of mpls_uc or mpls_mc\n"
+ 		"               with default: mpls_uc\n"
+-- 
+2.29.2
+
diff --git a/SOURCES/0007-xfrm-not-try-to-delete-ipcomp-states-when-using-dele.patch b/SOURCES/0007-xfrm-not-try-to-delete-ipcomp-states-when-using-dele.patch
deleted file mode 100644
index 66d479f..0000000
--- a/SOURCES/0007-xfrm-not-try-to-delete-ipcomp-states-when-using-dele.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 7c1351ea866ec811ade4452b5f1791b34b0effe3 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 16 Apr 2020 12:10:23 +0200
-Subject: [PATCH] xfrm: not try to delete ipcomp states when using deleteall
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1808634
-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 7b413cd9b9a22..d014444e9af4f 100644
---- a/ip/xfrm_state.c
-+++ b/ip/xfrm_state.c
-@@ -1131,6 +1131,9 @@ static int xfrm_state_keep(struct nlmsghdr *n, void *arg)
- 	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.4
-
diff --git a/SOURCES/0008-man-ip.8-Add-missing-vrf-subcommand-description.patch b/SOURCES/0008-man-ip.8-Add-missing-vrf-subcommand-description.patch
deleted file mode 100644
index 0a36572..0000000
--- a/SOURCES/0008-man-ip.8-Add-missing-vrf-subcommand-description.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From 310becad3223411bc26e0401a838f2a7063406f3 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 23 Apr 2020 18:56:14 +0200
-Subject: [PATCH] man: ip.8: Add missing vrf subcommand description
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1780010
-Upstream Status: iproute2.git commit 229bb886a3c44
-
-commit 229bb886a3c4444521eca16c7ab74a539aaf9cb4
-Author: Andrea Claudi <aclaudi@redhat.com>
-Date:   Thu Feb 27 17:45:43 2020 +0100
-
-    man: ip.8: Add missing vrf subcommand description
-
-    Add description to the vrf subcommand and a reference to the
-    dedicated man page.
-
-    Signed-off-by: Andrea Claudi <aclaudi@redhat.com>
-    Reviewed-by: David Ahern <dsahern@gmail.com>
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
----
- man/man8/ip.8 | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
-diff --git a/man/man8/ip.8 b/man/man8/ip.8
-index e2bda2a2ea904..c425aaf1d506e 100644
---- a/man/man8/ip.8
-+++ b/man/man8/ip.8
-@@ -22,7 +22,7 @@ ip \- show / manipulate routing, network devices, interfaces and tunnels
- .BR link " | " address " | " addrlabel " | " route " | " rule " | " neigh " | "\
-  ntable " | " tunnel " | " tuntap " | " maddress " | "  mroute " | " mrule " | "\
-  monitor " | " xfrm " | " netns " | "  l2tp " | "  tcp_metrics " | " token " | "\
-- macsec " }"
-+ macsec " | " vrf " }"
- .sp
- 
- .ti -8
-@@ -312,6 +312,10 @@ readability.
- .B tuntap
- - manage TUN/TAP devices.
- 
-+.TP
-+.B vrf
-+- manage virtual routing and forwarding devices.
-+
- .TP
- .B xfrm
- - manage IPSec policies.
-@@ -411,6 +415,7 @@ was written by Alexey N. Kuznetsov and added in Linux 2.2.
- .BR ip-tcp_metrics (8),
- .BR ip-token (8),
- .BR ip-tunnel (8),
-+.BR ip-vrf (8),
- .BR ip-xfrm (8)
- .br
- .RB "IP Command reference " ip-cref.ps
--- 
-2.25.4
-
diff --git a/SOURCES/0008-tc-flower-fix-json-output-with-mpls-lse.patch b/SOURCES/0008-tc-flower-fix-json-output-with-mpls-lse.patch
new file mode 100644
index 0000000..3c57d58
--- /dev/null
+++ b/SOURCES/0008-tc-flower-fix-json-output-with-mpls-lse.patch
@@ -0,0 +1,120 @@
+From 52754e4b7d4b52e9852869d7e2f6af1b890677f1 Mon Sep 17 00:00:00 2001
+Message-Id: <52754e4b7d4b52e9852869d7e2f6af1b890677f1.1611877215.git.aclaudi@redhat.com>
+In-Reply-To: <cb7ce51cc1abd7b98370b903ec96205ebfe48661.1611877215.git.aclaudi@redhat.com>
+References: <cb7ce51cc1abd7b98370b903ec96205ebfe48661.1611877215.git.aclaudi@redhat.com>
+From: Andrea Claudi <aclaudi@redhat.com>
+Date: Fri, 29 Jan 2021 00:35:04 +0100
+Subject: [PATCH] tc: flower: fix json output with mpls lse
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1885770
+Upstream Status: unknown commit 676a1a70
+
+commit 676a1a708f8e99d6a4faa3de8a093f8f8c14b9da
+Author: Guillaume Nault <gnault@redhat.com>
+Date:   Tue Jan 12 11:30:53 2021 +0100
+
+    tc: flower: fix json output with mpls lse
+
+    The json output of the TCA_FLOWER_KEY_MPLS_OPTS attribute was invalid.
+
+    Example:
+
+      $ tc filter add dev eth0 ingress protocol mpls_uc flower mpls \
+          lse depth 1 label 100                                     \
+          lse depth 2 label 200
+
+      $ tc -json filter show dev eth0 ingress
+        ...{"eth_type":"8847",
+            "  mpls":["    lse":["depth":1,"label":100],
+                      "    lse":["depth":2,"label":200]]}...
+
+    This is invalid as the arrays, introduced by "[", can't contain raw
+    string:value pairs. Those must be enclosed into "{}" to form valid json
+    ojects. Also, there are spurious whitespaces before the mpls and lse
+    strings because of the indentation used for normal output.
+
+    Fix this by putting all LSE parameters (depth, label, tc, bos and ttl)
+    into the same json object. The "mpls" key now directly contains a list
+    of such objects.
+
+    Also, handle strings differently for normal and json output, so that
+    json strings don't get spurious indentation whitespaces.
+
+    Normal output isn't modified.
+    The json output now looks like:
+
+      $ tc -json filter show dev eth0 ingress
+        ...{"eth_type":"8847",
+            "mpls":[{"depth":1,"label":100},
+                    {"depth":2,"label":200}]}...
+
+    Fixes: eb09a15c12fb ("tc: flower: support multiple MPLS LSE match")
+    Signed-off-by: Guillaume Nault <gnault@redhat.com>
+    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
+---
+ tc/f_flower.c | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/tc/f_flower.c b/tc/f_flower.c
+index 00c919fd..27731078 100644
+--- a/tc/f_flower.c
++++ b/tc/f_flower.c
+@@ -2476,7 +2476,7 @@ static void flower_print_u32(const char *name, struct rtattr *attr)
+ 	print_uint(PRINT_ANY, name, namefrm, rta_getattr_u32(attr));
+ }
+ 
+-static void flower_print_mpls_opt_lse(const char *name, struct rtattr *lse)
++static void flower_print_mpls_opt_lse(struct rtattr *lse)
+ {
+ 	struct rtattr *tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_MAX + 1];
+ 	struct rtattr *attr;
+@@ -2493,7 +2493,8 @@ static void flower_print_mpls_opt_lse(const char *name, struct rtattr *lse)
+ 		     RTA_PAYLOAD(lse));
+ 
+ 	print_nl();
+-	open_json_array(PRINT_ANY, name);
++	print_string(PRINT_FP, NULL, "    lse", NULL);
++	open_json_object(NULL);
+ 	attr = tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_DEPTH];
+ 	if (attr)
+ 		print_hhu(PRINT_ANY, "depth", " depth %u",
+@@ -2511,10 +2512,10 @@ static void flower_print_mpls_opt_lse(const char *name, struct rtattr *lse)
+ 	attr = tb[TCA_FLOWER_KEY_MPLS_OPT_LSE_TTL];
+ 	if (attr)
+ 		print_hhu(PRINT_ANY, "ttl", " ttl %u", rta_getattr_u8(attr));
+-	close_json_array(PRINT_JSON, NULL);
++	close_json_object();
+ }
+ 
+-static void flower_print_mpls_opts(const char *name, struct rtattr *attr)
++static void flower_print_mpls_opts(struct rtattr *attr)
+ {
+ 	struct rtattr *lse;
+ 	int rem;
+@@ -2523,11 +2524,12 @@ static void flower_print_mpls_opts(const char *name, struct rtattr *attr)
+ 		return;
+ 
+ 	print_nl();
+-	open_json_array(PRINT_ANY, name);
++	print_string(PRINT_FP, NULL, "  mpls", NULL);
++	open_json_array(PRINT_JSON, "mpls");
+ 	rem = RTA_PAYLOAD(attr);
+ 	lse = RTA_DATA(attr);
+ 	while (RTA_OK(lse, rem)) {
+-		flower_print_mpls_opt_lse("    lse", lse);
++		flower_print_mpls_opt_lse(lse);
+ 		lse = RTA_NEXT(lse, rem);
+ 	};
+ 	if (rem)
+@@ -2650,7 +2652,7 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
+ 	flower_print_ip_attr("ip_ttl", tb[TCA_FLOWER_KEY_IP_TTL],
+ 			    tb[TCA_FLOWER_KEY_IP_TTL_MASK]);
+ 
+-	flower_print_mpls_opts("  mpls", tb[TCA_FLOWER_KEY_MPLS_OPTS]);
++	flower_print_mpls_opts(tb[TCA_FLOWER_KEY_MPLS_OPTS]);
+ 	flower_print_u32("mpls_label", tb[TCA_FLOWER_KEY_MPLS_LABEL]);
+ 	flower_print_u8("mpls_tc", tb[TCA_FLOWER_KEY_MPLS_TC]);
+ 	flower_print_u8("mpls_bos", tb[TCA_FLOWER_KEY_MPLS_BOS]);
+-- 
+2.29.2
+
diff --git a/SOURCES/0009-iproute-force-rtm_dst_len-to-32-128.patch b/SOURCES/0009-iproute-force-rtm_dst_len-to-32-128.patch
new file mode 100644
index 0000000..c5aee30
--- /dev/null
+++ b/SOURCES/0009-iproute-force-rtm_dst_len-to-32-128.patch
@@ -0,0 +1,67 @@
+From f2cb0f1570ca603c5d92d6a7d87596d07fdb01cd Mon Sep 17 00:00:00 2001
+Message-Id: <f2cb0f1570ca603c5d92d6a7d87596d07fdb01cd.1612868485.git.aclaudi@redhat.com>
+In-Reply-To: <cb7ce51cc1abd7b98370b903ec96205ebfe48661.1612868485.git.aclaudi@redhat.com>
+References: <cb7ce51cc1abd7b98370b903ec96205ebfe48661.1612868485.git.aclaudi@redhat.com>
+From: Andrea Claudi <aclaudi@redhat.com>
+Date: Tue, 9 Feb 2021 12:00:58 +0100
+Subject: [PATCH] iproute: force rtm_dst_len to 32/128
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1852038
+Upstream Status: unknown commit 5a37254b
+
+commit 5a37254b71249bfb73d44d6278d767a6b127a2f9
+Author: Luca Boccassi <bluca@debian.org>
+Date:   Sun Jan 24 17:36:58 2021 +0000
+
+    iproute: force rtm_dst_len to 32/128
+
+    Since NETLINK_GET_STRICT_CHK was enabled, the kernel rejects commands
+    that pass a prefix length, eg:
+
+     ip route get `1.0.0.0/1
+      Error: ipv4: Invalid values in header for route get request.
+     ip route get 0.0.0.0/0
+      Error: ipv4: rtm_src_len and rtm_dst_len must be 32 for IPv4
+
+    Since there's no point in setting a rtm_dst_len that we know is going
+    to be rejected, just force it to the right value if it's passed on
+    the command line. Print a warning to stderr to notify users.
+
+    Bug-Debian: https://bugs.debian.org/944730
+    Reported-By: Clément 'wxcafé' Hertling <wxcafe@wxcafe.net>
+    Signed-off-by: Luca Boccassi <bluca@debian.org>
+    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
+---
+ ip/iproute.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/ip/iproute.c b/ip/iproute.c
+index 05ec2c29..1f3c347e 100644
+--- a/ip/iproute.c
++++ b/ip/iproute.c
+@@ -2067,7 +2067,18 @@ static int iproute_get(int argc, char **argv)
+ 			if (addr.bytelen)
+ 				addattr_l(&req.n, sizeof(req),
+ 					  RTA_DST, &addr.data, addr.bytelen);
+-			req.r.rtm_dst_len = addr.bitlen;
++			if (req.r.rtm_family == AF_INET && addr.bitlen != 32) {
++				fprintf(stderr,
++					"Warning: /%u as prefix is invalid, only /32 (or none) is supported.\n",
++					addr.bitlen);
++				req.r.rtm_dst_len = 32;
++			} else if (req.r.rtm_family == AF_INET6 && addr.bitlen != 128) {
++				fprintf(stderr,
++					"Warning: /%u as prefix is invalid, only /128 (or none) is supported.\n",
++					addr.bitlen);
++				req.r.rtm_dst_len = 128;
++			} else
++				req.r.rtm_dst_len = addr.bitlen;
+ 			address_found = true;
+ 		}
+ 		argc--; argv++;
+-- 
+2.29.2
+
diff --git a/SOURCES/0009-nstat-print-useful-error-messages-in-abort-cases.patch b/SOURCES/0009-nstat-print-useful-error-messages-in-abort-cases.patch
deleted file mode 100644
index 8e439d5..0000000
--- a/SOURCES/0009-nstat-print-useful-error-messages-in-abort-cases.patch
+++ /dev/null
@@ -1,122 +0,0 @@
-From 5723280683d940b33647b8dc92a3aa3b1a9a5466 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 30 Apr 2020 12:20:17 +0200
-Subject: [PATCH] nstat: print useful error messages in abort() cases
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1824896
-Upstream Status: iproute2.git commit 2c7056ac26412
-
-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 23113b223b22d..425e75ef461ec 100644
---- a/misc/nstat.c
-+++ b/misc/nstat.c
-@@ -142,14 +142,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;
-@@ -190,8 +195,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;
-@@ -211,8 +219,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;
-@@ -221,18 +231,27 @@ static void load_ugly_table(FILE *fp)
- 		}
- 		n = db;
- 		nread = getline(&buf, &buflen, fp);
--		if (nread == -1)
--			abort();
-+		if (nread == -1) {
-+			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.4
-
diff --git a/SOURCES/0010-ip-link-xstats-fix-TX-IGMP-reports-string.patch b/SOURCES/0010-ip-link-xstats-fix-TX-IGMP-reports-string.patch
deleted file mode 100644
index 0ab0707..0000000
--- a/SOURCES/0010-ip-link-xstats-fix-TX-IGMP-reports-string.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 28a6ef808bd5c196c2259f7841a97c1ba703479d Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 30 Apr 2020 12:32:41 +0200
-Subject: [PATCH] ip link: xstats: fix TX IGMP reports string
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1796041
-Upstream Status: iproute2.git commit 5cdeb77cd6ec2
-
-commit 5cdeb77cd6ec26f0a7103dfb21494a6a43903206
-Author: Andrea Claudi <aclaudi@redhat.com>
-Date:   Wed Jan 29 15:31:11 2020 +0100
-
-    ip link: xstats: fix TX IGMP reports string
-
-    This restore the string format we have before jsonification, adding a
-    missing space between v2 and v3 on TX IGMP reports string.
-
-    Fixes: a9bc23a79227a ("ip: bridge: add xstats json support")
-    Signed-off-by: Andrea Claudi <aclaudi@redhat.com>
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
----
- ip/iplink_bridge.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ip/iplink_bridge.c b/ip/iplink_bridge.c
-index 06f736d4dc710..868ea6e266ebe 100644
---- a/ip/iplink_bridge.c
-+++ b/ip/iplink_bridge.c
-@@ -742,7 +742,7 @@ static void bridge_print_stats_attr(struct rtattr *attr, int ifindex)
- 			print_string(PRINT_FP, NULL, "%-16s      ", "");
- 			print_u64(PRINT_ANY, "tx_v1", "TX: v1 %llu ",
- 				  mstats->igmp_v1reports[BR_MCAST_DIR_TX]);
--			print_u64(PRINT_ANY, "tx_v2", "v2 %llu",
-+			print_u64(PRINT_ANY, "tx_v2", "v2 %llu ",
- 				  mstats->igmp_v2reports[BR_MCAST_DIR_TX]);
- 			print_u64(PRINT_ANY, "tx_v3", "v3 %llu\n",
- 				  mstats->igmp_v3reports[BR_MCAST_DIR_TX]);
--- 
-2.25.4
-
diff --git a/SOURCES/0010-iplink_bareudp-cleanup-help-message-and-man-page.patch b/SOURCES/0010-iplink_bareudp-cleanup-help-message-and-man-page.patch
new file mode 100644
index 0000000..a0ca03e
--- /dev/null
+++ b/SOURCES/0010-iplink_bareudp-cleanup-help-message-and-man-page.patch
@@ -0,0 +1,104 @@
+From e5143d1e2787fca4ea365c4010e0da5bcbbbba36 Mon Sep 17 00:00:00 2001
+Message-Id: <e5143d1e2787fca4ea365c4010e0da5bcbbbba36.1615575079.git.aclaudi@redhat.com>
+In-Reply-To: <cb7ce51cc1abd7b98370b903ec96205ebfe48661.1615575079.git.aclaudi@redhat.com>
+References: <cb7ce51cc1abd7b98370b903ec96205ebfe48661.1615575079.git.aclaudi@redhat.com>
+From: Andrea Claudi <aclaudi@redhat.com>
+Date: Mon, 8 Mar 2021 12:52:23 +0100
+Subject: [PATCH] iplink_bareudp: cleanup help message and man page
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1912412
+Upstream Status: unknown commit 86d9660d
+
+commit 86d9660dc1805be4435497ff194f618535e8fc97
+Author: Guillaume Nault <gnault@redhat.com>
+Date:   Mon Feb 1 18:44:07 2021 +0100
+
+    iplink_bareudp: cleanup help message and man page
+
+    * Fix PROTO description in help message (mpls isn't a valid argument).
+
+     * Remove SRCPORTMIN description from help message since it doesn't
+       appear in the syntax string.
+
+     * Use same keywords in help message and in man page.
+
+     * Use the "ethertype" option name (.B ethertype) rather than the
+       option value (.I ETHERTYPE) in the man page description of
+       [no]multiproto.
+
+    Signed-off-by: Guillaume Nault <gnault@redhat.com>
+    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
+---
+ ip/iplink_bareudp.c   |  8 +++++---
+ man/man8/ip-link.8.in | 15 +++++++++------
+ 2 files changed, 14 insertions(+), 9 deletions(-)
+
+diff --git a/ip/iplink_bareudp.c b/ip/iplink_bareudp.c
+index 860ec699..aa311106 100644
+--- a/ip/iplink_bareudp.c
++++ b/ip/iplink_bareudp.c
+@@ -22,9 +22,11 @@ static void print_explain(FILE *f)
+ 		"		[ srcportmin PORT ]\n"
+ 		"		[ [no]multiproto ]\n"
+ 		"\n"
+-		"Where:	PORT       := 0-65535\n"
+-		"	PROTO      := NUMBER | ip | mpls\n"
+-		"	SRCPORTMIN := 0-65535\n"
++		"Where:	PORT  := UDP_PORT\n"
++		"	PROTO := ETHERTYPE\n"
++		"\n"
++		"Note: ETHERTYPE can be given as number or as protocol name (\"ipv4\", \"ipv6\",\n"
++		"      \"mpls_uc\", etc.).\n"
+ 	);
+ }
+ 
+diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
+index f451ecf3..ce3c8636 100644
+--- a/man/man8/ip-link.8.in
++++ b/man/man8/ip-link.8.in
+@@ -1304,9 +1304,9 @@ For a link of type
+ the following additional arguments are supported:
+ 
+ .BI "ip link add " DEVICE
+-.BI type " bareudp " dstport " PORT " ethertype " ETHERTYPE"
++.BI type " bareudp " dstport " PORT " ethertype " PROTO"
+ [
+-.BI srcportmin " SRCPORTMIN "
++.BI srcportmin " PORT "
+ ] [
+ .RB [ no ] multiproto
+ ]
+@@ -1317,11 +1317,14 @@ the following additional arguments are supported:
+ - specifies the destination port for the UDP tunnel.
+ 
+ .sp
+-.BI ethertype " ETHERTYPE"
++.BI ethertype " PROTO"
+ - specifies the ethertype of the L3 protocol being tunnelled.
++.B ethertype
++can be given as plain Ethernet protocol number or using the protocol name
++("ipv4", "ipv6", "mpls_uc", etc.).
+ 
+ .sp
+-.BI srcportmin " SRCPORTMIN"
++.BI srcportmin " PORT"
+ - selects the lowest value of the UDP tunnel source port range.
+ 
+ .sp
+@@ -1329,11 +1332,11 @@ the following additional arguments are supported:
+ - activates support for protocols similar to the one
+ .RB "specified by " ethertype .
+ When
+-.I ETHERTYPE
++.B ethertype
+ is "mpls_uc" (that is, unicast MPLS), this allows the tunnel to also handle
+ multicast MPLS.
+ When
+-.I ETHERTYPE
++.B ethertype
+ is "ipv4", this allows the tunnel to also handle IPv6. This option is disabled
+ by default.
+ 
+-- 
+2.30.2
+
diff --git a/SOURCES/0011-ip-fix-ip-route-show-json-output-for-multipath-nexth.patch b/SOURCES/0011-ip-fix-ip-route-show-json-output-for-multipath-nexth.patch
deleted file mode 100644
index c82b769..0000000
--- a/SOURCES/0011-ip-fix-ip-route-show-json-output-for-multipath-nexth.patch
+++ /dev/null
@@ -1,148 +0,0 @@
-From 65d5e933e5162c3464857ee233a2f20e778ee1b6 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 30 Apr 2020 12:35:47 +0200
-Subject: [PATCH] ip: fix ip route show json output for multipath nexthops
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1738633
-Upstream Status: iproute2.git commit 4ecefff3cf250
-
-commit 4ecefff3cf250c1e4499dff14c80ed38bec6d7de
-Author: Julien Fortin <julien@cumulusnetworks.com>
-Date:   Thu Sep 26 17:29:34 2019 +0200
-
-    ip: fix ip route show json output for multipath nexthops
-
-    print_rta_multipath doesn't support JSON output:
-
-    {
-        "dst":"27.0.0.13",
-        "protocol":"bgp",
-        "metric":20,
-        "flags":[],
-        "gateway":"169.254.0.1"dev uplink-1 weight 1 ,
-        "flags":["onlink"],
-        "gateway":"169.254.0.1"dev uplink-2 weight 1 ,
-        "flags":["onlink"]
-    },
-
-    since RTA_MULTIPATH has nested objects we should print them
-    in a json array.
-
-    With the path we have the following output:
-
-    {
-        "flags": [],
-        "dst": "36.0.0.13",
-        "protocol": "bgp",
-        "metric": 20,
-        "nexthops": [
-            {
-                "weight": 1,
-                "flags": [
-                    "onlink"
-                ],
-                "gateway": "169.254.0.1",
-                "dev": "uplink-1"
-            },
-            {
-                "weight": 1,
-                "flags": [
-                    "onlink"
-                ],
-                "gateway": "169.254.0.1",
-                "dev": "uplink-2"
-            }
-        ]
-    }
-
-    Fixes: 663c3cb23103f4 ("iproute: implement JSON and color output")
-
-    Signed-off-by: Julien Fortin <julien@cumulusnetworks.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- ip/iproute.c | 46 ++++++++++++++++++++++++++++------------------
- 1 file changed, 28 insertions(+), 18 deletions(-)
-
-diff --git a/ip/iproute.c b/ip/iproute.c
-index a453385113cb9..32bb52df250c2 100644
---- a/ip/iproute.c
-+++ b/ip/iproute.c
-@@ -649,24 +649,26 @@ static void print_rta_multipath(FILE *fp, const struct rtmsg *r,
- 	int len = RTA_PAYLOAD(rta);
- 	int first = 1;
- 
-+	open_json_array(PRINT_JSON, "nexthops");
-+
- 	while (len >= sizeof(*nh)) {
- 		struct rtattr *tb[RTA_MAX + 1];
- 
- 		if (nh->rtnh_len > len)
- 			break;
- 
--		if (!is_json_context()) {
--			if ((r->rtm_flags & RTM_F_CLONED) &&
--			    r->rtm_type == RTN_MULTICAST) {
--				if (first) {
--					fprintf(fp, "Oifs: ");
--					first = 0;
--				} else {
--					fprintf(fp, " ");
--				}
--			} else
--				fprintf(fp, "%s\tnexthop ", _SL_);
--		}
-+		open_json_object(NULL);
-+
-+		if ((r->rtm_flags & RTM_F_CLONED) &&
-+		    r->rtm_type == RTN_MULTICAST) {
-+			if (first) {
-+				print_string(PRINT_FP, NULL, "Oifs: ", NULL);
-+				first = 0;
-+			} else {
-+				print_string(PRINT_FP, NULL, " ", NULL);
-+			}
-+		} else
-+			print_string(PRINT_FP, NULL, "%s\tnexthop ", _SL_);
- 
- 		if (nh->rtnh_len > sizeof(*nh)) {
- 			parse_rtattr(tb, RTA_MAX, RTNH_DATA(nh),
-@@ -689,22 +691,30 @@ static void print_rta_multipath(FILE *fp, const struct rtmsg *r,
- 
- 		if ((r->rtm_flags & RTM_F_CLONED) &&
- 		    r->rtm_type == RTN_MULTICAST) {
--			fprintf(fp, "%s", ll_index_to_name(nh->rtnh_ifindex));
-+			print_string(PRINT_ANY, "dev",
-+				     "%s", ll_index_to_name(nh->rtnh_ifindex));
-+
- 			if (nh->rtnh_hops != 1)
--				fprintf(fp, "(ttl>%d)", nh->rtnh_hops);
--			fprintf(fp, " ");
-+				print_int(PRINT_ANY, "ttl", "(ttl>%d)", nh->rtnh_hops);
-+
-+			print_string(PRINT_FP, NULL, " ", NULL);
- 		} else {
--			fprintf(fp, "dev %s ", ll_index_to_name(nh->rtnh_ifindex));
-+			print_string(PRINT_ANY, "dev",
-+				     "dev %s ", ll_index_to_name(nh->rtnh_ifindex));
-+
- 			if (r->rtm_family != AF_MPLS)
--				fprintf(fp, "weight %d ",
--					nh->rtnh_hops+1);
-+				print_int(PRINT_ANY, "weight",
-+					  "weight %d ", nh->rtnh_hops + 1);
- 		}
- 
- 		print_rt_flags(fp, nh->rtnh_flags);
- 
- 		len -= NLMSG_ALIGN(nh->rtnh_len);
- 		nh = RTNH_NEXT(nh);
-+
-+		close_json_object();
- 	}
-+	close_json_array(PRINT_JSON, NULL);
- }
- 
- int print_route(struct nlmsghdr *n, void *arg)
--- 
-2.25.4
-
diff --git a/SOURCES/0012-man-bridge.8-fix-bridge-link-show-description.patch b/SOURCES/0012-man-bridge.8-fix-bridge-link-show-description.patch
deleted file mode 100644
index 7e0c378..0000000
--- a/SOURCES/0012-man-bridge.8-fix-bridge-link-show-description.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 12bf930c542feeb9578d9320bc39a34365747127 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 30 Apr 2020 12:43:30 +0200
-Subject: [PATCH] man: bridge.8: fix bridge link show description
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1817571
-Upstream Status: iproute2.git commit 0641bed8a3c77
-
-commit 0641bed8a3c779c37746c4d7be9e01a35e920841
-Author: Andrea Claudi <aclaudi@redhat.com>
-Date:   Fri Mar 27 11:45:12 2020 +0100
-
-    man: bridge.8: fix bridge link show description
-
-    When multiple bridges are present, 'bridge link show' diplays ports
-    for all bridges. Make this clear in the command description, and
-    point out the user to the ip command to display ports for a specific
-    bridge.
-
-    Reported-by: Marc Muehlfeld <mmuehlfe@redhat.com>
-    Signed-off-by: Andrea Claudi <aclaudi@redhat.com>
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
----
- man/man8/bridge.8 | 7 +++++--
- 1 file changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
-index bb4fb521f8e57..d750e54a17b8b 100644
---- a/man/man8/bridge.8
-+++ b/man/man8/bridge.8
-@@ -409,9 +409,12 @@ link setting is configured on the software bridge (default)
- .BR "\-t" , " \-timestamp"
- display current time when using monitor option.
- 
--.SS bridge link show - list bridge port configuration.
-+.SS bridge link show - list ports configuration for all bridges.
- 
--This command displays the current bridge port configuration and flags.
-+This command displays port configuration and flags for all bridges.
-+
-+To display port configuration and flags for a specific bridge, use the
-+"ip link show master <bridge_device>" command.
- 
- .SH bridge fdb - forwarding database management
- 
--- 
-2.25.4
-
diff --git a/SOURCES/0013-xfrm-also-check-for-ipv6-state-in-xfrm_state_keep.patch b/SOURCES/0013-xfrm-also-check-for-ipv6-state-in-xfrm_state_keep.patch
deleted file mode 100644
index 8d5b4b4..0000000
--- a/SOURCES/0013-xfrm-also-check-for-ipv6-state-in-xfrm_state_keep.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 40dda2fc9fb2597996e443117df18995c58444a9 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 30 Apr 2020 12:46:30 +0200
-Subject: [PATCH] xfrm: also check for ipv6 state in xfrm_state_keep
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1828033
-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 d014444e9af4f..44f08ceed24dd 100644
---- a/ip/xfrm_state.c
-+++ b/ip/xfrm_state.c
-@@ -1131,7 +1131,8 @@ static int xfrm_state_keep(struct nlmsghdr *n, void *arg)
- 	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/0014-Update-kernel-headers-and-import-udp.h.patch b/SOURCES/0014-Update-kernel-headers-and-import-udp.h.patch
deleted file mode 100644
index cef917b..0000000
--- a/SOURCES/0014-Update-kernel-headers-and-import-udp.h.patch
+++ /dev/null
@@ -1,115 +0,0 @@
-From 90897540c719814eca34ce6b5b78b3bb76c4a43a Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Fri, 5 Jun 2020 15:42:49 +0200
-Subject: [PATCH] Update kernel headers and import udp.h
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1844045
-Upstream Status: iproute2.git commit 4df5ad933ca8c
-
-commit 4df5ad933ca8cebf23a4868061b28ab869e9b77a
-Author: David Ahern <dsahern@gmail.com>
-Date:   Wed Jan 22 03:40:26 2020 +0000
-
-    Update kernel headers and import udp.h
-
-    Update kernel headers to commit:
-        4f2c17e0f332 ("Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next")
-
-    and import udp.h for the next patch.
-
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- include/uapi/linux/hdlc/ioctl.h |  9 +++++++
- include/uapi/linux/if.h         |  1 +
- include/uapi/linux/udp.h        | 47 +++++++++++++++++++++++++++++++++
- 3 files changed, 57 insertions(+)
- create mode 100644 include/uapi/linux/udp.h
-
-diff --git a/include/uapi/linux/hdlc/ioctl.h b/include/uapi/linux/hdlc/ioctl.h
-index 0fe4238e82462..b06341acab5ec 100644
---- a/include/uapi/linux/hdlc/ioctl.h
-+++ b/include/uapi/linux/hdlc/ioctl.h
-@@ -79,6 +79,15 @@ typedef struct {
-     unsigned int timeout;
- } cisco_proto;
- 
-+typedef struct {
-+	unsigned short dce; /* 1 for DCE (network side) operation */
-+	unsigned int modulo; /* modulo (8 = basic / 128 = extended) */
-+	unsigned int window; /* frame window size */
-+	unsigned int t1; /* timeout t1 */
-+	unsigned int t2; /* timeout t2 */
-+	unsigned int n2; /* frame retry counter */
-+} x25_hdlc_proto;
-+
- /* PPP doesn't need any info now - supply length = 0 to ioctl */
- 
- #endif /* __ASSEMBLY__ */
-diff --git a/include/uapi/linux/if.h b/include/uapi/linux/if.h
-index 495cdd2324428..626da393123b6 100644
---- a/include/uapi/linux/if.h
-+++ b/include/uapi/linux/if.h
-@@ -210,6 +210,7 @@ struct if_settings {
- 		fr_proto		*fr;
- 		fr_proto_pvc		*fr_pvc;
- 		fr_proto_pvc_info	*fr_pvc_info;
-+		x25_hdlc_proto		*x25;
- 
- 		/* interface settings */
- 		sync_serial_settings	*sync;
-diff --git a/include/uapi/linux/udp.h b/include/uapi/linux/udp.h
-new file mode 100644
-index 0000000000000..d0a7223a0119c
---- /dev/null
-+++ b/include/uapi/linux/udp.h
-@@ -0,0 +1,47 @@
-+/* 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
-+ *		interface as the means of communication with the user level.
-+ *
-+ *		Definitions for the UDP protocol.
-+ *
-+ * Version:	@(#)udp.h	1.0.2	04/28/93
-+ *
-+ * Author:	Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
-+ *
-+ *		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_UDP_H
-+#define _LINUX_UDP_H
-+
-+#include <linux/types.h>
-+
-+struct udphdr {
-+	__be16	source;
-+	__be16	dest;
-+	__be16	len;
-+	__sum16	check;
-+};
-+
-+/* UDP socket options */
-+#define UDP_CORK	1	/* Never send partially complete segments */
-+#define UDP_ENCAP	100	/* Set the socket to accept encapsulated packets */
-+#define UDP_NO_CHECK6_TX 101	/* Disable sending checksum for UDP6X */
-+#define UDP_NO_CHECK6_RX 102	/* Disable accpeting checksum for UDP6 */
-+#define UDP_SEGMENT	103	/* Set GSO segmentation size */
-+#define UDP_GRO		104	/* This socket can receive UDP GRO packets */
-+
-+/* UDP encapsulation types */
-+#define UDP_ENCAP_ESPINUDP_NON_IKE	1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
-+#define UDP_ENCAP_ESPINUDP	2 /* draft-ietf-ipsec-udp-encaps-06 */
-+#define UDP_ENCAP_L2TPINUDP	3 /* rfc2661 */
-+#define UDP_ENCAP_GTP0		4 /* GSM TS 09.60 */
-+#define UDP_ENCAP_GTP1U		5 /* 3GPP TS 29.060 */
-+#define UDP_ENCAP_RXRPC		6
-+#define TCP_ENCAP_ESPINTCP	7 /* Yikes, this is really xfrm encap types. */
-+
-+#endif /* _LINUX_UDP_H */
--- 
-2.26.2
-
diff --git a/SOURCES/0015-ip-xfrm-add-espintcp-encapsulation.patch b/SOURCES/0015-ip-xfrm-add-espintcp-encapsulation.patch
deleted file mode 100644
index d19a729..0000000
--- a/SOURCES/0015-ip-xfrm-add-espintcp-encapsulation.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-From b0312111114ed805f84b1e96d73f468e3a372025 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Fri, 5 Jun 2020 15:42:49 +0200
-Subject: [PATCH] ip: xfrm: add espintcp encapsulation
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1844045
-Upstream Status: iproute2.git commit 22aec42679d57
-
-commit 22aec42679d57b8e0aef864c4d45feadb727c3ce
-Author: Sabrina Dubroca <sd@queasysnail.net>
-Date:   Sun Jan 19 11:32:09 2020 +0100
-
-    ip: xfrm: add espintcp encapsulation
-
-    While at it, convert xfrm_xfrma_print and xfrm_encap_type_parse to use
-    the UAPI macros for encap_type as suggested by David Ahern, and add the
-    UAPI udp.h header (sync'd from ipsec-next to get the TCP_ENCAP_ESPINTCP
-    definition).
-
-    Co-developed-by: Herbert Xu <herbert@gondor.apana.org.au>
-    Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- ip/ipxfrm.c        | 14 ++++++++++----
- ip/xfrm_state.c    |  2 +-
- man/man8/ip-xfrm.8 |  4 ++--
- 3 files changed, 13 insertions(+), 7 deletions(-)
-
-diff --git a/ip/ipxfrm.c b/ip/ipxfrm.c
-index 32f560933a477..fec206abc1f03 100644
---- a/ip/ipxfrm.c
-+++ b/ip/ipxfrm.c
-@@ -34,6 +34,7 @@
- #include <netdb.h>
- #include <linux/netlink.h>
- #include <linux/rtnetlink.h>
-+#include <linux/udp.h>
- 
- #include "utils.h"
- #include "xfrm.h"
-@@ -753,12 +754,15 @@ void xfrm_xfrma_print(struct rtattr *tb[], __u16 family,
- 
- 		fprintf(fp, "type ");
- 		switch (e->encap_type) {
--		case 1:
-+		case UDP_ENCAP_ESPINUDP_NON_IKE:
- 			fprintf(fp, "espinudp-nonike ");
- 			break;
--		case 2:
-+		case UDP_ENCAP_ESPINUDP:
- 			fprintf(fp, "espinudp ");
- 			break;
-+		case TCP_ENCAP_ESPINTCP:
-+			fprintf(fp, "espintcp ");
-+			break;
- 		default:
- 			fprintf(fp, "%u ", e->encap_type);
- 			break;
-@@ -1208,9 +1212,11 @@ int xfrm_encap_type_parse(__u16 *type, int *argcp, char ***argvp)
- 	char **argv = *argvp;
- 
- 	if (strcmp(*argv, "espinudp-nonike") == 0)
--		*type = 1;
-+		*type = UDP_ENCAP_ESPINUDP_NON_IKE;
- 	else if (strcmp(*argv, "espinudp") == 0)
--		*type = 2;
-+		*type = UDP_ENCAP_ESPINUDP;
-+	else if (strcmp(*argv, "espintcp") == 0)
-+		*type = TCP_ENCAP_ESPINTCP;
- 	else
- 		invarg("ENCAP-TYPE value is invalid", *argv);
- 
-diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c
-index 44f08ceed24dd..f4bf3356bb01f 100644
---- a/ip/xfrm_state.c
-+++ b/ip/xfrm_state.c
-@@ -112,7 +112,7 @@ static void usage(void)
- 		"LIMIT-LIST := [ LIMIT-LIST ] limit LIMIT\n"
- 		"LIMIT := { time-soft | time-hard | time-use-soft | time-use-hard } SECONDS |\n"
- 		"         { byte-soft | byte-hard } SIZE | { packet-soft | packet-hard } COUNT\n"
--		"ENCAP := { espinudp | espinudp-nonike } SPORT DPORT OADDR\n"
-+		"ENCAP := { espinudp | espinudp-nonike | espintcp } SPORT DPORT OADDR\n"
- 		"DIR := in | out\n");
- 
- 	exit(-1);
-diff --git a/man/man8/ip-xfrm.8 b/man/man8/ip-xfrm.8
-index cfce1e40b7f7d..f99f30bb448a6 100644
---- a/man/man8/ip-xfrm.8
-+++ b/man/man8/ip-xfrm.8
-@@ -207,7 +207,7 @@ ip-xfrm \- transform configuration
- 
- .ti -8
- .IR ENCAP " :="
--.RB "{ " espinudp " | " espinudp-nonike " }"
-+.RB "{ " espinudp " | " espinudp-nonike " | " espintcp " }"
- .IR SPORT " " DPORT " " OADDR
- 
- .ti -8
-@@ -548,7 +548,7 @@ sets limits in seconds, bytes, or numbers of packets.
- .TP
- .I ENCAP
- encapsulates packets with protocol
--.BR espinudp " or " espinudp-nonike ","
-+.BR espinudp ", " espinudp-nonike ", or " espintcp ","
- .RI "using source port " SPORT ", destination port "  DPORT
- .RI ", and original address " OADDR "."
- 
--- 
-2.26.2
-
diff --git a/SOURCES/0016-Update-kernel-headers-and-import-mptcp.h.patch b/SOURCES/0016-Update-kernel-headers-and-import-mptcp.h.patch
deleted file mode 100644
index 2d709bd..0000000
--- a/SOURCES/0016-Update-kernel-headers-and-import-mptcp.h.patch
+++ /dev/null
@@ -1,177 +0,0 @@
-From 93f77d1e57c84093b91bc9227929cfb4a24534e9 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 4 Jun 2020 19:25:47 +0200
-Subject: [PATCH] Update kernel headers and import mptcp.h
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1812207
-Upstream Status: iproute2.git commit 02ade5a8ea1c2
-Conflicts: on bpf uapi due to missing commit b5a77cf70116f ("uapi: update bpf.h")
-           and on if_bridge uapi due to several unrelated missing changes.
-
-commit 02ade5a8ea1c23201a99d8cdf7e02a6ba90d7718
-Author: David Ahern <dsahern@gmail.com>
-Date:   Wed Apr 29 16:41:39 2020 +0000
-
-    Update kernel headers and import mptcp.h
-
-    Update kernel headers to commit
-        790ab249b55d ("net: ethernet: fec: Prevent MII event after MII_SPEED write")
-
-    and import mptcp.h
-
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- include/uapi/linux/if.h        |  1 +
- include/uapi/linux/if_bridge.h |  1 +
- include/uapi/linux/if_ether.h  |  1 +
- include/uapi/linux/if_link.h   |  1 +
- include/uapi/linux/mptcp.h     | 89 ++++++++++++++++++++++++++++++++++
- 5 files changed, 93 insertions(+)
- create mode 100644 include/uapi/linux/mptcp.h
-
-diff --git a/include/uapi/linux/if.h b/include/uapi/linux/if.h
-index 626da393123b6..9a3bc23d0235e 100644
---- a/include/uapi/linux/if.h
-+++ b/include/uapi/linux/if.h
-@@ -175,6 +175,7 @@ enum {
- enum {
- 	IF_LINK_MODE_DEFAULT,
- 	IF_LINK_MODE_DORMANT,	/* limit upward transition to dormant */
-+	IF_LINK_MODE_TESTING,	/* limit upward transition to testing */
- };
- 
- /*
-diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h
-index 31fc51bdedb3c..53ba8385b022e 100644
---- a/include/uapi/linux/if_bridge.h
-+++ b/include/uapi/linux/if_bridge.h
-@@ -120,6 +120,7 @@ enum {
- 	IFLA_BRIDGE_MODE,
- 	IFLA_BRIDGE_VLAN_INFO,
- 	IFLA_BRIDGE_VLAN_TUNNEL_INFO,
-+	IFLA_BRIDGE_MRP,
- 	__IFLA_BRIDGE_MAX,
- };
- #define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1)
-diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h
-index 728c42dfd59c1..1a0c7dfe8e38e 100644
---- a/include/uapi/linux/if_ether.h
-+++ b/include/uapi/linux/if_ether.h
-@@ -92,6 +92,7 @@
- #define ETH_P_PREAUTH	0x88C7		/* 802.11 Preauthentication */
- #define ETH_P_TIPC	0x88CA		/* TIPC 			*/
- #define ETH_P_LLDP	0x88CC		/* Link Layer Discovery Protocol */
-+#define ETH_P_MRP	0x88E3		/* Media Redundancy Protocol	*/
- #define ETH_P_MACSEC	0x88E5		/* 802.1ae MACsec */
- #define ETH_P_8021AH	0x88E7          /* 802.1ah Backbone Service Tag */
- #define ETH_P_MVRP	0x88F5          /* 802.1Q MVRP                  */
-diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
-index d36919fb4024a..4da0768d7a5a3 100644
---- a/include/uapi/linux/if_link.h
-+++ b/include/uapi/linux/if_link.h
-@@ -338,6 +338,7 @@ enum {
- 	IFLA_BRPORT_NEIGH_SUPPRESS,
- 	IFLA_BRPORT_ISOLATED,
- 	IFLA_BRPORT_BACKUP_PORT,
-+	IFLA_BRPORT_MRP_RING_OPEN,
- 	__IFLA_BRPORT_MAX
- };
- #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
-diff --git a/include/uapi/linux/mptcp.h b/include/uapi/linux/mptcp.h
-new file mode 100644
-index 0000000000000..009b8f0b0e8be
---- /dev/null
-+++ b/include/uapi/linux/mptcp.h
-@@ -0,0 +1,89 @@
-+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
-+#ifndef _MPTCP_H
-+#define _MPTCP_H
-+
-+#include <linux/const.h>
-+#include <linux/types.h>
-+
-+#define MPTCP_SUBFLOW_FLAG_MCAP_REM		_BITUL(0)
-+#define MPTCP_SUBFLOW_FLAG_MCAP_LOC		_BITUL(1)
-+#define MPTCP_SUBFLOW_FLAG_JOIN_REM		_BITUL(2)
-+#define MPTCP_SUBFLOW_FLAG_JOIN_LOC		_BITUL(3)
-+#define MPTCP_SUBFLOW_FLAG_BKUP_REM		_BITUL(4)
-+#define MPTCP_SUBFLOW_FLAG_BKUP_LOC		_BITUL(5)
-+#define MPTCP_SUBFLOW_FLAG_FULLY_ESTABLISHED	_BITUL(6)
-+#define MPTCP_SUBFLOW_FLAG_CONNECTED		_BITUL(7)
-+#define MPTCP_SUBFLOW_FLAG_MAPVALID		_BITUL(8)
-+
-+enum {
-+	MPTCP_SUBFLOW_ATTR_UNSPEC,
-+	MPTCP_SUBFLOW_ATTR_TOKEN_REM,
-+	MPTCP_SUBFLOW_ATTR_TOKEN_LOC,
-+	MPTCP_SUBFLOW_ATTR_RELWRITE_SEQ,
-+	MPTCP_SUBFLOW_ATTR_MAP_SEQ,
-+	MPTCP_SUBFLOW_ATTR_MAP_SFSEQ,
-+	MPTCP_SUBFLOW_ATTR_SSN_OFFSET,
-+	MPTCP_SUBFLOW_ATTR_MAP_DATALEN,
-+	MPTCP_SUBFLOW_ATTR_FLAGS,
-+	MPTCP_SUBFLOW_ATTR_ID_REM,
-+	MPTCP_SUBFLOW_ATTR_ID_LOC,
-+	MPTCP_SUBFLOW_ATTR_PAD,
-+	__MPTCP_SUBFLOW_ATTR_MAX
-+};
-+
-+#define MPTCP_SUBFLOW_ATTR_MAX (__MPTCP_SUBFLOW_ATTR_MAX - 1)
-+
-+/* netlink interface */
-+#define MPTCP_PM_NAME		"mptcp_pm"
-+#define MPTCP_PM_CMD_GRP_NAME	"mptcp_pm_cmds"
-+#define MPTCP_PM_VER		0x1
-+
-+/*
-+ * ATTR types defined for MPTCP
-+ */
-+enum {
-+	MPTCP_PM_ATTR_UNSPEC,
-+
-+	MPTCP_PM_ATTR_ADDR,				/* nested address */
-+	MPTCP_PM_ATTR_RCV_ADD_ADDRS,			/* u32 */
-+	MPTCP_PM_ATTR_SUBFLOWS,				/* u32 */
-+
-+	__MPTCP_PM_ATTR_MAX
-+};
-+
-+#define MPTCP_PM_ATTR_MAX (__MPTCP_PM_ATTR_MAX - 1)
-+
-+enum {
-+	MPTCP_PM_ADDR_ATTR_UNSPEC,
-+
-+	MPTCP_PM_ADDR_ATTR_FAMILY,			/* u16 */
-+	MPTCP_PM_ADDR_ATTR_ID,				/* u8 */
-+	MPTCP_PM_ADDR_ATTR_ADDR4,			/* struct in_addr */
-+	MPTCP_PM_ADDR_ATTR_ADDR6,			/* struct in6_addr */
-+	MPTCP_PM_ADDR_ATTR_PORT,			/* u16 */
-+	MPTCP_PM_ADDR_ATTR_FLAGS,			/* u32 */
-+	MPTCP_PM_ADDR_ATTR_IF_IDX,			/* s32 */
-+
-+	__MPTCP_PM_ADDR_ATTR_MAX
-+};
-+
-+#define MPTCP_PM_ADDR_ATTR_MAX (__MPTCP_PM_ADDR_ATTR_MAX - 1)
-+
-+#define MPTCP_PM_ADDR_FLAG_SIGNAL			(1 << 0)
-+#define MPTCP_PM_ADDR_FLAG_SUBFLOW			(1 << 1)
-+#define MPTCP_PM_ADDR_FLAG_BACKUP			(1 << 2)
-+
-+enum {
-+	MPTCP_PM_CMD_UNSPEC,
-+
-+	MPTCP_PM_CMD_ADD_ADDR,
-+	MPTCP_PM_CMD_DEL_ADDR,
-+	MPTCP_PM_CMD_GET_ADDR,
-+	MPTCP_PM_CMD_FLUSH_ADDRS,
-+	MPTCP_PM_CMD_SET_LIMITS,
-+	MPTCP_PM_CMD_GET_LIMITS,
-+
-+	__MPTCP_PM_CMD_AFTER_LAST
-+};
-+
-+#endif /* _MPTCP_H */
--- 
-2.26.2
-
diff --git a/SOURCES/0017-add-support-for-mptcp-netlink-interface.patch b/SOURCES/0017-add-support-for-mptcp-netlink-interface.patch
deleted file mode 100644
index 47995fd..0000000
--- a/SOURCES/0017-add-support-for-mptcp-netlink-interface.patch
+++ /dev/null
@@ -1,532 +0,0 @@
-From 1f25184a76227f8a7a1e425434e6e0f0bd13457d Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 4 Jun 2020 19:26:50 +0200
-Subject: [PATCH] add support for mptcp netlink interface
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1812207
-Upstream Status: unknown commit 7e0767cd862bb
-
-commit 7e0767cd862bb5dd2d41c41c5e6f55d633f953ea
-Author: Paolo Abeni <pabeni@redhat.com>
-Date:   Thu Apr 23 15:37:08 2020 +0200
-
-    add support for mptcp netlink interface
-
-    Implement basic commands to:
-    - manipulate MPTCP endpoints list
-    - manipulate MPTCP connection limits
-
-    Examples:
-    1. Allows multiple subflows per MPTCP connection
-       $ ip mptcp limits set subflows 2
-
-    2. Accept ADD_ADDR announcement from the peer (server):
-       $ ip mptcp limits set add_addr_accepted 2
-
-    3. Add a ipv4 address to be annunced for backup subflows:
-       $ ip mptcp endpoint add 10.99.1.2 signal backup
-
-    4. Add an ipv6 address used as source for additional subflows:
-       $ ip mptcp endpoint add 2001::2 subflow
-
-    Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- ip/Makefile    |   2 +-
- ip/ip.c        |   3 +-
- ip/ip_common.h |   1 +
- ip/ipmptcp.c   | 436 +++++++++++++++++++++++++++++++++++++++++++++++++
- 4 files changed, 440 insertions(+), 2 deletions(-)
- create mode 100644 ip/ipmptcp.c
-
-diff --git a/ip/Makefile b/ip/Makefile
-index 5ab78d7d3b84e..8735b8e4706b3 100644
---- a/ip/Makefile
-+++ b/ip/Makefile
-@@ -11,7 +11,7 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o ipnetns.o \
-     iplink_bridge.o iplink_bridge_slave.o ipfou.o iplink_ipvlan.o \
-     iplink_geneve.o iplink_vrf.o iproute_lwtunnel.o ipmacsec.o ipila.o \
-     ipvrf.o iplink_xstats.o ipseg6.o iplink_netdevsim.o iplink_rmnet.o \
--    ipnexthop.o
-+    ipnexthop.o ipmptcp.o
- 
- RTMONOBJ=rtmon.o
- 
-diff --git a/ip/ip.c b/ip/ip.c
-index fed26f8d48279..8d62f4e312bdc 100644
---- a/ip/ip.c
-+++ b/ip/ip.c
-@@ -51,7 +51,7 @@ static void usage(void)
- 		"where  OBJECT := { link | address | addrlabel | route | rule | neigh | ntable |\n"
- 		"                   tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm |\n"
- 		"                   netns | l2tp | fou | macsec | tcp_metrics | token | netconf | ila |\n"
--		"                   vrf | sr | nexthop }\n"
-+		"                   vrf | sr | nexthop | mptcp }\n"
- 		"       OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n"
- 		"                    -h[uman-readable] | -iec | -j[son] | -p[retty] |\n"
- 		"                    -f[amily] { inet | inet6 | mpls | bridge | link } |\n"
-@@ -103,6 +103,7 @@ static const struct cmd {
- 	{ "vrf",	do_ipvrf},
- 	{ "sr",		do_seg6 },
- 	{ "nexthop",	do_ipnh },
-+	{ "mptcp",	do_mptcp },
- 	{ "help",	do_help },
- 	{ 0 }
- };
-diff --git a/ip/ip_common.h b/ip/ip_common.h
-index cd916ec87c265..0dd4a53fc8333 100644
---- a/ip/ip_common.h
-+++ b/ip/ip_common.h
-@@ -82,6 +82,7 @@ void vrf_reset(void);
- int netns_identify_pid(const char *pidstr, char *name, int len);
- int do_seg6(int argc, char **argv);
- int do_ipnh(int argc, char **argv);
-+int do_mptcp(int argc, char **argv);
- 
- int iplink_get(char *name, __u32 filt_mask);
- int iplink_ifla_xstats(int argc, char **argv);
-diff --git a/ip/ipmptcp.c b/ip/ipmptcp.c
-new file mode 100644
-index 0000000000000..bc12418bd39c6
---- /dev/null
-+++ b/ip/ipmptcp.c
-@@ -0,0 +1,436 @@
-+// SPDX-License-Identifier: GPL-2.0
-+
-+#include <stdio.h>
-+#include <string.h>
-+#include <rt_names.h>
-+#include <errno.h>
-+
-+#include <linux/genetlink.h>
-+#include <linux/mptcp.h>
-+
-+#include "utils.h"
-+#include "ip_common.h"
-+#include "libgenl.h"
-+#include "json_print.h"
-+
-+static void usage(void)
-+{
-+	fprintf(stderr,
-+		"Usage:	ip mptcp endpoint add ADDRESS [ dev NAME ] [ id ID ]\n"
-+		"				      [ FLAG-LIST ]\n"
-+		"	ip mptcp endpoint delete id ID\n"
-+		"	ip mptcp endpoint show [ id ID ]\n"
-+		"	ip mptcp endpoint flush\n"
-+		"	ip mptcp limits set [ subflows NR ] [ add_addr_accepted NR ]\n"
-+		"	ip mptcp limits show\n"
-+		"FLAG-LIST := [ FLAG-LIST ] FLAG\n"
-+		"FLAG  := [ signal | subflow | backup ]\n");
-+
-+	exit(-1);
-+}
-+
-+/* netlink socket */
-+static struct rtnl_handle genl_rth = { .fd = -1 };
-+static int genl_family = -1;
-+
-+#define MPTCP_BUFLEN	4096
-+#define MPTCP_REQUEST(_req,  _cmd, _flags)	\
-+	GENL_REQUEST(_req, MPTCP_BUFLEN, genl_family, 0,	\
-+		     MPTCP_PM_VER, _cmd, _flags)
-+
-+/* Mapping from argument to address flag mask */
-+static const struct {
-+	const char *name;
-+	unsigned long value;
-+} mptcp_addr_flag_names[] = {
-+	{ "signal",		MPTCP_PM_ADDR_FLAG_SIGNAL },
-+	{ "subflow",		MPTCP_PM_ADDR_FLAG_SUBFLOW },
-+	{ "backup",		MPTCP_PM_ADDR_FLAG_BACKUP },
-+};
-+
-+static void print_mptcp_addr_flags(unsigned int flags)
-+{
-+	unsigned int i;
-+
-+	for (i = 0; i < ARRAY_SIZE(mptcp_addr_flag_names); i++) {
-+		unsigned long mask = mptcp_addr_flag_names[i].value;
-+
-+		if (flags & mask) {
-+			print_string(PRINT_FP, NULL, "%s ",
-+				     mptcp_addr_flag_names[i].name);
-+			print_bool(PRINT_JSON,
-+				   mptcp_addr_flag_names[i].name, NULL, true);
-+		}
-+
-+		flags &= ~mask;
-+	}
-+
-+	if (flags) {
-+		/* unknown flags */
-+		SPRINT_BUF(b1);
-+
-+		snprintf(b1, sizeof(b1), "%02x", flags);
-+		print_string(PRINT_ANY, "rawflags", "rawflags %s ", b1);
-+	}
-+}
-+
-+static int get_flags(const char *arg, __u32 *flags)
-+{
-+	unsigned int i;
-+
-+	for (i = 0; i < ARRAY_SIZE(mptcp_addr_flag_names); i++) {
-+		if (strcmp(arg, mptcp_addr_flag_names[i].name))
-+			continue;
-+
-+		*flags |= mptcp_addr_flag_names[i].value;
-+		return 0;
-+	}
-+	return -1;
-+}
-+
-+static int mptcp_parse_opt(int argc, char **argv, struct nlmsghdr *n,
-+			 bool adding)
-+{
-+	struct rtattr *attr_addr;
-+	bool addr_set = false;
-+	inet_prefix address;
-+	bool id_set = false;
-+	__u32 index = 0;
-+	__u32 flags = 0;
-+	__u8 id = 0;
-+
-+	ll_init_map(&rth);
-+	while (argc > 0) {
-+		if (get_flags(*argv, &flags) == 0) {
-+		} else if (matches(*argv, "id") == 0) {
-+			NEXT_ARG();
-+
-+			if (get_u8(&id, *argv, 0))
-+				invarg("invalid ID\n", *argv);
-+			id_set = true;
-+		} else if (matches(*argv, "dev") == 0) {
-+			const char *ifname;
-+
-+			NEXT_ARG();
-+
-+			ifname = *argv;
-+
-+			if (check_ifname(ifname))
-+				invarg("invalid interface name\n", ifname);
-+
-+			index = ll_name_to_index(ifname);
-+
-+			if (!index)
-+				invarg("device does not exist\n", ifname);
-+
-+		} else if (get_addr(&address, *argv, AF_UNSPEC) == 0) {
-+			addr_set = true;
-+		} else {
-+			invarg("unknown argument", *argv);
-+		}
-+		NEXT_ARG_FWD();
-+	}
-+
-+	if (!addr_set && adding)
-+		missarg("ADDRESS");
-+
-+	if (!id_set && !adding)
-+		missarg("ID");
-+
-+	attr_addr = addattr_nest(n, MPTCP_BUFLEN,
-+				 MPTCP_PM_ATTR_ADDR | NLA_F_NESTED);
-+	if (id_set)
-+		addattr8(n, MPTCP_BUFLEN, MPTCP_PM_ADDR_ATTR_ID, id);
-+	if (flags)
-+		addattr32(n, MPTCP_BUFLEN, MPTCP_PM_ADDR_ATTR_FLAGS, flags);
-+	if (index)
-+		addattr32(n, MPTCP_BUFLEN, MPTCP_PM_ADDR_ATTR_IF_IDX, index);
-+	if (addr_set) {
-+		int type;
-+
-+		addattr16(n, MPTCP_BUFLEN, MPTCP_PM_ADDR_ATTR_FAMILY,
-+			  address.family);
-+		type = address.family == AF_INET ? MPTCP_PM_ADDR_ATTR_ADDR4 :
-+						   MPTCP_PM_ADDR_ATTR_ADDR6;
-+		addattr_l(n, MPTCP_BUFLEN, type, &address.data,
-+			  address.bytelen);
-+	}
-+
-+	addattr_nest_end(n, attr_addr);
-+	return 0;
-+}
-+
-+static int mptcp_addr_modify(int argc, char **argv, int cmd)
-+{
-+	MPTCP_REQUEST(req, cmd, NLM_F_REQUEST);
-+	int ret;
-+
-+	ret = mptcp_parse_opt(argc, argv, &req.n, cmd == MPTCP_PM_CMD_ADD_ADDR);
-+	if (ret)
-+		return ret;
-+
-+	if (rtnl_talk(&genl_rth, &req.n, NULL) < 0)
-+		return -2;
-+
-+	return 0;
-+}
-+
-+static int print_mptcp_addrinfo(struct rtattr *addrinfo)
-+{
-+	struct rtattr *tb[MPTCP_PM_ADDR_ATTR_MAX + 1];
-+	__u8 family = AF_UNSPEC, addr_attr_type;
-+	const char *ifname;
-+	unsigned int flags;
-+	int index;
-+	__u16 id;
-+
-+	parse_rtattr_nested(tb, MPTCP_PM_ADDR_ATTR_MAX, addrinfo);
-+
-+	open_json_object(NULL);
-+	if (tb[MPTCP_PM_ADDR_ATTR_FAMILY])
-+		family = rta_getattr_u8(tb[MPTCP_PM_ADDR_ATTR_FAMILY]);
-+
-+	addr_attr_type = family == AF_INET ? MPTCP_PM_ADDR_ATTR_ADDR4 :
-+					     MPTCP_PM_ADDR_ATTR_ADDR6;
-+	if (tb[addr_attr_type]) {
-+		print_string(PRINT_ANY, "address", "%s ",
-+			     format_host_rta(family, tb[addr_attr_type]));
-+	}
-+	if (tb[MPTCP_PM_ADDR_ATTR_ID]) {
-+		id = rta_getattr_u8(tb[MPTCP_PM_ADDR_ATTR_ID]);
-+		print_uint(PRINT_ANY, "id", "id %u ", id);
-+	}
-+	if (tb[MPTCP_PM_ADDR_ATTR_FLAGS]) {
-+		flags = rta_getattr_u32(tb[MPTCP_PM_ADDR_ATTR_FLAGS]);
-+		print_mptcp_addr_flags(flags);
-+	}
-+	if (tb[MPTCP_PM_ADDR_ATTR_IF_IDX]) {
-+		index = rta_getattr_s32(tb[MPTCP_PM_ADDR_ATTR_IF_IDX]);
-+		ifname = index ? ll_index_to_name(index) : NULL;
-+
-+		if (ifname)
-+			print_string(PRINT_ANY, "dev", "dev %s ", ifname);
-+	}
-+
-+	close_json_object();
-+	print_string(PRINT_FP, NULL, "\n", NULL);
-+	fflush(stdout);
-+
-+	return 0;
-+}
-+
-+static int print_mptcp_addr(struct nlmsghdr *n, void *arg)
-+{
-+	struct rtattr *tb[MPTCP_PM_ATTR_MAX + 1];
-+	struct genlmsghdr *ghdr;
-+	struct rtattr *addrinfo;
-+	int len = n->nlmsg_len;
-+
-+	if (n->nlmsg_type != genl_family)
-+		return 0;
-+
-+	len -= NLMSG_LENGTH(GENL_HDRLEN);
-+	if (len < 0)
-+		return -1;
-+
-+	ghdr = NLMSG_DATA(n);
-+	parse_rtattr_flags(tb, MPTCP_PM_ATTR_MAX, (void *) ghdr + GENL_HDRLEN,
-+			   len, NLA_F_NESTED);
-+	addrinfo = tb[MPTCP_PM_ATTR_ADDR];
-+	if (!addrinfo)
-+		return -1;
-+
-+	ll_init_map(&rth);
-+	return print_mptcp_addrinfo(addrinfo);
-+}
-+
-+static int mptcp_addr_dump(void)
-+{
-+	MPTCP_REQUEST(req, MPTCP_PM_CMD_GET_ADDR, NLM_F_REQUEST | NLM_F_DUMP);
-+
-+	if (rtnl_send(&genl_rth, &req.n, req.n.nlmsg_len) < 0) {
-+		perror("Cannot send show request");
-+		exit(1);
-+	}
-+
-+	new_json_obj(json);
-+
-+	if (rtnl_dump_filter(&genl_rth, print_mptcp_addr, stdout) < 0) {
-+		fprintf(stderr, "Dump terminated\n");
-+		delete_json_obj();
-+		fflush(stdout);
-+		return -2;
-+	}
-+
-+	close_json_object();
-+	fflush(stdout);
-+	return 0;
-+}
-+
-+static int mptcp_addr_show(int argc, char **argv)
-+{
-+	MPTCP_REQUEST(req, MPTCP_PM_CMD_GET_ADDR, NLM_F_REQUEST);
-+	struct nlmsghdr *answer;
-+	int ret;
-+
-+	if (!argv)
-+		return mptcp_addr_dump();
-+
-+	ret = mptcp_parse_opt(argc, argv, &req.n, false);
-+	if (ret)
-+		return ret;
-+
-+	if (rtnl_talk(&genl_rth, &req.n, &answer) < 0)
-+		return -2;
-+
-+	return print_mptcp_addr(answer, stdout);
-+}
-+
-+static int mptcp_addr_flush(int argc, char **argv)
-+{
-+	MPTCP_REQUEST(req, MPTCP_PM_CMD_FLUSH_ADDRS, NLM_F_REQUEST);
-+
-+	if (rtnl_talk(&genl_rth, &req.n, NULL) < 0)
-+		return -2;
-+
-+	return 0;
-+}
-+
-+static int mptcp_parse_limit(int argc, char **argv, struct nlmsghdr *n)
-+{
-+	bool set_rcv_add_addrs = false;
-+	bool set_subflows = false;
-+	__u32 rcv_add_addrs = 0;
-+	__u32 subflows = 0;
-+
-+	while (argc > 0) {
-+		if (matches(*argv, "subflows") == 0) {
-+			NEXT_ARG();
-+
-+			if (get_u32(&subflows, *argv, 0))
-+				invarg("invalid subflows\n", *argv);
-+			set_subflows = true;
-+		} else if (matches(*argv, "add_addr_accepted") == 0) {
-+			NEXT_ARG();
-+
-+			if (get_u32(&rcv_add_addrs, *argv, 0))
-+				invarg("invalid add_addr_accepted\n", *argv);
-+			set_rcv_add_addrs = true;
-+		} else {
-+			invarg("unknown limit", *argv);
-+		}
-+		NEXT_ARG_FWD();
-+	}
-+
-+	if (set_rcv_add_addrs)
-+		addattr32(n, MPTCP_BUFLEN, MPTCP_PM_ATTR_RCV_ADD_ADDRS,
-+			  rcv_add_addrs);
-+	if (set_subflows)
-+		addattr32(n, MPTCP_BUFLEN, MPTCP_PM_ATTR_SUBFLOWS, subflows);
-+	return set_rcv_add_addrs || set_subflows;
-+}
-+
-+static int print_mptcp_limit(struct nlmsghdr *n, void *arg)
-+{
-+	struct rtattr *tb[MPTCP_PM_ATTR_MAX + 1];
-+	struct genlmsghdr *ghdr;
-+	int len = n->nlmsg_len;
-+	__u32 val;
-+
-+	if (n->nlmsg_type != genl_family)
-+		return 0;
-+
-+	len -= NLMSG_LENGTH(GENL_HDRLEN);
-+	if (len < 0)
-+		return -1;
-+
-+	ghdr = NLMSG_DATA(n);
-+	parse_rtattr(tb, MPTCP_PM_ATTR_MAX, (void *) ghdr + GENL_HDRLEN, len);
-+
-+	open_json_object(NULL);
-+	if (tb[MPTCP_PM_ATTR_RCV_ADD_ADDRS]) {
-+		val = rta_getattr_u32(tb[MPTCP_PM_ATTR_RCV_ADD_ADDRS]);
-+
-+		print_uint(PRINT_ANY, "add_addr_accepted",
-+			   "add_addr_accepted %d ", val);
-+	}
-+
-+	if (tb[MPTCP_PM_ATTR_SUBFLOWS]) {
-+		val = rta_getattr_u32(tb[MPTCP_PM_ATTR_SUBFLOWS]);
-+
-+		print_uint(PRINT_ANY, "subflows", "subflows %d ", val);
-+	}
-+	print_string(PRINT_FP, NULL, "%s", "\n");
-+	fflush(stdout);
-+	close_json_object();
-+	return 0;
-+}
-+
-+static int mptcp_limit_get_set(int argc, char **argv, int cmd)
-+{
-+	bool do_get = cmd == MPTCP_PM_CMD_GET_LIMITS;
-+	MPTCP_REQUEST(req, cmd, NLM_F_REQUEST);
-+	struct nlmsghdr *answer;
-+	int ret;
-+
-+	ret = mptcp_parse_limit(argc, argv, &req.n);
-+	if (ret < 0)
-+		return -1;
-+
-+	if (rtnl_talk(&genl_rth, &req.n, do_get ? &answer : NULL) < 0)
-+		return -2;
-+
-+	if (do_get)
-+		return print_mptcp_limit(answer, stdout);
-+	return 0;
-+}
-+
-+int do_mptcp(int argc, char **argv)
-+{
-+	if (argc == 0)
-+		usage();
-+
-+	if (matches(*argv, "help") == 0)
-+		usage();
-+
-+	if (genl_init_handle(&genl_rth, MPTCP_PM_NAME, &genl_family))
-+		exit(1);
-+
-+	if (matches(*argv, "endpoint") == 0) {
-+		NEXT_ARG_FWD();
-+		if (argc == 0)
-+			return mptcp_addr_show(0, NULL);
-+
-+		if (matches(*argv, "add") == 0)
-+			return mptcp_addr_modify(argc-1, argv+1,
-+						 MPTCP_PM_CMD_ADD_ADDR);
-+		if (matches(*argv, "delete") == 0)
-+			return mptcp_addr_modify(argc-1, argv+1,
-+						 MPTCP_PM_CMD_DEL_ADDR);
-+		if (matches(*argv, "show") == 0)
-+			return mptcp_addr_show(argc-1, argv+1);
-+		if (matches(*argv, "flush") == 0)
-+			return mptcp_addr_flush(argc-1, argv+1);
-+
-+		goto unknown;
-+	}
-+
-+	if (matches(*argv, "limits") == 0) {
-+		NEXT_ARG_FWD();
-+		if (argc == 0)
-+			return mptcp_limit_get_set(0, NULL,
-+						   MPTCP_PM_CMD_GET_LIMITS);
-+
-+		if (matches(*argv, "set") == 0)
-+			return mptcp_limit_get_set(argc-1, argv+1,
-+						   MPTCP_PM_CMD_SET_LIMITS);
-+		if (matches(*argv, "show") == 0)
-+			return mptcp_limit_get_set(argc-1, argv+1,
-+						   MPTCP_PM_CMD_GET_LIMITS);
-+	}
-+
-+unknown:
-+	fprintf(stderr, "Command \"%s\" is unknown, try \"ip mptcp help\".\n",
-+		*argv);
-+	exit(-1);
-+}
--- 
-2.26.2
-
diff --git a/SOURCES/0018-Update-kernel-headers.patch b/SOURCES/0018-Update-kernel-headers.patch
deleted file mode 100644
index 9129be5..0000000
--- a/SOURCES/0018-Update-kernel-headers.patch
+++ /dev/null
@@ -1,217 +0,0 @@
-From 98f0c643a333ff630407828f4141131502edc6f9 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 4 Jun 2020 19:26:50 +0200
-Subject: [PATCH] Update kernel headers
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1812207
-Upstream Status: unknown commit 3d72f125c300d
-
-commit 3d72f125c300dd261a5151cf1cac7cfa152376b2
-Author: David Ahern <dsahern@gmail.com>
-Date:   Sun Sep 15 10:32:58 2019 -0700
-
-    Update kernel headers
-
-    Update kernel headers to commit:
-        aa2eaa8c272a ("Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net")
-
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- include/uapi/linux/bpf.h       | 15 ++++++++++++---
- include/uapi/linux/can.h       | 20 +++++++++++++++++++-
- include/uapi/linux/devlink.h   | 11 +++++++++++
- include/uapi/linux/inet_diag.h |  9 +++++++++
- include/uapi/linux/pkt_cls.h   |  2 ++
- include/uapi/linux/sctp.h      |  3 +++
- 6 files changed, 56 insertions(+), 4 deletions(-)
-
-diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
-index 3e195ff43fa01..6d55239a4cc0f 100644
---- a/include/uapi/linux/bpf.h
-+++ b/include/uapi/linux/bpf.h
-@@ -106,6 +106,7 @@ enum bpf_cmd {
- 	BPF_TASK_FD_QUERY,
- 	BPF_MAP_LOOKUP_AND_DELETE_ELEM,
- 	BPF_MAP_FREEZE,
-+	BPF_BTF_GET_NEXT_ID,
- };
- 
- enum bpf_map_type {
-@@ -284,6 +285,9 @@ enum bpf_attach_type {
-  */
- #define BPF_F_TEST_RND_HI32	(1U << 2)
- 
-+/* The verifier internal test flag. Behavior is undefined */
-+#define BPF_F_TEST_STATE_FREQ	(1U << 3)
-+
- /* When BPF ldimm64's insn[0].src_reg != 0 then this can have
-  * two extensions:
-  *
-@@ -337,6 +341,9 @@ enum bpf_attach_type {
- #define BPF_F_RDONLY_PROG	(1U << 7)
- #define BPF_F_WRONLY_PROG	(1U << 8)
- 
-+/* Clone map from listener for newly accepted socket */
-+#define BPF_F_CLONE		(1U << 9)
-+
- /* flags for BPF_PROG_QUERY */
- #define BPF_F_QUERY_EFFECTIVE	(1U << 0)
- 
-@@ -577,6 +584,8 @@ union bpf_attr {
-  * 		limited to five).
-  *
-  * 		Each time the helper is called, it appends a line to the trace.
-+ * 		Lines are discarded while *\/sys/kernel/debug/tracing/trace* is
-+ * 		open, use *\/sys/kernel/debug/tracing/trace_pipe* to avoid this.
-  * 		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
-@@ -1015,7 +1024,7 @@ union bpf_attr {
-  * 		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)
-+ * int bpf_perf_event_output(struct pt_regs *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
-@@ -1077,7 +1086,7 @@ union bpf_attr {
-  * 	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)
-+ * int bpf_get_stackid(struct pt_regs *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
-@@ -1726,7 +1735,7 @@ union bpf_attr {
-  * 	Return
-  * 		0 on success, or a negative error in case of failure.
-  *
-- * int bpf_override_return(struct pt_reg *regs, u64 rc)
-+ * int bpf_override_return(struct pt_regs *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*.
-diff --git a/include/uapi/linux/can.h b/include/uapi/linux/can.h
-index 9009f0b6505cf..c61cdc7ad5cc6 100644
---- a/include/uapi/linux/can.h
-+++ b/include/uapi/linux/can.h
-@@ -157,7 +157,8 @@ struct canfd_frame {
- #define CAN_TP20	4 /* VAG Transport Protocol v2.0 */
- #define CAN_MCNET	5 /* Bosch MCNet */
- #define CAN_ISOTP	6 /* ISO 15765-2 Transport Protocol */
--#define CAN_NPROTO	7
-+#define CAN_J1939	7 /* SAE J1939 */
-+#define CAN_NPROTO	8
- 
- #define SOL_CAN_BASE 100
- 
-@@ -174,6 +175,23 @@ struct sockaddr_can {
- 		/* transport protocol class address information (e.g. ISOTP) */
- 		struct { canid_t rx_id, tx_id; } tp;
- 
-+		/* J1939 address information */
-+		struct {
-+			/* 8 byte name when using dynamic addressing */
-+			__u64 name;
-+
-+			/* pgn:
-+			 * 8 bit: PS in PDU2 case, else 0
-+			 * 8 bit: PF
-+			 * 1 bit: DP
-+			 * 1 bit: reserved
-+			 */
-+			__u32 pgn;
-+
-+			/* 1 byte address */
-+			__u8 addr;
-+		} j1939;
-+
- 		/* reserved for future CAN protocols address information */
- 	} can_addr;
- };
-diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
-index 3fb683bee6ba1..79e1405db67cc 100644
---- a/include/uapi/linux/devlink.h
-+++ b/include/uapi/linux/devlink.h
-@@ -202,6 +202,15 @@ enum devlink_param_cmode {
- enum devlink_param_fw_load_policy_value {
- 	DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_DRIVER,
- 	DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_FLASH,
-+	DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_DISK,
-+	DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_UNKNOWN,
-+};
-+
-+enum devlink_param_reset_dev_on_drv_probe_value {
-+	DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_UNKNOWN,
-+	DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_ALWAYS,
-+	DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_NEVER,
-+	DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_DISK,
- };
- 
- enum {
-@@ -410,6 +419,8 @@ enum devlink_attr {
- 	DEVLINK_ATTR_TRAP_METADATA,			/* nested */
- 	DEVLINK_ATTR_TRAP_GROUP_NAME,			/* string */
- 
-+	DEVLINK_ATTR_RELOAD_FAILED,			/* u8 0 or 1 */
-+
- 	/* add new attributes above here, update the policy in devlink.c */
- 
- 	__DEVLINK_ATTR_MAX,
-diff --git a/include/uapi/linux/inet_diag.h b/include/uapi/linux/inet_diag.h
-index f3bcd7ee82771..3dff6841486a4 100644
---- a/include/uapi/linux/inet_diag.h
-+++ b/include/uapi/linux/inet_diag.h
-@@ -153,11 +153,20 @@ enum {
- 	INET_DIAG_BBRINFO,	/* request as INET_DIAG_VEGASINFO */
- 	INET_DIAG_CLASS_ID,	/* request as INET_DIAG_TCLASS */
- 	INET_DIAG_MD5SIG,
-+	INET_DIAG_ULP_INFO,
- 	__INET_DIAG_MAX,
- };
- 
- #define INET_DIAG_MAX (__INET_DIAG_MAX - 1)
- 
-+enum {
-+	INET_ULP_INFO_UNSPEC,
-+	INET_ULP_INFO_NAME,
-+	INET_ULP_INFO_TLS,
-+	__INET_ULP_INFO_MAX,
-+};
-+#define INET_ULP_INFO_MAX (__INET_ULP_INFO_MAX - 1)
-+
- /* INET_DIAG_MEM */
- 
- struct inet_diag_meminfo {
-diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
-index 0a9ab625cba7b..c6ad22f76edee 100644
---- a/include/uapi/linux/pkt_cls.h
-+++ b/include/uapi/linux/pkt_cls.h
-@@ -165,6 +165,8 @@ enum {
- 	TCA_POLICE_RESULT,
- 	TCA_POLICE_TM,
- 	TCA_POLICE_PAD,
-+	TCA_POLICE_RATE64,
-+	TCA_POLICE_PEAKRATE64,
- 	__TCA_POLICE_MAX
- #define TCA_POLICE_RESULT TCA_POLICE_RESULT
- };
-diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
-index c4bce0a2011c1..0d4c1507a169d 100644
---- a/include/uapi/linux/sctp.h
-+++ b/include/uapi/linux/sctp.h
-@@ -134,6 +134,9 @@ typedef __s32 sctp_assoc_t;
- #define SCTP_INTERLEAVING_SUPPORTED	125
- #define SCTP_SENDMSG_CONNECT	126
- #define SCTP_EVENT	127
-+#define SCTP_ASCONF_SUPPORTED	128
-+#define SCTP_AUTH_SUPPORTED	129
-+#define SCTP_ECN_SUPPORTED	130
- 
- /* PR-SCTP policies */
- #define SCTP_PR_SCTP_NONE	0x0000
--- 
-2.26.2
-
diff --git a/SOURCES/0019-Update-kernel-headers.patch b/SOURCES/0019-Update-kernel-headers.patch
deleted file mode 100644
index f6e47ee..0000000
--- a/SOURCES/0019-Update-kernel-headers.patch
+++ /dev/null
@@ -1,150 +0,0 @@
-From 4dfaa0a3e4ea077d95d7355e73a8069b1c8af97b Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 4 Jun 2020 19:26:50 +0200
-Subject: [PATCH] Update kernel headers
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1812207
-Upstream Status: unknown commit ce9191ffee31d
-Conflicts: several unrelated missing changes in uapi
-
-commit ce9191ffee31d440591bf49ef530b80ee9975dfb
-Author: David Ahern <dsahern@gmail.com>
-Date:   Tue Mar 31 23:23:28 2020 +0000
-
-    Update kernel headers
-
-    Update kernel headers to commit:
-        7f80ccfe9968 ("net: ipv6: rpl_iptunnel: Fix potential memory leak in rpl_do_srh_inline")
-
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- include/uapi/linux/bpf.h       | 20 +++++++++++++++++++-
- include/uapi/linux/devlink.h   |  6 ++++++
- include/uapi/linux/if_link.h   |  5 ++++-
- include/uapi/linux/inet_diag.h |  1 +
- include/uapi/linux/lwtunnel.h  |  1 +
- 5 files changed, 31 insertions(+), 2 deletions(-)
-
-diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
-index 6d55239a4cc0f..94aa5a1d38215 100644
---- a/include/uapi/linux/bpf.h
-+++ b/include/uapi/linux/bpf.h
-@@ -483,7 +483,7 @@ union bpf_attr {
- 		__u32		prog_cnt;
- 	} query;
- 
--	struct {
-+	struct { /* anonymous struct used by BPF_RAW_TRACEPOINT_OPEN command */
- 		__u64 name;
- 		__u32 prog_fd;
- 	} raw_tracepoint;
-@@ -511,6 +511,24 @@ union bpf_attr {
- 		__u64		probe_offset;	/* output: probe_offset */
- 		__u64		probe_addr;	/* output: probe_addr */
- 	} task_fd_query;
-+
-+	struct { /* struct used by BPF_LINK_CREATE command */
-+		__u32		prog_fd;	/* eBPF program to attach */
-+		__u32		target_fd;	/* object to attach to */
-+		__u32		attach_type;	/* attach type */
-+		__u32		flags;		/* extra flags */
-+	} link_create;
-+
-+	struct { /* struct used by BPF_LINK_UPDATE command */
-+		__u32		link_fd;	/* link fd */
-+		/* new program fd to update link with */
-+		__u32		new_prog_fd;
-+		__u32		flags;		/* extra flags */
-+		/* expected link's program fd; is specified only if
-+		 * BPF_F_REPLACE flag is set in flags */
-+		__u32		old_prog_fd;
-+	} link_update;
-+
- } __attribute__((aligned(8)));
- 
- /* The description below is an attempt at providing documentation to eBPF
-diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
-index 79e1405db67cc..e63aeab76bcb8 100644
---- a/include/uapi/linux/devlink.h
-+++ b/include/uapi/linux/devlink.h
-@@ -117,6 +117,11 @@ enum devlink_command {
- 	DEVLINK_CMD_TRAP_GROUP_NEW,
- 	DEVLINK_CMD_TRAP_GROUP_DEL,
- 
-+	DEVLINK_CMD_TRAP_POLICER_GET,	/* can dump */
-+	DEVLINK_CMD_TRAP_POLICER_SET,
-+	DEVLINK_CMD_TRAP_POLICER_NEW,
-+	DEVLINK_CMD_TRAP_POLICER_DEL,
-+
- 	/* add new commands above here */
- 	__DEVLINK_CMD_MAX,
- 	DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
-@@ -216,6 +221,7 @@ enum devlink_param_reset_dev_on_drv_probe_value {
- enum {
- 	DEVLINK_ATTR_STATS_RX_PACKETS,		/* u64 */
- 	DEVLINK_ATTR_STATS_RX_BYTES,		/* u64 */
-+	DEVLINK_ATTR_STATS_RX_DROPPED,		/* u64 */
- 
- 	__DEVLINK_ATTR_STATS_MAX,
- 	DEVLINK_ATTR_STATS_MAX = __DEVLINK_ATTR_STATS_MAX - 1
-diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
-index 4da0768d7a5a3..5d69479b8052d 100644
---- a/include/uapi/linux/if_link.h
-+++ b/include/uapi/linux/if_link.h
-@@ -459,6 +459,7 @@ enum {
- 	IFLA_MACSEC_REPLAY_PROTECT,
- 	IFLA_MACSEC_VALIDATION,
- 	IFLA_MACSEC_PAD,
-+	IFLA_MACSEC_OFFLOAD,
- 	__IFLA_MACSEC_MAX,
- };
- 
-@@ -949,11 +950,12 @@ enum {
- #define XDP_FLAGS_SKB_MODE		(1U << 1)
- #define XDP_FLAGS_DRV_MODE		(1U << 2)
- #define XDP_FLAGS_HW_MODE		(1U << 3)
-+#define XDP_FLAGS_REPLACE		(1U << 4)
- #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)
-+					 XDP_FLAGS_MODES | XDP_FLAGS_REPLACE)
- 
- /* These are stored into IFLA_XDP_ATTACHED on dump. */
- enum {
-@@ -973,6 +975,7 @@ enum {
- 	IFLA_XDP_DRV_PROG_ID,
- 	IFLA_XDP_SKB_PROG_ID,
- 	IFLA_XDP_HW_PROG_ID,
-+	IFLA_XDP_EXPECTED_FD,
- 	__IFLA_XDP_MAX,
- };
- 
-diff --git a/include/uapi/linux/inet_diag.h b/include/uapi/linux/inet_diag.h
-index 3dff6841486a4..db45fc664a5fd 100644
---- a/include/uapi/linux/inet_diag.h
-+++ b/include/uapi/linux/inet_diag.h
-@@ -163,6 +163,7 @@ enum {
- 	INET_ULP_INFO_UNSPEC,
- 	INET_ULP_INFO_NAME,
- 	INET_ULP_INFO_TLS,
-+	INET_ULP_INFO_MPTCP,
- 	__INET_ULP_INFO_MAX,
- };
- #define INET_ULP_INFO_MAX (__INET_ULP_INFO_MAX - 1)
-diff --git a/include/uapi/linux/lwtunnel.h b/include/uapi/linux/lwtunnel.h
-index 3f3fe6f30df0b..0ba94063c1809 100644
---- a/include/uapi/linux/lwtunnel.h
-+++ b/include/uapi/linux/lwtunnel.h
-@@ -13,6 +13,7 @@ enum lwtunnel_encap_types {
- 	LWTUNNEL_ENCAP_SEG6,
- 	LWTUNNEL_ENCAP_BPF,
- 	LWTUNNEL_ENCAP_SEG6_LOCAL,
-+	LWTUNNEL_ENCAP_RPL,
- 	__LWTUNNEL_ENCAP_MAX,
- };
- 
--- 
-2.26.2
-
diff --git a/SOURCES/0020-ss-allow-dumping-MPTCP-subflow-information.patch b/SOURCES/0020-ss-allow-dumping-MPTCP-subflow-information.patch
deleted file mode 100644
index 2189263..0000000
--- a/SOURCES/0020-ss-allow-dumping-MPTCP-subflow-information.patch
+++ /dev/null
@@ -1,144 +0,0 @@
-From afc9c910cc9c818180364860b04535def3c19b6e Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 4 Jun 2020 19:27:41 +0200
-Subject: [PATCH] ss: allow dumping MPTCP subflow information
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1812207
-Upstream Status: unknown commit 712fdd98c0839
-Conflicts: context changes and code slightly adapted in tcp_show_info()
-           due to missing commit 14cadc707b919 ("ss: allow dumping kTLS info")
-
-commit 712fdd98c0839540a50baca0fb858c7a72d18031
-Author: Davide Caratti <dcaratti@redhat.com>
-Date:   Thu Apr 23 15:37:09 2020 +0200
-
-    ss: allow dumping MPTCP subflow information
-
-     [root@f31 packetdrill]# ss -tni
-
-     ESTAB    0        0           192.168.82.247:8080           192.0.2.1:35273
-              cubic wscale:7,8 [...] tcp-ulp-mptcp flags:Mec token:0000(id:0)/5f856c60(id:0) seq:b810457db34209a5 sfseq:1 ssnoff:0 maplen:190
-
-    Additionally extends ss manpage to describe the new entry layout.
-
-    Signed-off-by: Davide Caratti <dcaratti@redhat.com>
-    Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- man/man8/ss.8 |  5 ++++
- misc/ss.c     | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 74 insertions(+)
-
-diff --git a/man/man8/ss.8 b/man/man8/ss.8
-index 023d771b17878..c80853f98c49a 100644
---- a/man/man8/ss.8
-+++ b/man/man8/ss.8
-@@ -261,6 +261,11 @@ the pacing rate and max pacing rate
- .TP
- .B rcv_space:<rcv_space>
- a helper variable for TCP internal auto tuning socket receive buffer
-+.P
-+.TP
-+.B tcp-ulp-mptcp flags:[MmBbJjecv] token:<rem_token(rem_id)/loc_token(loc_id)> seq:<sn> sfseq:<ssn> ssnoff:<off> maplen:<maplen>
-+MPTCP subflow information
-+.P
- .RE
- .TP
- .B \-\-tos
-diff --git a/misc/ss.c b/misc/ss.c
-index 363b4c8d87cd3..3d565af86087c 100644
---- a/misc/ss.c
-+++ b/misc/ss.c
-@@ -51,6 +51,7 @@
- #include <linux/tipc.h>
- #include <linux/tipc_netlink.h>
- #include <linux/tipc_sockets_diag.h>
-+#include <linux/mptcp.h>
- 
- /* AF_VSOCK/PF_VSOCK is only provided since glibc 2.18 */
- #ifndef PF_VSOCK
-@@ -2751,6 +2752,59 @@ static void print_md5sig(struct tcp_diag_md5sig *sig)
- 	print_escape_buf(sig->tcpm_key, sig->tcpm_keylen, " ,");
- }
- 
-+static void mptcp_subflow_info(struct rtattr *tb[])
-+{
-+	u_int32_t flags = 0;
-+
-+	if (tb[MPTCP_SUBFLOW_ATTR_FLAGS]) {
-+		char caps[32 + 1] = { 0 }, *cap = &caps[0];
-+
-+		flags = rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_FLAGS]);
-+
-+		if (flags & MPTCP_SUBFLOW_FLAG_MCAP_REM)
-+			*cap++ = 'M';
-+		if (flags & MPTCP_SUBFLOW_FLAG_MCAP_LOC)
-+			*cap++ = 'm';
-+		if (flags & MPTCP_SUBFLOW_FLAG_JOIN_REM)
-+			*cap++ = 'J';
-+		if (flags & MPTCP_SUBFLOW_FLAG_JOIN_LOC)
-+			*cap++ = 'j';
-+		if (flags & MPTCP_SUBFLOW_FLAG_BKUP_REM)
-+			*cap++ = 'B';
-+		if (flags & MPTCP_SUBFLOW_FLAG_BKUP_LOC)
-+			*cap++ = 'b';
-+		if (flags & MPTCP_SUBFLOW_FLAG_FULLY_ESTABLISHED)
-+			*cap++ = 'e';
-+		if (flags & MPTCP_SUBFLOW_FLAG_CONNECTED)
-+			*cap++ = 'c';
-+		if (flags & MPTCP_SUBFLOW_FLAG_MAPVALID)
-+			*cap++ = 'v';
-+		if (flags)
-+			out(" flags:%s", caps);
-+	}
-+	if (tb[MPTCP_SUBFLOW_ATTR_TOKEN_REM] &&
-+	    tb[MPTCP_SUBFLOW_ATTR_TOKEN_LOC] &&
-+	    tb[MPTCP_SUBFLOW_ATTR_ID_REM] &&
-+	    tb[MPTCP_SUBFLOW_ATTR_ID_LOC])
-+		out(" token:%04x(id:%hhu)/%04x(id:%hhu)",
-+		    rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_TOKEN_REM]),
-+		    rta_getattr_u8(tb[MPTCP_SUBFLOW_ATTR_ID_REM]),
-+		    rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_TOKEN_LOC]),
-+		    rta_getattr_u8(tb[MPTCP_SUBFLOW_ATTR_ID_LOC]));
-+	if (tb[MPTCP_SUBFLOW_ATTR_MAP_SEQ])
-+		out(" seq:%llx",
-+		    rta_getattr_u64(tb[MPTCP_SUBFLOW_ATTR_MAP_SEQ]));
-+	if (tb[MPTCP_SUBFLOW_ATTR_MAP_SFSEQ])
-+		out(" sfseq:%x",
-+		    rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_MAP_SFSEQ]));
-+	if (tb[MPTCP_SUBFLOW_ATTR_SSN_OFFSET])
-+		out(" ssnoff:%x",
-+		    rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_SSN_OFFSET]));
-+	if (tb[MPTCP_SUBFLOW_ATTR_MAP_DATALEN])
-+		out(" maplen:%x",
-+		    rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_MAP_DATALEN]));
-+}
-+
- #define TCPI_HAS_OPT(info, opt) !!(info->tcpi_options & (opt))
- 
- static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r,
-@@ -2906,6 +2960,21 @@ static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r,
- 			print_md5sig(sig++);
- 		}
- 	}
-+	if (tb[INET_DIAG_ULP_INFO]) {
-+		struct rtattr *ulpinfo[INET_ULP_INFO_MAX + 1] = { 0 };
-+
-+		parse_rtattr_nested(ulpinfo, INET_ULP_INFO_MAX,
-+				    tb[INET_DIAG_ULP_INFO]);
-+
-+		if (ulpinfo[INET_ULP_INFO_MPTCP]) {
-+			struct rtattr *sfinfo[MPTCP_SUBFLOW_ATTR_MAX + 1] =
-+				{ 0 };
-+
-+			parse_rtattr_nested(sfinfo, MPTCP_SUBFLOW_ATTR_MAX,
-+					    ulpinfo[INET_ULP_INFO_MPTCP]);
-+			mptcp_subflow_info(sfinfo);
-+		}
-+	}
- }
- 
- static const char *format_host_sa(struct sockaddr_storage *sa)
--- 
-2.26.2
-
diff --git a/SOURCES/0021-man-mptcp-man-page.patch b/SOURCES/0021-man-mptcp-man-page.patch
deleted file mode 100644
index f9aed62..0000000
--- a/SOURCES/0021-man-mptcp-man-page.patch
+++ /dev/null
@@ -1,174 +0,0 @@
-From af65892658d7c271d1fb328065a35f8017610418 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 4 Jun 2020 19:28:45 +0200
-Subject: [PATCH] man: mptcp man page
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1812207
-Upstream Status: unknown commit 2d8b5fe93e9de
-
-commit 2d8b5fe93e9decb56acc243905d82fb22d6c4cfd
-Author: Paolo Abeni <pabeni@redhat.com>
-Date:   Thu Apr 23 15:37:10 2020 +0200
-
-    man: mptcp man page
-
-    describe the mptcp subcommands implemented so far.
-
-    Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- man/man8/ip-mptcp.8 | 142 ++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 142 insertions(+)
- create mode 100644 man/man8/ip-mptcp.8
-
-diff --git a/man/man8/ip-mptcp.8 b/man/man8/ip-mptcp.8
-new file mode 100644
-index 0000000000000..f6457e97efbe8
---- /dev/null
-+++ b/man/man8/ip-mptcp.8
-@@ -0,0 +1,142 @@
-+.TH IP\-MPTCP 8 "4 Apr 2020" "iproute2" "Linux"
-+.SH "NAME"
-+ip-mptcp \- MPTCP path manager configuration
-+.SH "SYNOPSIS"
-+.sp
-+.ad l
-+.in +8
-+.ti -8
-+.B ip
-+.RI "[ " OPTIONS " ]"
-+.B mptcp
-+.RB "{ "
-+.B endpoint
-+.RB " | "
-+.B limits
-+.RB " | "
-+.B help
-+.RB " }"
-+.sp
-+
-+.ti -8
-+.BR "ip mptcp endpoint add "
-+.IR IFADDR
-+.RB "[ " dev
-+.IR IFNAME " ]"
-+.RB "[ " id
-+.I ID
-+.RB "] [ "
-+.I FLAG-LIST
-+.RB "] "
-+
-+.ti -8
-+.BR "ip mptcp endpoint del id "
-+.I ID
-+
-+.ti -8
-+.BR "ip mptcp endpoint show "
-+.RB "[ " id
-+.I ID
-+.RB "]"
-+
-+.ti -8
-+.BR "ip mptcp endpoint flush"
-+
-+.ti -8
-+.IR FLAG-LIST " := [ "  FLAG-LIST " ] " FLAG
-+
-+.ti -8
-+.IR FLAG " := ["
-+.B signal
-+.RB "|"
-+.B subflow
-+.RB "|"
-+.B backup
-+.RB  "]"
-+
-+.ti -8
-+.BR "ip mptcp limits set "
-+.RB "[ "
-+.B subflow
-+.IR SUBFLOW_NR " ]"
-+.RB "[ "
-+.B add_addr_accepted
-+.IR  ADD_ADDR_ACCEPTED_NR " ]"
-+
-+.ti -8
-+.BR "ip mptcp limits show"
-+
-+.SH DESCRIPTION
-+
-+MPTCP is a transport protocol built on top of TCP that allows TCP
-+connections to use multiple paths to maximize resource usage and increase
-+redundancy. The ip-mptcp sub-commands allow configuring several aspects of the
-+MPTCP path manager, which is in charge of subflows creation:
-+
-+.P
-+The
-+.B endpoint
-+object specifies the IP addresses that will be used and/or announced for
-+additional subflows:
-+
-+.TS
-+l l.
-+ip mptcp endpoint add	add new MPTCP endpoint
-+ip mptcp endpoint delete	delete existing MPTCP endpoint
-+ip mptcp endpoint show	get existing MPTCP endpoint
-+ip mptcp endpoint flush	flush all existing MPTCP endpoints
-+.TE
-+
-+.TP
-+.IR ID
-+is a unique numeric identifier for the given endpoint
-+
-+.TP
-+.BR signal
-+the endpoint will be announced/signalled to each peer via an ADD_ADDR MPTCP
-+sub-option
-+
-+.TP
-+.BR subflow
-+if additional subflow creation is allowed by MPTCP limits, the endpoint will
-+be used as the source address to create an additional subflow after that
-+the MPTCP connection is established.
-+
-+.TP
-+.BR backup
-+the endpoint will be announced as a backup address, if this is a
-+.BR signal
-+endpoint, or the subflow will be created as a backup one if this is a
-+.BR subflow
-+endpoint
-+
-+.sp
-+.PP
-+The
-+.B limits
-+object specifies the constraints for subflow creations:
-+
-+.TS
-+l l.
-+ip mptcp limits show	get current MPTCP subflow creation limits
-+ip mptcp limits set	change the MPTCP subflow creation limits
-+.TE
-+
-+.TP
-+.IR SUBFLOW_NR
-+specifies the maximum number of additional subflows allowed for each MPTCP
-+connection. Additional subflows can be created due to: incoming accepted
-+ADD_ADDR option, local
-+.BR subflow
-+endpoints, additional subflows started by the peer.
-+
-+.TP
-+.IR ADD_ADDR_ACCEPTED_NR
-+specifies the maximum number of ADD_ADDR suboptions accepted for each MPTCP
-+connection. The MPTCP path manager will try to create a new subflow for
-+each accepted ADD_ADDR option, respecting the
-+.IR SUBFLOW_NR
-+limit.
-+
-+.SH AUTHOR
-+Original Manpage by Paolo Abeni <pabeni@redhat.com>
--- 
-2.26.2
-
diff --git a/SOURCES/0022-man-ip.8-add-reference-to-mptcp-man-page.patch b/SOURCES/0022-man-ip.8-add-reference-to-mptcp-man-page.patch
deleted file mode 100644
index c38458f..0000000
--- a/SOURCES/0022-man-ip.8-add-reference-to-mptcp-man-page.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From c2e8f8b4c1980c773b967953b795f81942e209fb Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 4 Jun 2020 19:28:45 +0200
-Subject: [PATCH] man: ip.8: add reference to mptcp man-page
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1812207
-Upstream Status: unknown commit 0c42c6b130196
-
-commit 0c42c6b130196d1d7e87acc5122f8fd325e75c5b
-Author: Paolo Abeni <pabeni@redhat.com>
-Date:   Wed Apr 29 19:17:22 2020 +0200
-
-    man: ip.8: add reference to mptcp man-page
-
-    While at it, additionally fix a mandoc warning in mptcp.8
-
-    Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- man/man8/ip-mptcp.8 | 1 -
- man/man8/ip.8       | 7 ++++++-
- 2 files changed, 6 insertions(+), 2 deletions(-)
-
-diff --git a/man/man8/ip-mptcp.8 b/man/man8/ip-mptcp.8
-index f6457e97efbe8..ef8409ea4a24d 100644
---- a/man/man8/ip-mptcp.8
-+++ b/man/man8/ip-mptcp.8
-@@ -2,7 +2,6 @@
- .SH "NAME"
- ip-mptcp \- MPTCP path manager configuration
- .SH "SYNOPSIS"
--.sp
- .ad l
- .in +8
- .ti -8
-diff --git a/man/man8/ip.8 b/man/man8/ip.8
-index c425aaf1d506e..f391237b4fcae 100644
---- a/man/man8/ip.8
-+++ b/man/man8/ip.8
-@@ -22,7 +22,7 @@ ip \- show / manipulate routing, network devices, interfaces and tunnels
- .BR link " | " address " | " addrlabel " | " route " | " rule " | " neigh " | "\
-  ntable " | " tunnel " | " tuntap " | " maddress " | "  mroute " | " mrule " | "\
-  monitor " | " xfrm " | " netns " | "  l2tp " | "  tcp_metrics " | " token " | "\
-- macsec " | " vrf " }"
-+ macsec " | " vrf " | " mptcp " }"
- .sp
- 
- .ti -8
-@@ -268,6 +268,10 @@ readability.
- .B monitor
- - watch for netlink messages.
- 
-+.TP
-+.B mptcp
-+- manage MPTCP path manager.
-+
- .TP
- .B mroute
- - multicast routing cache entry.
-@@ -406,6 +410,7 @@ was written by Alexey N. Kuznetsov and added in Linux 2.2.
- .BR ip-link (8),
- .BR ip-maddress (8),
- .BR ip-monitor (8),
-+.BR ip-mptcp (8),
- .BR ip-mroute (8),
- .BR ip-neighbour (8),
- .BR ip-netns (8),
--- 
-2.26.2
-
diff --git a/SOURCES/0023-Update-kernel-headers.patch b/SOURCES/0023-Update-kernel-headers.patch
deleted file mode 100644
index 7d329c4..0000000
--- a/SOURCES/0023-Update-kernel-headers.patch
+++ /dev/null
@@ -1,568 +0,0 @@
-From f0023a7d874697821516583c1b3be95e2f110668 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 4 Jun 2020 21:41:59 +0200
-Subject: [PATCH] Update kernel headers
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1830485
-Upstream Status: iproute2.git commit 7438afd2cc8d3
-Conflicts: on devlink uapi due to missing commit 9dcd8788fe6bc
-           ("Update kernel headers")
-
-commit 7438afd2cc8d37fd7f12e29963e1d926de53dda7
-Author: David Ahern <dsahern@gmail.com>
-Date:   Mon Nov 25 23:13:09 2019 +0000
-
-    Update kernel headers
-
-    Update kernel headers to commit:
-        c431047c4efe ("enetc: add support Credit Based Shaper(CBS) for hardware offload")
-
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- include/uapi/linux/bpf.h                    | 130 ++++++++++++++------
- include/uapi/linux/gen_stats.h              |   5 +-
- include/uapi/linux/lwtunnel.h               |  41 ++++++
- include/uapi/linux/netfilter/ipset/ip_set.h |   2 +
- include/uapi/linux/pkt_cls.h                |  29 +++++
- include/uapi/linux/pkt_sched.h              |  22 ++--
- include/uapi/linux/sctp.h                   |  15 +++
- include/uapi/linux/tc_act/tc_tunnel_key.h   |  29 +++++
- include/uapi/linux/tipc.h                   |  21 ++++
- include/uapi/linux/tipc_netlink.h           |   4 +
- 10 files changed, 246 insertions(+), 52 deletions(-)
-
-diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
-index 94aa5a1d38215..bf3475f915cf1 100644
---- a/include/uapi/linux/bpf.h
-+++ b/include/uapi/linux/bpf.h
-@@ -173,6 +173,7 @@ enum bpf_prog_type {
- 	BPF_PROG_TYPE_CGROUP_SYSCTL,
- 	BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE,
- 	BPF_PROG_TYPE_CGROUP_SOCKOPT,
-+	BPF_PROG_TYPE_TRACING,
- };
- 
- enum bpf_attach_type {
-@@ -199,6 +200,9 @@ enum bpf_attach_type {
- 	BPF_CGROUP_UDP6_RECVMSG,
- 	BPF_CGROUP_GETSOCKOPT,
- 	BPF_CGROUP_SETSOCKOPT,
-+	BPF_TRACE_RAW_TP,
-+	BPF_TRACE_FENTRY,
-+	BPF_TRACE_FEXIT,
- 	__MAX_BPF_ATTACH_TYPE
- };
- 
-@@ -344,6 +348,9 @@ enum bpf_attach_type {
- /* Clone map from listener for newly accepted socket */
- #define BPF_F_CLONE		(1U << 9)
- 
-+/* Enable memory-mapping BPF map */
-+#define BPF_F_MMAPABLE		(1U << 10)
-+
- /* flags for BPF_PROG_QUERY */
- #define BPF_F_QUERY_EFFECTIVE	(1U << 0)
- 
-@@ -421,6 +428,7 @@ union bpf_attr {
- 		__aligned_u64	line_info;	/* line info */
- 		__u32		line_info_cnt;	/* number of bpf_line_info records */
- 		__u32		attach_btf_id;	/* in-kernel BTF type id to attach to */
-+		__u32		attach_prog_fd; /* 0 to attach to vmlinux */
- 	};
- 
- 	struct { /* anonymous struct used by BPF_OBJ_* commands */
-@@ -579,10 +587,13 @@ union bpf_attr {
-  * 	Return
-  * 		0 on success, or a negative error in case of failure.
-  *
-- * int bpf_probe_read(void *dst, u32 size, const void *src)
-+ * int bpf_probe_read(void *dst, u32 size, const void *unsafe_ptr)
-  * 	Description
-  * 		For tracing programs, safely attempt to read *size* bytes from
-- * 		address *src* and store the data in *dst*.
-+ * 		kernel space address *unsafe_ptr* and store the data in *dst*.
-+ *
-+ * 		Generally, use bpf_probe_read_user() or bpf_probe_read_kernel()
-+ * 		instead.
-  * 	Return
-  * 		0 on success, or a negative error in case of failure.
-  *
-@@ -1444,45 +1455,14 @@ union bpf_attr {
-  * 	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)
-+ * int bpf_probe_read_str(void *dst, u32 size, const void *unsafe_ptr)
-  * 	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.
-- * 			}
-+ * 		Copy a NUL terminated string from an unsafe kernel address
-+ * 		*unsafe_ptr* to *dst*. See bpf_probe_read_kernel_str() for
-+ * 		more details.
-  *
-- * 		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.
-+ * 		Generally, use bpf_probe_read_user_str() or bpf_probe_read_kernel_str()
-+ * 		instead.
-  * 	Return
-  * 		On success, the strictly positive length of the string,
-  * 		including the trailing NUL character. On error, a negative
-@@ -2793,6 +2773,72 @@ union bpf_attr {
-  * 		restricted to raw_tracepoint bpf programs.
-  * 	Return
-  * 		0 on success, or a negative error in case of failure.
-+ *
-+ * int bpf_probe_read_user(void *dst, u32 size, const void *unsafe_ptr)
-+ * 	Description
-+ * 		Safely attempt to read *size* bytes from user space address
-+ * 		*unsafe_ptr* and store the data in *dst*.
-+ * 	Return
-+ * 		0 on success, or a negative error in case of failure.
-+ *
-+ * int bpf_probe_read_kernel(void *dst, u32 size, const void *unsafe_ptr)
-+ * 	Description
-+ * 		Safely attempt to read *size* bytes from kernel space address
-+ * 		*unsafe_ptr* and store the data in *dst*.
-+ * 	Return
-+ * 		0 on success, or a negative error in case of failure.
-+ *
-+ * int bpf_probe_read_user_str(void *dst, u32 size, const void *unsafe_ptr)
-+ * 	Description
-+ * 		Copy a NUL terminated string from an unsafe user 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_user_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_user()** 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.
-+ *
-+ * int bpf_probe_read_kernel_str(void *dst, u32 size, const void *unsafe_ptr)
-+ * 	Description
-+ * 		Copy a NUL terminated string from an unsafe kernel address *unsafe_ptr*
-+ * 		to *dst*. Same semantics as with bpf_probe_read_user_str() apply.
-+ * 	Return
-+ * 		On success, the strictly positive length of the string,	including
-+ * 		the trailing NUL character. On error, a negative value.
-  */
- #define __BPF_FUNC_MAPPER(FN)		\
- 	FN(unspec),			\
-@@ -2906,7 +2952,11 @@ union bpf_attr {
- 	FN(sk_storage_delete),		\
- 	FN(send_signal),		\
- 	FN(tcp_gen_syncookie),		\
--	FN(skb_output),
-+	FN(skb_output),			\
-+	FN(probe_read_user),		\
-+	FN(probe_read_kernel),		\
-+	FN(probe_read_user_str),	\
-+	FN(probe_read_kernel_str),
- 
- /* integer value in 'imm' field of BPF_CALL instruction selects which helper
-  * function eBPF program intends to call
-diff --git a/include/uapi/linux/gen_stats.h b/include/uapi/linux/gen_stats.h
-index 065408e16a807..852f234f1fd63 100644
---- a/include/uapi/linux/gen_stats.h
-+++ b/include/uapi/linux/gen_stats.h
-@@ -13,6 +13,7 @@ enum {
- 	TCA_STATS_RATE_EST64,
- 	TCA_STATS_PAD,
- 	TCA_STATS_BASIC_HW,
-+	TCA_STATS_PKT64,
- 	__TCA_STATS_MAX,
- };
- #define TCA_STATS_MAX (__TCA_STATS_MAX - 1)
-@@ -26,10 +27,6 @@ struct gnet_stats_basic {
- 	__u64	bytes;
- 	__u32	packets;
- };
--struct gnet_stats_basic_packed {
--	__u64	bytes;
--	__u32	packets;
--} __attribute__ ((packed));
- 
- /**
-  * struct gnet_stats_rate_est - rate estimator
-diff --git a/include/uapi/linux/lwtunnel.h b/include/uapi/linux/lwtunnel.h
-index 0ba94063c1809..b7c0191fd1b5f 100644
---- a/include/uapi/linux/lwtunnel.h
-+++ b/include/uapi/linux/lwtunnel.h
-@@ -28,6 +28,7 @@ enum lwtunnel_ip_t {
- 	LWTUNNEL_IP_TOS,
- 	LWTUNNEL_IP_FLAGS,
- 	LWTUNNEL_IP_PAD,
-+	LWTUNNEL_IP_OPTS,
- 	__LWTUNNEL_IP_MAX,
- };
- 
-@@ -42,11 +43,51 @@ enum lwtunnel_ip6_t {
- 	LWTUNNEL_IP6_TC,
- 	LWTUNNEL_IP6_FLAGS,
- 	LWTUNNEL_IP6_PAD,
-+	LWTUNNEL_IP6_OPTS,
- 	__LWTUNNEL_IP6_MAX,
- };
- 
- #define LWTUNNEL_IP6_MAX (__LWTUNNEL_IP6_MAX - 1)
- 
-+enum {
-+	LWTUNNEL_IP_OPTS_UNSPEC,
-+	LWTUNNEL_IP_OPTS_GENEVE,
-+	LWTUNNEL_IP_OPTS_VXLAN,
-+	LWTUNNEL_IP_OPTS_ERSPAN,
-+	__LWTUNNEL_IP_OPTS_MAX,
-+};
-+
-+#define LWTUNNEL_IP_OPTS_MAX (__LWTUNNEL_IP_OPTS_MAX - 1)
-+
-+enum {
-+	LWTUNNEL_IP_OPT_GENEVE_UNSPEC,
-+	LWTUNNEL_IP_OPT_GENEVE_CLASS,
-+	LWTUNNEL_IP_OPT_GENEVE_TYPE,
-+	LWTUNNEL_IP_OPT_GENEVE_DATA,
-+	__LWTUNNEL_IP_OPT_GENEVE_MAX,
-+};
-+
-+#define LWTUNNEL_IP_OPT_GENEVE_MAX (__LWTUNNEL_IP_OPT_GENEVE_MAX - 1)
-+
-+enum {
-+	LWTUNNEL_IP_OPT_VXLAN_UNSPEC,
-+	LWTUNNEL_IP_OPT_VXLAN_GBP,
-+	__LWTUNNEL_IP_OPT_VXLAN_MAX,
-+};
-+
-+#define LWTUNNEL_IP_OPT_VXLAN_MAX (__LWTUNNEL_IP_OPT_VXLAN_MAX - 1)
-+
-+enum {
-+	LWTUNNEL_IP_OPT_ERSPAN_UNSPEC,
-+	LWTUNNEL_IP_OPT_ERSPAN_VER,
-+	LWTUNNEL_IP_OPT_ERSPAN_INDEX,
-+	LWTUNNEL_IP_OPT_ERSPAN_DIR,
-+	LWTUNNEL_IP_OPT_ERSPAN_HWID,
-+	__LWTUNNEL_IP_OPT_ERSPAN_MAX,
-+};
-+
-+#define LWTUNNEL_IP_OPT_ERSPAN_MAX (__LWTUNNEL_IP_OPT_ERSPAN_MAX - 1)
-+
- enum {
- 	LWT_BPF_PROG_UNSPEC,
- 	LWT_BPF_PROG_FD,
-diff --git a/include/uapi/linux/netfilter/ipset/ip_set.h b/include/uapi/linux/netfilter/ipset/ip_set.h
-index c512003dba6ba..4b372f46f0d04 100644
---- a/include/uapi/linux/netfilter/ipset/ip_set.h
-+++ b/include/uapi/linux/netfilter/ipset/ip_set.h
-@@ -205,6 +205,8 @@ enum ipset_cadt_flags {
- 	IPSET_FLAG_WITH_FORCEADD = (1 << IPSET_FLAG_BIT_WITH_FORCEADD),
- 	IPSET_FLAG_BIT_WITH_SKBINFO = 6,
- 	IPSET_FLAG_WITH_SKBINFO = (1 << IPSET_FLAG_BIT_WITH_SKBINFO),
-+	IPSET_FLAG_BIT_IFACE_WILDCARD = 7,
-+	IPSET_FLAG_IFACE_WILDCARD = (1 << IPSET_FLAG_BIT_IFACE_WILDCARD),
- 	IPSET_FLAG_CADT_MAX	= 15,
- };
- 
-diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
-index c6ad22f76edee..449a63971451f 100644
---- a/include/uapi/linux/pkt_cls.h
-+++ b/include/uapi/linux/pkt_cls.h
-@@ -571,6 +571,14 @@ enum {
- 					 * TCA_FLOWER_KEY_ENC_OPT_GENEVE_
- 					 * attributes
- 					 */
-+	TCA_FLOWER_KEY_ENC_OPTS_VXLAN,	/* Nested
-+					 * TCA_FLOWER_KEY_ENC_OPT_VXLAN_
-+					 * attributes
-+					 */
-+	TCA_FLOWER_KEY_ENC_OPTS_ERSPAN,	/* Nested
-+					 * TCA_FLOWER_KEY_ENC_OPT_ERSPAN_
-+					 * attributes
-+					 */
- 	__TCA_FLOWER_KEY_ENC_OPTS_MAX,
- };
- 
-@@ -588,6 +596,27 @@ enum {
- #define TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX \
- 		(__TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX - 1)
- 
-+enum {
-+	TCA_FLOWER_KEY_ENC_OPT_VXLAN_UNSPEC,
-+	TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP,		/* u32 */
-+	__TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX,
-+};
-+
-+#define TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX \
-+		(__TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX - 1)
-+
-+enum {
-+	TCA_FLOWER_KEY_ENC_OPT_ERSPAN_UNSPEC,
-+	TCA_FLOWER_KEY_ENC_OPT_ERSPAN_VER,              /* u8 */
-+	TCA_FLOWER_KEY_ENC_OPT_ERSPAN_INDEX,            /* be32 */
-+	TCA_FLOWER_KEY_ENC_OPT_ERSPAN_DIR,              /* u8 */
-+	TCA_FLOWER_KEY_ENC_OPT_ERSPAN_HWID,             /* u8 */
-+	__TCA_FLOWER_KEY_ENC_OPT_ERSPAN_MAX,
-+};
-+
-+#define TCA_FLOWER_KEY_ENC_OPT_ERSPAN_MAX \
-+		(__TCA_FLOWER_KEY_ENC_OPT_ERSPAN_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/pkt_sched.h b/include/uapi/linux/pkt_sched.h
-index 18f185299f472..dab60bd8f0f4a 100644
---- a/include/uapi/linux/pkt_sched.h
-+++ b/include/uapi/linux/pkt_sched.h
-@@ -950,19 +950,25 @@ enum {
- 	TCA_PIE_BETA,
- 	TCA_PIE_ECN,
- 	TCA_PIE_BYTEMODE,
-+	TCA_PIE_DQ_RATE_ESTIMATOR,
- 	__TCA_PIE_MAX
- };
- #define TCA_PIE_MAX   (__TCA_PIE_MAX - 1)
- 
- struct tc_pie_xstats {
--	__u64 prob;             /* current probability */
--	__u32 delay;            /* current delay in ms */
--	__u32 avg_dq_rate;      /* current average dq_rate in bits/pie_time */
--	__u32 packets_in;       /* total number of packets enqueued */
--	__u32 dropped;          /* packets dropped due to pie_action */
--	__u32 overlimit;        /* dropped due to lack of space in queue */
--	__u32 maxq;             /* maximum queue size */
--	__u32 ecn_mark;         /* packets marked with ecn*/
-+	__u64 prob;			/* current probability */
-+	__u32 delay;			/* current delay in ms */
-+	__u32 avg_dq_rate;		/* current average dq_rate in
-+					 * bits/pie_time
-+					 */
-+	__u32 dq_rate_estimating;	/* is avg_dq_rate being calculated? */
-+	__u32 packets_in;		/* total number of packets enqueued */
-+	__u32 dropped;			/* packets dropped due to pie_action */
-+	__u32 overlimit;		/* dropped due to lack of space
-+					 * in queue
-+					 */
-+	__u32 maxq;			/* maximum queue size */
-+	__u32 ecn_mark;			/* packets marked with ecn*/
- };
- 
- /* CBS */
-diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
-index 0d4c1507a169d..f8f218b16c280 100644
---- a/include/uapi/linux/sctp.h
-+++ b/include/uapi/linux/sctp.h
-@@ -105,6 +105,7 @@ typedef __s32 sctp_assoc_t;
- #define SCTP_DEFAULT_SNDINFO	34
- #define SCTP_AUTH_DEACTIVATE_KEY	35
- #define SCTP_REUSE_PORT		36
-+#define SCTP_PEER_ADDR_THLDS_V2	37
- 
- /* Internal Socket Options. Some of the sctp library functions are
-  * implemented using these socket options.
-@@ -137,6 +138,8 @@ typedef __s32 sctp_assoc_t;
- #define SCTP_ASCONF_SUPPORTED	128
- #define SCTP_AUTH_SUPPORTED	129
- #define SCTP_ECN_SUPPORTED	130
-+#define SCTP_EXPOSE_POTENTIALLY_FAILED_STATE	131
-+#define SCTP_EXPOSE_PF_STATE	SCTP_EXPOSE_POTENTIALLY_FAILED_STATE
- 
- /* PR-SCTP policies */
- #define SCTP_PR_SCTP_NONE	0x0000
-@@ -410,6 +413,8 @@ enum sctp_spc_state {
- 	SCTP_ADDR_ADDED,
- 	SCTP_ADDR_MADE_PRIM,
- 	SCTP_ADDR_CONFIRMED,
-+	SCTP_ADDR_POTENTIALLY_FAILED,
-+#define SCTP_ADDR_PF	SCTP_ADDR_POTENTIALLY_FAILED
- };
- 
- 
-@@ -917,6 +922,7 @@ struct sctp_paddrinfo {
- enum sctp_spinfo_state {
- 	SCTP_INACTIVE,
- 	SCTP_PF,
-+#define	SCTP_POTENTIALLY_FAILED		SCTP_PF
- 	SCTP_ACTIVE,
- 	SCTP_UNCONFIRMED,
- 	SCTP_UNKNOWN = 0xffff  /* Value used for transport state unknown */
-@@ -1062,6 +1068,15 @@ struct sctp_paddrthlds {
- 	__u16 spt_pathpfthld;
- };
- 
-+/* Use a new structure with spt_pathcpthld for back compatibility */
-+struct sctp_paddrthlds_v2 {
-+	sctp_assoc_t spt_assoc_id;
-+	struct sockaddr_storage spt_address;
-+	__u16 spt_pathmaxrxt;
-+	__u16 spt_pathpfthld;
-+	__u16 spt_pathcpthld;
-+};
-+
- /*
-  * Socket Option for Getting the Association/Stream-Specific PR-SCTP Status
-  */
-diff --git a/include/uapi/linux/tc_act/tc_tunnel_key.h b/include/uapi/linux/tc_act/tc_tunnel_key.h
-index 41c8b462c177c..3f10dc4e7a4bb 100644
---- a/include/uapi/linux/tc_act/tc_tunnel_key.h
-+++ b/include/uapi/linux/tc_act/tc_tunnel_key.h
-@@ -50,6 +50,14 @@ enum {
- 						 * TCA_TUNNEL_KEY_ENC_OPTS_
- 						 * attributes
- 						 */
-+	TCA_TUNNEL_KEY_ENC_OPTS_VXLAN,		/* Nested
-+						 * TCA_TUNNEL_KEY_ENC_OPTS_
-+						 * attributes
-+						 */
-+	TCA_TUNNEL_KEY_ENC_OPTS_ERSPAN,		/* Nested
-+						 * TCA_TUNNEL_KEY_ENC_OPTS_
-+						 * attributes
-+						 */
- 	__TCA_TUNNEL_KEY_ENC_OPTS_MAX,
- };
- 
-@@ -67,4 +75,25 @@ enum {
- #define TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX \
- 	(__TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX - 1)
- 
-+enum {
-+	TCA_TUNNEL_KEY_ENC_OPT_VXLAN_UNSPEC,
-+	TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP,		/* u32 */
-+	__TCA_TUNNEL_KEY_ENC_OPT_VXLAN_MAX,
-+};
-+
-+#define TCA_TUNNEL_KEY_ENC_OPT_VXLAN_MAX \
-+	(__TCA_TUNNEL_KEY_ENC_OPT_VXLAN_MAX - 1)
-+
-+enum {
-+	TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_UNSPEC,
-+	TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_VER,		/* u8 */
-+	TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_INDEX,		/* be32 */
-+	TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_DIR,		/* u8 */
-+	TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_HWID,		/* u8 */
-+	__TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_MAX,
-+};
-+
-+#define TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_MAX \
-+	(__TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_MAX - 1)
-+
- #endif
-diff --git a/include/uapi/linux/tipc.h b/include/uapi/linux/tipc.h
-index 0f6f28b2e3010..de5bcd2a09fae 100644
---- a/include/uapi/linux/tipc.h
-+++ b/include/uapi/linux/tipc.h
-@@ -233,6 +233,27 @@ struct tipc_sioc_nodeid_req {
- 	char node_id[TIPC_NODEID_LEN];
- };
- 
-+/*
-+ * TIPC Crypto, AEAD
-+ */
-+#define TIPC_AEAD_ALG_NAME		(32)
-+
-+struct tipc_aead_key {
-+	char alg_name[TIPC_AEAD_ALG_NAME];
-+	unsigned int keylen;	/* in bytes */
-+	char key[];
-+};
-+
-+#define TIPC_AEAD_KEYLEN_MIN		(16 + 4)
-+#define TIPC_AEAD_KEYLEN_MAX		(32 + 4)
-+#define TIPC_AEAD_KEY_SIZE_MAX		(sizeof(struct tipc_aead_key) + \
-+							TIPC_AEAD_KEYLEN_MAX)
-+
-+static __inline__ int tipc_aead_key_size(struct tipc_aead_key *key)
-+{
-+	return sizeof(*key) + key->keylen;
-+}
-+
- /* The macros and functions below are deprecated:
-  */
- 
-diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h
-index efb958fd167d0..6c2194ab745bd 100644
---- a/include/uapi/linux/tipc_netlink.h
-+++ b/include/uapi/linux/tipc_netlink.h
-@@ -63,6 +63,8 @@ enum {
- 	TIPC_NL_PEER_REMOVE,
- 	TIPC_NL_BEARER_ADD,
- 	TIPC_NL_UDP_GET_REMOTEIP,
-+	TIPC_NL_KEY_SET,
-+	TIPC_NL_KEY_FLUSH,
- 
- 	__TIPC_NL_CMD_MAX,
- 	TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
-@@ -160,6 +162,8 @@ enum {
- 	TIPC_NLA_NODE_UNSPEC,
- 	TIPC_NLA_NODE_ADDR,		/* u32 */
- 	TIPC_NLA_NODE_UP,		/* flag */
-+	TIPC_NLA_NODE_ID,		/* data */
-+	TIPC_NLA_NODE_KEY,		/* data */
- 
- 	__TIPC_NLA_NODE_MAX,
- 	TIPC_NLA_NODE_MAX = __TIPC_NLA_NODE_MAX - 1
--- 
-2.26.2
-
diff --git a/SOURCES/0024-iproute_lwtunnel-add-options-support-for-geneve-meta.patch b/SOURCES/0024-iproute_lwtunnel-add-options-support-for-geneve-meta.patch
deleted file mode 100644
index e093682..0000000
--- a/SOURCES/0024-iproute_lwtunnel-add-options-support-for-geneve-meta.patch
+++ /dev/null
@@ -1,297 +0,0 @@
-From c6f909bd0f40c58f39f857e1c57638cb41241fa2 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 4 Jun 2020 21:43:01 +0200
-Subject: [PATCH] iproute_lwtunnel: add options support for geneve metadata
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1830485
-Upstream Status: unknown commit ca7614d4c6f45
-
-commit ca7614d4c6f456187d831a8202bb4a8559a72f8b
-Author: Xin Long <lucien.xin@gmail.com>
-Date:   Mon Apr 27 18:27:45 2020 +0800
-
-    iproute_lwtunnel: add options support for geneve metadata
-
-    This patch is to add LWTUNNEL_IP(6)_OPTS and LWTUNNEL_IP_OPTS_GENEVE's
-    parse and print to implement geneve options support in iproute_lwtunnel.
-
-    Options are expressed as class:type:data and multiple options may be
-    listed using a comma delimiter, class and type are numbers and data
-    is a hex string.
-
-    With this patch, users can add and dump geneve options like:
-
-      # ip netns add a
-      # ip netns add b
-      # ip -n a link add eth0 type veth peer name eth0 netns b
-      # ip -n a link set eth0 up; ip -n b link set eth0 up
-      # ip -n a addr add 10.1.0.1/24 dev eth0
-      # ip -n b addr add 10.1.0.2/24 dev eth0
-      # ip -n b link add geneve1 type geneve id 1 remote 10.1.0.1 ttl 64
-      # ip -n b addr add 1.1.1.1/24 dev geneve1
-      # ip -n b link set geneve1 up
-      # ip -n b route add 2.1.1.0/24 dev geneve1
-      # ip -n a link add geneve1 type geneve external
-      # ip -n a addr add 2.1.1.1/24 dev geneve1
-      # ip -n a link set geneve1 up
-      # ip -n a route add 1.1.1.0/24 encap ip id 1 geneve_opts \
-        1:1:1212121234567890,1:1:1212121234567890,1:1:1212121234567890 \
-        dst 10.1.0.2 dev geneve1
-      # ip -n a route show
-      # ip netns exec a ping 1.1.1.1 -c 1
-
-       1.1.1.0/24  encap ip id 1 src 0.0.0.0 dst 10.1.0.2 ttl 0 tos 0
-         geneve_opts 1:1:1212121234567890,1:1:1212121234567890 ...
-
-       PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
-       64 bytes from 1.1.1.1: icmp_seq=1 ttl=64 time=0.079 ms
-
-    v1->v2:
-      - improve the changelog.
-      - use PRINT_ANY to support dumping with json format.
-    v2->v3:
-      - implement proper JSON array for opts instead of just bunch of strings.
-    v3->v4:
-      - keep the same format between input and output, json and non json.
-      - print class and type as uint and print data as hex string.
-
-    Signed-off-by: Xin Long <lucien.xin@gmail.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- ip/iproute_lwtunnel.c | 174 +++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 172 insertions(+), 2 deletions(-)
-
-diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
-index 60f34a32a6e5b..76d906c47c44f 100644
---- a/ip/iproute_lwtunnel.c
-+++ b/ip/iproute_lwtunnel.c
-@@ -291,6 +291,54 @@ static void print_encap_mpls(FILE *fp, struct rtattr *encap)
- 			rta_getattr_u8(tb[MPLS_IPTUNNEL_TTL]));
- }
- 
-+static void lwtunnel_print_geneve_opts(struct rtattr *attr)
-+{
-+	struct rtattr *tb[LWTUNNEL_IP_OPT_GENEVE_MAX + 1];
-+	struct rtattr *i = RTA_DATA(attr);
-+	int rem = RTA_PAYLOAD(attr);
-+	char *name = "geneve_opts";
-+	int data_len, offset = 0;
-+	char data[rem * 2 + 1];
-+	__u16 class;
-+	__u8 type;
-+
-+	print_nl();
-+	print_string(PRINT_FP, name, "\t%s ", name);
-+	open_json_array(PRINT_JSON, name);
-+
-+	while (rem) {
-+		parse_rtattr(tb, LWTUNNEL_IP_OPT_GENEVE_MAX, i, rem);
-+		class = rta_getattr_be16(tb[LWTUNNEL_IP_OPT_GENEVE_CLASS]);
-+		type = rta_getattr_u8(tb[LWTUNNEL_IP_OPT_GENEVE_TYPE]);
-+		data_len = RTA_PAYLOAD(tb[LWTUNNEL_IP_OPT_GENEVE_DATA]);
-+		hexstring_n2a(RTA_DATA(tb[LWTUNNEL_IP_OPT_GENEVE_DATA]),
-+			      data_len, data, sizeof(data));
-+		offset += data_len + 20;
-+		rem -= data_len + 20;
-+		i = RTA_DATA(attr) + offset;
-+
-+		open_json_object(NULL);
-+		print_uint(PRINT_ANY, "class", "%u", class);
-+		print_uint(PRINT_ANY, "type", ":%u", type);
-+		if (rem)
-+			print_string(PRINT_ANY, "data", ":%s,", data);
-+		else
-+			print_string(PRINT_ANY, "data", ":%s ", data);
-+		close_json_object();
-+	}
-+
-+	close_json_array(PRINT_JSON, name);
-+}
-+
-+static void lwtunnel_print_opts(struct rtattr *attr)
-+{
-+	struct rtattr *tb_opt[LWTUNNEL_IP_OPTS_MAX + 1];
-+
-+	parse_rtattr_nested(tb_opt, LWTUNNEL_IP_OPTS_MAX, attr);
-+	if (tb_opt[LWTUNNEL_IP_OPTS_GENEVE])
-+		lwtunnel_print_geneve_opts(tb_opt[LWTUNNEL_IP_OPTS_GENEVE]);
-+}
-+
- static void print_encap_ip(FILE *fp, struct rtattr *encap)
- {
- 	struct rtattr *tb[LWTUNNEL_IP_MAX+1];
-@@ -329,6 +377,9 @@ static void print_encap_ip(FILE *fp, struct rtattr *encap)
- 		if (flags & TUNNEL_SEQ)
- 			print_bool(PRINT_ANY, "seq", "seq ", true);
- 	}
-+
-+	if (tb[LWTUNNEL_IP_OPTS])
-+		lwtunnel_print_opts(tb[LWTUNNEL_IP_OPTS]);
- }
- 
- static void print_encap_ila(FILE *fp, struct rtattr *encap)
-@@ -401,6 +452,9 @@ static void print_encap_ip6(FILE *fp, struct rtattr *encap)
- 		if (flags & TUNNEL_SEQ)
- 			print_bool(PRINT_ANY, "seq", "seq ", true);
- 	}
-+
-+	if (tb[LWTUNNEL_IP6_OPTS])
-+		lwtunnel_print_opts(tb[LWTUNNEL_IP6_OPTS]);
- }
- 
- static void print_encap_bpf(FILE *fp, struct rtattr *encap)
-@@ -795,11 +849,97 @@ static int parse_encap_mpls(struct rtattr *rta, size_t len,
- 	return 0;
- }
- 
-+static int lwtunnel_parse_geneve_opt(char *str, size_t len, struct rtattr *rta)
-+{
-+	struct rtattr *nest;
-+	char *token;
-+	int i, err;
-+
-+	nest = rta_nest(rta, len, LWTUNNEL_IP_OPTS_GENEVE | NLA_F_NESTED);
-+	i = 1;
-+	token = strsep(&str, ":");
-+	while (token) {
-+		switch (i) {
-+		case LWTUNNEL_IP_OPT_GENEVE_CLASS:
-+		{
-+			__be16 opt_class;
-+
-+			if (!strlen(token))
-+				break;
-+			err = get_be16(&opt_class, token, 0);
-+			if (err)
-+				return err;
-+
-+			rta_addattr16(rta, len, i, opt_class);
-+			break;
-+		}
-+		case LWTUNNEL_IP_OPT_GENEVE_TYPE:
-+		{
-+			__u8 opt_type;
-+
-+			if (!strlen(token))
-+				break;
-+			err = get_u8(&opt_type, token, 0);
-+			if (err)
-+				return err;
-+
-+			rta_addattr8(rta, len, i, opt_type);
-+			break;
-+		}
-+		case LWTUNNEL_IP_OPT_GENEVE_DATA:
-+		{
-+			size_t token_len = strlen(token);
-+			__u8 *opts;
-+
-+			if (!token_len)
-+				break;
-+			opts = malloc(token_len / 2);
-+			if (!opts)
-+				return -1;
-+			if (hex2mem(token, opts, token_len / 2) < 0) {
-+				free(opts);
-+				return -1;
-+			}
-+			rta_addattr_l(rta, len, i, opts, token_len / 2);
-+			free(opts);
-+
-+			break;
-+		}
-+		default:
-+			fprintf(stderr, "Unknown \"geneve_opts\" type\n");
-+			return -1;
-+		}
-+
-+		token = strsep(&str, ":");
-+		i++;
-+	}
-+	rta_nest_end(rta, nest);
-+
-+	return 0;
-+}
-+
-+static int lwtunnel_parse_geneve_opts(char *str, size_t len, struct rtattr *rta)
-+{
-+	char *token;
-+	int err;
-+
-+	token = strsep(&str, ",");
-+	while (token) {
-+		err = lwtunnel_parse_geneve_opt(token, len, rta);
-+		if (err)
-+			return err;
-+
-+		token = strsep(&str, ",");
-+	}
-+
-+	return 0;
-+}
-+
- static int parse_encap_ip(struct rtattr *rta, size_t len,
- 			  int *argcp, char ***argvp)
- {
- 	int id_ok = 0, dst_ok = 0, src_ok = 0, tos_ok = 0, ttl_ok = 0;
--	int key_ok = 0, csum_ok = 0, seq_ok = 0;
-+	int key_ok = 0, csum_ok = 0, seq_ok = 0, opts_ok = 0;
- 	char **argv = *argvp;
- 	int argc = *argcp;
- 	int ret = 0;
-@@ -851,6 +991,21 @@ static int parse_encap_ip(struct rtattr *rta, size_t len,
- 			if (get_u8(&ttl, *argv, 0))
- 				invarg("\"ttl\" value is invalid\n", *argv);
- 			ret = rta_addattr8(rta, len, LWTUNNEL_IP_TTL, ttl);
-+		} else if (strcmp(*argv, "geneve_opts") == 0) {
-+			struct rtattr *nest;
-+
-+			if (opts_ok++)
-+				duparg2("opts", *argv);
-+
-+			NEXT_ARG();
-+
-+			nest = rta_nest(rta, len,
-+					LWTUNNEL_IP_OPTS | NLA_F_NESTED);
-+			ret = lwtunnel_parse_geneve_opts(*argv, len, rta);
-+			if (ret)
-+				invarg("\"geneve_opts\" value is invalid\n",
-+				       *argv);
-+			rta_nest_end(rta, nest);
- 		} else if (strcmp(*argv, "key") == 0) {
- 			if (key_ok++)
- 				duparg2("key", *argv);
-@@ -966,7 +1121,7 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len,
- 			   int *argcp, char ***argvp)
- {
- 	int id_ok = 0, dst_ok = 0, src_ok = 0, tos_ok = 0, ttl_ok = 0;
--	int key_ok = 0, csum_ok = 0, seq_ok = 0;
-+	int key_ok = 0, csum_ok = 0, seq_ok = 0, opts_ok = 0;
- 	char **argv = *argvp;
- 	int argc = *argcp;
- 	int ret = 0;
-@@ -1020,6 +1175,21 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len,
- 				       *argv);
- 			ret = rta_addattr8(rta, len, LWTUNNEL_IP6_HOPLIMIT,
- 					   hoplimit);
-+		} else if (strcmp(*argv, "geneve_opts") == 0) {
-+			struct rtattr *nest;
-+
-+			if (opts_ok++)
-+				duparg2("opts", *argv);
-+
-+			NEXT_ARG();
-+
-+			nest = rta_nest(rta, len,
-+					LWTUNNEL_IP_OPTS | NLA_F_NESTED);
-+			ret = lwtunnel_parse_geneve_opts(*argv, len, rta);
-+			if (ret)
-+				invarg("\"geneve_opts\" value is invalid\n",
-+				       *argv);
-+			rta_nest_end(rta, nest);
- 		} else if (strcmp(*argv, "key") == 0) {
- 			if (key_ok++)
- 				duparg2("key", *argv);
--- 
-2.26.2
-
diff --git a/SOURCES/0025-iproute_lwtunnel-add-options-support-for-vxlan-metad.patch b/SOURCES/0025-iproute_lwtunnel-add-options-support-for-vxlan-metad.patch
deleted file mode 100644
index cc25df9..0000000
--- a/SOURCES/0025-iproute_lwtunnel-add-options-support-for-vxlan-metad.patch
+++ /dev/null
@@ -1,175 +0,0 @@
-From 873511fb86756c40631f80963356179627d69d49 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 4 Jun 2020 21:43:01 +0200
-Subject: [PATCH] iproute_lwtunnel: add options support for vxlan metadata
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1830485
-Upstream Status: unknown commit b1bc0f3892222
-
-commit b1bc0f38922220b379ed39552a5e2a7cf9dccd92
-Author: Xin Long <lucien.xin@gmail.com>
-Date:   Mon Apr 27 18:27:46 2020 +0800
-
-    iproute_lwtunnel: add options support for vxlan metadata
-
-    This patch is to add LWTUNNEL_IP_OPTS_VXLAN's parse and print to implement
-    vxlan options support in iproute_lwtunnel.
-
-    Option is expressed a number for gbp only, and vxlan doesn't support
-    multiple options.
-
-    With this patch, users can add and dump vxlan options like:
-
-      # ip netns add a
-      # ip netns add b
-      # ip -n a link add eth0 type veth peer name eth0 netns b
-      # ip -n a link set eth0 up
-      # ip -n b link set eth0 up
-      # ip -n a addr add 10.1.0.1/24 dev eth0
-      # ip -n b addr add 10.1.0.2/24 dev eth0
-      # ip -n b link add vxlan1 type vxlan id 1 local 10.1.0.2 \
-        remote 10.1.0.1 dev eth0 ttl 64 gbp
-      # ip -n b addr add 1.1.1.1/24 dev vxlan1
-      # ip -n b link set vxlan1 up
-      # ip -n b route add 2.1.1.0/24 dev vxlan1
-      # ip -n a link add vxlan1 type vxlan local 10.1.0.1 dev eth0 ttl 64 \
-        gbp external
-      # ip -n a addr add 2.1.1.1/24 dev vxlan1
-      # ip -n a link set vxlan1 up
-      # ip -n a route add 1.1.1.0/24 encap ip id 1 \
-        vxlan_opts 1110 dst 10.1.0.2 dev vxlan1
-      # ip -n a route show
-      # ip netns exec a ping 1.1.1.1 -c 1
-
-       1.1.1.0/24  encap ip id 1 src 0.0.0.0 dst 10.1.0.2 ttl 0 tos 0
-         vxlan_opts 1110 dev vxlan1 scope link
-
-       PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
-       64 bytes from 1.1.1.1: icmp_seq=1 ttl=64 time=0.111 ms
-
-    v1->v2:
-      - improve the changelog.
-      - get_u32 with base = 0 for gbp.
-      - use PRINT_ANY to support dumping with json format.
-    v2->v3:
-      - implement proper JSON array for opts.
-    v3->v4:
-      - keep the same format between input and output, json and non json.
-      - print gbp as uint.
-
-    Signed-off-by: Xin Long <lucien.xin@gmail.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- ip/iproute_lwtunnel.c | 68 +++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 68 insertions(+)
-
-diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
-index 76d906c47c44f..17514dcad9219 100644
---- a/ip/iproute_lwtunnel.c
-+++ b/ip/iproute_lwtunnel.c
-@@ -330,6 +330,26 @@ static void lwtunnel_print_geneve_opts(struct rtattr *attr)
- 	close_json_array(PRINT_JSON, name);
- }
- 
-+static void lwtunnel_print_vxlan_opts(struct rtattr *attr)
-+{
-+	struct rtattr *tb[LWTUNNEL_IP_OPT_VXLAN_MAX + 1];
-+	struct rtattr *i = RTA_DATA(attr);
-+	int rem = RTA_PAYLOAD(attr);
-+	char *name = "vxlan_opts";
-+	__u32 gbp;
-+
-+	parse_rtattr(tb, LWTUNNEL_IP_OPT_VXLAN_MAX, i, rem);
-+	gbp = rta_getattr_u32(tb[LWTUNNEL_IP_OPT_VXLAN_GBP]);
-+
-+	print_nl();
-+	print_string(PRINT_FP, name, "\t%s ", name);
-+	open_json_array(PRINT_JSON, name);
-+	open_json_object(NULL);
-+	print_uint(PRINT_ANY, "gbp", "%u ", gbp);
-+	close_json_object();
-+	close_json_array(PRINT_JSON, name);
-+}
-+
- static void lwtunnel_print_opts(struct rtattr *attr)
- {
- 	struct rtattr *tb_opt[LWTUNNEL_IP_OPTS_MAX + 1];
-@@ -337,6 +357,8 @@ static void lwtunnel_print_opts(struct rtattr *attr)
- 	parse_rtattr_nested(tb_opt, LWTUNNEL_IP_OPTS_MAX, attr);
- 	if (tb_opt[LWTUNNEL_IP_OPTS_GENEVE])
- 		lwtunnel_print_geneve_opts(tb_opt[LWTUNNEL_IP_OPTS_GENEVE]);
-+	else if (tb_opt[LWTUNNEL_IP_OPTS_VXLAN])
-+		lwtunnel_print_vxlan_opts(tb_opt[LWTUNNEL_IP_OPTS_VXLAN]);
- }
- 
- static void print_encap_ip(FILE *fp, struct rtattr *encap)
-@@ -935,6 +957,22 @@ static int lwtunnel_parse_geneve_opts(char *str, size_t len, struct rtattr *rta)
- 	return 0;
- }
- 
-+static int lwtunnel_parse_vxlan_opts(char *str, size_t len, struct rtattr *rta)
-+{
-+	struct rtattr *nest;
-+	__u32 gbp;
-+	int err;
-+
-+	nest = rta_nest(rta, len, LWTUNNEL_IP_OPTS_VXLAN | NLA_F_NESTED);
-+	err = get_u32(&gbp, str, 0);
-+	if (err)
-+		return err;
-+	rta_addattr32(rta, len, LWTUNNEL_IP_OPT_VXLAN_GBP, gbp);
-+
-+	rta_nest_end(rta, nest);
-+	return 0;
-+}
-+
- static int parse_encap_ip(struct rtattr *rta, size_t len,
- 			  int *argcp, char ***argvp)
- {
-@@ -1006,6 +1044,21 @@ static int parse_encap_ip(struct rtattr *rta, size_t len,
- 				invarg("\"geneve_opts\" value is invalid\n",
- 				       *argv);
- 			rta_nest_end(rta, nest);
-+		} else if (strcmp(*argv, "vxlan_opts") == 0) {
-+			struct rtattr *nest;
-+
-+			if (opts_ok++)
-+				duparg2("opts", *argv);
-+
-+			NEXT_ARG();
-+
-+			nest = rta_nest(rta, len,
-+					LWTUNNEL_IP_OPTS | NLA_F_NESTED);
-+			ret = lwtunnel_parse_vxlan_opts(*argv, len, rta);
-+			if (ret)
-+				invarg("\"vxlan_opts\" value is invalid\n",
-+				       *argv);
-+			rta_nest_end(rta, nest);
- 		} else if (strcmp(*argv, "key") == 0) {
- 			if (key_ok++)
- 				duparg2("key", *argv);
-@@ -1190,6 +1243,21 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len,
- 				invarg("\"geneve_opts\" value is invalid\n",
- 				       *argv);
- 			rta_nest_end(rta, nest);
-+		} else if (strcmp(*argv, "vxlan_opts") == 0) {
-+			struct rtattr *nest;
-+
-+			if (opts_ok++)
-+				duparg2("opts", *argv);
-+
-+			NEXT_ARG();
-+
-+			nest = rta_nest(rta, len,
-+					LWTUNNEL_IP_OPTS | NLA_F_NESTED);
-+			ret = lwtunnel_parse_vxlan_opts(*argv, len, rta);
-+			if (ret)
-+				invarg("\"vxlan_opts\" value is invalid\n",
-+				       *argv);
-+			rta_nest_end(rta, nest);
- 		} else if (strcmp(*argv, "key") == 0) {
- 			if (key_ok++)
- 				duparg2("key", *argv);
--- 
-2.26.2
-
diff --git a/SOURCES/0026-iproute_lwtunnel-add-options-support-for-erspan-meta.patch b/SOURCES/0026-iproute_lwtunnel-add-options-support-for-erspan-meta.patch
deleted file mode 100644
index d9f0bb6..0000000
--- a/SOURCES/0026-iproute_lwtunnel-add-options-support-for-erspan-meta.patch
+++ /dev/null
@@ -1,246 +0,0 @@
-From 3628115b53f7b693f623638fb5ec71bc292a3a00 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 4 Jun 2020 21:43:01 +0200
-Subject: [PATCH] iproute_lwtunnel: add options support for erspan metadata
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1830485
-Upstream Status: unknown commit 39fa047938fbe
-
-commit 39fa047938fbef6cd08687b0daa4d86afbfdc61c
-Author: Xin Long <lucien.xin@gmail.com>
-Date:   Mon Apr 27 18:27:47 2020 +0800
-
-    iproute_lwtunnel: add options support for erspan metadata
-
-    This patch is to add LWTUNNEL_IP_OPTS_ERSPAN's parse and print to implement
-    erspan options support in iproute_lwtunnel.
-
-    Option is expressed as version:index:dir:hwid, dir and hwid will be parsed
-    when version is 2, while index will be parsed when version is 1. All of
-    these are numbers. erspan doesn't support multiple options.
-
-    With this patch, users can add and dump erspan options like:
-
-      # ip netns add a
-      # ip netns add b
-      # ip -n a link add eth0 type veth peer name eth0 netns b
-      # ip -n a link set eth0 up
-      # ip -n b link set eth0 up
-      # ip -n a addr add 10.1.0.1/24 dev eth0
-      # ip -n b addr add 10.1.0.2/24 dev eth0
-      # ip -n b link add erspan1 type erspan key 1 seq erspan 123 \
-        local 10.1.0.2 remote 10.1.0.1
-      # ip -n b addr add 1.1.1.1/24 dev erspan1
-      # ip -n b link set erspan1 up
-      # ip -n b route add 2.1.1.0/24 dev erspan1
-      # ip -n a link add erspan1 type erspan key 1 seq local 10.1.0.1 external
-      # ip -n a addr add 2.1.1.1/24 dev erspan1
-      # ip -n a link set erspan1 up
-      # ip -n a route add 1.1.1.0/24 encap ip id 1 \
-        erspan_opts 2:123:1:2 dst 10.1.0.2 dev erspan1
-      # ip -n a route show
-      # ip netns exec a ping 1.1.1.1 -c 1
-
-       1.1.1.0/24  encap ip id 1 src 0.0.0.0 dst 10.1.0.2 ttl 0 tos 0
-         erspan_opts 2:0:1:2 dev erspan1 scope link
-
-       PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
-       64 bytes from 1.1.1.1: icmp_seq=1 ttl=64 time=0.124 ms
-
-    v1->v2:
-      - improve the changelog.
-      - use PRINT_ANY to support dumping with json format.
-    v2->v3:
-      - implement proper JSON object for opts instead of just bunch of strings.
-    v3->v4:
-      - keep the same format between input and output, json and non json.
-      - print version, index, dir and hwid as uint.
-
-    Signed-off-by: Xin Long <lucien.xin@gmail.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- ip/iproute_lwtunnel.c | 140 ++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 140 insertions(+)
-
-diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
-index 17514dcad9219..7e145768c111f 100644
---- a/ip/iproute_lwtunnel.c
-+++ b/ip/iproute_lwtunnel.c
-@@ -350,6 +350,38 @@ static void lwtunnel_print_vxlan_opts(struct rtattr *attr)
- 	close_json_array(PRINT_JSON, name);
- }
- 
-+static void lwtunnel_print_erspan_opts(struct rtattr *attr)
-+{
-+	struct rtattr *tb[LWTUNNEL_IP_OPT_ERSPAN_MAX + 1];
-+	struct rtattr *i = RTA_DATA(attr);
-+	char *name = "erspan_opts";
-+	__u8 ver, hwid, dir;
-+	__u32 idx;
-+
-+	parse_rtattr(tb, LWTUNNEL_IP_OPT_ERSPAN_MAX, i, RTA_PAYLOAD(attr));
-+	ver = rta_getattr_u8(tb[LWTUNNEL_IP_OPT_ERSPAN_VER]);
-+	if (ver == 1) {
-+		idx = rta_getattr_be32(tb[LWTUNNEL_IP_OPT_ERSPAN_INDEX]);
-+		dir = 0;
-+		hwid = 0;
-+	} else {
-+		idx = 0;
-+		dir = rta_getattr_u8(tb[LWTUNNEL_IP_OPT_ERSPAN_DIR]);
-+		hwid = rta_getattr_u8(tb[LWTUNNEL_IP_OPT_ERSPAN_HWID]);
-+	}
-+
-+	print_nl();
-+	print_string(PRINT_FP, name, "\t%s ", name);
-+	open_json_array(PRINT_JSON, name);
-+	open_json_object(NULL);
-+	print_uint(PRINT_ANY, "ver", "%u", ver);
-+	print_uint(PRINT_ANY, "index", ":%u", idx);
-+	print_uint(PRINT_ANY, "dir", ":%u", dir);
-+	print_uint(PRINT_ANY, "hwid", ":%u ", hwid);
-+	close_json_object();
-+	close_json_array(PRINT_JSON, name);
-+}
-+
- static void lwtunnel_print_opts(struct rtattr *attr)
- {
- 	struct rtattr *tb_opt[LWTUNNEL_IP_OPTS_MAX + 1];
-@@ -359,6 +391,8 @@ static void lwtunnel_print_opts(struct rtattr *attr)
- 		lwtunnel_print_geneve_opts(tb_opt[LWTUNNEL_IP_OPTS_GENEVE]);
- 	else if (tb_opt[LWTUNNEL_IP_OPTS_VXLAN])
- 		lwtunnel_print_vxlan_opts(tb_opt[LWTUNNEL_IP_OPTS_VXLAN]);
-+	else if (tb_opt[LWTUNNEL_IP_OPTS_ERSPAN])
-+		lwtunnel_print_erspan_opts(tb_opt[LWTUNNEL_IP_OPTS_ERSPAN]);
- }
- 
- static void print_encap_ip(FILE *fp, struct rtattr *encap)
-@@ -973,6 +1007,82 @@ static int lwtunnel_parse_vxlan_opts(char *str, size_t len, struct rtattr *rta)
- 	return 0;
- }
- 
-+static int lwtunnel_parse_erspan_opts(char *str, size_t len, struct rtattr *rta)
-+{
-+	struct rtattr *nest;
-+	char *token;
-+	int i, err;
-+
-+	nest = rta_nest(rta, len, LWTUNNEL_IP_OPTS_ERSPAN | NLA_F_NESTED);
-+	i = 1;
-+	token = strsep(&str, ":");
-+	while (token) {
-+		switch (i) {
-+		case LWTUNNEL_IP_OPT_ERSPAN_VER:
-+		{
-+			__u8 opt_type;
-+
-+			if (!strlen(token))
-+				break;
-+			err = get_u8(&opt_type, token, 0);
-+			if (err)
-+				return err;
-+
-+			rta_addattr8(rta, len, i, opt_type);
-+			break;
-+		}
-+		case LWTUNNEL_IP_OPT_ERSPAN_INDEX:
-+		{
-+			__be32 opt_class;
-+
-+			if (!strlen(token))
-+				break;
-+			err = get_be32(&opt_class, token, 0);
-+			if (err)
-+				return err;
-+
-+			rta_addattr32(rta, len, i, opt_class);
-+			break;
-+		}
-+		case LWTUNNEL_IP_OPT_ERSPAN_DIR:
-+		{
-+			__u8 opt_type;
-+
-+			if (!strlen(token))
-+				break;
-+			err = get_u8(&opt_type, token, 0);
-+			if (err)
-+				return err;
-+
-+			rta_addattr8(rta, len, i, opt_type);
-+			break;
-+		}
-+		case LWTUNNEL_IP_OPT_ERSPAN_HWID:
-+		{
-+			__u8 opt_type;
-+
-+			if (!strlen(token))
-+				break;
-+			err = get_u8(&opt_type, token, 0);
-+			if (err)
-+				return err;
-+
-+			rta_addattr8(rta, len, i, opt_type);
-+			break;
-+		}
-+		default:
-+			fprintf(stderr, "Unknown \"geneve_opts\" type\n");
-+			return -1;
-+		}
-+
-+		token = strsep(&str, ":");
-+		i++;
-+	}
-+
-+	rta_nest_end(rta, nest);
-+	return 0;
-+}
-+
- static int parse_encap_ip(struct rtattr *rta, size_t len,
- 			  int *argcp, char ***argvp)
- {
-@@ -1059,6 +1169,21 @@ static int parse_encap_ip(struct rtattr *rta, size_t len,
- 				invarg("\"vxlan_opts\" value is invalid\n",
- 				       *argv);
- 			rta_nest_end(rta, nest);
-+		} else if (strcmp(*argv, "erspan_opts") == 0) {
-+			struct rtattr *nest;
-+
-+			if (opts_ok++)
-+				duparg2("opts", *argv);
-+
-+			NEXT_ARG();
-+
-+			nest = rta_nest(rta, len,
-+					LWTUNNEL_IP_OPTS | NLA_F_NESTED);
-+			ret = lwtunnel_parse_erspan_opts(*argv, len, rta);
-+			if (ret)
-+				invarg("\"erspan_opts\" value is invalid\n",
-+				       *argv);
-+			rta_nest_end(rta, nest);
- 		} else if (strcmp(*argv, "key") == 0) {
- 			if (key_ok++)
- 				duparg2("key", *argv);
-@@ -1258,6 +1383,21 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len,
- 				invarg("\"vxlan_opts\" value is invalid\n",
- 				       *argv);
- 			rta_nest_end(rta, nest);
-+		} else if (strcmp(*argv, "erspan_opts") == 0) {
-+			struct rtattr *nest;
-+
-+			if (opts_ok++)
-+				duparg2("opts", *argv);
-+
-+			NEXT_ARG();
-+
-+			nest = rta_nest(rta, len,
-+					LWTUNNEL_IP_OPTS | NLA_F_NESTED);
-+			ret = lwtunnel_parse_erspan_opts(*argv, len, rta);
-+			if (ret)
-+				invarg("\"erspan_opts\" value is invalid\n",
-+				       *argv);
-+			rta_nest_end(rta, nest);
- 		} else if (strcmp(*argv, "key") == 0) {
- 			if (key_ok++)
- 				duparg2("key", *argv);
--- 
-2.26.2
-
diff --git a/SOURCES/0027-tc-m_tunnel_key-add-options-support-for-vxlan.patch b/SOURCES/0027-tc-m_tunnel_key-add-options-support-for-vxlan.patch
deleted file mode 100644
index b86d0b3..0000000
--- a/SOURCES/0027-tc-m_tunnel_key-add-options-support-for-vxlan.patch
+++ /dev/null
@@ -1,258 +0,0 @@
-From f970b592af7421ce932a788a6a14161c351d75e0 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 4 Jun 2020 21:43:01 +0200
-Subject: [PATCH] tc: m_tunnel_key: add options support for vxlan
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1830485
-Upstream Status: unknown commit f72c3ad00f3b7
-Conflicts: context change due to missing commit 7b0d424abef16
-           ("tc: do not output newline in oneline mode")
-
-commit f72c3ad00f3b7869e90840d0098a83cb88224892
-Author: Xin Long <lucien.xin@gmail.com>
-Date:   Mon Apr 27 18:27:48 2020 +0800
-
-    tc: m_tunnel_key: add options support for vxlan
-
-    This patch is to add TCA_TUNNEL_KEY_ENC_OPTS_VXLAN's parse and
-    print to implement vxlan options support in m_tunnel_key, like
-    Commit 6217917a3826 ("tc: m_tunnel_key: Add tunnel option support
-    to act_tunnel_key") for geneve options support.
-
-    Option is expressed a 32bit number for gbp only, and vxlan
-    doesn't support multiple options.
-
-    With this patch, users can add and dump vxlan options like:
-
-      # ip link add name vxlan1 type vxlan dstport 0 external
-      # tc qdisc add dev eth0 ingress
-      # tc filter add dev eth0 protocol ip parent ffff: \
-          flower indev eth0 \
-            ip_proto udp \
-            action tunnel_key \
-              set src_ip 10.0.99.192 \
-              dst_ip 10.0.99.193 \
-              dst_port 6081 \
-              id 11 \
-              vxlan_opts 65793 \
-          action mirred egress redirect dev vxlan1
-      # tc -s filter show dev eth0 parent ffff:
-
-         filter protocol ip pref 49152 flower chain 0 handle 0x1
-           indev eth0
-           eth_type ipv4
-           ip_proto udp
-           not_in_hw
-             action order 1: tunnel_key  set
-             src_ip 10.0.99.192
-             dst_ip 10.0.99.193
-             key_id 11
-             dst_port 6081
-             vxlan_opts 65793
-             ...
-
-    v1->v2:
-      - get_u32 with base = 0 for gbp.
-      - use to print_unint("0x%x") to print gbp.
-    v2->v3:
-      - implement proper JSON array for opts.
-    v3->v4:
-      - keep the same format between input and output, json and non json.
-      - print gbp as uint.
-
-    Signed-off-by: Xin Long <lucien.xin@gmail.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- man/man8/tc-tunnel_key.8 | 10 ++++-
- tc/m_tunnel_key.c        | 85 +++++++++++++++++++++++++++++++++++-----
- 2 files changed, 85 insertions(+), 10 deletions(-)
-
-diff --git a/man/man8/tc-tunnel_key.8 b/man/man8/tc-tunnel_key.8
-index 2145eb62e70e2..c208e2c82a181 100644
---- a/man/man8/tc-tunnel_key.8
-+++ b/man/man8/tc-tunnel_key.8
-@@ -66,8 +66,10 @@ options.
- .B id
- ,
- .B dst_port
--and
-+,
- .B geneve_opts
-+and
-+.B vxlan_opts
- are optional.
- .RS
- .TP
-@@ -91,6 +93,12 @@ is specified in the form CLASS:TYPE:DATA, where CLASS is represented as a
- variable length hexadecimal value. Additionally multiple options may be
- listed using a comma delimiter.
- .TP
-+.B vxlan_opts
-+Vxlan metatdata options.
-+.B vxlan_opts
-+is specified in the form GBP, as a 32bit number. Multiple options is not
-+supported.
-+.TP
- .B tos
- Outer header TOS
- .TP
-diff --git a/tc/m_tunnel_key.c b/tc/m_tunnel_key.c
-index 4e65e444776a2..76391d6c85fb2 100644
---- a/tc/m_tunnel_key.c
-+++ b/tc/m_tunnel_key.c
-@@ -29,7 +29,7 @@ static void explain(void)
- 		"src_ip <IP> (mandatory)\n"
- 		"dst_ip <IP> (mandatory)\n"
- 		"dst_port <UDP_PORT>\n"
--		"geneve_opts <OPTIONS>\n"
-+		"geneve_opts | vxlan_opts <OPTIONS>\n"
- 		"csum | nocsum (default is \"csum\")\n");
- }
- 
-@@ -112,6 +112,21 @@ static int tunnel_key_parse_u8(char *str, int base, int type,
- 	return 0;
- }
- 
-+static int tunnel_key_parse_u32(char *str, int base, int type,
-+				struct nlmsghdr *n)
-+{
-+	__u32 value;
-+	int ret;
-+
-+	ret = get_u32(&value, str, base);
-+	if (ret)
-+		return ret;
-+
-+	addattr32(n, MAX_MSG, type, value);
-+
-+	return 0;
-+}
-+
- static int tunnel_key_parse_geneve_opt(char *str, struct nlmsghdr *n)
- {
- 	char *token, *saveptr = NULL;
-@@ -190,6 +205,27 @@ static int tunnel_key_parse_geneve_opts(char *str, struct nlmsghdr *n)
- 	return 0;
- }
- 
-+static int tunnel_key_parse_vxlan_opt(char *str, struct nlmsghdr *n)
-+{
-+	struct rtattr *encap, *nest;
-+	int ret;
-+
-+	encap = addattr_nest(n, MAX_MSG,
-+			     TCA_TUNNEL_KEY_ENC_OPTS | NLA_F_NESTED);
-+	nest = addattr_nest(n, MAX_MSG,
-+			    TCA_TUNNEL_KEY_ENC_OPTS_VXLAN | NLA_F_NESTED);
-+
-+	ret = tunnel_key_parse_u32(str, 0,
-+				   TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP, n);
-+	if (ret)
-+		return ret;
-+
-+	addattr_nest_end(n, nest);
-+	addattr_nest_end(n, encap);
-+
-+	return 0;
-+}
-+
- static int tunnel_key_parse_tos_ttl(char *str, int type, struct nlmsghdr *n)
- {
- 	int ret;
-@@ -287,6 +323,13 @@ static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p,
- 				fprintf(stderr, "Illegal \"geneve_opts\"\n");
- 				return -1;
- 			}
-+		} else if (matches(*argv, "vxlan_opts") == 0) {
-+			NEXT_ARG();
-+
-+			if (tunnel_key_parse_vxlan_opt(*argv, n)) {
-+				fprintf(stderr, "Illegal \"vxlan_opts\"\n");
-+				return -1;
-+			}
- 		} else if (matches(*argv, "tos") == 0) {
- 			NEXT_ARG();
- 			ret = tunnel_key_parse_tos_ttl(*argv,
-@@ -406,13 +449,13 @@ static void tunnel_key_print_flag(FILE *f, const char *name_on,
- 		     rta_getattr_u8(attr) ? name_on : name_off);
- }
- 
--static void tunnel_key_print_geneve_options(const char *name,
--					    struct rtattr *attr)
-+static void tunnel_key_print_geneve_options(struct rtattr *attr)
- {
- 	struct rtattr *tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX + 1];
- 	struct rtattr *i = RTA_DATA(attr);
- 	int ii, data_len = 0, offset = 0;
- 	int rem = RTA_PAYLOAD(attr);
-+	char *name = "geneve_opts";
- 	char strbuf[rem * 2 + 1];
- 	char data[rem * 2 + 1];
- 	uint8_t data_r[rem];
-@@ -420,7 +463,8 @@ static void tunnel_key_print_geneve_options(const char *name,
- 	uint8_t type;
- 
- 	open_json_array(PRINT_JSON, name);
--	print_string(PRINT_FP, name, "\n\t%s ", "geneve_opt");
-+	print_nl();
-+	print_string(PRINT_FP, name, "\t%s ", name);
- 
- 	while (rem) {
- 		parse_rtattr(tb, TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX, i, rem);
-@@ -453,7 +497,27 @@ static void tunnel_key_print_geneve_options(const char *name,
- 	close_json_array(PRINT_JSON, name);
- }
- 
--static void tunnel_key_print_key_opt(const char *name, struct rtattr *attr)
-+static void tunnel_key_print_vxlan_options(struct rtattr *attr)
-+{
-+	struct rtattr *tb[TCA_TUNNEL_KEY_ENC_OPT_VXLAN_MAX + 1];
-+	struct rtattr *i = RTA_DATA(attr);
-+	int rem = RTA_PAYLOAD(attr);
-+	char *name = "vxlan_opts";
-+	__u32 gbp;
-+
-+	parse_rtattr(tb, TCA_TUNNEL_KEY_ENC_OPT_VXLAN_MAX, i, rem);
-+	gbp = rta_getattr_u32(tb[TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP]);
-+
-+	print_nl();
-+	print_string(PRINT_FP, name, "\t%s ", name);
-+	open_json_array(PRINT_JSON, name);
-+	open_json_object(NULL);
-+	print_uint(PRINT_ANY, "gbp", "%u", gbp);
-+	close_json_object();
-+	close_json_array(PRINT_JSON, name);
-+}
-+
-+static void tunnel_key_print_key_opt(struct rtattr *attr)
- {
- 	struct rtattr *tb[TCA_TUNNEL_KEY_ENC_OPTS_MAX + 1];
- 
-@@ -461,8 +525,12 @@ static void tunnel_key_print_key_opt(const char *name, struct rtattr *attr)
- 		return;
- 
- 	parse_rtattr_nested(tb, TCA_TUNNEL_KEY_ENC_OPTS_MAX, attr);
--	tunnel_key_print_geneve_options(name,
--					tb[TCA_TUNNEL_KEY_ENC_OPTS_GENEVE]);
-+	if (tb[TCA_TUNNEL_KEY_ENC_OPTS_GENEVE])
-+		tunnel_key_print_geneve_options(
-+			tb[TCA_TUNNEL_KEY_ENC_OPTS_GENEVE]);
-+	else if (tb[TCA_TUNNEL_KEY_ENC_OPTS_VXLAN])
-+		tunnel_key_print_vxlan_options(
-+			tb[TCA_TUNNEL_KEY_ENC_OPTS_VXLAN]);
- }
- 
- static void tunnel_key_print_tos_ttl(FILE *f, char *name,
-@@ -518,8 +586,7 @@ 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_key_opt("geneve_opts",
--					 tb[TCA_TUNNEL_KEY_ENC_OPTS]);
-+		tunnel_key_print_key_opt(tb[TCA_TUNNEL_KEY_ENC_OPTS]);
- 		tunnel_key_print_flag(f, "nocsum", "csum",
- 				      tb[TCA_TUNNEL_KEY_NO_CSUM]);
- 		tunnel_key_print_tos_ttl(f, "tos",
--- 
-2.26.2
-
diff --git a/SOURCES/0028-tc-m_tunnel_key-add-options-support-for-erpsan.patch b/SOURCES/0028-tc-m_tunnel_key-add-options-support-for-erpsan.patch
deleted file mode 100644
index 5dfebf0..0000000
--- a/SOURCES/0028-tc-m_tunnel_key-add-options-support-for-erpsan.patch
+++ /dev/null
@@ -1,265 +0,0 @@
-From 2fb8c115a8031d893fff588181cc42764391e4d5 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 4 Jun 2020 21:43:50 +0200
-Subject: [PATCH] tc: m_tunnel_key: add options support for erpsan
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1830485
-Upstream Status: unknown commit 668fd9b25d9ec
-
-commit 668fd9b25d9eca3067040273239f7825db95442b
-Author: Xin Long <lucien.xin@gmail.com>
-Date:   Mon Apr 27 18:27:49 2020 +0800
-
-    tc: m_tunnel_key: add options support for erpsan
-
-    This patch is to add TCA_TUNNEL_KEY_ENC_OPTS_ERSPAN's parse and
-    print to implement erspan options support in m_tunnel_key, like
-    Commit 6217917a3826 ("tc: m_tunnel_key: Add tunnel option support
-    to act_tunnel_key") for geneve options support.
-
-    Option is expressed as version:index:dir:hwid, dir and hwid will
-    be parsed when version is 2, while index will be parsed when
-    version is 1. erspan doesn't support multiple options.
-
-    With this patch, users can add and dump erspan options like:
-
-      # ip link add name erspan1 type erspan external
-      # tc qdisc add dev eth0 ingress
-      # tc filter add dev eth0 protocol ip parent ffff: \
-          flower indev eth0 \
-            ip_proto udp \
-            action tunnel_key \
-              set src_ip 10.0.99.192 \
-              dst_ip 10.0.99.193 \
-              dst_port 6081 \
-              id 11 \
-              erspan_opts 1:2:0:0 \
-          action mirred egress redirect dev erspan1
-      # tc -s filter show dev eth0 parent ffff:
-
-         filter protocol ip pref 49151 flower chain 0 handle 0x1
-           indev eth0
-           eth_type ipv4
-           ip_proto udp
-           not_in_hw
-             action order 1: tunnel_key  set
-             src_ip 10.0.99.192
-             dst_ip 10.0.99.193
-             key_id 11
-             dst_port 6081
-             erspan_opts 1:2:0:0
-             csum pipe
-               index 2 ref 1 bind 1
-             ...
-    v1->v2:
-      - no change.
-    v2->v3:
-      - no change.
-    v3->v4:
-      - keep the same format between input and output, json and non json.
-      - print version, index, dir and hwid as uint.
-
-    Signed-off-by: Xin Long <lucien.xin@gmail.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- man/man8/tc-tunnel_key.8 |  12 +++-
- tc/m_tunnel_key.c        | 117 ++++++++++++++++++++++++++++++++++++++-
- 2 files changed, 127 insertions(+), 2 deletions(-)
-
-diff --git a/man/man8/tc-tunnel_key.8 b/man/man8/tc-tunnel_key.8
-index c208e2c82a181..ad9972402c0e5 100644
---- a/man/man8/tc-tunnel_key.8
-+++ b/man/man8/tc-tunnel_key.8
-@@ -68,8 +68,10 @@ options.
- .B dst_port
- ,
- .B geneve_opts
--and
-+,
- .B vxlan_opts
-+and
-+.B erspan_opts
- are optional.
- .RS
- .TP
-@@ -99,6 +101,14 @@ Vxlan metatdata options.
- is specified in the form GBP, as a 32bit number. Multiple options is not
- supported.
- .TP
-+.B erspan_opts
-+Erspan metatdata options.
-+.B erspan_opts
-+is specified in the form VERSION:INDEX:DIR:HWID, where VERSION is represented
-+as a 8bit number, INDEX as an 32bit number, DIR and HWID as a 8bit number.
-+Multiple options is not supported. Note INDEX is used when VERSION is 1,
-+and DIR and HWID are used when VERSION is 2.
-+.TP
- .B tos
- Outer header TOS
- .TP
-diff --git a/tc/m_tunnel_key.c b/tc/m_tunnel_key.c
-index 76391d6c85fb2..a56fe24413fa0 100644
---- a/tc/m_tunnel_key.c
-+++ b/tc/m_tunnel_key.c
-@@ -29,7 +29,7 @@ static void explain(void)
- 		"src_ip <IP> (mandatory)\n"
- 		"dst_ip <IP> (mandatory)\n"
- 		"dst_port <UDP_PORT>\n"
--		"geneve_opts | vxlan_opts <OPTIONS>\n"
-+		"geneve_opts | vxlan_opts | erspan_opts <OPTIONS>\n"
- 		"csum | nocsum (default is \"csum\")\n");
- }
- 
-@@ -97,6 +97,21 @@ static int tunnel_key_parse_be16(char *str, int base, int type,
- 	return 0;
- }
- 
-+static int tunnel_key_parse_be32(char *str, int base, int type,
-+				 struct nlmsghdr *n)
-+{
-+	__be32 value;
-+	int ret;
-+
-+	ret = get_be32(&value, str, base);
-+	if (ret)
-+		return ret;
-+
-+	addattr32(n, MAX_MSG, type, value);
-+
-+	return 0;
-+}
-+
- static int tunnel_key_parse_u8(char *str, int base, int type,
- 			       struct nlmsghdr *n)
- {
-@@ -226,6 +241,63 @@ static int tunnel_key_parse_vxlan_opt(char *str, struct nlmsghdr *n)
- 	return 0;
- }
- 
-+static int tunnel_key_parse_erspan_opt(char *str, struct nlmsghdr *n)
-+{
-+	char *token, *saveptr = NULL;
-+	struct rtattr *encap, *nest;
-+	int i, ret;
-+
-+	encap = addattr_nest(n, MAX_MSG,
-+			     TCA_TUNNEL_KEY_ENC_OPTS | NLA_F_NESTED);
-+	nest = addattr_nest(n, MAX_MSG,
-+			    TCA_TUNNEL_KEY_ENC_OPTS_ERSPAN | NLA_F_NESTED);
-+
-+	token = strtok_r(str, ":", &saveptr);
-+	i = 1;
-+	while (token) {
-+		switch (i) {
-+		case TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_VER:
-+		{
-+			ret = tunnel_key_parse_u8(token, 0, i, n);
-+			if (ret)
-+				return ret;
-+			break;
-+		}
-+		case TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_INDEX:
-+		{
-+			ret = tunnel_key_parse_be32(token, 0, i, n);
-+			if (ret)
-+				return ret;
-+			break;
-+		}
-+		case TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_DIR:
-+		{
-+			ret = tunnel_key_parse_u8(token, 0, i, n);
-+			if (ret)
-+				return ret;
-+			break;
-+		}
-+		case TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_HWID:
-+		{
-+			ret = tunnel_key_parse_u8(token, 0, i, n);
-+			if (ret)
-+				return ret;
-+			break;
-+		}
-+		default:
-+			return -1;
-+		}
-+
-+		token = strtok_r(NULL, ":", &saveptr);
-+		i++;
-+	}
-+
-+	addattr_nest_end(n, nest);
-+	addattr_nest_end(n, encap);
-+
-+	return 0;
-+}
-+
- static int tunnel_key_parse_tos_ttl(char *str, int type, struct nlmsghdr *n)
- {
- 	int ret;
-@@ -330,6 +402,13 @@ static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p,
- 				fprintf(stderr, "Illegal \"vxlan_opts\"\n");
- 				return -1;
- 			}
-+		} else if (matches(*argv, "erspan_opts") == 0) {
-+			NEXT_ARG();
-+
-+			if (tunnel_key_parse_erspan_opt(*argv, n)) {
-+				fprintf(stderr, "Illegal \"erspan_opts\"\n");
-+				return -1;
-+			}
- 		} else if (matches(*argv, "tos") == 0) {
- 			NEXT_ARG();
- 			ret = tunnel_key_parse_tos_ttl(*argv,
-@@ -517,6 +596,39 @@ static void tunnel_key_print_vxlan_options(struct rtattr *attr)
- 	close_json_array(PRINT_JSON, name);
- }
- 
-+static void tunnel_key_print_erspan_options(struct rtattr *attr)
-+{
-+	struct rtattr *tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_MAX + 1];
-+	struct rtattr *i = RTA_DATA(attr);
-+	int rem = RTA_PAYLOAD(attr);
-+	char *name = "erspan_opts";
-+	__u8 ver, hwid, dir;
-+	__u32 idx;
-+
-+	parse_rtattr(tb, TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_MAX, i, rem);
-+	ver = rta_getattr_u8(tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_VER]);
-+	if (ver == 1) {
-+		idx = rta_getattr_be32(tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_INDEX]);
-+		dir = 0;
-+		hwid = 0;
-+	} else {
-+		idx = 0;
-+		dir = rta_getattr_u8(tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_DIR]);
-+		hwid = rta_getattr_u8(tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_HWID]);
-+	}
-+
-+	print_nl();
-+	print_string(PRINT_FP, name, "\t%s ", name);
-+	open_json_array(PRINT_JSON, name);
-+	open_json_object(NULL);
-+	print_uint(PRINT_ANY, "ver", "%u", ver);
-+	print_uint(PRINT_ANY, "index", ":%u", idx);
-+	print_uint(PRINT_ANY, "dir", ":%u", dir);
-+	print_uint(PRINT_ANY, "hwid", ":%u", hwid);
-+	close_json_object();
-+	close_json_array(PRINT_JSON, name);
-+}
-+
- static void tunnel_key_print_key_opt(struct rtattr *attr)
- {
- 	struct rtattr *tb[TCA_TUNNEL_KEY_ENC_OPTS_MAX + 1];
-@@ -531,6 +643,9 @@ static void tunnel_key_print_key_opt(struct rtattr *attr)
- 	else if (tb[TCA_TUNNEL_KEY_ENC_OPTS_VXLAN])
- 		tunnel_key_print_vxlan_options(
- 			tb[TCA_TUNNEL_KEY_ENC_OPTS_VXLAN]);
-+	else if (tb[TCA_TUNNEL_KEY_ENC_OPTS_ERSPAN])
-+		tunnel_key_print_erspan_options(
-+			tb[TCA_TUNNEL_KEY_ENC_OPTS_ERSPAN]);
- }
- 
- static void tunnel_key_print_tos_ttl(FILE *f, char *name,
--- 
-2.26.2
-
diff --git a/SOURCES/0029-tc-f_flower-add-options-support-for-vxlan.patch b/SOURCES/0029-tc-f_flower-add-options-support-for-vxlan.patch
deleted file mode 100644
index 0de0f70..0000000
--- a/SOURCES/0029-tc-f_flower-add-options-support-for-vxlan.patch
+++ /dev/null
@@ -1,316 +0,0 @@
-From 4bd1eb80a195ce1a64e33f5fc9d5c58bf9f30c8d Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 4 Jun 2020 21:43:50 +0200
-Subject: [PATCH] tc: f_flower: add options support for vxlan
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1830485
-Upstream Status: unknown commit 93c8d5f72f8ce
-Conflicts: on a removed line due to missing commit 93c8d5f72f8ce
-           ("tc: f_flower: add options support for vxlan")
-
-commit 93c8d5f72f8ce4b98c68508e85457f83933302c0
-Author: Xin Long <lucien.xin@gmail.com>
-Date:   Mon Apr 27 18:27:50 2020 +0800
-
-    tc: f_flower: add options support for vxlan
-
-    This patch is to add TCA_FLOWER_KEY_ENC_OPTS_VXLAN's parse and
-    print to implement vxlan options support in m_tunnel_key, like
-    Commit 56155d4df86d ("tc: f_flower: add geneve option match
-    support to flower") for geneve options support.
-
-    Option is expressed a 32bit number for gbp only, and vxlan
-    doesn't support multiple options.
-
-    With this patch, users can add and dump vxlan options like:
-
-      # ip link add name vxlan1 type vxlan dstport 0 external
-      # tc qdisc add dev vxlan1 ingress
-      # tc filter add dev vxlan1 protocol ip parent ffff: \
-          flower \
-            enc_src_ip 10.0.99.192 \
-            enc_dst_ip 10.0.99.193 \
-            enc_key_id 11 \
-            vxlan_opts 65793/4008635966 \
-            ip_proto udp \
-            action mirred egress redirect dev eth1
-      # tc -s filter show dev vxlan1 parent ffff:
-
-         filter protocol ip pref 49152 flower chain 0 handle 0x1
-           eth_type ipv4
-           ip_proto udp
-           enc_dst_ip 10.0.99.193
-           enc_src_ip 10.0.99.192
-           enc_key_id 11
-           vxlan_opts 65793/4008635966
-           not_in_hw
-             action order 1: mirred (Egress Redirect to device eth1) stolen
-             index 3 ref 1 bind 1
-             Action statistics:
-             Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
-             backlog 0b 0p requeues 0
-
-    v1->v2:
-      - get_u32 with base = 0 for gbp.
-    v2->v3:
-      - implement proper JSON array for opts.
-    v3->v4:
-      - keep the same format between input and output, json and non json.
-      - print gbp as uint.
-
-    Signed-off-by: Xin Long <lucien.xin@gmail.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- man/man8/tc-flower.8 |  12 ++++
- tc/f_flower.c        | 130 +++++++++++++++++++++++++++++++++++++------
- 2 files changed, 126 insertions(+), 16 deletions(-)
-
-diff --git a/man/man8/tc-flower.8 b/man/man8/tc-flower.8
-index adff41e39b006..0efacbfdf9a95 100644
---- a/man/man8/tc-flower.8
-+++ b/man/man8/tc-flower.8
-@@ -81,7 +81,11 @@ flower \- flow based traffic control filter
- .IR TOS " | "
- .B enc_ttl
- .IR TTL " | "
-+{
- .B geneve_opts
-+|
-+.B vxlan_opts
-+}
- .IR OPTIONS " | "
- .BR ip_flags
- .IR IP_FLAGS
-@@ -290,6 +294,8 @@ bits is assumed.
- .BI enc_ttl " NUMBER"
- .TQ
- .BI geneve_opts " OPTIONS"
-+.TQ
-+.BI vxlan_opts " OPTIONS"
- Match on IP tunnel metadata. Key id
- .I NUMBER
- is a 32 bit tunnel key id (e.g. VNI for VXLAN tunnel).
-@@ -310,6 +316,12 @@ the masks is missing, \fBtc\fR assumes a full-length match. The options can
- be described in the form CLASS:TYPE:DATA/CLASS_MASK:TYPE_MASK:DATA_MASK,
- where CLASS is represented as a 16bit hexadecimal value, TYPE as an 8bit
- hexadecimal value and DATA as a variable length hexadecimal value.
-+vxlan_opts
-+.I OPTIONS
-+doesn't support multiple options, and it consists of a key followed by a slash
-+and corresponding mask. If the mask is missing, \fBtc\fR assumes a full-length
-+match. The option can be described in the form GBP/GBP_MASK, where GBP is
-+represented as a 32bit number.
- .TP
- .BI ip_flags " IP_FLAGS"
- .I IP_FLAGS
-diff --git a/tc/f_flower.c b/tc/f_flower.c
-index 70d40d3b2f2bf..09079cd2c2280 100644
---- a/tc/f_flower.c
-+++ b/tc/f_flower.c
-@@ -81,6 +81,7 @@ static void explain(void)
- 		"			enc_tos MASKED-IP_TOS |\n"
- 		"			enc_ttl MASKED-IP_TTL |\n"
- 		"			geneve_opts MASKED-OPTIONS |\n"
-+		"			vxlan_opts MASKED-OPTIONS |\n"
- 		"			ip_flags IP-FLAGS | \n"
- 		"			enc_dst_port [ port_number ] }\n"
- 		"	FILTERID := X:Y:Z\n"
-@@ -648,7 +649,7 @@ static int flower_parse_enc_port(char *str, int type, struct nlmsghdr *n)
- 	return 0;
- }
- 
--static int flower_parse_geneve_opts(char *str, struct nlmsghdr *n)
-+static int flower_parse_geneve_opt(char *str, struct nlmsghdr *n)
- {
- 	struct rtattr *nest;
- 	char *token;
-@@ -718,14 +719,33 @@ static int flower_parse_geneve_opts(char *str, struct nlmsghdr *n)
- 	return 0;
- }
- 
--static int flower_parse_enc_opt_part(char *str, struct nlmsghdr *n)
-+static int flower_parse_vxlan_opt(char *str, struct nlmsghdr *n)
-+{
-+	struct rtattr *nest;
-+	__u32 gbp;
-+	int err;
-+
-+	nest = addattr_nest(n, MAX_MSG,
-+			    TCA_FLOWER_KEY_ENC_OPTS_VXLAN | NLA_F_NESTED);
-+
-+	err = get_u32(&gbp, str, 0);
-+	if (err)
-+		return err;
-+	addattr32(n, MAX_MSG, TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP, gbp);
-+
-+	addattr_nest_end(n, nest);
-+
-+	return 0;
-+}
-+
-+static int flower_parse_geneve_opts(char *str, struct nlmsghdr *n)
- {
- 	char *token;
- 	int err;
- 
- 	token = strsep(&str, ",");
- 	while (token) {
--		err = flower_parse_geneve_opts(token, n);
-+		err = flower_parse_geneve_opt(token, n);
- 		if (err)
- 			return err;
- 
-@@ -755,7 +775,7 @@ static int flower_check_enc_opt_key(char *key)
- 	return 0;
- }
- 
--static int flower_parse_enc_opts(char *str, struct nlmsghdr *n)
-+static int flower_parse_enc_opts_geneve(char *str, struct nlmsghdr *n)
- {
- 	char key[XATTR_SIZE_MAX], mask[XATTR_SIZE_MAX];
- 	int data_len, key_len, mask_len, err;
-@@ -807,13 +827,50 @@ static int flower_parse_enc_opts(char *str, struct nlmsghdr *n)
- 	mask[mask_len - 1] = '\0';
- 
- 	nest = addattr_nest(n, MAX_MSG, TCA_FLOWER_KEY_ENC_OPTS);
--	err = flower_parse_enc_opt_part(key, n);
-+	err = flower_parse_geneve_opts(key, n);
- 	if (err)
- 		return err;
- 	addattr_nest_end(n, nest);
- 
- 	nest = addattr_nest(n, MAX_MSG, TCA_FLOWER_KEY_ENC_OPTS_MASK);
--	err = flower_parse_enc_opt_part(mask, n);
-+	err = flower_parse_geneve_opts(mask, n);
-+	if (err)
-+		return err;
-+	addattr_nest_end(n, nest);
-+
-+	return 0;
-+}
-+
-+static int flower_parse_enc_opts_vxlan(char *str, struct nlmsghdr *n)
-+{
-+	char key[XATTR_SIZE_MAX], mask[XATTR_SIZE_MAX];
-+	struct rtattr *nest;
-+	char *slash;
-+	int err;
-+
-+	slash = strchr(str, '/');
-+	if (slash) {
-+		*slash++ = '\0';
-+		if (strlen(slash) > XATTR_SIZE_MAX)
-+			return -1;
-+		strcpy(mask, slash);
-+	} else {
-+		strcpy(mask, "0xffffffff");
-+	}
-+
-+	if (strlen(str) > XATTR_SIZE_MAX)
-+		return -1;
-+	strcpy(key, str);
-+
-+	nest = addattr_nest(n, MAX_MSG, TCA_FLOWER_KEY_ENC_OPTS | NLA_F_NESTED);
-+	err = flower_parse_vxlan_opt(str, n);
-+	if (err)
-+		return err;
-+	addattr_nest_end(n, nest);
-+
-+	nest = addattr_nest(n, MAX_MSG,
-+			    TCA_FLOWER_KEY_ENC_OPTS_MASK | NLA_F_NESTED);
-+	err = flower_parse_vxlan_opt(mask, n);
- 	if (err)
- 		return err;
- 	addattr_nest_end(n, nest);
-@@ -1275,11 +1332,18 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
- 			}
- 		} else if (matches(*argv, "geneve_opts") == 0) {
- 			NEXT_ARG();
--			ret = flower_parse_enc_opts(*argv, n);
-+			ret = flower_parse_enc_opts_geneve(*argv, n);
- 			if (ret < 0) {
- 				fprintf(stderr, "Illegal \"geneve_opts\"\n");
- 				return -1;
- 			}
-+		} else if (matches(*argv, "vxlan_opts") == 0) {
-+			NEXT_ARG();
-+			ret = flower_parse_enc_opts_vxlan(*argv, n);
-+			if (ret < 0) {
-+				fprintf(stderr, "Illegal \"vxlan_opts\"\n");
-+				return -1;
-+			}
- 		} else if (matches(*argv, "action") == 0) {
- 			NEXT_ARG();
- 			ret = parse_action(&argc, &argv, TCA_FLOWER_ACT, n);
-@@ -1643,10 +1707,29 @@ static void flower_print_geneve_opts(const char *name, struct rtattr *attr,
- 	close_json_array(PRINT_JSON, name);
- }
- 
--static void flower_print_geneve_parts(const char *name, struct rtattr *attr,
--				      char *key, char *mask)
-+static void flower_print_vxlan_opts(const char *name, struct rtattr *attr,
-+				    char *strbuf)
-+{
-+	struct rtattr *tb[TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX + 1];
-+	struct rtattr *i = RTA_DATA(attr);
-+	int rem = RTA_PAYLOAD(attr);
-+	__u32 gbp;
-+
-+	parse_rtattr(tb, TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX, i, rem);
-+	gbp = rta_getattr_u32(tb[TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP]);
-+
-+	open_json_array(PRINT_JSON, name);
-+	open_json_object(NULL);
-+	print_uint(PRINT_JSON, "gbp", NULL, gbp);
-+	close_json_object();
-+	close_json_array(PRINT_JSON, name);
-+
-+	sprintf(strbuf, "%u", gbp);
-+}
-+
-+static void flower_print_enc_parts(const char *name, const char *namefrm,
-+				   struct rtattr *attr, char *key, char *mask)
- {
--	char *namefrm = "\n  geneve_opt %s";
- 	char *key_token, *mask_token, *out;
- 	int len;
- 
-@@ -1687,14 +1770,29 @@ static void flower_print_enc_opts(const char *name, struct rtattr *attr,
- 		goto err_key_free;
- 
- 	parse_rtattr_nested(key_tb, TCA_FLOWER_KEY_ENC_OPTS_MAX, attr);
--	flower_print_geneve_opts("geneve_opt_key",
--				 key_tb[TCA_FLOWER_KEY_ENC_OPTS_GENEVE], key);
--
- 	parse_rtattr_nested(msk_tb, TCA_FLOWER_KEY_ENC_OPTS_MAX, mask_attr);
--	flower_print_geneve_opts("geneve_opt_mask",
--				 msk_tb[TCA_FLOWER_KEY_ENC_OPTS_GENEVE], msk);
- 
--	flower_print_geneve_parts(name, attr, key, msk);
-+	if (key_tb[TCA_FLOWER_KEY_ENC_OPTS_GENEVE]) {
-+		flower_print_geneve_opts("geneve_opt_key",
-+				key_tb[TCA_FLOWER_KEY_ENC_OPTS_GENEVE], key);
-+
-+		if (msk_tb[TCA_FLOWER_KEY_ENC_OPTS_GENEVE])
-+			flower_print_geneve_opts("geneve_opt_mask",
-+				msk_tb[TCA_FLOWER_KEY_ENC_OPTS_GENEVE], msk);
-+
-+		flower_print_enc_parts(name, "  geneve_opts %s", attr, key,
-+				       msk);
-+	} else if (key_tb[TCA_FLOWER_KEY_ENC_OPTS_VXLAN]) {
-+		flower_print_vxlan_opts("vxlan_opt_key",
-+				key_tb[TCA_FLOWER_KEY_ENC_OPTS_VXLAN], key);
-+
-+		if (msk_tb[TCA_FLOWER_KEY_ENC_OPTS_VXLAN])
-+			flower_print_vxlan_opts("vxlan_opt_mask",
-+				msk_tb[TCA_FLOWER_KEY_ENC_OPTS_VXLAN], msk);
-+
-+		flower_print_enc_parts(name, "  vxlan_opts %s", attr, key,
-+				       msk);
-+	}
- 
- 	free(msk);
- err_key_free:
--- 
-2.26.2
-
diff --git a/SOURCES/0030-tc-f_flower-add-options-support-for-erspan.patch b/SOURCES/0030-tc-f_flower-add-options-support-for-erspan.patch
deleted file mode 100644
index 6c1469b..0000000
--- a/SOURCES/0030-tc-f_flower-add-options-support-for-erspan.patch
+++ /dev/null
@@ -1,324 +0,0 @@
-From 6784a916b142c3bd5cf7c20a30b23e362bd4908a Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Thu, 4 Jun 2020 21:44:22 +0200
-Subject: [PATCH] tc: f_flower: add options support for erspan
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1830485
-Upstream Status: unknown commit 4e578c78fedfe
-
-commit 4e578c78fedfe6ffa5fa5fde56778b264485829b
-Author: Xin Long <lucien.xin@gmail.com>
-Date:   Mon Apr 27 18:27:51 2020 +0800
-
-    tc: f_flower: add options support for erspan
-
-    This patch is to add TCA_FLOWER_KEY_ENC_OPTS_ERSPAN's parse and
-    print to implement erspan options support in m_tunnel_key, like
-    Commit 56155d4df86d ("tc: f_flower: add geneve option match
-    support to flower") for geneve options support.
-
-    Option is expressed as version:index:dir:hwid, dir and hwid will
-    be parsed when version is 2, while index will be parsed when
-    version is 1. erspan doesn't support multiple options.
-
-    With this patch, users can add and dump erspan options like:
-
-      # ip link add name erspan1 type erspan external
-      # tc qdisc add dev erspan1 ingress
-      # tc filter add dev erspan1 protocol ip parent ffff: \
-          flower \
-            enc_src_ip 10.0.99.192 \
-            enc_dst_ip 10.0.99.193 \
-            enc_key_id 11 \
-            erspan_opts 1:2:0:0/1:255:0:0 \
-            ip_proto udp \
-            action mirred egress redirect dev eth1
-      # tc -s filter show dev erspan1 parent ffff:
-
-         filter protocol ip pref 49152 flower chain 0 handle 0x1
-           eth_type ipv4
-           ip_proto udp
-           enc_dst_ip 10.0.99.193
-           enc_src_ip 10.0.99.192
-           enc_key_id 11
-           erspan_opts 1:2:0:0/1:255:0:0
-           not_in_hw
-             action order 1: mirred (Egress Redirect to device eth1) stolen
-             index 1 ref 1 bind 1
-             Action statistics:
-             Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
-             backlog 0b 0p requeues 0
-
-    v1->v2:
-      - no change.
-    v2->v3:
-      - no change.
-    v3->v4:
-      - keep the same format between input and output, json and non json.
-      - print version, index, dir and hwid as uint.
-
-    Signed-off-by: Xin Long <lucien.xin@gmail.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- man/man8/tc-flower.8 |  13 ++++
- tc/f_flower.c        | 171 +++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 184 insertions(+)
-
-diff --git a/man/man8/tc-flower.8 b/man/man8/tc-flower.8
-index 0efacbfdf9a95..f41b0f7f1ef13 100644
---- a/man/man8/tc-flower.8
-+++ b/man/man8/tc-flower.8
-@@ -85,6 +85,8 @@ flower \- flow based traffic control filter
- .B geneve_opts
- |
- .B vxlan_opts
-+|
-+.B erspan_opts
- }
- .IR OPTIONS " | "
- .BR ip_flags
-@@ -296,6 +298,8 @@ bits is assumed.
- .BI geneve_opts " OPTIONS"
- .TQ
- .BI vxlan_opts " OPTIONS"
-+.TQ
-+.BI erspan_opts " OPTIONS"
- Match on IP tunnel metadata. Key id
- .I NUMBER
- is a 32 bit tunnel key id (e.g. VNI for VXLAN tunnel).
-@@ -322,6 +326,15 @@ doesn't support multiple options, and it consists of a key followed by a slash
- and corresponding mask. If the mask is missing, \fBtc\fR assumes a full-length
- match. The option can be described in the form GBP/GBP_MASK, where GBP is
- represented as a 32bit number.
-+erspan_opts
-+.I OPTIONS
-+doesn't support multiple options, and it consists of a key followed by a slash
-+and corresponding mask. If the mask is missing, \fBtc\fR assumes a full-length
-+match. The option can be described in the form
-+VERSION:INDEX:DIR:HWID/VERSION:INDEX_MASK:DIR_MASK:HWID_MASK, where VERSION is
-+represented as a 8bit number, INDEX as an 32bit number, DIR and HWID as a 8bit
-+number. Multiple options is not supported. Note INDEX/INDEX_MASK is used when
-+VERSION is 1, and DIR/DIR_MASK and HWID/HWID_MASK are used when VERSION is 2.
- .TP
- .BI ip_flags " IP_FLAGS"
- .I IP_FLAGS
-diff --git a/tc/f_flower.c b/tc/f_flower.c
-index 09079cd2c2280..691541ec59d4c 100644
---- a/tc/f_flower.c
-+++ b/tc/f_flower.c
-@@ -82,6 +82,7 @@ static void explain(void)
- 		"			enc_ttl MASKED-IP_TTL |\n"
- 		"			geneve_opts MASKED-OPTIONS |\n"
- 		"			vxlan_opts MASKED-OPTIONS |\n"
-+		"                       erspan_opts MASKED-OPTIONS |\n"
- 		"			ip_flags IP-FLAGS | \n"
- 		"			enc_dst_port [ port_number ] }\n"
- 		"	FILTERID := X:Y:Z\n"
-@@ -738,6 +739,84 @@ static int flower_parse_vxlan_opt(char *str, struct nlmsghdr *n)
- 	return 0;
- }
- 
-+static int flower_parse_erspan_opt(char *str, struct nlmsghdr *n)
-+{
-+	struct rtattr *nest;
-+	char *token;
-+	int i, err;
-+
-+	nest = addattr_nest(n, MAX_MSG,
-+			    TCA_FLOWER_KEY_ENC_OPTS_ERSPAN | NLA_F_NESTED);
-+
-+	i = 1;
-+	token = strsep(&str, ":");
-+	while (token) {
-+		switch (i) {
-+		case TCA_FLOWER_KEY_ENC_OPT_ERSPAN_VER:
-+		{
-+			__u8 opt_type;
-+
-+			if (!strlen(token))
-+				break;
-+			err = get_u8(&opt_type, token, 0);
-+			if (err)
-+				return err;
-+
-+			addattr8(n, MAX_MSG, i, opt_type);
-+			break;
-+		}
-+		case TCA_FLOWER_KEY_ENC_OPT_ERSPAN_INDEX:
-+		{
-+			__be32 opt_index;
-+
-+			if (!strlen(token))
-+				break;
-+			err = get_be32(&opt_index, token, 0);
-+			if (err)
-+				return err;
-+
-+			addattr32(n, MAX_MSG, i, opt_index);
-+			break;
-+		}
-+		case TCA_FLOWER_KEY_ENC_OPT_ERSPAN_DIR:
-+		{
-+			__u8 opt_type;
-+
-+			if (!strlen(token))
-+				break;
-+			err = get_u8(&opt_type, token, 0);
-+			if (err)
-+				return err;
-+
-+			addattr8(n, MAX_MSG, i, opt_type);
-+			break;
-+		}
-+		case TCA_FLOWER_KEY_ENC_OPT_ERSPAN_HWID:
-+		{
-+			__u8 opt_type;
-+
-+			if (!strlen(token))
-+				break;
-+			err = get_u8(&opt_type, token, 0);
-+			if (err)
-+				return err;
-+
-+			addattr8(n, MAX_MSG, i, opt_type);
-+			break;
-+		}
-+		default:
-+			fprintf(stderr, "Unknown \"geneve_opts\" type\n");
-+			return -1;
-+		}
-+
-+		token = strsep(&str, ":");
-+		i++;
-+	}
-+	addattr_nest_end(n, nest);
-+
-+	return 0;
-+}
-+
- static int flower_parse_geneve_opts(char *str, struct nlmsghdr *n)
- {
- 	char *token;
-@@ -878,6 +957,49 @@ static int flower_parse_enc_opts_vxlan(char *str, struct nlmsghdr *n)
- 	return 0;
- }
- 
-+static int flower_parse_enc_opts_erspan(char *str, struct nlmsghdr *n)
-+{
-+	char key[XATTR_SIZE_MAX], mask[XATTR_SIZE_MAX];
-+	struct rtattr *nest;
-+	char *slash;
-+	int err;
-+
-+
-+	slash = strchr(str, '/');
-+	if (slash) {
-+		*slash++ = '\0';
-+		if (strlen(slash) > XATTR_SIZE_MAX)
-+			return -1;
-+		strcpy(mask, slash);
-+	} else {
-+		int index;
-+
-+		slash = strchr(str, ':');
-+		index = (int)(slash - str);
-+		memcpy(mask, str, index);
-+		strcpy(mask + index, ":0xffffffff:0xff:0xff");
-+	}
-+
-+	if (strlen(str) > XATTR_SIZE_MAX)
-+		return -1;
-+	strcpy(key, str);
-+
-+	nest = addattr_nest(n, MAX_MSG, TCA_FLOWER_KEY_ENC_OPTS | NLA_F_NESTED);
-+	err = flower_parse_erspan_opt(key, n);
-+	if (err)
-+		return err;
-+	addattr_nest_end(n, nest);
-+
-+	nest = addattr_nest(n, MAX_MSG,
-+			    TCA_FLOWER_KEY_ENC_OPTS_MASK | NLA_F_NESTED);
-+	err = flower_parse_erspan_opt(mask, n);
-+	if (err)
-+		return err;
-+	addattr_nest_end(n, nest);
-+
-+	return 0;
-+}
-+
- static int flower_parse_opt(struct filter_util *qu, char *handle,
- 			    int argc, char **argv, struct nlmsghdr *n)
- {
-@@ -1344,6 +1466,13 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
- 				fprintf(stderr, "Illegal \"vxlan_opts\"\n");
- 				return -1;
- 			}
-+		} else if (matches(*argv, "erspan_opts") == 0) {
-+			NEXT_ARG();
-+			ret = flower_parse_enc_opts_erspan(*argv, n);
-+			if (ret < 0) {
-+				fprintf(stderr, "Illegal \"erspan_opts\"\n");
-+				return -1;
-+			}
- 		} else if (matches(*argv, "action") == 0) {
- 			NEXT_ARG();
- 			ret = parse_action(&argc, &argv, TCA_FLOWER_ACT, n);
-@@ -1727,6 +1856,38 @@ static void flower_print_vxlan_opts(const char *name, struct rtattr *attr,
- 	sprintf(strbuf, "%u", gbp);
- }
- 
-+static void flower_print_erspan_opts(const char *name, struct rtattr *attr,
-+				     char *strbuf)
-+{
-+	struct rtattr *tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_MAX + 1];
-+	__u8 ver, hwid, dir;
-+	__u32 idx;
-+
-+	parse_rtattr(tb, TCA_FLOWER_KEY_ENC_OPT_ERSPAN_MAX, RTA_DATA(attr),
-+		     RTA_PAYLOAD(attr));
-+	ver = rta_getattr_u8(tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_VER]);
-+	if (ver == 1) {
-+		idx = rta_getattr_be32(tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_INDEX]);
-+		hwid = 0;
-+		dir = 0;
-+	} else {
-+		idx = 0;
-+		hwid = rta_getattr_u8(tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_HWID]);
-+		dir = rta_getattr_u8(tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_DIR]);
-+	}
-+
-+	open_json_array(PRINT_JSON, name);
-+	open_json_object(NULL);
-+	print_uint(PRINT_JSON, "ver", NULL, ver);
-+	print_uint(PRINT_JSON, "index", NULL, idx);
-+	print_uint(PRINT_JSON, "dir", NULL, dir);
-+	print_uint(PRINT_JSON, "hwid", NULL, hwid);
-+	close_json_object();
-+	close_json_array(PRINT_JSON, name);
-+
-+	sprintf(strbuf, "%u:%u:%u:%u", ver, idx, dir, hwid);
-+}
-+
- static void flower_print_enc_parts(const char *name, const char *namefrm,
- 				   struct rtattr *attr, char *key, char *mask)
- {
-@@ -1792,6 +1953,16 @@ static void flower_print_enc_opts(const char *name, struct rtattr *attr,
- 
- 		flower_print_enc_parts(name, "  vxlan_opts %s", attr, key,
- 				       msk);
-+	} else if (key_tb[TCA_FLOWER_KEY_ENC_OPTS_ERSPAN]) {
-+		flower_print_erspan_opts("erspan_opt_key",
-+				key_tb[TCA_FLOWER_KEY_ENC_OPTS_ERSPAN], key);
-+
-+		if (msk_tb[TCA_FLOWER_KEY_ENC_OPTS_ERSPAN])
-+			flower_print_erspan_opts("erspan_opt_mask",
-+				msk_tb[TCA_FLOWER_KEY_ENC_OPTS_ERSPAN], msk);
-+
-+		flower_print_enc_parts(name, "  erspan_opts %s", attr, key,
-+				       msk);
- 	}
- 
- 	free(msk);
--- 
-2.26.2
-
diff --git a/SOURCES/0031-devlink-Add-health-error-recovery-status-monitoring.patch b/SOURCES/0031-devlink-Add-health-error-recovery-status-monitoring.patch
deleted file mode 100644
index 813691b..0000000
--- a/SOURCES/0031-devlink-Add-health-error-recovery-status-monitoring.patch
+++ /dev/null
@@ -1,116 +0,0 @@
-From 81a035c029c2ef108da0f854c5a670aa3f06bb94 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Wed, 17 Jun 2020 12:10:11 +0200
-Subject: [PATCH] devlink: Add health error recovery status monitoring
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1821039
-Upstream Status: iproute2.git commit 5023df6a21c73
-Conflicts: context change due to missing commit
-  - ef12d6dafaeb9 ("devlink: Add devlink trap set and show commands")
-  - 4ede9e9d56206 ("devlink: Add devlink trap group set and show commands")
-  - a66af5569337b ("devlink: Add devlink trap policer set and show commands")
-
-commit 5023df6a21c73560b514d7fde5381d140373afe9
-Author: Moshe Shemesh <moshe@mellanox.com>
-Date:   Tue Feb 4 23:37:02 2020 +0200
-
-    devlink: Add health error recovery status monitoring
-
-    Add support for devlink health error recovery status monitoring.
-    Update devlink-monitor man page accordingly.
-
-    Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
-    Acked-by: Jiri Pirko <jiri@mellanox.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- devlink/devlink.c          | 17 +++++++++++++++--
- man/man8/devlink-monitor.8 |  3 ++-
- 2 files changed, 17 insertions(+), 3 deletions(-)
-
-diff --git a/devlink/devlink.c b/devlink/devlink.c
-index 0293373928f50..f7e859c266394 100644
---- a/devlink/devlink.c
-+++ b/devlink/devlink.c
-@@ -3764,6 +3764,7 @@ static const char *cmd_name(uint8_t cmd)
- 	case DEVLINK_CMD_REGION_SET: return "set";
- 	case DEVLINK_CMD_REGION_NEW: return "new";
- 	case DEVLINK_CMD_REGION_DEL: return "del";
-+	case DEVLINK_CMD_HEALTH_REPORTER_RECOVER: return "status";
- 	default: return "<unknown cmd>";
- 	}
- }
-@@ -3792,6 +3793,8 @@ static const char *cmd_obj(uint8_t cmd)
- 	case DEVLINK_CMD_REGION_NEW:
- 	case DEVLINK_CMD_REGION_DEL:
- 		return "region";
-+	case DEVLINK_CMD_HEALTH_REPORTER_RECOVER:
-+		return "health";
- 	default: return "<unknown obj>";
- 	}
- }
-@@ -3817,6 +3820,7 @@ static bool cmd_filter_check(struct dl *dl, uint8_t cmd)
- }
- 
- static void pr_out_region(struct dl *dl, struct nlattr **tb);
-+static void pr_out_health(struct dl *dl, struct nlattr **tb_health);
- 
- static int cmd_mon_show_cb(const struct nlmsghdr *nlh, void *data)
- {
-@@ -3872,6 +3876,14 @@ static int cmd_mon_show_cb(const struct nlmsghdr *nlh, void *data)
- 		pr_out_mon_header(genl->cmd);
- 		pr_out_region(dl, tb);
- 		break;
-+	case DEVLINK_CMD_HEALTH_REPORTER_RECOVER:
-+		mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
-+		if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
-+		    !tb[DEVLINK_ATTR_HEALTH_REPORTER])
-+			return MNL_CB_ERROR;
-+		pr_out_mon_header(genl->cmd);
-+		pr_out_health(dl, tb);
-+		break;
- 	}
- 	return MNL_CB_OK;
- }
-@@ -3885,7 +3897,8 @@ static int cmd_mon_show(struct dl *dl)
- 	while ((cur_obj = dl_argv_index(dl, index++))) {
- 		if (strcmp(cur_obj, "all") != 0 &&
- 		    strcmp(cur_obj, "dev") != 0 &&
--		    strcmp(cur_obj, "port") != 0) {
-+		    strcmp(cur_obj, "port") != 0 &&
-+		    strcmp(cur_obj, "health") != 0) {
- 			pr_err("Unknown object \"%s\"\n", cur_obj);
- 			return -EINVAL;
- 		}
-@@ -3902,7 +3915,7 @@ static int cmd_mon_show(struct dl *dl)
- static void cmd_mon_help(void)
- {
- 	pr_err("Usage: devlink monitor [ all | OBJECT-LIST ]\n"
--	       "where  OBJECT-LIST := { dev | port }\n");
-+	       "where  OBJECT-LIST := { dev | port | health }\n");
- }
- 
- static int cmd_mon(struct dl *dl)
-diff --git a/man/man8/devlink-monitor.8 b/man/man8/devlink-monitor.8
-index 13fe641dc8f54..9bc579673ebf4 100644
---- a/man/man8/devlink-monitor.8
-+++ b/man/man8/devlink-monitor.8
-@@ -21,7 +21,7 @@ command is the first in the command line and then the object list.
- .I OBJECT-LIST
- is the list of object types that we want to monitor.
- It may contain
--.BR dev ", " port ".
-+.BR dev ", " port ", " health ".
- 
- .B devlink
- opens Devlink Netlink socket, listens on it and dumps state changes.
-@@ -31,6 +31,7 @@ opens Devlink Netlink socket, listens on it and dumps state changes.
- .BR devlink-dev (8),
- .BR devlink-sb (8),
- .BR devlink-port (8),
-+.BR devlink-health (8),
- .br
- 
- .SH AUTHOR
--- 
-2.26.2
-
diff --git a/SOURCES/0032-ss-allow-dumping-kTLS-info.patch b/SOURCES/0032-ss-allow-dumping-kTLS-info.patch
deleted file mode 100644
index 9fe02ae..0000000
--- a/SOURCES/0032-ss-allow-dumping-kTLS-info.patch
+++ /dev/null
@@ -1,139 +0,0 @@
-From 06bd12bd8e48182f7f3293bbec187b4e90da796f Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Mon, 29 Jun 2020 14:36:51 +0200
-Subject: [PATCH] ss: allow dumping kTLS info
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1812207
-Upstream Status: iproute2.git commit 14cadc707b919
-Conflicts: due to out-of-order cherry-pick of commit
-           712fdd98c0839 ("ss: allow dumping MPTCP subflow information")
-
-commit 14cadc707b919914e9a2d5dffad9232c3ae97c5f
-Author: Davide Caratti <dcaratti@redhat.com>
-Date:   Mon Oct 7 12:16:44 2019 +0200
-
-    ss: allow dumping kTLS info
-
-    now that INET_DIAG_INFO requests can dump TCP ULP information, extend 'ss'
-    to allow diagnosing kTLS when it is attached to a TCP socket. While at it,
-    import kTLS uAPI definitions from the latest net-next tree.
-
-    CC: Andrea Claudi <aclaudi@redhat.com>
-    Co-developed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
-    Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
-    Signed-off-by: Davide Caratti <dcaratti@redhat.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- misc/ss.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 82 insertions(+)
-
-diff --git a/misc/ss.c b/misc/ss.c
-index 3d565af86087c..8285382bd6c4a 100644
---- a/misc/ss.c
-+++ b/misc/ss.c
-@@ -51,6 +51,7 @@
- #include <linux/tipc.h>
- #include <linux/tipc_netlink.h>
- #include <linux/tipc_sockets_diag.h>
-+#include <linux/tls.h>
- #include <linux/mptcp.h>
- 
- /* AF_VSOCK/PF_VSOCK is only provided since glibc 2.18 */
-@@ -2752,6 +2753,72 @@ static void print_md5sig(struct tcp_diag_md5sig *sig)
- 	print_escape_buf(sig->tcpm_key, sig->tcpm_keylen, " ,");
- }
- 
-+static void tcp_tls_version(struct rtattr *attr)
-+{
-+	u_int16_t val;
-+
-+	if (!attr)
-+		return;
-+	val = rta_getattr_u16(attr);
-+
-+	switch (val) {
-+	case TLS_1_2_VERSION:
-+		out(" version: 1.2");
-+		break;
-+	case TLS_1_3_VERSION:
-+		out(" version: 1.3");
-+		break;
-+	default:
-+		out(" version: unknown(%hu)", val);
-+		break;
-+	}
-+}
-+
-+static void tcp_tls_cipher(struct rtattr *attr)
-+{
-+	u_int16_t val;
-+
-+	if (!attr)
-+		return;
-+	val = rta_getattr_u16(attr);
-+
-+	switch (val) {
-+	case TLS_CIPHER_AES_GCM_128:
-+		out(" cipher: aes-gcm-128");
-+		break;
-+	case TLS_CIPHER_AES_GCM_256:
-+		out(" cipher: aes-gcm-256");
-+		break;
-+	}
-+}
-+
-+static void tcp_tls_conf(const char *name, struct rtattr *attr)
-+{
-+	u_int16_t val;
-+
-+	if (!attr)
-+		return;
-+	val = rta_getattr_u16(attr);
-+
-+	switch (val) {
-+	case TLS_CONF_BASE:
-+		out(" %s: none", name);
-+		break;
-+	case TLS_CONF_SW:
-+		out(" %s: sw", name);
-+		break;
-+	case TLS_CONF_HW:
-+		out(" %s: hw", name);
-+		break;
-+	case TLS_CONF_HW_RECORD:
-+		out(" %s: hw-record", name);
-+		break;
-+	default:
-+		out(" %s: unknown(%hu)", name, val);
-+		break;
-+	}
-+}
-+
- static void mptcp_subflow_info(struct rtattr *tb[])
- {
- 	u_int32_t flags = 0;
-@@ -2966,6 +3033,21 @@ static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r,
- 		parse_rtattr_nested(ulpinfo, INET_ULP_INFO_MAX,
- 				    tb[INET_DIAG_ULP_INFO]);
- 
-+		if (ulpinfo[INET_ULP_INFO_NAME])
-+			out(" tcp-ulp-%s",
-+			    rta_getattr_str(ulpinfo[INET_ULP_INFO_NAME]));
-+
-+		if (ulpinfo[INET_ULP_INFO_TLS]) {
-+			struct rtattr *tlsinfo[TLS_INFO_MAX + 1] = { 0 };
-+
-+			parse_rtattr_nested(tlsinfo, TLS_INFO_MAX,
-+					    ulpinfo[INET_ULP_INFO_TLS]);
-+
-+			tcp_tls_version(tlsinfo[TLS_INFO_VERSION]);
-+			tcp_tls_cipher(tlsinfo[TLS_INFO_CIPHER]);
-+			tcp_tls_conf("rxconf", tlsinfo[TLS_INFO_RXCONF]);
-+			tcp_tls_conf("txconf", tlsinfo[TLS_INFO_TXCONF]);
-+		}
- 		if (ulpinfo[INET_ULP_INFO_MPTCP]) {
- 			struct rtattr *sfinfo[MPTCP_SUBFLOW_ATTR_MAX + 1] =
- 				{ 0 };
--- 
-2.26.2
-
diff --git a/SOURCES/0033-Import-tc_act-tc_ct.h-uapi-file.patch b/SOURCES/0033-Import-tc_act-tc_ct.h-uapi-file.patch
deleted file mode 100644
index f3c473d..0000000
--- a/SOURCES/0033-Import-tc_act-tc_ct.h-uapi-file.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 4c330f41bce887a4a06d6c84c62a3a8c1b0b5160 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Tue, 9 Jun 2020 15:45:55 +0200
-Subject: [PATCH] Import tc_act/tc_ct.h uapi file
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1844637
-Upstream Status: iproute2.git commit f47081befffc5
-
-commit f47081befffc50a5eef734d0a6654b59047e7808
-Author: David Ahern <dsahern@gmail.com>
-Date:   Thu Jul 18 15:40:07 2019 -0700
-
-    Import tc_act/tc_ct.h uapi file
-
-    Import include/uapi/linux/tc_act/tc_ct.h header from commit of last
-    kernel headers sync.
-
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- include/uapi/linux/tc_act/tc_ct.h | 41 +++++++++++++++++++++++++++++++
- 1 file changed, 41 insertions(+)
- create mode 100644 include/uapi/linux/tc_act/tc_ct.h
-
-diff --git a/include/uapi/linux/tc_act/tc_ct.h b/include/uapi/linux/tc_act/tc_ct.h
-new file mode 100644
-index 0000000000000..5fb1d7ac10272
---- /dev/null
-+++ b/include/uapi/linux/tc_act/tc_ct.h
-@@ -0,0 +1,41 @@
-+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-+#ifndef __UAPI_TC_CT_H
-+#define __UAPI_TC_CT_H
-+
-+#include <linux/types.h>
-+#include <linux/pkt_cls.h>
-+
-+enum {
-+	TCA_CT_UNSPEC,
-+	TCA_CT_PARMS,
-+	TCA_CT_TM,
-+	TCA_CT_ACTION,		/* u16 */
-+	TCA_CT_ZONE,		/* u16 */
-+	TCA_CT_MARK,		/* u32 */
-+	TCA_CT_MARK_MASK,	/* u32 */
-+	TCA_CT_LABELS,		/* u128 */
-+	TCA_CT_LABELS_MASK,	/* u128 */
-+	TCA_CT_NAT_IPV4_MIN,	/* be32 */
-+	TCA_CT_NAT_IPV4_MAX,	/* be32 */
-+	TCA_CT_NAT_IPV6_MIN,	/* struct in6_addr */
-+	TCA_CT_NAT_IPV6_MAX,	/* struct in6_addr */
-+	TCA_CT_NAT_PORT_MIN,	/* be16 */
-+	TCA_CT_NAT_PORT_MAX,	/* be16 */
-+	TCA_CT_PAD,
-+	__TCA_CT_MAX
-+};
-+
-+#define TCA_CT_MAX (__TCA_CT_MAX - 1)
-+
-+#define TCA_CT_ACT_COMMIT	(1 << 0)
-+#define TCA_CT_ACT_FORCE	(1 << 1)
-+#define TCA_CT_ACT_CLEAR	(1 << 2)
-+#define TCA_CT_ACT_NAT		(1 << 3)
-+#define TCA_CT_ACT_NAT_SRC	(1 << 4)
-+#define TCA_CT_ACT_NAT_DST	(1 << 5)
-+
-+struct tc_ct {
-+	tc_gen;
-+};
-+
-+#endif /* __UAPI_TC_CT_H */
--- 
-2.26.2
-
diff --git a/SOURCES/0034-tc-add-NLA_F_NESTED-flag-to-all-actions-options-nest.patch b/SOURCES/0034-tc-add-NLA_F_NESTED-flag-to-all-actions-options-nest.patch
deleted file mode 100644
index 5832ac4..0000000
--- a/SOURCES/0034-tc-add-NLA_F_NESTED-flag-to-all-actions-options-nest.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From bf795d2418ee298ddc73171829d6dc4914c22a46 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Tue, 9 Jun 2020 15:45:56 +0200
-Subject: [PATCH] tc: add NLA_F_NESTED flag to all actions options nested block
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1844637
-Upstream Status: iproute2.git commit 18aa9f5583e94
-
-commit 18aa9f5583e94abc7204b2376b819ede1180da97
-Author: Paul Blakey <paulb@mellanox.com>
-Date:   Thu Jul 11 11:14:25 2019 +0300
-
-    tc: add NLA_F_NESTED flag to all actions options nested block
-
-    Strict netlink validation now requires this flag on all nested
-    attributes, add it for action options.
-
-    Signed-off-by: Paul Blakey <paulb@mellanox.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- tc/m_action.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/tc/m_action.c b/tc/m_action.c
-index c46aeaafa8ebf..4da810c8c0aa7 100644
---- a/tc/m_action.c
-+++ b/tc/m_action.c
-@@ -214,7 +214,8 @@ done0:
- 			tail = addattr_nest(n, MAX_MSG, ++prio);
- 			addattr_l(n, MAX_MSG, TCA_ACT_KIND, k, strlen(k) + 1);
- 
--			ret = a->parse_aopt(a, &argc, &argv, TCA_ACT_OPTIONS,
-+			ret = a->parse_aopt(a, &argc, &argv,
-+					    TCA_ACT_OPTIONS | NLA_F_NESTED,
- 					    n);
- 
- 			if (ret < 0) {
--- 
-2.26.2
-
diff --git a/SOURCES/0035-tc-Introduce-tc-ct-action.patch b/SOURCES/0035-tc-Introduce-tc-ct-action.patch
deleted file mode 100644
index 3971adf..0000000
--- a/SOURCES/0035-tc-Introduce-tc-ct-action.patch
+++ /dev/null
@@ -1,621 +0,0 @@
-From ef66b6a546f3f1fd517cfa306cc347ad096bd932 Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Tue, 9 Jun 2020 15:45:56 +0200
-Subject: [PATCH] tc: Introduce tc ct action
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1844637
-Upstream Status: iproute2.git commit c8a494314c400
-
-commit c8a494314c400eb023d7555933ba8ab40345519b
-Author: Paul Blakey <paulb@mellanox.com>
-Date:   Thu Jul 11 11:14:26 2019 +0300
-
-    tc: Introduce tc ct action
-
-    New tc action to send packets to conntrack module, commit
-    them, and set a zone, labels, mark, and nat on the connection.
-
-    It can also clear the packet's conntrack state by using clear.
-
-    Usage:
-       ct clear
-       ct commit [force] [zone] [mark] [label] [nat]
-       ct [nat] [zone]
-
-    Signed-off-by: Paul Blakey <paulb@mellanox.com>
-    Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
-    Signed-off-by: Yossi Kuperman <yossiku@mellanox.com>
-    Acked-by: Jiri Pirko <jiri@mellanox.com>
-    Acked-by: Roi Dayan <roid@mellanox.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- tc/Makefile  |   1 +
- tc/m_ct.c    | 497 +++++++++++++++++++++++++++++++++++++++++++++++++++
- tc/tc_util.c |  44 +++++
- tc/tc_util.h |   4 +
- 4 files changed, 546 insertions(+)
- create mode 100644 tc/m_ct.c
-
-diff --git a/tc/Makefile b/tc/Makefile
-index 09ff3692b1663..14171a28cba5d 100644
---- a/tc/Makefile
-+++ b/tc/Makefile
-@@ -53,6 +53,7 @@ TCMODULES += m_ctinfo.o
- TCMODULES += m_bpf.o
- TCMODULES += m_tunnel_key.o
- TCMODULES += m_sample.o
-+TCMODULES += m_ct.o
- TCMODULES += p_ip.o
- TCMODULES += p_ip6.o
- TCMODULES += p_icmp.o
-diff --git a/tc/m_ct.c b/tc/m_ct.c
-new file mode 100644
-index 0000000000000..8589cb9a3c515
---- /dev/null
-+++ b/tc/m_ct.c
-@@ -0,0 +1,497 @@
-+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
-+/* -
-+ * m_ct.c     Connection tracking action
-+ *
-+ * Authors:   Paul Blakey <paulb@mellanox.com>
-+ *            Yossi Kuperman <yossiku@mellanox.com>
-+ *            Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
-+ */
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include "utils.h"
-+#include "tc_util.h"
-+#include <linux/tc_act/tc_ct.h>
-+
-+static void
-+usage(void)
-+{
-+	fprintf(stderr,
-+		"Usage: ct clear\n"
-+		"	ct commit [force] [zone ZONE] [mark MASKED_MARK] [label MASKED_LABEL] [nat NAT_SPEC]\n"
-+		"	ct [nat] [zone ZONE]\n"
-+		"Where: ZONE is the conntrack zone table number\n"
-+		"	NAT_SPEC is {src|dst} addr addr1[-addr2] [port port1[-port2]]\n"
-+		"\n");
-+	exit(-1);
-+}
-+
-+static int ct_parse_nat_addr_range(const char *str, struct nlmsghdr *n)
-+{
-+	inet_prefix addr = { .family = AF_UNSPEC, };
-+	char *addr1, *addr2 = 0;
-+	SPRINT_BUF(buffer);
-+	int attr;
-+	int ret;
-+
-+	strncpy(buffer, str, sizeof(buffer) - 1);
-+
-+	addr1 = buffer;
-+	addr2 = strchr(addr1, '-');
-+	if (addr2) {
-+		*addr2 = '\0';
-+		addr2++;
-+	}
-+
-+	ret = get_addr(&addr, addr1, AF_UNSPEC);
-+	if (ret)
-+		return ret;
-+	attr = addr.family == AF_INET ? TCA_CT_NAT_IPV4_MIN :
-+					TCA_CT_NAT_IPV6_MIN;
-+	addattr_l(n, MAX_MSG, attr, addr.data, addr.bytelen);
-+
-+	if (addr2) {
-+		ret = get_addr(&addr, addr2, addr.family);
-+		if (ret)
-+			return ret;
-+	}
-+	attr = addr.family == AF_INET ? TCA_CT_NAT_IPV4_MAX :
-+					TCA_CT_NAT_IPV6_MAX;
-+	addattr_l(n, MAX_MSG, attr, addr.data, addr.bytelen);
-+
-+	return 0;
-+}
-+
-+static int ct_parse_nat_port_range(const char *str, struct nlmsghdr *n)
-+{
-+	char *port1, *port2 = 0;
-+	SPRINT_BUF(buffer);
-+	__be16 port;
-+	int ret;
-+
-+	strncpy(buffer, str, sizeof(buffer) - 1);
-+
-+	port1 = buffer;
-+	port2 = strchr(port1, '-');
-+	if (port2) {
-+		*port2 = '\0';
-+		port2++;
-+	}
-+
-+	ret = get_be16(&port, port1, 10);
-+	if (ret)
-+		return -1;
-+	addattr16(n, MAX_MSG, TCA_CT_NAT_PORT_MIN, port);
-+
-+	if (port2) {
-+		ret = get_be16(&port, port2, 10);
-+		if (ret)
-+			return -1;
-+	}
-+	addattr16(n, MAX_MSG, TCA_CT_NAT_PORT_MAX, port);
-+
-+	return 0;
-+}
-+
-+
-+static int ct_parse_u16(char *str, int value_type, int mask_type,
-+			struct nlmsghdr *n)
-+{
-+	__u16 value, mask;
-+	char *slash = 0;
-+
-+	if (mask_type != TCA_CT_UNSPEC) {
-+		slash = strchr(str, '/');
-+		if (slash)
-+			*slash = '\0';
-+	}
-+
-+	if (get_u16(&value, str, 0))
-+		return -1;
-+
-+	if (slash) {
-+		if (get_u16(&mask, slash + 1, 0))
-+			return -1;
-+	} else {
-+		mask = UINT16_MAX;
-+	}
-+
-+	addattr16(n, MAX_MSG, value_type, value);
-+	if (mask_type != TCA_CT_UNSPEC)
-+		addattr16(n, MAX_MSG, mask_type, mask);
-+
-+	return 0;
-+}
-+
-+static int ct_parse_u32(char *str, int value_type, int mask_type,
-+			struct nlmsghdr *n)
-+{
-+	__u32 value, mask;
-+	char *slash;
-+
-+	slash = strchr(str, '/');
-+	if (slash)
-+		*slash = '\0';
-+
-+	if (get_u32(&value, str, 0))
-+		return -1;
-+
-+	if (slash) {
-+		if (get_u32(&mask, slash + 1, 0))
-+			return -1;
-+	} else {
-+		mask = UINT32_MAX;
-+	}
-+
-+	addattr32(n, MAX_MSG, value_type, value);
-+	addattr32(n, MAX_MSG, mask_type, mask);
-+
-+	return 0;
-+}
-+
-+static int ct_parse_mark(char *str, struct nlmsghdr *n)
-+{
-+	return ct_parse_u32(str, TCA_CT_MARK, TCA_CT_MARK_MASK, n);
-+}
-+
-+static int ct_parse_labels(char *str, struct nlmsghdr *n)
-+{
-+#define LABELS_SIZE	16
-+	uint8_t labels[LABELS_SIZE], lmask[LABELS_SIZE];
-+	char *slash, *mask = NULL;
-+	size_t slen, slen_mask = 0;
-+
-+	slash = index(str, '/');
-+	if (slash) {
-+		*slash = 0;
-+		mask = slash+1;
-+		slen_mask = strlen(mask);
-+	}
-+
-+	slen = strlen(str);
-+	if (slen > LABELS_SIZE*2 || slen_mask > LABELS_SIZE*2) {
-+		char errmsg[128];
-+
-+		snprintf(errmsg, sizeof(errmsg),
-+				"%zd Max allowed size %d",
-+				slen, LABELS_SIZE*2);
-+		invarg(errmsg, str);
-+	}
-+
-+	if (hex2mem(str, labels, slen/2) < 0)
-+		invarg("ct: labels must be a hex string\n", str);
-+	addattr_l(n, MAX_MSG, TCA_CT_LABELS, labels, slen/2);
-+
-+	if (mask) {
-+		if (hex2mem(mask, lmask, slen_mask/2) < 0)
-+			invarg("ct: labels mask must be a hex string\n", mask);
-+	} else {
-+		memset(lmask, 0xff, sizeof(lmask));
-+		slen_mask = sizeof(lmask)*2;
-+	}
-+	addattr_l(n, MAX_MSG, TCA_CT_LABELS_MASK, lmask, slen_mask/2);
-+
-+	return 0;
-+}
-+
-+static int
-+parse_ct(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
-+		struct nlmsghdr *n)
-+{
-+	struct tc_ct sel = {};
-+	char **argv = *argv_p;
-+	struct rtattr *tail;
-+	int argc = *argc_p;
-+	int ct_action = 0;
-+	int ret;
-+
-+	tail = addattr_nest(n, MAX_MSG, tca_id);
-+
-+	if (argc && matches(*argv, "ct") == 0)
-+		NEXT_ARG_FWD();
-+
-+	while (argc > 0) {
-+		if (matches(*argv, "zone") == 0) {
-+			NEXT_ARG();
-+
-+			if (ct_parse_u16(*argv,
-+					 TCA_CT_ZONE, TCA_CT_UNSPEC, n)) {
-+				fprintf(stderr, "ct: Illegal \"zone\"\n");
-+				return -1;
-+			}
-+		} else if (matches(*argv, "nat") == 0) {
-+			ct_action |= TCA_CT_ACT_NAT;
-+
-+			NEXT_ARG();
-+			if (matches(*argv, "src") == 0)
-+				ct_action |= TCA_CT_ACT_NAT_SRC;
-+			else if (matches(*argv, "dst") == 0)
-+				ct_action |= TCA_CT_ACT_NAT_DST;
-+			else
-+				continue;
-+
-+			NEXT_ARG();
-+			if (matches(*argv, "addr") != 0)
-+				usage();
-+
-+			NEXT_ARG();
-+			ret = ct_parse_nat_addr_range(*argv, n);
-+			if (ret) {
-+				fprintf(stderr, "ct: Illegal nat address range\n");
-+				return -1;
-+			}
-+
-+			NEXT_ARG_FWD();
-+			if (matches(*argv, "port") != 0)
-+				continue;
-+
-+			NEXT_ARG();
-+			ret = ct_parse_nat_port_range(*argv, n);
-+			if (ret) {
-+				fprintf(stderr, "ct: Illegal nat port range\n");
-+				return -1;
-+			}
-+		} else if (matches(*argv, "clear") == 0) {
-+			ct_action |= TCA_CT_ACT_CLEAR;
-+		} else if (matches(*argv, "commit") == 0) {
-+			ct_action |= TCA_CT_ACT_COMMIT;
-+		} else if (matches(*argv, "force") == 0) {
-+			ct_action |= TCA_CT_ACT_FORCE;
-+		} else if (matches(*argv, "index") == 0) {
-+			NEXT_ARG();
-+			if (get_u32(&sel.index, *argv, 10)) {
-+				fprintf(stderr, "ct: Illegal \"index\"\n");
-+				return -1;
-+			}
-+		} else if (matches(*argv, "mark") == 0) {
-+			NEXT_ARG();
-+
-+			ret = ct_parse_mark(*argv, n);
-+			if (ret) {
-+				fprintf(stderr, "ct: Illegal \"mark\"\n");
-+				return -1;
-+			}
-+		} else if (matches(*argv, "label") == 0) {
-+			NEXT_ARG();
-+
-+			ret = ct_parse_labels(*argv, n);
-+			if (ret) {
-+				fprintf(stderr, "ct: Illegal \"label\"\n");
-+				return -1;
-+			}
-+		} else if (matches(*argv, "help") == 0) {
-+			usage();
-+		} else {
-+			break;
-+		}
-+		NEXT_ARG_FWD();
-+	}
-+
-+	if (ct_action & TCA_CT_ACT_CLEAR &&
-+	    ct_action & ~TCA_CT_ACT_CLEAR) {
-+		fprintf(stderr, "ct: clear can only be used alone\n");
-+		return -1;
-+	}
-+
-+	if (ct_action & TCA_CT_ACT_NAT_SRC &&
-+	    ct_action & TCA_CT_ACT_NAT_DST) {
-+		fprintf(stderr, "ct: src and dst nat can't be used together\n");
-+		return -1;
-+	}
-+
-+	if ((ct_action & TCA_CT_ACT_COMMIT) &&
-+	    (ct_action & TCA_CT_ACT_NAT) &&
-+	    !(ct_action & (TCA_CT_ACT_NAT_SRC | TCA_CT_ACT_NAT_DST))) {
-+		fprintf(stderr, "ct: commit and nat must set src or dst\n");
-+		return -1;
-+	}
-+
-+	if (!(ct_action & TCA_CT_ACT_COMMIT) &&
-+	    (ct_action & (TCA_CT_ACT_NAT_SRC | TCA_CT_ACT_NAT_DST))) {
-+		fprintf(stderr, "ct: src or dst is only valid if commit is set\n");
-+		return -1;
-+	}
-+
-+	parse_action_control_dflt(&argc, &argv, &sel.action, false,
-+				  TC_ACT_PIPE);
-+	NEXT_ARG_FWD();
-+
-+	addattr16(n, MAX_MSG, TCA_CT_ACTION, ct_action);
-+	addattr_l(n, MAX_MSG, TCA_CT_PARMS, &sel, sizeof(sel));
-+	addattr_nest_end(n, tail);
-+
-+	*argc_p = argc;
-+	*argv_p = argv;
-+	return 0;
-+}
-+
-+static int ct_sprint_port(char *buf, const char *prefix, struct rtattr *attr)
-+{
-+	if (!attr)
-+		return 0;
-+
-+	return sprintf(buf, "%s%d", prefix, rta_getattr_be16(attr));
-+}
-+
-+static int ct_sprint_ip_addr(char *buf, const char *prefix,
-+			     struct rtattr *attr)
-+{
-+	int family;
-+	size_t len;
-+
-+	if (!attr)
-+		return 0;
-+
-+	len = RTA_PAYLOAD(attr);
-+
-+	if (len == 4)
-+		family = AF_INET;
-+	else if (len == 16)
-+		family = AF_INET6;
-+	else
-+		return 0;
-+
-+	return sprintf(buf, "%s%s", prefix, rt_addr_n2a_rta(family, attr));
-+}
-+
-+static void ct_print_nat(int ct_action, struct rtattr **tb)
-+{
-+	size_t done = 0;
-+	char out[256] = "";
-+	bool nat;
-+
-+	if (!(ct_action & TCA_CT_ACT_NAT))
-+		return;
-+
-+	if (ct_action & TCA_CT_ACT_NAT_SRC) {
-+		nat = true;
-+		done += sprintf(out + done, "src");
-+	} else if (ct_action & TCA_CT_ACT_NAT_DST) {
-+		nat = true;
-+		done += sprintf(out + done, "dst");
-+	}
-+
-+	if (nat) {
-+		done += ct_sprint_ip_addr(out + done, " addr ",
-+					  tb[TCA_CT_NAT_IPV4_MIN]);
-+		done += ct_sprint_ip_addr(out + done, " addr ",
-+					  tb[TCA_CT_NAT_IPV6_MIN]);
-+		if (tb[TCA_CT_NAT_IPV4_MAX] &&
-+		    memcmp(RTA_DATA(tb[TCA_CT_NAT_IPV4_MIN]),
-+			   RTA_DATA(tb[TCA_CT_NAT_IPV4_MAX]), 4))
-+			done += ct_sprint_ip_addr(out + done, "-",
-+						  tb[TCA_CT_NAT_IPV4_MAX]);
-+		else if (tb[TCA_CT_NAT_IPV6_MAX] &&
-+			    memcmp(RTA_DATA(tb[TCA_CT_NAT_IPV6_MIN]),
-+				   RTA_DATA(tb[TCA_CT_NAT_IPV6_MAX]), 16))
-+			done += ct_sprint_ip_addr(out + done, "-",
-+						  tb[TCA_CT_NAT_IPV6_MAX]);
-+		done += ct_sprint_port(out + done, " port ",
-+				       tb[TCA_CT_NAT_PORT_MIN]);
-+		if (tb[TCA_CT_NAT_PORT_MAX] &&
-+		    memcmp(RTA_DATA(tb[TCA_CT_NAT_PORT_MIN]),
-+			   RTA_DATA(tb[TCA_CT_NAT_PORT_MAX]), 2))
-+			done += ct_sprint_port(out + done, "-",
-+					       tb[TCA_CT_NAT_PORT_MAX]);
-+	}
-+
-+	if (done)
-+		print_string(PRINT_ANY, "nat", " nat %s", out);
-+	else
-+		print_string(PRINT_ANY, "nat", " nat", "");
-+}
-+
-+static void ct_print_labels(struct rtattr *attr,
-+			    struct rtattr *mask_attr)
-+{
-+	const unsigned char *str;
-+	bool print_mask = false;
-+	char out[256], *p;
-+	int data_len, i;
-+
-+	if (!attr)
-+		return;
-+
-+	data_len = RTA_PAYLOAD(attr);
-+	hexstring_n2a(RTA_DATA(attr), data_len, out, sizeof(out));
-+	p = out + data_len*2;
-+
-+	data_len = RTA_PAYLOAD(attr);
-+	str = RTA_DATA(mask_attr);
-+	if (data_len != 16)
-+		print_mask = true;
-+	for (i = 0; !print_mask && i < data_len; i++) {
-+		if (str[i] != 0xff)
-+			print_mask = true;
-+	}
-+	if (print_mask) {
-+		*p++ = '/';
-+		hexstring_n2a(RTA_DATA(mask_attr), data_len, p,
-+			      sizeof(out)-(p-out));
-+		p += data_len*2;
-+	}
-+	*p = '\0';
-+
-+	print_string(PRINT_ANY, "label", " label %s", out);
-+}
-+
-+static int print_ct(struct action_util *au, FILE *f, struct rtattr *arg)
-+{
-+	struct rtattr *tb[TCA_CT_MAX + 1];
-+	const char *commit;
-+	struct tc_ct *p;
-+	int ct_action = 0;
-+
-+	if (arg == NULL)
-+		return -1;
-+
-+	parse_rtattr_nested(tb, TCA_CT_MAX, arg);
-+	if (tb[TCA_CT_PARMS] == NULL) {
-+		print_string(PRINT_FP, NULL, "%s", "[NULL ct parameters]");
-+		return -1;
-+	}
-+
-+	p = RTA_DATA(tb[TCA_CT_PARMS]);
-+
-+	print_string(PRINT_ANY, "kind", "%s", "ct");
-+
-+	if (tb[TCA_CT_ACTION])
-+		ct_action = rta_getattr_u16(tb[TCA_CT_ACTION]);
-+	if (ct_action & TCA_CT_ACT_COMMIT) {
-+		commit = ct_action & TCA_CT_ACT_FORCE ?
-+			 "commit force" : "commit";
-+		print_string(PRINT_ANY, "action", " %s", commit);
-+	} else if (ct_action & TCA_CT_ACT_CLEAR) {
-+		print_string(PRINT_ANY, "action", " %s", "clear");
-+	}
-+
-+	print_masked_u32("mark", tb[TCA_CT_MARK], tb[TCA_CT_MARK_MASK]);
-+	print_masked_u16("zone", tb[TCA_CT_ZONE], NULL);
-+	ct_print_labels(tb[TCA_CT_LABELS], tb[TCA_CT_LABELS_MASK]);
-+	ct_print_nat(ct_action, tb);
-+
-+	print_action_control(f, " ", p->action, "");
-+
-+	print_uint(PRINT_ANY, "index", "\n\t index %u", p->index);
-+	print_int(PRINT_ANY, "ref", " ref %d", p->refcnt);
-+	print_int(PRINT_ANY, "bind", " bind %d", p->bindcnt);
-+
-+	if (show_stats) {
-+		if (tb[TCA_CT_TM]) {
-+			struct tcf_t *tm = RTA_DATA(tb[TCA_CT_TM]);
-+
-+			print_tm(f, tm);
-+		}
-+	}
-+	print_string(PRINT_FP, NULL, "%s", "\n ");
-+
-+	return 0;
-+}
-+
-+struct action_util ct_action_util = {
-+	.id = "ct",
-+	.parse_aopt = parse_ct,
-+	.print_aopt = print_ct,
-+};
-diff --git a/tc/tc_util.c b/tc/tc_util.c
-index b90d256c33a4a..0eb530408d056 100644
---- a/tc/tc_util.c
-+++ b/tc/tc_util.c
-@@ -914,3 +914,47 @@ compat_xstats:
- 	if (tb[TCA_XSTATS] && xstats)
- 		*xstats = tb[TCA_XSTATS];
- }
-+
-+void print_masked_u32(const char *name, struct rtattr *attr,
-+		      struct rtattr *mask_attr)
-+{
-+	__u32 value, mask;
-+	SPRINT_BUF(namefrm);
-+	SPRINT_BUF(out);
-+	size_t done;
-+
-+	if (!attr)
-+		return;
-+
-+	value = rta_getattr_u32(attr);
-+	mask = mask_attr ? rta_getattr_u32(mask_attr) : UINT32_MAX;
-+
-+	done = sprintf(out, "%u", value);
-+	if (mask != UINT32_MAX)
-+		sprintf(out + done, "/0x%x", mask);
-+
-+	sprintf(namefrm, " %s %%s", name);
-+	print_string(PRINT_ANY, name, namefrm, out);
-+}
-+
-+void print_masked_u16(const char *name, struct rtattr *attr,
-+		      struct rtattr *mask_attr)
-+{
-+	__u16 value, mask;
-+	SPRINT_BUF(namefrm);
-+	SPRINT_BUF(out);
-+	size_t done;
-+
-+	if (!attr)
-+		return;
-+
-+	value = rta_getattr_u16(attr);
-+	mask = mask_attr ? rta_getattr_u16(mask_attr) : UINT16_MAX;
-+
-+	done = sprintf(out, "%u", value);
-+	if (mask != UINT16_MAX)
-+		sprintf(out + done, "/0x%x", mask);
-+
-+	sprintf(namefrm, " %s %%s", name);
-+	print_string(PRINT_ANY, name, namefrm, out);
-+}
-diff --git a/tc/tc_util.h b/tc/tc_util.h
-index eb4b60db3fdd7..0c3425abc62fa 100644
---- a/tc/tc_util.h
-+++ b/tc/tc_util.h
-@@ -127,4 +127,8 @@ int action_a2n(char *arg, int *result, bool allow_num);
- 
- bool tc_qdisc_block_exists(__u32 block_index);
- 
-+void print_masked_u32(const char *name, struct rtattr *attr,
-+		      struct rtattr *mask_attr);
-+void print_masked_u16(const char *name, struct rtattr *attr,
-+		      struct rtattr *mask_attr);
- #endif
--- 
-2.26.2
-
diff --git a/SOURCES/0036-tc-flower-Add-matching-on-conntrack-info.patch b/SOURCES/0036-tc-flower-Add-matching-on-conntrack-info.patch
deleted file mode 100644
index 9de9989..0000000
--- a/SOURCES/0036-tc-flower-Add-matching-on-conntrack-info.patch
+++ /dev/null
@@ -1,393 +0,0 @@
-From b60d960c65c6aa5695ecf1c71b18790ca0cb475c Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Tue, 9 Jun 2020 15:45:56 +0200
-Subject: [PATCH] tc: flower: Add matching on conntrack info
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1844637
-Upstream Status: iproute2.git commit 2fffb1c03056e
-
-commit 2fffb1c03056e71d49d623f7ca460883fa6110a6
-Author: Paul Blakey <paulb@mellanox.com>
-Date:   Thu Jul 11 11:14:27 2019 +0300
-
-    tc: flower: Add matching on conntrack info
-
-    Matches on conntrack state, zone, mark, and label.
-
-    Signed-off-by: Paul Blakey <paulb@mellanox.com>
-    Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
-    Signed-off-by: Yossi Kuperman <yossiku@mellanox.com>
-    Acked-by: Jiri Pirko <jiri@mellanox.com>
-    Acked-by: Roi Dayan <roid@mellanox.com>
-    Signed-off-by: David Ahern <dsahern@gmail.com>
----
- man/man8/tc-flower.8 |  35 ++++++
- tc/f_flower.c        | 276 ++++++++++++++++++++++++++++++++++++++++++-
- 2 files changed, 310 insertions(+), 1 deletion(-)
-
-diff --git a/man/man8/tc-flower.8 b/man/man8/tc-flower.8
-index f41b0f7f1ef13..0f95f303f23b7 100644
---- a/man/man8/tc-flower.8
-+++ b/man/man8/tc-flower.8
-@@ -295,6 +295,41 @@ bits is assumed.
- .TQ
- .BI enc_ttl " NUMBER"
- .TQ
-+.BR
-+.TP
-+.BI ct_state " CT_STATE"
-+.TQ
-+.BI ct_zone " CT_MASKED_ZONE"
-+.TQ
-+.BI ct_mark " CT_MASKED_MARK"
-+.TQ
-+.BI ct_label " CT_MASKED_LABEL"
-+Matches on connection tracking info
-+.RS
-+.TP
-+.I CT_STATE
-+Match the connection state, and can ne combination of [{+|-}flag] flags, where flag can be one of
-+.RS
-+.TP
-+trk - Tracked connection.
-+.TP
-+new - New connection.
-+.TP
-+est - Established connection.
-+.TP
-+Example: +trk+est
-+.RE
-+.TP
-+.I CT_MASKED_ZONE
-+Match the connection zone, and can be masked.
-+.TP
-+.I CT_MASKED_MARK
-+32bit match on the connection mark, and can be masked.
-+.TP
-+.I CT_MASKED_LABEL
-+128bit match on the connection label, and can be masked.
-+.RE
-+.TP
- .BI geneve_opts " OPTIONS"
- .TQ
- .BI vxlan_opts " OPTIONS"
-diff --git a/tc/f_flower.c b/tc/f_flower.c
-index 691541ec59d4c..0a6eaa0df94ce 100644
---- a/tc/f_flower.c
-+++ b/tc/f_flower.c
-@@ -84,9 +84,14 @@ static void explain(void)
- 		"			vxlan_opts MASKED-OPTIONS |\n"
- 		"                       erspan_opts MASKED-OPTIONS |\n"
- 		"			ip_flags IP-FLAGS | \n"
--		"			enc_dst_port [ port_number ] }\n"
-+		"			enc_dst_port [ port_number ] |\n"
-+		"			ct_state MASKED_CT_STATE |\n"
-+		"			ct_label MASKED_CT_LABEL |\n"
-+		"			ct_mark MASKED_CT_MARK |\n"
-+		"			ct_zone MASKED_CT_ZONE }\n"
- 		"	FILTERID := X:Y:Z\n"
- 		"	MASKED_LLADDR := { LLADDR | LLADDR/MASK | LLADDR/BITS }\n"
-+		"	MASKED_CT_STATE := combination of {+|-} and flags trk,est,new\n"
- 		"	ACTION-SPEC := ... look at individual actions\n"
- 		"\n"
- 		"NOTE:	CLASSID, IP-PROTO are parsed as hexadecimal input.\n"
-@@ -216,6 +221,159 @@ static int flower_parse_matching_flags(char *str,
- 	return 0;
- }
- 
-+static int flower_parse_u16(char *str, int value_type, int mask_type,
-+			    struct nlmsghdr *n)
-+{
-+	__u16 value, mask;
-+	char *slash;
-+
-+	slash = strchr(str, '/');
-+	if (slash)
-+		*slash = '\0';
-+
-+	if (get_u16(&value, str, 0))
-+		return -1;
-+
-+	if (slash) {
-+		if (get_u16(&mask, slash + 1, 0))
-+			return -1;
-+	} else {
-+		mask = UINT16_MAX;
-+	}
-+
-+	addattr16(n, MAX_MSG, value_type, value);
-+	addattr16(n, MAX_MSG, mask_type, mask);
-+
-+	return 0;
-+}
-+
-+static int flower_parse_u32(char *str, int value_type, int mask_type,
-+			    struct nlmsghdr *n)
-+{
-+	__u32 value, mask;
-+	char *slash;
-+
-+	slash = strchr(str, '/');
-+	if (slash)
-+		*slash = '\0';
-+
-+	if (get_u32(&value, str, 0))
-+		return -1;
-+
-+	if (slash) {
-+		if (get_u32(&mask, slash + 1, 0))
-+			return -1;
-+	} else {
-+		mask = UINT32_MAX;
-+	}
-+
-+	addattr32(n, MAX_MSG, value_type, value);
-+	addattr32(n, MAX_MSG, mask_type, mask);
-+
-+	return 0;
-+}
-+
-+static int flower_parse_ct_mark(char *str, struct nlmsghdr *n)
-+{
-+	return flower_parse_u32(str,
-+				TCA_FLOWER_KEY_CT_MARK,
-+				TCA_FLOWER_KEY_CT_MARK_MASK,
-+				n);
-+}
-+
-+static int flower_parse_ct_zone(char *str, struct nlmsghdr *n)
-+{
-+	return flower_parse_u16(str,
-+				TCA_FLOWER_KEY_CT_ZONE,
-+				TCA_FLOWER_KEY_CT_ZONE_MASK,
-+				n);
-+}
-+
-+static int flower_parse_ct_labels(char *str, struct nlmsghdr *n)
-+{
-+#define LABELS_SIZE	16
-+	uint8_t labels[LABELS_SIZE], lmask[LABELS_SIZE];
-+	char *slash, *mask = NULL;
-+	size_t slen, slen_mask = 0;
-+
-+	slash = index(str, '/');
-+	if (slash) {
-+		*slash = 0;
-+		mask = slash + 1;
-+		slen_mask = strlen(mask);
-+	}
-+
-+	slen = strlen(str);
-+	if (slen > LABELS_SIZE * 2 || slen_mask > LABELS_SIZE * 2) {
-+		char errmsg[128];
-+
-+		snprintf(errmsg, sizeof(errmsg),
-+				"%zd Max allowed size %d",
-+				slen, LABELS_SIZE*2);
-+		invarg(errmsg, str);
-+	}
-+
-+	if (hex2mem(str, labels, slen / 2) < 0)
-+		invarg("labels must be a hex string\n", str);
-+	addattr_l(n, MAX_MSG, TCA_FLOWER_KEY_CT_LABELS, labels, slen / 2);
-+
-+	if (mask) {
-+		if (hex2mem(mask, lmask, slen_mask / 2) < 0)
-+			invarg("labels mask must be a hex string\n", mask);
-+	} else {
-+		memset(lmask, 0xff, sizeof(lmask));
-+		slen_mask = sizeof(lmask) * 2;
-+	}
-+	addattr_l(n, MAX_MSG, TCA_FLOWER_KEY_CT_LABELS_MASK, lmask,
-+		  slen_mask / 2);
-+
-+	return 0;
-+}
-+
-+static struct flower_ct_states {
-+	char *str;
-+	int flag;
-+} flower_ct_states[] = {
-+	{ "trk", TCA_FLOWER_KEY_CT_FLAGS_TRACKED },
-+	{ "new", TCA_FLOWER_KEY_CT_FLAGS_NEW },
-+	{ "est", TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED },
-+};
-+
-+static int flower_parse_ct_state(char *str, struct nlmsghdr *n)
-+{
-+	int flags = 0, mask = 0,  len, i;
-+	bool p;
-+
-+	while (*str != '\0') {
-+		if (*str == '+')
-+			p = true;
-+		else if (*str == '-')
-+			p = false;
-+		else
-+			return -1;
-+
-+		for (i = 0; i < ARRAY_SIZE(flower_ct_states); i++) {
-+			len = strlen(flower_ct_states[i].str);
-+			if (strncmp(str + 1, flower_ct_states[i].str, len))
-+				continue;
-+
-+			if (p)
-+				flags |= flower_ct_states[i].flag;
-+			mask |= flower_ct_states[i].flag;
-+			break;
-+		}
-+
-+		if (i == ARRAY_SIZE(flower_ct_states))
-+			return -1;
-+
-+		str += len + 1;
-+	}
-+
-+	addattr16(n, MAX_MSG, TCA_FLOWER_KEY_CT_STATE, flags);
-+	addattr16(n, MAX_MSG, TCA_FLOWER_KEY_CT_STATE_MASK, mask);
-+	return 0;
-+}
-+
- static int flower_parse_ip_proto(char *str, __be16 eth_type, int type,
- 				 __u8 *p_ip_proto, struct nlmsghdr *n)
- {
-@@ -1077,6 +1235,34 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
- 			flags |= TCA_CLS_FLAGS_SKIP_HW;
- 		} else if (matches(*argv, "skip_sw") == 0) {
- 			flags |= TCA_CLS_FLAGS_SKIP_SW;
-+		} else if (matches(*argv, "ct_state") == 0) {
-+			NEXT_ARG();
-+			ret = flower_parse_ct_state(*argv, n);
-+			if (ret < 0) {
-+				fprintf(stderr, "Illegal \"ct_state\"\n");
-+				return -1;
-+			}
-+		} else if (matches(*argv, "ct_zone") == 0) {
-+			NEXT_ARG();
-+			ret = flower_parse_ct_zone(*argv, n);
-+			if (ret < 0) {
-+				fprintf(stderr, "Illegal \"ct_zone\"\n");
-+				return -1;
-+			}
-+		} else if (matches(*argv, "ct_mark") == 0) {
-+			NEXT_ARG();
-+			ret = flower_parse_ct_mark(*argv, n);
-+			if (ret < 0) {
-+				fprintf(stderr, "Illegal \"ct_mark\"\n");
-+				return -1;
-+			}
-+		} else if (matches(*argv, "ct_label") == 0) {
-+			NEXT_ARG();
-+			ret = flower_parse_ct_labels(*argv, n);
-+			if (ret < 0) {
-+				fprintf(stderr, "Illegal \"ct_label\"\n");
-+				return -1;
-+			}
- 		} else if (matches(*argv, "indev") == 0) {
- 			NEXT_ARG();
- 			if (check_ifname(*argv))
-@@ -1783,6 +1969,85 @@ static void flower_print_tcp_flags(const char *name, struct rtattr *flags_attr,
- 	print_string(PRINT_ANY, name, namefrm, out);
- }
- 
-+static void flower_print_ct_state(struct rtattr *flags_attr,
-+				  struct rtattr *mask_attr)
-+{
-+	SPRINT_BUF(out);
-+	uint16_t state;
-+	uint16_t state_mask;
-+	size_t done = 0;
-+	int i;
-+
-+	if (!flags_attr)
-+		return;
-+
-+	state = rta_getattr_u16(flags_attr);
-+	if (mask_attr)
-+		state_mask = rta_getattr_u16(mask_attr);
-+	else
-+		state_mask = UINT16_MAX;
-+
-+	for (i = 0; i < ARRAY_SIZE(flower_ct_states); i++) {
-+		if (!(state_mask & flower_ct_states[i].flag))
-+			continue;
-+
-+		if (state & flower_ct_states[i].flag)
-+			done += sprintf(out + done, "+%s",
-+					flower_ct_states[i].str);
-+		else
-+			done += sprintf(out + done, "-%s",
-+					flower_ct_states[i].str);
-+	}
-+
-+	print_string(PRINT_ANY, "ct_state", "\n  ct_state %s", out);
-+}
-+
-+static void flower_print_ct_label(struct rtattr *attr,
-+				  struct rtattr *mask_attr)
-+{
-+	const unsigned char *str;
-+	bool print_mask = false;
-+	int data_len, i;
-+	SPRINT_BUF(out);
-+	char *p;
-+
-+	if (!attr)
-+		return;
-+
-+	data_len = RTA_PAYLOAD(attr);
-+	hexstring_n2a(RTA_DATA(attr), data_len, out, sizeof(out));
-+	p = out + data_len*2;
-+
-+	data_len = RTA_PAYLOAD(attr);
-+	str = RTA_DATA(mask_attr);
-+	if (data_len != 16)
-+		print_mask = true;
-+	for (i = 0; !print_mask && i < data_len; i++) {
-+		if (str[i] != 0xff)
-+			print_mask = true;
-+	}
-+	if (print_mask) {
-+		*p++ = '/';
-+		hexstring_n2a(RTA_DATA(mask_attr), data_len, p,
-+			      sizeof(out)-(p-out));
-+		p += data_len*2;
-+	}
-+	*p = '\0';
-+
-+	print_string(PRINT_ANY, "ct_label", "\n  ct_label %s", out);
-+}
-+
-+static void flower_print_ct_zone(struct rtattr *attr,
-+				 struct rtattr *mask_attr)
-+{
-+	print_masked_u16("ct_zone", attr, mask_attr);
-+}
-+
-+static void flower_print_ct_mark(struct rtattr *attr,
-+				 struct rtattr *mask_attr)
-+{
-+	print_masked_u32("ct_mark", attr, mask_attr);
-+}
- 
- static void flower_print_key_id(const char *name, struct rtattr *attr)
- {
-@@ -2218,6 +2483,15 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
- 				    tb[TCA_FLOWER_KEY_FLAGS],
- 				    tb[TCA_FLOWER_KEY_FLAGS_MASK]);
- 
-+	flower_print_ct_state(tb[TCA_FLOWER_KEY_CT_STATE],
-+			      tb[TCA_FLOWER_KEY_CT_STATE_MASK]);
-+	flower_print_ct_zone(tb[TCA_FLOWER_KEY_CT_ZONE],
-+			     tb[TCA_FLOWER_KEY_CT_ZONE_MASK]);
-+	flower_print_ct_mark(tb[TCA_FLOWER_KEY_CT_MARK],
-+			     tb[TCA_FLOWER_KEY_CT_MARK_MASK]);
-+	flower_print_ct_label(tb[TCA_FLOWER_KEY_CT_LABELS],
-+			      tb[TCA_FLOWER_KEY_CT_LABELS_MASK]);
-+
- 	close_json_object();
- 
- 	if (tb[TCA_FLOWER_FLAGS]) {
--- 
-2.26.2
-
diff --git a/SOURCES/0037-man-tc-ct.8-Add-manual-page-for-ct-tc-action.patch b/SOURCES/0037-man-tc-ct.8-Add-manual-page-for-ct-tc-action.patch
deleted file mode 100644
index 5888574..0000000
--- a/SOURCES/0037-man-tc-ct.8-Add-manual-page-for-ct-tc-action.patch
+++ /dev/null
@@ -1,154 +0,0 @@
-From 7c371119412595ad2d063b91fdea616dcacb4eed Mon Sep 17 00:00:00 2001
-From: Andrea Claudi <aclaudi@redhat.com>
-Date: Tue, 9 Jun 2020 15:45:56 +0200
-Subject: [PATCH] man: tc-ct.8: Add manual page for ct tc action
-
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1844637
-Upstream Status: iproute2.git commit 924c43778a845
-
-commit 924c43778a8453e2cd0fd1440b9224bed9c87c0d
-Author: Paul Blakey <paulb@mellanox.com>
-Date:   Thu May 14 17:10:20 2020 +0300
-
-    man: tc-ct.8: Add manual page for ct tc action
-
-    Signed-off-by: Paul Blakey <paulb@mellanox.com>
-    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
----
- man/man8/tc-ct.8     | 107 +++++++++++++++++++++++++++++++++++++++++++
- man/man8/tc-flower.8 |   6 +++
- 2 files changed, 113 insertions(+)
- create mode 100644 man/man8/tc-ct.8
-
-diff --git a/man/man8/tc-ct.8 b/man/man8/tc-ct.8
-new file mode 100644
-index 0000000000000..45d29320f1d01
---- /dev/null
-+++ b/man/man8/tc-ct.8
-@@ -0,0 +1,107 @@
-+.TH "ct action in tc" 8 "14 May 2020" "iproute2" "Linux"
-+.SH NAME
-+ct \- tc connection tracking action
-+.SH SYNOPSIS
-+.in +8
-+.ti -8
-+.BR "tc ... action ct commit [ force ] [ zone "
-+.IR ZONE
-+.BR "] [ mark "
-+.IR MASKED_MARK
-+.BR "] [ label "
-+.IR MASKED_LABEL
-+.BR "] [ nat "
-+.IR NAT_SPEC
-+.BR "]"
-+
-+.ti -8
-+.BR "tc ... action ct [ nat ] [ zone "
-+.IR ZONE
-+.BR "]"
-+
-+.ti -8
-+.BR "tc ... action ct clear"
-+
-+.SH DESCRIPTION
-+The ct action is a tc action for sending packets and interacting with the netfilter conntrack module.
-+
-+It can (as shown in the synopsis, in order):
-+
-+Send the packet to conntrack, and commit the connection, while configuring
-+a 32bit mark, 128bit label, and src/dst nat.
-+
-+Send the packet to conntrack, which will mark the packet with the connection's state and
-+configured metadata (mark/label), and execute previous configured nat.
-+
-+Clear the packet's of previous connection tracking state.
-+
-+.SH OPTIONS
-+.TP
-+.BI zone " ZONE"
-+Specify a conntrack zone number on which to send the packet to conntrack.
-+.TP
-+.BI mark " MASKED_MARK"
-+Specify a masked 32bit mark to set for the connection (only valid with commit).
-+.TP
-+.BI label " MASKED_LABEL"
-+Specify a masked 128bit label to set for the connection (only valid with commit).
-+.TP
-+.BI nat " NAT_SPEC"
-+.BI Where " NAT_SPEC " ":= {src|dst} addr" " addr1" "[-" "addr2" "] [port " "port1" "[-" "port2" "]]"
-+
-+Specify src/dst and range of nat to configure for the connection (only valid with commit).
-+.RS
-+.TP
-+src/dst - configure src or dst nat
-+.TP
-+.BI  "" "addr1" "/" "addr2" " - IPv4/IPv6 addresses"
-+.TP
-+.BI  "" "port1" "/" "port2" " - Port numbers"
-+.RE
-+.TP
-+.BI nat
-+Restore any previous configured nat.
-+.TP
-+.BI clear
-+Remove any conntrack state and metadata (mark/label) from the packet (must only option specified).
-+.TP
-+.BI force
-+Forces conntrack direction for a previously commited connections, so that current direction will become the original direction (only valid with commit).
-+
-+.SH EXAMPLES
-+Example showing natted firewall in conntrack zone 2, and conntrack mark usage:
-+.EX
-+
-+#Add ingress qdisc on eth0 and eth1 interfaces
-+.nf
-+$ tc qdisc add dev eth0 handle ingress
-+$ tc qdisc add dev eth1 handle ingress
-+
-+#Setup filters on eth0, allowing opening new connections in zone 2, and doing src nat + mark for each new connection
-+$ tc filter add dev eth0 ingress prio 1 chain 0 proto ip flower ip_proto tcp ct_state -trk \\
-+action ct zone 2 pipe action goto chain 2
-+$ tc filter add dev eth0 ingress prio 1 chain 2 proto ip flower ct_state +trk+new \\
-+action ct zone 2 commit mark 0xbb nat src addr 5.5.5.7 pipe action mirred egress redirect dev eth1
-+$ tc filter add dev eth0 ingress prio 1 chain 2 proto ip flower ct_zone 2 ct_mark 0xbb ct_state +trk+est \\
-+action ct nat pipe action mirred egress redirect dev eth1
-+
-+#Setup filters on eth1, allowing only established connections of zone 2 through, and reverse nat (dst nat in this case)
-+$ tc filter add dev eth1 ingress prio 1 chain 0 proto ip flower ip_proto tcp ct_state -trk \\
-+action ct zone 2 pipe action goto chain 1
-+$ tc filter add dev eth1 ingress prio 1 chain 1 proto ip flower ct_zone 2 ct_mark 0xbb ct_state +trk+est \\
-+action ct nat pipe action mirred egress redirect dev eth0
-+.fi
-+
-+.EE
-+
-+.RE
-+.SH SEE ALSO
-+.BR tc (8),
-+.BR tc-flower (8)
-+.BR tc-mirred (8)
-+.SH AUTHORS
-+Paul Blakey <paulb@mellanox.com>
-+
-+Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
-+
-+Yossi Kuperman <yossiku@mellanox.com>
-diff --git a/man/man8/tc-flower.8 b/man/man8/tc-flower.8
-index 0f95f303f23b7..02a7256f36ebb 100644
---- a/man/man8/tc-flower.8
-+++ b/man/man8/tc-flower.8
-@@ -1,5 +1,11 @@
- .TH "Flower filter in tc" 8 "22 Oct 2015" "iproute2" "Linux"
- 
-+	"Usage: ct clear\n"
-+		"	ct commit [force] [zone ZONE] [mark MASKED_MARK] [label MASKED_LABEL] [nat NAT_SPEC] [OFFLOAD_POLICY]\n"
-+		"	ct [nat] [zone ZONE] [OFFLOAD_POLICY]\n"
-+		"Where: ZONE is the conntrack zone table number\n"
-+		"	NAT_SPEC is {src|dst} addr addr1[-addr2] [port port1[-port2]]\n"
-+		"	OFFLOAD_POLICY is [policy_pkts PACKETS] [policy_timeout TIMEOUT]\n"
- .SH NAME
- flower \- flow based traffic control filter
- .SH SYNOPSIS
--- 
-2.26.2
-
diff --git a/SOURCES/avpkt b/SOURCES/avpkt
deleted file mode 100644
index c362b94..0000000
--- a/SOURCES/avpkt
+++ /dev/null
@@ -1 +0,0 @@
-AVPKT=3000
diff --git a/SOURCES/cbq-0000.example b/SOURCES/cbq-0000.example
deleted file mode 100644
index 5503374..0000000
--- a/SOURCES/cbq-0000.example
+++ /dev/null
@@ -1,5 +0,0 @@
-DEVICE=eth0,10Mbit,1Mbit
-RATE=128Kbit
-WEIGHT=10Kbit
-PRIO=5
-RULE=192.168.1.0/24
diff --git a/SPECS/iproute.spec b/SPECS/iproute.spec
index 9c2fe0a..6ef0b52 100644
--- a/SPECS/iproute.spec
+++ b/SPECS/iproute.spec
@@ -1,5 +1,5 @@
-%define rpmversion 5.3.0
-%define specrelease 5%{?dist}
+%define rpmversion 5.9.0
+%define specrelease 4%{?dist}
 %define pkg_release %{specrelease}%{?buildid}
 
 Summary:            Advanced IP routing and network device configuration tools
@@ -9,46 +9,17 @@ Release:            %{pkg_release}
 Group:              Applications/System
 URL:                http://kernel.org/pub/linux/utils/net/%{name}2/
 Source0:            http://kernel.org/pub/linux/utils/net/%{name}2/%{name}2-%{version}.tar.xz
-Source1:            cbq-0000.example
-Source2:            avpkt
-Source3:            rt_dsfield.deprecated
-Patch0:             0001-Update-kernel-headers.patch
+Source1:            rt_dsfield.deprecated
+Patch0:             0001-v5.9.0.patch
 Patch1:             0002-Update-kernel-headers.patch
-Patch2:             0003-tc-implement-support-for-action-flags.patch
-Patch3:             0004-man-rdma-statistic-Add-filter-description.patch
-Patch4:             0005-man-rdma.8-Add-missing-resource-subcommand-descripti.patch
-Patch5:             0006-ip-xfrm-Fix-help-messages.patch
-Patch6:             0007-xfrm-not-try-to-delete-ipcomp-states-when-using-dele.patch
-Patch7:             0008-man-ip.8-Add-missing-vrf-subcommand-description.patch
-Patch8:             0009-nstat-print-useful-error-messages-in-abort-cases.patch
-Patch9:             0010-ip-link-xstats-fix-TX-IGMP-reports-string.patch
-Patch10:            0011-ip-fix-ip-route-show-json-output-for-multipath-nexth.patch
-Patch11:            0012-man-bridge.8-fix-bridge-link-show-description.patch
-Patch12:            0013-xfrm-also-check-for-ipv6-state-in-xfrm_state_keep.patch
-Patch13:            0014-Update-kernel-headers-and-import-udp.h.patch
-Patch14:            0015-ip-xfrm-add-espintcp-encapsulation.patch
-Patch15:            0016-Update-kernel-headers-and-import-mptcp.h.patch
-Patch16:            0017-add-support-for-mptcp-netlink-interface.patch
-Patch17:            0018-Update-kernel-headers.patch
-Patch18:            0019-Update-kernel-headers.patch
-Patch19:            0020-ss-allow-dumping-MPTCP-subflow-information.patch
-Patch20:            0021-man-mptcp-man-page.patch
-Patch21:            0022-man-ip.8-add-reference-to-mptcp-man-page.patch
-Patch22:            0023-Update-kernel-headers.patch
-Patch23:            0024-iproute_lwtunnel-add-options-support-for-geneve-meta.patch
-Patch24:            0025-iproute_lwtunnel-add-options-support-for-vxlan-metad.patch
-Patch25:            0026-iproute_lwtunnel-add-options-support-for-erspan-meta.patch
-Patch26:            0027-tc-m_tunnel_key-add-options-support-for-vxlan.patch
-Patch27:            0028-tc-m_tunnel_key-add-options-support-for-erpsan.patch
-Patch28:            0029-tc-f_flower-add-options-support-for-vxlan.patch
-Patch29:            0030-tc-f_flower-add-options-support-for-erspan.patch
-Patch30:            0031-devlink-Add-health-error-recovery-status-monitoring.patch
-Patch31:            0032-ss-allow-dumping-kTLS-info.patch
-Patch32:            0033-Import-tc_act-tc_ct.h-uapi-file.patch
-Patch33:            0034-tc-add-NLA_F_NESTED-flag-to-all-actions-options-nest.patch
-Patch34:            0035-tc-Introduce-tc-ct-action.patch
-Patch35:            0036-tc-flower-Add-matching-on-conntrack-info.patch
-Patch36:            0037-man-tc-ct.8-Add-manual-page-for-ct-tc-action.patch
+Patch2:             0003-m_vlan-add-pop_eth-and-push_eth-actions.patch
+Patch3:             0004-m_mpls-add-mac_push-action.patch
+Patch4:             0005-m_mpls-test-the-mac_push-action-after-modify.patch
+Patch5:             0006-tc-vlan-fix-help-and-error-message-strings.patch
+Patch6:             0007-tc-mpls-fix-manpage-example-and-help-message-string.patch
+Patch7:             0008-tc-flower-fix-json-output-with-mpls-lse.patch
+Patch8:             0009-iproute-force-rtm_dst_len-to-32-128.patch
+Patch9:             0010-iplink_bareudp-cleanup-help-message-and-man-page.patch
 License:            GPLv2+ and Public Domain
 BuildRequires:      bison
 BuildRequires:      elfutils-libelf-devel
@@ -127,16 +98,8 @@ export CONFDIR='%{_sysconfdir}/iproute2'
 export DOCDIR='%{_docdir}'
 %make_install
 
-install -m755 examples/cbqinit.eth1 ${DESTDIR}/${SBINDIR}/cbq
 echo '.so man8/tc-cbq.8' > %{buildroot}%{_mandir}/man8/cbq.8
 
-install -d -m755 %{buildroot}%{_sysconfdir}/sysconfig/cbq
-for config in \
-    %{SOURCE1} \
-    %{SOURCE2}
-    do install -m644 ${config} %{buildroot}%{_sysconfdir}/sysconfig/cbq
-done
-
 # libnetlink
 install -D -m644 include/libnetlink.h %{buildroot}%{_includedir}/libnetlink.h
 install -D -m644 lib/libnetlink.a %{buildroot}%{_libdir}/libnetlink.a
@@ -145,13 +108,13 @@ install -D -m644 lib/libnetlink.a %{buildroot}%{_libdir}/libnetlink.a
 rm -rf '%{buildroot}%{_docdir}'
 
 # Append deprecated values to rt_dsfield for compatibility reasons
-cat %{SOURCE3} >>%{buildroot}%{_sysconfdir}/iproute2/rt_dsfield
+cat %{SOURCE1} >>%{buildroot}%{_sysconfdir}/iproute2/rt_dsfield
 
 %files
 %dir %{_sysconfdir}/iproute2
 %{!?_licensedir:%global license %%doc}
 %license COPYING
-%doc README README.iproute2+tc README.distribution README.lnstat
+%doc README README.devel
 %{_mandir}/man7/*
 %exclude %{_mandir}/man7/tc-*
 %{_mandir}/man8/*
@@ -160,21 +123,17 @@ cat %{SOURCE3} >>%{buildroot}%{_sysconfdir}/iproute2/rt_dsfield
 %attr(644,root,root) %config(noreplace) %{_sysconfdir}/iproute2/*
 %{_sbindir}/*
 %exclude %{_sbindir}/tc
-%exclude %{_sbindir}/cbq
+%{_datadir}/bash-completion/completions/devlink
 
 %files tc
 %{!?_licensedir:%global license %%doc}
 %license COPYING
-%doc README.iproute2+tc
 %{_mandir}/man7/tc-*
 %{_mandir}/man8/tc*
 %{_mandir}/man8/cbq*
 %dir %{_libdir}/tc/
 %{_libdir}/tc/*
 %{_sbindir}/tc
-%{_sbindir}/cbq
-%dir %{_sysconfdir}/sysconfig/cbq
-%config(noreplace) %{_sysconfdir}/sysconfig/cbq/*
 %{_datadir}/bash-completion/completions/tc
 
 %if ! 0%{?_module_build}
@@ -193,6 +152,24 @@ cat %{SOURCE3} >>%{buildroot}%{_sysconfdir}/iproute2/rt_dsfield
 %{_includedir}/iproute2/bpf_elf.h
 
 %changelog
+* Fri Mar 12 2021 Andrea Claudi <aclaudi@redhat.com> [5.9.0-4.el8]
+- iplink_bareudp: cleanup help message and man page (Andrea Claudi) [1912412]
+
+* Tue Feb 09 2021 Andrea Claudi <aclaudi@redhat.com> [5.9.0-3.el8]
+- iproute: force rtm_dst_len to 32/128 (Andrea Claudi) [1852038]
+
+* Thu Jan 28 2021 Andrea Claudi <aclaudi@redhat.com> [5.9.0-2.el8]
+- tc: flower: fix json output with mpls lse (Andrea Claudi) [1885770]
+- tc-mpls: fix manpage example and help message string (Andrea Claudi) [1885770]
+- tc-vlan: fix help and error message strings (Andrea Claudi) [1885770]
+- m_mpls: test the 'mac_push' action after 'modify' (Andrea Claudi) [1885770]
+- m_mpls: add mac_push action (Andrea Claudi) [1885770]
+- m_vlan: add pop_eth and push_eth actions (Andrea Claudi) [1885770]
+- Update kernel headers (Andrea Claudi) [1885770]
+
+* Tue Nov 17 2020 Andrea Claudi <aclaudi@redhat.com> [5.9.0-1.el8]
+- Rebase iproute to v5.9.0 [1896011]
+
 * Mon Jun 29 2020 Andrea Claudi <aclaudi@redhat.com> [5.3.0-5.el8]
 - man: tc-ct.8: Add manual page for ct tc action (Andrea Claudi) [1844637]
 - tc: flower: Add matching on conntrack info (Andrea Claudi) [1844637]