import iproute-5.9.0-3.el8
This commit is contained in:
parent
f1046a6991
commit
19bf5d4957
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
||||
SOURCES/iproute2-5.3.0.tar.xz
|
||||
SOURCES/iproute2-5.9.0.tar.xz
|
||||
|
@ -1 +1 @@
|
||||
fb5e623678688304a42d29d27d22287dcca12135 SOURCES/iproute2-5.3.0.tar.xz
|
||||
c9e0ca453307ce7c221ccffc10939f4136b4ad5d SOURCES/iproute2-5.9.0.tar.xz
|
||||
|
@ -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
20
SOURCES/0001-v5.9.0.patch
Normal 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
|
||||
|
@ -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
|
||||
|
||||
|
343
SOURCES/0003-m_vlan-add-pop_eth-and-push_eth-actions.patch
Normal file
343
SOURCES/0003-m_vlan-add-pop_eth-and-push_eth-actions.patch
Normal 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
|
||||
|
@ -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
|
||||
|
342
SOURCES/0004-m_mpls-add-mac_push-action.patch
Normal file
342
SOURCES/0004-m_mpls-add-mac_push-action.patch
Normal 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
120
SOURCES/0008-tc-flower-fix-json-output-with-mpls-lse.patch
Normal file
120
SOURCES/0008-tc-flower-fix-json-output-with-mpls-lse.patch
Normal 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
|
||||
|
67
SOURCES/0009-iproute-force-rtm_dst_len-to-32-128.patch
Normal file
67
SOURCES/0009-iproute-force-rtm_dst_len-to-32-128.patch
Normal 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -1 +0,0 @@
|
||||
AVPKT=3000
|
@ -1,5 +0,0 @@
|
||||
DEVICE=eth0,10Mbit,1Mbit
|
||||
RATE=128Kbit
|
||||
WEIGHT=10Kbit
|
||||
PRIO=5
|
||||
RULE=192.168.1.0/24
|
@ -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]
|
||||
|
Loading…
Reference in New Issue
Block a user