Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 23 Feb 2011 23:42:42 -0600
From:      Peter Lei <peter.lei@ieee.org>
To:        =?UTF-8?B?6buE55m76L6J?= <huangdenghui@gmail.com>
Cc:        freebsd-net@freebsd.org
Subject:   Re: question about freebsd sctp sctp_asconf_iterator_stcb function.
Message-ID:  <4D65EFD2.3020400@ieee.org>
In-Reply-To: <AANLkTik7iYb7YX71uZut-A6JT%2BX6iDum9ZwoqAL1DaKg@mail.gmail.com>
References:  <AANLkTik7iYb7YX71uZut-A6JT%2BX6iDum9ZwoqAL1DaKg@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Hi,

No, the original code looks correct.  The address management code needs
to run regardless of whether SCTP_PCB_FLAGS_DO_ASCONF is enabled (or
whether the peer supports ASCONF or not).  The newly added address is
put onto the restricted list to prevent the stack from using the new
address as a source address for any existing associations.  Similarly,
any addresses that have been locally removed should no longer be used.

The endpoint's SCTP_PCB_FLAGS_DO_ASCONF flag and the association's
peer_supports_asconf flag are then checked to determine whether to
send an ASCONF(ADD/DELETE) chunk to the peers.  If an ASCONF is sent
for an address addition, upon getting an ASCONF-ACK indicating success,
the address will be moved off the restricted list and onto the local
address list as a usable as a source address.

If ASCONF is disabled or the peer doesn't support ASCONF, or the peer
rejects the addition, then that address would stay on the restricted
list, and not be used by the local stack as a possible source address.

Hope that clarifies...

--peter


On 2/23/11 8:09 PM, 黄登辉 wrote:
> Hi
> 
>      I have a little about the following code section of
> sctp_asconf_iterator_stcb function.
> 
>          if (type == SCTP_ADD_IP_ADDRESS) {
>             /* prevent this address from being used as a source */
>             sctp_add_local_addr_restricted(stcb, ifa);
>         } else if (type == SCTP_DEL_IP_ADDRESS) {
>             struct sctp_nets *net;
> 
>             TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
>                 sctp_rtentry_t *rt;
> 
>                 /* delete this address if cached */
>                 if (net->ro._s_addr == ifa) {
>                     sctp_free_ifa(net->ro._s_addr);
>                     net->ro._s_addr = NULL;
>                     net->src_addr_selected = 0;
>                     rt = net->ro.ro_rt;
>                     if (rt) {
>                         RTFREE(rt);
>                         net->ro.ro_rt = NULL;
>                     }
>                     /*
>                      * Now we deleted our src address,
>                      * should we not also now reset the
>                      * cwnd/rto to start as if its a new
>                      * address?
>                      */
>                     stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb,
> net);
>                     net->RTO = 0;
> 
>                 }
>             }
>         } else if (type == SCTP_SET_PRIM_ADDR) {
>             if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0)
> {
>                 /* must validate the ifa is in the ep */
>                 if (sctp_is_addr_in_ep(stcb->sctp_ep, ifa) == 0) {
>                     continue;
>                 }
>             } else {
>                 /* Need to check scopes for this guy */
>                 if (sctp_is_address_in_scope(ifa,
>                     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;
>                 }
>             }
>         }
>         /* queue an asconf for this address add/delete */
>         if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF) &&
>             stcb->asoc.peer_supports_asconf) {
>             /* queue an asconf for this addr */
>             status = sctp_asconf_queue_add(stcb, ifa, type);
>             /*
>              * if queued ok, and in the open state, update the
>              * count of queued params.  If in the non-open
>              * state, these get sent when the assoc goes open.
>              */
>             if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
>                 if (status >= 0) {
>                     num_queued++;
>                 }
>             }
>         }
> 
> 
> should change like this:
> 
>         if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF) &&
>             stcb->asoc.peer_supports_asconf) {
>             if (type == SCTP_ADD_IP_ADDRESS) {
>                 /* prevent this address from being used as a source */
>                 sctp_add_local_addr_restricted(stcb, ifa);
>             } else if (type == SCTP_DEL_IP_ADDRESS) {
>                 struct sctp_nets *net;
> 
>                 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
>                     sctp_rtentry_t *rt;
> 
>                     /* delete this address if cached */
>                     if (net->ro._s_addr == ifa) {
>                         sctp_free_ifa(net->ro._s_addr);
>                         net->ro._s_addr = NULL;
>                         net->src_addr_selected = 0;
>                         rt = net->ro.ro_rt;
>                         if (rt) {
>                             RTFREE(rt);
>                             net->ro.ro_rt = NULL;
>                         }
>                         /*
>                          * Now we deleted our src address,
>                          * should we not also now reset the
>                          * cwnd/rto to start as if its a new
>                          * address?
>                          */
> 
> stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net);
>                         net->RTO = 0;
> 
>                     }
>                 }
>             } else if (type == SCTP_SET_PRIM_ADDR) {
>                 if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) ==
> 0) {
>                     /* must validate the ifa is in the ep */
>                     if (sctp_is_addr_in_ep(stcb->sctp_ep, ifa) == 0) {
>                         continue;
>                     }
>                 } else {
>                     /* Need to check scopes for this guy */
>                     if (sctp_is_address_in_scope(ifa,
>                         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;
>                     }
>                 }
>             }
>             /* queue an asconf for this address add/delete */
> 
>                 /* queue an asconf for this addr */
>                 status = sctp_asconf_queue_add(stcb, ifa, type);
>                 /*
>                  * if queued ok, and in the open state, update the
>                  * count of queued params.  If in the non-open
>                  * state, these get sent when the assoc goes open.
>                  */
>                 if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
>                     if (status >= 0) {
>                         num_queued++;
>                     }
>                 }
>         }
> 
> 
> because  i think put some address into restricted address list is used to
> dynamic address configuration.
> So first we need to make sure this feature SCTP_PCB_FLAGS_DO_ASCONF is on
> and peer endpoint also support this feature.
> If i am wrong, experts please give some comments.
> _______________________________________________
> freebsd-net@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-net
> To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org"
> 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4D65EFD2.3020400>