Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F105719981
D25067.id72546.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
19 KB
Referenced Files
None
Subscribers
None
D25067.id72546.diff
View Options
Index: head/sys/net/if_llatbl.c
===================================================================
--- head/sys/net/if_llatbl.c
+++ head/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: head/sys/net/route.h
===================================================================
--- head/sys/net/route.h
+++ head/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: head/sys/net/route.c
===================================================================
--- head/sys/net/route.c
+++ head/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>
@@ -346,6 +347,9 @@
nhops_init_rib(rh);
+ /* Init subscription system */
+ CK_STAILQ_INIT(&rh->rnh_subscribers);
+
/* Finally, set base callbacks */
rh->rnh_addaddr = rn_addroute;
rh->rnh_deladdr = rn_delete;
@@ -1148,6 +1152,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 +1185,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,14 +1198,17 @@
*/
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: head/sys/net/route/nhop_ctl.c
===================================================================
--- head/sys/net/route/nhop_ctl.c
+++ head/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: head/sys/net/route/route_ctl.h
===================================================================
--- head/sys/net/route/route_ctl.h
+++ head/sys/net/route/route_ctl.h
@@ -0,0 +1,90 @@
+/*-
+ * 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);
+
+enum rib_subscription_type {
+ RIB_NOTIFY_IMMEDIATE,
+ RIB_NOTIFY_DELAYED
+};
+
+typedef void rib_subscription_cb_t(struct rib_head *rnh, struct rib_cmd_info *rc,
+ void *arg);
+
+struct rib_subscription {
+ CK_STAILQ_ENTRY(rib_subscription) next;
+ rib_subscription_cb_t *func;
+ void *arg;
+ enum rib_subscription_type type;
+};
+
+struct rib_subscription *rib_subscribe(uint32_t fibnum, int family,
+ rib_subscription_cb_t *f, void *arg, enum rib_subscription_type type,
+ int waitok);
+int rib_unsibscribe(uint32_t fibnum, int family, struct rib_subscription *rs);
+
+
+#endif
+
Index: head/sys/net/route/route_ctl.c
===================================================================
--- head/sys/net/route/route_ctl.c
+++ head/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>
@@ -67,11 +68,61 @@
* All functions assumes they are called in net epoch.
*/
+static void rib_notify(struct rib_head *rnh, enum rib_subscription_type type,
+ struct rib_cmd_info *rc);
+
static void rt_notifydelete(struct rtentry *rt, struct rt_addrinfo *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), ("rib_add_route: bad fibnum"));
+
+ 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].
+ *
+ * Returns 0 on success and fills in operation metadata into @rc.
+ */
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 +197,7 @@
rt->rt_weight = 1;
rt_setmetrics(info, rt);
+ rt_old = NULL;
RIB_WLOCK(rnh);
RT_LOCK(rt);
@@ -163,12 +215,20 @@
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;
+
+ rib_notify(rnh, RIB_NOTIFY_IMMEDIATE, rc);
+ } else if ((info->rti_flags & RTF_PINNED) != 0) {
+
/*
* Force removal and re-try addition
* TODO: better multipath&pinned support
@@ -180,9 +240,26 @@
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);
+ rc->rc_nh_old = rt_old->rt_nhop;
+ rc->rc_nh_new = nh;
+ } else {
+ rc->rc_cmd = RTM_DELETE;
+ rc->rc_rt = RNTORT(rn);
+ rc->rc_nh_old = rt_old->rt_nhop;
+ rc->rc_nh_new = nh;
+ }
+ rib_notify(rnh, RIB_NOTIFY_IMMEDIATE, rc);
+ }
}
RIB_WUNLOCK(rnh);
@@ -208,12 +285,6 @@
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);
@@ -221,6 +292,29 @@
/*
+ * 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 in operation metadata into @rc.
+ */
+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,
* Returns NULL and sets @perror to:
@@ -295,7 +389,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 +408,13 @@
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_notify(rnh, RIB_NOTIFY_IMMEDIATE, rc);
+ }
RIB_WUNLOCK(rnh);
if (error != 0)
return (error);
@@ -324,17 +425,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,14 +550,18 @@
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);
/* Update generation id to reflect rtable change */
rnh->rnh_gen++;
+ rib_notify(rnh, RIB_NOTIFY_IMMEDIATE, rc);
+
RIB_WUNLOCK(rnh);
nhop_free(nh_orig);
@@ -451,7 +571,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 +588,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;
}
@@ -581,4 +701,62 @@
}
}
+static void
+rib_notify(struct rib_head *rnh, enum rib_subscription_type type,
+ struct rib_cmd_info *rc)
+{
+ struct rib_subscription *rs;
+
+ CK_STAILQ_FOREACH(rs, &rnh->rnh_subscribers, next) {
+ if (rs->type == type)
+ rs->func(rnh, rc, rs->arg);
+ }
+}
+
+struct rib_subscription *
+rib_subscribe(uint32_t fibnum, int family, rib_subscription_cb_t *f, void *arg,
+ enum rib_subscription_type type, int waitok)
+{
+ struct rib_head *rnh;
+ struct rib_subscription *rs;
+ int flags = M_ZERO | (waitok ? M_WAITOK : 0);
+
+ NET_EPOCH_ASSERT();
+ KASSERT((fibnum < rt_numfibs), ("%s: bad fibnum", __func__));
+ rnh = rt_tables_get_rnh(fibnum, family);
+
+ rs = malloc(sizeof(struct rib_subscription), M_RTABLE, flags);
+ if (rs == NULL)
+ return (NULL);
+
+ rs->func = f;
+ rs->arg = arg;
+ rs->type = type;
+
+ RIB_WLOCK(rnh);
+ CK_STAILQ_INSERT_TAIL(&rnh->rnh_subscribers, rs, next);
+ RIB_WUNLOCK(rnh);
+
+ return (rs);
+}
+
+int
+rib_unsibscribe(uint32_t fibnum, int family, struct rib_subscription *rs)
+{
+ struct rib_head *rnh;
+
+ NET_EPOCH_ASSERT();
+ KASSERT((fibnum < rt_numfibs), ("%s: bad fibnum", __func__));
+ rnh = rt_tables_get_rnh(fibnum, family);
+
+ if (rnh == NULL)
+ return (ENOENT);
+
+ RIB_WLOCK(rnh);
+ CK_STAILQ_REMOVE(&rnh->rnh_subscribers, rs, rib_subscription, next);
+ RIB_WUNLOCK(rnh);
+
+ free(rs, M_RTABLE);
+ return (0);
+}
Index: head/sys/net/route/route_ddb.c
===================================================================
--- head/sys/net/route/route_ddb.c
+++ head/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: head/sys/net/route/route_helpers.c
===================================================================
--- head/sys/net/route/route_helpers.c
+++ head/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: head/sys/net/route/route_temporal.c
===================================================================
--- head/sys/net/route/route_temporal.c
+++ head/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: head/sys/net/route/route_var.h
===================================================================
--- head/sys/net/route/route_var.h
+++ head/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>
@@ -63,6 +64,7 @@
struct callout expire_callout; /* Callout for expiring dynamic routes */
time_t next_expire; /* Next expire run ts */
struct nh_control *nh_control; /* nexthop subsystem data */
+ CK_STAILQ_HEAD(, rib_subscription) rnh_subscribers;/* notification subscribers */
};
#define RIB_RLOCK_TRACKER struct rm_priotracker _rib_tracker
@@ -110,12 +112,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: head/sys/netinet/in_rmx.c
===================================================================
--- head/sys/netinet/in_rmx.c
+++ head/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: head/sys/netinet/ip_icmp.c
===================================================================
--- head/sys/netinet/ip_icmp.c
+++ head/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: head/sys/netinet6/icmp6.c
===================================================================
--- head/sys/netinet6/icmp6.c
+++ head/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: head/sys/netinet6/in6_rmx.c
===================================================================
--- head/sys/netinet6/in6_rmx.c
+++ head/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: head/sys/netinet6/nd6_rtr.c
===================================================================
--- head/sys/netinet6/nd6_rtr.c
+++ head/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
Details
Attached
Mime Type
text/plain
Expires
Fri, Dec 20, 4:42 PM (17 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15531747
Default Alt Text
D25067.id72546.diff (19 KB)
Attached To
Mode
D25067: add new rib manipulation functions.
Attached
Detach File
Event Timeline
Log In to Comment