Page MenuHomeFreeBSD

D25067.id72444.diff
No OneTemporary

D25067.id72444.diff

Index: sys/net/if_llatbl.c
===================================================================
--- sys/net/if_llatbl.c
+++ sys/net/if_llatbl.c
@@ -58,6 +58,7 @@
#include <net/if_dl.h>
#include <net/if_var.h>
#include <net/route.h>
+#include <net/route/route_ctl.h>
#include <net/vnet.h>
#include <netinet/if_ether.h>
#include <netinet6/in6_var.h>
Index: sys/net/route.h
===================================================================
--- sys/net/route.h
+++ sys/net/route.h
@@ -399,12 +399,6 @@
void rtfree_func(struct rtentry *);
void rt_updatemtu(struct ifnet *);
-typedef int rt_walktree_f_t(struct rtentry *, void *);
-typedef void rt_setwarg_t(struct rib_head *, uint32_t, int, void *);
-void rib_walk_del(u_int fibnum, int family, rt_filter_f_t *filter_f,
- void *arg, bool report);
-void rt_foreach_fib_walk(int af, rt_setwarg_t *, rt_walktree_f_t *, void *);
-void rt_foreach_fib_walk_del(int af, rt_filter_f_t *filter_f, void *arg);
void rt_flushifroutes_af(struct ifnet *, int);
void rt_flushifroutes(struct ifnet *ifp);
@@ -423,12 +417,8 @@
int rib_lookup_info(uint32_t, const struct sockaddr *, uint32_t, uint32_t,
struct rt_addrinfo *);
void rib_free_info(struct rt_addrinfo *info);
-int rib_add_redirect(u_int fibnum, struct sockaddr *dst,
- struct sockaddr *gateway, struct sockaddr *author, struct ifnet *ifp,
- int flags, int expire_sec);
/* New API */
-void rib_walk(int af, u_int fibnum, rt_walktree_f_t *wa_f, void *arg);
struct nhop_object *rib_lookup(uint32_t fibnum, const struct sockaddr *dst,
uint32_t flags, uint32_t flowid);
#endif
Index: sys/net/route.c
===================================================================
--- sys/net/route.c
+++ sys/net/route.c
@@ -61,6 +61,7 @@
#include <net/if_var.h>
#include <net/if_dl.h>
#include <net/route.h>
+#include <net/route/route_ctl.h>
#include <net/route/route_var.h>
#include <net/route/nhop.h>
#include <net/route/shared.h>
@@ -1148,6 +1149,7 @@
{
const struct sockaddr *dst;
struct rib_head *rnh;
+ struct rib_cmd_info rc;
int error;
KASSERT((fibnum < rt_numfibs), ("rtrequest1_fib: bad fibnum"));
@@ -1180,10 +1182,11 @@
if (info->rti_flags & RTF_HOST)
info->rti_info[RTAX_NETMASK] = NULL;
+ bzero(&rc, sizeof(struct rib_cmd_info));
error = 0;
switch (req) {
case RTM_DELETE:
- error = del_route(rnh, info, ret_nrt);
+ error = del_route(rnh, info, &rc);
break;
case RTM_RESOLVE:
/*
@@ -1192,15 +1195,18 @@
*/
break;
case RTM_ADD:
- error = add_route(rnh, info, ret_nrt);
+ error = add_route(rnh, info, &rc);
break;
case RTM_CHANGE:
- error = change_route(rnh, info, ret_nrt);
+ error = change_route(rnh, info, &rc);
break;
default:
error = EOPNOTSUPP;
}
+ if (ret_nrt != NULL)
+ *ret_nrt = rc.rc_rt;
+
return (error);
}
Index: sys/net/route/nhop_ctl.c
===================================================================
--- sys/net/route/nhop_ctl.c
+++ sys/net/route/nhop_ctl.c
@@ -44,6 +44,7 @@
#include <net/if_var.h>
#include <net/if_dl.h>
#include <net/route.h>
+#include <net/route/route_ctl.h>
#include <net/route/route_var.h>
#include <net/route/nhop_utils.h>
#include <net/route/nhop.h>
Index: sys/net/route/route_ctl.h
===================================================================
--- /dev/null
+++ sys/net/route/route_ctl.h
@@ -0,0 +1,69 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2020 Alexander V. Chernikov
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * This header file contains public functions and structures used for
+ * routing table manipulations.
+ */
+
+#ifndef _NET_ROUTE_ROUTE_CTL_H_
+#define _NET_ROUTE_ROUTE_CTL_H_
+
+struct rib_cmd_info {
+ uint8_t rc_cmd; /* RTM_ADD|RTM_DEL|RTM_CHANGE */
+ uint8_t spare[3];
+ uint32_t rc_nh_weight; /* new nhop weight */
+ struct rtentry *rc_rt; /* Target entry */
+ struct nhop_object *rc_nh_old; /* Target nhop OR mpath */
+ struct nhop_object *rc_nh_new; /* Target nhop OR mpath */
+};
+
+
+int rib_add_route(uint32_t fibnum, struct rt_addrinfo *info,
+ struct rib_cmd_info *rc);
+int rib_del_route(uint32_t fibnum, struct rt_addrinfo *info,
+ struct rib_cmd_info *rc);
+int rib_change_route(uint32_t fibnum, struct rt_addrinfo *info,
+ struct rib_cmd_info *rc);
+
+int rib_add_redirect(u_int fibnum, struct sockaddr *dst,
+ struct sockaddr *gateway, struct sockaddr *author, struct ifnet *ifp,
+ int flags, int expire_sec);
+
+typedef int rt_walktree_f_t(struct rtentry *, void *);
+void rib_walk(int af, u_int fibnum, rt_walktree_f_t *wa_f, void *arg);
+void rib_walk_del(u_int fibnum, int family, rt_filter_f_t *filter_f,
+ void *arg, bool report);
+
+typedef void rt_setwarg_t(struct rib_head *, uint32_t, int, void *);
+void rt_foreach_fib_walk(int af, rt_setwarg_t *, rt_walktree_f_t *, void *);
+void rt_foreach_fib_walk_del(int af, rt_filter_f_t *filter_f, void *arg);
+
+#endif
+
Index: sys/net/route/route_ctl.c
===================================================================
--- sys/net/route/route_ctl.c
+++ sys/net/route/route_ctl.c
@@ -47,6 +47,7 @@
#include <net/if_dl.h>
#include <net/vnet.h>
#include <net/route.h>
+#include <net/route/route_ctl.h>
#include <net/route/route_var.h>
#include <net/route/nhop_utils.h>
#include <net/route/nhop.h>
@@ -69,9 +70,61 @@
static void rt_notifydelete(struct rtentry *rt, struct rt_addrinfo *info);
+/*
+ * Returns rib_head poiner based on @fibnum and RTAX_DST family
+ * from @info.
+ */
+static struct rib_head *
+get_rnh(uint32_t fibnum, const struct rt_addrinfo *info)
+{
+ struct rib_head *rnh;
+ struct sockaddr *dst;
+
+ KASSERT((fibnum < rt_numfibs), ("%s: bad fibnum", __func__));
+
+ dst = info->rti_info[RTAX_DST];
+ rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
+
+ return (rnh);
+}
+
+/*
+ * Adds route defined by @info into the kernel table specified by @fibnum and
+ * sa_family in @info->rti_info[RTAX_DST].
+ * @rc cannot be NULL.
+ *
+ * Returns 0 on success and fills in @rc with operation metadata.
+ */
+int
+rib_add_route(uint32_t fibnum, struct rt_addrinfo *info,
+ struct rib_cmd_info *rc)
+{
+ struct rib_head *rnh;
+
+ NET_EPOCH_ASSERT();
+
+ rnh = get_rnh(fibnum, info);
+ if (rnh == NULL)
+ return (EAFNOSUPPORT);
+
+ /*
+ * Check consistency between RTF_HOST flag and netmask
+ * existence.
+ */
+ if (info->rti_flags & RTF_HOST)
+ info->rti_info[RTAX_NETMASK] = NULL;
+ else if (info->rti_info[RTAX_NETMASK] == NULL)
+ return (EINVAL);
+
+ bzero(rc, sizeof(struct rib_cmd_info));
+ rc->rc_cmd = RTM_ADD;
+
+ return (add_route(rnh, info, rc));
+}
+
int
add_route(struct rib_head *rnh, struct rt_addrinfo *info,
- struct rtentry **ret_nrt)
+ struct rib_cmd_info *rc)
{
struct sockaddr *dst, *ndst, *gateway, *netmask;
struct rtentry *rt, *rt_old;
@@ -146,6 +199,7 @@
rt->rt_weight = 1;
rt_setmetrics(info, rt);
+ rt_old = NULL;
RIB_WLOCK(rnh);
RT_LOCK(rt);
@@ -163,11 +217,17 @@
rn = rnh->rnh_addaddr(ndst, netmask, &rnh->head, rt->rt_nodes);
- if (rn != NULL && rt->rt_expire > 0)
- tmproutes_update(rnh, rt);
+ if (rn != NULL) {
+ /* Most common usecase */
+ if (rt->rt_expire > 0)
+ tmproutes_update(rnh, rt);
- rt_old = NULL;
- if (rn == NULL && (info->rti_flags & RTF_PINNED) != 0) {
+ /* Finalize notification */
+ rnh->rnh_gen++;
+
+ rc->rc_rt = RNTORT(rn);
+ rc->rc_nh_new = nh;
+ } else if ((info->rti_flags & RTF_PINNED) != 0) {
/*
* Force removal and re-try addition
@@ -180,9 +240,23 @@
rt_old = rt_unlinkrte(rnh, info, &error);
info->rti_flags |= RTF_PINNED;
info->rti_info[RTAX_DST] = info_dst;
- if (rt_old != NULL)
+ if (rt_old != NULL) {
rn = rnh->rnh_addaddr(ndst, netmask, &rnh->head,
rt->rt_nodes);
+
+ /* Finalize notification */
+ rnh->rnh_gen++;
+
+ if (rn != NULL) {
+ rc->rc_cmd = RTM_CHANGE;
+ rc->rc_rt = RNTORT(rn);
+ } else {
+ rc->rc_cmd = RTM_DELETE;
+ rc->rc_rt = rt_old;
+ }
+ rc->rc_nh_old = rt_old->rt_nhop;
+ rc->rc_nh_new = nh;
+ }
}
RIB_WUNLOCK(rnh);
@@ -208,18 +282,35 @@
if (ifa->ifa_rtrequest)
ifa->ifa_rtrequest(RTM_ADD, rt, rt->rt_nhop, info);
- /*
- * actually return a resultant rtentry
- */
- if (ret_nrt)
- *ret_nrt = rt;
- rnh->rnh_gen++; /* Routing table updated */
RT_UNLOCK(rt);
return (0);
}
+/*
+ * Removes route defined by @info from the kernel table specified by @fibnum and
+ * sa_family in @info->rti_info[RTAX_DST].
+ *
+ * Returns 0 on success and fills @rc with operation metadata.
+ */
+int
+rib_del_route(uint32_t fibnum, struct rt_addrinfo *info, struct rib_cmd_info *rc)
+{
+ struct rib_head *rnh;
+
+ NET_EPOCH_ASSERT();
+
+ rnh = get_rnh(fibnum, info);
+ if (rnh == NULL)
+ return (EAFNOSUPPORT);
+
+ bzero(rc, sizeof(struct rib_cmd_info));
+ rc->rc_cmd = RTM_DELETE;
+
+ return (del_route(rnh, info, rc));
+}
+
/*
* Conditionally unlinks rtentry matching data inside @info from @rnh.
* Returns unlinked, locked and referenced @rtentry on success,
@@ -295,7 +386,7 @@
int
del_route(struct rib_head *rnh, struct rt_addrinfo *info,
- struct rtentry **ret_nrt)
+ struct rib_cmd_info *rc)
{
struct sockaddr *dst, *netmask;
struct sockaddr_storage mdst;
@@ -314,6 +405,12 @@
RIB_WLOCK(rnh);
rt = rt_unlinkrte(rnh, info, &error);
+ if (rt != NULL) {
+ /* Finalize notification */
+ rnh->rnh_gen++;
+ rc->rc_rt = rt;
+ rc->rc_nh_old = rt->rt_nhop;
+ }
RIB_WUNLOCK(rnh);
if (error != 0)
return (error);
@@ -324,17 +421,32 @@
* If the caller wants it, then it can have it,
* the entry will be deleted after the end of the current epoch.
*/
- if (ret_nrt)
- *ret_nrt = rt;
-
rtfree(rt);
return (0);
}
+int
+rib_change_route(uint32_t fibnum, struct rt_addrinfo *info,
+ struct rib_cmd_info *rc)
+{
+ struct rib_head *rnh;
+
+ NET_EPOCH_ASSERT();
+
+ rnh = get_rnh(fibnum, info);
+ if (rnh == NULL)
+ return (EAFNOSUPPORT);
+
+ bzero(rc, sizeof(struct rib_cmd_info));
+ rc->rc_cmd = RTM_CHANGE;
+
+ return (change_route(rnh, info, rc));
+}
+
static int
change_route_one(struct rib_head *rnh, struct rt_addrinfo *info,
- struct rtentry **ret_nrt)
+ struct rib_cmd_info *rc)
{
RIB_RLOCK_TRACKER;
struct rtentry *rt = NULL;
@@ -434,8 +546,10 @@
if ((nh_orig->nh_ifa != nh->nh_ifa) && nh_orig->nh_ifa->ifa_rtrequest)
nh_orig->nh_ifa->ifa_rtrequest(RTM_DELETE, rt, nh_orig, info);
- if (ret_nrt != NULL)
- *ret_nrt = rt;
+ /* Finalize notification */
+ rc->rc_rt = rt;
+ rc->rc_nh_old = nh_orig;
+ rc->rc_nh_new = rt->rt_nhop;
RT_UNLOCK(rt);
@@ -451,7 +565,7 @@
int
change_route(struct rib_head *rnh, struct rt_addrinfo *info,
- struct rtentry **ret_nrt)
+ struct rib_cmd_info *rc)
{
int error;
@@ -468,7 +582,7 @@
* multiple times before failing.
*/
for (int i = 0; i < RIB_MAX_RETRIES; i++) {
- error = change_route_one(rnh, info, ret_nrt);
+ error = change_route_one(rnh, info, rc);
if (error != EAGAIN)
break;
}
Index: sys/net/route/route_ddb.c
===================================================================
--- sys/net/route/route_ddb.c
+++ sys/net/route/route_ddb.c
@@ -50,6 +50,7 @@
#include <net/if_dl.h>
#include <net/route.h>
#include <net/route/nhop.h>
+#include <net/route/route_ctl.h>
#include <net/route/route_var.h>
/*
Index: sys/net/route/route_helpers.c
===================================================================
--- sys/net/route/route_helpers.c
+++ sys/net/route/route_helpers.c
@@ -50,6 +50,7 @@
#include <net/if_var.h>
#include <net/if_dl.h>
#include <net/route.h>
+#include <net/route/route_ctl.h>
#include <net/route/route_var.h>
#include <net/route/nhop_utils.h>
#include <net/route/nhop.h>
Index: sys/net/route/route_temporal.c
===================================================================
--- sys/net/route/route_temporal.c
+++ sys/net/route/route_temporal.c
@@ -38,11 +38,13 @@
#include <sys/socket.h>
#include <sys/kernel.h>
#include <sys/lock.h>
+#include <sys/ck.h>
#include <sys/rmlock.h>
#include <sys/callout.h>
#include <net/if.h>
#include <net/route.h>
+#include <net/route/route_ctl.h>
#include <net/route/route_var.h>
#include <net/vnet.h>
Index: sys/net/route/route_var.h
===================================================================
--- sys/net/route/route_var.h
+++ sys/net/route/route_var.h
@@ -35,6 +35,7 @@
#ifndef RNF_NORMAL
#include <net/radix.h>
#endif
+#include <sys/ck.h>
#include <sys/epoch.h>
#include <netinet/in.h> /* struct sockaddr_in */
#include <sys/counter.h>
@@ -110,12 +111,13 @@
struct radix_node *rt_mpath_unlink(struct rib_head *rnh,
struct rt_addrinfo *info, struct rtentry *rto, int *perror);
#endif
+struct rib_cmd_info;
int add_route(struct rib_head *rnh, struct rt_addrinfo *info,
- struct rtentry **ret_nrt);
+ struct rib_cmd_info *rc);
int del_route(struct rib_head *rnh, struct rt_addrinfo *info,
- struct rtentry **ret_nrt);
+ struct rib_cmd_info *rc);
int change_route(struct rib_head *, struct rt_addrinfo *,
- struct rtentry **);
+ struct rib_cmd_info *rc);
VNET_PCPUSTAT_DECLARE(struct rtstat, rtstat);
#define RTSTAT_ADD(name, val) \
Index: sys/netinet/in_rmx.c
===================================================================
--- sys/netinet/in_rmx.c
+++ sys/netinet/in_rmx.c
@@ -42,6 +42,7 @@
#include <net/if.h>
#include <net/if_var.h>
#include <net/route.h>
+#include <net/route/route_ctl.h>
#include <net/route/route_var.h>
#include <net/route/nhop.h>
#include <net/route/shared.h>
Index: sys/netinet/ip_icmp.c
===================================================================
--- sys/netinet/ip_icmp.c
+++ sys/netinet/ip_icmp.c
@@ -52,6 +52,7 @@
#include <net/if_var.h>
#include <net/if_types.h>
#include <net/route.h>
+#include <net/route/route_ctl.h>
#include <net/route/nhop.h>
#include <net/vnet.h>
Index: sys/netinet6/icmp6.c
===================================================================
--- sys/netinet6/icmp6.c
+++ sys/netinet6/icmp6.c
@@ -93,6 +93,7 @@
#include <net/if_llatbl.h>
#include <net/if_types.h>
#include <net/route.h>
+#include <net/route/route_ctl.h>
#include <net/route/nhop.h>
#include <net/vnet.h>
Index: sys/netinet6/in6_rmx.c
===================================================================
--- sys/netinet6/in6_rmx.c
+++ sys/netinet6/in6_rmx.c
@@ -81,6 +81,7 @@
#include <net/if.h>
#include <net/if_var.h>
#include <net/route.h>
+#include <net/route/route_ctl.h>
#include <net/route/route_var.h>
#include <net/route/nhop.h>
#include <net/route/shared.h>
Index: sys/netinet6/nd6_rtr.c
===================================================================
--- sys/netinet6/nd6_rtr.c
+++ sys/netinet6/nd6_rtr.c
@@ -60,6 +60,7 @@
#include <net/if_dl.h>
#include <net/route.h>
#include <net/route/nhop.h>
+#include <net/route/route_ctl.h>
#include <net/route/route_var.h>
#include <net/radix.h>
#include <net/vnet.h>

File Metadata

Mime Type
text/plain
Expires
Fri, May 22, 9:41 AM (4 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33418167
Default Alt Text
D25067.id72444.diff (15 KB)

Event Timeline