aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander V. Chernikov <melifaro@FreeBSD.org>2022-08-04 12:35:31 +0000
committerAlexander V. Chernikov <melifaro@FreeBSD.org>2022-08-10 18:27:13 +0000
commit66230639ce311c9fbc3a92e7039b8577a7577b6e (patch)
treeff771f0a2f9ff4dec793dfe248be830275d966c7
parentdedeec1143385b0c7436d360170d8d99b2d0fa18 (diff)
downloadsrc-66230639ce311c9fbc3a92e7039b8577a7577b6e.tar.gz
src-66230639ce311c9fbc3a92e7039b8577a7577b6e.zip
routing: split nexthop creation and rtentry creation.
This change is required for the upcoming introduction of the next nexhop-based operations KPI, as it will create rtentry and nexthops at different stages of route table modification. Differential Revision: https://reviews.freebsd.org/D36072 MFC after: 2 weeks
-rw-r--r--sys/net/route.c7
-rw-r--r--sys/net/route.h3
-rw-r--r--sys/net/route/route_ctl.c95
3 files changed, 42 insertions, 63 deletions
diff --git a/sys/net/route.c b/sys/net/route.c
index 0cf56fc18364..8198bc0883be 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -727,11 +727,12 @@ rt_print(char *buf, int buflen, struct rtentry *rt)
#endif
void
-rt_maskedcopy(struct sockaddr *src, struct sockaddr *dst, struct sockaddr *netmask)
+rt_maskedcopy(const struct sockaddr *src, struct sockaddr *dst,
+ const struct sockaddr *netmask)
{
- u_char *cp1 = (u_char *)src;
+ const u_char *cp1 = (const u_char *)src;
u_char *cp2 = (u_char *)dst;
- u_char *cp3 = (u_char *)netmask;
+ const u_char *cp3 = (const u_char *)netmask;
u_char *cplim = cp2 + *cp3;
u_char *cplim2 = cp2 + *cp1;
diff --git a/sys/net/route.h b/sys/net/route.h
index 46dc0c555218..931b284b664d 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -423,7 +423,8 @@ int rt_addrmsg(int, struct ifaddr *, 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 *);
+void rt_maskedcopy(const struct sockaddr *, struct sockaddr *,
+ const struct sockaddr *);
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);
diff --git a/sys/net/route/route_ctl.c b/sys/net/route/route_ctl.c
index 34a029746fa1..8f116cd65aa9 100644
--- a/sys/net/route/route_ctl.c
+++ b/sys/net/route/route_ctl.c
@@ -626,13 +626,38 @@ check_gateway(struct rib_head *rnh, struct sockaddr *dst,
* to be stable till the end of the operation (radix rt insertion/change/removal).
* return errno otherwise.
*/
+static struct rtentry *
+create_rtentry(struct rib_head *rnh, const struct sockaddr *dst,
+ struct sockaddr *netmask)
+{
+ MPASS(dst->sa_len <= sizeof(((struct rtentry *)NULL)->rt_dstb));
+
+ struct rtentry *rt = uma_zalloc(V_rtzone, M_NOWAIT | M_ZERO);
+ if (rt == NULL)
+ return (NULL);
+ rt->rte_flags = RTF_UP | (netmask == NULL ? RTF_HOST : 0);
+
+ /* Fill in dst, ensuring it's masked if needed. */
+ if (netmask != NULL) {
+ rt_maskedcopy(dst, &rt->rt_dst, netmask);
+ } else
+ bcopy(dst, &rt->rt_dst, dst->sa_len);
+ rt_key(rt) = &rt->rt_dst;
+ /* Set netmask to the storage from info. It will be updated upon insertion */
+ rt_mask(rt) = netmask;
+
+ return (rt);
+}
+
static int
-create_rtentry(struct rib_head *rnh, struct rt_addrinfo *info,
- struct rtentry **prt)
+add_route_byinfo(struct rib_head *rnh, struct rt_addrinfo *info,
+ struct rib_cmd_info *rc)
{
- struct sockaddr *dst, *ndst, *gateway, *netmask;
- struct rtentry *rt;
+ struct nhop_object *nh_orig;
+ struct route_nhop_data rnd_orig, rnd_add;
struct nhop_object *nh;
+ struct rtentry *rt, *rt_orig;
+ struct sockaddr *dst, *gateway, *netmask;
int error, flags;
dst = info->rti_info[RTAX_DST];
@@ -663,65 +688,17 @@ create_rtentry(struct rib_head *rnh, struct rt_addrinfo *info,
return (error);
}
- error = nhop_create_from_info(rnh, info, &nh);
- if (error != 0)
- return (error);
-
- rt = uma_zalloc(V_rtzone, M_NOWAIT | M_ZERO);
- if (rt == NULL) {
- nhop_free(nh);
+ if ((rt = create_rtentry(rnh, dst, netmask)) == NULL)
return (ENOBUFS);
- }
- rt->rte_flags = (RTF_UP | flags) & RTE_RT_FLAG_MASK;
- rt->rt_nhop = nh;
-
- /* Fill in dst */
- memcpy(&rt->rt_dst, dst, dst->sa_len);
- rt_key(rt) = &rt->rt_dst;
- /*
- * point to the (possibly newly malloc'd) dest address.
- */
- ndst = (struct sockaddr *)rt_key(rt);
-
- /*
- * make sure it contains the value we want (masked if needed).
- */
- if (netmask) {
- rt_maskedcopy(dst, ndst, netmask);
- } else
- bcopy(dst, ndst, dst->sa_len);
- /* Set netmask to the storage from info. It will be updated upon insertion */
- rt_mask(rt) = netmask;
-
- /*
- * We use the ifa reference returned by rt_getifa_fib().
- * This moved from below so that rnh->rnh_addaddr() can
- * examine the ifa and ifa->ifa_ifp if it so desires.
- */
- rt->rt_weight = get_info_weight(info, RT_DEFAULT_WEIGHT);
-
- *prt = rt;
- return (0);
-}
-
-static int
-add_route_byinfo(struct rib_head *rnh, struct rt_addrinfo *info,
- struct rib_cmd_info *rc)
-{
- struct nhop_object *nh_orig;
- struct route_nhop_data rnd_orig, rnd_add;
- struct nhop_object *nh;
- struct rtentry *rt, *rt_orig;
- int error;
-
- error = create_rtentry(rnh, info, &rt);
- if (error != 0)
+ error = nhop_create_from_info(rnh, info, &nh);
+ if (error != 0) {
+ uma_zfree(V_rtzone, rt);
return (error);
+ }
- rnd_add.rnd_nhop = rt->rt_nhop;
- rnd_add.rnd_weight = rt->rt_weight;
- nh = rt->rt_nhop;
+ rnd_add.rnd_nhop = nh;
+ rnd_add.rnd_weight = get_info_weight(info, RT_DEFAULT_WEIGHT);
RIB_WLOCK(rnh);
error = add_route(rnh, rt, &rnd_add, rc);