Hi Bjoern,

fixed in http://svn.freebsd.org/changeset/base/222077
Thanks for reporting it.

Best regards
Michael

On May 18, 2011, at 6:35 PM, Bjoern A. Zeeb wrote:

> 
> 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