git: a36158432361 - releng/13.1 - nhops: split nh_family into nh_upper_family and nh_neigh_family.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 28 Mar 2022 15:26:00 UTC
The branch releng/13.1 has been updated by melifaro:
URL: https://cgit.FreeBSD.org/src/commit/?id=a3615843236128203255a079e55bc0c9a12c1090
commit a3615843236128203255a079e55bc0c9a12c1090
Author: Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2021-12-26 18:07:37 +0000
Commit: Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2022-03-28 15:25:07 +0000
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.
Approved by: re(gjb)
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D33663
(cherry picked from commit 823a08d7403c475fea0ecbbfff021fa8db274879)
(cherry picked from commit 519bdbb448ddc176c856db14fa90d6c4ba720c8d)
---
sys/net/route/nhop.h | 3 +++
sys/net/route/nhop_ctl.c | 60 +++++++++++++++++++++++++++++++++++++++---------
sys/net/route/nhop_var.h | 5 ++--
3 files changed, 55 insertions(+), 13 deletions(-)
diff --git a/sys/net/route/nhop.h b/sys/net/route/nhop.h
index ce18cc04e163..1d37a84b68b4 100644
--- a/sys/net/route/nhop.h
+++ b/sys/net/route/nhop.h
@@ -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 */
diff --git a/sys/net/route/nhop_ctl.c b/sys/net/route/nhop_ctl.c
index 21aefcc7a83b..45830cbb14c8 100644
--- a/sys/net/route/nhop_ctl.c
+++ b/sys/net/route/nhop_ctl.c
@@ -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;
diff --git a/sys/net/route/nhop_var.h b/sys/net/route/nhop_var.h
index 76984df0497f..facf8a7a546b 100644
--- a/sys/net/route/nhop_var.h
+++ b/sys/net/route/nhop_var.h
@@ -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 */