From nobody Tue Apr 25 11:15:34 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 4Q5KDR1fnXz473Y4; Tue, 25 Apr 2023 11:15:35 +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 4Q5KDQ5YSRz45fg; Tue, 25 Apr 2023 11:15:34 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1682421334; 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=q6m+7EVyeUAT9Z694c0PRe6CrcPbGaGrOzJGv0+wpwg=; b=MtYEYuDnxzp405jhuGvq2NpvPzukCWSDJzzOCs+BPzy/CrgfFdaR612tVAwG8rH2DlY1P2 wPP9p2uhCohLWjpK3LZqxrOowuRmr8rlCMzd8beGDRNjpinHuiCq+s7dLBgeMwHFsNCyPU UouOSwp0TkQRe92koRuymyZvpSqrvdwH+clDf2zinttwj0JAv59NukLuMyKWhJe7W9dnIT ro6xmoHN5fbTwFmuBJHhJruCAalVa4Ln6eM7GHj769PYdMhvtUZR4doqeMlhcrTHN1moM2 qbVu7JlGr+6pxK0oLDEEbh7Dj+FS2fQIHpTszsbKfq2ROrRdlCnE0X9NBgY2gA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1682421334; 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=q6m+7EVyeUAT9Z694c0PRe6CrcPbGaGrOzJGv0+wpwg=; b=SIVxiByNop2eK0fB+Ve07cuYc82ELbw8S9QILAQQOacGWLlfEIELXtN22eBJGRB2buzFRj iFwsOCYA76ByIT6EZJdrU+dicgarwmGHQZmsgdjfW8nXJZkQUnhoE60cRZexk9A77tQLPl 6Fl5KDnZQ57DA6oIQUtQU65vDjrY0beH63SMZ61Zg6/W/MqxQk6IG3S5HNHZy9vWQxsBAr cO0xLsjzyDuWxvAzffb9NAUhyzG/wZOtoT0lEHeqPOUUEAdpLdQmJ8/MzFnE1zsitVR/ss H6gfzVPUvxTuo8Cg278mQscl5uzMxIz5VeU370UW2mZLq9N6nJSHGi7juJtGlg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1682421334; a=rsa-sha256; cv=none; b=fhx1uXjbHolKWCnWyUfM8a71WN6L8UI2jWFVt0wWC6r89SuL8+Y3qfPCymjSgw9wm9n7Qb Fw+DMF0alAyEqCQoOuLlvE9+5DjGy9YKY5vZrCtE1FKy+yDZ3X1hQY/rdNQiwQOOHkDjLm FmSOyqVHxCOOrXSV3EMe/SX3FgkPdfzE/W6iBR8sbhKClY6VyWOW58qbH0FnUB8MPZktgs Dxxf4SV1VNAzfosg+3DhPxxxjhzf4kgl9Q8Ay5OHXWOO38eGBIhWA/Hr3pxpNjMMDqCDGu UZAO093Wz+vPAhcmzpA2oXRT0IaICykNRD/5adDhGUPXC9SMo7KKeZnzK0AjLg== 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 4Q5KDQ4fxTz14w1; Tue, 25 Apr 2023 11:15:34 +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 33PBFYHi012817; Tue, 25 Apr 2023 11:15:34 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 33PBFYYv012816; Tue, 25 Apr 2023 11:15:34 GMT (envelope-from git) Date: Tue, 25 Apr 2023 11:15:34 GMT Message-Id: <202304251115.33PBFYYv012816@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: b32cf15d8617 - main - netlink: add support for dumping kernel nexthops. 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: b32cf15d861794fc91d0f2666a71865ccd0fcb3e Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by melifaro: URL: https://cgit.FreeBSD.org/src/commit/?id=b32cf15d861794fc91d0f2666a71865ccd0fcb3e commit b32cf15d861794fc91d0f2666a71865ccd0fcb3e Author: Alexander V. Chernikov AuthorDate: 2023-04-25 11:12:18 +0000 Commit: Alexander V. Chernikov CommitDate: 2023-04-25 11:12:18 +0000 netlink: add support for dumping kernel nexthops. MFC after: 2 weeks --- sys/netlink/route/nexthop.c | 107 +++++++++++++++++++++++++++++++++++--------- sys/netlink/route/nexthop.h | 11 +++++ 2 files changed, 98 insertions(+), 20 deletions(-) diff --git a/sys/netlink/route/nexthop.c b/sys/netlink/route/nexthop.c index 1b468ca18e73..94cc6caf7d82 100644 --- a/sys/netlink/route/nexthop.c +++ b/sys/netlink/route/nexthop.c @@ -436,11 +436,9 @@ enomem: } static bool -dump_nhop(const struct user_nhop *unhop, struct nlmsghdr *hdr, +dump_nhop(const struct nhop_object *nh, uint32_t uidx, struct nlmsghdr *hdr, struct nl_writer *nw) { - struct nhop_object *nh = unhop->un_nhop_src; - if (!nlmsg_reply(nw, hdr, sizeof(struct nhmsg))) goto enomem; @@ -448,10 +446,11 @@ dump_nhop(const struct user_nhop *unhop, struct nlmsghdr *hdr, ENOMEM_IF_NULL(nhm); nhm->nh_family = nhop_get_neigh_family(nh); nhm->nh_scope = 0; // XXX: what's that? - nhm->nh_protocol = unhop->un_protocol; + nhm->nh_protocol = nhop_get_origin(nh); nhm->nh_flags = 0; - nlattr_add_u32(nw, NHA_ID, unhop->un_idx); + if (uidx != 0) + nlattr_add_u32(nw, NHA_ID, uidx); if (nh->nh_flags & NHF_BLACKHOLE) { nlattr_add_flag(nw, NHA_BLACKHOLE); goto done; @@ -475,6 +474,19 @@ dump_nhop(const struct user_nhop *unhop, struct nlmsghdr *hdr, #endif } + int off = nlattr_add_nested(nw, NHA_FREEBSD); + if (off != 0) { + nlattr_add_u32(nw, NHAF_AIF, nh->nh_aifp->if_index); + + if (uidx == 0) { + nlattr_add_u32(nw, NHAF_KID, nhop_get_idx(nh)); + nlattr_add_u32(nw, NHAF_FAMILY, nhop_get_upper_family(nh)); + nlattr_add_u32(nw, NHAF_TABLE, nhop_get_fibnum(nh)); + } + + nlattr_set_len(nw, off); + } + done: if (nlmsg_end(nw)) return (true); @@ -488,7 +500,7 @@ dump_unhop(const struct user_nhop *unhop, struct nlmsghdr *hdr, struct nl_writer *nw) { if (unhop->un_nhop_src != NULL) - dump_nhop(unhop, hdr, nw); + dump_nhop(unhop->un_nhop_src, unhop->un_idx, hdr, nw); else dump_nhgrp(unhop, hdr, nw); } @@ -670,15 +682,29 @@ struct nl_parsed_nhop { uint32_t nha_id; uint8_t nha_blackhole; uint8_t nha_groups; + uint8_t nhaf_knhops; + uint8_t nhaf_family; struct ifnet *nha_oif; struct sockaddr *nha_gw; struct nlattr *nha_group; uint8_t nh_family; uint8_t nh_protocol; + uint32_t nhaf_table; + uint32_t nhaf_kid; + uint32_t nhaf_aif; }; #define _IN(_field) offsetof(struct nhmsg, _field) #define _OUT(_field) offsetof(struct nl_parsed_nhop, _field) +static struct nlattr_parser nla_p_nh_fbsd[] = { + { .type = NHAF_KNHOPS, .off = _OUT(nhaf_knhops), .cb = nlattr_get_flag }, + { .type = NHAF_TABLE, .off = _OUT(nhaf_table), .cb = nlattr_get_uint32 }, + { .type = NHAF_FAMILY, .off = _OUT(nhaf_family), .cb = nlattr_get_uint8 }, + { .type = NHAF_KID, .off = _OUT(nhaf_kid), .cb = nlattr_get_uint32 }, + { .type = NHAF_AIF, .off = _OUT(nhaf_aif), .cb = nlattr_get_uint32 }, +}; +NL_DECLARE_ATTR_PARSER(nh_fbsd_parser, nla_p_nh_fbsd); + static const struct nlfield_parser nlf_p_nh[] = { { .off_in = _IN(nh_family), .off_out = _OUT(nh_family), .cb = nlf_get_u8 }, { .off_in = _IN(nh_protocol), .off_out = _OUT(nh_protocol), .cb = nlf_get_u8 }, @@ -691,6 +717,7 @@ static const struct nlattr_parser nla_p_nh[] = { { .type = NHA_OIF, .off = _OUT(nha_oif), .cb = nlattr_get_ifp }, { .type = NHA_GATEWAY, .off = _OUT(nha_gw), .cb = nlattr_get_ip }, { .type = NHA_GROUPS, .off = _OUT(nha_groups), .cb = nlattr_get_flag }, + { .type = NHA_FREEBSD, .arg = &nh_fbsd_parser, .cb = nlattr_get_nested }, }; #undef _IN #undef _OUT @@ -801,6 +828,7 @@ newnhop(struct nl_parsed_nhop *attrs, struct user_nhop *unhop, struct nl_pstate return (ENOMEM); } nhop_set_uidx(nh, attrs->nha_id); + nhop_set_origin(nh, attrs->nh_protocol); if (attrs->nha_blackhole) nhop_set_blackhole(nh, NHF_BLACKHOLE); @@ -957,14 +985,10 @@ static int rtnl_handle_getnhop(struct nlmsghdr *hdr, struct nlpcb *nlp, struct nl_pstate *npt) { - struct unhop_ctl *ctl = atomic_load_ptr(&V_un_ctl); struct user_nhop *unhop; UN_TRACKER; int error; - if (__predict_false(ctl == NULL)) - return (ESRCH); - struct nl_parsed_nhop attrs = {}; error = nl_parse_nlmsg(hdr, &nhmsg_parser, npt, &attrs); if (error != 0) @@ -979,8 +1003,13 @@ rtnl_handle_getnhop(struct nlmsghdr *hdr, struct nlpcb *nlp, }; if (attrs.nha_id != 0) { + struct unhop_ctl *ctl = atomic_load_ptr(&V_un_ctl); + struct user_nhop key = { .un_idx = attrs.nha_id }; + + if (__predict_false(ctl == NULL)) + return (ESRCH); + NL_LOG(LOG_DEBUG2, "searching for uidx %u", attrs.nha_id); - struct user_nhop key= { .un_idx = attrs.nha_id }; UN_RLOCK(ctl); CHT_SLIST_FIND_BYOBJ(&ctl->un_head, unhop, &key, unhop); UN_RUNLOCK(ctl); @@ -989,15 +1018,53 @@ rtnl_handle_getnhop(struct nlmsghdr *hdr, struct nlpcb *nlp, return (ESRCH); dump_unhop(unhop, &wa.hdr, wa.nw); return (0); - } + } else if (attrs.nhaf_kid != 0) { + struct nhop_iter iter = { + .fibnum = attrs.nhaf_table, + .family = attrs.nhaf_family, + }; + int error = ESRCH; + + NL_LOG(LOG_DEBUG2, "START table %u family %d", attrs.nhaf_table, attrs.nhaf_family); + for (struct nhop_object *nh = nhops_iter_start(&iter); nh; + nh = nhops_iter_next(&iter)) { + NL_LOG(LOG_DEBUG3, "get %u", nhop_get_idx(nh)); + if (nhop_get_idx(nh) == attrs.nhaf_kid) { + dump_nhop(nh, 0, &wa.hdr, wa.nw); + error = 0; + break; + } + } + nhops_iter_stop(&iter); + return (error); + } else if (attrs.nhaf_knhops) { + struct nhop_iter iter = { + .fibnum = attrs.nhaf_table, + .family = attrs.nhaf_family, + }; + + NL_LOG(LOG_DEBUG2, "DUMP table %u family %d", attrs.nhaf_table, attrs.nhaf_family); + wa.hdr.nlmsg_flags |= NLM_F_MULTI; + for (struct nhop_object *nh = nhops_iter_start(&iter); nh; + nh = nhops_iter_next(&iter)) { + dump_nhop(nh, 0, &wa.hdr, wa.nw); + } + nhops_iter_stop(&iter); + } else { + struct unhop_ctl *ctl = atomic_load_ptr(&V_un_ctl); - UN_RLOCK(ctl); - wa.hdr.nlmsg_flags |= NLM_F_MULTI; - CHT_SLIST_FOREACH(&ctl->un_head, unhop, unhop) { - if (UNHOP_IS_MASTER(unhop) && match_unhop(&attrs, unhop)) - dump_unhop(unhop, &wa.hdr, wa.nw); - } CHT_SLIST_FOREACH_END; - UN_RUNLOCK(ctl); + if (__predict_false(ctl == NULL)) + return (ESRCH); + + NL_LOG(LOG_DEBUG2, "DUMP unhops"); + UN_RLOCK(ctl); + wa.hdr.nlmsg_flags |= NLM_F_MULTI; + CHT_SLIST_FOREACH(&ctl->un_head, unhop, unhop) { + if (UNHOP_IS_MASTER(unhop) && match_unhop(&attrs, unhop)) + dump_unhop(unhop, &wa.hdr, wa.nw); + } CHT_SLIST_FOREACH_END; + UN_RUNLOCK(ctl); + } if (wa.error == 0) { if (!nlmsg_end_dump(wa.nw, wa.error, &wa.hdr)) @@ -1026,7 +1093,7 @@ static const struct rtnl_cmd_handler cmd_handlers[] = { } }; -static const struct nlhdr_parser *all_parsers[] = { &nhmsg_parser }; +static const struct nlhdr_parser *all_parsers[] = { &nhmsg_parser, &nh_fbsd_parser }; void rtnl_nexthops_init(void) diff --git a/sys/netlink/route/nexthop.h b/sys/netlink/route/nexthop.h index 310c3e08fc4b..4128e014a2d0 100644 --- a/sys/netlink/route/nexthop.h +++ b/sys/netlink/route/nexthop.h @@ -56,10 +56,21 @@ enum { NHA_FDB, /* not supported */ NHA_RES_GROUP, /* not supported */ NHA_RES_BUCKET, /* not supported */ + NHA_FREEBSD, /* nested: FreeBSD-specific attributes */ __NHA_MAX, }; #define NHA_MAX (__NHA_MAX - 1) +enum { + NHAF_UNSPEC, + NHAF_KNHOPS, /* flag: dump kernel nexthops */ + NHAF_KGOUPS, /* flag: dump kernel nexthop groups */ + NHAF_TABLE, /* u32: rtable id */ + NHAF_FAMILY, /* u32: upper family */ + NHAF_KID, /* u32: kernel nexthop index */ + NHAF_AIF, /* u32: source interface address */ +}; + /* * Attributes that can be used as filters: * NHA_ID (nexhop or group), NHA_OIF, NHA_GROUPS,