Page MenuHomeFreeBSD

D25192.id72838.diff
No OneTemporary

D25192.id72838.diff

Index: sys/net/route/route_ctl.h
===================================================================
--- sys/net/route/route_ctl.h
+++ sys/net/route/route_ctl.h
@@ -51,6 +51,8 @@
struct rib_cmd_info *rc);
int rib_change_route(uint32_t fibnum, struct rt_addrinfo *info,
struct rib_cmd_info *rc);
+int rib_action(uint32_t fibnum, int action, 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,
Index: sys/net/route/route_ctl.c
===================================================================
--- sys/net/route/route_ctl.c
+++ sys/net/route/route_ctl.c
@@ -610,6 +610,37 @@
return (error);
}
+/*
+ * Performs modification of routing table specificed by @action.
+ * Table is specified by @fibnum and sa_family in @info->rti_info[RTAX_DST].
+ * Needs to be run in network epoch.
+ *
+ * Returns 0 on success and fills in @rc with action result.
+ */
+int
+rib_action(uint32_t fibnum, int action, struct rt_addrinfo *info,
+ struct rib_cmd_info *rc)
+{
+ int error;
+
+ switch (action) {
+ case RTM_ADD:
+ error = rib_add_route(fibnum, info, rc);
+ break;
+ case RTM_DELETE:
+ error = rib_del_route(fibnum, info, rc);
+ break;
+ case RTM_CHANGE:
+ error = rib_change_route(fibnum, info, rc);
+ break;
+ default:
+ error = ENOTSUP;
+ }
+
+ return (error);
+}
+
+
static void
rt_notifydelete(struct rtentry *rt, struct rt_addrinfo *info)
{
Index: sys/net/rtsock.c
===================================================================
--- sys/net/rtsock.c
+++ sys/net/rtsock.c
@@ -62,6 +62,7 @@
#include <net/netisr.h>
#include <net/raw_cb.h>
#include <net/route.h>
+#include <net/route/route_ctl.h>
#include <net/route/route_var.h>
#ifdef RADIX_MPATH
#include <net/radix_mpath.h>
@@ -181,10 +182,10 @@
static void rt_getmetrics(const struct rtentry *rt, struct rt_metrics *out);
static void rt_dispatch(struct mbuf *, sa_family_t);
static int handle_rtm_get(struct rt_addrinfo *info, u_int fibnum,
- struct rt_msghdr *rtm, struct rtentry **ret_nrt);
+ struct rt_msghdr *rtm, struct rib_cmd_info *rc);
static int update_rtm_from_rte(struct rt_addrinfo *info,
struct rt_msghdr **prtm, int alloc_len,
- struct rtentry *rt);
+ struct rtentry *rt, struct nhop_object *nh);
static void send_rtm_reply(struct socket *so, struct rt_msghdr *rtm,
struct mbuf *m, sa_family_t saf, u_int fibnum,
int rtm_errno);
@@ -656,10 +657,9 @@
*/
static int
handle_rtm_get(struct rt_addrinfo *info, u_int fibnum,
- struct rt_msghdr *rtm, struct rtentry **ret_nrt)
+ struct rt_msghdr *rtm, struct rib_cmd_info *rc)
{
RIB_RLOCK_TRACKER;
- struct rtentry *rt;
struct rib_head *rnh;
sa_family_t saf;
@@ -677,14 +677,14 @@
* address lookup (no mask).
* 'route -n get addr'
*/
- rt = (struct rtentry *) rnh->rnh_matchaddr(
+ rc->rc_rt = (struct rtentry *) rnh->rnh_matchaddr(
info->rti_info[RTAX_DST], &rnh->head);
} else
- rt = (struct rtentry *) rnh->rnh_lookup(
+ rc->rc_rt = (struct rtentry *) rnh->rnh_lookup(
info->rti_info[RTAX_DST],
info->rti_info[RTAX_NETMASK], &rnh->head);
- if (rt == NULL) {
+ if (rc->rc_rt == NULL) {
RIB_RUNLOCK(rnh);
return (ESRCH);
}
@@ -695,8 +695,8 @@
* (no need to call rt_mpath_matchgate if gate == NULL)
*/
if (rt_mpath_capable(rnh) && info->rti_info[RTAX_GATEWAY]) {
- rt = rt_mpath_matchgate(rt, info->rti_info[RTAX_GATEWAY]);
- if (!rt) {
+ rc->rc_rt = rt_mpath_matchgate(rc->rt, info->rti_info[RTAX_GATEWAY]);
+ if (rc->rc_rt == NULL) {
RIB_RUNLOCK(rnh);
return (ESRCH);
}
@@ -713,16 +713,13 @@
struct sockaddr laddr;
struct nhop_object *nh;
- nh = rt->rt_nhop;
+ nh = rc->rc_rt->rt_nhop;
if (nh->nh_ifp != NULL &&
nh->nh_ifp->if_type == IFT_PROPVIRTUAL) {
- struct epoch_tracker et;
struct ifaddr *ifa;
- NET_EPOCH_ENTER(et);
ifa = ifa_ifwithnet(info->rti_info[RTAX_DST], 1,
RT_ALL_FIBS);
- NET_EPOCH_EXIT(et);
if (ifa != NULL)
rt_maskedcopy(ifa->ifa_addr,
&laddr,
@@ -734,24 +731,21 @@
/*
* refactor rt and no lock operation necessary
*/
- rt = (struct rtentry *)rnh->rnh_matchaddr(&laddr,
+ rc->rc_rt = (struct rtentry *)rnh->rnh_matchaddr(&laddr,
&rnh->head);
- if (rt == NULL) {
+ if (rc->rc_rt == NULL) {
RIB_RUNLOCK(rnh);
return (ESRCH);
}
}
- RT_LOCK(rt);
+ rc->rc_nh_new = rc->rc_rt->rt_nhop;
RIB_RUNLOCK(rnh);
- *ret_nrt = rt;
-
return (0);
}
/*
* Update sockaddrs, flags, etc in @prtm based on @rt data.
- * Assumes @rt is locked.
* rtm can be reallocated.
*
* Returns 0 on success, along with pointer to (potentially reallocated)
@@ -760,21 +754,17 @@
*/
static int
update_rtm_from_rte(struct rt_addrinfo *info, struct rt_msghdr **prtm,
- int alloc_len, struct rtentry *rt)
+ int alloc_len, struct rtentry *rt, struct nhop_object *nh)
{
struct sockaddr_storage netmask_ss;
struct walkarg w;
union sockaddr_union saun;
struct rt_msghdr *rtm, *orig_rtm = NULL;
- struct nhop_object *nh;
struct ifnet *ifp;
int error, len;
- RT_LOCK_ASSERT(rt);
-
rtm = *prtm;
- nh = rt->rt_nhop;
info->rti_info[RTAX_DST] = rt_key(rt);
info->rti_info[RTAX_GATEWAY] = &nh->gw_sa;
info->rti_info[RTAX_NETMASK] = rtsock_fix_netmask(rt_key(rt),
@@ -854,6 +844,8 @@
int alloc_len = 0, len, error = 0, fibnum;
sa_family_t saf = AF_UNSPEC;
struct walkarg w;
+ struct rib_cmd_info rc;
+ struct nhop_object *nh;
fibnum = so->so_fibnum;
@@ -881,6 +873,7 @@
m_copydata(m, 0, len, (caddr_t)rtm);
bzero(&info, sizeof(info));
bzero(&w, sizeof(w));
+ nh = NULL;
if (rtm->rtm_version != RTM_VERSION) {
/* Do not touch message since format is unknown */
@@ -920,25 +913,21 @@
if (info.rti_info[RTAX_GATEWAY] == NULL)
senderr(EINVAL);
}
- saved_nrt = NULL;
- error = rtrequest1_fib(rtm->rtm_type, &info, &saved_nrt,
- fibnum);
- if (error == 0 && saved_nrt != NULL) {
+ error = rib_action(fibnum, rtm->rtm_type, &info, &rc);
+ if (error == 0) {
#ifdef INET6
rti_need_deembed = (V_deembed_scopeid) ? 1 : 0;
#endif
- RT_LOCK(saved_nrt);
- rtm->rtm_index = saved_nrt->rt_nhop->nh_ifp->if_index;
- RT_UNLOCK(saved_nrt);
+ rtm->rtm_index = rc.rc_nh_new->nh_ifp->if_index;
+ nh = rc.rc_nh_new;
}
break;
case RTM_DELETE:
saved_nrt = NULL;
- error = rtrequest1_fib(RTM_DELETE, &info, &saved_nrt, fibnum);
+ error = rib_action(fibnum, RTM_DELETE, &info, &rc);
if (error == 0) {
- RT_LOCK(saved_nrt);
- rt = saved_nrt;
+ nh = rc.rc_nh_old;
goto report;
}
#ifdef INET6
@@ -948,17 +937,17 @@
break;
case RTM_GET:
- error = handle_rtm_get(&info, fibnum, rtm, &rt);
+ error = handle_rtm_get(&info, fibnum, rtm, &rc);
if (error != 0)
senderr(error);
+ nh = rc.rc_nh_new;
report:
- RT_LOCK_ASSERT(rt);
- if (!can_export_rte(curthread->td_ucred, rt)) {
- RT_UNLOCK(rt);
+ if (!can_export_rte(curthread->td_ucred, rc.rc_rt)) {
senderr(ESRCH);
}
- error = update_rtm_from_rte(&info, &rtm, alloc_len, rt);
+
+ error = update_rtm_from_rte(&info, &rtm, alloc_len, rc.rc_rt, nh);
/*
* Note that some sockaddr pointers may have changed to
* point to memory outsize @rtm. Some may be pointing
@@ -974,7 +963,6 @@
#ifdef INET6
rti_need_deembed = 0;
#endif
- RT_UNLOCK(rt);
if (error != 0)
senderr(error);
break;

File Metadata

Mime Type
text/plain
Expires
Sun, Jan 19, 5:39 PM (14 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15952636
Default Alt Text
D25192.id72838.diff (7 KB)

Event Timeline