/*
- * Copyright (c) 2000-2013 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2017 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
#include <sys/protosw.h>
#include <sys/syslog.h>
#include <sys/mcache.h>
-#include <kern/lock.h>
+#include <kern/locks.h>
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <netinet/in_arp.h>
+#include <netinet/ip.h>
+#include <netinet/ip6.h>
+#include <netinet6/nd6.h>
extern int tvtohz(struct timeval *);
-static int in_rtqtimo_run; /* in_rtqtimo is scheduled to run */
+static int in_rtqtimo_run; /* in_rtqtimo is scheduled to run */
static void in_rtqtimo(void *);
static void in_sched_rtqtimo(struct timeval *);
static int in_ifadownkill(struct radix_node *, void *);
-#define RTPRF_OURS RTF_PROTO3 /* set on routes we manage */
-
/*
* Do what we need to do when inserting a route.
*/
uint32_t flags = rt->rt_flags;
boolean_t verbose = (rt_verbose > 1);
- lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
+ LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
RT_LOCK_ASSERT_HELD(rt);
- if (verbose)
- rt_str(rt, dbuf, sizeof (dbuf), gbuf, sizeof (gbuf));
+ if (verbose) {
+ rt_str(rt, dbuf, sizeof(dbuf), gbuf, sizeof(gbuf));
+ }
/*
* For IP, all unicast non-host routes are automatically cloning.
*/
- if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr)))
+ if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
rt->rt_flags |= RTF_MULTICAST;
+ }
- if (!(rt->rt_flags & (RTF_HOST | RTF_CLONING | RTF_MULTICAST)))
+ if (!(rt->rt_flags & (RTF_HOST | RTF_CLONING | RTF_MULTICAST))) {
rt->rt_flags |= RTF_PRCLONING;
+ }
/*
* A little bit of help for both IP output and input:
RT_CONVERT_LOCK(rt);
IFA_LOCK_SPIN(rt->rt_ifa);
if (satosin(rt->rt_ifa->ifa_addr)->sin_addr.s_addr ==
- sin->sin_addr.s_addr)
+ sin->sin_addr.s_addr) {
rt->rt_flags |= RTF_LOCAL;
+ }
IFA_UNLOCK(rt->rt_ifa);
}
}
if (!rt->rt_rmx.rmx_mtu && !(rt->rt_rmx.rmx_locks & RTV_MTU) &&
- rt->rt_ifp)
+ rt->rt_ifp) {
rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu;
+ if (INTF_ADJUST_MTU_FOR_CLAT46(rt->rt_ifp)) {
+ rt->rt_rmx.rmx_mtu = IN6_LINKMTU(rt->rt_ifp);
+ /* Further adjust the size for CLAT46 expansion */
+ rt->rt_rmx.rmx_mtu -= CLAT46_HDR_EXPANSION_OVERHD;
+ }
+ }
ret = rn_addroute(v_arg, n_arg, head, treenodes);
if (ret == NULL && (rt->rt_flags & RTF_HOST)) {
char dbufc[MAX_IPv4_STR_LEN];
RT_LOCK(rt2);
- if (verbose)
- rt_str(rt2, dbufc, sizeof (dbufc), NULL, 0);
+ if (verbose) {
+ rt_str(rt2, dbufc, sizeof(dbufc), NULL, 0);
+ }
if ((rt2->rt_flags & RTF_LLINFO) &&
(rt2->rt_flags & RTF_HOST) &&
}
}
- if (!verbose)
+ if (!verbose) {
goto done;
+ }
if (ret != NULL) {
if (flags != rt->rt_flags) {
rt->rt_flags, RTF_BITS);
}
done:
- return (ret);
+ return ret;
}
static struct radix_node *
{
struct radix_node *rn;
- lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
+ LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
rn = rn_delete(v_arg, netmask_arg, head);
if (rt_verbose > 1 && rn != NULL) {
struct rtentry *rt = (struct rtentry *)rn;
RT_LOCK(rt);
- rt_str(rt, dbuf, sizeof (dbuf), gbuf, sizeof (gbuf));
+ rt_str(rt, dbuf, sizeof(dbuf), gbuf, sizeof(gbuf));
log(LOG_DEBUG, "%s: route to %s->%s->%s deleted, "
"flags=%b\n", __func__, dbuf, gbuf, (rt->rt_ifp != NULL) ?
rt->rt_ifp->if_xname : "", rt->rt_flags, RTF_BITS);
RT_UNLOCK(rt);
}
- return (rn);
+ return rn;
}
/*
if (rt_verbose > 2) {
char dbuf[MAX_IPv4_STR_LEN], gbuf[MAX_IPv4_STR_LEN];
- rt_str(rt, dbuf, sizeof (dbuf), gbuf, sizeof (gbuf));
+ rt_str(rt, dbuf, sizeof(dbuf), gbuf, sizeof(gbuf));
log(LOG_DEBUG, "%s: route to %s->%s->%s validated, "
"flags=%b\n", __func__, dbuf, gbuf,
(rt->rt_ifp != NULL) ? rt->rt_ifp->if_xname : "",
rt_setexpire(rt, 0);
}
}
- return (rn);
+ return rn;
}
/*
static struct radix_node *
in_matroute(void *v_arg, struct radix_node_head *head)
{
- return (in_matroute_args(v_arg, head, NULL, NULL));
+ return in_matroute_args(v_arg, head, NULL, NULL);
}
/*
in_validate(rn);
RT_UNLOCK((struct rtentry *)rn);
}
- return (rn);
+ return rn;
}
/* one hour is ``really old'' */
-static uint32_t rtq_reallyold = 60*60;
+static uint32_t rtq_reallyold = 60 * 60;
SYSCTL_UINT(_net_inet_ip, IPCTL_RTEXPIRE, rtexpire,
- CTLFLAG_RW | CTLFLAG_LOCKED, &rtq_reallyold, 0,
- "Default expiration time on dynamically learned routes");
+ CTLFLAG_RW | CTLFLAG_LOCKED, &rtq_reallyold, 0,
+ "Default expiration time on dynamically learned routes");
/* never automatically crank down to less */
static uint32_t rtq_minreallyold = 10;
SYSCTL_UINT(_net_inet_ip, IPCTL_RTMINEXPIRE, rtminexpire,
- CTLFLAG_RW | CTLFLAG_LOCKED, &rtq_minreallyold, 0,
- "Minimum time to attempt to hold onto dynamically learned routes");
+ CTLFLAG_RW | CTLFLAG_LOCKED, &rtq_minreallyold, 0,
+ "Minimum time to attempt to hold onto dynamically learned routes");
/* 128 cached routes is ``too many'' */
static uint32_t rtq_toomany = 128;
SYSCTL_UINT(_net_inet_ip, IPCTL_RTMAXCACHE, rtmaxcache,
- CTLFLAG_RW | CTLFLAG_LOCKED, &rtq_toomany, 0,
- "Upper limit on dynamically learned routes");
+ CTLFLAG_RW | CTLFLAG_LOCKED, &rtq_toomany, 0,
+ "Upper limit on dynamically learned routes");
/*
* On last reference drop, mark the route as belong to us so that it can be
struct rtentry *rt = (struct rtentry *)rn;
boolean_t verbose = (rt_verbose > 1);
- lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
+ LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
RT_LOCK_ASSERT_HELD(rt);
- if (!(rt->rt_flags & RTF_UP))
- return; /* prophylactic measures */
-
- if ((rt->rt_flags & (RTF_LLINFO | RTF_HOST)) != RTF_HOST)
+ if (!(rt->rt_flags & RTF_UP)) {
+ return; /* prophylactic measures */
+ }
+ if ((rt->rt_flags & (RTF_LLINFO | RTF_HOST)) != RTF_HOST) {
return;
+ }
- if (rt->rt_flags & RTPRF_OURS)
+ if (rt->rt_flags & RTPRF_OURS) {
return;
+ }
- if (!(rt->rt_flags & (RTF_WASCLONED | RTF_DYNAMIC)))
+ if (!(rt->rt_flags & (RTF_WASCLONED | RTF_DYNAMIC))) {
return;
+ }
- if (verbose)
- rt_str(rt, dbuf, sizeof (dbuf), gbuf, sizeof (gbuf));
+ if (verbose) {
+ rt_str(rt, dbuf, sizeof(dbuf), gbuf, sizeof(gbuf));
+ }
/*
* Delete the route immediately if RTF_DELCLONE is set or
RT_REMREF_LOCKED(rt);
} else {
RT_LOCK(rt);
- if (!verbose)
- rt_str(rt, dbuf, sizeof (dbuf),
- gbuf, sizeof (gbuf));
+ if (!verbose) {
+ rt_str(rt, dbuf, sizeof(dbuf),
+ gbuf, sizeof(gbuf));
+ }
log(LOG_ERR, "%s: error deleting route to "
"%s->%s->%s, flags=%b, err=%d\n", __func__,
dbuf, gbuf, (rt->rt_ifp != NULL) ?
int err;
timenow = net_uptime();
- lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
+ LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
RT_LOCK(rt);
if (rt->rt_flags & RTPRF_OURS) {
char dbuf[MAX_IPv4_STR_LEN], gbuf[MAX_IPv4_STR_LEN];
- if (verbose)
- rt_str(rt, dbuf, sizeof (dbuf), gbuf, sizeof (gbuf));
+ if (verbose) {
+ rt_str(rt, dbuf, sizeof(dbuf), gbuf, sizeof(gbuf));
+ }
ap->found++;
VERIFY(rt->rt_expire == 0 || rt->rt_rmx.rmx_expire != 0);
rt, rt->rt_refcnt);
/* NOTREACHED */
}
+
if (verbose) {
log(LOG_DEBUG, "%s: deleting route to "
"%s->%s->%s, flags=%b, draining=%d\n",
rt->rt_ifp->if_xname : "", rt->rt_flags,
RTF_BITS, ap->draining);
}
- RT_ADDREF_LOCKED(rt); /* for us to free below */
+ RT_ADDREF_LOCKED(rt); /* for us to free below */
/*
* Delete this route since we're done with it;
* the route may be freed afterwards, so we
rt->rt_gateway, rt_mask(rt), rt->rt_flags, NULL);
if (err != 0) {
RT_LOCK(rt);
- if (!verbose)
- rt_str(rt, dbuf, sizeof (dbuf),
- gbuf, sizeof (gbuf));
+ if (!verbose) {
+ rt_str(rt, dbuf, sizeof(dbuf),
+ gbuf, sizeof(gbuf));
+ }
log(LOG_ERR, "%s: error deleting route to "
"%s->%s->%s, flags=%b, err=%d\n", __func__,
dbuf, gbuf, (rt->rt_ifp != NULL) ?
RT_UNLOCK(rt);
}
- return (0);
+ return 0;
}
-#define RTQ_TIMEOUT 60*10 /* run no less than once every ten minutes */
+#define RTQ_TIMEOUT 60*10 /* run no less than once every ten minutes */
static int rtq_timeout = RTQ_TIMEOUT;
static void
log(LOG_DEBUG, "%s: initial nextstop is T+%u seconds\n",
__func__, rtq_timeout);
}
- bzero(&arg, sizeof (arg));
+ bzero(&arg, sizeof(arg));
arg.rnh = rnh;
arg.nextstop = timenow + rtq_timeout;
rnh->rnh_walktree(rnh, in_rtqkill, &arg);
((timenow - last_adjusted_timeout) >= (uint64_t)rtq_timeout) &&
rtq_reallyold > rtq_minreallyold) {
rtq_reallyold = 2 * rtq_reallyold / 3;
- if (rtq_reallyold < rtq_minreallyold)
+ if (rtq_reallyold < rtq_minreallyold) {
rtq_reallyold = rtq_minreallyold;
+ }
last_adjusted_timeout = timenow;
if (verbose) {
atv.tv_sec = arg.nextstop - timenow;
/* re-arm the timer only if there's work to do */
in_rtqtimo_run = 0;
- if (ours > 0)
+ if (ours > 0) {
in_sched_rtqtimo(&atv);
- else if (verbose)
+ } else if (verbose) {
log(LOG_DEBUG, "%s: not rescheduling timer\n", __func__);
+ }
lck_mtx_unlock(rnh_lock);
}
static void
in_sched_rtqtimo(struct timeval *atv)
{
- lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
+ LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
if (!in_rtqtimo_run) {
struct timeval tv;
struct radix_node_head *rnh;
struct rtqk_arg arg;
- if (rt_verbose > 1)
+ if (rt_verbose > 1) {
log(LOG_DEBUG, "%s: draining routes\n", __func__);
+ }
lck_mtx_lock(rnh_lock);
rnh = rt_tables[AF_INET];
VERIFY(rnh != NULL);
- bzero(&arg, sizeof (arg));
+ bzero(&arg, sizeof(arg));
arg.rnh = rnh;
arg.draining = 1;
rnh->rnh_walktree(rnh, in_rtqkill, &arg);
/* If called from route_init(), make sure it is exactly once */
VERIFY(head != (void **)&rt_tables[AF_INET] || *head == NULL);
- if (!rn_inithead(head, off))
- return (0);
+ if (!rn_inithead(head, off)) {
+ return 0;
+ }
/*
* We can get here from nfs_subs.c as well, in which case this
* this also takes care of the case when we're called more than
* once from anywhere but route_init().
*/
- if (head != (void **)&rt_tables[AF_INET])
- return (1); /* only do this for the real routing table */
-
+ if (head != (void **)&rt_tables[AF_INET]) {
+ return 1; /* only do this for the real routing table */
+ }
rnh = *head;
rnh->rnh_addaddr = in_addroute;
rnh->rnh_deladdr = in_deleteroute;
rnh->rnh_matchaddr = in_matroute;
rnh->rnh_matchaddr_args = in_matroute_args;
rnh->rnh_close = in_clsroute;
- return (1);
+ return 1;
}
/*
boolean_t verbose = (rt_verbose != 0);
int err;
- lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
+ LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
RT_LOCK(rt);
if (rt->rt_ifa == ap->ifa &&
(ap->del || !(rt->rt_flags & RTF_STATIC))) {
- rt_str(rt, dbuf, sizeof (dbuf), gbuf, sizeof (gbuf));
+ rt_str(rt, dbuf, sizeof(dbuf), gbuf, sizeof(gbuf));
if (verbose) {
log(LOG_DEBUG, "%s: deleting route to %s->%s->%s, "
"flags=%b\n", __func__, dbuf, gbuf,
(rt->rt_ifp != NULL) ? rt->rt_ifp->if_xname : "",
rt->rt_flags, RTF_BITS);
}
- RT_ADDREF_LOCKED(rt); /* for us to free below */
+ RT_ADDREF_LOCKED(rt); /* for us to free below */
/*
* We need to disable the automatic prune that happens
* in this case in rtrequest() because it will blow
rt->rt_gateway, rt_mask(rt), rt->rt_flags, NULL);
if (err != 0) {
RT_LOCK(rt);
- if (!verbose)
- rt_str(rt, dbuf, sizeof (dbuf),
- gbuf, sizeof (gbuf));
+ if (!verbose) {
+ rt_str(rt, dbuf, sizeof(dbuf),
+ gbuf, sizeof(gbuf));
+ }
log(LOG_ERR, "%s: error deleting route to "
"%s->%s->%s, flags=%b, err=%d\n", __func__,
dbuf, gbuf, (rt->rt_ifp != NULL) ?
} else {
RT_UNLOCK(rt);
}
- return (0);
+ return 0;
}
int
struct in_ifadown_arg arg;
struct radix_node_head *rnh;
- lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
+ LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
/*
* Holding rnh_lock here prevents the possibility of
* ifa from changing (e.g. in_ifinit), so it is safe
* to access its ifa_addr without locking.
*/
- if (ifa->ifa_addr->sa_family != AF_INET)
- return (1);
+ if (ifa->ifa_addr->sa_family != AF_INET) {
+ return 1;
+ }
/* trigger route cache reevaluation */
routegenid_inet_update();
IFA_LOCK_SPIN(ifa);
ifa->ifa_flags &= ~IFA_ROUTE;
IFA_UNLOCK(ifa);
- return (0);
+ return 0;
}