import iproute-5.9.0-3.el8

This commit is contained in:
CentOS Sources 2021-03-30 09:57:50 -04:00 committed by Stepan Oksanichenko
parent f1046a6991
commit 19bf5d4957
50 changed files with 1397 additions and 6988 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/iproute2-5.3.0.tar.xz
SOURCES/iproute2-5.9.0.tar.xz

View File

@ -1 +1 @@
fb5e623678688304a42d29d27d22287dcca12135 SOURCES/iproute2-5.3.0.tar.xz
c9e0ca453307ce7c221ccffc10939f4136b4ad5d SOURCES/iproute2-5.9.0.tar.xz

View File

@ -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

20
SOURCES/0001-v5.9.0.patch Normal file
View File

@ -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

View File

@ -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 */
};
@@ -404,6 +404,9 @@ enum {
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.
*/
#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 TCA_ACT_FLAGS_NO_PERCPU_STATS 1 /* Don't use percpu allocator for
+ * actions stats.
+ */
/* Enable memory-mapping BPF map */
BPF_F_MMAPABLE = (1U << 10),
+
#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,
+/* Share perf_event among processes */
+ BPF_F_PRESERVE_ELEMS = (1U << 11),
};
+/* 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 */
/* Flags for BPF_PROG_QUERY. */
@@ -414,6 +417,11 @@ enum {
*/
#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 */
};
+/*
+ * 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. */
+};
+
/* 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;
+/*
+ * 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_
__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 */
+#include <linux/const.h>
+
#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.
+ */
};
/*
* Flag values
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,
};
+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
+};
+
#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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1 +0,0 @@
AVPKT=3000

View File

@ -1,5 +0,0 @@
DEVICE=eth0,10Mbit,1Mbit
RATE=128Kbit
WEIGHT=10Kbit
PRIO=5
RULE=192.168.1.0/24

View File

@ -1,5 +1,5 @@
%define rpmversion 5.3.0
%define specrelease 5%{?dist}
%define rpmversion 5.9.0
%define specrelease 3%{?dist}
%define pkg_release %{specrelease}%{?buildid}
Summary: Advanced IP routing and network device configuration tools
@ -9,46 +9,16 @@ 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
License: GPLv2+ and Public Domain
BuildRequires: bison
BuildRequires: elfutils-libelf-devel
@ -127,16 +97,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 +107,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 +122,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 +151,21 @@ cat %{SOURCE3} >>%{buildroot}%{_sysconfdir}/iproute2/rt_dsfield
%{_includedir}/iproute2/bpf_elf.h
%changelog
* 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]