nhops: split nh_family into nh_upper_family and nh_neigh_family.

With IPv4 over IPv6 nexthops and IP->MPLS support, there is a need
 to distingush "upper" e.g. traffic family and "neighbor" e.g. LLE/gateway
 address family. Store them explicitly in the private part of the nexthop data.

While here, store nhop fibnum in nhop_prip datastructure to make it self-contained.

MFC after:	2 weeks
Differential Revision: https://reviews.freebsd.org/D33663
This commit is contained in:
Alexander V. Chernikov 2021-12-26 18:07:37 +00:00
parent ff3a85d324
commit 823a08d740
3 changed files with 55 additions and 13 deletions

View File

@ -179,6 +179,9 @@ enum nhop_type nhop_get_type(const struct nhop_object *nh);
int nhop_get_rtflags(const struct nhop_object *nh);
struct vnet *nhop_get_vnet(const struct nhop_object *nh);
struct nhop_object *nhop_select_func(struct nhop_object *nh, uint32_t flowid);
int nhop_get_upper_family(const struct nhop_object *nh);
int nhop_get_neigh_family(const struct nhop_object *nh);
uint32_t nhop_get_fibnum(const struct nhop_object *nh);
#endif /* _KERNEL */

View File

@ -28,6 +28,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_route.h"
#include <sys/param.h>
@ -58,7 +59,7 @@ __FBSDID("$FreeBSD$");
* Nexthops in the original sense are the objects containing all the necessary
* information to forward the packet to the selected destination.
* In particular, nexthop is defined by a combination of
* ifp, ifa, aifp, mtu, gw addr(if set), nh_type, nh_family, mask of rt_flags and
* ifp, ifa, aifp, mtu, gw addr(if set), nh_type, nh_upper_family, mask of rt_flags and
* NHF_DEFAULT
*
* Additionally, each nexthop gets assigned its unique index (nexthop index).
@ -278,13 +279,17 @@ fill_nhop_from_info(struct nhop_priv *nh_priv, struct rt_addrinfo *info)
rt_flags = info->rti_flags & NHOP_RT_FLAG_MASK;
nh->nh_priv->rt_flags = rt_flags;
nh_priv->nh_family = info->rti_info[RTAX_DST]->sa_family;
nh_priv->nh_upper_family = info->rti_info[RTAX_DST]->sa_family;
nh_priv->nh_type = 0; // hook responsibility to set nhop type
nh->nh_flags = convert_rt_to_nh_flags(rt_flags);
set_nhop_mtu_from_info(nh, info);
if ((error = set_nhop_gw_from_info(nh, info)) != 0)
return (error);
if (nh->gw_sa.sa_family == AF_LINK)
nh_priv->nh_neigh_family = nh_priv->nh_upper_family;
else
nh_priv->nh_neigh_family = nh->gw_sa.sa_family;
nh->nh_ifp = (info->rti_ifp != NULL) ? info->rti_ifp : info->rti_ifa->ifa_ifp;
nh->nh_ifa = info->rti_ifa;
@ -401,6 +406,7 @@ get_nhop(struct rib_head *rnh, struct rt_addrinfo *info,
static int
alter_nhop_from_info(struct nhop_object *nh, struct rt_addrinfo *info)
{
struct nhop_priv *nh_priv = nh->nh_priv;
struct sockaddr *info_gw;
int error;
@ -410,8 +416,8 @@ alter_nhop_from_info(struct nhop_object *nh, struct rt_addrinfo *info)
/* XXX: allow only one of BLACKHOLE,REJECT,GATEWAY */
/* Allow some flags (FLAG1,STATIC,BLACKHOLE,REJECT) to be toggled on change. */
nh->nh_priv->rt_flags &= ~RTF_FMASK;
nh->nh_priv->rt_flags |= info->rti_flags & RTF_FMASK;
nh_priv->rt_flags &= ~RTF_FMASK;
nh_priv->rt_flags |= info->rti_flags & RTF_FMASK;
/* Consider gateway change */
info_gw = info->rti_info[RTAX_GATEWAY];
@ -419,12 +425,16 @@ alter_nhop_from_info(struct nhop_object *nh, struct rt_addrinfo *info)
error = set_nhop_gw_from_info(nh, info);
if (error != 0)
return (error);
if (nh->gw_sa.sa_family == AF_LINK)
nh_priv->nh_neigh_family = nh_priv->nh_upper_family;
else
nh_priv->nh_neigh_family = nh->gw_sa.sa_family;
/* Update RTF_GATEWAY flag status */
nh->nh_priv->rt_flags &= ~RTF_GATEWAY;
nh->nh_priv->rt_flags |= (RTF_GATEWAY & info->rti_flags);
nh_priv->rt_flags &= ~RTF_GATEWAY;
nh_priv->rt_flags |= (RTF_GATEWAY & info->rti_flags);
}
/* Update datapath flags */
nh->nh_flags = convert_rt_to_nh_flags(nh->nh_priv->rt_flags);
nh->nh_flags = convert_rt_to_nh_flags(nh_priv->rt_flags);
if (info->rti_ifa != NULL)
nh->nh_ifa = info->rti_ifa;
@ -458,7 +468,8 @@ nhop_create_from_nhop(struct rib_head *rnh, const struct nhop_object *nh_orig,
nh = nh_priv->nh;
/* Start with copying data from original nexthop */
nh_priv->nh_family = nh_orig->nh_priv->nh_family;
nh_priv->nh_upper_family = nh_orig->nh_priv->nh_upper_family;
nh_priv->nh_neigh_family = nh_orig->nh_priv->nh_neigh_family;
nh_priv->rt_flags = nh_orig->nh_priv->rt_flags;
nh_priv->nh_type = nh_orig->nh_priv->nh_type;
@ -561,6 +572,8 @@ finalize_nhop(struct nh_control *ctl, struct rt_addrinfo *info,
/* Please see nhop_free() comments on the initial value */
refcount_init(&nh_priv->nh_linked, 2);
nh_priv->nh_fibnum = ctl->ctl_rh->rib_fibnum;
print_nhop("FINALIZE", nh);
if (link_nhop(ctl, nh_priv) == 0) {
@ -608,7 +621,7 @@ print_nhop(const char *prefix, const struct nhop_object *nh)
print_nhop_sa(addr_buf, sizeof(addr_buf), &nh->gw_sa);
DPRINTF("%s nhop priv %p: AF %d ifp %p %s addr %s src %p %s aifp %p %s mtu %d nh_flags %X",
prefix, nh->nh_priv, nh->nh_priv->nh_family, nh->nh_ifp,
prefix, nh->nh_priv, nh->nh_priv->nh_upper_family, nh->nh_ifp,
if_name(nh->nh_ifp), addr_buf, nh->nh_ifa, src_buf, nh->nh_aifp,
if_name(nh->nh_aifp), nh->nh_mtu, nh->nh_flags);
}
@ -782,6 +795,31 @@ nhop_select_func(struct nhop_object *nh, uint32_t flowid)
return (nhop_select(nh, flowid));
}
/*
* Returns address family of the traffic uses the nexthop.
*/
int
nhop_get_upper_family(const struct nhop_object *nh)
{
return (nh->nh_priv->nh_upper_family);
}
/*
* Returns address family of the LLE or gateway that is used
* to forward the traffic to.
*/
int
nhop_get_neigh_family(const struct nhop_object *nh)
{
return (nh->nh_priv->nh_neigh_family);
}
uint32_t
nhop_get_fibnum(const struct nhop_object *nh)
{
return (nh->nh_priv->nh_fibnum);
}
void
nhops_update_ifmtu(struct rib_head *rh, struct ifnet *ifp, uint32_t mtu)
{
@ -845,7 +883,7 @@ dump_nhop_entry(struct rib_head *rh, struct nhop_object *nh, struct sysctl_req *
pnhe->nh_fib = rh->rib_fibnum;
pnhe->ifindex = nh->nh_ifp->if_index;
pnhe->aifindex = nh->nh_aifp->if_index;
pnhe->nh_family = nh->nh_priv->nh_family;
pnhe->nh_family = nh->nh_priv->nh_upper_family;
pnhe->nh_type = nh->nh_priv->nh_type;
pnhe->nh_mtu = nh->nh_mtu;
pnhe->nh_flags = nh->nh_flags;

View File

@ -74,12 +74,13 @@ struct nh_control {
struct nhop_object;
struct nhop_priv {
/* nhop lookup comparison start */
uint8_t nh_family; /* address family of the lookup */
uint8_t spare;
uint8_t nh_upper_family;/* address family of the lookup */
uint8_t nh_neigh_family;/* neighbor address family */
uint16_t nh_type; /* nexthop type */
uint32_t rt_flags; /* routing flags for the control plane */
/* nhop lookup comparison end */
uint32_t nh_idx; /* nexthop index */
uint32_t nh_fibnum; /* nexthop fib */
void *cb_func; /* function handling additional rewrite caps */
u_int nh_refcnt; /* number of references, refcount(9) */
u_int nh_linked; /* refcount(9), == 2 if linked to the list */