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);
 }
 
 /*
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to