Merge ../iproute2-next

This commit is contained in:
Stephen Hemminger 2019-05-10 08:55:11 -07:00
commit f9e2cf35eb
34 changed files with 1218 additions and 62 deletions

8
.mailmap Normal file
View File

@ -0,0 +1,8 @@
#
# This list is used by git-shortlog to fix a few botched name translations
# in the git archive, either because the author's full name was messed up
# and/or not always written the same way, making contributions from the
# same person appearing not to be so or badly displayed.
#
Steve Wise <larrystevenwise@gmail.com> <swise@opengridcomputing.com>
Steve Wise <larrystevenwise@gmail.com> <swise@chelsio.com>

View File

@ -3422,7 +3422,7 @@ static void pr_out_occ_show_item_list(const char *label, struct list_head *list,
occ_item->bound_pool_index); occ_item->bound_pool_index);
else else
pr_out_sp(7, "%2u:", occ_item->index); pr_out_sp(7, "%2u:", occ_item->index);
pr_out_sp(15, "%7u/%u", occ_item->cur, occ_item->max); pr_out_sp(21, "%10u/%u", occ_item->cur, occ_item->max);
if (i++ % 4 == 0) if (i++ % 4 == 0)
pr_out("\n"); pr_out("\n");
} }

View File

@ -105,6 +105,7 @@ enum bpf_cmd {
BPF_BTF_GET_FD_BY_ID, BPF_BTF_GET_FD_BY_ID,
BPF_TASK_FD_QUERY, BPF_TASK_FD_QUERY,
BPF_MAP_LOOKUP_AND_DELETE_ELEM, BPF_MAP_LOOKUP_AND_DELETE_ELEM,
BPF_MAP_FREEZE,
}; };
enum bpf_map_type { enum bpf_map_type {
@ -132,6 +133,7 @@ enum bpf_map_type {
BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE, BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE,
BPF_MAP_TYPE_QUEUE, BPF_MAP_TYPE_QUEUE,
BPF_MAP_TYPE_STACK, BPF_MAP_TYPE_STACK,
BPF_MAP_TYPE_SK_STORAGE,
}; };
/* Note that tracing related programs such as /* Note that tracing related programs such as
@ -166,6 +168,8 @@ enum bpf_prog_type {
BPF_PROG_TYPE_LIRC_MODE2, BPF_PROG_TYPE_LIRC_MODE2,
BPF_PROG_TYPE_SK_REUSEPORT, BPF_PROG_TYPE_SK_REUSEPORT,
BPF_PROG_TYPE_FLOW_DISSECTOR, BPF_PROG_TYPE_FLOW_DISSECTOR,
BPF_PROG_TYPE_CGROUP_SYSCTL,
BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE,
}; };
enum bpf_attach_type { enum bpf_attach_type {
@ -187,6 +191,7 @@ enum bpf_attach_type {
BPF_CGROUP_UDP6_SENDMSG, BPF_CGROUP_UDP6_SENDMSG,
BPF_LIRC_MODE2, BPF_LIRC_MODE2,
BPF_FLOW_DISSECTOR, BPF_FLOW_DISSECTOR,
BPF_CGROUP_SYSCTL,
__MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE
}; };
@ -255,8 +260,19 @@ enum bpf_attach_type {
*/ */
#define BPF_F_ANY_ALIGNMENT (1U << 1) #define BPF_F_ANY_ALIGNMENT (1U << 1)
/* when bpf_ldimm64->src_reg == BPF_PSEUDO_MAP_FD, bpf_ldimm64->imm == fd */ /* When BPF ldimm64's insn[0].src_reg != 0 then this can have
* two extensions:
*
* insn[0].src_reg: BPF_PSEUDO_MAP_FD BPF_PSEUDO_MAP_VALUE
* insn[0].imm: map fd map fd
* insn[1].imm: 0 offset into value
* insn[0].off: 0 0
* insn[1].off: 0 0
* ldimm64 rewrite: address of map address of map[0]+offset
* verifier type: CONST_PTR_TO_MAP PTR_TO_MAP_VALUE
*/
#define BPF_PSEUDO_MAP_FD 1 #define BPF_PSEUDO_MAP_FD 1
#define BPF_PSEUDO_MAP_VALUE 2
/* when bpf_call->src_reg == BPF_PSEUDO_CALL, bpf_call->imm == pc-relative /* when bpf_call->src_reg == BPF_PSEUDO_CALL, bpf_call->imm == pc-relative
* offset to another bpf function * offset to another bpf function
@ -283,7 +299,7 @@ enum bpf_attach_type {
#define BPF_OBJ_NAME_LEN 16U #define BPF_OBJ_NAME_LEN 16U
/* Flags for accessing BPF object */ /* Flags for accessing BPF object from syscall side. */
#define BPF_F_RDONLY (1U << 3) #define BPF_F_RDONLY (1U << 3)
#define BPF_F_WRONLY (1U << 4) #define BPF_F_WRONLY (1U << 4)
@ -293,6 +309,10 @@ enum bpf_attach_type {
/* Zero-initialize hash function seed. This should only be used for testing. */ /* Zero-initialize hash function seed. This should only be used for testing. */
#define BPF_F_ZERO_SEED (1U << 6) #define BPF_F_ZERO_SEED (1U << 6)
/* Flags for accessing BPF object from program side. */
#define BPF_F_RDONLY_PROG (1U << 7)
#define BPF_F_WRONLY_PROG (1U << 8)
/* flags for BPF_PROG_QUERY */ /* flags for BPF_PROG_QUERY */
#define BPF_F_QUERY_EFFECTIVE (1U << 0) #define BPF_F_QUERY_EFFECTIVE (1U << 0)
@ -396,6 +416,13 @@ union bpf_attr {
__aligned_u64 data_out; __aligned_u64 data_out;
__u32 repeat; __u32 repeat;
__u32 duration; __u32 duration;
__u32 ctx_size_in; /* input: len of ctx_in */
__u32 ctx_size_out; /* input/output: len of ctx_out
* returns ENOSPC if ctx_out
* is too small.
*/
__aligned_u64 ctx_in;
__aligned_u64 ctx_out;
} test; } test;
struct { /* anonymous struct used by BPF_*_GET_*_ID */ struct { /* anonymous struct used by BPF_*_GET_*_ID */
@ -1478,13 +1505,31 @@ union bpf_attr {
* Grow or shrink the room for data in the packet associated to * Grow or shrink the room for data in the packet associated to
* *skb* by *len_diff*, and according to the selected *mode*. * *skb* by *len_diff*, and according to the selected *mode*.
* *
* There is a single supported mode at this time: * There are two supported modes at this time:
*
* * **BPF_ADJ_ROOM_MAC**: Adjust room at the mac layer
* (room space is added or removed below the layer 2 header).
* *
* * **BPF_ADJ_ROOM_NET**: Adjust room at the network layer * * **BPF_ADJ_ROOM_NET**: Adjust room at the network layer
* (room space is added or removed below the layer 3 header). * (room space is added or removed below the layer 3 header).
* *
* All values for *flags* are reserved for future usage, and must * The following flags are supported at this time:
* be left at zero. *
* * **BPF_F_ADJ_ROOM_FIXED_GSO**: Do not adjust gso_size.
* Adjusting mss in this way is not allowed for datagrams.
*
* * **BPF_F_ADJ_ROOM_ENCAP_L3_IPV4 **:
* * **BPF_F_ADJ_ROOM_ENCAP_L3_IPV6 **:
* Any new space is reserved to hold a tunnel header.
* Configure skb offsets and other fields accordingly.
*
* * **BPF_F_ADJ_ROOM_ENCAP_L4_GRE **:
* * **BPF_F_ADJ_ROOM_ENCAP_L4_UDP **:
* Use with ENCAP_L3 flags to further specify the tunnel type.
*
* * **BPF_F_ADJ_ROOM_ENCAP_L2(len) **:
* Use with ENCAP_L3/L4 flags to further specify the tunnel
* type; **len** is the length of the inner MAC header.
* *
* A call to this helper is susceptible to change the underlaying * A call to this helper is susceptible to change the underlaying
* packet buffer. Therefore, at load time, all checks on pointers * packet buffer. Therefore, at load time, all checks on pointers
@ -1694,12 +1739,19 @@ union bpf_attr {
* error if an eBPF program tries to set a callback that is not * error if an eBPF program tries to set a callback that is not
* supported in the current kernel. * supported in the current kernel.
* *
* The supported callback values that *argval* can combine are: * *argval* is a flag array which can combine these flags:
* *
* * **BPF_SOCK_OPS_RTO_CB_FLAG** (retransmission time out) * * **BPF_SOCK_OPS_RTO_CB_FLAG** (retransmission time out)
* * **BPF_SOCK_OPS_RETRANS_CB_FLAG** (retransmission) * * **BPF_SOCK_OPS_RETRANS_CB_FLAG** (retransmission)
* * **BPF_SOCK_OPS_STATE_CB_FLAG** (TCP state change) * * **BPF_SOCK_OPS_STATE_CB_FLAG** (TCP state change)
* *
* Therefore, this function can be used to clear a callback flag by
* setting the appropriate bit to zero. e.g. to disable the RTO
* callback:
*
* **bpf_sock_ops_cb_flags_set(bpf_sock,**
* **bpf_sock->bpf_sock_ops_cb_flags & ~BPF_SOCK_OPS_RTO_CB_FLAG)**
*
* Here are some examples of where one could call such eBPF * Here are some examples of where one could call such eBPF
* program: * program:
* *
@ -2431,6 +2483,190 @@ union bpf_attr {
* Return * Return
* A **struct bpf_sock** pointer on success, or **NULL** in * A **struct bpf_sock** pointer on success, or **NULL** in
* case of failure. * case of failure.
*
* struct bpf_sock *bpf_skc_lookup_tcp(void *ctx, struct bpf_sock_tuple *tuple, u32 tuple_size, u64 netns, u64 flags)
* Description
* Look for TCP socket matching *tuple*, optionally in a child
* network namespace *netns*. The return value must be checked,
* and if non-**NULL**, released via **bpf_sk_release**\ ().
*
* This function is identical to bpf_sk_lookup_tcp, except that it
* also returns timewait or request sockets. Use bpf_sk_fullsock
* or bpf_tcp_socket to access the full structure.
*
* This helper is available only if the kernel was compiled with
* **CONFIG_NET** configuration option.
* Return
* Pointer to **struct bpf_sock**, or **NULL** in case of failure.
* For sockets with reuseport option, the **struct bpf_sock**
* result is from **reuse->socks**\ [] using the hash of the tuple.
*
* int bpf_tcp_check_syncookie(struct bpf_sock *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.
*
* 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
* sizeof(struct tcphdr).
*
* Return
* 0 if iph and th are a valid SYN cookie ACK, or a negative error
* otherwise.
*
* int bpf_sysctl_get_name(struct bpf_sysctl *ctx, char *buf, size_t buf_len, u64 flags)
* Description
* Get name of sysctl in /proc/sys/ and copy it into provided by
* program buffer *buf* of size *buf_len*.
*
* The buffer is always NUL terminated, unless it's zero-sized.
*
* If *flags* is zero, full name (e.g. "net/ipv4/tcp_mem") is
* copied. Use **BPF_F_SYSCTL_BASE_NAME** flag to copy base name
* only (e.g. "tcp_mem").
* Return
* Number of character copied (not including the trailing NUL).
*
* **-E2BIG** if the buffer wasn't big enough (*buf* will contain
* truncated name in this case).
*
* int bpf_sysctl_get_current_value(struct bpf_sysctl *ctx, char *buf, size_t buf_len)
* Description
* Get current value of sysctl as it is presented in /proc/sys
* (incl. newline, etc), and copy it as a string into provided
* by program buffer *buf* of size *buf_len*.
*
* The whole value is copied, no matter what file position user
* space issued e.g. sys_read at.
*
* The buffer is always NUL terminated, unless it's zero-sized.
* Return
* Number of character copied (not including the trailing NUL).
*
* **-E2BIG** if the buffer wasn't big enough (*buf* will contain
* truncated name in this case).
*
* **-EINVAL** if current value was unavailable, e.g. because
* sysctl is uninitialized and read returns -EIO for it.
*
* int bpf_sysctl_get_new_value(struct bpf_sysctl *ctx, char *buf, size_t buf_len)
* Description
* Get new value being written by user space to sysctl (before
* the actual write happens) and copy it as a string into
* provided by program buffer *buf* of size *buf_len*.
*
* User space may write new value at file position > 0.
*
* The buffer is always NUL terminated, unless it's zero-sized.
* Return
* Number of character copied (not including the trailing NUL).
*
* **-E2BIG** if the buffer wasn't big enough (*buf* will contain
* truncated name in this case).
*
* **-EINVAL** if sysctl is being read.
*
* int bpf_sysctl_set_new_value(struct bpf_sysctl *ctx, const char *buf, size_t buf_len)
* Description
* Override new value being written by user space to sysctl with
* value provided by program in buffer *buf* of size *buf_len*.
*
* *buf* should contain a string in same form as provided by user
* space on sysctl write.
*
* User space may write new value at file position > 0. To override
* the whole sysctl value file position should be set to zero.
* Return
* 0 on success.
*
* **-E2BIG** if the *buf_len* is too big.
*
* **-EINVAL** if sysctl is being read.
*
* int bpf_strtol(const char *buf, size_t buf_len, u64 flags, long *res)
* Description
* Convert the initial part of the string from buffer *buf* of
* size *buf_len* to a long integer according to the given base
* and save the result in *res*.
*
* The string may begin with an arbitrary amount of white space
* (as determined by isspace(3)) followed by a single optional '-'
* sign.
*
* Five least significant bits of *flags* encode base, other bits
* are currently unused.
*
* Base must be either 8, 10, 16 or 0 to detect it automatically
* similar to user space strtol(3).
* Return
* Number of characters consumed on success. Must be positive but
* no more than buf_len.
*
* **-EINVAL** if no valid digits were found or unsupported base
* was provided.
*
* **-ERANGE** if resulting value was out of range.
*
* int bpf_strtoul(const char *buf, size_t buf_len, u64 flags, unsigned long *res)
* Description
* Convert the initial part of the string from buffer *buf* of
* size *buf_len* to an unsigned long integer according to the
* given base and save the result in *res*.
*
* The string may begin with an arbitrary amount of white space
* (as determined by isspace(3)).
*
* Five least significant bits of *flags* encode base, other bits
* are currently unused.
*
* Base must be either 8, 10, 16 or 0 to detect it automatically
* similar to user space strtoul(3).
* Return
* Number of characters consumed on success. Must be positive but
* no more than buf_len.
*
* **-EINVAL** if no valid digits were found or unsupported base
* was provided.
*
* **-ERANGE** if resulting value was out of range.
*
* void *bpf_sk_storage_get(struct bpf_map *map, struct bpf_sock *sk, void *value, u64 flags)
* Description
* Get a bpf-local-storage from a sk.
*
* Logically, it could be thought of getting the value from
* a *map* with *sk* as the **key**. From this
* perspective, the usage is not much different from
* **bpf_map_lookup_elem(map, &sk)** except this
* helper enforces the key must be a **bpf_fullsock()**
* and the map must be a BPF_MAP_TYPE_SK_STORAGE also.
*
* Underneath, the value is stored locally at *sk* instead of
* the map. The *map* is used as the bpf-local-storage **type**.
* The bpf-local-storage **type** (i.e. the *map*) is searched
* against all bpf-local-storages residing at sk.
*
* An optional *flags* (BPF_SK_STORAGE_GET_F_CREATE) can be
* used such that a new bpf-local-storage will be
* created if one does not exist. *value* can be used
* together with BPF_SK_STORAGE_GET_F_CREATE to specify
* the initial value of a bpf-local-storage. If *value* is
* NULL, the new bpf-local-storage will be zero initialized.
* Return
* A bpf-local-storage pointer is returned on success.
*
* **NULL** if not found or there was an error in adding
* a new bpf-local-storage.
*
* int bpf_sk_storage_delete(struct bpf_map *map, struct bpf_sock *sk)
* Description
* Delete a bpf-local-storage from a sk.
* Return
* 0 on success.
*
* **-ENOENT** if the bpf-local-storage cannot be found.
*/ */
#define __BPF_FUNC_MAPPER(FN) \ #define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \ FN(unspec), \
@ -2531,7 +2767,17 @@ union bpf_attr {
FN(sk_fullsock), \ FN(sk_fullsock), \
FN(tcp_sock), \ FN(tcp_sock), \
FN(skb_ecn_set_ce), \ FN(skb_ecn_set_ce), \
FN(get_listener_sock), FN(get_listener_sock), \
FN(skc_lookup_tcp), \
FN(tcp_check_syncookie), \
FN(sysctl_get_name), \
FN(sysctl_get_current_value), \
FN(sysctl_get_new_value), \
FN(sysctl_set_new_value), \
FN(strtol), \
FN(strtoul), \
FN(sk_storage_get), \
FN(sk_storage_delete),
/* integer value in 'imm' field of BPF_CALL instruction selects which helper /* integer value in 'imm' field of BPF_CALL instruction selects which helper
* function eBPF program intends to call * function eBPF program intends to call
@ -2590,9 +2836,30 @@ enum bpf_func_id {
/* Current network namespace */ /* Current network namespace */
#define BPF_F_CURRENT_NETNS (-1L) #define BPF_F_CURRENT_NETNS (-1L)
/* BPF_FUNC_skb_adjust_room flags. */
#define BPF_F_ADJ_ROOM_FIXED_GSO (1ULL << 0)
#define BPF_ADJ_ROOM_ENCAP_L2_MASK 0xff
#define BPF_ADJ_ROOM_ENCAP_L2_SHIFT 56
#define BPF_F_ADJ_ROOM_ENCAP_L3_IPV4 (1ULL << 1)
#define BPF_F_ADJ_ROOM_ENCAP_L3_IPV6 (1ULL << 2)
#define BPF_F_ADJ_ROOM_ENCAP_L4_GRE (1ULL << 3)
#define BPF_F_ADJ_ROOM_ENCAP_L4_UDP (1ULL << 4)
#define BPF_F_ADJ_ROOM_ENCAP_L2(len) (((__u64)len & \
BPF_ADJ_ROOM_ENCAP_L2_MASK) \
<< BPF_ADJ_ROOM_ENCAP_L2_SHIFT)
/* BPF_FUNC_sysctl_get_name flags. */
#define BPF_F_SYSCTL_BASE_NAME (1ULL << 0)
/* BPF_FUNC_sk_storage_get flags */
#define BPF_SK_STORAGE_GET_F_CREATE (1ULL << 0)
/* Mode for BPF_FUNC_skb_adjust_room helper. */ /* Mode for BPF_FUNC_skb_adjust_room helper. */
enum bpf_adj_room_mode { enum bpf_adj_room_mode {
BPF_ADJ_ROOM_NET, BPF_ADJ_ROOM_NET,
BPF_ADJ_ROOM_MAC,
}; };
/* Mode for BPF_FUNC_skb_load_bytes_relative helper. */ /* Mode for BPF_FUNC_skb_load_bytes_relative helper. */
@ -3218,4 +3485,14 @@ struct bpf_line_info {
struct bpf_spin_lock { struct bpf_spin_lock {
__u32 val; __u32 val;
}; };
struct bpf_sysctl {
__u32 write; /* Sysctl is being read (= 0) or written (= 1).
* Allows 1,2,4-byte read, but no write.
*/
__u32 file_pos; /* Sysctl file position to read from, write to.
* Allows 1,2,4-byte read an 4-byte write.
*/
};
#endif /* __LINUX_BPF_H__ */ #endif /* __LINUX_BPF_H__ */

View File

@ -39,11 +39,11 @@ struct btf_type {
* struct, union and fwd * struct, union and fwd
*/ */
__u32 info; __u32 info;
/* "size" is used by INT, ENUM, STRUCT and UNION. /* "size" is used by INT, ENUM, STRUCT, UNION and DATASEC.
* "size" tells the size of the type it is describing. * "size" tells the size of the type it is describing.
* *
* "type" is used by PTR, TYPEDEF, VOLATILE, CONST, RESTRICT, * "type" is used by PTR, TYPEDEF, VOLATILE, CONST, RESTRICT,
* FUNC and FUNC_PROTO. * FUNC, FUNC_PROTO and VAR.
* "type" is a type_id referring to another type. * "type" is a type_id referring to another type.
*/ */
union { union {
@ -70,8 +70,10 @@ struct btf_type {
#define BTF_KIND_RESTRICT 11 /* Restrict */ #define BTF_KIND_RESTRICT 11 /* Restrict */
#define BTF_KIND_FUNC 12 /* Function */ #define BTF_KIND_FUNC 12 /* Function */
#define BTF_KIND_FUNC_PROTO 13 /* Function Proto */ #define BTF_KIND_FUNC_PROTO 13 /* Function Proto */
#define BTF_KIND_MAX 13 #define BTF_KIND_VAR 14 /* Variable */
#define NR_BTF_KINDS 14 #define BTF_KIND_DATASEC 15 /* Section */
#define BTF_KIND_MAX BTF_KIND_DATASEC
#define NR_BTF_KINDS (BTF_KIND_MAX + 1)
/* For some specific BTF_KIND, "struct btf_type" is immediately /* For some specific BTF_KIND, "struct btf_type" is immediately
* followed by extra data. * followed by extra data.
@ -138,4 +140,26 @@ struct btf_param {
__u32 type; __u32 type;
}; };
enum {
BTF_VAR_STATIC = 0,
BTF_VAR_GLOBAL_ALLOCATED,
};
/* BTF_KIND_VAR is followed by a single "struct btf_var" to describe
* additional information related to the variable such as its linkage.
*/
struct btf_var {
__u32 linkage;
};
/* BTF_KIND_DATASEC is followed by multiple "struct btf_var_secinfo"
* to describe all BTF_KIND_VAR types it contains along with it's
* in-section offset as well as size.
*/
struct btf_var_secinfo {
__u32 type;
__u32 offset;
__u32 size;
};
#endif /* __LINUX_BTF_H__ */ #endif /* __LINUX_BTF_H__ */

View File

@ -16,6 +16,12 @@ enum {
FOU_ATTR_IPPROTO, /* u8 */ FOU_ATTR_IPPROTO, /* u8 */
FOU_ATTR_TYPE, /* u8 */ FOU_ATTR_TYPE, /* u8 */
FOU_ATTR_REMCSUM_NOPARTIAL, /* flag */ FOU_ATTR_REMCSUM_NOPARTIAL, /* flag */
FOU_ATTR_LOCAL_V4, /* u32 */
FOU_ATTR_LOCAL_V6, /* in6_addr */
FOU_ATTR_PEER_V4, /* u32 */
FOU_ATTR_PEER_V6, /* in6_addr */
FOU_ATTR_PEER_PORT, /* u16 */
FOU_ATTR_IFINDEX, /* s32 */
__FOU_ATTR_MAX, __FOU_ATTR_MAX,
}; };

View File

@ -90,6 +90,8 @@ struct icmp6hdr {
#define ICMPV6_TIME_EXCEED 3 #define ICMPV6_TIME_EXCEED 3
#define ICMPV6_PARAMPROB 4 #define ICMPV6_PARAMPROB 4
#define ICMPV6_ERRMSG_MAX 127
#define ICMPV6_INFOMSG_MASK 0x80 #define ICMPV6_INFOMSG_MASK 0x80
#define ICMPV6_ECHO_REQUEST 128 #define ICMPV6_ECHO_REQUEST 128
@ -110,6 +112,8 @@ struct icmp6hdr {
#define ICMPV6_MRDISC_ADV 151 #define ICMPV6_MRDISC_ADV 151
#define ICMPV6_MSG_MAX 255
/* /*
* Codes for Destination Unreachable * Codes for Destination Unreachable
*/ */

View File

@ -109,6 +109,7 @@
#define ETH_P_QINQ2 0x9200 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */ #define ETH_P_QINQ2 0x9200 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
#define ETH_P_QINQ3 0x9300 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */ #define ETH_P_QINQ3 0x9300 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
#define ETH_P_EDSA 0xDADA /* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */ #define ETH_P_EDSA 0xDADA /* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
#define ETH_P_DSA_8021Q 0xDADB /* Fake VLAN Header for DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
#define ETH_P_IFE 0xED3E /* ForCES inter-FE LFB type */ #define ETH_P_IFE 0xED3E /* ForCES inter-FE LFB type */
#define ETH_P_AF_IUCV 0xFBFB /* IBM af_iucv [ NOT AN OFFICIALLY REGISTERED ID ] */ #define ETH_P_AF_IUCV 0xFBFB /* IBM af_iucv [ NOT AN OFFICIALLY REGISTERED ID ] */

View File

@ -60,6 +60,7 @@
#define TUNSETSTEERINGEBPF _IOR('T', 224, int) #define TUNSETSTEERINGEBPF _IOR('T', 224, int)
#define TUNSETFILTEREBPF _IOR('T', 225, int) #define TUNSETFILTEREBPF _IOR('T', 225, int)
#define TUNSETCARRIER _IOW('T', 226, int) #define TUNSETCARRIER _IOW('T', 226, int)
#define TUNGETDEVNETNS _IO('T', 227)
/* TUNSETIFF ifr flags */ /* TUNSETIFF ifr flags */
#define IFF_TUN 0x0001 #define IFF_TUN 0x0001

View File

@ -32,10 +32,11 @@ enum vlan_ioctl_cmds {
}; };
enum vlan_flags { enum vlan_flags {
VLAN_FLAG_REORDER_HDR = 0x1, VLAN_FLAG_REORDER_HDR = 0x1,
VLAN_FLAG_GVRP = 0x2, VLAN_FLAG_GVRP = 0x2,
VLAN_FLAG_LOOSE_BINDING = 0x4, VLAN_FLAG_LOOSE_BINDING = 0x4,
VLAN_FLAG_MVRP = 0x8, VLAN_FLAG_MVRP = 0x8,
VLAN_FLAG_BRIDGE_BINDING = 0x10,
}; };
enum vlan_name_types { enum vlan_name_types {

View File

@ -1148,6 +1148,16 @@ enum {
#define TCA_TAPRIO_SCHED_MAX (__TCA_TAPRIO_SCHED_MAX - 1) #define TCA_TAPRIO_SCHED_MAX (__TCA_TAPRIO_SCHED_MAX - 1)
/* The format for the admin sched (dump only):
* [TCA_TAPRIO_SCHED_ADMIN_SCHED]
* [TCA_TAPRIO_ATTR_SCHED_BASE_TIME]
* [TCA_TAPRIO_ATTR_SCHED_ENTRY_LIST]
* [TCA_TAPRIO_ATTR_SCHED_ENTRY]
* [TCA_TAPRIO_ATTR_SCHED_ENTRY_CMD]
* [TCA_TAPRIO_ATTR_SCHED_ENTRY_GATES]
* [TCA_TAPRIO_ATTR_SCHED_ENTRY_INTERVAL]
*/
enum { enum {
TCA_TAPRIO_ATTR_UNSPEC, TCA_TAPRIO_ATTR_UNSPEC,
TCA_TAPRIO_ATTR_PRIOMAP, /* struct tc_mqprio_qopt */ TCA_TAPRIO_ATTR_PRIOMAP, /* struct tc_mqprio_qopt */
@ -1156,6 +1166,9 @@ enum {
TCA_TAPRIO_ATTR_SCHED_SINGLE_ENTRY, /* single entry */ TCA_TAPRIO_ATTR_SCHED_SINGLE_ENTRY, /* single entry */
TCA_TAPRIO_ATTR_SCHED_CLOCKID, /* s32 */ TCA_TAPRIO_ATTR_SCHED_CLOCKID, /* s32 */
TCA_TAPRIO_PAD, TCA_TAPRIO_PAD,
TCA_TAPRIO_ATTR_ADMIN_SCHED, /* The admin sched, only used in dump */
TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME, /* s64 */
TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME_EXTENSION, /* s64 */
__TCA_TAPRIO_ATTR_MAX, __TCA_TAPRIO_ATTR_MAX,
}; };

View File

@ -19,6 +19,7 @@
#ifndef _LINUX_SOCKIOS_H #ifndef _LINUX_SOCKIOS_H
#define _LINUX_SOCKIOS_H #define _LINUX_SOCKIOS_H
#include <asm/bitsperlong.h>
#include <asm/sockios.h> #include <asm/sockios.h>
/* Linux-specific socket ioctls */ /* Linux-specific socket ioctls */
@ -27,6 +28,30 @@
#define SOCK_IOC_TYPE 0x89 #define SOCK_IOC_TYPE 0x89
/*
* the timeval/timespec data structure layout is defined by libc,
* so we need to cover both possible versions on 32-bit.
*/
/* Get stamp (timeval) */
#define SIOCGSTAMP_NEW _IOR(SOCK_IOC_TYPE, 0x06, long long[2])
/* Get stamp (timespec) */
#define SIOCGSTAMPNS_NEW _IOR(SOCK_IOC_TYPE, 0x07, long long[2])
#if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))
/* on 64-bit and x32, avoid the ?: operator */
#ifndef SIOCGSTAMP
#define SIOCGSTAMP SIOCGSTAMP_OLD
#endif
#ifndef SIOCGSTAMPNS
#define SIOCGSTAMPNS SIOCGSTAMPNS_OLD
#endif
#else
#define SIOCGSTAMP ((sizeof(struct timeval)) == 8 ? \
SIOCGSTAMP_OLD : SIOCGSTAMP_NEW)
#define SIOCGSTAMPNS ((sizeof(struct timespec)) == 8 ? \
SIOCGSTAMPNS_OLD : SIOCGSTAMPNS_NEW)
#endif
/* Routing table calls. */ /* Routing table calls. */
#define SIOCADDRT 0x890B /* add routing table entry */ #define SIOCADDRT 0x890B /* add routing table entry */
#define SIOCDELRT 0x890C /* delete routing table entry */ #define SIOCDELRT 0x890C /* delete routing table entry */

View File

@ -160,15 +160,42 @@ enum {
#define TCPI_OPT_ECN_SEEN 16 /* we received at least one packet with ECT */ #define TCPI_OPT_ECN_SEEN 16 /* we received at least one packet with ECT */
#define TCPI_OPT_SYN_DATA 32 /* SYN-ACK acked data in SYN sent or rcvd */ #define TCPI_OPT_SYN_DATA 32 /* SYN-ACK acked data in SYN sent or rcvd */
/*
* Sender's congestion state indicating normal or abnormal situations
* in the last round of packets sent. The state is driven by the ACK
* information and timer events.
*/
enum tcp_ca_state { enum tcp_ca_state {
/*
* Nothing bad has been observed recently.
* No apparent reordering, packet loss, or ECN marks.
*/
TCP_CA_Open = 0, TCP_CA_Open = 0,
#define TCPF_CA_Open (1<<TCP_CA_Open) #define TCPF_CA_Open (1<<TCP_CA_Open)
/*
* The sender enters disordered state when it has received DUPACKs or
* SACKs in the last round of packets sent. This could be due to packet
* loss or reordering but needs further information to confirm packets
* have been lost.
*/
TCP_CA_Disorder = 1, TCP_CA_Disorder = 1,
#define TCPF_CA_Disorder (1<<TCP_CA_Disorder) #define TCPF_CA_Disorder (1<<TCP_CA_Disorder)
/*
* The sender enters Congestion Window Reduction (CWR) state when it
* has received ACKs with ECN-ECE marks, or has experienced congestion
* or packet discard on the sender host (e.g. qdisc).
*/
TCP_CA_CWR = 2, TCP_CA_CWR = 2,
#define TCPF_CA_CWR (1<<TCP_CA_CWR) #define TCPF_CA_CWR (1<<TCP_CA_CWR)
/*
* The sender is in fast recovery and retransmitting lost packets,
* typically triggered by ACK events.
*/
TCP_CA_Recovery = 3, TCP_CA_Recovery = 3,
#define TCPF_CA_Recovery (1<<TCP_CA_Recovery) #define TCPF_CA_Recovery (1<<TCP_CA_Recovery)
/*
* The sender is in loss recovery triggered by retransmission timeout.
*/
TCP_CA_Loss = 4 TCP_CA_Loss = 4
#define TCPF_CA_Loss (1<<TCP_CA_Loss) #define TCPF_CA_Loss (1<<TCP_CA_Loss)
}; };

View File

@ -190,6 +190,7 @@ struct sockaddr_tipc {
#define TIPC_MCAST_REPLICAST 134 /* Default: TIPC selects. No arg */ #define TIPC_MCAST_REPLICAST 134 /* Default: TIPC selects. No arg */
#define TIPC_GROUP_JOIN 135 /* Takes struct tipc_group_req* */ #define TIPC_GROUP_JOIN 135 /* Takes struct tipc_group_req* */
#define TIPC_GROUP_LEAVE 136 /* No argument */ #define TIPC_GROUP_LEAVE 136 /* No argument */
#define TIPC_SOCK_RECVQ_USED 137 /* Default: none (read only) */
/* /*
* Flag values * Flag values

View File

@ -281,6 +281,8 @@ enum {
TIPC_NLA_PROP_TOL, /* u32 */ TIPC_NLA_PROP_TOL, /* u32 */
TIPC_NLA_PROP_WIN, /* u32 */ TIPC_NLA_PROP_WIN, /* u32 */
TIPC_NLA_PROP_MTU, /* u32 */ TIPC_NLA_PROP_MTU, /* u32 */
TIPC_NLA_PROP_BROADCAST, /* u32 */
TIPC_NLA_PROP_BROADCAST_RATIO, /* u32 */
__TIPC_NLA_PROP_MAX, __TIPC_NLA_PROP_MAX,
TIPC_NLA_PROP_MAX = __TIPC_NLA_PROP_MAX - 1 TIPC_NLA_PROP_MAX = __TIPC_NLA_PROP_MAX - 1

View File

@ -28,11 +28,16 @@ static void usage(void)
{ {
fprintf(stderr, fprintf(stderr,
"Usage: ip fou add port PORT { ipproto PROTO | gue } [ -6 ]\n" "Usage: ip fou add port PORT { ipproto PROTO | gue } [ -6 ]\n"
" ip fou del port PORT [ -6 ]\n" " [ local IFADDR ] [ peer IFADDR ]\n"
" [ peer_port PORT ] [ dev IFNAME ]\n"
" ip fou del port PORT [ -6 ] [ local IFADDR ]\n"
" [ peer IFADDR ] [ peer_port PORT ]\n"
" [ dev IFNAME ]\n"
" ip fou show\n" " ip fou show\n"
"\n" "\n"
"Where: PROTO { ipproto-name | 1..255 }\n" "Where: PROTO { ipproto-name | 1..255 }\n"
" PORT { 1..65535 }\n"); " PORT { 1..65535 }\n"
" IFADDR { addr }\n");
exit(-1); exit(-1);
} }
@ -48,12 +53,14 @@ static int genl_family = -1;
static int fou_parse_opt(int argc, char **argv, struct nlmsghdr *n, static int fou_parse_opt(int argc, char **argv, struct nlmsghdr *n,
bool adding) bool adding)
{ {
__u16 port; const char *local = NULL, *peer = NULL;
int port_set = 0; __u16 port, peer_port = 0;
__u8 ipproto, type; __u8 family = AF_INET;
bool gue_set = false; bool gue_set = false;
int ipproto_set = 0; int ipproto_set = 0;
__u8 family = AF_INET; __u8 ipproto, type;
int port_set = 0;
int index = 0;
while (argc > 0) { while (argc > 0) {
if (!matches(*argv, "port")) { if (!matches(*argv, "port")) {
@ -77,6 +84,37 @@ static int fou_parse_opt(int argc, char **argv, struct nlmsghdr *n,
gue_set = true; gue_set = true;
} else if (!matches(*argv, "-6")) { } else if (!matches(*argv, "-6")) {
family = AF_INET6; family = AF_INET6;
} else if (!matches(*argv, "local")) {
NEXT_ARG();
local = *argv;
} else if (!matches(*argv, "peer")) {
NEXT_ARG();
peer = *argv;
} else if (!matches(*argv, "peer_port")) {
NEXT_ARG();
if (get_be16(&peer_port, *argv, 0) || peer_port == 0)
invarg("invalid peer port", *argv);
} else if (!matches(*argv, "dev")) {
const char *ifname;
NEXT_ARG();
ifname = *argv;
if (check_ifname(ifname)) {
fprintf(stderr, "fou: invalid device name\n");
exit(EXIT_FAILURE);
}
index = ll_name_to_index(ifname);
if (!index) {
fprintf(stderr, "fou: unknown device name\n");
exit(EXIT_FAILURE);
}
} else { } else {
fprintf(stderr fprintf(stderr
, "fou: unknown command \"%s\"?\n", *argv); , "fou: unknown command \"%s\"?\n", *argv);
@ -101,6 +139,11 @@ static int fou_parse_opt(int argc, char **argv, struct nlmsghdr *n,
return -1; return -1;
} }
if ((peer_port && !peer) || (peer && !peer_port)) {
fprintf(stderr, "fou: both peer and peer port must be set\n");
return -1;
}
type = gue_set ? FOU_ENCAP_GUE : FOU_ENCAP_DIRECT; type = gue_set ? FOU_ENCAP_GUE : FOU_ENCAP_DIRECT;
addattr16(n, 1024, FOU_ATTR_PORT, port); addattr16(n, 1024, FOU_ATTR_PORT, port);
@ -110,6 +153,38 @@ static int fou_parse_opt(int argc, char **argv, struct nlmsghdr *n,
if (ipproto_set) if (ipproto_set)
addattr8(n, 1024, FOU_ATTR_IPPROTO, ipproto); addattr8(n, 1024, FOU_ATTR_IPPROTO, ipproto);
if (local) {
inet_prefix local_addr;
__u8 attr_type = family == AF_INET ? FOU_ATTR_LOCAL_V4 :
FOU_ATTR_LOCAL_V6;
if (get_addr(&local_addr, local, family)) {
fprintf(stderr, "fou: parsing local address failed\n");
exit(EXIT_FAILURE);
}
addattr_l(n, 1024, attr_type, &local_addr.data,
local_addr.bytelen);
}
if (peer) {
inet_prefix peer_addr;
__u8 attr_type = family == AF_INET ? FOU_ATTR_PEER_V4 :
FOU_ATTR_PEER_V6;
if (get_addr(&peer_addr, peer, family)) {
fprintf(stderr, "fou: parsing peer address failed\n");
exit(EXIT_FAILURE);
}
addattr_l(n, 1024, attr_type, &peer_addr.data,
peer_addr.bytelen);
if (peer_port)
addattr16(n, 1024, FOU_ATTR_PEER_PORT, peer_port);
}
if (index)
addattr32(n, 1024, FOU_ATTR_IFINDEX, index);
return 0; return 0;
} }
@ -139,8 +214,10 @@ static int do_del(int argc, char **argv)
static int print_fou_mapping(struct nlmsghdr *n, void *arg) static int print_fou_mapping(struct nlmsghdr *n, void *arg)
{ {
struct genlmsghdr *ghdr; __u8 family = AF_INET, local_attr_type, peer_attr_type, byte_len;
struct rtattr *tb[FOU_ATTR_MAX + 1]; struct rtattr *tb[FOU_ATTR_MAX + 1];
__u8 empty_buf[16] = {0};
struct genlmsghdr *ghdr;
int len = n->nlmsg_len; int len = n->nlmsg_len;
if (n->nlmsg_type != genl_family) if (n->nlmsg_type != genl_family)
@ -166,7 +243,7 @@ static int print_fou_mapping(struct nlmsghdr *n, void *arg)
" ipproto %u", rta_getattr_u8(tb[FOU_ATTR_IPPROTO])); " ipproto %u", rta_getattr_u8(tb[FOU_ATTR_IPPROTO]));
if (tb[FOU_ATTR_AF]) { if (tb[FOU_ATTR_AF]) {
__u8 family = rta_getattr_u8(tb[FOU_ATTR_AF]); family = rta_getattr_u8(tb[FOU_ATTR_AF]);
print_string(PRINT_JSON, "family", NULL, print_string(PRINT_JSON, "family", NULL,
family_name(family)); family_name(family));
@ -175,6 +252,48 @@ static int print_fou_mapping(struct nlmsghdr *n, void *arg)
print_string(PRINT_FP, NULL, print_string(PRINT_FP, NULL,
" -6", NULL); " -6", NULL);
} }
local_attr_type = family == AF_INET ? FOU_ATTR_LOCAL_V4 :
FOU_ATTR_LOCAL_V6;
peer_attr_type = family == AF_INET ? FOU_ATTR_PEER_V4 :
FOU_ATTR_PEER_V6;
byte_len = af_bit_len(family) / 8;
if (tb[local_attr_type] && memcmp(RTA_DATA(tb[local_attr_type]),
empty_buf, byte_len)) {
print_string(PRINT_ANY, "local", " local %s",
format_host_rta(family, tb[local_attr_type]));
}
if (tb[peer_attr_type] && memcmp(RTA_DATA(tb[peer_attr_type]),
empty_buf, byte_len)) {
print_string(PRINT_ANY, "peer", " peer %s",
format_host_rta(family, tb[peer_attr_type]));
}
if (tb[FOU_ATTR_PEER_PORT]) {
__u16 p_port = ntohs(rta_getattr_u16(tb[FOU_ATTR_PEER_PORT]));
if (p_port)
print_uint(PRINT_ANY, "peer_port", " peer_port %u",
p_port);
}
if (tb[FOU_ATTR_IFINDEX]) {
int index = rta_getattr_s32(tb[FOU_ATTR_IFINDEX]);
if (index) {
const char *ifname;
ifname = ll_index_to_name(index);
if (ifname)
print_string(PRINT_ANY, "dev", " dev %s",
ifname);
}
}
print_string(PRINT_FP, NULL, "\n", NULL); print_string(PRINT_FP, NULL, "\n", NULL);
close_json_object(); close_json_object();

View File

@ -41,6 +41,7 @@ static void print_explain(FILE *f)
" [ vlan_protocol VLAN_PROTOCOL ]\n" " [ vlan_protocol VLAN_PROTOCOL ]\n"
" [ vlan_default_pvid VLAN_DEFAULT_PVID ]\n" " [ vlan_default_pvid VLAN_DEFAULT_PVID ]\n"
" [ vlan_stats_enabled VLAN_STATS_ENABLED ]\n" " [ vlan_stats_enabled VLAN_STATS_ENABLED ]\n"
" [ vlan_stats_per_port VLAN_STATS_PER_PORT ]\n"
" [ mcast_snooping MULTICAST_SNOOPING ]\n" " [ mcast_snooping MULTICAST_SNOOPING ]\n"
" [ mcast_router MULTICAST_ROUTER ]\n" " [ mcast_router MULTICAST_ROUTER ]\n"
" [ mcast_query_use_ifaddr MCAST_QUERY_USE_IFADDR ]\n" " [ mcast_query_use_ifaddr MCAST_QUERY_USE_IFADDR ]\n"
@ -175,6 +176,14 @@ static int bridge_parse_opt(struct link_util *lu, int argc, char **argv,
invarg("invalid vlan_stats_enabled", *argv); invarg("invalid vlan_stats_enabled", *argv);
addattr8(n, 1024, IFLA_BR_VLAN_STATS_ENABLED, addattr8(n, 1024, IFLA_BR_VLAN_STATS_ENABLED,
vlan_stats_enabled); vlan_stats_enabled);
} else if (matches(*argv, "vlan_stats_per_port") == 0) {
__u8 vlan_stats_per_port;
NEXT_ARG();
if (get_u8(&vlan_stats_per_port, *argv, 0))
invarg("invalid vlan_stats_per_port", *argv);
addattr8(n, 1024, IFLA_BR_VLAN_STATS_PER_PORT,
vlan_stats_per_port);
} else if (matches(*argv, "mcast_router") == 0) { } else if (matches(*argv, "mcast_router") == 0) {
__u8 mcast_router; __u8 mcast_router;
@ -521,6 +530,12 @@ static void bridge_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
"vlan_stats_enabled %u ", "vlan_stats_enabled %u ",
rta_getattr_u8(tb[IFLA_BR_VLAN_STATS_ENABLED])); rta_getattr_u8(tb[IFLA_BR_VLAN_STATS_ENABLED]));
if (tb[IFLA_BR_VLAN_STATS_PER_PORT])
print_uint(PRINT_ANY,
"vlan_stats_per_port",
"vlan_stats_per_port %u ",
rta_getattr_u8(tb[IFLA_BR_VLAN_STATS_PER_PORT]));
if (tb[IFLA_BR_GROUP_FWD_MASK]) if (tb[IFLA_BR_GROUP_FWD_MASK])
print_0xhex(PRINT_ANY, print_0xhex(PRINT_ANY,
"group_fwd_mask", "group_fwd_mask",

View File

@ -27,6 +27,7 @@ static void print_explain(FILE *f)
" [ gvrp { on | off } ]\n" " [ gvrp { on | off } ]\n"
" [ mvrp { on | off } ]\n" " [ mvrp { on | off } ]\n"
" [ loose_binding { on | off } ]\n" " [ loose_binding { on | off } ]\n"
" [ bridge_binding { on | off } ]\n"
" [ ingress-qos-map QOS-MAP ]\n" " [ ingress-qos-map QOS-MAP ]\n"
" [ egress-qos-map QOS-MAP ]\n" " [ egress-qos-map QOS-MAP ]\n"
"\n" "\n"
@ -134,6 +135,15 @@ static int vlan_parse_opt(struct link_util *lu, int argc, char **argv,
flags.flags &= ~VLAN_FLAG_LOOSE_BINDING; flags.flags &= ~VLAN_FLAG_LOOSE_BINDING;
else else
return on_off("loose_binding", *argv); return on_off("loose_binding", *argv);
} else if (matches(*argv, "bridge_binding") == 0) {
NEXT_ARG();
flags.mask |= VLAN_FLAG_BRIDGE_BINDING;
if (strcmp(*argv, "on") == 0)
flags.flags |= VLAN_FLAG_BRIDGE_BINDING;
else if (strcmp(*argv, "off") == 0)
flags.flags &= ~VLAN_FLAG_BRIDGE_BINDING;
else
return on_off("bridge_binding", *argv);
} else if (matches(*argv, "ingress-qos-map") == 0) { } else if (matches(*argv, "ingress-qos-map") == 0) {
NEXT_ARG(); NEXT_ARG();
if (vlan_parse_qos_map(&argc, &argv, n, if (vlan_parse_qos_map(&argc, &argv, n,
@ -204,6 +214,7 @@ static void vlan_print_flags(FILE *fp, __u32 flags)
_PF(GVRP); _PF(GVRP);
_PF(MVRP); _PF(MVRP);
_PF(LOOSE_BINDING); _PF(LOOSE_BINDING);
_PF(BRIDGE_BINDING);
#undef _PF #undef _PF
if (flags) if (flags)
print_hex(PRINT_ANY, NULL, "%x", flags); print_hex(PRINT_ANY, NULL, "%x", flags);

View File

@ -384,6 +384,9 @@ int print_neigh(struct nlmsghdr *n, void *arg)
if (r->ndm_flags & NTF_EXT_LEARNED) if (r->ndm_flags & NTF_EXT_LEARNED)
print_null(PRINT_ANY, "extern_learn", " %s ", "extern_learn"); print_null(PRINT_ANY, "extern_learn", " %s ", "extern_learn");
if (r->ndm_flags & NTF_OFFLOADED)
print_null(PRINT_ANY, "offload", " %s", "offload");
if (show_stats) { if (show_stats) {
if (tb[NDA_CACHEINFO]) if (tb[NDA_CACHEINFO])
print_cacheinfo(RTA_DATA(tb[NDA_CACHEINFO])); print_cacheinfo(RTA_DATA(tb[NDA_CACHEINFO]));

View File

@ -24,11 +24,43 @@ ip-gue \- Generic UDP Encapsulation receive port configuration
.B ipproto .B ipproto
.IR PROTO .IR PROTO
.RB " }" .RB " }"
.RB "[ "
.B local
.IR IFADDR
.RB " ]"
.RB "[ "
.B peer
.IR IFADDR
.RB " ]"
.RB "[ "
.B peer_port
.IR PORT
.RB " ]"
.RB "[ "
.B dev
.IR IFNAME
.RB " ]"
.br .br
.ti -8 .ti -8
.BR "ip fou del" .BR "ip fou del"
.B port .B port
.IR PORT .IR PORT
.RB "[ "
.B local
.IR IFADDR
.RB " ]"
.RB "[ "
.B peer
.IR IFADDR
.RB " ]"
.RB "[ "
.B peer_port
.IR PORT
.RB " ]"
.RB "[ "
.B dev
.IR IFNAME
.RB " ]"
.br .br
.ti -8 .ti -8
.B ip fou show .B ip fou show
@ -50,11 +82,22 @@ When creating a FOU or GUE receive port, the port number is specified in
.I PORT .I PORT
argument. If FOU is used, the IP protocol number associated with the port is specified in argument. If FOU is used, the IP protocol number associated with the port is specified in
.I PROTO .I PROTO
argument. You can bind a port to a local address/interface, by specifying the
address in the local
.I IFADDR
argument or the device in the
.I IFNAME
argument. If you would like to connect the port, you can specify the peer
address in the peer
.I IFADDR
argument and peer port in the peer_port
.I PORT
argument. argument.
.PP .PP
A FOU or GUE receive port is deleted by specifying A FOU or GUE receive port is deleted by specifying
.I PORT .I PORT
in the delete command. in the delete command, as well as local address/interface or peer address/port
(if set).
.SH EXAMPLES .SH EXAMPLES
.PP .PP
.SS Configure a FOU receive port for GRE bound to 7777 .SS Configure a FOU receive port for GRE bound to 7777
@ -72,6 +115,10 @@ in the delete command.
.SS Delete the GUE receive port bound to 9999 .SS Delete the GUE receive port bound to 9999
.nf .nf
# ip fou del port 9999 # ip fou del port 9999
.SS Configure a FOU receive port for GRE bound to 1.2.3.4:7777
.nf
# ip fou add port 7777 ipproto 47 local 1.2.3.4
.PP
.SH SEE ALSO .SH SEE ALSO
.br .br
.BR ip (8) .BR ip (8)

View File

@ -406,6 +406,9 @@ the following additional arguments are supported:
.BR loose_binding " { " on " | " off " } " .BR loose_binding " { " on " | " off " } "
] ]
[ [
.BR bridge_binding " { " on " | " off " } "
]
[
.BI ingress-qos-map " QOS-MAP " .BI ingress-qos-map " QOS-MAP "
] ]
[ [
@ -459,6 +462,10 @@ where <phy_dev> is the physical device to which VLAN device is bound.
.BR loose_binding " { " on " | " off " } " .BR loose_binding " { " on " | " off " } "
- specifies whether the VLAN device state is bound to the physical device state. - specifies whether the VLAN device state is bound to the physical device state.
.BR bridge_binding " { " on " | " off " } "
- specifies whether the VLAN device link state tracks the state of bridge ports
that are members of the VLAN.
.BI ingress-qos-map " QOS-MAP " .BI ingress-qos-map " QOS-MAP "
- defines a mapping of VLAN header prio field to the Linux internal packet - defines a mapping of VLAN header prio field to the Linux internal packet
priority on incoming frames. The format is FROM:TO with multiple mappings priority on incoming frames. The format is FROM:TO with multiple mappings
@ -1392,6 +1399,8 @@ the following additional arguments are supported:
] [ ] [
.BI vlan_stats_enabled " VLAN_STATS_ENABLED " .BI vlan_stats_enabled " VLAN_STATS_ENABLED "
] [ ] [
.BI vlan_stats_per_port " VLAN_STATS_PER_PORT "
] [
.BI mcast_snooping " MULTICAST_SNOOPING " .BI mcast_snooping " MULTICAST_SNOOPING "
] [ ] [
.BI mcast_router " MULTICAST_ROUTER " .BI mcast_router " MULTICAST_ROUTER "
@ -1503,6 +1512,13 @@ or disable
.RI ( VLAN_STATS_ENABLED " == 0) " .RI ( VLAN_STATS_ENABLED " == 0) "
per-VLAN stats accounting. per-VLAN stats accounting.
.BI vlan_stats_per_port " VLAN_STATS_PER_PORT "
- enable
.RI ( VLAN_STATS_PER_PORT " == 1) "
or disable
.RI ( VLAN_STATS_PER_PORT " == 0) "
per-VLAN per-port stats accounting. Can be changed only when there are no port VLANs configured.
.BI mcast_snooping " MULTICAST_SNOOPING " .BI mcast_snooping " MULTICAST_SNOOPING "
- turn multicast snooping on - turn multicast snooping on
.RI ( MULTICAST_SNOOPING " > 0) " .RI ( MULTICAST_SNOOPING " > 0) "

View File

@ -22,6 +22,18 @@ rdma-link \- rdma link configuration
.B rdma link show .B rdma link show
.RI "[ " DEV/PORT_INDEX " ]" .RI "[ " DEV/PORT_INDEX " ]"
.ti -8
.B rdma link add
.BR NAME
.BR type
.BR TYPE
.BR netdev
.BR NETDEV
.ti -8
.B rdma link delete
.RI NAME
.ti -8 .ti -8
.B rdma link help .B rdma link help
@ -33,6 +45,31 @@ rdma-link \- rdma link configuration
- specifies the RDMA link to show. - specifies the RDMA link to show.
If this argument is omitted all links are listed. If this argument is omitted all links are listed.
.SS rdma link add NAME type TYPE netdev NETDEV - add an rdma link for the specified type to the network device
.sp
.BR NAME
- specifies the new name of the rdma link to add
.BR TYPE
- specifies which rdma type to use. Link types:
.sp
.in +8
.B rxe
- Soft RoCE driver
.sp
.B siw
- Soft iWARP driver
.in -8
.BR NETDEV
- specifies the network device to which the link is bound
.SS rdma link delete NAME - delete an rdma link
.PP
.BR NAME
- specifies the name of the rdma link to delete
.PP
.SH "EXAMPLES" .SH "EXAMPLES"
.PP .PP
rdma link show rdma link show
@ -45,6 +82,16 @@ rdma link show mlx5_2/1
Shows the state of specified rdma link. Shows the state of specified rdma link.
.RE .RE
.PP .PP
rdma link add rxe_eth0 type rxe netdev eth0
.RS 4
Adds a RXE link named rxe_eth0 to network device eth0
.RE
.PP
rdma link del rxe_eth0
.RS 4
Removes RXE link rxe_eth0
.RE
.PP
.SH SEE ALSO .SH SEE ALSO
.BR rdma (8), .BR rdma (8),

View File

@ -24,6 +24,9 @@ Output version information.
.B \-H, \-\-no-header .B \-H, \-\-no-header
Suppress header line. Suppress header line.
.TP .TP
.B \-O, \-\-oneline
Print each socket's data on a single line.
.TP
.B \-n, \-\-numeric .B \-n, \-\-numeric
Do not try to resolve service names. Do not try to resolve service names.
.TP .TP

View File

@ -597,6 +597,7 @@ struct bpf_elf_map __section("maps") map_stats = {
.size_key = sizeof(uint32_t), .size_key = sizeof(uint32_t),
.size_value = sizeof(struct tuple), .size_value = sizeof(struct tuple),
.max_elem = BPF_MAX_MARK, .max_elem = BPF_MAX_MARK,
.pinning = PIN_GLOBAL_NS,
}; };
static inline void cls_update_stats(const struct __sk_buff *skb, static inline void cls_update_stats(const struct __sk_buff *skb,
@ -709,13 +710,22 @@ in both examples was:
#define likely(x) __builtin_expect(!!(x), 1) #define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0) #define unlikely(x) __builtin_expect(!!(x), 0)
/* Used map structure */ /* Object pinning settings */
#define PIN_NONE 0
#define PIN_OBJECT_NS 1
#define PIN_GLOBAL_NS 2
/* ELF map definition */
struct bpf_elf_map { struct bpf_elf_map {
__u32 type; __u32 type;
__u32 size_key; __u32 size_key;
__u32 size_value; __u32 size_value;
__u32 max_elem; __u32 max_elem;
__u32 flags;
__u32 id; __u32 id;
__u32 pinning;
__u32 inner_id;
__u32 inner_idx;
}; };
/* Some used BPF function calls. */ /* Some used BPF function calls. */

View File

@ -1,4 +1,4 @@
.TH TIPC-LINK 8 "02 Jun 2015" "iproute2" "Linux" .TH TIPC-LINK 8 "22 Mar 2019" "iproute2" "Linux"
.\" For consistency, please keep padding right aligned. .\" For consistency, please keep padding right aligned.
.\" For example '.B "foo " bar' and not '.B foo " bar"' .\" For example '.B "foo " bar' and not '.B foo " bar"'
@ -14,18 +14,36 @@ tipc-link \- show links or modify link properties
.ti -8 .ti -8
.B tipc link set .B tipc link set
.RB "{ " "priority " .br
.RB "[ " "{ " "priority "
.IR PRIORITY .IR PRIORITY
.RB "| " tolerance .RB "| " tolerance
.IR TOLERANCE .IR TOLERANCE
.RB "| " window .RB "| " window
.IR "WINDOW " } .IR "WINDOW " }
.BI "link " LINK .BI "link " LINK " ]"
.RB "|"
.br
.RB "[ "
.RB "{ " broadcast " [ "
.IR BROADCAST
.RB " | "
.IR REPLICAST
.RB " | "
.IR AUTOSELECT
.RB "[ " ratio
.IR SIZE
.RB "] " ] " } " "]"
.ti -8 .ti -8
.B tipc link get .B tipc link get
.RB "{ " "priority" " | " tolerance " | " window " } " link .br
.I LINK .RB "[ " "{ " "priority" " | " tolerance " | " window " } " link
.IR LINK " ] "
.RB "|"
.br
.RB "[ " { " broadcast " } " ]"
.br
.ti -8 .ti -8
.B tipc link statistics .B tipc link statistics
@ -306,6 +324,31 @@ They are usually transient and occur during the cluster startup phase
or network reconfiguration. or network reconfiguration.
Possible status are: U or D. The status U implies up and D down. Possible status are: U or D. The status U implies up and D down.
.SS Broadcast properties
.TP
.B BROADCAST
.br
Forces all multicast traffic to be transmitted via broadcast only,
irrespective of cluster size and number of destinations.
.TP
.B REPLICAST
.br
Forces all multicast traffic to be transmitted via replicast only,
irrespective of cluster size and number of destinations.
.TP
.B AUTOSELECT
.br
Auto switching to broadcast or replicast depending on cluster size and
destination node number.
.TP
.B ratio SIZE
.br
Set the AUTOSELECT criteria, percentage of destination nodes vs cluster
size.
.SH EXAMPLES .SH EXAMPLES
.PP .PP
tipc link monitor list tipc link monitor list

View File

@ -121,6 +121,7 @@ static int follow_events;
static int sctp_ino; static int sctp_ino;
static int show_tipcinfo; static int show_tipcinfo;
static int show_tos; static int show_tos;
int oneline;
enum col_id { enum col_id {
COL_NETID, COL_NETID,
@ -3053,7 +3054,8 @@ static int inet_show_sock(struct nlmsghdr *nlh,
} }
if (show_mem || (show_tcpinfo && s->type != IPPROTO_UDP)) { if (show_mem || (show_tcpinfo && s->type != IPPROTO_UDP)) {
out("\n\t"); if (!oneline)
out("\n\t");
if (s->type == IPPROTO_SCTP) if (s->type == IPPROTO_SCTP)
sctp_show_info(nlh, r, tb); sctp_show_info(nlh, r, tb);
else else
@ -3973,7 +3975,10 @@ static int packet_show_sock(struct nlmsghdr *nlh, void *arg)
if (show_details) { if (show_details) {
if (pinfo) { if (pinfo) {
out("\n\tver:%d", pinfo->pdi_version); if (oneline)
out(" ver:%d", pinfo->pdi_version);
else
out("\n\tver:%d", pinfo->pdi_version);
out(" cpy_thresh:%d", pinfo->pdi_copy_thresh); out(" cpy_thresh:%d", pinfo->pdi_copy_thresh);
out(" flags( "); out(" flags( ");
if (pinfo->pdi_flags & PDI_RUNNING) if (pinfo->pdi_flags & PDI_RUNNING)
@ -3991,19 +3996,28 @@ static int packet_show_sock(struct nlmsghdr *nlh, void *arg)
out(" )"); out(" )");
} }
if (ring_rx) { if (ring_rx) {
out("\n\tring_rx("); if (oneline)
out(" ring_rx(");
else
out("\n\tring_rx(");
packet_show_ring(ring_rx); packet_show_ring(ring_rx);
out(")"); out(")");
} }
if (ring_tx) { if (ring_tx) {
out("\n\tring_tx("); if (oneline)
out(" ring_tx(");
else
out("\n\tring_tx(");
packet_show_ring(ring_tx); packet_show_ring(ring_tx);
out(")"); out(")");
} }
if (has_fanout) { if (has_fanout) {
uint16_t type = (fanout >> 16) & 0xffff; uint16_t type = (fanout >> 16) & 0xffff;
out("\n\tfanout("); if (oneline)
out(" fanout(");
else
out("\n\tfanout(");
out("id:%d,", fanout & 0xffff); out("id:%d,", fanout & 0xffff);
out("type:"); out("type:");
@ -4032,7 +4046,10 @@ static int packet_show_sock(struct nlmsghdr *nlh, void *arg)
int num = RTA_PAYLOAD(tb[PACKET_DIAG_FILTER]) / int num = RTA_PAYLOAD(tb[PACKET_DIAG_FILTER]) /
sizeof(struct sock_filter); sizeof(struct sock_filter);
out("\n\tbpf filter (%d): ", num); if (oneline)
out(" bpf filter (%d): ", num);
else
out("\n\tbpf filter (%d): ", num);
while (num) { while (num) {
out(" 0x%02x %u %u %u,", out(" 0x%02x %u %u %u,",
fil->code, fil->jt, fil->jf, fil->k); fil->code, fil->jt, fil->jf, fil->k);
@ -4144,7 +4161,10 @@ static int xdp_stats_print(struct sockstat *s, const struct filter *f)
static void xdp_show_ring(const char *name, struct xdp_diag_ring *ring) static void xdp_show_ring(const char *name, struct xdp_diag_ring *ring)
{ {
out("\n\t%s(", name); if (oneline)
out(" %s(", name);
else
out("\n\t%s(", name);
out("entries:%u", ring->entries); out("entries:%u", ring->entries);
out(")"); out(")");
} }
@ -4152,7 +4172,10 @@ static void xdp_show_ring(const char *name, struct xdp_diag_ring *ring)
static void xdp_show_umem(struct xdp_diag_umem *umem, struct xdp_diag_ring *fr, static void xdp_show_umem(struct xdp_diag_umem *umem, struct xdp_diag_ring *fr,
struct xdp_diag_ring *cr) struct xdp_diag_ring *cr)
{ {
out("\n\tumem("); if (oneline)
out(" tumem(");
else
out("\n\tumem(");
out("id:%u", umem->id); out("id:%u", umem->id);
out(",size:%llu", umem->size); out(",size:%llu", umem->size);
out(",num_pages:%u", umem->num_pages); out(",num_pages:%u", umem->num_pages);
@ -4574,7 +4597,10 @@ static int tipc_show_sock(struct nlmsghdr *nlh, void *arg)
proc_ctx_print(&ss); proc_ctx_print(&ss);
if (show_tipcinfo) { if (show_tipcinfo) {
out("\n type:%s", stype_nameg[ss.type]); if (oneline)
out(" type:%s", stype_nameg[ss.type]);
else
out("\n type:%s", stype_nameg[ss.type]);
out(" cong:%s ", out(" cong:%s ",
stat[TIPC_NLA_SOCK_STAT_LINK_CONG] ? "link" : stat[TIPC_NLA_SOCK_STAT_LINK_CONG] ? "link" :
stat[TIPC_NLA_SOCK_STAT_CONN_CONG] ? "conn" : "none"); stat[TIPC_NLA_SOCK_STAT_CONN_CONG] ? "conn" : "none");
@ -4877,6 +4903,7 @@ static void _usage(FILE *dest)
"\n" "\n"
" -K, --kill forcibly close sockets, display what was closed\n" " -K, --kill forcibly close sockets, display what was closed\n"
" -H, --no-header Suppress header line\n" " -H, --no-header Suppress header line\n"
" -O, --oneline socket's data printed on a single line\n"
"\n" "\n"
" -A, --query=QUERY, --socket=QUERY\n" " -A, --query=QUERY, --socket=QUERY\n"
" QUERY := {all|inet|tcp|udp|raw|unix|unix_dgram|unix_stream|unix_seqpacket|packet|netlink|vsock_stream|vsock_dgram|tipc}[,QUERY]\n" " QUERY := {all|inet|tcp|udp|raw|unix|unix_dgram|unix_stream|unix_seqpacket|packet|netlink|vsock_stream|vsock_dgram|tipc}[,QUERY]\n"
@ -5003,6 +5030,7 @@ static const struct option long_opts[] = {
{ "kill", 0, 0, 'K' }, { "kill", 0, 0, 'K' },
{ "no-header", 0, 0, 'H' }, { "no-header", 0, 0, 'H' },
{ "xdp", 0, 0, OPT_XDPSOCK}, { "xdp", 0, 0, OPT_XDPSOCK},
{ "oneline", 0, 0, 'O' },
{ 0 } { 0 }
}; };
@ -5018,7 +5046,7 @@ int main(int argc, char *argv[])
int state_filter = 0; int state_filter = 0;
while ((ch = getopt_long(argc, argv, while ((ch = getopt_long(argc, argv,
"dhaletuwxnro460spbEf:miA:D:F:vVzZN:KHS", "dhaletuwxnro460spbEf:miA:D:F:vVzZN:KHSO",
long_opts, NULL)) != EOF) { long_opts, NULL)) != EOF) {
switch (ch) { switch (ch) {
case 'n': case 'n':
@ -5192,6 +5220,9 @@ int main(int argc, char *argv[])
case 'H': case 'H':
show_header = 0; show_header = 0;
break; break;
case 'O':
oneline = 1;
break;
case 'h': case 'h':
help(); help();
case '?': case '?':

View File

@ -268,7 +268,7 @@ static int dev_set_name(struct rd *rd)
mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx); mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx);
mnl_attr_put_strz(rd->nlh, RDMA_NLDEV_ATTR_DEV_NAME, rd_argv(rd)); mnl_attr_put_strz(rd->nlh, RDMA_NLDEV_ATTR_DEV_NAME, rd_argv(rd));
return rd_send_msg(rd); return rd_sendrecv_msg(rd, seq);
} }
static int dev_one_set(struct rd *rd) static int dev_one_set(struct rd *rd)

View File

@ -9,6 +9,9 @@
static int link_help(struct rd *rd) static int link_help(struct rd *rd)
{ {
pr_out("Usage: %s link show [DEV/PORT_INDEX]\n", rd->filename); pr_out("Usage: %s link show [DEV/PORT_INDEX]\n", rd->filename);
pr_out("Usage: %s link add NAME type TYPE netdev NETDEV\n",
rd->filename);
pr_out("Usage: %s link delete NAME\n", rd->filename);
return 0; return 0;
} }
@ -336,10 +339,85 @@ static int link_show(struct rd *rd)
return rd_exec_link(rd, link_one_show, true); return rd_exec_link(rd, link_one_show, true);
} }
static int link_add_netdev(struct rd *rd)
{
char *link_netdev;
uint32_t seq;
if (rd_no_arg(rd)) {
pr_err("Please provide a net device name.\n");
return -EINVAL;
}
link_netdev = rd_argv(rd);
rd_prepare_msg(rd, RDMA_NLDEV_CMD_NEWLINK, &seq,
(NLM_F_REQUEST | NLM_F_ACK));
mnl_attr_put_strz(rd->nlh, RDMA_NLDEV_ATTR_DEV_NAME, rd->link_name);
mnl_attr_put_strz(rd->nlh, RDMA_NLDEV_ATTR_LINK_TYPE, rd->link_type);
mnl_attr_put_strz(rd->nlh, RDMA_NLDEV_ATTR_NDEV_NAME, link_netdev);
return rd_sendrecv_msg(rd, seq);
}
static int link_add_type(struct rd *rd)
{
const struct rd_cmd cmds[] = {
{ NULL, link_help},
{ "netdev", link_add_netdev},
{ 0 }
};
if (rd_no_arg(rd)) {
pr_err("Please provide a link type name.\n");
return -EINVAL;
}
rd->link_type = rd_argv(rd);
rd_arg_inc(rd);
return rd_exec_cmd(rd, cmds, "parameter");
}
static int link_add(struct rd *rd)
{
const struct rd_cmd cmds[] = {
{ NULL, link_help},
{ "type", link_add_type},
{ 0 }
};
if (rd_no_arg(rd)) {
pr_err("Please provide a link name to add.\n");
return -EINVAL;
}
rd->link_name = rd_argv(rd);
rd_arg_inc(rd);
return rd_exec_cmd(rd, cmds, "parameter");
}
static int _link_del(struct rd *rd)
{
uint32_t seq;
if (!rd_no_arg(rd)) {
pr_err("Unknown parameter %s\n", rd_argv(rd));
return -EINVAL;
}
rd_prepare_msg(rd, RDMA_NLDEV_CMD_DELLINK, &seq,
(NLM_F_REQUEST | NLM_F_ACK));
mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx);
return rd_sendrecv_msg(rd, seq);
}
static int link_del(struct rd *rd)
{
return rd_exec_require_dev(rd, _link_del);
}
int cmd_link(struct rd *rd) int cmd_link(struct rd *rd)
{ {
const struct rd_cmd cmds[] = { const struct rd_cmd cmds[] = {
{ NULL, link_show }, { NULL, link_show },
{ "add", link_add },
{ "delete", link_del },
{ "show", link_show }, { "show", link_show },
{ "list", link_show }, { "list", link_show },
{ "help", link_help }, { "help", link_help },

View File

@ -68,7 +68,10 @@ struct rd {
json_writer_t *jw; json_writer_t *jw;
bool json_output; bool json_output;
bool pretty_output; bool pretty_output;
bool suppress_errors;
struct list_head filter_list; struct list_head filter_list;
char *link_name;
char *link_type;
}; };
struct rd_cmd { struct rd_cmd {
@ -119,6 +122,7 @@ bool rd_is_string_filtered_attr(struct rd *rd, const char *key, const char *val,
*/ */
int rd_send_msg(struct rd *rd); int rd_send_msg(struct rd *rd);
int rd_recv_msg(struct rd *rd, mnl_cb_t callback, void *data, uint32_t seq); int rd_recv_msg(struct rd *rd, mnl_cb_t callback, void *data, uint32_t seq);
int rd_sendrecv_msg(struct rd *rd, unsigned int seq);
void rd_prepare_msg(struct rd *rd, uint32_t cmd, uint32_t *seq, uint16_t flags); void rd_prepare_msg(struct rd *rd, uint32_t cmd, uint32_t *seq, uint16_t flags);
int rd_dev_init_cb(const struct nlmsghdr *nlh, void *data); int rd_dev_init_cb(const struct nlmsghdr *nlh, void *data);
int rd_attr_cb(const struct nlattr *attr, void *data); int rd_attr_cb(const struct nlattr *attr, void *data);

View File

@ -31,6 +31,7 @@ int res_qp_idx_parse_cb(const struct nlmsghdr *nlh, void *data);
if (id) { \ if (id) { \
ret = rd_doit_index(rd, &idx); \ ret = rd_doit_index(rd, &idx); \
if (ret) { \ if (ret) { \
rd->suppress_errors = true; \
ret = _res_send_idx_msg(rd, command, \ ret = _res_send_idx_msg(rd, command, \
name##_idx_parse_cb, \ name##_idx_parse_cb, \
idx, id); \ idx, id); \

View File

@ -693,10 +693,28 @@ int rd_recv_msg(struct rd *rd, mnl_cb_t callback, void *data, unsigned int seq)
ret = mnl_cb_run(buf, ret, seq, portid, callback, data); ret = mnl_cb_run(buf, ret, seq, portid, callback, data);
} while (ret > 0); } while (ret > 0);
if (ret < 0 && !rd->suppress_errors)
perror("error");
mnl_socket_close(rd->nl); mnl_socket_close(rd->nl);
return ret; return ret;
} }
static int null_cb(const struct nlmsghdr *nlh, void *data)
{
return MNL_CB_OK;
}
int rd_sendrecv_msg(struct rd *rd, unsigned int seq)
{
int ret;
ret = rd_send_msg(rd);
if (!ret)
ret = rd_recv_msg(rd, null_cb, rd, seq);
return ret;
}
static struct dev_map *_dev_map_lookup(struct rd *rd, const char *dev_name) static struct dev_map *_dev_map_lookup(struct rd *rd, const char *dev_name)
{ {
struct dev_map *dev_map; struct dev_map *dev_map;

View File

@ -75,6 +75,7 @@ TCMODULES += f_matchall.o
TCMODULES += q_cbs.o TCMODULES += q_cbs.o
TCMODULES += q_etf.o TCMODULES += q_etf.o
TCMODULES += q_taprio.o TCMODULES += q_taprio.o
TCMODULES += q_plug.o
TCSO := TCSO :=
ifeq ($(TC_CONFIG_ATM),y) ifeq ($(TC_CONFIG_ATM),y)

76
tc/q_plug.c Normal file
View File

@ -0,0 +1,76 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* q_log.c plug scheduler
*
* Copyright (C) 2019 Paolo Abeni <pabeni@redhat.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "utils.h"
#include "tc_util.h"
static void explain(void)
{
fprintf(stderr, "Usage: ... plug [block | release | release_indefinite | limit NUMBER]\n");
}
static int plug_parse_opt(struct qdisc_util *qu, int argc, char **argv,
struct nlmsghdr *n, const char *dev)
{
struct tc_plug_qopt opt = {};
int ok = 0;
while (argc > 0) {
if (strcmp(*argv, "block") == 0) {
opt.action = TCQ_PLUG_BUFFER;
ok++;
} else if (strcmp(*argv, "release") == 0) {
opt.action = TCQ_PLUG_RELEASE_ONE;
ok++;
} else if (strcmp(*argv, "release_indefinite") == 0) {
opt.action = TCQ_PLUG_RELEASE_INDEFINITE;
ok++;
} else if (strcmp(*argv, "limit") == 0) {
opt.action = TCQ_PLUG_LIMIT;
NEXT_ARG();
if (get_size(&opt.limit, *argv)) {
fprintf(stderr, "Illegal value for \"limit\": \"%s\"\n", *argv);
return -1;
}
ok++;
} else if (strcmp(*argv, "help") == 0) {
explain();
return -1;
} else {
fprintf(stderr, "%s: unknown parameter \"%s\"\n", qu->id, *argv);
explain();
return -1;
}
argc--; argv++;
}
if (ok)
addattr_l(n, 1024, TCA_OPTIONS, &opt, sizeof(opt));
return 0;
}
static int plug_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
{
/* dummy implementation as sch_plug does not implement a dump op */
return 0;
}
struct qdisc_util plug_qdisc_util = {
.id = "plug",
.parse_qopt = plug_parse_opt,
.print_qopt = plug_print_opt,
};

View File

@ -155,8 +155,10 @@ static int taprio_parse_opt(struct qdisc_util *qu, int argc,
{ {
__s32 clockid = CLOCKID_INVALID; __s32 clockid = CLOCKID_INVALID;
struct tc_mqprio_qopt opt = { }; struct tc_mqprio_qopt opt = { };
__s64 cycle_time_extension = 0;
struct list_head sched_entries; struct list_head sched_entries;
struct rtattr *tail; struct rtattr *tail, *l;
__s64 cycle_time = 0;
__s64 base_time = 0; __s64 base_time = 0;
int err, idx; int err, idx;
@ -245,6 +247,29 @@ static int taprio_parse_opt(struct qdisc_util *qu, int argc,
PREV_ARG(); PREV_ARG();
break; break;
} }
} else if (strcmp(*argv, "cycle-time") == 0) {
NEXT_ARG();
if (cycle_time) {
fprintf(stderr, "taprio: duplicate \"cycle-time\" specification\n");
return -1;
}
if (get_s64(&cycle_time, *argv, 10)) {
PREV_ARG();
break;
}
} else if (strcmp(*argv, "cycle-time-extension") == 0) {
NEXT_ARG();
if (cycle_time_extension) {
fprintf(stderr, "taprio: duplicate \"cycle-time-extension\" specification\n");
return -1;
}
if (get_s64(&cycle_time_extension, *argv, 10)) {
PREV_ARG();
break;
}
} else if (strcmp(*argv, "clockid") == 0) { } else if (strcmp(*argv, "clockid") == 0) {
NEXT_ARG(); NEXT_ARG();
if (clockid != CLOCKID_INVALID) { if (clockid != CLOCKID_INVALID) {
@ -268,27 +293,33 @@ static int taprio_parse_opt(struct qdisc_util *qu, int argc,
tail = NLMSG_TAIL(n); tail = NLMSG_TAIL(n);
addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); addattr_l(n, 1024, TCA_OPTIONS, NULL, 0);
if (clockid != CLOCKID_INVALID)
addattr_l(n, 1024, TCA_TAPRIO_ATTR_SCHED_CLOCKID, &clockid, sizeof(clockid));
if (opt.num_tc > 0) if (opt.num_tc > 0)
addattr_l(n, 1024, TCA_TAPRIO_ATTR_PRIOMAP, &opt, sizeof(opt)); addattr_l(n, 1024, TCA_TAPRIO_ATTR_PRIOMAP, &opt, sizeof(opt));
if (base_time) if (base_time)
addattr_l(n, 1024, TCA_TAPRIO_ATTR_SCHED_BASE_TIME, &base_time, sizeof(base_time)); addattr_l(n, 1024, TCA_TAPRIO_ATTR_SCHED_BASE_TIME, &base_time, sizeof(base_time));
addattr_l(n, 1024, TCA_TAPRIO_ATTR_SCHED_CLOCKID, &clockid, sizeof(clockid)); if (cycle_time)
addattr_l(n, 1024, TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME,
&cycle_time, sizeof(cycle_time));
if (!list_empty(&sched_entries)) { if (cycle_time_extension)
struct rtattr *entry_list; addattr_l(n, 1024, TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME_EXTENSION,
entry_list = addattr_nest(n, 1024, TCA_TAPRIO_ATTR_SCHED_ENTRY_LIST | NLA_F_NESTED); &cycle_time_extension, sizeof(cycle_time_extension));
err = add_sched_list(&sched_entries, n); l = addattr_nest(n, 1024, TCA_TAPRIO_ATTR_SCHED_ENTRY_LIST | NLA_F_NESTED);
if (err < 0) {
fprintf(stderr, "Could not add schedule to netlink message\n");
return -1;
}
addattr_nest_end(n, entry_list); err = add_sched_list(&sched_entries, n);
if (err < 0) {
fprintf(stderr, "Could not add schedule to netlink message\n");
return -1;
} }
addattr_nest_end(n, l);
tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
return 0; return 0;
@ -306,6 +337,8 @@ static int print_sched_list(FILE *f, struct rtattr *list)
open_json_array(PRINT_JSON, "schedule"); open_json_array(PRINT_JSON, "schedule");
print_string(PRINT_FP, NULL, "%s", _SL_);
for (item = RTA_DATA(list); RTA_OK(item, rem); item = RTA_NEXT(item, rem)) { for (item = RTA_DATA(list); RTA_OK(item, rem); item = RTA_NEXT(item, rem)) {
struct rtattr *tb[TCA_TAPRIO_SCHED_ENTRY_MAX + 1]; struct rtattr *tb[TCA_TAPRIO_SCHED_ENTRY_MAX + 1];
__u32 index = 0, gatemask = 0, interval = 0; __u32 index = 0, gatemask = 0, interval = 0;
@ -340,12 +373,37 @@ static int print_sched_list(FILE *f, struct rtattr *list)
return 0; return 0;
} }
static int print_schedule(FILE *f, struct rtattr **tb)
{
int64_t base_time = 0, cycle_time = 0, cycle_time_extension = 0;
if (tb[TCA_TAPRIO_ATTR_SCHED_BASE_TIME])
base_time = rta_getattr_s64(tb[TCA_TAPRIO_ATTR_SCHED_BASE_TIME]);
if (tb[TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME])
cycle_time = rta_getattr_s64(tb[TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME]);
if (tb[TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME_EXTENSION])
cycle_time_extension = rta_getattr_s64(
tb[TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME_EXTENSION]);
print_lluint(PRINT_ANY, "base_time", "\tbase-time %lld", base_time);
print_lluint(PRINT_ANY, "cycle_time", " cycle-time %lld", cycle_time);
print_lluint(PRINT_ANY, "cycle_time_extension",
" cycle-time-extension %lld", cycle_time_extension);
print_sched_list(f, tb[TCA_TAPRIO_ATTR_SCHED_ENTRY_LIST]);
return 0;
}
static int taprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) static int taprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
{ {
struct rtattr *tb[TCA_TAPRIO_ATTR_MAX + 1]; struct rtattr *tb[TCA_TAPRIO_ATTR_MAX + 1];
struct tc_mqprio_qopt *qopt = 0; struct tc_mqprio_qopt *qopt = 0;
__s32 clockid = CLOCKID_INVALID; __s32 clockid = CLOCKID_INVALID;
__s64 base_time = 0;
int i; int i;
if (opt == NULL) if (opt == NULL)
@ -378,19 +436,27 @@ static int taprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
print_string(PRINT_FP, NULL, "%s", _SL_); print_string(PRINT_FP, NULL, "%s", _SL_);
if (tb[TCA_TAPRIO_ATTR_SCHED_BASE_TIME])
base_time = rta_getattr_s64(tb[TCA_TAPRIO_ATTR_SCHED_BASE_TIME]);
if (tb[TCA_TAPRIO_ATTR_SCHED_CLOCKID]) if (tb[TCA_TAPRIO_ATTR_SCHED_CLOCKID])
clockid = rta_getattr_s32(tb[TCA_TAPRIO_ATTR_SCHED_CLOCKID]); clockid = rta_getattr_s32(tb[TCA_TAPRIO_ATTR_SCHED_CLOCKID]);
print_string(PRINT_ANY, "clockid", "clockid %s", get_clock_name(clockid)); print_string(PRINT_ANY, "clockid", "clockid %s", get_clock_name(clockid));
print_lluint(PRINT_ANY, "base_time", " base-time %lld", base_time); print_schedule(f, tb);
print_string(PRINT_FP, NULL, "%s", _SL_); if (tb[TCA_TAPRIO_ATTR_ADMIN_SCHED]) {
struct rtattr *t[TCA_TAPRIO_ATTR_MAX + 1];
return print_sched_list(f, tb[TCA_TAPRIO_ATTR_SCHED_ENTRY_LIST]); parse_rtattr_nested(t, TCA_TAPRIO_ATTR_MAX,
tb[TCA_TAPRIO_ATTR_ADMIN_SCHED]);
open_json_object(NULL);
print_schedule(f, t);
close_json_object();
}
return 0;
} }
struct qdisc_util taprio_qdisc_util = { struct qdisc_util taprio_qdisc_util = {

View File

@ -28,6 +28,9 @@
#define PRIORITY_STR "priority" #define PRIORITY_STR "priority"
#define TOLERANCE_STR "tolerance" #define TOLERANCE_STR "tolerance"
#define WINDOW_STR "window" #define WINDOW_STR "window"
#define BROADCAST_STR "broadcast"
static const char tipc_bclink_name[] = "broadcast-link";
static int link_list_cb(const struct nlmsghdr *nlh, void *data) static int link_list_cb(const struct nlmsghdr *nlh, void *data)
{ {
@ -172,10 +175,92 @@ static void cmd_link_get_help(struct cmdl *cmdl)
"PROPERTIES\n" "PROPERTIES\n"
" tolerance - Get link tolerance\n" " tolerance - Get link tolerance\n"
" priority - Get link priority\n" " priority - Get link priority\n"
" window - Get link window\n", " window - Get link window\n"
" broadcast - Get link broadcast\n",
cmdl->argv[0]); cmdl->argv[0]);
} }
static int cmd_link_get_bcast_cb(const struct nlmsghdr *nlh, void *data)
{
int *prop = data;
int prop_ratio = TIPC_NLA_PROP_BROADCAST_RATIO;
struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
struct nlattr *info[TIPC_NLA_MAX + 1] = {};
struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1] = {};
struct nlattr *props[TIPC_NLA_PROP_MAX + 1] = {};
int bc_mode;
mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
if (!info[TIPC_NLA_LINK])
return MNL_CB_ERROR;
mnl_attr_parse_nested(info[TIPC_NLA_LINK], parse_attrs, attrs);
if (!attrs[TIPC_NLA_LINK_PROP])
return MNL_CB_ERROR;
mnl_attr_parse_nested(attrs[TIPC_NLA_LINK_PROP], parse_attrs, props);
if (!props[*prop])
return MNL_CB_ERROR;
bc_mode = mnl_attr_get_u32(props[*prop]);
new_json_obj(json);
open_json_object(NULL);
switch (bc_mode) {
case 0x1:
print_string(PRINT_ANY, "method", "%s\n", "BROADCAST");
break;
case 0x2:
print_string(PRINT_ANY, "method", "%s\n", "REPLICAST");
break;
case 0x4:
print_string(PRINT_ANY, "method", "%s", "AUTOSELECT");
close_json_object();
open_json_object(NULL);
print_uint(PRINT_ANY, "ratio", " ratio:%u%\n",
mnl_attr_get_u32(props[prop_ratio]));
break;
default:
print_string(PRINT_ANY, NULL, "UNKNOWN\n", NULL);
break;
}
close_json_object();
delete_json_obj();
return MNL_CB_OK;
}
static void cmd_link_get_bcast_help(struct cmdl *cmdl)
{
fprintf(stderr, "Usage: %s link get PPROPERTY\n\n"
"PROPERTIES\n"
" broadcast - Get link broadcast\n",
cmdl->argv[0]);
}
static int cmd_link_get_bcast(struct nlmsghdr *nlh, const struct cmd *cmd,
struct cmdl *cmdl, void *data)
{
int prop = TIPC_NLA_PROP_BROADCAST;
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlattr *attrs;
if (help_flag) {
(cmd->help)(cmdl);
return -EINVAL;
}
nlh = msg_init(buf, TIPC_NL_LINK_GET);
if (!nlh) {
fprintf(stderr, "error, message initialisation failed\n");
return -1;
}
attrs = mnl_attr_nest_start(nlh, TIPC_NLA_LINK);
/* Direct to broadcast-link setting */
mnl_attr_put_strz(nlh, TIPC_NLA_LINK_NAME, tipc_bclink_name);
mnl_attr_nest_end(nlh, attrs);
return msg_doit(nlh, cmd_link_get_bcast_cb, &prop);
}
static int cmd_link_get(struct nlmsghdr *nlh, const struct cmd *cmd, static int cmd_link_get(struct nlmsghdr *nlh, const struct cmd *cmd,
struct cmdl *cmdl, void *data) struct cmdl *cmdl, void *data)
{ {
@ -183,6 +268,7 @@ static int cmd_link_get(struct nlmsghdr *nlh, const struct cmd *cmd,
{ PRIORITY_STR, cmd_link_get_prop, cmd_link_get_help }, { PRIORITY_STR, cmd_link_get_prop, cmd_link_get_help },
{ TOLERANCE_STR, cmd_link_get_prop, cmd_link_get_help }, { TOLERANCE_STR, cmd_link_get_prop, cmd_link_get_help },
{ WINDOW_STR, cmd_link_get_prop, cmd_link_get_help }, { WINDOW_STR, cmd_link_get_prop, cmd_link_get_help },
{ BROADCAST_STR, cmd_link_get_bcast, cmd_link_get_bcast_help },
{ NULL } { NULL }
}; };
@ -521,7 +607,8 @@ static void cmd_link_set_help(struct cmdl *cmdl)
"PROPERTIES\n" "PROPERTIES\n"
" tolerance TOLERANCE - Set link tolerance\n" " tolerance TOLERANCE - Set link tolerance\n"
" priority PRIORITY - Set link priority\n" " priority PRIORITY - Set link priority\n"
" window WINDOW - Set link window\n", " window WINDOW - Set link window\n"
" broadcast BROADCAST - Set link broadcast\n",
cmdl->argv[0]); cmdl->argv[0]);
} }
@ -585,6 +672,95 @@ static int cmd_link_set_prop(struct nlmsghdr *nlh, const struct cmd *cmd,
return msg_doit(nlh, link_get_cb, &prop); return msg_doit(nlh, link_get_cb, &prop);
} }
static void cmd_link_set_bcast_help(struct cmdl *cmdl)
{
fprintf(stderr, "Usage: %s link set broadcast PROPERTY\n\n"
"PROPERTIES\n"
" BROADCAST - Forces all multicast traffic to be\n"
" transmitted via broadcast only,\n"
" irrespective of cluster size and number\n"
" of destinations\n\n"
" REPLICAST - Forces all multicast traffic to be\n"
" transmitted via replicast only,\n"
" irrespective of cluster size and number\n"
" of destinations\n\n"
" AUTOSELECT - Auto switching to broadcast or replicast\n"
" depending on cluster size and destination\n"
" node number\n\n"
" ratio SIZE - Set the AUTOSELECT criteria, percentage of\n"
" destination nodes vs cluster size\n\n",
cmdl->argv[0]);
}
static int cmd_link_set_bcast(struct nlmsghdr *nlh, const struct cmd *cmd,
struct cmdl *cmdl, void *data)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlattr *props;
struct nlattr *attrs;
struct opt *opt;
struct opt opts[] = {
{ "BROADCAST", OPT_KEY, NULL },
{ "REPLICAST", OPT_KEY, NULL },
{ "AUTOSELECT", OPT_KEY, NULL },
{ "ratio", OPT_KEYVAL, NULL },
{ NULL }
};
int method = 0;
if (help_flag) {
(cmd->help)(cmdl);
return -EINVAL;
}
if (parse_opts(opts, cmdl) < 0)
return -EINVAL;
for (opt = opts; opt->key; opt++)
if (opt->val)
break;
if (!opt || !opt->key) {
(cmd->help)(cmdl);
return -EINVAL;
}
nlh = msg_init(buf, TIPC_NL_LINK_SET);
if (!nlh) {
fprintf(stderr, "error, message initialisation failed\n");
return -1;
}
attrs = mnl_attr_nest_start(nlh, TIPC_NLA_LINK);
/* Direct to broadcast-link setting */
mnl_attr_put_strz(nlh, TIPC_NLA_LINK_NAME, tipc_bclink_name);
props = mnl_attr_nest_start(nlh, TIPC_NLA_LINK_PROP);
if (get_opt(opts, "BROADCAST"))
method = 0x1;
else if (get_opt(opts, "REPLICAST"))
method = 0x2;
else if (get_opt(opts, "AUTOSELECT"))
method = 0x4;
opt = get_opt(opts, "ratio");
if (!method && !opt) {
(cmd->help)(cmdl);
return -EINVAL;
}
if (method)
mnl_attr_put_u32(nlh, TIPC_NLA_PROP_BROADCAST, method);
if (opt)
mnl_attr_put_u32(nlh, TIPC_NLA_PROP_BROADCAST_RATIO,
atoi(opt->val));
mnl_attr_nest_end(nlh, props);
mnl_attr_nest_end(nlh, attrs);
return msg_doit(nlh, NULL, NULL);
}
static int cmd_link_set(struct nlmsghdr *nlh, const struct cmd *cmd, static int cmd_link_set(struct nlmsghdr *nlh, const struct cmd *cmd,
struct cmdl *cmdl, void *data) struct cmdl *cmdl, void *data)
{ {
@ -592,6 +768,7 @@ static int cmd_link_set(struct nlmsghdr *nlh, const struct cmd *cmd,
{ PRIORITY_STR, cmd_link_set_prop, cmd_link_set_help }, { PRIORITY_STR, cmd_link_set_prop, cmd_link_set_help },
{ TOLERANCE_STR, cmd_link_set_prop, cmd_link_set_help }, { TOLERANCE_STR, cmd_link_set_prop, cmd_link_set_help },
{ WINDOW_STR, cmd_link_set_prop, cmd_link_set_help }, { WINDOW_STR, cmd_link_set_prop, cmd_link_set_help },
{ BROADCAST_STR, cmd_link_set_bcast, cmd_link_set_bcast_help },
{ NULL } { NULL }
}; };