Skip to content

Commit

Permalink
xnu-517.7.21
Browse files Browse the repository at this point in the history
  • Loading branch information
Darwin authored and das committed Jun 4, 2017
1 parent 1a5d9d2 commit ed5869b
Show file tree
Hide file tree
Showing 50 changed files with 4,408 additions and 861 deletions.
2 changes: 1 addition & 1 deletion bsd/conf/version.minor
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4
5
2 changes: 1 addition & 1 deletion bsd/hfs/hfs_link.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ hfs_link(ap)
}

// XXXdbg - need to do this here as well because cp could have changed
error = VOP_UPDATE(vp, &tv, &tv, 1);
(void) VOP_UPDATE(vp, &tv, &tv, 1);


if (hfsmp->jnl) {
Expand Down
2 changes: 2 additions & 0 deletions bsd/kern/sysctl_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ extern struct sysctl_oid sysctl__net_inet_ip_sourceroute;
extern struct sysctl_oid sysctl__net_inet_ip_subnets_are_local;
extern struct sysctl_oid sysctl__net_inet_ip_keepfaith;
extern struct sysctl_oid sysctl__net_inet_ip_maxfragpackets;
extern struct sysctl_oid sysctl__net_inet_ip_maxfragsperpacket;
extern struct sysctl_oid sysctl__net_inet_ip_check_interface;
extern struct sysctl_oid sysctl__net_inet_ip_check_route_selfref;
extern struct sysctl_oid sysctl__net_inet_ip_use_route_genid;
Expand Down Expand Up @@ -525,6 +526,7 @@ struct sysctl_oid *newsysctl_list[] =
,&sysctl__net_inet_ip_subnets_are_local
,&sysctl__net_inet_ip_keepfaith
,&sysctl__net_inet_ip_maxfragpackets
,&sysctl__net_inet_ip_maxfragsperpacket
,&sysctl__net_inet_ip_check_interface
,&sysctl__net_inet_ip_check_route_selfref
,&sysctl__net_inet_ip_use_route_genid
Expand Down
130 changes: 69 additions & 61 deletions bsd/netinet/ip_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,17 @@ SYSCTL_INT(_net_inet_ip, IPCTL_KEEPFAITH, keepfaith, CTLFLAG_RW,
&ip_keepfaith, 0,
"Enable packet capture for FAITH IPv4->IPv6 translater daemon");

static int ip_nfragpackets = 0;
static int ip_maxfragpackets; /* initialized in ip_init() */
static int nipq = 0; /* total # of reass queues */
static int maxnipq = 0;
SYSCTL_INT(_net_inet_ip, OID_AUTO, maxfragpackets, CTLFLAG_RW,
&ip_maxfragpackets, 0,
&maxnipq, 0,
"Maximum number of IPv4 fragment reassembly queue entries");

static int maxfragsperpacket;
SYSCTL_INT(_net_inet_ip, OID_AUTO, maxfragsperpacket, CTLFLAG_RW,
&maxfragsperpacket, 0,
"Maximum number of IPv4 fragments allowed per packet");

/*
* XXX - Setting ip_checkinterface mostly implements the receive side of
* the Strong ES model described in RFC 1122, but since the routing table
Expand Down Expand Up @@ -198,8 +203,6 @@ SYSCTL_STRUCT(_net_inet_ip, IPCTL_STATS, stats, CTLFLAG_RD,
(((((x) & 0xF) | ((((x) >> 8) & 0xF) << 4)) ^ (y)) & IPREASS_HMASK)

static struct ipq ipq[IPREASS_NHASH];
static int nipq = 0; /* total # of reass queues */
static int maxnipq;
const int ipintrq_present = 1;

#if IPCTL_DEFMTU
Expand Down Expand Up @@ -314,8 +317,8 @@ ip_init()
for (i = 0; i < IPREASS_NHASH; i++)
ipq[i].next = ipq[i].prev = &ipq[i];

maxnipq = nmbclusters / 4;
ip_maxfragpackets = nmbclusters / 4;
maxnipq = nmbclusters / 32;
maxfragsperpacket = 16;

#if RANDOM_IP_ID
ip_id = time_second & 0xffff;
Expand Down Expand Up @@ -770,21 +773,13 @@ ip_input(struct mbuf *m)
*/
if (ip->ip_off & (IP_MF | IP_OFFMASK | IP_RF)) {

#if 0 /*
* Reassembly should be able to treat a mbuf cluster, for later
* operation of contiguous protocol headers on the cluster. (KAME)
*/
if (m->m_flags & M_EXT) { /* XXX */
if ((m = m_pullup(m, hlen)) == 0) {
ipstat.ips_toosmall++;
#if IPFIREWALL_FORWARD
ip_fw_fwd_addr = NULL;
#endif
return;
/* If maxnipq is 0, never accept fragments. */
if (maxnipq == 0) {
ipstat.ips_fragments++;
ipstat.ips_fragdropped++;
goto bad;
}
ip = mtod(m, struct ip *);
}
#endif

sum = IPREASS_HASH(ip->ip_src.s_addr, ip->ip_id);
/*
* Look for queue of fragments
Expand All @@ -799,31 +794,37 @@ ip_input(struct mbuf *m)

fp = 0;

/* check if there's a place for the new queue */
if (nipq > maxnipq) {
/*
* Enforce upper bound on number of fragmented packets
* for which we attempt reassembly;
* If maxnipq is -1, accept all fragments without limitation.
*/
if ((nipq > maxnipq) && (maxnipq > 0)) {
/*
* drop something from the tail of the current queue
* before proceeding further
*/
if (ipq[sum].prev == &ipq[sum]) { /* gak */
for (i = 0; i < IPREASS_NHASH; i++) {
if (ipq[i].prev != &ipq[i]) {
ipstat.ips_fragtimeout +=
ipq[i].prev->ipq_nfrags;
ip_freef(ipq[i].prev);
break;
}
}
} else
} else {
ipstat.ips_fragtimeout += ipq[sum].prev->ipq_nfrags;
ip_freef(ipq[sum].prev);
}
}
found:
/*
* Adjust ip_len to not reflect header,
* set ip_mff if more fragments are expected,
* convert offset of this to bytes.
*/
ip->ip_len -= hlen;
mff = (ip->ip_off & IP_MF) != 0;
if (mff) {
if (ip->ip_off & IP_MF) {
/*
* Make sure that fragments have a data length
* that's a non-zero multiple of 8 bytes.
Expand All @@ -833,18 +834,15 @@ ip_input(struct mbuf *m)
goto bad;
}
m->m_flags |= M_FRAG;
} else {
/* Clear the flag in case packet comes from loopback */
} else
m->m_flags &= ~M_FRAG;
}
ip->ip_off <<= 3;

/*
* If datagram marked as having more fragments
* or if this is not the first fragment,
* attempt reassembly; if it succeeds, proceed.
* Attempt reassembly; if it succeeds, proceed.
* ip_reass() will return a different mbuf, and update
* the divert info in divert_info and args.divert_rule.
*/
if (mff || ip->ip_off) {
ipstat.ips_fragments++;
m->m_pkthdr.header = ip;
#if IPDIVERT
Expand Down Expand Up @@ -877,9 +875,6 @@ ip_input(struct mbuf *m)
}
#endif
} else
if (fp)
ip_freef(fp);
} else
ip->ip_len -= hlen;

#if IPDIVERT
Expand Down Expand Up @@ -1021,20 +1016,12 @@ ip_reass(m, fp, where)
* If first fragment to arrive, create a reassembly queue.
*/
if (fp == 0) {
/*
* Enforce upper bound on number of fragmented packets
* for which we attempt reassembly;
* If maxfrag is 0, never accept fragments.
* If maxfrag is -1, accept all fragments without limitation.
*/
if ((ip_maxfragpackets >= 0) && (ip_nfragpackets >= ip_maxfragpackets))
goto dropfrag;
ip_nfragpackets++;
if ((t = m_get(M_DONTWAIT, MT_FTABLE)) == NULL)
goto dropfrag;
fp = mtod(t, struct ipq *);
insque((void*)fp, (void*)where);
nipq++;
fp->ipq_nfrags = 1;
fp->ipq_ttl = IPFRAGTTL;
fp->ipq_p = ip->ip_p;
fp->ipq_id = ip->ip_id;
Expand All @@ -1051,6 +1038,8 @@ ip_reass(m, fp, where)
fp->ipq_div_cookie = 0;
#endif
goto inserted;
} else {
fp->ipq_nfrags++;
}

#define GETIP(m) ((struct ip*)((m)->m_pkthdr.header))
Expand Down Expand Up @@ -1105,6 +1094,8 @@ ip_reass(m, fp, where)
}
nq = q->m_nextpkt;
m->m_nextpkt = nq;
ipstat.ips_fragdropped++;
fp->ipq_nfrags--;
m_freem(q);
}

Expand All @@ -1113,30 +1104,49 @@ ip_reass(m, fp, where)
#if IPDIVERT
/*
* Transfer firewall instructions to the fragment structure.
* Any fragment diverting causes the whole packet to divert.
* Only trust info in the fragment at offset 0.
*/
if (ip->ip_off == 0) {
#ifdef IPDIVERT_44
fp->ipq_div_info = *divinfo;
#else
fp->ipq_divert = *divinfo;
#endif
fp->ipq_div_cookie = *divcookie;
}
*divinfo = 0;
*divcookie = 0;
#endif

/*
* Check for complete reassembly.
* Check for complete reassembly and perform frag per packet
* limiting.
*
* Frag limiting is performed here so that the nth frag has
* a chance to complete the packet before we drop the packet.
* As a result, n+1 frags are actually allowed per packet, but
* only n will ever be stored. (n = maxfragsperpacket.)
*
*/
next = 0;
for (p = NULL, q = fp->ipq_frags; q; p = q, q = q->m_nextpkt) {
if (GETIP(q)->ip_off != next)
if (GETIP(q)->ip_off != next) {
if (fp->ipq_nfrags > maxfragsperpacket) {
ipstat.ips_fragdropped += fp->ipq_nfrags;
ip_freef(fp);
}
return (0);
}
next += GETIP(q)->ip_len;
}
/* Make sure the last packet didn't have the IP_MF flag */
if (p->m_flags & M_FRAG)
if (p->m_flags & M_FRAG) {
if (fp->ipq_nfrags > maxfragsperpacket) {
ipstat.ips_fragdropped += fp->ipq_nfrags;
ip_freef(fp);
}
return (0);
}

/*
* Reassembly is complete. Make sure the packet is a sane size.
Expand All @@ -1145,6 +1155,7 @@ ip_reass(m, fp, where)
ip = GETIP(q);
if (next + (IP_VHL_HL(ip->ip_vhl) << 2) > IP_MAXPACKET) {
ipstat.ips_toolong++;
ipstat.ips_fragdropped += fp->ipq_nfrags;
ip_freef(fp);
return (0);
}
Expand All @@ -1161,12 +1172,8 @@ ip_reass(m, fp, where)
for (q = nq; q != NULL; q = nq) {
nq = q->m_nextpkt;
q->m_nextpkt = NULL;
if (q->m_pkthdr.csum_flags & CSUM_TCP_SUM16)
m->m_pkthdr.csum_flags = 0;
else {
m->m_pkthdr.csum_flags &= q->m_pkthdr.csum_flags;
m->m_pkthdr.csum_data += q->m_pkthdr.csum_data;
}
m_cat(m, q);
}

Expand Down Expand Up @@ -1194,7 +1201,6 @@ ip_reass(m, fp, where)
remque((void*)fp);
nipq--;
(void) m_free(dtom(fp));
ip_nfragpackets--;
m->m_len += (IP_VHL_HL(ip->ip_vhl) << 2);
m->m_data -= (IP_VHL_HL(ip->ip_vhl) << 2);
/* some debugging cruft by sklower, below, will go away soon */
Expand All @@ -1212,6 +1218,8 @@ ip_reass(m, fp, where)
*divcookie = 0;
#endif
ipstat.ips_fragdropped++;
if (fp != 0)
fp->ipq_nfrags--;
m_freem(m);
return (0);

Expand All @@ -1235,7 +1243,6 @@ ip_freef(fp)
}
remque((void*)fp);
(void) m_free(dtom(fp));
ip_nfragpackets--;
nipq--;
}

Expand All @@ -1259,7 +1266,7 @@ ip_slowtimo()
--fp->ipq_ttl;
fp = fp->next;
if (fp->prev->ipq_ttl == 0) {
ipstat.ips_fragtimeout++;
ipstat.ips_fragtimeout += fp->prev->ipq_nfrags;
ip_freef(fp->prev);
}
}
Expand All @@ -1269,11 +1276,12 @@ ip_slowtimo()
* (due to the limit being lowered), drain off
* enough to get down to the new limit.
*/
if (maxnipq >= 0 && nipq > maxnipq) {
for (i = 0; i < IPREASS_NHASH; i++) {
if (ip_maxfragpackets >= 0) {
while ((ip_nfragpackets > ip_maxfragpackets) &&
while (nipq > maxnipq &&
(ipq[i].next != &ipq[i])) {
ipstat.ips_fragdropped++;
ipstat.ips_fragdropped +=
ipq[i].next->ipq_nfrags;
ip_freef(ipq[i].next);
}
}
Expand All @@ -1292,7 +1300,7 @@ ip_drain()

for (i = 0; i < IPREASS_NHASH; i++) {
while (ipq[i].next != &ipq[i]) {
ipstat.ips_fragdropped++;
ipstat.ips_fragdropped += ipq[i].next->ipq_nfrags;
ip_freef(ipq[i].next);
}
}
Expand Down
3 changes: 2 additions & 1 deletion bsd/netinet/ip_var.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ struct ipq {
u_short ipq_id; /* sequence id for reassembly */
struct mbuf *ipq_frags; /* to ip headers of fragments */
struct in_addr ipq_src,ipq_dst;
u_long reserved[4]; /* for future use */
u_long ipq_nfrags;
u_long reserved[3]; /* for future use */
#if IPDIVERT
#ifdef IPDIVERT_44
u_int32_t ipq_div_info; /* ipfw divert port & flags */
Expand Down
2 changes: 1 addition & 1 deletion bsd/netinet6/frag6.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ frag6_init()
{
struct timeval tv;

ip6_maxfragpackets = nmbclusters / 4;
ip6_maxfragpackets = nmbclusters / 32;

/*
* in many cases, random() here does NOT return random number
Expand Down
Loading

0 comments on commit ed5869b

Please sign in to comment.