diff --git a/include/linux/if_tunnel.h b/include/linux/if_tunnel.h index 1fbd86bf..e0c3c0a3 100644 --- a/include/linux/if_tunnel.h +++ b/include/linux/if_tunnel.h @@ -2,6 +2,9 @@ #define _IF_TUNNEL_H_ #include +#include +#include +#include #include diff --git a/include/linux/libc-compat.h b/include/linux/libc-compat.h index 2280d3f1..f38571da 100644 --- a/include/linux/libc-compat.h +++ b/include/linux/libc-compat.h @@ -139,6 +139,25 @@ #endif /* _NETINET_IN_H */ +/* Coordinate with glibc netipx/ipx.h header. */ +#if defined(__NETIPX_IPX_H) + +#define __UAPI_DEF_SOCKADDR_IPX 0 +#define __UAPI_DEF_IPX_ROUTE_DEFINITION 0 +#define __UAPI_DEF_IPX_INTERFACE_DEFINITION 0 +#define __UAPI_DEF_IPX_CONFIG_DATA 0 +#define __UAPI_DEF_IPX_ROUTE_DEF 0 + +#else /* defined(__NETIPX_IPX_H) */ + +#define __UAPI_DEF_SOCKADDR_IPX 1 +#define __UAPI_DEF_IPX_ROUTE_DEFINITION 1 +#define __UAPI_DEF_IPX_INTERFACE_DEFINITION 1 +#define __UAPI_DEF_IPX_CONFIG_DATA 1 +#define __UAPI_DEF_IPX_ROUTE_DEF 1 + +#endif /* defined(__NETIPX_IPX_H) */ + /* Definitions for xattr.h */ #if defined(_SYS_XATTR_H) #define __UAPI_DEF_XATTR 0 @@ -179,6 +198,13 @@ #define __UAPI_DEF_IN6_PKTINFO 1 #define __UAPI_DEF_IP6_MTUINFO 1 +/* Definitions for ipx.h */ +#define __UAPI_DEF_SOCKADDR_IPX 1 +#define __UAPI_DEF_IPX_ROUTE_DEFINITION 1 +#define __UAPI_DEF_IPX_INTERFACE_DEFINITION 1 +#define __UAPI_DEF_IPX_CONFIG_DATA 1 +#define __UAPI_DEF_IPX_ROUTE_DEF 1 + /* Definitions for xattr.h */ #define __UAPI_DEF_XATTR 1 diff --git a/include/utils.h b/include/utils.h index 82f1aa7d..1b4f939c 100644 --- a/include/utils.h +++ b/include/utils.h @@ -249,5 +249,6 @@ int do_each_netns(int (*func)(char *nsname, void *arg), void *arg, 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); #endif /* __UTILS_H__ */ diff --git a/ip/ipmacsec.c b/ip/ipmacsec.c index 6bd1f54f..2e670e9e 100644 --- a/ip/ipmacsec.c +++ b/ip/ipmacsec.c @@ -95,7 +95,7 @@ static void ipmacsec_usage(void) fprintf(stderr, "where OPTS := [ pn ] [ on | off ]\n"); fprintf(stderr, " ID := 128-bit hex string\n"); fprintf(stderr, " KEY := 128-bit hex string\n"); - fprintf(stderr, " SCI := { sci | port address }\n"); + fprintf(stderr, " SCI := { sci | port { 1..2^16-1 } address }\n"); exit(-1); } @@ -134,12 +134,12 @@ static int get_an(__u8 *val, const char *arg) static int get_sci(__u64 *sci, const char *arg) { - return get_u64(sci, arg, 16); + return get_be64(sci, arg, 16); } static int get_port(__be16 *port, const char *arg) { - return get_be16(port, arg, 10); + return get_be16(port, arg, 0); } #define _STR(a) #a @@ -776,7 +776,7 @@ static void print_tx_sc(const char *prefix, __u64 sci, __u8 encoding_sa, struct rtattr *a; int rem; - printf("%sTXSC: %016llx on SA %d\n", prefix, sci, encoding_sa); + printf("%sTXSC: %016llx on SA %d\n", prefix, ntohll(sci), encoding_sa); print_secy_stats(prefix, secy_stats); print_txsc_stats(prefix, txsc_stats); @@ -845,7 +845,7 @@ static void print_rx_sc(const char *prefix, __u64 sci, __u8 active, struct rtattr *a; int rem; - printf("%sRXSC: %016llx, state %s\n", prefix, sci, + printf("%sRXSC: %016llx, state %s\n", prefix, ntohll(sci), values_on_off[!!active]); print_rxsc_stats(prefix, rxsc_stats); @@ -1018,7 +1018,7 @@ static void macsec_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) if (tb[IFLA_MACSEC_SCI]) { fprintf(f, "sci %016llx ", - rta_getattr_u64(tb[IFLA_MACSEC_SCI])); + ntohll(rta_getattr_u64(tb[IFLA_MACSEC_SCI]))); } print_flag(f, tb, "protect", IFLA_MACSEC_PROTECT); @@ -1069,7 +1069,7 @@ static bool check_txsc_flags(bool es, bool scb, bool sci) static void usage(FILE *f) { fprintf(f, - "Usage: ... macsec [ port PORT | sci SCI ]\n" + "Usage: ... macsec [ [ address ] port { 1..2^16-1 } | sci ]\n" " [ cipher { default | gcm-aes-128 } ]\n" " [ icvlen { 8..16 } ]\n" " [ encrypt { on | off } ]\n" diff --git a/ip/ipmroute.c b/ip/ipmroute.c index 5d6922a2..133367a2 100644 --- a/ip/ipmroute.c +++ b/ip/ipmroute.c @@ -112,7 +112,7 @@ int print_mroute(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) return 0; } - family = r->rtm_family == RTNL_FAMILY_IPMR ? AF_INET : AF_INET6; + family = get_real_family(r->rtm_type, r->rtm_family); if (n->nlmsg_type == RTM_DELROUTE) fprintf(fp, "Deleted "); diff --git a/ip/iproute.c b/ip/iproute.c index 4d7da023..0bc01368 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -311,7 +311,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) struct rtmsg *r = NLMSG_DATA(n); int len = n->nlmsg_len; struct rtattr *tb[RTA_MAX+1]; - int host_len; + int host_len, family; __u32 table; SPRINT_BUF(b1); @@ -363,13 +363,14 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) fprintf(fp, "%s ", rtnl_rtntype_n2a(r->rtm_type, b1, sizeof(b1))); if (tb[RTA_DST]) { + family = get_real_family(r->rtm_type, r->rtm_family); if (r->rtm_dst_len != host_len) { fprintf(fp, "%s/%u ", - rt_addr_n2a_rta(r->rtm_family, tb[RTA_DST]), + rt_addr_n2a_rta(family, tb[RTA_DST]), r->rtm_dst_len); } else { fprintf(fp, "%s ", - format_host_rta(r->rtm_family, tb[RTA_DST])); + format_host_rta(family, tb[RTA_DST])); } } else if (r->rtm_dst_len) { fprintf(fp, "0/%d ", r->rtm_dst_len); @@ -377,13 +378,14 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) fprintf(fp, "default "); } if (tb[RTA_SRC]) { + family = get_real_family(r->rtm_type, r->rtm_family); if (r->rtm_src_len != host_len) { fprintf(fp, "from %s/%u ", - rt_addr_n2a_rta(r->rtm_family, tb[RTA_SRC]), + rt_addr_n2a_rta(family, tb[RTA_SRC]), r->rtm_src_len); } else { fprintf(fp, "from %s ", - format_host_rta(r->rtm_family, tb[RTA_SRC])); + format_host_rta(family, tb[RTA_SRC])); } } else if (r->rtm_src_len) { fprintf(fp, "from 0/%u ", r->rtm_src_len); diff --git a/ip/iprule.c b/ip/iprule.c index 8f242067..70562c55 100644 --- a/ip/iprule.c +++ b/ip/iprule.c @@ -346,6 +346,11 @@ static int iprule_modify(int cmd, int argc, char **argv) req.r.rtm_type = RTN_UNICAST; } + if (cmd == RTM_DELRULE && argc == 0) { + fprintf(stderr, "\"ip rule del\" requires arguments.\n"); + return -1; + } + while (argc > 0) { if (strcmp(*argv, "not") == 0) { req.r.rtm_flags |= FIB_RULE_INVERT; diff --git a/ip/iptuntap.c b/ip/iptuntap.c index 43774f96..34fb0cf3 100644 --- a/ip/iptuntap.c +++ b/ip/iptuntap.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "rt_names.h" #include "utils.h" @@ -104,7 +105,8 @@ static int tap_del_ioctl(struct ifreq *ifr) return ret; } -static int parse_args(int argc, char **argv, struct ifreq *ifr, uid_t *uid, gid_t *gid) +static int parse_args(int argc, char **argv, + struct ifreq *ifr, uid_t *uid, gid_t *gid) { int count = 0; @@ -273,6 +275,110 @@ static void print_flags(long flags) printf(" UNKNOWN_FLAGS:%lx", flags); } +static char *pid_name(pid_t pid) +{ + char *comm; + FILE *f; + int err; + + err = asprintf(&comm, "/proc/%d/comm", pid); + if (err < 0) + return NULL; + + f = fopen(comm, "r"); + free(comm); + if (!f) { + perror("fopen"); + return NULL; + } + + if (fscanf(f, "%ms\n", &comm) != 1) { + perror("fscanf"); + comm = NULL; + } + + + if (fclose(f)) + perror("fclose"); + + return comm; +} + +static void show_processes(const char *name) +{ + glob_t globbuf = { }; + char **fd_path; + int err; + + err = glob("/proc/[0-9]*/fd/[0-9]*", GLOB_NOSORT, + NULL, &globbuf); + if (err) + return; + + fd_path = globbuf.gl_pathv; + while (*fd_path) { + const char *dev_net_tun = "/dev/net/tun"; + const size_t linkbuf_len = strlen(dev_net_tun) + 2; + char linkbuf[linkbuf_len], *fdinfo; + int pid, fd; + FILE *f; + + if (sscanf(*fd_path, "/proc/%d/fd/%d", &pid, &fd) != 2) + goto next; + + if (pid == getpid()) + goto next; + + err = readlink(*fd_path, linkbuf, linkbuf_len - 1); + if (err < 0) { + perror("readlink"); + goto next; + } + linkbuf[err] = '\0'; + if (strcmp(dev_net_tun, linkbuf)) + goto next; + + if (asprintf(&fdinfo, "/proc/%d/fdinfo/%d", pid, fd) < 0) + goto next; + + f = fopen(fdinfo, "r"); + free(fdinfo); + if (!f) { + perror("fopen"); + goto next; + } + + while (!feof(f)) { + char *key = NULL, *value = NULL; + + err = fscanf(f, "%m[^:]: %ms\n", &key, &value); + if (err == EOF) { + if (ferror(f)) + perror("fscanf"); + break; + } else if (err == 2 && + !strcmp("iff", key) && + !strcmp(name, value)) { + char *pname = pid_name(pid); + + printf(" %s(%d)", pname ? : "", pid); + free(pname); + } + + free(key); + free(value); + } + if (fclose(f)) + perror("fclose"); + +next: + ++fd_path; + } + + globfree(&globbuf); +} + + static int do_show(int argc, char **argv) { DIR *dir; @@ -302,6 +408,11 @@ static int do_show(int argc, char **argv) if (group != -1) printf(" group %ld", group); printf("\n"); + if (show_details) { + printf("\tAttached to processes:"); + show_processes(d->d_name); + printf("\n"); + } } closedir(dir); return 0; diff --git a/lib/utils.c b/lib/utils.c index 96604746..9ada7737 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -1156,3 +1156,12 @@ int get_guid(__u64 *guid, const char *arg) return 0; } + +/* This is a necessary workaround for multicast route dumps */ +int get_real_family(int rtm_type, int rtm_family) +{ + if (rtm_type != RTN_MULTICAST) + return rtm_family; + + return rtm_family == RTNL_FAMILY_IPMR ? AF_INET : AF_INET6; +} diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in index 58247ced..ffc4160a 100644 --- a/man/man8/ip-link.8.in +++ b/man/man8/ip-link.8.in @@ -952,7 +952,9 @@ For a link of type the following additional arguments are supported: .BI "ip link add link " DEVICE " name " NAME " type macsec" -[ +[ [ +.BI address " " +] .BI port " PORT" | .BI sci " SCI" @@ -976,12 +978,20 @@ the following additional arguments are supported: .in +8 .sp -.BI port " PORT " -- sets the port number for this MACsec device. +.BI address " " +- sets the system identifier component of secure channel for this MACsec device. + +.sp +.BI port " PORT " +- sets the port number component of secure channel for this MACsec device, in a +range from 1 to 65535 inclusive. Numbers with a leading " 0 " or " 0x " are +interpreted as octal and hexadecimal, respectively. .sp .BI sci " SCI " -- sets the SCI for this MACsec device. +- sets the secure channel identifier for this MACsec device. +.I SCI +is a 64bit wide number in hexadecimal format. .sp .BI cipher " CIPHER_SUITE " diff --git a/man/man8/ip-macsec.8 b/man/man8/ip-macsec.8 index 105aeecd..1aca3bdc 100644 --- a/man/man8/ip-macsec.8 +++ b/man/man8/ip-macsec.8 @@ -3,10 +3,12 @@ ip-macsec \- MACsec device configuration .SH "SYNOPSIS" .BI "ip link add link " DEVICE " name " NAME " type macsec " -[ +[ [ +.BI address " " +] .BI port " PORT" | -.BI sci " SCI" +.BI sci " " ] [ .BR cipher " { " default " | " gcm-aes-128 " } ] [" .BI icvlen " ICVLEN" @@ -62,8 +64,12 @@ ip-macsec \- MACsec device configuration .IR SCI " := { " .B sci .IR " | " -.BI port " " address " " +.BI port +.IR PORT +.BI address " " } +.br +.IR PORT " := { " 1..2^16-1 " } " .SH DESCRIPTION diff --git a/man/man8/ip-rule.8 b/man/man8/ip-rule.8 index 1774ae3e..3508d809 100644 --- a/man/man8/ip-rule.8 +++ b/man/man8/ip-rule.8 @@ -93,7 +93,7 @@ Each policy routing rule consists of a .B selector and an .B action predicate. -The RPDB is scanned in order of decreasing priority. The selector +The RPDB is scanned in order of increasing priority. The selector of each rule is applied to {source address, destination address, incoming interface, tos, fwmark} and, if the selector matches the packet, the action is performed. The action predicate may return with success. diff --git a/man/man8/ip.8 b/man/man8/ip.8 index f11fc0b9..8ecb1996 100644 --- a/man/man8/ip.8 +++ b/man/man8/ip.8 @@ -21,7 +21,8 @@ ip \- show / manipulate routing, devices, policy routing and tunnels .IR OBJECT " := { " .BR link " | " address " | " addrlabel " | " route " | " rule " | " neigh " | "\ ntable " | " tunnel " | " tuntap " | " maddress " | " mroute " | " mrule " | "\ - monitor " | " xfrm " | " netns " | " l2tp " | " tcp_metrics " | " token " }" + monitor " | " xfrm " | " netns " | " l2tp " | " tcp_metrics " | " token " | "\ + macsec " }" .sp .ti -8 diff --git a/tc/tc_class.c b/tc/tc_class.c index f3864d22..1a1f1fa2 100644 --- a/tc/tc_class.c +++ b/tc/tc_class.c @@ -52,7 +52,6 @@ static void usage(void) fprintf(stderr, "Where:\n"); fprintf(stderr, "QDISC_KIND := { prio | cbq | etc. }\n"); fprintf(stderr, "OPTIONS := ... try tc class add help\n"); - return; } static int tc_class_modify(int cmd, unsigned int flags, int argc, char **argv) diff --git a/tc/tc_stab.c b/tc/tc_stab.c index dc20dd19..1a0a3e3f 100644 --- a/tc/tc_stab.c +++ b/tc/tc_stab.c @@ -40,7 +40,6 @@ static void stab_help(void) " linklayer : adapting to a linklayer e.g. atm\n" "Example: ... stab overhead 20 linklayer atm\n"); - return; } int check_size_table_opts(struct tc_sizespec *s)