svn commit: r365973 - in head/sys: net net/route netinet netinet6

Alexander V. Chernikov melifaro at FreeBSD.org
Mon Sep 21 20:02:34 UTC 2020


Author: melifaro
Date: Mon Sep 21 20:02:26 2020
New Revision: 365973
URL: https://svnweb.freebsd.org/changeset/base/365973

Log:
  Rework part of routing code to reduce difference to D26449.
  
  * Split rt_setmetrics into get_info_weight() and rt_set_expire_info(),
   as these two can be applied at different entities and at different times.
  * Start filling route weight in route change notifications
  * Pass flowid to UDP/raw IP route lookups
  * Rework nd6_subscription_cb() and sysctl_dumpentry() to prepare for the fact
   that rtentry can contain multiple nexthops.
  
  Differential Revision:	https://reviews.freebsd.org/D26497

Modified:
  head/sys/net/route.c
  head/sys/net/route.h
  head/sys/net/route/route_ctl.c
  head/sys/net/route/route_var.h
  head/sys/net/rtsock.c
  head/sys/netinet/ip_output.c
  head/sys/netinet6/nd6.c

Modified: head/sys/net/route.c
==============================================================================
--- head/sys/net/route.c	Mon Sep 21 19:50:39 2020	(r365972)
+++ head/sys/net/route.c	Mon Sep 21 20:02:26 2020	(r365973)
@@ -849,18 +849,6 @@ rt_mpath_unlink(struct rib_head *rnh, struct rt_addrin
 #endif
 
 void
-rt_setmetrics(const struct rt_addrinfo *info, struct rtentry *rt)
-{
-
-	if (info->rti_mflags & RTV_WEIGHT)
-		rt->rt_weight = info->rti_rmx->rmx_weight;
-	/* Kernel -> userland timebase conversion. */
-	if (info->rti_mflags & RTV_EXPIRE)
-		rt->rt_expire = info->rti_rmx->rmx_expire ?
-		    info->rti_rmx->rmx_expire - time_second + time_uptime : 0;
-}
-
-void
 rt_maskedcopy(struct sockaddr *src, struct sockaddr *dst, struct sockaddr *netmask)
 {
 	u_char *cp1 = (u_char *)src;

Modified: head/sys/net/route.h
==============================================================================
--- head/sys/net/route.h	Mon Sep 21 19:50:39 2020	(r365972)
+++ head/sys/net/route.h	Mon Sep 21 20:02:26 2020	(r365973)
@@ -104,6 +104,10 @@ struct rt_metrics {
 /* lle state is exported in rmx_state rt_metrics field */
 #define	rmx_state	rmx_weight
 
+/* default route weight */
+#define	RT_DEFAULT_WEIGHT	1
+#define	RT_MAX_WEIGHT		16777215	/* 3 bytes */
+
 /*
  * Keep a generation count of routing table, incremented on route addition,
  * so we can invalidate caches.  This is accessed without a lock, as precision

Modified: head/sys/net/route/route_ctl.c
==============================================================================
--- head/sys/net/route/route_ctl.c	Mon Sep 21 19:50:39 2020	(r365972)
+++ head/sys/net/route/route_ctl.c	Mon Sep 21 20:02:26 2020	(r365973)
@@ -175,6 +175,32 @@ get_rnh(uint32_t fibnum, const struct rt_addrinfo *inf
 	return (rnh);
 }
 
+static int
+get_info_weight(const struct rt_addrinfo *info, uint32_t default_weight)
+{
+	uint32_t weight;
+
+	if (info->rti_mflags & RTV_WEIGHT)
+		weight = info->rti_rmx->rmx_weight;
+	else
+		weight = default_weight;
+	/* Keep upper 1 byte for adm distance purposes */
+	if (weight > RT_MAX_WEIGHT)
+		weight = RT_MAX_WEIGHT;
+
+	return (weight);
+}
+
+static void
+rt_set_expire_info(struct rtentry *rt, const struct rt_addrinfo *info)
+{
+
+	/* Kernel -> userland timebase conversion. */
+	if (info->rti_mflags & RTV_EXPIRE)
+		rt->rt_expire = info->rti_rmx->rmx_expire ?
+		    info->rti_rmx->rmx_expire - time_second + time_uptime : 0;
+}
+
 /*
  * Check if specified @gw matches gw data in the nexthop @nh.
  *
@@ -423,10 +449,9 @@ create_rtentry(struct rib_head *rnh, struct rt_addrinf
 	 * examine the ifa and  ifa->ifa_ifp if it so desires.
 	 */
 	ifa = info->rti_ifa;
-	rt->rt_weight = 1;
+	rt->rt_weight = get_info_weight(info, RT_DEFAULT_WEIGHT);
+	rt_set_expire_info(rt, info);
 
-	rt_setmetrics(info, rt);
-
 	*prt = rt;
 	return (0);
 }
@@ -815,7 +840,7 @@ change_route_nhop(struct rib_head *rnh, struct rtentry
 
 	if (rnd->rnd_nhop != NULL) {
 		/* Changing expiration & nexthop & weight to a new one */
-		rt_setmetrics(info, rt);
+		rt_set_expire_info(rt, info);
 		rt->rt_nhop = rnd->rnd_nhop;
 		rt->rt_weight = rnd->rnd_weight;
 		if (rt->rt_expire > 0)

Modified: head/sys/net/route/route_var.h
==============================================================================
--- head/sys/net/route/route_var.h	Mon Sep 21 19:50:39 2020	(r365972)
+++ head/sys/net/route/route_var.h	Mon Sep 21 20:02:26 2020	(r365973)
@@ -115,7 +115,6 @@ _Static_assert(__offsetof(struct route, ro_dst) == __o
 struct rib_head *rt_tables_get_rnh(uint32_t table, sa_family_t family);
 void rt_mpath_init_rnh(struct rib_head *rnh);
 int rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum);
-void rt_setmetrics(const struct rt_addrinfo *info, struct rtentry *rt);
 #ifdef RADIX_MPATH
 struct radix_node *rt_mpath_unlink(struct rib_head *rnh,
     struct rt_addrinfo *info, struct rtentry *rto, int *perror);

Modified: head/sys/net/rtsock.c
==============================================================================
--- head/sys/net/rtsock.c	Mon Sep 21 19:50:39 2020	(r365972)
+++ head/sys/net/rtsock.c	Mon Sep 21 20:02:26 2020	(r365973)
@@ -175,6 +175,8 @@ static int	rtsock_msg_buffer(int type, struct rt_addri
 static int	rt_xaddrs(caddr_t cp, caddr_t cplim,
 			struct rt_addrinfo *rtinfo);
 static int	sysctl_dumpentry(struct radix_node *rn, void *vw);
+static int	sysctl_dumpnhop(struct rtentry *rt, struct nhop_object *nh,
+			uint32_t weight, struct walkarg *w);
 static int	sysctl_iflist(int af, struct walkarg *w);
 static int	sysctl_ifmalist(int af, struct walkarg *w);
 static int	route_output(struct mbuf *m, struct socket *so, ...);
@@ -740,6 +742,7 @@ handle_rtm_get(struct rt_addrinfo *info, u_int fibnum,
 		}
 	}
 	rc->rc_nh_new = rc->rc_rt->rt_nhop;
+	rc->rc_nh_weight = rc->rc_rt->rt_weight;
 	RIB_RUNLOCK(rnh);
 
 	return (0);
@@ -1696,9 +1699,7 @@ sysctl_dumpentry(struct radix_node *rn, void *vw)
 	struct walkarg *w = vw;
 	struct rtentry *rt = (struct rtentry *)rn;
 	struct nhop_object *nh;
-	int error = 0, size;
-	struct rt_addrinfo info;
-	struct sockaddr_storage ss;
+	int error = 0;
 
 	NET_EPOCH_ASSERT();
 
@@ -1707,6 +1708,20 @@ sysctl_dumpentry(struct radix_node *rn, void *vw)
 	if (!can_export_rte(w->w_req->td->td_ucred, rt))
 		return (0);
 	nh = rt->rt_nhop;
+	error = sysctl_dumpnhop(rt, nh, rt->rt_weight, w);
+
+	return (0);
+}
+
+
+static int
+sysctl_dumpnhop(struct rtentry *rt, struct nhop_object *nh, uint32_t weight,
+    struct walkarg *w)
+{
+	struct rt_addrinfo info;
+	int error = 0, size;
+	struct sockaddr_storage ss;
+
 	bzero((caddr_t)&info, sizeof(info));
 	info.rti_info[RTAX_DST] = rt_key(rt);
 	info.rti_info[RTAX_GATEWAY] = &nh->gw_sa;

Modified: head/sys/netinet/ip_output.c
==============================================================================
--- head/sys/netinet/ip_output.c	Mon Sep 21 19:50:39 2020	(r365972)
+++ head/sys/netinet/ip_output.c	Mon Sep 21 20:02:26 2020	(r365973)
@@ -512,7 +512,8 @@ again:
 	} else {
 		struct nhop_object *nh;
 
-		nh = fib4_lookup(M_GETFIB(m), ip->ip_dst, 0, NHR_NONE, 0);
+		nh = fib4_lookup(M_GETFIB(m), ip->ip_dst, 0, NHR_NONE,
+		    m->m_pkthdr.flowid);
 		if (nh == NULL) {
 #if defined(IPSEC) || defined(IPSEC_SUPPORT)
 			/*

Modified: head/sys/netinet6/nd6.c
==============================================================================
--- head/sys/netinet6/nd6.c	Mon Sep 21 19:50:39 2020	(r365972)
+++ head/sys/netinet6/nd6.c	Mon Sep 21 20:02:26 2020	(r365973)
@@ -1570,23 +1570,28 @@ nd6_free_redirect(const struct llentry *ln)
 /*
  * Updates status of the default router route.
  */
-void
-nd6_subscription_cb(struct rib_head *rnh, struct rib_cmd_info *rc, void *arg)
+static void
+check_release_defrouter(struct rib_cmd_info *rc, void *_cbdata)
 {
 	struct nd_defrouter *dr;
 	struct nhop_object *nh;
 
-	if (rc->rc_cmd == RTM_DELETE) {
-		nh = rc->rc_nh_old;
+	nh = rc->rc_nh_old;
 
-		if (nh->nh_flags & NHF_DEFAULT) {
-			dr = defrouter_lookup(&nh->gw6_sa.sin6_addr, nh->nh_ifp);
-			if (dr != NULL) {
-				dr->installed = 0;
-				defrouter_rele(dr);
-			}
+	if ((nh != NULL) && (nh->nh_flags & NHF_DEFAULT)) {
+		dr = defrouter_lookup(&nh->gw6_sa.sin6_addr, nh->nh_ifp);
+		if (dr != NULL) {
+			dr->installed = 0;
+			defrouter_rele(dr);
 		}
 	}
+}
+
+void
+nd6_subscription_cb(struct rib_head *rnh, struct rib_cmd_info *rc, void *arg)
+{
+
+	check_release_defrouter(rc, NULL);
 }
 
 int


More information about the svn-src-head mailing list