diff --git a/devlink/devlink.c b/devlink/devlink.c index 8ec96c01..007677a5 100644 --- a/devlink/devlink.c +++ b/devlink/devlink.c @@ -4654,6 +4654,7 @@ static int cmd_mon_show_cb(const struct nlmsghdr *nlh, void *data) pr_out_trap_policer(dl, tb, false); break; } + fflush(stdout); return MNL_CB_OK; } diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 378eda20..faf7df1d 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -81,6 +81,12 @@ struct bpf_cgroup_storage_key { __u32 attach_type; /* program attach type */ }; +union bpf_iter_link_info { + struct { + __u32 map_fd; + } map; +}; + /* BPF syscall commands, see bpf(2) man-page for details. */ enum bpf_cmd { BPF_MAP_CREATE, @@ -117,6 +123,7 @@ enum bpf_cmd { BPF_LINK_GET_NEXT_ID, BPF_ENABLE_STATS, BPF_ITER_CREATE, + BPF_LINK_DETACH, }; enum bpf_map_type { @@ -230,6 +237,7 @@ enum bpf_attach_type { BPF_CGROUP_INET_SOCK_RELEASE, BPF_XDP_CPUMAP, BPF_SK_LOOKUP, + BPF_XDP, __MAX_BPF_ATTACH_TYPE }; @@ -242,6 +250,7 @@ enum bpf_link_type { BPF_LINK_TYPE_CGROUP = 3, BPF_LINK_TYPE_ITER = 4, BPF_LINK_TYPE_NETNS = 5, + BPF_LINK_TYPE_XDP = 6, MAX_BPF_LINK_TYPE, }; @@ -607,9 +616,14 @@ union bpf_attr { struct { /* struct used by BPF_LINK_CREATE command */ __u32 prog_fd; /* eBPF program to attach */ - __u32 target_fd; /* object to attach to */ + union { + __u32 target_fd; /* object to attach to */ + __u32 target_ifindex; /* target ifindex */ + }; __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 */ } link_create; struct { /* struct used by BPF_LINK_UPDATE command */ @@ -622,6 +636,10 @@ union bpf_attr { __u32 old_prog_fd; } link_update; + struct { + __u32 link_fd; + } link_detach; + struct { /* struct used by BPF_ENABLE_STATS command */ __u32 type; } enable_stats; @@ -3229,7 +3247,7 @@ union bpf_attr { * Return * The id is returned or 0 in case the id could not be retrieved. * - * int bpf_ringbuf_output(void *ringbuf, void *data, u64 size, u64 flags) + * long bpf_ringbuf_output(void *ringbuf, void *data, u64 size, u64 flags) * Description * Copy *size* bytes from *data* into a ring buffer *ringbuf*. * If **BPF_RB_NO_WAKEUP** is specified in *flags*, no notification @@ -4057,6 +4075,9 @@ struct bpf_link_info { __u32 netns_ino; __u32 attach_type; } netns; + struct { + __u32 ifindex; + } xdp; }; } __attribute__((aligned(8))); diff --git a/include/uapi/linux/seg6_iptunnel.h b/include/uapi/linux/seg6_iptunnel.h index 3004e982..ee6d1dd5 100644 --- a/include/uapi/linux/seg6_iptunnel.h +++ b/include/uapi/linux/seg6_iptunnel.h @@ -37,5 +37,4 @@ enum { SEG6_IPTUN_MODE_L2ENCAP, }; - #endif diff --git a/ip/iplink.c b/ip/iplink.c index 7d4b244d..5ec33a98 100644 --- a/ip/iplink.c +++ b/ip/iplink.c @@ -86,26 +86,26 @@ void iplink_usage(void) " [ mtu MTU ]\n" " [ netns { PID | NAME } ]\n" " [ link-netns NAME | link-netnsid ID ]\n" - " [ alias NAME ]\n" - " [ vf NUM [ mac LLADDR ]\n" - " [ vlan VLANID [ qos VLAN-QOS ] [ proto VLAN-PROTO ] ]\n" - " [ rate TXRATE ]\n" - " [ max_tx_rate TXRATE ]\n" - " [ min_tx_rate TXRATE ]\n" - " [ spoofchk { on | off} ]\n" - " [ query_rss { on | off} ]\n" - " [ state { auto | enable | disable} ] ]\n" - " [ trust { on | off} ] ]\n" - " [ node_guid { eui64 } ]\n" - " [ port_guid { eui64 } ]\n" - " [ { xdp | xdpgeneric | xdpdrv | xdpoffload } { off |\n" - " object FILE [ section NAME ] [ verbose ] |\n" - " pinned FILE } ]\n" - " [ master DEVICE ][ vrf NAME ]\n" - " [ nomaster ]\n" - " [ addrgenmode { eui64 | none | stable_secret | random } ]\n" - " [ protodown { on | off } ]\n" - " [ gso_max_size BYTES ] | [ gso_max_segs PACKETS ]\n" + " [ alias NAME ]\n" + " [ vf NUM [ mac LLADDR ]\n" + " [ vlan VLANID [ qos VLAN-QOS ] [ proto VLAN-PROTO ] ]\n" + " [ rate TXRATE ]\n" + " [ max_tx_rate TXRATE ]\n" + " [ min_tx_rate TXRATE ]\n" + " [ spoofchk { on | off} ]\n" + " [ query_rss { on | off} ]\n" + " [ state { auto | enable | disable} ]\n" + " [ trust { on | off} ]\n" + " [ node_guid EUI64 ]\n" + " [ port_guid EUI64 ] ]\n" + " [ { xdp | xdpgeneric | xdpdrv | xdpoffload } { off |\n" + " object FILE [ section NAME ] [ verbose ] |\n" + " pinned FILE } ]\n" + " [ master DEVICE ][ vrf NAME ]\n" + " [ nomaster ]\n" + " [ addrgenmode { eui64 | none | stable_secret | random } ]\n" + " [ protodown { on | off } ]\n" + " [ gso_max_size BYTES ] | [ gso_max_segs PACKETS ]\n" "\n" " ip link show [ DEVICE | group GROUP ] [up] [master DEV] [vrf NAME] [type TYPE]\n" "\n" diff --git a/ip/iplink_hsr.c b/ip/iplink_hsr.c index 7d9167d4..da2d03d4 100644 --- a/ip/iplink_hsr.c +++ b/ip/iplink_hsr.c @@ -25,7 +25,7 @@ static void print_usage(FILE *f) { fprintf(f, "Usage:\tip link add name NAME type hsr slave1 SLAVE1-IF slave2 SLAVE2-IF\n" - "\t[ supervision ADDR-BYTE ] [version VERSION]\n" + "\t[ supervision ADDR-BYTE ] [version VERSION] [proto PROTOCOL]\n" "\n" "NAME\n" " name of new hsr device (e.g. hsr0)\n" @@ -35,7 +35,9 @@ static void print_usage(FILE *f) " 0-255; the last byte of the multicast address used for HSR supervision\n" " frames (default = 0)\n" "VERSION\n" - " 0,1; the protocol version to be used. (default = 0)\n"); + " 0,1; the protocol version to be used. (default = 0)\n" + "PROTOCOL\n" + " 0 - HSR, 1 - PRP. (default = 0 - HSR)\n"); } static void usage(void) @@ -49,6 +51,7 @@ static int hsr_parse_opt(struct link_util *lu, int argc, char **argv, int ifindex; unsigned char multicast_spec; unsigned char protocol_version; + unsigned char protocol = HSR_PROTOCOL_HSR; while (argc > 0) { if (matches(*argv, "supervision") == 0) { @@ -64,6 +67,13 @@ static int hsr_parse_opt(struct link_util *lu, int argc, char **argv, invarg("version is invalid", *argv); addattr_l(n, 1024, IFLA_HSR_VERSION, &protocol_version, 1); + } else if (matches(*argv, "proto") == 0) { + NEXT_ARG(); + if (!(get_u8(&protocol, *argv, 0) == HSR_PROTOCOL_HSR || + get_u8(&protocol, *argv, 0) == HSR_PROTOCOL_PRP)) + invarg("protocol is invalid", *argv); + addattr_l(n, 1024, IFLA_HSR_PROTOCOL, + &protocol, 1); } else if (matches(*argv, "slave1") == 0) { NEXT_ARG(); ifindex = ll_name_to_index(*argv); @@ -140,6 +150,9 @@ static void hsr_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) RTA_PAYLOAD(tb[IFLA_HSR_SUPERVISION_ADDR]), ARPHRD_VOID, b1, sizeof(b1))); + if (tb[IFLA_HSR_PROTOCOL]) + print_hhu(PRINT_ANY, "proto", "proto %hhu ", + rta_getattr_u8(tb[IFLA_HSR_PROTOCOL])); } static void hsr_print_help(struct link_util *lu, int argc, char **argv, diff --git a/ip/ipmaddr.c b/ip/ipmaddr.c index 3400e055..d41ac63a 100644 --- a/ip/ipmaddr.c +++ b/ip/ipmaddr.c @@ -291,7 +291,7 @@ static int multiaddr_modify(int cmd, int argc, char **argv) { struct ifreq ifr = {}; int family; - int fd; + int fd, len; if (cmd == RTM_NEWADDR) cmd = SIOCADDMULTI; @@ -313,9 +313,14 @@ static int multiaddr_modify(int cmd, int argc, char **argv) usage(); if (ifr.ifr_hwaddr.sa_data[0]) duparg("address", *argv); - if (ll_addr_a2n(ifr.ifr_hwaddr.sa_data, - 14, *argv) < 0) { - fprintf(stderr, "Error: \"%s\" is not a legal ll address.\n", *argv); + len = ll_addr_a2n(ifr.ifr_hwaddr.sa_data, + sizeof(ifr.ifr_hwaddr.sa_data), + *argv); + if (len < 0) + exit(1); + + if (len != ETH_ALEN) { + fprintf(stderr, "Error: Invalid address length %d - must be %d bytes\n", len, ETH_ALEN); exit(1); } } diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in index c6bd2c53..367105b7 100644 --- a/man/man8/ip-link.8.in +++ b/man/man8/ip-link.8.in @@ -1404,7 +1404,8 @@ the following additional arguments are supported: .BI slave1 " SLAVE1-IF " slave2 " SLAVE2-IF " .RB [ " supervision" .IR ADDR-BYTE " ] [" -.BR version " { " 0 " | " 1 " } ]" +.BR version " { " 0 " | " 1 " } [" +.BR proto " { " 0 " | " 1 " } ]" .in +8 .sp @@ -1425,6 +1426,12 @@ Default option is "0", possible values 0-255. - Selects the protocol version of the interface. Default option is "0", which corresponds to the 2010 version of the HSR standard. Option "1" activates the 2012 version. + +.BR proto " { " 0 " | " 1 " }" +- Selects the protocol at the interface. Default option is "0", which +corresponds to the HSR standard. Option "1" activates the Parallel +Redundancy Protocol (PRP). +. .in -8 .TP diff --git a/rdma/res.c b/rdma/res.c index c99a1fcb..dc12bbe4 100644 --- a/rdma/res.c +++ b/rdma/res.c @@ -157,26 +157,36 @@ void print_comm(struct rd *rd, const char *str, struct nlattr **nla_line) if (!str) return; - if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) + if (nla_line[RDMA_NLDEV_ATTR_RES_PID] || rd->json_output) snprintf(tmp, sizeof(tmp), "%s", str); else snprintf(tmp, sizeof(tmp), "[%s]", str); - print_color_string(PRINT_ANY, COLOR_NONE, "comm", "comm %s ", str); + print_color_string(PRINT_ANY, COLOR_NONE, "comm", "comm %s ", tmp); } void print_dev(struct rd *rd, uint32_t idx, const char *name) { - print_color_int(PRINT_ANY, COLOR_NONE, "ifindex", "ifindex %d ", idx); - print_color_string(PRINT_ANY, COLOR_NONE, "ifname", "ifname %s ", name); + print_color_int(PRINT_ANY, COLOR_NONE, "ifindex", NULL, idx); + print_color_string(PRINT_ANY, COLOR_NONE, "ifname", "dev %s ", name); } void print_link(struct rd *rd, uint32_t idx, const char *name, uint32_t port, struct nlattr **nla_line) { + char tmp[64] = {}; + print_color_uint(PRINT_JSON, COLOR_NONE, "ifindex", NULL, idx); - print_color_string(PRINT_ANY, COLOR_NONE, "ifname", "link %s/", name); - if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]) - print_color_uint(PRINT_ANY, COLOR_NONE, "port", "%u ", port); + print_color_string(PRINT_ANY, COLOR_NONE, "ifname", NULL, name); + if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]) { + print_color_uint(PRINT_ANY, COLOR_NONE, "port", NULL, port); + snprintf(tmp, sizeof(tmp), "%s/%d", name, port); + } else { + snprintf(tmp, sizeof(tmp), "%s/-", name); + } + + if (!rd->json_output) + print_color_string(PRINT_ANY, COLOR_NONE, NULL, "link %s ", + tmp); } void print_qp_type(struct rd *rd, uint32_t val)