summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctp_pcb.c
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2007-06-01 11:19:54 +0000
committerrrs <rrs@FreeBSD.org>2007-06-01 11:19:54 +0000
commitf978918265146648d92dec52ff74fbf46eb3f5f9 (patch)
treec2755093118649fbe976c97b2ea337fa91ffad1b /sys/netinet/sctp_pcb.c
parent4623bf3eb19a3fc2581cc6506b9754427f5e3687 (diff)
downloadFreeBSD-src-f978918265146648d92dec52ff74fbf46eb3f5f9.zip
FreeBSD-src-f978918265146648d92dec52ff74fbf46eb3f5f9.tar.gz
- Take out the broken table-id concept. Panda Routers have a M-VRF
concept that is NOT well thought out for a multi-homed transport protocol. So the useless table-id entries passed around need to be removed. - Add a event timer for the zero copy api. - Fix a bug in sctp_timer.c when searching for an alternate with the largest ssthresh (the compare was wrong).
Diffstat (limited to 'sys/netinet/sctp_pcb.c')
-rw-r--r--sys/netinet/sctp_pcb.c42
1 files changed, 38 insertions, 4 deletions
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index 76f59c4..3b1e3b7 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -281,6 +281,8 @@ sctp_delete_ifn(struct sctp_ifn *sctp_ifnp, int hold_addr_lock)
SCTP_IPI_ADDR_LOCK();
LIST_REMOVE(sctp_ifnp, next_bucket);
LIST_REMOVE(sctp_ifnp, next_ifn);
+ SCTP_DEREGISTER_INTERFACE(sctp_ifnp->ifn_index,
+ sctp_ifnp->registered_af);
if (hold_addr_lock == 0)
SCTP_IPI_ADDR_UNLOCK();
/* Take away the reference, and possibly free it */
@@ -300,6 +302,7 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
struct sctp_ifalist *hash_addr_head;
struct sctp_ifnlist *hash_ifn_head;
uint32_t hash_of_addr;
+ int new_ifn_af = 0;
/* How granular do we need the locks to be here? */
SCTP_IPI_ADDR_LOCK();
@@ -331,7 +334,7 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
sctp_ifnp->ifa_count = 0;
sctp_ifnp->refcount = 1;
sctp_ifnp->vrf = vrf;
- sctp_ifnp->ifn_mtu = SCTP_GATHER_MTU_FROM_IFN_INFO(ifn, ifn_index);
+ sctp_ifnp->ifn_mtu = SCTP_GATHER_MTU_FROM_IFN_INFO(ifn, ifn_index, addr->sa_family);
if (if_name != NULL) {
memcpy(sctp_ifnp->ifn_name, if_name, SCTP_IFNAMSIZ);
} else {
@@ -343,6 +346,7 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
LIST_INSERT_HEAD(hash_ifn_head, sctp_ifnp, next_bucket);
LIST_INSERT_HEAD(&vrf->ifnlist, sctp_ifnp, next_ifn);
atomic_add_int(&sctppcbinfo.ipi_count_ifns, 1);
+ new_ifn_af = 1;
}
sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, 1);
if (sctp_ifap) {
@@ -403,6 +407,9 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
sctp_ifap->src_is_priv = 1;
}
+ sctp_ifnp->num_v4++;
+ if (new_ifn_af)
+ new_ifn_af = AF_INET;
} else if (sctp_ifap->address.sa.sa_family == AF_INET6) {
/* ok to use deprecated addresses? */
struct sockaddr_in6 *sin6;
@@ -415,6 +422,11 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
sctp_ifap->src_is_priv = 1;
}
+ sctp_ifnp->num_v6++;
+ if (new_ifn_af)
+ new_ifn_af = AF_INET6;
+ } else {
+ new_ifn_af = 0;
}
hash_of_addr = sctp_get_ifa_hash_val(&sctp_ifap->address.sa);
@@ -430,6 +442,10 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
sctp_ifnp->ifa_count++;
vrf->total_ifa_count++;
atomic_add_int(&sctppcbinfo.ipi_count_ifas, 1);
+ if (new_ifn_af) {
+ SCTP_REGISTER_INTERFACE(ifn_index, new_ifn_af);
+ sctp_ifnp->registered_af = new_ifn_af;
+ }
SCTP_IPI_ADDR_UNLOCK();
if (dynamic_add) {
/*
@@ -496,8 +512,28 @@ sctp_del_addr_from_vrf(uint32_t vrf_id, struct sockaddr *addr,
LIST_REMOVE(sctp_ifap, next_ifa);
if (sctp_ifap->ifn_p) {
sctp_ifap->ifn_p->ifa_count--;
+ if (sctp_ifap->address.sa.sa_family == AF_INET6)
+ sctp_ifap->ifn_p->num_v6--;
+ else if (sctp_ifap->address.sa.sa_family == AF_INET)
+ sctp_ifap->ifn_p->num_v4--;
if (SCTP_LIST_EMPTY(&sctp_ifap->ifn_p->ifalist)) {
sctp_delete_ifn(sctp_ifap->ifn_p, 1);
+ } else {
+ if ((sctp_ifap->ifn_p->num_v6 == 0) &&
+ (sctp_ifap->ifn_p->registered_af == AF_INET6)) {
+ SCTP_DEREGISTER_INTERFACE(ifn_index,
+ AF_INET6);
+ SCTP_REGISTER_INTERFACE(ifn_index,
+ AF_INET);
+ sctp_ifap->ifn_p->registered_af = AF_INET;
+ } else if ((sctp_ifap->ifn_p->num_v4 == 0) &&
+ (sctp_ifap->ifn_p->registered_af == AF_INET)) {
+ SCTP_DEREGISTER_INTERFACE(ifn_index,
+ AF_INET);
+ SCTP_REGISTER_INTERFACE(ifn_index,
+ AF_INET6);
+ sctp_ifap->ifn_p->registered_af = AF_INET6;
+ }
}
sctp_free_ifn(sctp_ifap->ifn_p);
sctp_ifap->ifn_p = NULL;
@@ -1793,7 +1829,6 @@ sctp_inpcb_alloc(struct socket *so)
return (ENOBUFS);
}
inp->def_vrf_id = SCTP_DEFAULT_VRFID;
- inp->def_table_id = SCTP_DEFAULT_TABLEID;
SCTP_INP_INFO_WLOCK();
SCTP_INP_LOCK_INIT(inp);
@@ -3068,8 +3103,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
(void)sa6_embedscope(sin6, ip6_use_defzone);
sin6->sin6_scope_id = 0;
}
- SCTP_RTALLOC((sctp_route_t *) & net->ro, stcb->asoc.vrf_id,
- stcb->asoc.table_id);
+ SCTP_RTALLOC((sctp_route_t *) & net->ro, stcb->asoc.vrf_id);
if (newaddr->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6;
OpenPOWER on IntegriCloud