summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctp_asconf.c
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2007-08-16 01:51:22 +0000
committerrrs <rrs@FreeBSD.org>2007-08-16 01:51:22 +0000
commit1bcb372970356c4bb20cdd532350ea0df88a6f20 (patch)
tree2530cafc57ae1f3f5858ead34bf340916e72c7a1 /sys/netinet/sctp_asconf.c
parentba0da0a95deba64ddb6dc37fb2698973ff97e1ef (diff)
downloadFreeBSD-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.c51
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 */
}
OpenPOWER on IntegriCloud