Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 7 Jan 2021 19:38:26 GMT
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: d68cf57b7f22 - main - Refactor rt_addrmsg() and rt_routemsg().
Message-ID:  <202101071938.107JcQ8m069618@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by melifaro:

URL: https://cgit.FreeBSD.org/src/commit/?id=d68cf57b7f22a38a2b276bff039432d1aa2022f8

commit d68cf57b7f22a38a2b276bff039432d1aa2022f8
Author:     Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2021-01-07 19:13:52 +0000
Commit:     Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2021-01-07 19:38:19 +0000

    Refactor rt_addrmsg() and rt_routemsg().
    
    Summary:
    * Refactor rt_addrmsg(): make V_rt_add_addr_allfibs decision locally.
    * Fix rt_routemsg() and multipath by accepting nexthop instead of interface pointer.
    * Refactor rtsock_routemsg(): avoid accessing rtentry fields directly.
    * Simplify in_addprefix() by moving prefix search to a separate  function.
    
    Reviewers: #network
    
    Subscribers: imp, ae, bz
    
    Differential Revision: https://reviews.freebsd.org/D28011
---
 sys/net/route.c           | 17 ++++++++++-------
 sys/net/route.h           |  6 +-----
 sys/net/route/route_ctl.c | 15 ++++++++++++---
 sys/net/route/route_ctl.h |  1 +
 sys/net/route/route_var.h |  7 +++++++
 sys/net/rtsock.c          | 16 +++++++++-------
 sys/netinet/in.c          | 46 +++++++++++++++++++++++++---------------------
 sys/netinet6/in6.c        |  2 +-
 sys/netinet6/nd6_rtr.c    | 18 ++++++++++++------
 9 files changed, 78 insertions(+), 50 deletions(-)

diff --git a/sys/net/route.c b/sys/net/route.c
index 2f4ae40e83aa..b3383f90789b 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -710,10 +710,13 @@ rt_addrmsg(int cmd, struct ifaddr *ifa, int fibnum)
 
 	KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE,
 	    ("unexpected cmd %d", cmd));
-	KASSERT(fibnum == RT_ALL_FIBS || (fibnum >= 0 && fibnum < rt_numfibs),
+	KASSERT((fibnum >= 0 && fibnum < rt_numfibs),
 	    ("%s: fib out of range 0 <=%d<%d", __func__, fibnum, rt_numfibs));
 
 	EVENTHANDLER_DIRECT_INVOKE(rt_addrmsg, ifa, cmd);
+
+	if (V_rt_add_addr_allfibs)
+		fibnum = RT_ALL_FIBS;
 	return (rtsock_addrmsg(cmd, ifa, fibnum));
 }
 
@@ -721,13 +724,13 @@ rt_addrmsg(int cmd, struct ifaddr *ifa, int fibnum)
  * Announce kernel-originated route addition/removal to rtsock based on @rt data.
  * cmd: RTM_ cmd
  * @rt: valid rtentry
- * @ifp: target route interface
+ * @nh: nhop object to announce
  * @fibnum: fib id or RT_ALL_FIBS
  *
  * Returns 0 on success.
  */
 int
-rt_routemsg(int cmd, struct rtentry *rt, struct ifnet *ifp, int rti_addrs,
+rt_routemsg(int cmd, struct rtentry *rt, struct nhop_object *nh,
     int fibnum)
 {
 
@@ -739,7 +742,7 @@ rt_routemsg(int cmd, struct rtentry *rt, struct ifnet *ifp, int rti_addrs,
 
 	KASSERT(rt_key(rt) != NULL, (":%s: rt_key must be supplied", __func__));
 
-	return (rtsock_routemsg(cmd, rt, ifp, 0, fibnum));
+	return (rtsock_routemsg(cmd, rt, nh, fibnum));
 }
 
 /*
@@ -775,16 +778,16 @@ rt_newaddrmsg_fib(int cmd, struct ifaddr *ifa, struct rtentry *rt, int fibnum)
 
 	KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE,
 		("unexpected cmd %u", cmd));
-	KASSERT(fibnum == RT_ALL_FIBS || (fibnum >= 0 && fibnum < rt_numfibs),
+	KASSERT((fibnum >= 0 && fibnum < rt_numfibs),
 	    ("%s: fib out of range 0 <=%d<%d", __func__, fibnum, rt_numfibs));
 
 	if (cmd == RTM_ADD) {
 		rt_addrmsg(cmd, ifa, fibnum);
 		if (rt != NULL)
-			rt_routemsg(cmd, rt, ifa->ifa_ifp, 0, fibnum);
+			rt_routemsg(cmd, rt, nhop_select(rt->rt_nhop, 0), fibnum);
 	} else {
 		if (rt != NULL)
-			rt_routemsg(cmd, rt, ifa->ifa_ifp, 0, fibnum);
+			rt_routemsg(cmd, rt, nhop_select(rt->rt_nhop, 0), fibnum);
 		rt_addrmsg(cmd, ifa, fibnum);
 	}
 }
diff --git a/sys/net/route.h b/sys/net/route.h
index e9f5b8b9d7f6..96a8e78ecb3a 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -417,7 +417,7 @@ void	 rt_missmsg(int, struct rt_addrinfo *, int, int);
 void	 rt_missmsg_fib(int, struct rt_addrinfo *, int, int, int);
 void	 rt_newaddrmsg_fib(int, struct ifaddr *, struct rtentry *, int);
 int	 rt_addrmsg(int, struct ifaddr *, int);
-int	 rt_routemsg(int, struct rtentry *, struct ifnet *ifp, int, int);
+int	 rt_routemsg(int, struct rtentry *, struct nhop_object *, int);
 int	 rt_routemsg_info(int, struct rt_addrinfo *, int);
 void	 rt_newmaddrmsg(int, struct ifmultiaddr *);
 void 	 rt_maskedcopy(struct sockaddr *, struct sockaddr *, struct sockaddr *);
@@ -425,10 +425,6 @@ struct rib_head *rt_table_init(int, int, u_int);
 void	rt_table_destroy(struct rib_head *);
 u_int	rt_tables_get_gen(uint32_t table, sa_family_t family);
 
-int	rtsock_addrmsg(int, struct ifaddr *, int);
-int	rtsock_routemsg(int, struct rtentry *, struct ifnet *ifp, int, int);
-int	rtsock_routemsg_info(int, struct rt_addrinfo *, int);
-
 struct sockaddr *rtsock_fix_netmask(const struct sockaddr *dst,
 	    const struct sockaddr *smask, struct sockaddr_storage *dmask);
 
diff --git a/sys/net/route/route_ctl.c b/sys/net/route/route_ctl.c
index c0fc3b5f1888..230d23845c64 100644
--- a/sys/net/route/route_ctl.c
+++ b/sys/net/route/route_ctl.c
@@ -244,6 +244,16 @@ rt_is_host(const struct rtentry *rt)
 	return (rt->rte_flags & RTF_HOST);
 }
 
+sa_family_t
+rt_get_family(const struct rtentry *rt)
+{
+	const struct sockaddr *dst;
+
+	dst = (const struct sockaddr *)rt_key_const(rt);
+
+	return (dst->sa_family);
+}
+
 /*
  * Returns pointer to nexthop or nexthop group
  * associated with @rt
@@ -1322,11 +1332,10 @@ rib_walk_del(u_int fibnum, int family, rib_filter_f_t *filter_f, void *arg, bool
 				nhg = (struct nhgrp_object *)nh;
 				wn = nhgrp_get_nhops(nhg, &num_nhops);
 				for (int i = 0; i < num_nhops; i++)
-					rt_routemsg(RTM_DELETE, rt,
-					    wn[i].nh->nh_ifp, 0, fibnum);
+					rt_routemsg(RTM_DELETE, rt, wn[i].nh, fibnum);
 			} else
 #endif
-			rt_routemsg(RTM_DELETE, rt, nh->nh_ifp, 0, fibnum);
+			rt_routemsg(RTM_DELETE, rt, nh, fibnum);
 		}
 		rtfree(rt);
 	}
diff --git a/sys/net/route/route_ctl.h b/sys/net/route/route_ctl.h
index da0520fd89f5..c52c6b96e126 100644
--- a/sys/net/route/route_ctl.h
+++ b/sys/net/route/route_ctl.h
@@ -100,6 +100,7 @@ const struct rtentry *rib_lookup_lpm(uint32_t fibnum, int family,
 
 /* rtentry accessors */
 bool rt_is_host(const struct rtentry *rt);
+sa_family_t rt_get_family(const struct rtentry *);
 struct nhop_object *rt_get_raw_nhop(const struct rtentry *rt);
 #ifdef INET
 struct in_addr;
diff --git a/sys/net/route/route_var.h b/sys/net/route/route_var.h
index fe299f90714d..427c286a5090 100644
--- a/sys/net/route/route_var.h
+++ b/sys/net/route/route_var.h
@@ -306,6 +306,13 @@ void nhgrp_ref_object(struct nhgrp_object *nhg);
 uint32_t nhgrp_get_idx(const struct nhgrp_object *nhg);
 void nhgrp_free(struct nhgrp_object *nhg);
 
+/* rtsock */
+int rtsock_routemsg(int cmd, struct rtentry *rt, struct nhop_object *nh,
+    int fibnum);
+int rtsock_routemsg_info(int cmd, struct rt_addrinfo *info, int fibnum);
+int rtsock_addrmsg(int cmd, struct ifaddr *ifa, int fibnum);
+
+
 /* lookup_framework.c */
 void fib_grow_rtables(uint32_t new_num_tables);
 int fib_select_algo_initial(struct rib_head *rh);
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 88ae0c0868c8..ba1182d55439 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1591,23 +1591,25 @@ rtsock_addrmsg(int cmd, struct ifaddr *ifa, int fibnum)
  * Returns 0 on success.
  */
 int
-rtsock_routemsg(int cmd, struct rtentry *rt, struct ifnet *ifp, int rti_addrs,
+rtsock_routemsg(int cmd, struct rtentry *rt, struct nhop_object *nh,
     int fibnum)
 {
-	struct sockaddr_storage ss;
+	union sockaddr_union dst, mask;
 	struct rt_addrinfo info;
-	struct nhop_object *nh;
 
 	if (V_route_cb.any_count == 0)
 		return (0);
 
-	nh = rt->rt_nhop;
+	int family = rt_get_family(rt);
+	init_sockaddrs_family(family, &dst.sa, &mask.sa);
+	export_rtaddrs(rt, &dst.sa, &mask.sa);
+
 	bzero((caddr_t)&info, sizeof(info));
-	info.rti_info[RTAX_DST] = rt_key(rt);
-	info.rti_info[RTAX_NETMASK] = rtsock_fix_netmask(rt_key(rt), rt_mask(rt), &ss);
+	info.rti_info[RTAX_DST] = &dst.sa;
+	info.rti_info[RTAX_NETMASK] = &mask.sa;
 	info.rti_info[RTAX_GATEWAY] = &nh->gw_sa;
 	info.rti_flags = rt->rte_flags | nhop_get_rtflags(nh);
-	info.rti_ifp = ifp;
+	info.rti_ifp = nh->nh_ifp;
 
 	return (rtsock_routemsg_info(cmd, &info, fibnum));
 }
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index dd2286195c41..cf6541dca879 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -714,15 +714,15 @@ in_gifaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
 	    ? RTF_HOST : 0)
 
 /*
- * Check if we have a route for the given prefix already or add one accordingly.
+ * Check if we have a route for the given prefix already.
  */
-int
-in_addprefix(struct in_ifaddr *target, int flags)
+static bool
+in_hasrtprefix(struct in_ifaddr *target, int flags)
 {
 	struct rm_priotracker in_ifa_tracker;
 	struct in_ifaddr *ia;
 	struct in_addr prefix, mask, p, m;
-	int error;
+	bool result = false;
 
 	if ((flags & RTF_HOST) != 0) {
 		prefix = target->ia_dstaddr.sin_addr;
@@ -758,22 +758,30 @@ in_addprefix(struct in_ifaddr *target, int flags)
 		 * interface address, we are done here.
 		 */
 		if (ia->ia_flags & IFA_ROUTE) {
-			if (V_nosameprefix) {
-				IN_IFADDR_RUNLOCK(&in_ifa_tracker);
-				return (EEXIST);
-			} else {
-				int fibnum;
-
-				fibnum = V_rt_add_addr_allfibs ? RT_ALL_FIBS :
-					target->ia_ifp->if_fib;
-				rt_addrmsg(RTM_ADD, &target->ia_ifa, fibnum);
-				IN_IFADDR_RUNLOCK(&in_ifa_tracker);
-				return (0);
-			}
+			result = true;
+			break;
 		}
 	}
 	IN_IFADDR_RUNLOCK(&in_ifa_tracker);
 
+	return (result);
+}
+
+int
+in_addprefix(struct in_ifaddr *target, int flags)
+{
+	int error;
+
+	if (in_hasrtprefix(target, flags)) {
+		if (V_nosameprefix)
+			return (EEXIST);
+		else {
+			rt_addrmsg(RTM_ADD, &target->ia_ifa,
+			    target->ia_ifp->if_fib);
+			return (0);
+		}
+	}
+
 	/*
 	 * No-one seem to have this prefix route, so we try to insert it.
 	 */
@@ -869,11 +877,7 @@ in_scrubprefix(struct in_ifaddr *target, u_int flags)
 	}
 
 	if ((target->ia_flags & IFA_ROUTE) == 0) {
-		int fibnum;
-
-		fibnum = V_rt_add_addr_allfibs ? RT_ALL_FIBS :
-			target->ia_ifp->if_fib;
-		rt_addrmsg(RTM_DELETE, &target->ia_ifa, fibnum);
+		rt_addrmsg(RTM_DELETE, &target->ia_ifa, target->ia_ifp->if_fib);
 
 		/*
 		 * Removing address from !IFF_UP interface or
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index a86bdf5a1876..7c572e7b833b 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -186,7 +186,7 @@ in6_newaddrmsg(struct in6_ifaddr *ia, int cmd)
 	if (cmd != RTM_DELETE)
 		info.rti_ifp = V_loif;
 
-	fibnum = V_rt_add_addr_allfibs ? RT_ALL_FIBS : ia62ifa(ia)->ifa_ifp->if_fib;
+	fibnum = ia62ifa(ia)->ifa_ifp->if_fib;
 
 	if (cmd == RTM_ADD) {
 		rt_addrmsg(cmd, &ia->ia_ifa, fibnum);
diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c
index 41c9e0251d59..c6317b1ea263 100644
--- a/sys/netinet6/nd6_rtr.c
+++ b/sys/netinet6/nd6_rtr.c
@@ -698,8 +698,10 @@ defrouter_addreq(struct nd_defrouter *new)
 
 	NET_EPOCH_ASSERT();
 	error = rib_action(fibnum, RTM_ADD, &info, &rc);
-	if (rc.rc_rt != NULL)
-		rt_routemsg(RTM_ADD, rc.rc_rt, new->ifp, 0, fibnum);
+	if (rc.rc_rt != NULL) {
+		struct nhop_object *nh = nhop_select(rc.rc_nh_new, 0);
+		rt_routemsg(RTM_ADD, rc.rc_rt, nh, fibnum);
+	}
 	if (error == 0)
 		new->installed = 1;
 }
@@ -736,8 +738,10 @@ defrouter_delreq(struct nd_defrouter *dr)
 
 	NET_EPOCH_ENTER(et);
 	rib_action(fibnum, RTM_DELETE, &info, &rc);
-	if (rc.rc_rt != NULL)
-		rt_routemsg(RTM_DELETE, rc.rc_rt, dr->ifp, 0, fibnum);
+	if (rc.rc_rt != NULL) {
+		struct nhop_object *nh = nhop_select(rc.rc_nh_old, 0);
+		rt_routemsg(RTM_DELETE, rc.rc_rt, nh, fibnum);
+	}
 	NET_EPOCH_EXIT(et);
 
 	dr->installed = 0;
@@ -2077,7 +2081,8 @@ nd6_prefix_onlink_rtrequest(struct nd_prefix *pr, struct ifaddr *ifa)
 		}
 
 		pr->ndpr_stateflags |= NDPRF_ONLINK;
-		rt_routemsg(RTM_ADD, rc.rc_rt, pr->ndpr_ifp, 0, fibnum);
+		struct nhop_object *nh = nhop_select(rc.rc_nh_new, 0);
+		rt_routemsg(RTM_ADD, rc.rc_rt, nh, fibnum);
 	}
 
 	/* Return the last error we got. */
@@ -2224,7 +2229,8 @@ nd6_prefix_offlink(struct nd_prefix *pr)
 		}
 
 		/* report route deletion to the routing socket. */
-		rt_routemsg(RTM_DELETE, rc.rc_rt, ifp, 0, fibnum);
+		struct nhop_object *nh = nhop_select(rc.rc_nh_old, 0);
+		rt_routemsg(RTM_DELETE, rc.rc_rt, nh, fibnum);
 	}
 	NET_EPOCH_EXIT(et);
 	error = a_failure;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202101071938.107JcQ8m069618>