summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/in.c117
-rw-r--r--sys/netinet/in.h2
-rw-r--r--sys/netinet/in_debug.c3
-rw-r--r--sys/netinet/in_var.h9
-rw-r--r--sys/netinet/ip_carp.c22
-rw-r--r--sys/netinet/ip_input.c5
-rw-r--r--sys/netinet/ipfw/dummynet.txt2
-rw-r--r--sys/netinet/sctp_pcb.c4
-rw-r--r--sys/netinet/sctp_structs.h2
-rw-r--r--sys/netinet/sctp_usrreq.c14
-rw-r--r--sys/netinet/sctputil.c2
-rw-r--r--sys/netinet/tcp.h1
-rw-r--r--sys/netinet/tcp_input.c51
-rw-r--r--sys/netinet/tcp_output.c15
-rw-r--r--sys/netinet/tcp_reass.c30
-rw-r--r--sys/netinet/tcp_timer.c7
-rw-r--r--sys/netinet/tcp_usrreq.c14
-rw-r--r--sys/netinet/tcp_var.h10
-rw-r--r--sys/netinet/udp_var.h3
19 files changed, 129 insertions, 184 deletions
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index da4e8a0..bba364d 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -76,11 +76,6 @@ static int in_ifinit(struct ifnet *,
struct in_ifaddr *, struct sockaddr_in *, int);
static void in_purgemaddrs(struct ifnet *);
-static VNET_DEFINE(int, subnetsarelocal);
-#define V_subnetsarelocal VNET(subnetsarelocal)
-SYSCTL_VNET_INT(_net_inet_ip, OID_AUTO, subnets_are_local, CTLFLAG_RW,
- &VNET_NAME(subnetsarelocal), 0,
- "Treat all subnets as directly connected");
static VNET_DEFINE(int, sameprefixcarponly);
#define V_sameprefixcarponly VNET(sameprefixcarponly)
SYSCTL_VNET_INT(_net_inet_ip, OID_AUTO, same_prefix_carp_only, CTLFLAG_RW,
@@ -95,9 +90,7 @@ VNET_DECLARE(struct arpstat, arpstat); /* ARP statistics, see if_arp.h */
/*
* Return 1 if an internet address is for a ``local'' host
- * (one to which we have a connection). If subnetsarelocal
- * is true, this includes other subnets of the local net.
- * Otherwise, it includes only the directly-connected (sub)nets.
+ * (one to which we have a connection).
*/
int
in_localaddr(struct in_addr in)
@@ -106,19 +99,10 @@ in_localaddr(struct in_addr in)
register struct in_ifaddr *ia;
IN_IFADDR_RLOCK();
- if (V_subnetsarelocal) {
- TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) {
- if ((i & ia->ia_netmask) == ia->ia_net) {
- IN_IFADDR_RUNLOCK();
- return (1);
- }
- }
- } else {
- TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) {
- if ((i & ia->ia_subnetmask) == ia->ia_subnet) {
- IN_IFADDR_RUNLOCK();
- return (1);
- }
+ TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) {
+ if ((i & ia->ia_subnetmask) == ia->ia_subnet) {
+ IN_IFADDR_RUNLOCK();
+ return (1);
}
}
IN_IFADDR_RUNLOCK();
@@ -845,7 +829,7 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin,
{
register u_long i = ntohl(sin->sin_addr.s_addr);
struct sockaddr_in oldaddr;
- int s = splimp(), flags = RTF_UP, error = 0;
+ int flags = RTF_UP, error = 0;
oldaddr = ia->ia_addr;
if (oldaddr.sin_family == AF_INET)
@@ -865,7 +849,6 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin,
if (ifp->if_ioctl != NULL) {
error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia);
if (error) {
- splx(s);
/* LIST_REMOVE(ia, ia_hash) is done in in_control */
ia->ia_addr = oldaddr;
IN_IFADDR_WLOCK();
@@ -884,29 +867,24 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin,
return (error);
}
}
- splx(s);
if (scrub) {
ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
in_ifscrub(ifp, ia, LLE_STATIC);
ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
}
- if (IN_CLASSA(i))
- ia->ia_netmask = IN_CLASSA_NET;
- else if (IN_CLASSB(i))
- ia->ia_netmask = IN_CLASSB_NET;
- else
- ia->ia_netmask = IN_CLASSC_NET;
/*
- * The subnet mask usually includes at least the standard network part,
- * but may may be smaller in the case of supernetting.
- * If it is set, we believe it.
+ * Be compatible with network classes, if netmask isn't supplied,
+ * guess it based on classes.
*/
if (ia->ia_subnetmask == 0) {
- ia->ia_subnetmask = ia->ia_netmask;
+ if (IN_CLASSA(i))
+ ia->ia_subnetmask = IN_CLASSA_NET;
+ else if (IN_CLASSB(i))
+ ia->ia_subnetmask = IN_CLASSB_NET;
+ else
+ ia->ia_subnetmask = IN_CLASSC_NET;
ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask);
- } else
- ia->ia_netmask &= ia->ia_subnetmask;
- ia->ia_net = i & ia->ia_netmask;
+ }
ia->ia_subnet = i & ia->ia_subnetmask;
in_socktrim(&ia->ia_sockmask);
/*
@@ -919,10 +897,11 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin,
*/
ia->ia_ifa.ifa_metric = ifp->if_metric;
if (ifp->if_flags & IFF_BROADCAST) {
- ia->ia_broadaddr.sin_addr.s_addr =
- htonl(ia->ia_subnet | ~ia->ia_subnetmask);
- ia->ia_netbroadcast.s_addr =
- htonl(ia->ia_net | ~ ia->ia_netmask);
+ if (ia->ia_subnetmask == IN_RFC3021_MASK)
+ ia->ia_broadaddr.sin_addr.s_addr = INADDR_BROADCAST;
+ else
+ ia->ia_broadaddr.sin_addr.s_addr =
+ htonl(ia->ia_subnet | ~ia->ia_subnetmask);
} else if (ifp->if_flags & IFF_LOOPBACK) {
ia->ia_dstaddr = ia->ia_addr;
flags |= RTF_HOST;
@@ -1126,8 +1105,10 @@ in_scrubprefix(struct in_ifaddr *target, u_int flags)
RT_LOCK(ia_ro.ro_rt);
if (ia_ro.ro_rt->rt_refcnt <= 1)
freeit = 1;
- else
+ else if (flags & LLE_STATIC) {
RT_REMREF(ia_ro.ro_rt);
+ target->ia_flags &= ~IFA_RTSELF;
+ }
RTFREE_LOCKED(ia_ro.ro_rt);
}
if (freeit && (flags & LLE_STATIC)) {
@@ -1136,7 +1117,8 @@ in_scrubprefix(struct in_ifaddr *target, u_int flags)
if (error == 0)
target->ia_flags &= ~IFA_RTSELF;
}
- if (flags & LLE_STATIC)
+ if ((flags & LLE_STATIC) &&
+ !(target->ia_ifp->if_flags & IFF_NOARP))
/* remove arp cache */
arp_ifscrub(target->ia_ifp, IA_SIN(target)->sin_addr.s_addr);
}
@@ -1250,11 +1232,12 @@ in_broadcast(struct in_addr in, struct ifnet *ifp)
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
if (ifa->ifa_addr->sa_family == AF_INET &&
(in.s_addr == ia->ia_broadaddr.sin_addr.s_addr ||
- in.s_addr == ia->ia_netbroadcast.s_addr ||
/*
- * Check for old-style (host 0) broadcast.
+ * Check for old-style (host 0) broadcast, but
+ * taking into account that RFC 3021 obsoletes it.
*/
- t == ia->ia_subnet || t == ia->ia_net) &&
+ (ia->ia_subnetmask != IN_RFC3021_MASK &&
+ t == ia->ia_subnet)) &&
/*
* Check for an all one subnetmask. These
* only exist when an interface gets a secondary
@@ -1411,8 +1394,6 @@ static int
in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr)
{
struct rtentry *rt;
- struct ifnet *xifp;
- int error = 0;
KASSERT(l3addr->sa_family == AF_INET,
("sin_family %d", l3addr->sa_family));
@@ -1429,21 +1410,16 @@ in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr
* such as MANET, and the interface is of the correct type, then
* allow for ARP to proceed.
*/
- if (rt->rt_flags & (RTF_GATEWAY | RTF_HOST)) {
- xifp = rt->rt_ifp;
-
- if (xifp && (xifp->if_type != IFT_ETHER ||
- (xifp->if_flags & (IFF_NOARP | IFF_STATICARP)) != 0))
- error = EINVAL;
-
- if (memcmp(rt->rt_gateway->sa_data, l3addr->sa_data,
- sizeof(in_addr_t)) != 0)
- error = EINVAL;
- }
-
if (rt->rt_flags & RTF_GATEWAY) {
- RTFREE_LOCKED(rt);
- return (EINVAL);
+ if (!(rt->rt_flags & RTF_HOST) || !rt->rt_ifp ||
+ rt->rt_ifp->if_type != IFT_ETHER ||
+ (rt->rt_ifp->if_flags &
+ (IFF_NOARP | IFF_STATICARP)) != 0 ||
+ memcmp(rt->rt_gateway->sa_data, l3addr->sa_data,
+ sizeof(in_addr_t)) != 0) {
+ RTFREE_LOCKED(rt);
+ return (EINVAL);
+ }
}
/*
@@ -1452,32 +1428,31 @@ in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr
* interfaces have the same prefix. An incoming packet arrives
* on one interface and the corresponding outgoing packet leaves
* another interface.
- *
*/
if (rt->rt_ifp != ifp) {
- char *sa, *mask, *addr, *lim;
+ const char *sa, *mask, *addr, *lim;
int len;
- sa = (char *)rt_key(rt);
- mask = (char *)rt_mask(rt);
- addr = (char *)__DECONST(struct sockaddr *, l3addr);
- len = ((struct sockaddr_in *)__DECONST(struct sockaddr *, l3addr))->sin_len;
+ sa = (const char *)rt_key(rt);
+ mask = (const char *)rt_mask(rt);
+ addr = (const char *)l3addr;
+ len = ((const struct sockaddr_in *)l3addr)->sin_len;
lim = addr + len;
for ( ; addr < lim; sa++, mask++, addr++) {
if ((*sa ^ *addr) & *mask) {
- error = EINVAL;
#ifdef DIAGNOSTIC
log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n",
inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr));
#endif
- break;
+ RTFREE_LOCKED(rt);
+ return (EINVAL);
}
}
}
RTFREE_LOCKED(rt);
- return (error);
+ return (0);
}
/*
diff --git a/sys/netinet/in.h b/sys/netinet/in.h
index d5e4290..52844f0 100644
--- a/sys/netinet/in.h
+++ b/sys/netinet/in.h
@@ -392,6 +392,8 @@ __END_DECLS
#define IN_LOOPBACKNET 127 /* official! */
+#define IN_RFC3021_MASK (u_int32_t)0xfffffffe
+
/*
* Options for use with [gs]etsockopt at the IP level.
* First word of comment is data type; bool is stored in int.
diff --git a/sys/netinet/in_debug.c b/sys/netinet/in_debug.c
index 7624f1d..0795fa8 100644
--- a/sys/netinet/in_debug.c
+++ b/sys/netinet/in_debug.c
@@ -86,11 +86,8 @@ in_show_in_ifaddr(struct in_ifaddr *ia)
#define IA_DB_RPINTF_DPTR(f, e) db_printf("\t *%s = " f "\n", #e, *ia->e);
db_printf("\tin_ifaddr = %p\n", ia);
IA_DB_RPINTF_PTR("%p", ia_ifa);
- IA_DB_RPINTF("0x%08lx", ia_net);
- IA_DB_RPINTF("0x%08lx", ia_netmask);
IA_DB_RPINTF("0x%08lx", ia_subnet);
IA_DB_RPINTF("0x%08lx", ia_subnetmask);
- IA_DB_RPINTF("0x%08x", ia_netbroadcast.s_addr);
IA_DB_RPINTF("%p", ia_hash.le_next);
IA_DB_RPINTF("%p", ia_hash.le_prev);
IA_DB_RPINTF_DPTR("%p", ia_hash.le_prev);
diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h
index 5be07c1..3a5e328 100644
--- a/sys/netinet/in_var.h
+++ b/sys/netinet/in_var.h
@@ -60,12 +60,9 @@ struct in_ifaddr {
struct ifaddr ia_ifa; /* protocol-independent info */
#define ia_ifp ia_ifa.ifa_ifp
#define ia_flags ia_ifa.ifa_flags
- /* ia_{,sub}net{,mask} in host order */
- u_long ia_net; /* network number of interface */
- u_long ia_netmask; /* mask of net part */
- u_long ia_subnet; /* subnet number, including net */
- u_long ia_subnetmask; /* mask of subnet part */
- struct in_addr ia_netbroadcast; /* to recognize net broadcasts */
+ /* ia_subnet{,mask} in host order */
+ u_long ia_subnet; /* subnet address */
+ u_long ia_subnetmask; /* mask of subnet */
LIST_ENTRY(in_ifaddr) ia_hash; /* entry in bucket of inet addresses */
TAILQ_ENTRY(in_ifaddr) ia_link; /* list of internet addresses */
struct sockaddr_in ia_addr; /* reserve space for interface name */
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index d16159d..34dced8 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -1424,24 +1424,10 @@ carp_setrun(struct carp_softc *sc, sa_family_t af)
switch (sc->sc_state) {
case INIT:
- if (carp_opts[CARPCTL_PREEMPT] && !carp_suppress_preempt) {
- carp_send_ad_locked(sc);
-#ifdef INET
- carp_send_arp(sc);
-#endif
-#ifdef INET6
- carp_send_na(sc);
-#endif /* INET6 */
- CARP_LOG("%s: INIT -> MASTER (preempting)\n",
- SC2IFP(sc)->if_xname);
- carp_set_state(sc, MASTER);
- carp_setroute(sc, RTM_ADD);
- } else {
- CARP_LOG("%s: INIT -> BACKUP\n", SC2IFP(sc)->if_xname);
- carp_set_state(sc, BACKUP);
- carp_setroute(sc, RTM_DELETE);
- carp_setrun(sc, 0);
- }
+ CARP_LOG("%s: INIT -> BACKUP\n", SC2IFP(sc)->if_xname);
+ carp_set_state(sc, BACKUP);
+ carp_setroute(sc, RTM_DELETE);
+ carp_setrun(sc, 0);
break;
case BACKUP:
callout_stop(&sc->sc_ad_tmo);
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 67fcb74..0664acc 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -622,11 +622,6 @@ passin:
IF_ADDR_UNLOCK(ifp);
goto ours;
}
- if (ia->ia_netbroadcast.s_addr == ip->ip_dst.s_addr) {
- ifa_ref(ifa);
- IF_ADDR_UNLOCK(ifp);
- goto ours;
- }
#ifdef BOOTP_COMPAT
if (IA_SIN(ia)->sin_addr.s_addr == INADDR_ANY) {
ifa_ref(ifa);
diff --git a/sys/netinet/ipfw/dummynet.txt b/sys/netinet/ipfw/dummynet.txt
index 0ed6ad1..3a1efde 100644
--- a/sys/netinet/ipfw/dummynet.txt
+++ b/sys/netinet/ipfw/dummynet.txt
@@ -325,7 +325,7 @@ we do the following:
dummynet_task()
===============
-The dummynet_task() is the the main dummynet processing function and is
+The dummynet_task() is the main dummynet processing function and is
called every tick. This function first calculate the new current time, then
it checks if it is the time to wake up object from the system_heap comparing
the current time and the key of the heap. Two types of object (really the
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index 9eb9a7d..2b36ba4e 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -2786,6 +2786,9 @@ sctp_move_pcb_and_assoc(struct sctp_inpcb *old_inp, struct sctp_inpcb *new_inp,
LIST_INSERT_HEAD(&new_inp->sctp_addr_list, laddr,
sctp_nxt_addr);
new_inp->laddr_count++;
+ if (oladdr == stcb->asoc.last_used_address) {
+ stcb->asoc.last_used_address = laddr;
+ }
}
}
/*
@@ -2804,6 +2807,7 @@ sctp_move_pcb_and_assoc(struct sctp_inpcb *old_inp, struct sctp_inpcb *new_inp,
/* now what about the nets? */
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
net->pmtu_timer.ep = (void *)new_inp;
+ net->hb_timer.ep = (void *)new_inp;
net->rxt_timer.ep = (void *)new_inp;
}
SCTP_INP_WUNLOCK(new_inp);
diff --git a/sys/netinet/sctp_structs.h b/sys/netinet/sctp_structs.h
index 70bd812..eec2daa 100644
--- a/sys/netinet/sctp_structs.h
+++ b/sys/netinet/sctp_structs.h
@@ -191,6 +191,8 @@ struct iterator_control {
struct sctp_net_route {
sctp_rtentry_t *ro_rt;
void *ro_lle;
+ void *ro_ia;
+ int ro_flags;
union sctp_sockstore _l_addr; /* remote peer addr */
struct sctp_ifa *_s_addr; /* our selected src addr */
};
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index d49ea38..c6e77cd 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -2435,7 +2435,7 @@ flags_out:
paddrp->spp_flags |= SPP_PMTUD_DISABLE;
}
if (net->dscp & 0x01) {
- paddrp->spp_dscp = net->dscp >> 2;
+ paddrp->spp_dscp = net->dscp & 0xfc;
paddrp->spp_flags |= SPP_DSCP;
}
#ifdef INET6
@@ -2453,7 +2453,7 @@ flags_out:
paddrp->spp_pathmaxrxt = stcb->asoc.def_net_failure;
paddrp->spp_pathmtu = sctp_get_frag_point(stcb, &stcb->asoc);
if (stcb->asoc.default_dscp & 0x01) {
- paddrp->spp_dscp = stcb->asoc.default_dscp >> 2;
+ paddrp->spp_dscp = stcb->asoc.default_dscp & 0xfc;
paddrp->spp_flags |= SPP_DSCP;
}
#ifdef INET6
@@ -2488,7 +2488,7 @@ flags_out:
paddrp->spp_assoc_id = SCTP_FUTURE_ASSOC;
/* get inp's default */
if (inp->sctp_ep.default_dscp & 0x01) {
- paddrp->spp_dscp = inp->sctp_ep.default_dscp >> 2;
+ paddrp->spp_dscp = inp->sctp_ep.default_dscp & 0xfc;
paddrp->spp_flags |= SPP_DSCP;
}
#ifdef INET6
@@ -4691,7 +4691,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
net->failure_threshold = paddrp->spp_pathmaxrxt;
}
if (paddrp->spp_flags & SPP_DSCP) {
- net->dscp = paddrp->spp_dscp << 2;
+ net->dscp = paddrp->spp_dscp & 0xfc;
net->dscp |= 0x01;
}
#ifdef INET6
@@ -4794,10 +4794,10 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
}
if (paddrp->spp_flags & SPP_DSCP) {
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
- net->dscp = paddrp->spp_dscp << 2;
+ net->dscp = paddrp->spp_dscp & 0xfc;
net->dscp |= 0x01;
}
- stcb->asoc.default_dscp = paddrp->spp_dscp << 2;
+ stcb->asoc.default_dscp = paddrp->spp_dscp & 0xfc;
stcb->asoc.default_dscp |= 0x01;
}
#ifdef INET6
@@ -4851,7 +4851,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
sctp_feature_on(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD);
}
if (paddrp->spp_flags & SPP_DSCP) {
- inp->sctp_ep.default_dscp = paddrp->spp_dscp << 2;
+ inp->sctp_ep.default_dscp = paddrp->spp_dscp & 0xfc;
inp->sctp_ep.default_dscp |= 0x01;
}
#ifdef INET6
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index 4a16b06..3bd4e6f 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -1661,7 +1661,7 @@ sctp_timeout_handler(void *t)
sctp_auditing(4, inp, stcb, net);
#endif
if (!(net->dest_state & SCTP_ADDR_NOHB)) {
- sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
+ sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_HB_TMR, SCTP_SO_NOT_LOCKED);
}
break;
diff --git a/sys/netinet/tcp.h b/sys/netinet/tcp.h
index 443425f..805a561 100644
--- a/sys/netinet/tcp.h
+++ b/sys/netinet/tcp.h
@@ -34,6 +34,7 @@
#define _NETINET_TCP_H_
#include <sys/cdefs.h>
+#include <sys/types.h>
#if __BSD_VISIBLE
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 91517b3..128cccd 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -183,6 +183,11 @@ SYSCTL_VNET_INT(_net_inet_tcp, OID_AUTO, insecure_rst, CTLFLAG_RW,
&VNET_NAME(tcp_insecure_rst), 0,
"Follow the old (insecure) criteria for accepting RST packets");
+VNET_DEFINE(int, tcp_recvspace) = 1024*64;
+#define V_tcp_recvspace VNET(tcp_recvspace)
+SYSCTL_VNET_INT(_net_inet_tcp, TCPCTL_RECVSPACE, tcp_recvspace, CTLFLAG_RW,
+ &VNET_NAME(tcp_recvspace), 0, "Initial receive socket buffer size");
+
VNET_DEFINE(int, tcp_do_autorcvbuf) = 1;
#define V_tcp_do_autorcvbuf VNET(tcp_do_autorcvbuf)
SYSCTL_VNET_INT(_net_inet_tcp, OID_AUTO, recvbuf_auto, CTLFLAG_RW,
@@ -301,9 +306,6 @@ cc_conn_init(struct tcpcb *tp)
struct hc_metrics_lite metrics;
struct inpcb *inp = tp->t_inpcb;
int rtt;
-#ifdef INET6
- int isipv6 = ((inp->inp_vflag & INP_IPV6) != 0) ? 1 : 0;
-#endif
INP_WLOCK_ASSERT(tp->t_inpcb);
@@ -337,49 +339,16 @@ cc_conn_init(struct tcpcb *tp)
}
/*
- * Set the slow-start flight size depending on whether this
- * is a local network or not.
- *
- * Extend this so we cache the cwnd too and retrieve it here.
- * Make cwnd even bigger than RFC3390 suggests but only if we
- * have previous experience with the remote host. Be careful
- * not make cwnd bigger than remote receive window or our own
- * send socket buffer. Maybe put some additional upper bound
- * on the retrieved cwnd. Should do incremental updates to
- * hostcache when cwnd collapses so next connection doesn't
- * overloads the path again.
- *
- * XXXAO: Initializing the CWND from the hostcache is broken
- * and in its current form not RFC conformant. It is disabled
- * until fixed or removed entirely.
+ * Set the initial slow-start flight size.
*
* RFC3390 says only do this if SYN or SYN/ACK didn't got lost.
- * We currently check only in syncache_socket for that.
+ * XXX: We currently check only in syncache_socket for that.
*/
-/* #define TCP_METRICS_CWND */
-#ifdef TCP_METRICS_CWND
- if (metrics.rmx_cwnd)
- tp->snd_cwnd = max(tp->t_maxseg, min(metrics.rmx_cwnd / 2,
- min(tp->snd_wnd, so->so_snd.sb_hiwat)));
- else
-#endif
if (V_tcp_do_rfc3390)
tp->snd_cwnd = min(4 * tp->t_maxseg,
max(2 * tp->t_maxseg, 4380));
-#ifdef INET6
- else if (isipv6 && in6_localaddr(&inp->in6p_faddr))
- tp->snd_cwnd = tp->t_maxseg * V_ss_fltsz_local;
-#endif
-#if defined(INET) && defined(INET6)
- else if (!isipv6 && in_localaddr(inp->inp_faddr))
- tp->snd_cwnd = tp->t_maxseg * V_ss_fltsz_local;
-#endif
-#ifdef INET
- else if (in_localaddr(inp->inp_faddr))
- tp->snd_cwnd = tp->t_maxseg * V_ss_fltsz_local;
-#endif
else
- tp->snd_cwnd = tp->t_maxseg * V_ss_fltsz;
+ tp->snd_cwnd = tp->t_maxseg;
if (CC_ALGO(tp)->conn_init != NULL)
CC_ALGO(tp)->conn_init(tp->ccv);
@@ -3517,7 +3486,7 @@ tcp_mss(struct tcpcb *tp, int offer)
*/
so = inp->inp_socket;
SOCKBUF_LOCK(&so->so_snd);
- if ((so->so_snd.sb_hiwat == tcp_sendspace) && metrics.rmx_sendpipe)
+ if ((so->so_snd.sb_hiwat == V_tcp_sendspace) && metrics.rmx_sendpipe)
bufsize = metrics.rmx_sendpipe;
else
bufsize = so->so_snd.sb_hiwat;
@@ -3534,7 +3503,7 @@ tcp_mss(struct tcpcb *tp, int offer)
tp->t_maxseg = mss;
SOCKBUF_LOCK(&so->so_rcv);
- if ((so->so_rcv.sb_hiwat == tcp_recvspace) && metrics.rmx_recvpipe)
+ if ((so->so_rcv.sb_hiwat == V_tcp_recvspace) && metrics.rmx_recvpipe)
bufsize = metrics.rmx_recvpipe;
else
bufsize = so->so_rcv.sb_hiwat;
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index 702eed3..2db178d 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -89,22 +89,17 @@ SYSCTL_VNET_INT(_net_inet_tcp, OID_AUTO, path_mtu_discovery, CTLFLAG_RW,
&VNET_NAME(path_mtu_discovery), 1,
"Enable Path MTU Discovery");
-VNET_DEFINE(int, ss_fltsz) = 1;
-SYSCTL_VNET_INT(_net_inet_tcp, OID_AUTO, slowstart_flightsize, CTLFLAG_RW,
- &VNET_NAME(ss_fltsz), 1,
- "Slow start flight size");
-
-VNET_DEFINE(int, ss_fltsz_local) = 4;
-SYSCTL_VNET_INT(_net_inet_tcp, OID_AUTO, local_slowstart_flightsize,
- CTLFLAG_RW, &VNET_NAME(ss_fltsz_local), 1,
- "Slow start flight size for local networks");
-
VNET_DEFINE(int, tcp_do_tso) = 1;
#define V_tcp_do_tso VNET(tcp_do_tso)
SYSCTL_VNET_INT(_net_inet_tcp, OID_AUTO, tso, CTLFLAG_RW,
&VNET_NAME(tcp_do_tso), 0,
"Enable TCP Segmentation Offload");
+VNET_DEFINE(int, tcp_sendspace) = 1024*32;
+#define V_tcp_sendspace VNET(tcp_sendspace)
+SYSCTL_VNET_INT(_net_inet_tcp, TCPCTL_SENDSPACE, tcp_sendspace, CTLFLAG_RW,
+ &VNET_NAME(tcp_sendspace), 0, "Initial send socket buffer size");
+
VNET_DEFINE(int, tcp_do_autosndbuf) = 1;
#define V_tcp_do_autosndbuf VNET(tcp_do_autosndbuf)
SYSCTL_VNET_INT(_net_inet_tcp, OID_AUTO, sendbuf_auto, CTLFLAG_RW,
diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c
index 318fc26..d130361 100644
--- a/sys/netinet/tcp_reass.c
+++ b/sys/netinet/tcp_reass.c
@@ -177,7 +177,9 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m)
struct tseg_qent *nq;
struct tseg_qent *te = NULL;
struct socket *so = tp->t_inpcb->inp_socket;
+ char *s = NULL;
int flags;
+ struct tseg_qent tqs;
INP_WLOCK_ASSERT(tp->t_inpcb);
@@ -215,19 +217,40 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m)
TCPSTAT_INC(tcps_rcvmemdrop);
m_freem(m);
*tlenp = 0;
+ if ((s = tcp_log_addrs(&tp->t_inpcb->inp_inc, th, NULL, NULL))) {
+ log(LOG_DEBUG, "%s; %s: queue limit reached, "
+ "segment dropped\n", s, __func__);
+ free(s, M_TCPLOG);
+ }
return (0);
}
/*
* Allocate a new queue entry. If we can't, or hit the zone limit
* just drop the pkt.
+ *
+ * Use a temporary structure on the stack for the missing segment
+ * when the zone is exhausted. Otherwise we may get stuck.
*/
te = uma_zalloc(V_tcp_reass_zone, M_NOWAIT);
- if (te == NULL) {
+ if (te == NULL && th->th_seq != tp->rcv_nxt) {
TCPSTAT_INC(tcps_rcvmemdrop);
m_freem(m);
*tlenp = 0;
+ if ((s = tcp_log_addrs(&tp->t_inpcb->inp_inc, th, NULL, NULL))) {
+ log(LOG_DEBUG, "%s; %s: global zone limit reached, "
+ "segment dropped\n", s, __func__);
+ free(s, M_TCPLOG);
+ }
return (0);
+ } else if (th->th_seq == tp->rcv_nxt) {
+ bzero(&tqs, sizeof(struct tseg_qent));
+ te = &tqs;
+ if ((s = tcp_log_addrs(&tp->t_inpcb->inp_inc, th, NULL, NULL))) {
+ log(LOG_DEBUG, "%s; %s: global zone limit reached, "
+ "using stack for missing segment\n", s, __func__);
+ free(s, M_TCPLOG);
+ }
}
tp->t_segqlen++;
@@ -304,6 +327,8 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m)
if (p == NULL) {
LIST_INSERT_HEAD(&tp->t_segq, te, tqe_q);
} else {
+ KASSERT(te != &tqs, ("%s: temporary stack based entry not "
+ "first element in queue", __func__));
LIST_INSERT_AFTER(p, te, tqe_q);
}
@@ -327,7 +352,8 @@ present:
m_freem(q->tqe_m);
else
sbappendstream_locked(&so->so_rcv, q->tqe_m);
- uma_zfree(V_tcp_reass_zone, q);
+ if (q != &tqs)
+ uma_zfree(V_tcp_reass_zone, q);
tp->t_segqlen--;
q = nq;
} while (q && q->tqe_th->th_seq == tp->rcv_nxt);
diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c
index 73984c7..1651d69 100644
--- a/sys/netinet/tcp_timer.c
+++ b/sys/netinet/tcp_timer.c
@@ -495,6 +495,13 @@ tcp_timer_rexmt(void * xtp)
CURVNET_RESTORE();
return;
}
+ if (inp->inp_flags & INP_DROPPED) {
+ INP_WUNLOCK(inp);
+ INP_INFO_WUNLOCK(&V_tcbinfo);
+ CURVNET_RESTORE();
+ return;
+ }
+
tp = tcp_drop(tp, tp->t_softerror ?
tp->t_softerror : ETIMEDOUT);
headlocked = 1;
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 96cb1e4..7a7e1ce 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -1498,18 +1498,6 @@ tcp_ctloutput(struct socket *so, struct sockopt *sopt)
#undef INP_WLOCK_RECHECK
/*
- * tcp_sendspace and tcp_recvspace are the default send and receive window
- * sizes, respectively. These are obsolescent (this information should
- * be set by the route).
- */
-u_long tcp_sendspace = 1024*32;
-SYSCTL_ULONG(_net_inet_tcp, TCPCTL_SENDSPACE, sendspace, CTLFLAG_RW,
- &tcp_sendspace , 0, "Maximum outgoing TCP datagram size");
-u_long tcp_recvspace = 1024*64;
-SYSCTL_ULONG(_net_inet_tcp, TCPCTL_RECVSPACE, recvspace, CTLFLAG_RW,
- &tcp_recvspace , 0, "Maximum incoming TCP datagram size");
-
-/*
* Attach TCP protocol to socket, allocating
* internet protocol control block, tcp control block,
* bufer space, and entering LISTEN state if to accept connections.
@@ -1522,7 +1510,7 @@ tcp_attach(struct socket *so)
int error;
if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
- error = soreserve(so, tcp_sendspace, tcp_recvspace);
+ error = soreserve(so, V_tcp_sendspace, V_tcp_recvspace);
if (error)
return (error);
}
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index bbf392f..bc64ac2 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -606,9 +606,9 @@ VNET_DECLARE(int, tcp_mssdflt); /* XXX */
VNET_DECLARE(int, tcp_minmss);
VNET_DECLARE(int, tcp_delack_enabled);
VNET_DECLARE(int, tcp_do_rfc3390);
+VNET_DECLARE(int, tcp_sendspace);
+VNET_DECLARE(int, tcp_recvspace);
VNET_DECLARE(int, path_mtu_discovery);
-VNET_DECLARE(int, ss_fltsz);
-VNET_DECLARE(int, ss_fltsz_local);
VNET_DECLARE(int, tcp_do_rfc3465);
VNET_DECLARE(int, tcp_abc_l_var);
#define V_tcb VNET(tcb)
@@ -618,9 +618,9 @@ VNET_DECLARE(int, tcp_abc_l_var);
#define V_tcp_minmss VNET(tcp_minmss)
#define V_tcp_delack_enabled VNET(tcp_delack_enabled)
#define V_tcp_do_rfc3390 VNET(tcp_do_rfc3390)
+#define V_tcp_sendspace VNET(tcp_sendspace)
+#define V_tcp_recvspace VNET(tcp_recvspace)
#define V_path_mtu_discovery VNET(path_mtu_discovery)
-#define V_ss_fltsz VNET(ss_fltsz)
-#define V_ss_fltsz_local VNET(ss_fltsz_local)
#define V_tcp_do_rfc3465 VNET(tcp_do_rfc3465)
#define V_tcp_abc_l_var VNET(tcp_abc_l_var)
@@ -716,8 +716,6 @@ void tcp_hc_updatemtu(struct in_conninfo *, u_long);
void tcp_hc_update(struct in_conninfo *, struct hc_metrics_lite *);
extern struct pr_usrreqs tcp_usrreqs;
-extern u_long tcp_sendspace;
-extern u_long tcp_recvspace;
tcp_seq tcp_new_isn(struct tcpcb *);
void tcp_sack_doack(struct tcpcb *, struct tcpopt *, tcp_seq);
diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h
index 7e7cfba..6e5abd0 100644
--- a/sys/netinet/udp_var.h
+++ b/sys/netinet/udp_var.h
@@ -51,6 +51,9 @@ struct udpiphdr {
#define ui_ulen ui_u.uh_ulen
#define ui_sum ui_u.uh_sum
+struct inpcb;
+struct mbuf;
+
typedef void(*udp_tun_func_t)(struct mbuf *, int off, struct inpcb *);
/*
OpenPOWER on IntegriCloud