MFC 197288,197326,197327,197328,197342,197914,197929,
197955,199365,199370,199371,199373,199866 This MFCs all SCTP/VNET relevant fixes from head. Approved by: rrs (mentor)
This commit is contained in:
parent
a1c3a99ce5
commit
cf19fced17
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/stable/8/; revision=200208
@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/filio.h>
|
||||
#include <sys/jail.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/protosw.h>
|
||||
@ -2311,6 +2312,7 @@ sctp_peeloff(td, uap)
|
||||
goto done;
|
||||
td->td_retval[0] = fd;
|
||||
|
||||
CURVNET_SET(head->so_vnet);
|
||||
so = sonewconn(head, SS_ISCONNECTED);
|
||||
if (so == NULL)
|
||||
goto noconnection;
|
||||
@ -2350,6 +2352,7 @@ sctp_peeloff(td, uap)
|
||||
/*
|
||||
* Release explicitly held references before returning.
|
||||
*/
|
||||
CURVNET_RESTORE();
|
||||
done:
|
||||
if (nfp != NULL)
|
||||
fdrop(nfp, td);
|
||||
@ -2428,9 +2431,11 @@ sctp_generic_sendmsg (td, uap)
|
||||
auio.uio_offset = 0; /* XXX */
|
||||
auio.uio_resid = 0;
|
||||
len = auio.uio_resid = uap->mlen;
|
||||
CURVNET_SET(so->so_vnet);
|
||||
error = sctp_lower_sosend(so, to, &auio,
|
||||
(struct mbuf *)NULL, (struct mbuf *)NULL,
|
||||
uap->flags, use_rcvinfo, u_sinfo, td);
|
||||
CURVNET_RESTORE();
|
||||
if (error) {
|
||||
if (auio.uio_resid != len && (error == ERESTART ||
|
||||
error == EINTR || error == EWOULDBLOCK))
|
||||
@ -2538,9 +2543,11 @@ sctp_generic_sendmsg_iov(td, uap)
|
||||
}
|
||||
}
|
||||
len = auio.uio_resid;
|
||||
CURVNET_SET(so->so_vnet);
|
||||
error = sctp_lower_sosend(so, to, &auio,
|
||||
(struct mbuf *)NULL, (struct mbuf *)NULL,
|
||||
uap->flags, use_rcvinfo, u_sinfo, td);
|
||||
CURVNET_RESTORE();
|
||||
if (error) {
|
||||
if (auio.uio_resid != len && (error == ERESTART ||
|
||||
error == EINTR || error == EWOULDBLOCK))
|
||||
@ -2660,9 +2667,11 @@ sctp_generic_recvmsg(td, uap)
|
||||
if (KTRPOINT(td, KTR_GENIO))
|
||||
ktruio = cloneuio(&auio);
|
||||
#endif /* KTRACE */
|
||||
CURVNET_SET(so->so_vnet);
|
||||
error = sctp_sorecvmsg(so, &auio, (struct mbuf **)NULL,
|
||||
fromsa, fromlen, &msg_flags,
|
||||
(struct sctp_sndrcvinfo *)&sinfo, 1);
|
||||
CURVNET_RESTORE();
|
||||
if (error) {
|
||||
if (auio.uio_resid != (int)len && (error == ERESTART ||
|
||||
error == EINTR || error == EWOULDBLOCK))
|
||||
|
@ -1497,7 +1497,11 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
|
||||
((struct sockaddr_dl *)rt->rt_gateway)->sdl_index =
|
||||
rt->rt_ifp->if_index;
|
||||
}
|
||||
RT_ADDREF(rt);
|
||||
RT_UNLOCK(rt);
|
||||
rt_newaddrmsg(cmd, ifa, error, rt);
|
||||
RT_LOCK(rt);
|
||||
RT_REMREF(rt);
|
||||
if (cmd == RTM_DELETE) {
|
||||
/*
|
||||
* If we are deleting, and we found an entry,
|
||||
|
@ -150,39 +150,42 @@ struct protosw inetsw[] = {
|
||||
},
|
||||
#ifdef SCTP
|
||||
{
|
||||
.pr_type = SOCK_DGRAM,
|
||||
.pr_domain = &inetdomain,
|
||||
.pr_protocol = IPPROTO_SCTP,
|
||||
.pr_flags = PR_WANTRCVD,
|
||||
.pr_input = sctp_input,
|
||||
.pr_ctlinput = sctp_ctlinput,
|
||||
.pr_ctloutput = sctp_ctloutput,
|
||||
.pr_init = sctp_init,
|
||||
.pr_drain = sctp_drain,
|
||||
.pr_usrreqs = &sctp_usrreqs
|
||||
.pr_type = SOCK_DGRAM,
|
||||
.pr_domain = &inetdomain,
|
||||
.pr_protocol = IPPROTO_SCTP,
|
||||
.pr_flags = PR_WANTRCVD,
|
||||
.pr_input = sctp_input,
|
||||
.pr_ctlinput = sctp_ctlinput,
|
||||
.pr_ctloutput = sctp_ctloutput,
|
||||
.pr_init = sctp_init,
|
||||
#ifdef VIMAGE
|
||||
.pr_destroy = sctp_finish,
|
||||
#endif
|
||||
.pr_drain = sctp_drain,
|
||||
.pr_usrreqs = &sctp_usrreqs
|
||||
},
|
||||
{
|
||||
.pr_type = SOCK_SEQPACKET,
|
||||
.pr_domain = &inetdomain,
|
||||
.pr_protocol = IPPROTO_SCTP,
|
||||
.pr_flags = PR_WANTRCVD,
|
||||
.pr_input = sctp_input,
|
||||
.pr_ctlinput = sctp_ctlinput,
|
||||
.pr_ctloutput = sctp_ctloutput,
|
||||
.pr_drain = sctp_drain,
|
||||
.pr_usrreqs = &sctp_usrreqs
|
||||
.pr_type = SOCK_SEQPACKET,
|
||||
.pr_domain = &inetdomain,
|
||||
.pr_protocol = IPPROTO_SCTP,
|
||||
.pr_flags = PR_WANTRCVD,
|
||||
.pr_input = sctp_input,
|
||||
.pr_ctlinput = sctp_ctlinput,
|
||||
.pr_ctloutput = sctp_ctloutput,
|
||||
.pr_drain = sctp_drain,
|
||||
.pr_usrreqs = &sctp_usrreqs
|
||||
},
|
||||
|
||||
{
|
||||
.pr_type = SOCK_STREAM,
|
||||
.pr_domain = &inetdomain,
|
||||
.pr_protocol = IPPROTO_SCTP,
|
||||
.pr_flags = PR_WANTRCVD,
|
||||
.pr_input = sctp_input,
|
||||
.pr_ctlinput = sctp_ctlinput,
|
||||
.pr_ctloutput = sctp_ctloutput,
|
||||
.pr_drain = sctp_drain,
|
||||
.pr_usrreqs = &sctp_usrreqs
|
||||
.pr_type = SOCK_STREAM,
|
||||
.pr_domain = &inetdomain,
|
||||
.pr_protocol = IPPROTO_SCTP,
|
||||
.pr_flags = PR_WANTRCVD,
|
||||
.pr_input = sctp_input,
|
||||
.pr_ctlinput = sctp_ctlinput,
|
||||
.pr_ctloutput = sctp_ctloutput,
|
||||
.pr_drain = sctp_drain,
|
||||
.pr_usrreqs = &sctp_usrreqs
|
||||
},
|
||||
#endif /* SCTP */
|
||||
{
|
||||
|
@ -881,7 +881,7 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
|
||||
/* we probably don't need these operations */
|
||||
(void)sa6_recoverscope(from6);
|
||||
sa6_embedscope(from6,
|
||||
MODULE_GLOBAL(MOD_INET6, ip6_use_defzone));
|
||||
MODULE_GLOBAL(ip6_use_defzone));
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -89,6 +89,7 @@ sctp_wakeup_iterator(void)
|
||||
static void
|
||||
sctp_iterator_thread(void *v)
|
||||
{
|
||||
CURVNET_SET((struct vnet *)v);
|
||||
SCTP_IPI_ITERATOR_WQ_LOCK();
|
||||
SCTP_BASE_INFO(iterator_running) = 0;
|
||||
while (1) {
|
||||
@ -96,10 +97,12 @@ sctp_iterator_thread(void *v)
|
||||
&SCTP_BASE_INFO(ipi_iterator_wq_mtx),
|
||||
0, "waiting_for_work", 0);
|
||||
if (SCTP_BASE_INFO(threads_must_exit)) {
|
||||
SCTP_IPI_ITERATOR_WQ_DESTROY();
|
||||
kthread_exit();
|
||||
}
|
||||
sctp_iterator_worker();
|
||||
}
|
||||
CURVNET_RESTORE();
|
||||
}
|
||||
|
||||
void
|
||||
@ -108,7 +111,7 @@ sctp_startup_iterator(void)
|
||||
int ret;
|
||||
|
||||
ret = kproc_create(sctp_iterator_thread,
|
||||
(void *)NULL,
|
||||
(void *)curvnet,
|
||||
&SCTP_BASE_INFO(thread_proc),
|
||||
RFPROC,
|
||||
SCTP_KTHREAD_PAGES,
|
||||
@ -126,7 +129,7 @@ sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa)
|
||||
|
||||
ifa6 = (struct in6_ifaddr *)ifa->ifa;
|
||||
ifa->flags = ifa6->ia6_flags;
|
||||
if (!MODULE_GLOBAL(MOD_INET6, ip6_use_deprecated)) {
|
||||
if (!MODULE_GLOBAL(ip6_use_deprecated)) {
|
||||
if (ifa->flags &
|
||||
IN6_IFF_DEPRECATED) {
|
||||
ifa->localifa_flags |= SCTP_ADDR_IFA_UNUSEABLE;
|
||||
@ -206,7 +209,8 @@ sctp_init_ifns_for_vrf(int vrfid)
|
||||
struct sctp_ifa *sctp_ifa;
|
||||
uint32_t ifa_flags;
|
||||
|
||||
TAILQ_FOREACH(ifn, &MODULE_GLOBAL(MOD_NET, ifnet), if_list) {
|
||||
IFNET_RLOCK();
|
||||
TAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_list) {
|
||||
IF_ADDR_LOCK(ifn);
|
||||
TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
|
||||
if (ifa->ifa_addr == NULL) {
|
||||
@ -251,6 +255,7 @@ sctp_init_ifns_for_vrf(int vrfid)
|
||||
}
|
||||
IF_ADDR_UNLOCK(ifn);
|
||||
}
|
||||
IFNET_RUNLOCK();
|
||||
}
|
||||
|
||||
void
|
||||
@ -336,7 +341,8 @@ void
|
||||
struct ifnet *ifn;
|
||||
struct ifaddr *ifa;
|
||||
|
||||
TAILQ_FOREACH(ifn, &MODULE_GLOBAL(MOD_NET, ifnet), if_list) {
|
||||
IFNET_RLOCK();
|
||||
TAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_list) {
|
||||
if (!(*pred) (ifn)) {
|
||||
continue;
|
||||
}
|
||||
@ -344,6 +350,7 @@ void
|
||||
sctp_addr_change(ifa, add ? RTM_ADD : RTM_DELETE);
|
||||
}
|
||||
}
|
||||
IFNET_RUNLOCK();
|
||||
}
|
||||
|
||||
struct mbuf *
|
||||
|
@ -87,10 +87,13 @@ __FBSDID("$FreeBSD$");
|
||||
/* #define SCTP_AUDITING_ENABLED 1 used for debug/auditing */
|
||||
#define SCTP_AUDIT_SIZE 256
|
||||
|
||||
/* temporary disabled since it does not work with VNET. */
|
||||
#if 0
|
||||
#define SCTP_USE_THREAD_BASED_ITERATOR 1
|
||||
#endif
|
||||
|
||||
#define SCTP_KTRHEAD_NAME "sctp_iterator"
|
||||
#define SCTP_KTHREAD_PAGES 2
|
||||
#define SCTP_KTHREAD_PAGES 0
|
||||
|
||||
|
||||
/* If you support Multi-VRF how big to
|
||||
|
@ -5876,7 +5876,7 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
|
||||
* idea, so I will leave it in place.
|
||||
*/
|
||||
if (inp && ipsec4_in_reject(m, &inp->ip_inp.inp)) {
|
||||
MODULE_GLOBAL(MOD_IPSEC, ipsec4stat).in_polvio++;
|
||||
MODULE_GLOBAL(ipsec4stat).in_polvio++;
|
||||
SCTP_STAT_INCR(sctps_hdrops);
|
||||
goto bad;
|
||||
}
|
||||
|
@ -78,10 +78,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet/ip_icmp.h>
|
||||
#include <netinet/icmp_var.h>
|
||||
|
||||
#ifdef VIMAGE
|
||||
#error "SCTP is not yet compatible with VIMAGE."
|
||||
#endif
|
||||
|
||||
#ifdef IPSEC
|
||||
#include <netipsec/ipsec.h>
|
||||
#include <netipsec/key.h>
|
||||
@ -137,25 +133,21 @@ MALLOC_DECLARE(SCTP_M_SOCKOPT);
|
||||
#define SCTP_CTR6 CTR6
|
||||
#endif
|
||||
|
||||
#define SCTP_BASE_INFO(__m) system_base_info.sctppcbinfo.__m
|
||||
#define SCTP_BASE_STATS system_base_info.sctpstat
|
||||
#define SCTP_BASE_STAT(__m) system_base_info.sctpstat.__m
|
||||
#define SCTP_BASE_SYSCTL(__m) system_base_info.sctpsysctl.__m
|
||||
#define SCTP_BASE_VAR(__m) system_base_info.__m
|
||||
|
||||
/*
|
||||
* Macros to expand out globals defined by various modules
|
||||
* to either a real global or a virtualized instance of one,
|
||||
* depending on whether VIMAGE is defined.
|
||||
*/
|
||||
/* first define modules that supply us information */
|
||||
#define MOD_NET net
|
||||
#define MOD_INET inet
|
||||
#define MOD_INET6 inet6
|
||||
#define MOD_IPSEC ipsec
|
||||
|
||||
/* then define the macro(s) that hook into the vimage macros */
|
||||
#define MODULE_GLOBAL(__MODULE, __SYMBOL) V_ ## __SYMBOL
|
||||
#define MODULE_GLOBAL(__SYMBOL) V_##__SYMBOL
|
||||
|
||||
#define V_system_base_info VNET(system_base_info)
|
||||
#define SCTP_BASE_INFO(__m) V_system_base_info.sctppcbinfo.__m
|
||||
#define SCTP_BASE_STATS V_system_base_info.sctpstat
|
||||
#define SCTP_BASE_STATS_SYSCTL VNET_NAME(system_base_info.sctpstat)
|
||||
#define SCTP_BASE_STAT(__m) V_system_base_info.sctpstat.__m
|
||||
#define SCTP_BASE_SYSCTL(__m) VNET_NAME(system_base_info.sctpsysctl.__m)
|
||||
#define SCTP_BASE_VAR(__m) V_system_base_info.__m
|
||||
|
||||
/*
|
||||
*
|
||||
@ -263,10 +255,9 @@ MALLOC_DECLARE(SCTP_M_SOCKOPT);
|
||||
/* SCTP_ZONE_INIT: initialize the zone */
|
||||
typedef struct uma_zone *sctp_zone_t;
|
||||
|
||||
#define UMA_ZFLAG_FULL 0x0020
|
||||
#define SCTP_ZONE_INIT(zone, name, size, number) { \
|
||||
zone = uma_zcreate(name, size, NULL, NULL, NULL, NULL, UMA_ALIGN_PTR,\
|
||||
UMA_ZFLAG_FULL); \
|
||||
0); \
|
||||
uma_zone_set_max(zone, number); \
|
||||
}
|
||||
|
||||
|
@ -3829,7 +3829,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
|
||||
sin6 = &tmp;
|
||||
|
||||
/* KAME hack: embed scopeid */
|
||||
if (sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)) != 0) {
|
||||
if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
|
||||
SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
@ -3883,7 +3883,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
|
||||
if (net->src_addr_selected == 0) {
|
||||
sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
|
||||
/* KAME hack: embed scopeid */
|
||||
if (sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)) != 0) {
|
||||
if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
|
||||
SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
@ -3906,7 +3906,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
|
||||
} else {
|
||||
sin6 = (struct sockaddr_in6 *)&ro->ro_dst;
|
||||
/* KAME hack: embed scopeid */
|
||||
if (sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)) != 0) {
|
||||
if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
|
||||
SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
@ -5143,7 +5143,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
*/
|
||||
(void)sa6_recoverscope(sin6);
|
||||
stc.scope_id = sin6->sin6_scope_id;
|
||||
sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone));
|
||||
sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone));
|
||||
stc.loopback_scope = 1;
|
||||
stc.local_scope = 0;
|
||||
stc.site_scope = 1;
|
||||
@ -5179,7 +5179,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
*/
|
||||
(void)sa6_recoverscope(sin6);
|
||||
stc.scope_id = sin6->sin6_scope_id;
|
||||
sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone));
|
||||
sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone));
|
||||
} else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
|
||||
/*
|
||||
* If the new destination is
|
||||
@ -10768,7 +10768,7 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh,
|
||||
|
||||
/* Fill in the IPv6 header for the ABORT */
|
||||
ip6_out->ip6_flow = ip6->ip6_flow;
|
||||
ip6_out->ip6_hlim = MODULE_GLOBAL(MOD_INET6, ip6_defhlim);
|
||||
ip6_out->ip6_hlim = MODULE_GLOBAL(ip6_defhlim);
|
||||
if (port) {
|
||||
ip6_out->ip6_nxt = IPPROTO_UDP;
|
||||
} else {
|
||||
@ -11787,7 +11787,7 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
|
||||
|
||||
/* Fill in the IP6 header for the ABORT */
|
||||
ip6_out->ip6_flow = ip6->ip6_flow;
|
||||
ip6_out->ip6_hlim = MODULE_GLOBAL(MOD_INET6, ip6_defhlim);
|
||||
ip6_out->ip6_hlim = MODULE_GLOBAL(ip6_defhlim);
|
||||
if (port) {
|
||||
ip6_out->ip6_nxt = IPPROTO_UDP;
|
||||
} else {
|
||||
@ -12014,7 +12014,7 @@ sctp_send_operr_to(struct mbuf *m, int iphlen, struct mbuf *scm, uint32_t vtag,
|
||||
|
||||
/* Fill in the IP6 header for the ABORT */
|
||||
ip6_out->ip6_flow = ip6->ip6_flow;
|
||||
ip6_out->ip6_hlim = MODULE_GLOBAL(MOD_INET6, ip6_defhlim);
|
||||
ip6_out->ip6_hlim = MODULE_GLOBAL(ip6_defhlim);
|
||||
if (port) {
|
||||
ip6_out->ip6_nxt = IPPROTO_UDP;
|
||||
} else {
|
||||
@ -13765,7 +13765,7 @@ sctp_v6src_match_nexthop(struct sockaddr_in6 *src6, sctp_route_t * ro)
|
||||
return (0);
|
||||
|
||||
/* get prefix entry of address */
|
||||
LIST_FOREACH(pfx, &MODULE_GLOBAL(MOD_INET6, nd_prefix), ndpr_entry) {
|
||||
LIST_FOREACH(pfx, &MODULE_GLOBAL(nd_prefix), ndpr_entry) {
|
||||
if (pfx->ndpr_stateflags & NDPRF_DETACHED)
|
||||
continue;
|
||||
if (IN6_ARE_MASKED_ADDR_EQUAL(&pfx->ndpr_prefix.sin6_addr,
|
||||
|
@ -48,7 +48,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet/udp.h>
|
||||
|
||||
|
||||
struct sctp_base_info system_base_info;
|
||||
VNET_DEFINE(struct sctp_base_info, system_base_info);
|
||||
|
||||
/* FIX: we don't handle multiple link local scopes */
|
||||
/* "scopeless" replacement IN6_ARE_ADDR_EQUAL */
|
||||
@ -59,11 +59,11 @@ SCTP6_ARE_ADDR_EQUAL(struct sockaddr_in6 *a, struct sockaddr_in6 *b)
|
||||
struct sockaddr_in6 tmp_a, tmp_b;
|
||||
|
||||
memcpy(&tmp_a, a, sizeof(struct sockaddr_in6));
|
||||
if (sa6_embedscope(&tmp_a, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)) != 0) {
|
||||
if (sa6_embedscope(&tmp_a, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
|
||||
return 0;
|
||||
}
|
||||
memcpy(&tmp_b, b, sizeof(struct sockaddr_in6));
|
||||
if (sa6_embedscope(&tmp_b, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)) != 0) {
|
||||
if (sa6_embedscope(&tmp_b, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
|
||||
return 0;
|
||||
}
|
||||
return (IN6_ARE_ADDR_EQUAL(&tmp_a.sin6_addr, &tmp_b.sin6_addr));
|
||||
@ -2008,7 +2008,7 @@ sctp_findassociation_addr(struct mbuf *m, int iphlen, int offset,
|
||||
/* Get the scopes in properly to the sin6 addr's */
|
||||
/* we probably don't need these operations */
|
||||
(void)sa6_recoverscope(from6);
|
||||
sa6_embedscope(from6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone));
|
||||
sa6_embedscope(from6, MODULE_GLOBAL(ip6_use_defzone));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@ -2049,7 +2049,7 @@ sctp_findassociation_addr(struct mbuf *m, int iphlen, int offset,
|
||||
/* Get the scopes in properly to the sin6 addr's */
|
||||
/* we probably don't need these operations */
|
||||
(void)sa6_recoverscope(to6);
|
||||
sa6_embedscope(to6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone));
|
||||
sa6_embedscope(to6, MODULE_GLOBAL(ip6_use_defzone));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@ -2316,7 +2316,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
|
||||
}
|
||||
#endif /* IPSEC */
|
||||
SCTP_INCR_EP_COUNT();
|
||||
inp->ip_inp.inp.inp_ip_ttl = MODULE_GLOBAL(MOD_INET, ip_defttl);
|
||||
inp->ip_inp.inp.inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
|
||||
SCTP_INP_INFO_WUNLOCK();
|
||||
|
||||
so->so_pcb = (caddr_t)inp;
|
||||
@ -2688,7 +2688,7 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
|
||||
if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
||||
bindall = 0;
|
||||
/* KAME hack: embed scopeid */
|
||||
if (sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)) != 0) {
|
||||
if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
@ -2814,8 +2814,8 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
|
||||
int done;
|
||||
|
||||
if (ip_inp->inp_flags & INP_HIGHPORT) {
|
||||
first = MODULE_GLOBAL(MOD_INET, ipport_hifirstauto);
|
||||
last = MODULE_GLOBAL(MOD_INET, ipport_hilastauto);
|
||||
first = MODULE_GLOBAL(ipport_hifirstauto);
|
||||
last = MODULE_GLOBAL(ipport_hilastauto);
|
||||
} else if (ip_inp->inp_flags & INP_LOWPORT) {
|
||||
if (p && (error =
|
||||
priv_check(p, PRIV_NETINET_RESERVEDPORT)
|
||||
@ -2826,11 +2826,11 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
|
||||
return (error);
|
||||
}
|
||||
first = MODULE_GLOBAL(MOD_INET, ipport_lowfirstauto);
|
||||
last = MODULE_GLOBAL(MOD_INET, ipport_lowlastauto);
|
||||
first = MODULE_GLOBAL(ipport_lowfirstauto);
|
||||
last = MODULE_GLOBAL(ipport_lowlastauto);
|
||||
} else {
|
||||
first = MODULE_GLOBAL(MOD_INET, ipport_firstauto);
|
||||
last = MODULE_GLOBAL(MOD_INET, ipport_lastauto);
|
||||
first = MODULE_GLOBAL(ipport_firstauto);
|
||||
last = MODULE_GLOBAL(ipport_lastauto);
|
||||
}
|
||||
if (first > last) {
|
||||
uint16_t temp;
|
||||
@ -3756,7 +3756,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
|
||||
(void)sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone));
|
||||
(void)sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone));
|
||||
sin6->sin6_scope_id = 0;
|
||||
}
|
||||
#endif
|
||||
@ -5558,36 +5558,54 @@ sctp_pcb_finish(void)
|
||||
struct sctp_ifa *ifa;
|
||||
struct sctpvtaghead *chain;
|
||||
struct sctp_tagblock *twait_block, *prev_twait_block;
|
||||
struct sctp_laddr *wi;
|
||||
struct sctp_iterator *it;
|
||||
int i;
|
||||
|
||||
#if defined(SCTP_USE_THREAD_BASED_ITERATOR)
|
||||
SCTP_BASE_INFO(threads_must_exit) = 1;
|
||||
/* Wake the thread up so it will exit now */
|
||||
sctp_wakeup_iterator();
|
||||
|
||||
#endif
|
||||
SCTP_OS_TIMER_STOP(&SCTP_BASE_INFO(addr_wq_timer.timer));
|
||||
SCTP_IPI_ITERATOR_WQ_LOCK();
|
||||
while ((wi = LIST_FIRST(&SCTP_BASE_INFO(addr_wq))) != NULL) {
|
||||
LIST_REMOVE(wi, sctp_nxt_addr);
|
||||
SCTP_DECR_LADDR_COUNT();
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), wi);
|
||||
}
|
||||
SCTP_IPI_ITERATOR_WQ_UNLOCK();
|
||||
while ((it = TAILQ_FIRST(&SCTP_BASE_INFO(iteratorhead))) != NULL) {
|
||||
if (it->function_atend != NULL) {
|
||||
(*it->function_atend) (it->pointer, it->val);
|
||||
}
|
||||
TAILQ_REMOVE(&SCTP_BASE_INFO(iteratorhead), it, sctp_nxt_itr);
|
||||
SCTP_FREE(it, SCTP_M_ITER);
|
||||
}
|
||||
|
||||
/*
|
||||
* free the vrf/ifn/ifa lists and hashes (be sure address monitor is
|
||||
* destroyed first).
|
||||
*/
|
||||
vrf_bucket = &SCTP_BASE_INFO(sctp_vrfhash)[(SCTP_DEFAULT_VRFID & SCTP_BASE_INFO(hashvrfmark))];
|
||||
vrf = LIST_FIRST(vrf_bucket);
|
||||
while (vrf) {
|
||||
ifn = LIST_FIRST(&vrf->ifnlist);
|
||||
while (ifn) {
|
||||
ifa = LIST_FIRST(&ifn->ifalist);
|
||||
while (ifa) {
|
||||
while ((vrf = LIST_FIRST(vrf_bucket)) != NULL) {
|
||||
while ((ifn = LIST_FIRST(&vrf->ifnlist)) != NULL) {
|
||||
while ((ifa = LIST_FIRST(&ifn->ifalist)) != NULL) {
|
||||
/* free the ifa */
|
||||
LIST_REMOVE(ifa, next_bucket);
|
||||
LIST_REMOVE(ifa, next_ifa);
|
||||
SCTP_FREE(ifa, SCTP_M_IFA);
|
||||
ifa = LIST_FIRST(&ifn->ifalist);
|
||||
}
|
||||
/* free the ifn */
|
||||
LIST_REMOVE(ifn, next_bucket);
|
||||
LIST_REMOVE(ifn, next_ifn);
|
||||
SCTP_FREE(ifn, SCTP_M_IFN);
|
||||
ifn = LIST_FIRST(&vrf->ifnlist);
|
||||
}
|
||||
SCTP_HASH_FREE(vrf->vrf_addr_hash, vrf->vrf_addr_hashmark);
|
||||
/* free the vrf */
|
||||
LIST_REMOVE(vrf, next_vrf);
|
||||
SCTP_FREE(vrf, SCTP_M_VRF);
|
||||
vrf = LIST_FIRST(vrf_bucket);
|
||||
}
|
||||
/* free the vrf hashes */
|
||||
SCTP_HASH_FREE(SCTP_BASE_INFO(sctp_vrfhash), SCTP_BASE_INFO(hashvrfmark));
|
||||
@ -5614,9 +5632,7 @@ sctp_pcb_finish(void)
|
||||
/* free the locks and mutexes */
|
||||
#ifdef SCTP_PACKET_LOGGING
|
||||
SCTP_IP_PKTLOG_DESTROY();
|
||||
|
||||
#endif
|
||||
SCTP_IPI_ITERATOR_WQ_DESTROY();
|
||||
SCTP_IPI_ADDR_DESTROY();
|
||||
SCTP_ITERATOR_LOCK_DESTROY();
|
||||
SCTP_STATLOG_DESTROY();
|
||||
@ -6422,10 +6438,6 @@ sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
|
||||
|
||||
/* We look for anything larger than the cum-ack + 1 */
|
||||
|
||||
SCTP_STAT_INCR(sctps_protocol_drain_calls);
|
||||
if (SCTP_BASE_SYSCTL(sctp_do_drain) == 0) {
|
||||
return;
|
||||
}
|
||||
asoc = &stcb->asoc;
|
||||
if (asoc->cumulative_tsn == asoc->highest_tsn_inside_map) {
|
||||
/* none we can reneg on. */
|
||||
@ -6588,22 +6600,37 @@ sctp_drain()
|
||||
* is LOW on MBUF's and needs help. This is where reneging will
|
||||
* occur. We really hope this does NOT happen!
|
||||
*/
|
||||
struct sctp_inpcb *inp;
|
||||
struct sctp_tcb *stcb;
|
||||
VNET_ITERATOR_DECL(vnet_iter);
|
||||
VNET_LIST_RLOCK_NOSLEEP();
|
||||
VNET_FOREACH(vnet_iter) {
|
||||
CURVNET_SET(vnet_iter);
|
||||
struct sctp_inpcb *inp;
|
||||
struct sctp_tcb *stcb;
|
||||
|
||||
SCTP_INP_INFO_RLOCK();
|
||||
LIST_FOREACH(inp, &SCTP_BASE_INFO(listhead), sctp_list) {
|
||||
/* For each endpoint */
|
||||
SCTP_INP_RLOCK(inp);
|
||||
LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
|
||||
/* For each association */
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
sctp_drain_mbufs(inp, stcb);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
SCTP_STAT_INCR(sctps_protocol_drain_calls);
|
||||
if (SCTP_BASE_SYSCTL(sctp_do_drain) == 0) {
|
||||
#ifdef VIMAGE
|
||||
continue;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
SCTP_INP_INFO_RLOCK();
|
||||
LIST_FOREACH(inp, &SCTP_BASE_INFO(listhead), sctp_list) {
|
||||
/* For each endpoint */
|
||||
SCTP_INP_RLOCK(inp);
|
||||
LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
|
||||
/* For each association */
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
sctp_drain_mbufs(inp, stcb);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
}
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
}
|
||||
SCTP_INP_INFO_RUNLOCK();
|
||||
CURVNET_RESTORE();
|
||||
}
|
||||
SCTP_INP_INFO_RUNLOCK();
|
||||
VNET_LIST_RUNLOCK_NOSLEEP();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -462,7 +462,7 @@ struct sctp_tcb {
|
||||
* goes with the base info. sctp_pcb.c has
|
||||
* the real definition.
|
||||
*/
|
||||
extern struct sctp_base_info system_base_info;
|
||||
VNET_DECLARE(struct sctp_base_info, system_base_info);
|
||||
|
||||
#ifdef INET6
|
||||
int SCTP6_ARE_ADDR_EQUAL(struct sockaddr_in6 *a, struct sockaddr_in6 *b);
|
||||
|
@ -51,6 +51,7 @@ struct sctp_timer {
|
||||
void *ep;
|
||||
void *tcb;
|
||||
void *net;
|
||||
void *vnet;
|
||||
|
||||
/* for sanity checking */
|
||||
void *self;
|
||||
|
@ -930,7 +930,7 @@ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, output_unlocked, CTLTYPE_INT | CTLFLAG_RW,
|
||||
#endif
|
||||
|
||||
SYSCTL_STRUCT(_net_inet_sctp, OID_AUTO, stats, CTLFLAG_RW,
|
||||
&SCTP_BASE_STATS, sctpstat,
|
||||
&SCTP_BASE_STATS_SYSCTL, sctpstat,
|
||||
"SCTP statistics (struct sctp_stat)");
|
||||
|
||||
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, assoclist, CTLFLAG_RD,
|
||||
|
@ -1773,7 +1773,7 @@ sctp_pathmtu_timer(struct sctp_inpcb *inp,
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
|
||||
|
||||
/* KAME hack: embed scopeid */
|
||||
(void)sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone));
|
||||
(void)sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -544,7 +544,7 @@ sctp_attach(struct socket *so, int proto, struct thread *p)
|
||||
inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUND_V6; /* I'm not v6! */
|
||||
ip_inp = &inp->ip_inp.inp;
|
||||
ip_inp->inp_vflag |= INP_IPV4;
|
||||
ip_inp->inp_ip_ttl = MODULE_GLOBAL(MOD_INET, ip_defttl);
|
||||
ip_inp->inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
|
||||
#ifdef IPSEC
|
||||
error = ipsec_init_policy(so, &ip_inp->inp_sp);
|
||||
#ifdef SCTP_LOG_CLOSING
|
||||
|
@ -1446,6 +1446,7 @@ sctp_timeout_handler(void *t)
|
||||
inp = (struct sctp_inpcb *)tmr->ep;
|
||||
stcb = (struct sctp_tcb *)tmr->tcb;
|
||||
net = (struct sctp_nets *)tmr->net;
|
||||
CURVNET_SET((struct vnet *)tmr->vnet);
|
||||
did_output = 1;
|
||||
|
||||
#ifdef SCTP_AUDITING_ENABLED
|
||||
@ -1459,6 +1460,7 @@ sctp_timeout_handler(void *t)
|
||||
* SCTP_PRINTF("Stale SCTP timer fired (%p), ignoring...\n",
|
||||
* tmr);
|
||||
*/
|
||||
CURVNET_RESTORE();
|
||||
return;
|
||||
}
|
||||
tmr->stopped_from = 0xa001;
|
||||
@ -1467,10 +1469,12 @@ sctp_timeout_handler(void *t)
|
||||
* SCTP_PRINTF("SCTP timer fired with invalid type: 0x%x\n",
|
||||
* tmr->type);
|
||||
*/
|
||||
CURVNET_RESTORE();
|
||||
return;
|
||||
}
|
||||
tmr->stopped_from = 0xa002;
|
||||
if ((tmr->type != SCTP_TIMER_TYPE_ADDR_WQ) && (inp == NULL)) {
|
||||
CURVNET_RESTORE();
|
||||
return;
|
||||
}
|
||||
/* if this is an iterator timeout, get the struct and clear inp */
|
||||
@ -1494,6 +1498,7 @@ sctp_timeout_handler(void *t)
|
||||
(tmr->type != SCTP_TIMER_TYPE_ASOCKILL))
|
||||
) {
|
||||
SCTP_INP_DECR_REF(inp);
|
||||
CURVNET_RESTORE();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1505,6 +1510,7 @@ sctp_timeout_handler(void *t)
|
||||
if (inp) {
|
||||
SCTP_INP_DECR_REF(inp);
|
||||
}
|
||||
CURVNET_RESTORE();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1517,6 +1523,7 @@ sctp_timeout_handler(void *t)
|
||||
if (stcb) {
|
||||
atomic_add_int(&stcb->asoc.refcnt, -1);
|
||||
}
|
||||
CURVNET_RESTORE();
|
||||
return;
|
||||
}
|
||||
tmr->stopped_from = 0xa006;
|
||||
@ -1531,6 +1538,7 @@ sctp_timeout_handler(void *t)
|
||||
if (inp) {
|
||||
SCTP_INP_DECR_REF(inp);
|
||||
}
|
||||
CURVNET_RESTORE();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1903,6 +1911,7 @@ sctp_timeout_handler(void *t)
|
||||
out_no_decr:
|
||||
SCTPDBG(SCTP_DEBUG_TIMER1, "Timer now complete (type %d)\n",
|
||||
type);
|
||||
CURVNET_RESTORE();
|
||||
}
|
||||
|
||||
void
|
||||
@ -2263,6 +2272,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
tmr->tcb = (void *)stcb;
|
||||
tmr->net = (void *)net;
|
||||
tmr->self = (void *)tmr;
|
||||
tmr->vnet = (void *)curvnet;
|
||||
tmr->ticks = sctp_get_tick_count();
|
||||
(void)SCTP_OS_TIMER_START(&tmr->timer, to_ticks, sctp_timeout_handler, tmr);
|
||||
return;
|
||||
|
@ -223,7 +223,7 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
|
||||
*/
|
||||
if (in6p_ip && (ipsec6_in_reject(m, in6p_ip))) {
|
||||
/* XXX */
|
||||
MODULE_GLOBAL(MOD_IPSEC, ipsec6stat).in_polvio++;
|
||||
MODULE_GLOBAL(ipsec6stat).in_polvio++;
|
||||
goto bad;
|
||||
}
|
||||
#endif /* IPSEC */
|
||||
@ -695,7 +695,7 @@ sctp6_attach(struct socket *so, int proto, struct thread *p)
|
||||
* socket as well, because the socket may be bound to an IPv6
|
||||
* wildcard address, which may match an IPv4-mapped IPv6 address.
|
||||
*/
|
||||
inp6->inp_ip_ttl = MODULE_GLOBAL(MOD_INET, ip_defttl);
|
||||
inp6->inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
|
||||
#endif
|
||||
/*
|
||||
* Hmm what about the IPSEC stuff that is missing here but in
|
||||
@ -859,7 +859,7 @@ sctp6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
|
||||
}
|
||||
}
|
||||
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
|
||||
if (!MODULE_GLOBAL(MOD_INET6, ip6_v6only)) {
|
||||
if (!MODULE_GLOBAL(ip6_v6only)) {
|
||||
struct sockaddr_in sin;
|
||||
|
||||
/* convert v4-mapped into v4 addr and send */
|
||||
@ -990,7 +990,7 @@ sctp6_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
|
||||
}
|
||||
}
|
||||
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
|
||||
if (!MODULE_GLOBAL(MOD_INET6, ip6_v6only)) {
|
||||
if (!MODULE_GLOBAL(ip6_v6only)) {
|
||||
/* convert v4-mapped into v4 addr */
|
||||
in6_sin6_2_sin((struct sockaddr_in *)&ss, sin6);
|
||||
addr = (struct sockaddr *)&ss;
|
||||
|
Loading…
Reference in New Issue
Block a user