diff options
author | rrs <rrs@FreeBSD.org> | 2007-08-16 01:51:22 +0000 |
---|---|---|
committer | rrs <rrs@FreeBSD.org> | 2007-08-16 01:51:22 +0000 |
commit | 1bcb372970356c4bb20cdd532350ea0df88a6f20 (patch) | |
tree | 2530cafc57ae1f3f5858ead34bf340916e72c7a1 /sys/netinet/sctp_asconf.c | |
parent | ba0da0a95deba64ddb6dc37fb2698973ff97e1ef (diff) | |
download | FreeBSD-src-1bcb372970356c4bb20cdd532350ea0df88a6f20.zip FreeBSD-src-1bcb372970356c4bb20cdd532350ea0df88a6f20.tar.gz |
- Remove extra comment for 7.0 (no GIANT here).
- Remove unneeded WLOCK/UNLOCK of inp for getting TCB lock.
- Fix panic that may occur when freeing an assoc that has partial
delivery in progress (may dereference null socket pointer when
queuing partial delivery aborted notification)
- Some spacing and comment fixes.
- Fix address add handling to clear cached routes and source addresses
when peer acks the add in case the routing table changes.
Approved by: re@freebsd.org (Bruce Mah)
Diffstat (limited to 'sys/netinet/sctp_asconf.c')
-rw-r--r-- | sys/netinet/sctp_asconf.c | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c index a091011..b66e1b2 100644 --- a/sys/netinet/sctp_asconf.c +++ b/sys/netinet/sctp_asconf.c @@ -872,6 +872,47 @@ sctp_asconf_cleanup(struct sctp_tcb *stcb, struct sctp_nets *net) } /* + * cleanup any cached source addresses that may be topologically + * incorrect after a new address has been added to this interface. + */ +static void +sctp_asconf_nets_cleanup(struct sctp_tcb *stcb, struct sctp_ifn *ifn) +{ + struct sctp_nets *net; + + /* + * Ideally, we want to only clear cached routes and source addresses + * that are topologically incorrect. But since there is no easy way + * to know whether the newly added address on the ifn would cause a + * routing change (i.e. a new egress interface would be chosen) + * without doing a new routing lookup and source address selection, + * we will (for now) just flush any cached route using a different + * ifn (and cached source addrs) and let output re-choose them + * during the next send on that net. + */ + TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { + /* + * clear any cached route (and cached source address) if the + * route's interface is NOT the same as the address change. + * If it's the same interface, just clear the cached source + * address. + */ + if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro) && + SCTP_GET_IF_INDEX_FROM_ROUTE(&net->ro) != ifn->ifn_index) { + /* clear any cached route */ + RTFREE(net->ro.ro_rt); + net->ro.ro_rt = NULL; + } + /* clear any cached source address */ + if (net->src_addr_selected) { + sctp_free_ifa(net->ro._s_addr); + net->ro._s_addr = NULL; + net->src_addr_selected = 0; + } + } +} + +/* * process an ADD/DELETE IP ack from peer. * addr: corresponding sctp_ifa to the address being added/deleted. * type: SCTP_ADD_IP_ADDRESS or SCTP_DEL_IP_ADDRESS. @@ -883,8 +924,8 @@ sctp_asconf_addr_mgmt_ack(struct sctp_tcb *stcb, struct sctp_ifa *addr, { /* * do the necessary asoc list work- if we get a failure indication, - * leave the address on the "do not use" asoc list if we get a - * success indication, remove the address from the list + * leave the address on the assoc's restricted list. If we get a + * success indication, remove the address from the restricted list. */ /* * Note: this will only occur for ADD_IP_ADDRESS, since @@ -893,6 +934,12 @@ sctp_asconf_addr_mgmt_ack(struct sctp_tcb *stcb, struct sctp_ifa *addr, if (flag) { /* success case, so remove from the restricted list */ sctp_del_local_addr_restricted(stcb, addr); + + /* + * clear any cached, topologically incorrect source + * addresses + */ + sctp_asconf_nets_cleanup(stcb, addr->ifn_p); } /* else, leave it on the list */ } |