From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from gandalf.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id 772385A027E for ; Mon, 24 Jul 2023 08:09:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=201602; t=1690178979; bh=MrKJzQybkfyki0wxP4I+uyqibjsroFTaj19LRTrxqg4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=J/kQeBWRmBW/bhCmk0JRlvNAz5jS0SURmEj0fCV7txWgShAUV0LhNBZo0ncXvunOt 2qByDFBQeGZF0kLdKXEfdjVT0b9sALWYIuGQabSL9WLPO1FgnQxeSZ0BnW8+kgpX3v dZN4kRUjMgehb+xfMkT3Tb6Jcug38QDEIZfZUsME= Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4R8V9v62rJz4wyr; Mon, 24 Jul 2023 16:09:39 +1000 (AEST) From: David Gibson To: Stefano Brivio , passt-dev@passt.top Subject: [PATCH 17/17] netlink: Propagate errors for "dup" operations Date: Mon, 24 Jul 2023 16:09:36 +1000 Message-ID: <20230724060936.952659-18-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230724060936.952659-1-david@gibson.dropbear.id.au> References: <20230724060936.952659-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: 2BG6ZUSDMJDXX23QFEUUEIREDJ6NE7AK X-Message-ID-Hash: 2BG6ZUSDMJDXX23QFEUUEIREDJ6NE7AK X-MailFrom: dgibson@gandalf.ozlabs.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: David Gibson X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: We now detect errors on netlink "set" operations while configuring the pasta namespace with --config-net. However in many cases rather than a simple "set" we use a more complex "dup" function to copy configuration from the host to the namespace. We're not yet properly detecting and reporting netlink errors for that case. Change the "dup" operations to propagate netlink errors to their caller, pasta_ns_conf() and report them there. Link: https://bugs.passt.top/show_bug.cgi?id=60 Signed-off-by: David Gibson --- netlink.c | 40 ++++++++++++++++++++++++++++------------ netlink.h | 8 ++++---- pasta.c | 15 ++++++++------- 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/netlink.c b/netlink.c index 9e72b16..cdc18c0 100644 --- a/netlink.c +++ b/netlink.c @@ -413,9 +413,11 @@ int nl_route_set_def(int s, unsigned int ifi, sa_family_t af, void *gw) * @s_dst: Netlink socket in destination namespace * @ifi_dst: Interface index in destination namespace * @af: Address family + * + * Return: 0 on success, negative error code on failure */ -void nl_route_dup(int s_src, unsigned int ifi_src, - int s_dst, unsigned int ifi_dst, sa_family_t af) +int nl_route_dup(int s_src, unsigned int ifi_src, + int s_dst, unsigned int ifi_dst, sa_family_t af) { struct req_t { struct nlmsghdr nlh; @@ -477,9 +479,11 @@ void nl_route_dup(int s_src, unsigned int ifi_src, if (extra) { err("netlink: Too many routes to duplicate"); - return; + return -E2BIG; } } + if (status < 0) + return status; /* Routes might have dependencies between each other, and the * kernel processes RTM_NEWROUTE messages sequentially. For n @@ -494,15 +498,20 @@ void nl_route_dup(int s_src, unsigned int ifi_src, NLMSG_OK(nh, status); nh = NLMSG_NEXT(nh, status)) { uint16_t flags = nh->nlmsg_flags; + int rc; if (nh->nlmsg_type != RTM_NEWROUTE) continue; - nl_do(s_dst, nh, RTM_NEWROUTE, - (flags & ~NLM_F_DUMP_FILTERED) | NLM_F_CREATE, - nh->nlmsg_len); + rc = nl_do(s_dst, nh, RTM_NEWROUTE, + (flags & ~NLM_F_DUMP_FILTERED) | NLM_F_CREATE, + nh->nlmsg_len); + if (rc < 0 && rc != -ENETUNREACH && rc != -EEXIST) + return rc; } } + + return 0; } /** @@ -635,9 +644,11 @@ int nl_addr_set(int s, unsigned int ifi, sa_family_t af, * @s_dst: Netlink socket in destination network namespace * @ifi_dst: Interface index in destination namespace * @af: Address family + * + * Return: 0 on success, negative error code on failure */ -void nl_addr_dup(int s_src, unsigned int ifi_src, - int s_dst, unsigned int ifi_dst, sa_family_t af) +int nl_addr_dup(int s_src, unsigned int ifi_src, + int s_dst, unsigned int ifi_dst, sa_family_t af) { struct req_t { struct nlmsghdr nlh; @@ -651,6 +662,7 @@ void nl_addr_dup(int s_src, unsigned int ifi_src, struct nlmsghdr *nh; ssize_t status; uint16_t seq; + int rc= 0; seq = nl_send(s_src, &req, RTM_GETADDR, NLM_F_DUMP, sizeof(req)); nl_foreach_oftype(nh, status, s_src, buf, seq, RTM_NEWADDR) { @@ -663,7 +675,7 @@ void nl_addr_dup(int s_src, unsigned int ifi_src, ifa = (struct ifaddrmsg *)NLMSG_DATA(nh); - if (ifa->ifa_scope == RT_SCOPE_LINK || + if (rc < 0 || ifa->ifa_scope == RT_SCOPE_LINK || ifa->ifa_index != ifi_src) continue; @@ -675,10 +687,14 @@ void nl_addr_dup(int s_src, unsigned int ifi_src, rta->rta_type = IFA_UNSPEC; } - nl_do(s_dst, nh, RTM_NEWADDR, - (nh->nlmsg_flags & ~NLM_F_DUMP_FILTERED) | NLM_F_CREATE, - nh->nlmsg_len); + rc = nl_do(s_dst, nh, RTM_NEWADDR, + (nh->nlmsg_flags & ~NLM_F_DUMP_FILTERED) | NLM_F_CREATE, + nh->nlmsg_len); } + if (status < 0) + return status; + + return rc; } /** diff --git a/netlink.h b/netlink.h index b831405..9f4f8f4 100644 --- a/netlink.h +++ b/netlink.h @@ -13,14 +13,14 @@ void nl_sock_init(const struct ctx *c, bool ns); unsigned int nl_get_ext_if(int s, sa_family_t af); int nl_route_get_def(int s, unsigned int ifi, sa_family_t af, void *gw); int nl_route_set_def(int s, unsigned int ifi, sa_family_t af, void *gw); -void nl_route_dup(int s_src, unsigned int ifi_src, - int s_dst, unsigned int ifi_dst, sa_family_t af); +int nl_route_dup(int s_src, unsigned int ifi_src, + int s_dst, unsigned int ifi_dst, sa_family_t af); int nl_addr_get(int s, unsigned int ifi, sa_family_t af, void *addr, int *prefix_len, void *addr_l); int nl_addr_set(int s, unsigned int ifi, sa_family_t af, void *addr, int prefix_len); -void nl_addr_dup(int s_src, unsigned int ifi_src, - int s_dst, unsigned int ifi_dst, sa_family_t af); +int nl_addr_dup(int s_src, unsigned int ifi_src, + int s_dst, unsigned int ifi_dst, sa_family_t af); int nl_link_get_mac(int s, unsigned int ifi, void *mac); int nl_link_set_mac(int s, unsigned int ifi, void *mac); int nl_link_up(int s, unsigned int ifi, int mtu); diff --git a/pasta.c b/pasta.c index ed6fda3..b94423c 100644 --- a/pasta.c +++ b/pasta.c @@ -298,8 +298,9 @@ void pasta_ns_conf(struct ctx *c) &c->ip4.addr, c->ip4.prefix_len); else - nl_addr_dup(nl_sock, c->ifi4, - nl_sock_ns, c->pasta_ifi, AF_INET); + rc = nl_addr_dup(nl_sock, c->ifi4, + nl_sock_ns, c->pasta_ifi, + AF_INET); if (rc < 0) die("Couldn't set IPv4 address(es) in namespace: %s", strerror(-rc)); @@ -308,7 +309,7 @@ void pasta_ns_conf(struct ctx *c) rc = nl_route_set_def(nl_sock_ns, c->pasta_ifi, AF_INET, &c->ip4.gw); else - nl_route_dup(nl_sock, c->ifi4, nl_sock_ns, + rc = nl_route_dup(nl_sock, c->ifi4, nl_sock_ns, c->pasta_ifi, AF_INET); if (rc < 0) die("Couldn't set IPv4 route(s) in guest: %s", @@ -320,9 +321,9 @@ void pasta_ns_conf(struct ctx *c) rc = nl_addr_set(nl_sock_ns, c->pasta_ifi, AF_INET6, &c->ip6.addr, 64); else - nl_addr_dup(nl_sock, c->ifi4, - nl_sock_ns, c->pasta_ifi, - AF_INET6); + rc = nl_addr_dup(nl_sock, c->ifi4, + nl_sock_ns, c->pasta_ifi, + AF_INET6); if (rc < 0) die("Couldn't set IPv6 address(es) in namespace: %s", strerror(-rc)); @@ -331,7 +332,7 @@ void pasta_ns_conf(struct ctx *c) rc = nl_route_set_def(nl_sock_ns, c->pasta_ifi, AF_INET6, &c->ip6.gw); else - nl_route_dup(nl_sock, c->ifi6, + rc = nl_route_dup(nl_sock, c->ifi6, nl_sock_ns, c->pasta_ifi, AF_INET6); if (rc < 0) -- 2.41.0