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);
}