Skip to content

Commit

Permalink
xnu-517.3.7
Browse files Browse the repository at this point in the history
  • Loading branch information
Darwin authored and das committed Jun 4, 2017
1 parent 67cf648 commit 5245d98
Show file tree
Hide file tree
Showing 43 changed files with 386 additions and 179 deletions.
2 changes: 1 addition & 1 deletion bsd/conf/version.minor
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0
2
9 changes: 8 additions & 1 deletion bsd/hfs/hfs_vfsops.c
Original file line number Diff line number Diff line change
Expand Up @@ -1802,8 +1802,15 @@ hfs_sync(mp, waitfor, cred, p)
simple_unlock(&mntvnode_slock);
error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK, p);
if (error) {
if (error == ENOENT)
if (error == ENOENT) {
/*
* If vnode is being reclaimed, yield so
* that it can be removed from our list.
*/
if (UBCISVALID(vp))
(void) tsleep((caddr_t)&lbolt, PINOD, "hfs_sync", 0);
goto loop;
}
simple_lock(&mntvnode_slock);
continue;
}
Expand Down
185 changes: 119 additions & 66 deletions bsd/net/if.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address");
MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address");

int ifqmaxlen = IFQ_MAXLEN;
struct ifnethead ifnet; /* depend on static init XXX */
struct ifnethead ifnet = TAILQ_HEAD_INITIALIZER(ifnet);
struct ifmultihead ifma_lostlist = LIST_HEAD_INITIALIZER(ifma_lostlist);

#if INET6
Expand All @@ -124,10 +124,86 @@ extern void nd6_setmtu __P((struct ifnet *));
* parameters.
*/

int if_index = 0;
int if_index;
struct ifaddr **ifnet_addrs;
struct ifnet **ifindex2ifnet = NULL;
struct ifnet **ifindex2ifnet;

#define INITIAL_IF_INDEXLIM 8

/*
* Function: if_next_index
* Purpose:
* Return the next available interface index.
* Grow the ifnet_addrs[] and ifindex2ifnet[] arrays to accomodate the
* added entry when necessary.
*
* Note:
* ifnet_addrs[] is indexed by (if_index - 1), whereas
* ifindex2ifnet[] is indexed by ifp->if_index. That requires us to
* always allocate one extra element to hold ifindex2ifnet[0], which
* is unused.
*/
static int
if_next_index(void)
{
static int if_indexlim = 0;
static int if_list_growing = 0;
int new_index;

while (if_list_growing) {
/* wait until list is done growing */
(void)tsleep((caddr_t)&ifnet_addrs, PZERO, "if_next_index", 0);
}
new_index = ++if_index;
if (if_index > if_indexlim) {
unsigned n;
int new_if_indexlim;
caddr_t new_ifnet_addrs;
caddr_t new_ifindex2ifnet;
caddr_t old_ifnet_addrs;

/* mark list as growing */
if_list_growing = 1;

old_ifnet_addrs = (caddr_t)ifnet_addrs;
if (ifnet_addrs == NULL) {
new_if_indexlim = INITIAL_IF_INDEXLIM;
} else {
new_if_indexlim = if_indexlim << 1;
}

/* allocate space for the larger arrays */
n = (2 * new_if_indexlim + 1) * sizeof(caddr_t);
new_ifnet_addrs = _MALLOC(n, M_IFADDR, M_WAITOK);
new_ifindex2ifnet = new_ifnet_addrs
+ new_if_indexlim * sizeof(caddr_t);
bzero(new_ifnet_addrs, n);
if (ifnet_addrs != NULL) {
/* copy the existing data */
bcopy((caddr_t)ifnet_addrs, new_ifnet_addrs,
if_indexlim * sizeof(caddr_t));
bcopy((caddr_t)ifindex2ifnet,
new_ifindex2ifnet,
(if_indexlim + 1) * sizeof(caddr_t));
}

/* switch to the new tables and size */
ifnet_addrs = (struct ifaddr **)new_ifnet_addrs;
ifindex2ifnet = (struct ifnet **)new_ifindex2ifnet;
if_indexlim = new_if_indexlim;

/* release the old data */
if (old_ifnet_addrs != NULL) {
_FREE((caddr_t)old_ifnet_addrs, M_IFADDR);
}

/* wake up others that might be blocked */
if_list_growing = 0;
wakeup((caddr_t)&ifnet_addrs);
}
return (new_index);

}

/*
* Attach an interface to the
Expand All @@ -142,21 +218,10 @@ old_if_attach(ifp)
char workbuf[64];
register struct sockaddr_dl *sdl;
register struct ifaddr *ifa;
static int if_indexlim = 8;
static int inited;

if (ifp->if_snd.ifq_maxlen == 0)
ifp->if_snd.ifq_maxlen = ifqmaxlen;

if (!inited) {
TAILQ_INIT(&ifnet);
inited = 1;
}

TAILQ_INSERT_TAIL(&ifnet, ifp, if_link);
/* if the interface is recycled, keep the index */
if (!((ifp->if_eflags & IFEF_REUSE) && ifp->if_index))
ifp->if_index = ++if_index;
/*
* XXX -
* The old code would work if the interface passed a pre-existing
Expand All @@ -168,64 +233,52 @@ old_if_attach(ifp)
TAILQ_INIT(&ifp->if_prefixhead);
LIST_INIT(&ifp->if_multiaddrs);
getmicrotime(&ifp->if_lastchange);
if (ifnet_addrs == 0 || if_index >= if_indexlim) {
unsigned n = (if_indexlim <<= 1) * sizeof(ifa);
struct ifaddr **q = (struct ifaddr **)
_MALLOC(n, M_IFADDR, M_WAITOK);
bzero((caddr_t)q, n);
if (ifnet_addrs) {
bcopy((caddr_t)ifnet_addrs, (caddr_t)q, n/2);
FREE((caddr_t)ifnet_addrs, M_IFADDR);
}
ifnet_addrs = (struct ifaddr **)q;

/* grow ifindex2ifnet */
n = if_indexlim * sizeof(struct ifaddr *);
q = (struct ifaddr **)_MALLOC(n, M_IFADDR, M_WAITOK);
bzero(q, n);
if (ifindex2ifnet) {
bcopy((caddr_t)ifindex2ifnet, q, n/2);
_FREE((caddr_t)ifindex2ifnet, M_IFADDR);
}
ifindex2ifnet = (struct ifnet **)q;
}

ifindex2ifnet[if_index] = ifp;
if ((ifp->if_eflags & IFEF_REUSE) == 0 || ifp->if_index == 0) {
/* allocate a new entry */
ifp->if_index = if_next_index();
ifindex2ifnet[ifp->if_index] = ifp;

/*
* create a Link Level name for this device
*/
namelen = snprintf(workbuf, sizeof(workbuf),
"%s%d", ifp->if_name, ifp->if_unit);
/*
* create a Link Level name for this device
*/
namelen = snprintf(workbuf, sizeof(workbuf),
"%s%d", ifp->if_name, ifp->if_unit);
#define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))
masklen = _offsetof(struct sockaddr_dl, sdl_data[0]) + namelen;
socksize = masklen + ifp->if_addrlen;
masklen = _offsetof(struct sockaddr_dl, sdl_data[0]) + namelen;
socksize = masklen + ifp->if_addrlen;
#define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))
if (socksize < sizeof(*sdl))
socksize = sizeof(*sdl);
socksize = ROUNDUP(socksize);
ifasize = sizeof(*ifa) + 2 * socksize;
ifa = (struct ifaddr *) _MALLOC(ifasize, M_IFADDR, M_WAITOK);
if (ifa) {
bzero((caddr_t)ifa, ifasize);
sdl = (struct sockaddr_dl *)(ifa + 1);
sdl->sdl_len = socksize;
sdl->sdl_family = AF_LINK;
bcopy(workbuf, sdl->sdl_data, namelen);
sdl->sdl_nlen = namelen;
sdl->sdl_index = ifp->if_index;
sdl->sdl_type = ifp->if_type;
ifnet_addrs[if_index - 1] = ifa;
ifa->ifa_ifp = ifp;
ifa->ifa_rtrequest = link_rtrequest;
ifa->ifa_addr = (struct sockaddr *)sdl;
sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
ifa->ifa_netmask = (struct sockaddr *)sdl;
sdl->sdl_len = masklen;
while (namelen != 0)
sdl->sdl_data[--namelen] = 0xff;
if (socksize < sizeof(*sdl))
socksize = sizeof(*sdl);
socksize = ROUNDUP(socksize);
ifasize = sizeof(*ifa) + 2 * socksize;
ifa = (struct ifaddr *) _MALLOC(ifasize, M_IFADDR, M_WAITOK);
if (ifa) {
bzero((caddr_t)ifa, ifasize);
sdl = (struct sockaddr_dl *)(ifa + 1);
sdl->sdl_len = socksize;
sdl->sdl_family = AF_LINK;
bcopy(workbuf, sdl->sdl_data, namelen);
sdl->sdl_nlen = namelen;
sdl->sdl_index = ifp->if_index;
sdl->sdl_type = ifp->if_type;
ifnet_addrs[ifp->if_index - 1] = ifa;
ifa->ifa_ifp = ifp;
ifa->ifa_rtrequest = link_rtrequest;
ifa->ifa_addr = (struct sockaddr *)sdl;
sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
ifa->ifa_netmask = (struct sockaddr *)sdl;
sdl->sdl_len = masklen;
while (namelen != 0)
sdl->sdl_data[--namelen] = 0xff;
}
} else {
ifa = ifnet_addrs[ifp->if_index - 1];
}
if (ifa != NULL) {
TAILQ_INSERT_HEAD(&ifp->if_addrhead, ifa, ifa_link);
}
TAILQ_INSERT_TAIL(&ifnet, ifp, if_link);
}

__private_extern__ int
Expand Down
6 changes: 6 additions & 0 deletions bsd/netinet/in_pcb.c
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,10 @@ in_pcbdetach(inp)
struct inpcbinfo *ipi = inp->inp_pcbinfo;
struct rtentry *rt = inp->inp_route.ro_rt;


if (so->so_pcb == 0) /* we've been called twice, ignore */
return;

#if IPSEC
ipsec4_delete_pcbpolicy(inp);
#endif /*IPSEC*/
Expand Down Expand Up @@ -820,6 +824,8 @@ in_rtchange(inp, errno)
int errno;
{
if (inp->inp_route.ro_rt) {
if (ifa_foraddr(inp->inp_laddr.s_addr) == NULL)
return; /* we can't remove the route now. not sure if still ok to use src */
rtfree(inp->inp_route.ro_rt);
inp->inp_route.ro_rt = 0;
/*
Expand Down
9 changes: 7 additions & 2 deletions bsd/netinet/ip_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,10 +284,15 @@ ip_output(m0, opt, ro, flags, imo)
* cache with IPv6.
*/

if (ro->ro_rt && (ro->ro_rt->generation_id != route_generation) &&
((flags & (IP_ROUTETOIF | IP_FORWARDING)) == 0) && (ip->ip_src.s_addr != INADDR_ANY) &&
(ifa_foraddr(ip->ip_src.s_addr) == NULL)) {
error = EADDRNOTAVAIL;
goto bad;
}
if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
dst->sin_family != AF_INET ||
dst->sin_addr.s_addr != ip->ip_dst.s_addr ||
ro->ro_rt->generation_id != route_generation) ) {
dst->sin_addr.s_addr != ip->ip_dst.s_addr)) {
rtfree(ro->ro_rt);
ro->ro_rt = (struct rtentry *)0;
}
Expand Down
8 changes: 2 additions & 6 deletions bsd/netinet/tcp_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,8 @@ tcp_output(tp)
* come back before the TCP connection times out).
*/

if (tp->t_inpcb->inp_route.ro_rt != NULL &&
(tp->t_inpcb->inp_route.ro_rt->generation_id != route_generation)) {
if ((tp->t_inpcb->inp_route.ro_rt != NULL &&
(tp->t_inpcb->inp_route.ro_rt->generation_id != route_generation)) || (tp->t_inpcb->inp_route.ro_rt == NULL)) {
/* check that the source address is still valid */
if (ifa_foraddr(tp->t_inpcb->inp_laddr.s_addr) == NULL) {
if (tp->t_state >= TCPS_CLOSE_WAIT) {
Expand All @@ -258,10 +258,6 @@ tcp_output(tp)
else
return(0); /* silently ignore and keep data in socket */
}
else { /* Clear the cached route, will be reacquired later */
rtfree(tp->t_inpcb->inp_route.ro_rt);
tp->t_inpcb->inp_route.ro_rt = (struct rtentry *)0;
}
}
}
sendalot = 0;
Expand Down
4 changes: 4 additions & 0 deletions bsd/netinet/tcp_subr.c
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,9 @@ tcp_close(tp)
register struct rtentry *rt;
int dosavessthresh;

if ( inp->inp_ppcb == NULL) /* tcp_close was called previously, bail */
return;

#ifndef __APPLE__
/*
* Make sure that all of our timers are stopped before we
Expand All @@ -712,6 +715,7 @@ tcp_close(tp)
}
}
#endif


KERNEL_DEBUG(DBG_FNC_TCP_CLOSE | DBG_FUNC_START, tp,0,0,0,0);
switch (tp->t_state)
Expand Down
4 changes: 4 additions & 0 deletions bsd/netinet/tcp_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,10 @@ tcp_slowtimo()
#endif
ipnxt = ip->inp_list.le_next;
tp = intotcpcb(ip);
if (tp == NULL) { /* tp already closed, remove from list */
LIST_REMOVE(ip, inp_list);
continue;
}
if (tp->t_timer[TCPT_2MSL] >= N_TIME_WAIT_SLOTS) {
tp->t_timer[TCPT_2MSL] -= N_TIME_WAIT_SLOTS;
tp->t_rcvtime += N_TIME_WAIT_SLOTS;
Expand Down
30 changes: 18 additions & 12 deletions bsd/netinet6/in6_ifattach.c
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,8 @@ in6_tmpaddrtimer_funneled(void *ignored_arg)
#endif
}

extern size_t nd_ifinfo_indexlim;
extern int ip6_use_tempaddr;
void
in6_tmpaddrtimer(ignored_arg)
void *ignored_arg;
Expand All @@ -1048,19 +1050,23 @@ in6_tmpaddrtimer(ignored_arg)
(ip6_temp_preferred_lifetime - ip6_desync_factor -
ip6_temp_regen_advance) * hz);

bzero(nullbuf, sizeof(nullbuf));
for (i = 1; i < if_index + 1; i++) {
ndi = &nd_ifinfo[i];
if (bcmp(ndi->randomid, nullbuf, sizeof(nullbuf)) != 0) {
/*
* We've been generating a random ID on this interface.
* Create a new one.
*/
(void)generate_tmp_ifid(ndi->randomseed0,
ndi->randomseed1,
ndi->randomid);
if (ip6_use_tempaddr) {

bzero(nullbuf, sizeof(nullbuf));
for (i = 1; i < nd_ifinfo_indexlim + 1; i++) {
ndi = &nd_ifinfo[i];
if (ndi->flags != ND6_IFF_PERFORMNUD)
continue;
if (bcmp(ndi->randomid, nullbuf, sizeof(nullbuf)) != 0) {
/*
* We've been generating a random ID on this interface.
* Create a new one.
*/
(void)generate_tmp_ifid(ndi->randomseed0,
ndi->randomseed1,
ndi->randomid);
}
}
}

splx(s);
}
2 changes: 1 addition & 1 deletion bsd/netinet6/nd6.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ int nd6_debug = 0;
static int nd6_inuse, nd6_allocated;

struct llinfo_nd6 llinfo_nd6 = {&llinfo_nd6, &llinfo_nd6};
static size_t nd_ifinfo_indexlim = 8;
size_t nd_ifinfo_indexlim = 8;
struct nd_ifinfo *nd_ifinfo = NULL;
struct nd_drhead nd_defrouter;
struct nd_prhead nd_prefix = { 0 };
Expand Down
Loading

0 comments on commit 5245d98

Please sign in to comment.