diff --git a/Makefile b/Makefile index a87826fe..a3cc88f1 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,7 @@ HOSTCC ?= $(CC) DEFINES += -D_GNU_SOURCE # Turn on transparent support for LFS DEFINES += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -CCOPTS = -O2 +CCOPTS = -O2 -pipe WFLAGS := -Wall -Wstrict-prototypes -Wmissing-prototypes WFLAGS += -Wmissing-declarations -Wold-style-definition -Wformat=2 diff --git a/devlink/mnlg.c b/devlink/mnlg.c index 37cc25dd..ee125df0 100644 --- a/devlink/mnlg.c +++ b/devlink/mnlg.c @@ -85,6 +85,13 @@ static int mnlg_cb_error(const struct nlmsghdr *nlh, void *data) static int mnlg_cb_stop(const struct nlmsghdr *nlh, void *data) { + int len = *(int *)NLMSG_DATA(nlh); + + if (len < 0) { + errno = -len; + nl_dump_ext_ack_done(nlh, len); + return MNL_CB_ERROR; + } return MNL_CB_STOP; } diff --git a/include/libnetlink.h b/include/libnetlink.h index 1ddba8dc..311cf3fc 100644 --- a/include/libnetlink.h +++ b/include/libnetlink.h @@ -134,6 +134,7 @@ int rtnl_send(struct rtnl_handle *rth, const void *buf, int) int rtnl_send_check(struct rtnl_handle *rth, const void *buf, int) __attribute__((warn_unused_result)); int nl_dump_ext_ack(const struct nlmsghdr *nlh, nl_ext_ack_fn_t errfn); +int nl_dump_ext_ack_done(const struct nlmsghdr *nlh, int error); int addattr(struct nlmsghdr *n, int maxlen, int type); int addattr8(struct nlmsghdr *n, int maxlen, int type, __u8 data); diff --git a/include/namespace.h b/include/namespace.h index 89cdda11..e47f9b5d 100644 --- a/include/namespace.h +++ b/include/namespace.h @@ -49,8 +49,6 @@ static inline int setns(int fd, int nstype) } #endif /* HAVE_SETNS */ -void netns_save(void); -void netns_restore(void); int netns_switch(char *netns); int netns_get_fd(const char *netns); int netns_foreach(int (*func)(char *nsname, void *arg), void *arg); diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 12df263b..d7b5063f 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -192,6 +192,8 @@ enum bpf_attach_type { BPF_LIRC_MODE2, BPF_FLOW_DISSECTOR, BPF_CGROUP_SYSCTL, + BPF_CGROUP_UDP4_RECVMSG, + BPF_CGROUP_UDP6_RECVMSG, __MAX_BPF_ATTACH_TYPE }; @@ -3409,8 +3411,8 @@ struct bpf_raw_tracepoint_args { /* DIRECT: Skip the FIB rules and go to FIB table associated with device * OUTPUT: Do lookup from egress perspective; default is ingress */ -#define BPF_FIB_LOOKUP_DIRECT BIT(0) -#define BPF_FIB_LOOKUP_OUTPUT BIT(1) +#define BPF_FIB_LOOKUP_DIRECT (1U << 0) +#define BPF_FIB_LOOKUP_OUTPUT (1U << 1) enum { BPF_FIB_LKUP_RET_SUCCESS, /* lookup successful */ diff --git a/include/uapi/linux/if_infiniband.h b/include/uapi/linux/if_infiniband.h new file mode 100644 index 00000000..0fc33bf3 --- /dev/null +++ b/include/uapi/linux/if_infiniband.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ +/* + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available at + * , or the OpenIB.org BSD + * license, available in the LICENSE.TXT file accompanying this + * software. These details are also available at + * . + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Copyright (c) 2004 Topspin Communications. All rights reserved. + * + * $Id$ + */ + +#ifndef _LINUX_IF_INFINIBAND_H +#define _LINUX_IF_INFINIBAND_H + +#define INFINIBAND_ALEN 20 /* Octets in IPoIB HW addr */ + +#endif /* _LINUX_IF_INFINIBAND_H */ diff --git a/include/uapi/linux/snmp.h b/include/uapi/linux/snmp.h index 74904e9d..549a31c2 100644 --- a/include/uapi/linux/snmp.h +++ b/include/uapi/linux/snmp.h @@ -283,6 +283,7 @@ enum LINUX_MIB_TCPACKCOMPRESSED, /* TCPAckCompressed */ LINUX_MIB_TCPZEROWINDOWDROP, /* TCPZeroWindowDrop */ LINUX_MIB_TCPRCVQDROP, /* TCPRcvQDrop */ + LINUX_MIB_TCPWQUEUETOOBIG, /* TCPWqueueTooBig */ LINUX_MIB_TCPFASTOPENPASSIVEALTKEY, /* TCPFastOpenPassiveAltKey */ __LINUX_MIB_MAX }; diff --git a/include/utils.h b/include/utils.h index 0f57ee97..ec0231f9 100644 --- a/include/utils.h +++ b/include/utils.h @@ -295,14 +295,12 @@ extern int cmdlineno; ssize_t getcmdline(char **line, size_t *len, FILE *in); int makeargs(char *line, char *argv[], int maxargs); -int do_each_netns(int (*func)(char *nsname, void *arg), void *arg, - bool show_label); - char *int_to_str(int val, char *buf); int get_guid(__u64 *guid, const char *arg); int get_real_family(int rtm_type, int rtm_family); -int cmd_exec(const char *cmd, char **argv, bool do_fork); +int cmd_exec(const char *cmd, char **argv, bool do_fork, + int (*setup)(void *), void *arg); int make_path(const char *path, mode_t mode); char *find_cgroup2_mount(void); int get_command_name(const char *pid, char *comm, size_t len); diff --git a/ip/ip.c b/ip/ip.c index 7e35966d..fed26f8d 100644 --- a/ip/ip.c +++ b/ip/ip.c @@ -161,7 +161,6 @@ static int batch(const char *name) if (!force) break; } - netns_restore(); } if (line) free(line); diff --git a/ip/ipaddress.c b/ip/ipaddress.c index 1309ac7c..47e5be74 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -1851,7 +1851,6 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action) ipaddr_reset_filter(oneline, 0); filter.showqueue = 1; filter.family = preferred_family; - filter.group = -1; if (action == IPADD_FLUSH) { if (argc <= 0) { @@ -2108,6 +2107,7 @@ void ipaddr_reset_filter(int oneline, int ifindex) memset(&filter, 0, sizeof(filter)); filter.oneline = oneline; filter.ifindex = ifindex; + filter.group = -1; } static int default_scope(inet_prefix *lcl) diff --git a/ip/ipmacsec.c b/ip/ipmacsec.c index 54cd2b8c..ad6ad7d6 100644 --- a/ip/ipmacsec.c +++ b/ip/ipmacsec.c @@ -95,7 +95,7 @@ static void ipmacsec_usage(void) " ip macsec show DEV\n" "where OPTS := [ pn ] [ on | off ]\n" " ID := 128-bit hex string\n" - " KEY := 128-bit hex string\n" + " KEY := 128-bit or 256-bit hex string\n" " SCI := { sci | port { 1..2^16-1 } address }\n"); exit(-1); @@ -586,14 +586,20 @@ static void print_key(struct rtattr *key) keyid, sizeof(keyid))); } -#define DEFAULT_CIPHER_NAME "GCM-AES-128" +#define CIPHER_NAME_GCM_AES_128 "GCM-AES-128" +#define CIPHER_NAME_GCM_AES_256 "GCM-AES-256" +#define DEFAULT_CIPHER_NAME CIPHER_NAME_GCM_AES_128 static const char *cs_id_to_name(__u64 cid) { switch (cid) { case MACSEC_DEFAULT_CIPHER_ID: - case MACSEC_DEFAULT_CIPHER_ALT: return DEFAULT_CIPHER_NAME; + case MACSEC_CIPHER_ID_GCM_AES_128: + /* MACSEC_DEFAULT_CIPHER_ALT: */ + return CIPHER_NAME_GCM_AES_128; + case MACSEC_CIPHER_ID_GCM_AES_256: + return CIPHER_NAME_GCM_AES_256; default: return "(unknown)"; } @@ -1172,7 +1178,7 @@ static void usage(FILE *f) { fprintf(f, "Usage: ... macsec [ [ address ] port { 1..2^16-1 } | sci ]\n" - " [ cipher { default | gcm-aes-128 } ]\n" + " [ cipher { default | gcm-aes-128 | gcm-aes-256 } ]\n" " [ icvlen { 8..16 } ]\n" " [ encrypt { on | off } ]\n" " [ send_sci { on | off } ]\n" @@ -1217,13 +1223,17 @@ static int macsec_parse_opt(struct link_util *lu, int argc, char **argv, NEXT_ARG(); if (cipher.id) duparg("cipher", *argv); - if (strcmp(*argv, "default") == 0 || - strcmp(*argv, "gcm-aes-128") == 0 || - strcmp(*argv, "GCM-AES-128") == 0) + if (strcmp(*argv, "default") == 0) cipher.id = MACSEC_DEFAULT_CIPHER_ID; + else if (strcmp(*argv, "gcm-aes-128") == 0 || + strcmp(*argv, "GCM-AES-128") == 0) + cipher.id = MACSEC_CIPHER_ID_GCM_AES_128; + else if (strcmp(*argv, "gcm-aes-256") == 0 || + strcmp(*argv, "GCM-AES-256") == 0) + cipher.id = MACSEC_CIPHER_ID_GCM_AES_256; else - invarg("expected: default or gcm-aes-128", - *argv); + invarg("expected: default, gcm-aes-128 or" + " gcm-aes-256", *argv); } else if (strcmp(*argv, "icvlen") == 0) { NEXT_ARG(); if (cipher.icv_len) diff --git a/ip/ipmroute.c b/ip/ipmroute.c index 8b3c4c25..656ea0dc 100644 --- a/ip/ipmroute.c +++ b/ip/ipmroute.c @@ -46,7 +46,7 @@ static void usage(void) exit(-1); } -struct rtfilter { +static struct rtfilter { int tb; int af; int iif; diff --git a/ip/ipnetns.c b/ip/ipnetns.c index 8ead0c4c..a883f210 100644 --- a/ip/ipnetns.c +++ b/ip/ipnetns.c @@ -45,6 +45,7 @@ static int usage(void) static struct rtnl_handle rtnsh = { .fd = -1 }; static int have_rtnl_getnsid = -1; +static int saved_netns = -1; static int ipnetns_accept_msg(struct rtnl_ctrl_data *ctrl, struct nlmsghdr *n, void *arg) @@ -396,11 +397,24 @@ static int netns_list(int argc, char **argv) return 0; } +static int do_switch(void *arg) +{ + char *netns = arg; + + /* we just changed namespaces. clear any vrf association + * with prior namespace before exec'ing command + */ + vrf_reset(); + + return netns_switch(netns); +} + static int on_netns_exec(char *nsname, void *arg) { char **argv = arg; - cmd_exec(argv[1], argv + 1, true); + printf("\nnetns: %s\n", nsname); + cmd_exec(argv[0], argv, true, do_switch, nsname); return 0; } @@ -409,8 +423,6 @@ static int netns_exec(int argc, char **argv) /* Setup the proper environment for apps that are not netns * aware, and execute a program in that environment. */ - const char *cmd; - if (argc < 1 && !do_all) { fprintf(stderr, "No netns name specified\n"); return -1; @@ -421,22 +433,13 @@ static int netns_exec(int argc, char **argv) } if (do_all) - return do_each_netns(on_netns_exec, --argv, 1); - - if (netns_switch(argv[0])) - return -1; - - /* we just changed namespaces. clear any vrf association - * with prior namespace before exec'ing command - */ - vrf_reset(); + return netns_foreach(on_netns_exec, argv); /* ip must return the status of the child, * but do_cmd() will add a minus to this, * so let's add another one here to cancel it. */ - cmd = argv[1]; - return -cmd_exec(cmd, argv + 1, !!batch_mode); + return -cmd_exec(argv[1], argv + 1, !!batch_mode, do_switch, argv[0]); } static int is_pid(const char *str) @@ -633,6 +636,33 @@ static int create_netns_dir(void) return 0; } +/* Obtain a FD for the current namespace, so we can reenter it later */ +static void netns_save(void) +{ + if (saved_netns != -1) + return; + + saved_netns = open("/proc/self/ns/net", O_RDONLY | O_CLOEXEC); + if (saved_netns == -1) { + perror("Cannot open init namespace"); + exit(1); + } +} + +static void netns_restore(void) +{ + if (saved_netns == -1) + return; + + if (setns(saved_netns, CLONE_NEWNET)) { + perror("setns"); + exit(1); + } + + close(saved_netns); + saved_netns = -1; +} + static int netns_add(int argc, char **argv, bool create) { /* This function creates a new network namespace and @@ -726,9 +756,12 @@ static int netns_add(int argc, char **argv, bool create) proc_path, netns_path, strerror(errno)); goto out_delete; } + netns_restore(); + return 0; out_delete: if (create) { + netns_restore(); netns_delete(argc, argv); } else if (unlink(netns_path) < 0) { fprintf(stderr, "Cannot remove namespace file \"%s\": %s\n", diff --git a/ip/ipvrf.c b/ip/ipvrf.c index a13cf653..43366f6e 100644 --- a/ip/ipvrf.c +++ b/ip/ipvrf.c @@ -442,6 +442,13 @@ out: return rc; } +static int do_switch(void *arg) +{ + char *vrf = arg; + + return vrf_switch(vrf); +} + static int ipvrf_exec(int argc, char **argv) { if (argc < 1) { @@ -453,10 +460,7 @@ static int ipvrf_exec(int argc, char **argv) return -1; } - if (vrf_switch(argv[0])) - return -1; - - return -cmd_exec(argv[1], argv + 1, !!batch_mode); + return -cmd_exec(argv[1], argv + 1, !!batch_mode, do_switch, argv[0]); } /* reset VRF association of current process to default VRF; diff --git a/lib/exec.c b/lib/exec.c index eb36b59d..9b1c8f4a 100644 --- a/lib/exec.c +++ b/lib/exec.c @@ -5,8 +5,10 @@ #include #include "utils.h" +#include "namespace.h" -int cmd_exec(const char *cmd, char **argv, bool do_fork) +int cmd_exec(const char *cmd, char **argv, bool do_fork, + int (*setup)(void *), void *arg) { fflush(stdout); if (do_fork) { @@ -34,6 +36,9 @@ int cmd_exec(const char *cmd, char **argv, bool do_fork) } } + if (setup && setup(arg)) + return -1; + if (execvp(cmd, argv) < 0) fprintf(stderr, "exec of \"%s\" failed: %s\n", cmd, strerror(errno)); diff --git a/lib/libnetlink.c b/lib/libnetlink.c index af2a3bbf..8c490f89 100644 --- a/lib/libnetlink.c +++ b/lib/libnetlink.c @@ -126,7 +126,7 @@ int nl_dump_ext_ack(const struct nlmsghdr *nlh, nl_ext_ack_fn_t errfn) return 0; } -static int nl_dump_ext_ack_done(const struct nlmsghdr *nlh, int error) +int nl_dump_ext_ack_done(const struct nlmsghdr *nlh, int error) { struct nlattr *tb[NLMSGERR_ATTR_MAX + 1] = {}; unsigned int hlen = sizeof(int); @@ -156,7 +156,7 @@ int nl_dump_ext_ack(const struct nlmsghdr *nlh, nl_ext_ack_fn_t errfn) return 0; } -static int nl_dump_ext_ack_done(const struct nlmsghdr *nlh, int error) +int nl_dump_ext_ack_done(const struct nlmsghdr *nlh, int error) { return 0; } diff --git a/lib/namespace.c b/lib/namespace.c index a2aea57a..06ae0a48 100644 --- a/lib/namespace.c +++ b/lib/namespace.c @@ -15,35 +15,6 @@ #include "utils.h" #include "namespace.h" -static int saved_netns = -1; - -/* Obtain a FD for the current namespace, so we can reenter it later */ -void netns_save(void) -{ - if (saved_netns != -1) - return; - - saved_netns = open("/proc/self/ns/net", O_RDONLY | O_CLOEXEC); - if (saved_netns == -1) { - perror("Cannot open init namespace"); - exit(1); - } -} - -void netns_restore(void) -{ - if (saved_netns == -1) - return; - - if (setns(saved_netns, CLONE_NEWNET)) { - perror("setns"); - exit(1); - } - - close(saved_netns); - saved_netns = -1; -} - static void bind_etc(const char *name) { char etc_netns_path[sizeof(NETNS_ETC_DIR) + NAME_MAX]; @@ -90,8 +61,6 @@ int netns_switch(char *name) return -1; } - netns_save(); - if (setns(netns, CLONE_NEWNET) < 0) { fprintf(stderr, "setting the network namespace \"%s\" failed: %s\n", name, strerror(errno)); diff --git a/lib/utils.c b/lib/utils.c index a81c0700..be0f11b0 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -1418,33 +1418,6 @@ void print_nlmsg_timestamp(FILE *fp, const struct nlmsghdr *n) fprintf(fp, "Timestamp: %s %lu us\n", tstr, usecs); } -static int on_netns(char *nsname, void *arg) -{ - struct netns_func *f = arg; - - if (netns_switch(nsname)) - return -1; - - return f->func(nsname, f->arg); -} - -static int on_netns_label(char *nsname, void *arg) -{ - printf("\nnetns: %s\n", nsname); - return on_netns(nsname, arg); -} - -int do_each_netns(int (*func)(char *nsname, void *arg), void *arg, - bool show_label) -{ - struct netns_func nsf = { .func = func, .arg = arg }; - - if (show_label) - return netns_foreach(on_netns_label, &nsf); - - return netns_foreach(on_netns, &nsf); -} - char *int_to_str(int val, char *buf) { sprintf(buf, "%d", val); diff --git a/man/man8/ip-macsec.8 b/man/man8/ip-macsec.8 index 1aca3bdc..4fd8a5b6 100644 --- a/man/man8/ip-macsec.8 +++ b/man/man8/ip-macsec.8 @@ -10,7 +10,7 @@ ip-macsec \- MACsec device configuration | .BI sci " " ] [ -.BR cipher " { " default " | " gcm-aes-128 " } ] [" +.BR cipher " { " default " | " gcm-aes-128 " | "gcm-aes-256" } ] [" .BI icvlen " ICVLEN" ] [ .BR encrypt " { " on " | " off " } ] [" diff --git a/testsuite/Makefile b/testsuite/Makefile index 94a4a8c6..4451f316 100644 --- a/testsuite/Makefile +++ b/testsuite/Makefile @@ -18,9 +18,9 @@ KENVFN := $(shell mktemp /tmp/tc_testkenv.XXXXXX) ifneq (,$(wildcard /proc/config.gz)) KCPATH := /proc/config.gz else -KVER := $(shell uname -r) -KCPATHS := /lib/modules/$(KVER)/config /boot/config-$(KVER) -KCPATH := $(firstword $(wildcard $(KCPATHS))) + KVER := $(shell uname -r) + KCPATHS := /lib/modules/$(KVER)/config /boot/config-$(KVER) + KCPATH := $(firstword $(wildcard $(KCPATHS))) endif .PHONY: compile listtests alltests configure $(TESTS)