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
```
This commit is contained in:
Alexander V. Chernikov 2022-12-02 19:26:34 +00:00
parent 42f8123a4f
commit cc2be31177
2 changed files with 21 additions and 11 deletions

View File

@ -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

View File

@ -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);
struct nhgrp_object *nhg;
error = nhgrp_get_group(rh, wn, num_nhops, 0,
(struct nhgrp_object **)&nh);
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);
}