From owner-svn-src-all@FreeBSD.ORG Sun Feb 10 19:57:20 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 2F30B350; Sun, 10 Feb 2013 19:57:20 +0000 (UTC) (envelope-from tuexen@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 20D6DF3D; Sun, 10 Feb 2013 19:57:20 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r1AJvJhn089911; Sun, 10 Feb 2013 19:57:19 GMT (envelope-from tuexen@svn.freebsd.org) Received: (from tuexen@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id r1AJvJkw089910; Sun, 10 Feb 2013 19:57:19 GMT (envelope-from tuexen@svn.freebsd.org) Message-Id: <201302101957.r1AJvJkw089910@svn.freebsd.org> From: Michael Tuexen Date: Sun, 10 Feb 2013 19:57:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r246635 - head/sys/netinet X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Feb 2013 19:57:20 -0000 Author: tuexen Date: Sun Feb 10 19:57:19 2013 New Revision: 246635 URL: http://svnweb.freebsd.org/changeset/base/246635 Log: Make sure that received packets for removed addresses are handled consistently. While there, make variable names consistent. MFC after: 3 days Modified: head/sys/netinet/sctp_pcb.c Modified: head/sys/netinet/sctp_pcb.c ============================================================================== --- head/sys/netinet/sctp_pcb.c Sun Feb 10 19:49:37 2013 (r246634) +++ head/sys/netinet/sctp_pcb.c Sun Feb 10 19:57:19 2013 (r246635) @@ -824,6 +824,160 @@ out_now: } +static int +sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to) +{ + int loopback_scope, ipv4_local_scope, local_scope, site_scope; + int ipv4_addr_legal, ipv6_addr_legal; + struct sctp_vrf *vrf; + struct sctp_ifn *sctp_ifn; + struct sctp_ifa *sctp_ifa; + + loopback_scope = stcb->asoc.scope.loopback_scope; + ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope; + local_scope = stcb->asoc.scope.local_scope; + site_scope = stcb->asoc.scope.site_scope; + ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal; + ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal; + + SCTP_IPI_ADDR_RLOCK(); + vrf = sctp_find_vrf(stcb->asoc.vrf_id); + if (vrf == NULL) { + /* no vrf, no addresses */ + SCTP_IPI_ADDR_RUNLOCK(); + return (0); + } + if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { + LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) { + if ((loopback_scope == 0) && + SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) { + continue; + } + LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { + if (sctp_is_addr_restricted(stcb, sctp_ifa) && + (!sctp_is_addr_pending(stcb, sctp_ifa))) { + /* + * We allow pending addresses, where + * we have sent an asconf-add to be + * considered valid. + */ + continue; + } + switch (sctp_ifa->address.sa.sa_family) { +#ifdef INET + case AF_INET: + if (ipv4_addr_legal) { + struct sockaddr_in *sin, + *rsin; + + sin = &sctp_ifa->address.sin; + rsin = (struct sockaddr_in *)to; + if ((ipv4_local_scope == 0) && + IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) { + continue; + } + if (sin->sin_addr.s_addr == rsin->sin_addr.s_addr) { + SCTP_IPI_ADDR_RUNLOCK(); + return (1); + } + } + break; +#endif +#ifdef INET6 + case AF_INET6: + if (ipv6_addr_legal) { + struct sockaddr_in6 *sin6, + *rsin6; + + sin6 = &sctp_ifa->address.sin6; + rsin6 = (struct sockaddr_in6 *)to; + if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { + if (local_scope == 0) + continue; + if (sin6->sin6_scope_id == 0) { + if (sa6_recoverscope(sin6) != 0) + continue; + } + } + if ((site_scope == 0) && + (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) { + continue; + } + if (SCTP6_ARE_ADDR_EQUAL(sin6, rsin6)) { + SCTP_IPI_ADDR_RUNLOCK(); + return (1); + } + } + break; +#endif + default: + /* TSNH */ + break; + } + } + } + } else { + struct sctp_laddr *laddr; + + LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) { + if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) { + SCTPDBG(SCTP_DEBUG_PCB1, "ifa being deleted\n"); + continue; + } + if (sctp_is_addr_restricted(stcb, laddr->ifa) && + (!sctp_is_addr_pending(stcb, laddr->ifa))) { + /* + * We allow pending addresses, where we have + * sent an asconf-add to be considered + * valid. + */ + continue; + } + if (laddr->ifa->address.sa.sa_family != to->sa_family) { + continue; + } + switch (to->sa_family) { +#ifdef INET + case AF_INET: + { + struct sockaddr_in *sin, *rsin; + + sin = (struct sockaddr_in *)&laddr->ifa->address.sin; + rsin = (struct sockaddr_in *)to; + if (sin->sin_addr.s_addr == rsin->sin_addr.s_addr) { + SCTP_IPI_ADDR_RUNLOCK(); + return (1); + } + break; + } +#endif +#ifdef INET6 + case AF_INET6: + { + struct sockaddr_in6 *sin6, *rsin6; + + sin6 = (struct sockaddr_in6 *)&laddr->ifa->address.sin6; + rsin6 = (struct sockaddr_in6 *)to; + if (SCTP6_ARE_ADDR_EQUAL(sin6, rsin6)) { + SCTP_IPI_ADDR_RUNLOCK(); + return (1); + } + break; + } + +#endif + default: + /* TSNH */ + break; + } + + } + } + SCTP_IPI_ADDR_RUNLOCK(); + return (0); +} + + static struct sctp_tcb * sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from, struct sockaddr *to, struct sctp_nets **netp, uint32_t vrf_id) @@ -906,7 +1060,6 @@ sctp_tcb_special_locate(struct sctp_inpc if (laddr->ifa->address.sa.sa_family == to->sa_family) { /* see if it matches */ - #ifdef INET if (from->sa_family == AF_INET) { struct sockaddr_in *intf_addr, @@ -949,13 +1102,18 @@ sctp_tcb_special_locate(struct sctp_inpc * Ok if we hit here the ep has the address, does it hold * the tcb? */ - + /* XXX: Why don't we TAILQ_FOREACH through sctp_asoc_list? */ stcb = LIST_FIRST(&inp->sctp_asoc_list); if (stcb == NULL) { SCTP_INP_RUNLOCK(inp); continue; } SCTP_TCB_LOCK(stcb); + if (!sctp_does_stcb_own_this_addr(stcb, to)) { + SCTP_TCB_UNLOCK(stcb); + SCTP_INP_RUNLOCK(inp); + continue; + } if (stcb->rport != rport) { /* remote port does not match. */ SCTP_TCB_UNLOCK(stcb); @@ -967,6 +1125,11 @@ sctp_tcb_special_locate(struct sctp_inpc SCTP_INP_RUNLOCK(inp); continue; } + if (!sctp_does_stcb_own_this_addr(stcb, to)) { + SCTP_TCB_UNLOCK(stcb); + SCTP_INP_RUNLOCK(inp); + continue; + } /* Does this TCB have a matching address? */ TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { @@ -1035,156 +1198,6 @@ sctp_tcb_special_locate(struct sctp_inpc } -static int -sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to) -{ - int loopback_scope, ipv4_local_scope, local_scope, site_scope; - int ipv4_addr_legal, ipv6_addr_legal; - struct sctp_vrf *vrf; - struct sctp_ifn *sctp_ifn; - struct sctp_ifa *sctp_ifa; - - loopback_scope = stcb->asoc.scope.loopback_scope; - ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope; - local_scope = stcb->asoc.scope.local_scope; - site_scope = stcb->asoc.scope.site_scope; - ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal; - ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal; - - SCTP_IPI_ADDR_RLOCK(); - vrf = sctp_find_vrf(stcb->asoc.vrf_id); - if (vrf == NULL) { - /* no vrf, no addresses */ - SCTP_IPI_ADDR_RUNLOCK(); - return (0); - } - if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { - LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) { - if ((loopback_scope == 0) && - SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) { - continue; - } - LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { - if (sctp_is_addr_restricted(stcb, sctp_ifa) && - (!sctp_is_addr_pending(stcb, sctp_ifa))) { - /* - * We allow pending addresses, where - * we have sent an asconf-add to be - * considered valid. - */ - continue; - } - switch (sctp_ifa->address.sa.sa_family) { -#ifdef INET - case AF_INET: - if (ipv4_addr_legal) { - struct sockaddr_in *sin, - *rsin; - - sin = &sctp_ifa->address.sin; - rsin = (struct sockaddr_in *)to; - if ((ipv4_local_scope == 0) && - IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) { - continue; - } - if (sin->sin_addr.s_addr == rsin->sin_addr.s_addr) { - SCTP_IPI_ADDR_RUNLOCK(); - return (1); - } - } - break; -#endif -#ifdef INET6 - case AF_INET6: - if (ipv6_addr_legal) { - struct sockaddr_in6 *sin6, - *rsin6; - - sin6 = &sctp_ifa->address.sin6; - rsin6 = (struct sockaddr_in6 *)to; - if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { - if (local_scope == 0) - continue; - if (sin6->sin6_scope_id == 0) { - if (sa6_recoverscope(sin6) != 0) - continue; - } - } - if ((site_scope == 0) && - (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) { - continue; - } - if (SCTP6_ARE_ADDR_EQUAL(sin6, rsin6)) { - SCTP_IPI_ADDR_RUNLOCK(); - return (1); - } - } - break; -#endif - default: - /* TSNH */ - break; - } - } - } - } else { - struct sctp_laddr *laddr; - - LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) { - if (sctp_is_addr_restricted(stcb, laddr->ifa) && - (!sctp_is_addr_pending(stcb, laddr->ifa))) { - /* - * We allow pending addresses, where we have - * sent an asconf-add to be considered - * valid. - */ - continue; - } - if (laddr->ifa->address.sa.sa_family != to->sa_family) { - continue; - } - switch (to->sa_family) { -#ifdef INET - case AF_INET: - { - struct sockaddr_in *sin, *rsin; - - sin = (struct sockaddr_in *)&laddr->ifa->address.sin; - rsin = (struct sockaddr_in *)to; - if (sin->sin_addr.s_addr == rsin->sin_addr.s_addr) { - SCTP_IPI_ADDR_RUNLOCK(); - return (1); - } - break; - } -#endif -#ifdef INET6 - case AF_INET6: - { - struct sockaddr_in6 *sin6, *rsin6; - - sin6 = (struct sockaddr_in6 *)&laddr->ifa->address.sin6; - rsin6 = (struct sockaddr_in6 *)to; - if (SCTP6_ARE_ADDR_EQUAL(sin6, rsin6)) { - SCTP_IPI_ADDR_RUNLOCK(); - return (1); - } - break; - } - -#endif - default: - /* TSNH */ - break; - } - - } - } - SCTP_IPI_ADDR_RUNLOCK(); - return (0); -} - - /* * rules for use * @@ -1906,20 +1919,20 @@ sctp_findassociation_addr_sa(struct sock uint32_t vrf_id) { struct sctp_inpcb *inp = NULL; - struct sctp_tcb *retval; + struct sctp_tcb *stcb; SCTP_INP_INFO_RLOCK(); if (find_tcp_pool) { if (inp_p != NULL) { - retval = sctp_tcb_special_locate(inp_p, from, to, netp, + stcb = sctp_tcb_special_locate(inp_p, from, to, netp, vrf_id); } else { - retval = sctp_tcb_special_locate(&inp, from, to, netp, + stcb = sctp_tcb_special_locate(&inp, from, to, netp, vrf_id); } - if (retval != NULL) { + if (stcb != NULL) { SCTP_INP_INFO_RUNLOCK(); - return (retval); + return (stcb); } } inp = sctp_pcb_findep(to, 0, 1, vrf_id); @@ -1927,7 +1940,6 @@ sctp_findassociation_addr_sa(struct sock *inp_p = inp; } SCTP_INP_INFO_RUNLOCK(); - if (inp == NULL) { return (NULL); } @@ -1938,13 +1950,13 @@ sctp_findassociation_addr_sa(struct sock * inbound packet side. */ if (inp_p != NULL) { - retval = sctp_findassociation_ep_addr(inp_p, from, netp, to, + stcb = sctp_findassociation_ep_addr(inp_p, from, netp, to, NULL); } else { - retval = sctp_findassociation_ep_addr(&inp, from, netp, to, + stcb = sctp_findassociation_ep_addr(&inp, from, netp, to, NULL); } - return retval; + return (stcb); } @@ -1959,7 +1971,7 @@ sctp_findassociation_special_addr(struct struct sockaddr *dst) { struct sctp_paramhdr *phdr, parm_buf; - struct sctp_tcb *retval; + struct sctp_tcb *stcb; uint32_t ptype, plen; #ifdef INET @@ -1984,7 +1996,7 @@ sctp_findassociation_special_addr(struct sin6.sin6_port = sh->src_port; #endif - retval = NULL; + stcb = NULL; offset += sizeof(struct sctp_init_chunk); phdr = sctp_get_next_param(m, offset, &parm_buf, sizeof(parm_buf)); @@ -2009,10 +2021,10 @@ sctp_findassociation_special_addr(struct p4 = (struct sctp_ipv4addr_param *)phdr; memcpy(&sin4.sin_addr, &p4->addr, sizeof(p4->addr)); /* look it up */ - retval = sctp_findassociation_ep_addr(inp_p, + stcb = sctp_findassociation_ep_addr(inp_p, (struct sockaddr *)&sin4, netp, dst, NULL); - if (retval != NULL) { - return (retval); + if (stcb != NULL) { + return (stcb); } } #endif @@ -2030,10 +2042,10 @@ sctp_findassociation_special_addr(struct p6 = (struct sctp_ipv6addr_param *)phdr; memcpy(&sin6.sin6_addr, &p6->addr, sizeof(p6->addr)); /* look it up */ - retval = sctp_findassociation_ep_addr(inp_p, + stcb = sctp_findassociation_ep_addr(inp_p, (struct sockaddr *)&sin6, netp, dst, NULL); - if (retval != NULL) { - return (retval); + if (stcb != NULL) { + return (stcb); } } #endif @@ -2158,15 +2170,15 @@ sctp_findassociation_addr(struct mbuf *m struct sctp_inpcb **inp_p, struct sctp_nets **netp, uint32_t vrf_id) { int find_tcp_pool; - struct sctp_tcb *retval; + struct sctp_tcb *stcb; struct sctp_inpcb *inp; if (sh->v_tag) { /* we only go down this path if vtag is non-zero */ - retval = sctp_findassoc_by_vtag(src, dst, ntohl(sh->v_tag), + stcb = sctp_findassoc_by_vtag(src, dst, ntohl(sh->v_tag), inp_p, netp, sh->src_port, sh->dest_port, 0, vrf_id, 0); - if (retval) { - return (retval); + if (stcb) { + return (stcb); } } find_tcp_pool = 0; @@ -2178,15 +2190,15 @@ sctp_findassociation_addr(struct mbuf *m find_tcp_pool = 1; } if (inp_p) { - retval = sctp_findassociation_addr_sa(src, dst, inp_p, netp, + stcb = sctp_findassociation_addr_sa(src, dst, inp_p, netp, find_tcp_pool, vrf_id); inp = *inp_p; } else { - retval = sctp_findassociation_addr_sa(src, dst, &inp, netp, + stcb = sctp_findassociation_addr_sa(src, dst, &inp, netp, find_tcp_pool, vrf_id); } - SCTPDBG(SCTP_DEBUG_PCB1, "retval:%p inp:%p\n", (void *)retval, (void *)inp); - if (retval == NULL && inp) { + SCTPDBG(SCTP_DEBUG_PCB1, "stcb:%p inp:%p\n", (void *)stcb, (void *)inp); + if (stcb == NULL && inp) { /* Found a EP but not this address */ if ((ch->chunk_type == SCTP_INITIATION) || (ch->chunk_type == SCTP_INITIATION_ACK)) { @@ -2204,15 +2216,15 @@ sctp_findassociation_addr(struct mbuf *m } return (NULL); } - retval = sctp_findassociation_special_addr(m, + stcb = sctp_findassociation_special_addr(m, offset, sh, &inp, netp, dst); if (inp_p != NULL) { *inp_p = inp; } } } - SCTPDBG(SCTP_DEBUG_PCB1, "retval is %p\n", (void *)retval); - return (retval); + SCTPDBG(SCTP_DEBUG_PCB1, "stcb is %p\n", (void *)stcb); + return (stcb); } /*