From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from gandalf.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by passt.top (Postfix) with ESMTPS id 5BE005A0272 for ; Mon, 24 Jul 2023 08:09:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=201602; t=1690178979; bh=aluSPD4mAZXU4En2kUDPVLIYQ9Brgzln74jw7LNYDsw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EPFUJIheIbA/mbthjgSpNg3Bx3sH1DEE64/Awj9MK4Ae8ETaZblrYBzKxihR0r0CB voTrMsMWpWgoIZpuZd6h5C7SGu2gnXpt9F0sPqnyr3hgXOydNtHqtybwZxsGa/onJn jrXFkt4Uulfvc7fl2QZulvTvqCDn6+N0Biga9GFc= Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4R8V9v5WWkz4wyt; Mon, 24 Jul 2023 16:09:39 +1000 (AEST) From: David Gibson To: Stefano Brivio , passt-dev@passt.top Subject: [PATCH 13/17] netlink: Add nl_foreach_oftype to filter response message types Date: Mon, 24 Jul 2023 16:09:32 +1000 Message-ID: <20230724060936.952659-14-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: C4M7BQ7CXYQ36FJNZD3DHKE2LXV46MZ3 X-Message-ID-Hash: C4M7BQ7CXYQ36FJNZD3DHKE2LXV46MZ3 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: In most cases where processing response messages, we expect only one type of message (excepting NLMSG_DONE or NLMSG_ERROR), and so we need a test and continue to skip anything else. Add a helper macro to do this. This also fixes a bug in nl_get_ext_if() where we didn't have such a test and if we got a message other than RTM_NEWROUTE we would have parsed its contents as nonsense. Also add a warning message if we get such an unexpected message type, which could be useful for debugging if we ever hit it. Signed-off-by: David Gibson --- netlink.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/netlink.c b/netlink.c index 9293e2b..1d40856 100644 --- a/netlink.c +++ b/netlink.c @@ -210,17 +210,25 @@ static struct nlmsghdr *nl_next(int s, char *buf, struct nlmsghdr *nh, ssize_t * /** * nl_foreach - 'for' type macro to step through netlink response messages + * nl_foreach_oftype - as above, but only messages of expected type * @nh: Steps through each response header (struct nlmsghdr *) * @status: When loop exits indicates if there was an error (ssize_t) * @s: Netlink socket * @buf: Buffer for responses (at least NLBUFSIZ long) * @seq: Sequence number of request we're getting responses for - */ + * @type: Type of netlink message to process + */ #define nl_foreach(nh, status, s, buf, seq) \ for ((nh) = nl_next((s), (buf), NULL, &(status)); \ ((status) = nl_status((nh), (status), (seq))) > 0; \ (nh) = nl_next((s), (buf), (nh), &(status))) +#define nl_foreach_oftype(nh, status, s, buf, seq, type) \ + nl_foreach((nh), (status), (s), (buf), (seq)) \ + if ((nh)->nlmsg_type != (type)) { \ + warn("netlink: Unexpected message type"); \ + } else + /** * nl_do() - Send netlink "do" request, and wait for acknowledgement * @s: Netlink socket @@ -269,7 +277,7 @@ unsigned int nl_get_ext_if(int s, sa_family_t af) size_t na; seq = nl_send(s, &req, RTM_GETROUTE, NLM_F_DUMP, sizeof(req)); - nl_foreach(nh, status, s, buf, seq) { + nl_foreach_oftype(nh, status, s, buf, seq, RTM_NEWROUTE) { struct rtmsg *rtm = (struct rtmsg *)NLMSG_DATA(nh); if (rtm->rtm_dst_len || rtm->rtm_family != af) @@ -321,14 +329,11 @@ void nl_route_get_def(int s, unsigned int ifi, sa_family_t af, void *gw) uint16_t seq; seq = nl_send(s, &req, RTM_GETROUTE, NLM_F_DUMP, sizeof(req)); - nl_foreach(nh, status, s, buf, seq) { + nl_foreach_oftype(nh, status, s, buf, seq, RTM_NEWROUTE) { struct rtmsg *rtm = (struct rtmsg *)NLMSG_DATA(nh); struct rtattr *rta; size_t na; - if (nh->nlmsg_type != RTM_NEWROUTE) - continue; - if (rtm->rtm_dst_len) continue; @@ -519,14 +524,11 @@ void nl_addr_get(int s, unsigned int ifi, sa_family_t af, uint16_t seq; seq = nl_send(s, &req, RTM_GETADDR, NLM_F_DUMP, sizeof(req)); - nl_foreach(nh, status, s, buf, seq) { + nl_foreach_oftype(nh, status, s, buf, seq, RTM_NEWADDR) { struct ifaddrmsg *ifa = (struct ifaddrmsg *)NLMSG_DATA(nh); struct rtattr *rta; size_t na; - if (nh->nlmsg_type != RTM_NEWADDR) - continue; - if (ifa->ifa_index != ifi) continue; @@ -640,7 +642,7 @@ void nl_addr_dup(int s_src, unsigned int ifi_src, uint16_t seq; seq = nl_send(s_src, &req, RTM_GETADDR, NLM_F_DUMP, sizeof(req)); - nl_foreach(nh, status, s_src, buf, seq) { + nl_foreach_oftype(nh, status, s_src, buf, seq, RTM_NEWADDR) { struct ifaddrmsg *ifa; struct rtattr *rta; size_t na; @@ -689,14 +691,11 @@ void nl_link_get_mac(int s, unsigned int ifi, void *mac) uint16_t seq; seq = nl_send(s, &req, RTM_GETLINK, 0, sizeof(req)); - nl_foreach(nh, status, s, buf, seq) { + nl_foreach_oftype(nh, status, s, buf, seq, RTM_NEWLINK) { struct ifinfomsg *ifm = (struct ifinfomsg *)NLMSG_DATA(nh); struct rtattr *rta; size_t na; - if (nh->nlmsg_type != RTM_NEWLINK) - continue; - for (rta = IFLA_RTA(ifm), na = RTM_PAYLOAD(nh); RTA_OK(rta, na); rta = RTA_NEXT(rta, na)) { -- 2.41.0