On May 14, 2011, at 6:22 PM, Michael Tuexen wrote:

> Author: tuexen
> Date: Sat May 14 18:22:14 2011
> New Revision: 221904
> URL: http://svn.freebsd.org/changeset/base/221904
> 
> Log:
>  Fix the source address selection for boundall sockets
>  when sending INITs to a global IPv4 address having
>  only private IPv4 address.
>  Allow the usage of a private address and make sure
>  that no other private address will be used by the
>  association.
>  Initial work was done by rrs@.
> 
>  MFC after: 1 week.
> 
> Modified:
>  head/sys/netinet/sctp_output.c
>  head/sys/netinet/sctp_output.h
> 
> Modified: head/sys/netinet/sctp_output.c
> ==============================================================================
> --- head/sys/netinet/sctp_output.c    Sat May 14 18:22:08 2011        
> (r221903)
> +++ head/sys/netinet/sctp_output.c    Sat May 14 18:22:14 2011        
> (r221904)

...

> @@ -3068,19 +3112,81 @@ plan_d:
>                                        * It is restricted for some
>                                        * reason.. probably not yet added.
>                                        */
> +                                     sifa = NULL;
>                                       continue;
>                               }
>                       }
> -                     atomic_add_int(&sifa->refcount, 1);
> -                     return (sifa);
> +                     goto out;
>               }
>       }
> -     /*
> -      * Ok we can find NO address to source from that is not on our
> -      * restricted list and non_asoc_address is NOT ok, or it is on our
> -      * restricted list. We can't source to it :-(
> -      */
> -     return (NULL);
> +#ifdef INET
> +     if ((retried == 0) && (stcb->asoc.ipv4_local_scope == 0)) {
> +             stcb->asoc.ipv4_local_scope = 1;
> +             retried = 1;
> +             goto again_with_private_addresses_allowed;
> +     } else if (retried == 1) {
> +             stcb->asoc.ipv4_local_scope = 0;
> +     }
> +#endif
> +out:
> +     if (sifa) {
> +#ifdef INET

either this needs to go outside the if() or ...

> +             if (retried == 1) {
> +                     LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
> +                             if (dest_is_loop == 0 && 
> SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
> +                                     /* wrong base scope */
> +                                     continue;
> +                             }
> +                             LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, 
> next_ifa) {
> +                                     struct sctp_ifa *tmp_sifa;
> +
> +                                     if ((sctp_ifa->localifa_flags & 
> SCTP_ADDR_DEFER_USE) &&
> +                                         (non_asoc_addr_ok == 0))
> +                                             continue;
> +                                     tmp_sifa = 
> sctp_is_ifa_addr_acceptable(sctp_ifa,
> +                                         dest_is_loop,
> +                                         dest_is_priv, fam);
> +                                     if (tmp_sifa == NULL) {
> +                                             continue;
> +                                     }
> +                                     if (tmp_sifa == sifa) {
> +                                             continue;
> +                                     }
> +                                     if (stcb) {
> +                                             if 
> (sctp_is_address_in_scope(tmp_sifa,
> +                                                 stcb->asoc.ipv4_addr_legal,
> +                                                 stcb->asoc.ipv6_addr_legal,
> +                                                 stcb->asoc.loopback_scope,
> +                                                 stcb->asoc.ipv4_local_scope,
> +                                                 stcb->asoc.local_scope,
> +                                                 stcb->asoc.site_scope, 0) 
> == 0) {
> +                                                     continue;
> +                                             }
> +                                             if (((non_asoc_addr_ok == 0) &&
> +                                                 
> (sctp_is_addr_restricted(stcb, tmp_sifa))) ||
> +                                                 (non_asoc_addr_ok &&
> +                                                 
> (sctp_is_addr_restricted(stcb, tmp_sifa)) &&
> +                                                 
> (!sctp_is_addr_pending(stcb, tmp_sifa)))) {
> +                                                     /*
> +                                                      * It is restricted
> +                                                      * for some reason..
> +                                                      * probably not yet
> +                                                      * added.
> +                                                      */
> +                                                     continue;
> +                                             }
> +                                     }
> +                                     if ((tmp_sifa->address.sin.sin_family 
> == AF_INET) &&
> +                                         
> (IN4_ISPRIVATE_ADDRESS(&(tmp_sifa->address.sin.sin_addr)))) {
> +                                             
> sctp_add_local_addr_restricted(stcb, tmp_sifa);
> +                                     }
> +                             }
> +                     }
> +             }
> +             atomic_add_int(&sifa->refcount, 1);
> +     }
> +#endif

... this needs to be inside the block.   Either way will unbreak INET free 
kernels again.

> +     return (sifa);
> }



-- 
Bjoern A. Zeeb                                 You have to have visions!
         Stop bit received. Insert coin for new address family.

_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to