summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctp_asconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/sctp_asconf.c')
-rw-r--r--sys/netinet/sctp_asconf.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c
index d4f088b..5eaa7cd 100644
--- a/sys/netinet/sctp_asconf.c
+++ b/sys/netinet/sctp_asconf.c
@@ -39,7 +39,6 @@ __FBSDID("$FreeBSD$");
#include <netinet/sctp_header.h>
#include <netinet/sctputil.h>
#include <netinet/sctp_output.h>
-#include <netinet/sctp_bsd_addr.h>
#include <netinet/sctp_asconf.h>
/*
@@ -1054,6 +1053,7 @@ sctp_asconf_queue_add(struct sctp_tcb *stcb, struct sctp_ifa *ifa, uint16_t type
/* take the entry off the appropriate list */
sctp_asconf_addr_mgmt_ack(stcb, aa->ifa, type, 1);
/* free the entry */
+ sctp_free_ifa(aa->ifa);
SCTP_FREE(aa);
return (-1);
}
@@ -1074,6 +1074,7 @@ sctp_asconf_queue_add(struct sctp_tcb *stcb, struct sctp_ifa *ifa, uint16_t type
/* top level elements are "networked" during send */
aa->ap.aph.ph.param_type = type;
aa->ifa = ifa;
+ atomic_add_int(&ifa->refcount, 1);
/* correlation_id filled in during send routine later... */
if (ifa->address.sa.sa_family == AF_INET6) {
/* IPv6 address */
@@ -1150,6 +1151,7 @@ static uint32_t
sctp_asconf_queue_add_sa(struct sctp_tcb *stcb, struct sockaddr *sa,
uint16_t type)
{
+ struct sctp_ifa *ifa;
struct sctp_asconf_addr *aa, *aa_next;
uint32_t vrf_id;
@@ -1178,6 +1180,7 @@ sctp_asconf_queue_add_sa(struct sctp_tcb *stcb, struct sockaddr *sa,
/* delete the existing entry in the queue */
TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
/* free the entry */
+ sctp_free_ifa(aa->ifa);
SCTP_FREE(aa);
return (-1);
} else if (type == SCTP_DEL_IP_ADDRESS &&
@@ -1189,11 +1192,22 @@ sctp_asconf_queue_add_sa(struct sctp_tcb *stcb, struct sockaddr *sa,
/* take the entry off the appropriate list */
sctp_asconf_addr_mgmt_ack(stcb, aa->ifa, type, 1);
/* free the entry */
+ sctp_free_ifa(aa->ifa);
SCTP_FREE(aa);
return (-1);
}
} /* for each aa */
+ if (stcb) {
+ vrf_id = stcb->asoc.vrf_id;
+ } else {
+ vrf_id = SCTP_DEFAULT_VRFID;
+ }
+ ifa = sctp_find_ifa_by_addr(sa, vrf_id, 0);
+ if (ifa == NULL) {
+ /* Invalid address */
+ return (-1);
+ }
/* adding new request to the queue */
SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa), "AsconfAddr");
if (aa == NULL) {
@@ -1207,9 +1221,9 @@ sctp_asconf_queue_add_sa(struct sctp_tcb *stcb, struct sockaddr *sa,
}
/* fill in asconf address parameter fields */
/* top level elements are "networked" during send */
- vrf_id = SCTP_DEFAULT_VRFID;
aa->ap.aph.ph.param_type = type;
- aa->ifa = sctp_find_ifa_by_addr(sa, vrf_id, 0);
+ aa->ifa = ifa;
+ atomic_add_int(&ifa->refcount, 1);
/* correlation_id filled in during send routine later... */
if (sa->sa_family == AF_INET6) {
/* IPv6 address */
@@ -1372,6 +1386,7 @@ sctp_asconf_process_param_ack(struct sctp_tcb *stcb,
/* remove the param and free it */
TAILQ_REMOVE(&stcb->asoc.asconf_queue, aparam, next);
+ sctp_free_ifa(aparam->ifa);
SCTP_FREE(aparam);
}
@@ -2413,7 +2428,12 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
}
/* see if this address really (still) exists */
- vrf_id = SCTP_DEFAULT_VRFID;
+ if (stcb) {
+ vrf_id = stcb->asoc.vrf_id;
+ } else {
+ vrf_id = SCTP_DEFAULT_VRFID;
+ }
+
sctp_ifa = sctp_find_ifa_by_addr(sa, vrf_id, 0);
if (sctp_ifa == NULL) {
/* address doesn't exist anymore */
@@ -2626,7 +2646,11 @@ sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset,
struct sctp_ifa *sctp_ifa;
uint32_t vrf_id;
- vrf_id = SCTP_DEFAULT_VRFID;
+ if (stcb) {
+ vrf_id = stcb->asoc.vrf_id;
+ } else {
+ vrf_id = SCTP_DEFAULT_VRFID;
+ }
vrf = sctp_find_vrf(vrf_id);
if (vrf == NULL) {
return;
OpenPOWER on IntegriCloud