git: cc2be311772d - main - netlink: store user-provided rtm_protocol
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 02 Dec 2022 20:08:58 UTC
The branch main has been updated by melifaro: URL: https://cgit.FreeBSD.org/src/commit/?id=cc2be311772d368541157dcf8bf989f216a5b994 commit cc2be311772d368541157dcf8bf989f216a5b994 Author: Alexander V. Chernikov <melifaro@FreeBSD.org> AuthorDate: 2022-12-02 19:26:34 +0000 Commit: Alexander V. Chernikov <melifaro@FreeBSD.org> CommitDate: 2022-12-02 20:08:47 +0000 netlink: store user-provided rtm_protocol Store user-supplied source protocol in the nexthops and nexthop groups. Protocol specification help routing daemons like bird to quickly identify self-originated routes after the crash or restart. Example: ``` 10.2.0.0/24 via 10.0.0.2 dev vtnet0 proto bird 10.3.0.0/24 proto bird nexthop via 10.0.0.2 dev vtnet0 weight 3 nexthop via 10.0.0.3 dev vtnet0 weight 4 ``` --- sys/net/route/nhop_ctl.c | 1 + sys/netlink/route/route.c | 33 +++++++++++++++++++++------------ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/sys/net/route/nhop_ctl.c b/sys/net/route/nhop_ctl.c index d5d921dd66c7..201a1ed0a094 100644 --- a/sys/net/route/nhop_ctl.c +++ b/sys/net/route/nhop_ctl.c @@ -715,6 +715,7 @@ nhop_copy(struct nhop_object *nh, const struct nhop_object *nh_orig) nh_priv->nh_type = nh_orig->nh_priv->nh_type; nh_priv->rt_flags = nh_orig->nh_priv->rt_flags; nh_priv->nh_fibnum = nh_orig->nh_priv->nh_fibnum; + nh_priv->nh_origin = nh_orig->nh_priv->nh_origin; } void diff --git a/sys/netlink/route/route.c b/sys/netlink/route/route.c index 852843af1b7d..78949a643227 100644 --- a/sys/netlink/route/route.c +++ b/sys/netlink/route/route.c @@ -271,13 +271,8 @@ dump_px(uint32_t fibnum, const struct nlmsghdr *hdr, if (fibnum < 255) rtm->rtm_table = (unsigned char)fibnum; rtm->rtm_scope = RT_SCOPE_UNIVERSE; - if (!NH_IS_NHGRP(rnd->rnd_nhop)) { - rtm->rtm_protocol = nl_get_rtm_protocol(rnd->rnd_nhop); - rtm->rtm_type = get_rtm_type(rnd->rnd_nhop); - } else { - rtm->rtm_protocol = RTPROT_UNSPEC; /* TODO: protocol from nhg? */ - rtm->rtm_type = RTN_UNICAST; - } + rtm->rtm_protocol = nl_get_rtm_protocol(rnd->rnd_nhop); + rtm->rtm_type = get_rtm_type(rnd->rnd_nhop); nlattr_add_u32(nw, NL_RTA_TABLE, fibnum); @@ -445,6 +440,7 @@ struct nl_parsed_route { uint32_t rtax_mtu; uint8_t rtm_family; uint8_t rtm_dst_len; + uint8_t rtm_protocol; }; #define _IN(_field) offsetof(struct rtmsg, _field) @@ -469,6 +465,7 @@ static const struct nlattr_parser nla_p_rtmsg[] = { static const struct nlfield_parser nlf_p_rtmsg[] = { {.off_in = _IN(rtm_family), .off_out = _OUT(rtm_family), .cb = nlf_get_u8 }, {.off_in = _IN(rtm_dst_len), .off_out = _OUT(rtm_dst_len), .cb = nlf_get_u8 }, + {.off_in = _IN(rtm_protocol), .off_out = _OUT(rtm_protocol), .cb = nlf_get_u8 }, }; #undef _IN #undef _OUT @@ -736,6 +733,8 @@ create_nexthop_one(struct nl_parsed_route *attrs, struct rta_mpath_nh *mpnh, if (mpnh->ifp != NULL) nhop_set_transmit_ifp(nh, mpnh->ifp); nhop_set_rtflags(nh, attrs->rta_rtflags); + if (attrs->rtm_protocol > RTPROT_STATIC) + nhop_set_origin(nh, attrs->rtm_protocol); *pnh = finalize_nhop(nh, &error); @@ -748,13 +747,13 @@ create_nexthop_from_attrs(struct nl_parsed_route *attrs, struct nl_pstate *npt, int *perror) { struct nhop_object *nh = NULL; - int error = 0; if (attrs->rta_multipath != NULL) { #ifdef ROUTE_MPATH /* Multipath w/o explicit nexthops */ int num_nhops = attrs->rta_multipath->num_nhops; struct weightened_nhop *wn = npt_alloc(npt, sizeof(*wn) * num_nhops); + int error = 0; for (int i = 0; i < num_nhops; i++) { struct rta_mpath_nh *mpnh = &attrs->rta_multipath->nhops[i]; @@ -769,12 +768,20 @@ create_nexthop_from_attrs(struct nl_parsed_route *attrs, } if (error == 0) { struct rib_head *rh = nhop_get_rh(wn[0].nh); - - error = nhgrp_get_group(rh, wn, num_nhops, 0, - (struct nhgrp_object **)&nh); - + struct nhgrp_object *nhg; + + nhg = nhgrp_alloc(rh->rib_fibnum, rh->rib_family, + wn, num_nhops, perror); + if (nhg != NULL) { + if (attrs->rtm_protocol > RTPROT_STATIC) + nhgrp_set_origin(nhg, attrs->rtm_protocol); + nhg = nhgrp_get_nhgrp(nhg, perror); + } for (int i = 0; i < num_nhops; i++) nhop_free(wn[i].nh); + if (nhg != NULL) + return ((struct nhop_object *)nhg); + error = *perror; } #else error = ENOTSUP; @@ -799,6 +806,8 @@ create_nexthop_from_attrs(struct nl_parsed_route *attrs, if (attrs->rta_rtflags & RTF_REJECT) nhop_set_blackhole(nh, NHF_REJECT); nhop_set_rtflags(nh, attrs->rta_rtflags); + if (attrs->rtm_protocol > RTPROT_STATIC) + nhop_set_origin(nh, attrs->rtm_protocol); nh = finalize_nhop(nh, perror); }