The branch stable/13 has been updated by melifaro:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=5713f31ca0d96e90beb274000683656d171a77d9

commit 5713f31ca0d96e90beb274000683656d171a77d9
Author:     Alexander V. Chernikov <melif...@freebsd.org>
AuthorDate: 2022-12-02 19:26:34 +0000
Commit:     Alexander V. Chernikov <melif...@freebsd.org>
CommitDate: 2023-01-23 22:04:03 +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
    ```
    
    (cherry picked from commit cc2be311772d368541157dcf8bf989f216a5b994)
---
 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 9359a0b5126e..d042d9519f6b 100644
--- a/sys/net/route/nhop_ctl.c
+++ b/sys/net/route/nhop_ctl.c
@@ -714,6 +714,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);
        }
 

Reply via email to