From nobody Sat May 20 10:43:04 2023 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4QNgKN3D84z4BvfK; Sat, 20 May 2023 10:43:04 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4QNgKN2TBvz3x46; Sat, 20 May 2023 10:43:04 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1684579384; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=KFgOb4R2jo81xhlSbn2c9ArhltB2EzvTFoEdioeexS0=; b=AMOLwKxUlxBpZoru0YdGM/ItIjZ4EhEG58ymCvwoTqotlxhKtZIt8EclUe09Swe14HFCir bdRW4ezDjSWwUTCkGCkFE2Ae6OpM8mciTp09YUQmohFgTjHxCalblvTSTPX/Oj6Oq2rgD+ SpreVI14OJu8fCJAUi6pe17KAhfSJgyhYejhKMPhfkviiW0vbpUgIkioqBAHfuWYuKWkMq Fn6dfrYkUeJcy4PBhfe8oZ3RQtAMi9IIagJD5NiCkj1ks+HRPrd0niM6kogcQsr3bWl8FD X32GIQ0pO79ReVbOCr+sZNAPHhBP7IRfxznJwsJom+oz57O1uH6ssRXGet90zw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1684579384; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=KFgOb4R2jo81xhlSbn2c9ArhltB2EzvTFoEdioeexS0=; b=TDjisykE/oja9N2EUaWKt9KivvyCaQpbruMmiCImOwO8za4wPp4fLTyemAjE2dwafmPbED UNWB8h/5fKOHQupB3Z1xI74jFMb10TFW5L1QJrO8MZDhy50jzgIBdPTf9of1/tppc9JO6g /yioXWxx7eIm8BPoqDd9pTntL1b3xmxemmeZvLjZQW8nkM7OXUDWCqiFX8GHbirv1VGZ8g bVwTRP4djuexQCbvwmsamUEwyQB5OxRHtFYrdt3yZpsFfx7EPsE4/jVk9rQNSkwW1B7Zd2 ARerKVyjFr4LlxMuHpo6SjjR0lf1BGMYLECxiXJTpIJXw3nOUaae0Wya4QsMeg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1684579384; a=rsa-sha256; cv=none; b=IW+m4qRxvI5SU/8oD2M0BLWgL5hidtC04UdGSVYO0JBSThGgy2YZ5BZwpgVskm3vWwhuX4 uj61zo4nUa7sNADHsIKC3+EyJsSOtflHVnA6MzikT8mBmOyMlGXgEFDSi9XJ9n866E4RN8 3E5UfBt299nu/YBZyfXhDrjFwG3uCx/TMj156U5vE2UkrNYwa9GMzhJNpwystfKwWPsyYb oicK/pVnZNVo5nHmSIv/JsVmj1BRLiso86wC2Cnjk+Q9d9N5Ik8A5xNcHz98RnMMp67fh6 T2L9kSEA0I37RRv2dIoPDqNIZ4Oir+JD2rX/OGY+Y6GtDOHMRLM7OCjBjZFfDg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4QNgKN1XPFz16MY; Sat, 20 May 2023 10:43:04 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 34KAh4gm034855; Sat, 20 May 2023 10:43:04 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 34KAh4RW034854; Sat, 20 May 2023 10:43:04 GMT (envelope-from git) Date: Sat, 20 May 2023 10:43:04 GMT Message-Id: <202305201043.34KAh4RW034854@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: "Alexander V. Chernikov" Subject: git: 7eee0eaf1602 - main - netlink: automatically generate broadcast for IPv4 ifa if not set. List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: melifaro X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 7eee0eaf1602765bdf20c8e56884069085812c27 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by melifaro: URL: https://cgit.FreeBSD.org/src/commit/?id=7eee0eaf1602765bdf20c8e56884069085812c27 commit 7eee0eaf1602765bdf20c8e56884069085812c27 Author: Alexander V. Chernikov AuthorDate: 2023-05-20 10:42:08 +0000 Commit: Alexander V. Chernikov CommitDate: 2023-05-20 10:42:08 +0000 netlink: automatically generate broadcast for IPv4 ifa if not set. MFC after: 2 weeks --- sys/netlink/route/iface.c | 34 +++++++++++++++++++++++++++------- tests/sys/netlink/test_rtnl_ifaddr.py | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/sys/netlink/route/iface.c b/sys/netlink/route/iface.c index 976b485b3f56..33a5dbfec3a3 100644 --- a/sys/netlink/route/iface.c +++ b/sys/netlink/route/iface.c @@ -1096,13 +1096,14 @@ static int handle_newaddr_inet(struct nlmsghdr *hdr, struct nl_parsed_ifa *attrs, struct ifnet *ifp, struct nlpcb *nlp, struct nl_pstate *npt) { - if (attrs->ifa_prefixlen > 32) { + int plen = attrs->ifa_prefixlen; + int if_flags = if_getflags(ifp); + + if (plen > 32) { nlmsg_report_err_msg(npt, "invalid ifa_prefixlen"); return (EINVAL); }; - int if_flags = if_getflags(ifp); - if (if_flags & IFF_POINTOPOINT) { if (attrs->ifa_addr == NULL || attrs->ifa_dst == NULL) { nlmsg_report_err_msg(npt, "Empty IFA_LOCAL/IFA_ADDRESS"); @@ -1115,13 +1116,32 @@ handle_newaddr_inet(struct nlmsghdr *hdr, struct nl_parsed_ifa *attrs, } attrs->ifa_dst = attrs->ifa_broadcast; - if (attrs->ifa_dst == NULL && !(if_flags & IFF_LOOPBACK)) { - nlmsg_report_err_msg(npt, "empty IFA_BROADCAST for BRD interface"); - return (EINVAL); + /* Generate broadcast address if not set */ + if ((if_flags & IFF_BROADCAST) && attrs->ifa_dst == NULL) { + uint32_t s_baddr; + struct sockaddr_in *sin_brd; + + if (plen == 31) + s_baddr = INADDR_BROADCAST; /* RFC 3021 */ + else { + struct sockaddr_in *addr; + uint32_t s_mask; + + addr = (struct sockaddr_in *)attrs->ifa_addr; + s_mask = htonl(plen ? ~((1 << (32 - plen)) - 1) : 0); + s_baddr = addr->sin_addr.s_addr | ~s_mask; + } + + sin_brd = (struct sockaddr_in *)npt_alloc(npt, sizeof(*sin_brd)); + if (sin_brd == NULL) + return (ENOMEM); + sin_brd->sin_family = AF_INET; + sin_brd->sin_len = sizeof(*sin_brd); + sin_brd->sin_addr.s_addr = s_baddr; + attrs->ifa_dst = (struct sockaddr *)sin_brd; } } - int plen = attrs->ifa_prefixlen; struct sockaddr_in mask = { .sin_len = sizeof(struct sockaddr_in), .sin_family = AF_INET, diff --git a/tests/sys/netlink/test_rtnl_ifaddr.py b/tests/sys/netlink/test_rtnl_ifaddr.py index 11c08b32674a..c7d6d86e781b 100644 --- a/tests/sys/netlink/test_rtnl_ifaddr.py +++ b/tests/sys/netlink/test_rtnl_ifaddr.py @@ -254,6 +254,41 @@ class TestRtNlIfaddrOpsBroadcast(RtnlIfaOps): assert rx_msg.get_nla(IfaAttrType.IFA_LOCAL).addr == str(ifa.ip) assert rx_msg.get_nla(IfaAttrType.IFA_BROADCAST).addr == str(ifa_brd) + @pytest.mark.parametrize( + "brd", + [ + pytest.param((32, True, "192.0.2.1"), id="auto_32"), + pytest.param((31, True, "255.255.255.255"), id="auto_31"), + pytest.param((30, True, "192.0.2.3"), id="auto_30"), + pytest.param((30, False, "192.0.2.2"), id="custom_30"), + pytest.param((24, False, "192.0.2.7"), id="custom_24"), + ], + ) + def test_add_4_brd(self, brd): + """Tests proper broadcast setup when adding IPv4 ifa""" + plen, auto_brd, ifa_brd_str = brd + ifa = ipaddress.ip_interface("192.0.2.1/{}".format(plen)) + iface = self.vnet.iface_alias_map["if1"] + ifa_brd = ipaddress.ip_address(ifa_brd_str) + + msg = self.create_msg(ifa) + msg.add_nla(NlAttrIp(IfaAttrType.IFA_LOCAL, str(ifa.ip))) + if not auto_brd: + msg.add_nla(NlAttrIp(IfaAttrType.IFA_BROADCAST, str(ifa_brd))) + + self.send_check_success(msg) + + lst = self.get_ifa_list(iface.ifindex, self.get_family_from_ip(ifa.ip)) + assert len(lst) == 1 + rx_msg = lst[0] + + assert rx_msg.base_hdr.ifa_prefixlen == ifa.network.prefixlen + assert rx_msg.base_hdr.ifa_scope == RtScope.RT_SCOPE_UNIVERSE.value + + assert rx_msg.get_nla(IfaAttrType.IFA_ADDRESS).addr == str(ifa.ip) + assert rx_msg.get_nla(IfaAttrType.IFA_LOCAL).addr == str(ifa.ip) + assert rx_msg.get_nla(IfaAttrType.IFA_BROADCAST).addr == str(ifa_brd) + def test_add_6(self): ifa = ipaddress.ip_interface("2001:db8::1/64") iface = self.vnet.iface_alias_map["if1"]