From ef3671781644bd1722e55db4ad9d31047da0e42d Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 6 Apr 2018 13:33:49 +0200 Subject: [PATCH 01/11] bridge: fix typo in hairpin error message No 'g' to hairpin. Fixes: 64108901b737 ("bridge: Add support for setting bridge port attributes") Signed-off-by: Guillaume Nault Signed-off-by: Stephen Hemminger --- bridge/link.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridge/link.c b/bridge/link.c index 579d57e7..8d89aca2 100644 --- a/bridge/link.c +++ b/bridge/link.c @@ -312,7 +312,7 @@ static int brlink_modify(int argc, char **argv) return -1; } else if (strcmp(*argv, "hairpin") == 0) { NEXT_ARG(); - if (!on_off("hairping", &hairpin, *argv)) + if (!on_off("hairpin", &hairpin, *argv)) return -1; } else if (strcmp(*argv, "fastleave") == 0) { NEXT_ARG(); From dcf7997bcd55d2895323d6102a60ff9d535bb680 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 10 Apr 2018 10:48:56 -0700 Subject: [PATCH 02/11] uapi/bpf: update kernel header from 4.17-rc1 Signed-off-by: Stephen Hemminger --- include/uapi/linux/bpf.h | 62 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 24bd85fc..02b96cba 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -94,6 +94,7 @@ enum bpf_cmd { BPF_MAP_GET_FD_BY_ID, BPF_OBJ_GET_INFO_BY_FD, BPF_PROG_QUERY, + BPF_RAW_TRACEPOINT_OPEN, }; enum bpf_map_type { @@ -134,6 +135,8 @@ enum bpf_prog_type { BPF_PROG_TYPE_SK_SKB, BPF_PROG_TYPE_CGROUP_DEVICE, BPF_PROG_TYPE_SK_MSG, + BPF_PROG_TYPE_RAW_TRACEPOINT, + BPF_PROG_TYPE_CGROUP_SOCK_ADDR, }; enum bpf_attach_type { @@ -145,6 +148,12 @@ enum bpf_attach_type { BPF_SK_SKB_STREAM_VERDICT, BPF_CGROUP_DEVICE, BPF_SK_MSG_VERDICT, + BPF_CGROUP_INET4_BIND, + BPF_CGROUP_INET6_BIND, + BPF_CGROUP_INET4_CONNECT, + BPF_CGROUP_INET6_CONNECT, + BPF_CGROUP_INET4_POST_BIND, + BPF_CGROUP_INET6_POST_BIND, __MAX_BPF_ATTACH_TYPE }; @@ -294,6 +303,11 @@ union bpf_attr { __u32 prog_flags; char prog_name[BPF_OBJ_NAME_LEN]; __u32 prog_ifindex; /* ifindex of netdev to prep for */ + /* For some prog types expected attach type must be known at + * load time to verify attach type specific parts of prog + * (context accesses, allowed helpers, etc). + */ + __u32 expected_attach_type; }; struct { /* anonymous struct used by BPF_OBJ_* commands */ @@ -344,6 +358,11 @@ union bpf_attr { __aligned_u64 prog_ids; __u32 prog_cnt; } query; + + struct { + __u64 name; + __u32 prog_fd; + } raw_tracepoint; } __attribute__((aligned(8))); /* BPF helper function descriptions: @@ -729,6 +748,13 @@ union bpf_attr { * @flags: reserved for future use * Return: SK_PASS * + * int bpf_bind(ctx, addr, addr_len) + * Bind socket to address. Only binding to IP is supported, no port can be + * set in addr. + * @ctx: pointer to context of type bpf_sock_addr + * @addr: pointer to struct sockaddr to bind socket to + * @addr_len: length of sockaddr structure + * Return: 0 on success or negative error code */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -794,7 +820,8 @@ union bpf_attr { FN(msg_redirect_map), \ FN(msg_apply_bytes), \ FN(msg_cork_bytes), \ - FN(msg_pull_data), + FN(msg_pull_data), \ + FN(bind), /* integer value in 'imm' field of BPF_CALL instruction selects which helper * function eBPF program intends to call @@ -923,6 +950,15 @@ struct bpf_sock { __u32 protocol; __u32 mark; __u32 priority; + __u32 src_ip4; /* Allows 1,2,4-byte read. + * Stored in network byte order. + */ + __u32 src_ip6[4]; /* Allows 1,2,4-byte read. + * Stored in network byte order. + */ + __u32 src_port; /* Allows 4-byte read. + * Stored in host byte order + */ }; #define XDP_PACKET_HEADROOM 256 @@ -998,6 +1034,26 @@ struct bpf_map_info { __u64 netns_ino; } __attribute__((aligned(8))); +/* User bpf_sock_addr struct to access socket fields and sockaddr struct passed + * by user and intended to be used by socket (e.g. to bind to, depends on + * attach attach type). + */ +struct bpf_sock_addr { + __u32 user_family; /* Allows 4-byte read, but no write. */ + __u32 user_ip4; /* Allows 1,2,4-byte read and 4-byte write. + * Stored in network byte order. + */ + __u32 user_ip6[4]; /* Allows 1,2,4-byte read an 4-byte write. + * Stored in network byte order. + */ + __u32 user_port; /* Allows 4-byte read and write. + * Stored in network byte order + */ + __u32 family; /* Allows 4-byte read, but no write */ + __u32 type; /* Allows 4-byte read, but no write */ + __u32 protocol; /* Allows 4-byte read, but no write */ +}; + /* User bpf_sock_ops struct to access socket values and specify request ops * and their replies. * Some of this fields are in network (bigendian) byte order and may need @@ -1152,4 +1208,8 @@ struct bpf_cgroup_dev_ctx { __u32 minor; }; +struct bpf_raw_tracepoint_args { + __u64 args[0]; +}; + #endif /* __LINUX_BPF_H__ */ From b7d3a4f0090d86901c4cea913cd32e7fbd90cfb6 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 10 Apr 2018 10:49:41 -0700 Subject: [PATCH 03/11] uapi/tipc: update header from 4.17-rc1 Signed-off-by: Stephen Hemminger --- include/uapi/linux/tipc.h | 59 ++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/include/uapi/linux/tipc.h b/include/uapi/linux/tipc.h index 1d92ccb0..88a7251b 100644 --- a/include/uapi/linux/tipc.h +++ b/include/uapi/linux/tipc.h @@ -45,33 +45,33 @@ * TIPC addressing primitives */ -struct tipc_portid { +struct tipc_socket_addr { __u32 ref; __u32 node; }; -struct tipc_name { +struct tipc_service_addr { __u32 type; __u32 instance; }; -struct tipc_name_seq { +struct tipc_service_range { __u32 type; __u32 lower; __u32 upper; }; /* - * Application-accessible port name types + * Application-accessible service types */ -#define TIPC_CFG_SRV 0 /* configuration service name type */ -#define TIPC_TOP_SRV 1 /* topology service name type */ -#define TIPC_LINK_STATE 2 /* link state name type */ -#define TIPC_RESERVED_TYPES 64 /* lowest user-publishable name type */ +#define TIPC_NODE_STATE 0 /* node state service type */ +#define TIPC_TOP_SRV 1 /* topology server service type */ +#define TIPC_LINK_STATE 2 /* link state service type */ +#define TIPC_RESERVED_TYPES 64 /* lowest user-allowed service type */ /* - * Publication scopes when binding port names and port name sequences + * Publication scopes when binding service / service range */ enum tipc_scope { TIPC_CLUSTER_SCOPE = 2, /* 0 can also be used */ @@ -108,28 +108,28 @@ enum tipc_scope { * TIPC topology subscription service definitions */ -#define TIPC_SUB_PORTS 0x01 /* filter for port availability */ -#define TIPC_SUB_SERVICE 0x02 /* filter for service availability */ -#define TIPC_SUB_CANCEL 0x04 /* cancel a subscription */ +#define TIPC_SUB_PORTS 0x01 /* filter: evt at each match */ +#define TIPC_SUB_SERVICE 0x02 /* filter: evt at first up/last down */ +#define TIPC_SUB_CANCEL 0x04 /* filter: cancel a subscription */ #define TIPC_WAIT_FOREVER (~0) /* timeout for permanent subscription */ struct tipc_subscr { - struct tipc_name_seq seq; /* name sequence of interest */ + struct tipc_service_range seq; /* range of interest */ __u32 timeout; /* subscription duration (in ms) */ __u32 filter; /* bitmask of filter options */ char usr_handle[8]; /* available for subscriber use */ }; #define TIPC_PUBLISHED 1 /* publication event */ -#define TIPC_WITHDRAWN 2 /* withdraw event */ +#define TIPC_WITHDRAWN 2 /* withdrawal event */ #define TIPC_SUBSCR_TIMEOUT 3 /* subscription timeout event */ struct tipc_event { __u32 event; /* event type */ - __u32 found_lower; /* matching name seq instances */ - __u32 found_upper; /* " " " " */ - struct tipc_portid port; /* associated port */ + __u32 found_lower; /* matching range */ + __u32 found_upper; /* " " */ + struct tipc_socket_addr port; /* associated socket */ struct tipc_subscr s; /* associated subscription */ }; @@ -149,20 +149,20 @@ struct tipc_event { #define SOL_TIPC 271 #endif -#define TIPC_ADDR_NAMESEQ 1 -#define TIPC_ADDR_MCAST 1 -#define TIPC_ADDR_NAME 2 -#define TIPC_ADDR_ID 3 +#define TIPC_ADDR_MCAST 1 +#define TIPC_SERVICE_RANGE 1 +#define TIPC_SERVICE_ADDR 2 +#define TIPC_SOCKET_ADDR 3 struct sockaddr_tipc { unsigned short family; unsigned char addrtype; signed char scope; union { - struct tipc_portid id; - struct tipc_name_seq nameseq; + struct tipc_socket_addr id; + struct tipc_service_range nameseq; struct { - struct tipc_name name; + struct tipc_service_addr name; __u32 domain; } name; } addr; @@ -216,7 +216,7 @@ struct tipc_group_req { #define TIPC_MAX_MEDIA_NAME 16 #define TIPC_MAX_IF_NAME 16 #define TIPC_MAX_BEARER_NAME 32 -#define TIPC_MAX_LINK_NAME 60 +#define TIPC_MAX_LINK_NAME 68 #define SIOCGETLINKNAME SIOCPROTOPRIVATE @@ -230,8 +230,13 @@ struct tipc_sioc_ln_req { /* The macros and functions below are deprecated: */ +#define TIPC_CFG_SRV 0 #define TIPC_ZONE_SCOPE 1 +#define TIPC_ADDR_NAMESEQ 1 +#define TIPC_ADDR_NAME 2 +#define TIPC_ADDR_ID 3 + #define TIPC_NODE_BITS 12 #define TIPC_CLUSTER_BITS 12 #define TIPC_ZONE_BITS 8 @@ -250,6 +255,10 @@ struct tipc_sioc_ln_req { #define TIPC_ZONE_CLUSTER_MASK (TIPC_ZONE_MASK | TIPC_CLUSTER_MASK) +#define tipc_portid tipc_socket_addr +#define tipc_name tipc_service_addr +#define tipc_name_seq tipc_service_range + static __inline__ __u32 tipc_addr(unsigned int zone, unsigned int cluster, unsigned int node) From 811ee8943c97f88f3842286b9e18a2d028b6b5d3 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 10 Apr 2018 10:50:00 -0700 Subject: [PATCH 04/11] uapi/sctp: update header from 4.17-rc1 Signed-off-by: Stephen Hemminger --- include/uapi/linux/sctp.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h index 30076fd1..2d95ddc1 100644 --- a/include/uapi/linux/sctp.h +++ b/include/uapi/linux/sctp.h @@ -127,6 +127,7 @@ typedef __s32 sctp_assoc_t; #define SCTP_STREAM_SCHEDULER 123 #define SCTP_STREAM_SCHEDULER_VALUE 124 #define SCTP_INTERLEAVING_SUPPORTED 125 +#define SCTP_SENDMSG_CONNECT 126 /* PR-SCTP policies */ #define SCTP_PR_SCTP_NONE 0x0000 From ee53b42fd8b0b0cdb857d0f5bf7467e22a3457d9 Mon Sep 17 00:00:00 2001 From: Jakub Sitnicki Date: Wed, 11 Apr 2018 11:43:11 +0200 Subject: [PATCH 05/11] iproute: Abort if nexthop cannot be parsed Attempt to add a multipath route where a nexthop definition refers to a non-existent device causes 'ip' to crash and burn due to stack buffer overflow: # ip -6 route add fd00::1/64 nexthop dev fake1 Cannot find device "fake1" Cannot find device "fake1" Cannot find device "fake1" ... Segmentation fault (core dumped) Don't ignore errors from the helper routine that parses the nexthop definition, and abort immediately if parsing fails. Signed-off-by: Jakub Sitnicki --- ip/iproute.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ip/iproute.c b/ip/iproute.c index 1d8fd815..44351bc5 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -1038,7 +1038,10 @@ static int parse_nexthops(struct nlmsghdr *n, struct rtmsg *r, memset(rtnh, 0, sizeof(*rtnh)); rtnh->rtnh_len = sizeof(*rtnh); rta->rta_len += rtnh->rtnh_len; - parse_one_nh(n, r, rta, rtnh, &argc, &argv); + if (parse_one_nh(n, r, rta, rtnh, &argc, &argv)) { + fprintf(stderr, "Error: cannot parse nexthop\n"); + exit(-1); + } rtnh = RTNH_NEXT(rtnh); } From d42c7891d26e4d5616a55aac9fe10813767fcf9c Mon Sep 17 00:00:00 2001 From: David Ahern Date: Fri, 13 Apr 2018 09:36:33 -0700 Subject: [PATCH 06/11] utils: Do not reset family for default, any, all addresses Thomas reported a change in behavior with respect to autodectecting address families. Specifically, 'ip ro add default via fe80::1' syntax was failing to treat fe80::1 as an IPv6 address as it did in prior releases. The root causes appears to be a change in family when the default keyword is parsed. 'default', 'any' and 'all' are relevant outside of AF_INET. Leave the family arg as is for these when setting addr. Fixes: 93fa12418dc6 ("utils: Always specify family and ->bytelen in get_prefix_1()") Reported-by: Thomas Deutschmann Signed-off-by: David Ahern Cc: Serhey Popovych --- lib/utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/utils.c b/lib/utils.c index 60d7eb14..8a0bff0b 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -568,7 +568,7 @@ static int __get_addr_1(inet_prefix *addr, const char *name, int family) if (strcmp(name, "default") == 0) { if ((family == AF_DECnet) || (family == AF_MPLS)) return -1; - addr->family = (family != AF_UNSPEC) ? family : AF_INET; + addr->family = family; addr->bytelen = af_byte_len(addr->family); addr->bitlen = -2; addr->flags |= PREFIXLEN_SPECIFIED; @@ -579,7 +579,7 @@ static int __get_addr_1(inet_prefix *addr, const char *name, int family) strcmp(name, "any") == 0) { if ((family == AF_DECnet) || (family == AF_MPLS)) return -1; - addr->family = AF_UNSPEC; + addr->family = family; addr->bytelen = 0; addr->bitlen = -2; return 0; From 7cd3f08b6f2326bcf05194d6287febc32c2bb806 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 20 Apr 2018 09:29:13 -0700 Subject: [PATCH 07/11] ipneigh: fix missing format specifier Signed-off-by: Stephen Hemminger --- ip/ipneigh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ip/ipneigh.c b/ip/ipneigh.c index 47483817..bd6e5c5e 100644 --- a/ip/ipneigh.c +++ b/ip/ipneigh.c @@ -204,7 +204,7 @@ static void print_cacheinfo(const struct nda_cacheinfo *ci) print_uint(PRINT_ANY, "used", " used %u", ci->ndm_used / hz); print_uint(PRINT_ANY, "confirmed", "/%u", ci->ndm_confirmed / hz); - print_uint(PRINT_ANY, "updated", "/u", ci->ndm_updated / hz); + print_uint(PRINT_ANY, "updated", "/%u", ci->ndm_updated / hz); } static void print_neigh_state(unsigned int nud) From 0b01f088ee93be4a074ba7b3608dabf1fead497d Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 20 Apr 2018 10:04:14 -0700 Subject: [PATCH 08/11] flower: use 16 bit format where possible Should use print_hu not print_uint for 16 bit value. Signed-off-by: Stephen Hemminger --- tc/f_flower.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/f_flower.c b/tc/f_flower.c index 9d4bfd2f..ba8eb66c 100644 --- a/tc/f_flower.c +++ b/tc/f_flower.c @@ -1234,7 +1234,7 @@ static void flower_print_port(char *name, struct rtattr *attr) return; sprintf(namefrm,"\n %s %%u", name); - print_uint(PRINT_ANY, name, namefrm, rta_getattr_be16(attr)); + print_hu(PRINT_ANY, name, namefrm, rta_getattr_be16(attr)); } static void flower_print_tcp_flags(char *name, struct rtattr *flags_attr, From 0aaf62fcb669d4709c52e3b686966a7fbe999640 Mon Sep 17 00:00:00 2001 From: Roman Mashak Date: Fri, 20 Apr 2018 09:52:18 -0400 Subject: [PATCH 09/11] tc: return on invalid smac or dmac in ife action Return on invalid smac/dmac and use invarg consistently for invalid arguments report. Signed-off-by: Roman Mashak --- tc/m_ife.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/tc/m_ife.c b/tc/m_ife.c index d7e61703..ed0913a3 100644 --- a/tc/m_ife.c +++ b/tc/m_ife.c @@ -94,9 +94,7 @@ static int parse_ife(struct action_util *a, int *argc_p, char ***argv_p, } else if (matches(*argv, "tcindex") == 0) { ife_tcindex = IFE_META_TCINDEX; } else { - fprintf(stderr, "Illegal meta define <%s>\n", - *argv); - return -1; + invarg("Illegal meta define", *argv); } } else if (matches(*argv, "use") == 0) { NEXT_ARG(); @@ -116,9 +114,7 @@ static int parse_ife(struct action_util *a, int *argc_p, char ***argv_p, invarg("ife tcindex val is invalid", *argv); } else { - fprintf(stderr, "Illegal meta use type <%s>\n", - *argv); - return -1; + invarg("Illegal meta use type", *argv); } } else if (matches(*argv, "type") == 0) { NEXT_ARG(); @@ -132,8 +128,7 @@ static int parse_ife(struct action_util *a, int *argc_p, char ***argv_p, if (sscanf(daddr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", dbuf, dbuf + 1, dbuf + 2, dbuf + 3, dbuf + 4, dbuf + 5) != 6) { - fprintf(stderr, "Invalid mac address %s\n", - daddr); + invarg("Invalid mac address", *argv); } fprintf(stderr, "dst MAC address <%s>\n", daddr); @@ -143,8 +138,7 @@ static int parse_ife(struct action_util *a, int *argc_p, char ***argv_p, if (sscanf(saddr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", sbuf, sbuf + 1, sbuf + 2, sbuf + 3, sbuf + 4, sbuf + 5) != 6) { - fprintf(stderr, "Invalid mac address %s\n", - saddr); + invarg("Invalid mac address", *argv); } fprintf(stderr, "src MAC address <%s>\n", saddr); } else if (matches(*argv, "help") == 0) { From 260a92afe65b78cb775b36ca8fc15b03239d8b76 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 20 Apr 2018 10:38:00 -0700 Subject: [PATCH 10/11] bpf: fix warnings on gcc-8 about string truncation In theory, the path for BPF could exceed the 4K PATH_MAX. In practice, not really possible. But shut up gcc. Signed-off-by: Stephen Hemminger --- lib/bpf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/bpf.c b/lib/bpf.c index 04bc5a56..d9a406bf 100644 --- a/lib/bpf.c +++ b/lib/bpf.c @@ -634,7 +634,7 @@ static int bpf_gen_global(const char *bpf_sub_dir) static int bpf_gen_master(const char *base, const char *name) { - char bpf_sub_dir[PATH_MAX]; + char bpf_sub_dir[PATH_MAX + NAME_MAX + 1]; int ret; snprintf(bpf_sub_dir, sizeof(bpf_sub_dir), "%s%s/", base, name); @@ -675,8 +675,8 @@ static int bpf_slave_via_bind_mnt(const char *full_name, static int bpf_gen_slave(const char *base, const char *name, const char *link) { - char bpf_lnk_dir[PATH_MAX]; - char bpf_sub_dir[PATH_MAX]; + char bpf_lnk_dir[PATH_MAX + NAME_MAX + 1]; + char bpf_sub_dir[PATH_MAX + NAME_MAX]; struct stat sb = {}; int ret; From f5393225f947f76523571d6205198112dc4a8e09 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Wed, 18 Apr 2018 11:06:07 -0700 Subject: [PATCH 11/11] iplink_geneve: correct size of message to avoid spurious errors Commit 6c4b672738ac ("iplink_geneve: Get rid of inet_get_addr()") inadvertently changed the parameter to addattr_l() resulting in: addattr_l ERROR: message exceeded bound of 4 when remote is specified. Fixes: 6c4b672738ac ("iplink_geneve: Get rid of inet_get_addr()") Signed-off-by: Jakub Kicinski Reviewed-by: Quentin Monnet --- ip/iplink_geneve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ip/iplink_geneve.c b/ip/iplink_geneve.c index 1fcdd83a..26e70ff4 100644 --- a/ip/iplink_geneve.c +++ b/ip/iplink_geneve.c @@ -199,7 +199,7 @@ static int geneve_parse_opt(struct link_util *lu, int argc, char **argv, if (is_addrtype_inet(&daddr)) { int type = (daddr.family == AF_INET) ? IFLA_GENEVE_REMOTE : IFLA_GENEVE_REMOTE6; - addattr_l(n, sizeof(1024), type, daddr.data, daddr.bytelen); + addattr_l(n, 1024, type, daddr.data, daddr.bytelen); } if (!set_op || GENEVE_ATTRSET(attrs, IFLA_GENEVE_LABEL)) addattr32(n, 1024, IFLA_GENEVE_LABEL, label);