- fix (global) address handling in the presence of duplicates, the
last interface should own the address, but the current code fumbles the handoff. This fixes that. - move address related debugs to PCB4 and add additional ones to help in debugging address problems. Approved by: re@freebsd.org (K Smith)
This commit is contained in:
parent
84a0b303a9
commit
baf3da661c
@ -751,7 +751,7 @@ __FBSDID("$FreeBSD$");
|
||||
#define SCTP_DEBUG_PCB1 0x00100000
|
||||
#define SCTP_DEBUG_PCB2 0x00200000 /* unused */
|
||||
#define SCTP_DEBUG_PCB3 0x00400000
|
||||
#define SCTP_DEBUG_PCB4 0x00800000 /* unused */
|
||||
#define SCTP_DEBUG_PCB4 0x00800000
|
||||
#define SCTP_DEBUG_INDATA1 0x01000000
|
||||
#define SCTP_DEBUG_INDATA2 0x02000000 /* unused */
|
||||
#define SCTP_DEBUG_INDATA3 0x04000000 /* unused */
|
||||
|
@ -297,7 +297,8 @@ sctp_delete_ifn(struct sctp_ifn *sctp_ifnp, int hold_addr_lock)
|
||||
}
|
||||
|
||||
void
|
||||
sctp_mark_ifa_addr_down(uint32_t vrf_id, struct sockaddr *addr, const char *if_name, uint32_t ifn_index)
|
||||
sctp_mark_ifa_addr_down(uint32_t vrf_id, struct sockaddr *addr,
|
||||
const char *if_name, uint32_t ifn_index)
|
||||
{
|
||||
struct sctp_vrf *vrf;
|
||||
struct sctp_ifa *sctp_ifap = NULL;
|
||||
@ -305,17 +306,17 @@ sctp_mark_ifa_addr_down(uint32_t vrf_id, struct sockaddr *addr, const char *if_n
|
||||
SCTP_IPI_ADDR_RLOCK();
|
||||
vrf = sctp_find_vrf(vrf_id);
|
||||
if (vrf == NULL) {
|
||||
SCTPDBG(SCTP_DEBUG_PCB1, "Can't find vrf_id:%d\n", vrf_id);
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "Can't find vrf_id 0x%x\n", vrf_id);
|
||||
goto out;
|
||||
|
||||
}
|
||||
sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED);
|
||||
if (sctp_ifap == NULL) {
|
||||
SCTPDBG(SCTP_DEBUG_PCB1, "Can't find sctp_ifap for address\n");
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "Can't find sctp_ifap for address\n");
|
||||
goto out;
|
||||
}
|
||||
if (sctp_ifap->ifn_p == NULL) {
|
||||
SCTPDBG(SCTP_DEBUG_PCB1, "IFA has no IFN - can't mark unuseable\n");
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "IFA has no IFN - can't mark unuseable\n");
|
||||
goto out;
|
||||
}
|
||||
if (if_name) {
|
||||
@ -324,19 +325,19 @@ sctp_mark_ifa_addr_down(uint32_t vrf_id, struct sockaddr *addr, const char *if_n
|
||||
len1 = strlen(if_name);
|
||||
len2 = strlen(sctp_ifap->ifn_p->ifn_name);
|
||||
if (len1 != len2) {
|
||||
SCTPDBG(SCTP_DEBUG_PCB1, "IFN of ifa names different lenght %d vs %d - ignored\n",
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "IFN of ifa names different lenght %d vs %d - ignored\n",
|
||||
len1, len2);
|
||||
goto out;
|
||||
}
|
||||
if (strncmp(if_name, sctp_ifap->ifn_p->ifn_name, len1) != 0) {
|
||||
SCTPDBG(SCTP_DEBUG_PCB1, "IFN %s of IFA not the same as %s\n",
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "IFN %s of IFA not the same as %s\n",
|
||||
sctp_ifap->ifn_p->ifn_name,
|
||||
if_name);
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
if (sctp_ifap->ifn_p->ifn_index != ifn_index) {
|
||||
SCTPDBG(SCTP_DEBUG_PCB1, "IFA owned by ifn_index:%d down command for ifn_index:%d - ignored\n",
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "IFA owned by ifn_index:%d down command for ifn_index:%d - ignored\n",
|
||||
sctp_ifap->ifn_p->ifn_index, ifn_index);
|
||||
goto out;
|
||||
}
|
||||
@ -349,7 +350,8 @@ sctp_mark_ifa_addr_down(uint32_t vrf_id, struct sockaddr *addr, const char *if_n
|
||||
}
|
||||
|
||||
void
|
||||
sctp_mark_ifa_addr_up(uint32_t vrf_id, struct sockaddr *addr, const char *if_name, uint32_t ifn_index)
|
||||
sctp_mark_ifa_addr_up(uint32_t vrf_id, struct sockaddr *addr,
|
||||
const char *if_name, uint32_t ifn_index)
|
||||
{
|
||||
struct sctp_vrf *vrf;
|
||||
struct sctp_ifa *sctp_ifap = NULL;
|
||||
@ -357,17 +359,17 @@ sctp_mark_ifa_addr_up(uint32_t vrf_id, struct sockaddr *addr, const char *if_nam
|
||||
SCTP_IPI_ADDR_RLOCK();
|
||||
vrf = sctp_find_vrf(vrf_id);
|
||||
if (vrf == NULL) {
|
||||
SCTPDBG(SCTP_DEBUG_PCB1, "Can't find vrf_id:%d\n", vrf_id);
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "Can't find vrf_id 0x%x\n", vrf_id);
|
||||
goto out;
|
||||
|
||||
}
|
||||
sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED);
|
||||
if (sctp_ifap == NULL) {
|
||||
SCTPDBG(SCTP_DEBUG_PCB1, "Can't find sctp_ifap for address\n");
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "Can't find sctp_ifap for address\n");
|
||||
goto out;
|
||||
}
|
||||
if (sctp_ifap->ifn_p == NULL) {
|
||||
SCTPDBG(SCTP_DEBUG_PCB1, "IFA has no IFN - can't mark unuseable\n");
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "IFA has no IFN - can't mark unuseable\n");
|
||||
goto out;
|
||||
}
|
||||
if (if_name) {
|
||||
@ -376,19 +378,19 @@ sctp_mark_ifa_addr_up(uint32_t vrf_id, struct sockaddr *addr, const char *if_nam
|
||||
len1 = strlen(if_name);
|
||||
len2 = strlen(sctp_ifap->ifn_p->ifn_name);
|
||||
if (len1 != len2) {
|
||||
SCTPDBG(SCTP_DEBUG_PCB1, "IFN of ifa names different lenght %d vs %d - ignored\n",
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "IFN of ifa names different lenght %d vs %d - ignored\n",
|
||||
len1, len2);
|
||||
goto out;
|
||||
}
|
||||
if (strncmp(if_name, sctp_ifap->ifn_p->ifn_name, len1) != 0) {
|
||||
SCTPDBG(SCTP_DEBUG_PCB1, "IFN %s of IFA not the same as %s\n",
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "IFN %s of IFA not the same as %s\n",
|
||||
sctp_ifap->ifn_p->ifn_name,
|
||||
if_name);
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
if (sctp_ifap->ifn_p->ifn_index != ifn_index) {
|
||||
SCTPDBG(SCTP_DEBUG_PCB1, "IFA owned by ifn_index:%d down command for ifn_index:%d - ignored\n",
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "IFA owned by ifn_index:%d down command for ifn_index:%d - ignored\n",
|
||||
sctp_ifap->ifn_p->ifn_index, ifn_index);
|
||||
goto out;
|
||||
}
|
||||
@ -400,11 +402,81 @@ sctp_mark_ifa_addr_up(uint32_t vrf_id, struct sockaddr *addr, const char *if_nam
|
||||
SCTP_IPI_ADDR_RUNLOCK();
|
||||
}
|
||||
|
||||
/*-
|
||||
* Add an ifa to an ifn.
|
||||
* Register the interface as necessary.
|
||||
* NOTE: ADDR write lock MUST be held.
|
||||
*/
|
||||
static void
|
||||
sctp_add_ifa_to_ifn(struct sctp_ifn *sctp_ifnp, struct sctp_ifa *sctp_ifap)
|
||||
{
|
||||
int ifa_af;
|
||||
|
||||
LIST_INSERT_HEAD(&sctp_ifnp->ifalist, sctp_ifap, next_ifa);
|
||||
sctp_ifap->ifn_p = sctp_ifnp;
|
||||
atomic_add_int(&sctp_ifap->ifn_p->refcount, 1);
|
||||
/* update address counts */
|
||||
sctp_ifnp->ifa_count++;
|
||||
ifa_af = sctp_ifap->address.sa.sa_family;
|
||||
if (ifa_af == AF_INET)
|
||||
sctp_ifnp->num_v4++;
|
||||
else
|
||||
sctp_ifnp->num_v6++;
|
||||
if (sctp_ifnp->ifa_count == 1) {
|
||||
/* register the new interface */
|
||||
SCTP_REGISTER_INTERFACE(sctp_ifnp->ifn_index, ifa_af);
|
||||
sctp_ifnp->registered_af = ifa_af;
|
||||
}
|
||||
}
|
||||
|
||||
/*-
|
||||
* Remove an ifa from its ifn.
|
||||
* If no more addresses exist, remove the ifn too. Otherwise, re-register
|
||||
* the interface based on the remaining address families left.
|
||||
* NOTE: ADDR write lock MUST be held.
|
||||
*/
|
||||
static void
|
||||
sctp_remove_ifa_from_ifn(struct sctp_ifa *sctp_ifap)
|
||||
{
|
||||
uint32_t ifn_index;
|
||||
|
||||
LIST_REMOVE(sctp_ifap, next_ifa);
|
||||
if (sctp_ifap->ifn_p) {
|
||||
/* update address counts */
|
||||
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--;
|
||||
|
||||
ifn_index = sctp_ifap->ifn_p->ifn_index;
|
||||
if (SCTP_LIST_EMPTY(&sctp_ifap->ifn_p->ifalist)) {
|
||||
/* remove the ifn, possibly freeing it */
|
||||
sctp_delete_ifn(sctp_ifap->ifn_p, SCTP_ADDR_LOCKED);
|
||||
} else {
|
||||
/* re-register address family type, if needed */
|
||||
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;
|
||||
}
|
||||
/* free the ifn refcount */
|
||||
sctp_free_ifn(sctp_ifap->ifn_p);
|
||||
}
|
||||
sctp_ifap->ifn_p = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct sctp_ifa *
|
||||
sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
|
||||
uint32_t ifn_type, const char *if_name,
|
||||
void *ifa, struct sockaddr *addr, uint32_t ifa_flags,
|
||||
uint32_t ifn_type, const char *if_name, void *ifa,
|
||||
struct sockaddr *addr, uint32_t ifa_flags,
|
||||
int dynamic_add)
|
||||
{
|
||||
struct sctp_vrf *vrf;
|
||||
@ -415,7 +487,10 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
|
||||
uint32_t hash_of_addr;
|
||||
int new_ifn_af = 0;
|
||||
|
||||
/* How granular do we need the locks to be here? */
|
||||
#ifdef SCTP_DEBUG
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "vrf_id 0x%x: adding address: ", vrf_id);
|
||||
SCTPDBG_ADDR(SCTP_DEBUG_PCB4, addr);
|
||||
#endif
|
||||
SCTP_IPI_ADDR_WLOCK();
|
||||
sctp_ifnp = sctp_find_ifn(ifn, ifn_index);
|
||||
if (sctp_ifnp) {
|
||||
@ -436,7 +511,8 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
|
||||
* done though.
|
||||
*/
|
||||
SCTP_IPI_ADDR_WUNLOCK();
|
||||
SCTP_MALLOC(sctp_ifnp, struct sctp_ifn *, sizeof(struct sctp_ifn), SCTP_M_IFN);
|
||||
SCTP_MALLOC(sctp_ifnp, struct sctp_ifn *,
|
||||
sizeof(struct sctp_ifn), SCTP_M_IFN);
|
||||
if (sctp_ifnp == NULL) {
|
||||
#ifdef INVARIANTS
|
||||
panic("No memory for IFN:%u", sctp_ifnp->ifn_index);
|
||||
@ -470,44 +546,44 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
|
||||
/* Hmm, it already exists? */
|
||||
if ((sctp_ifap->ifn_p) &&
|
||||
(sctp_ifap->ifn_p->ifn_index == ifn_index)) {
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "Using existing ifn %s (0x%x) for ifa %p\n",
|
||||
sctp_ifap->ifn_p->ifn_name, ifn_index,
|
||||
sctp_ifap);
|
||||
if (new_ifn_af) {
|
||||
/* Remove the created one that we don't want */
|
||||
sctp_delete_ifn(sctp_ifnp, 1);
|
||||
sctp_delete_ifn(sctp_ifnp, SCTP_ADDR_LOCKED);
|
||||
}
|
||||
if (sctp_ifap->localifa_flags & SCTP_BEING_DELETED) {
|
||||
/* easy to solve, just switch back to active */
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "Clearing deleted ifa flag\n");
|
||||
sctp_ifap->localifa_flags = SCTP_ADDR_VALID;
|
||||
sctp_ifap->ifn_p = sctp_ifnp;
|
||||
atomic_add_int(&sctp_ifap->ifn_p->refcount, 1);
|
||||
}
|
||||
exit_stage_left:
|
||||
SCTP_IPI_ADDR_WUNLOCK();
|
||||
return (sctp_ifap);
|
||||
} else {
|
||||
goto exit_stage_left;
|
||||
}
|
||||
} else {
|
||||
if (sctp_ifap->ifn_p) {
|
||||
/*
|
||||
* The last IFN gets the address, old ones
|
||||
* are deleted.
|
||||
* The last IFN gets the address, removee
|
||||
* the old one
|
||||
*/
|
||||
if (new_ifn_af) {
|
||||
/*
|
||||
* Remove the created one that we
|
||||
* don't want
|
||||
*/
|
||||
sctp_free_ifn(sctp_ifap->ifn_p);
|
||||
if (sctp_ifap->ifn_p->refcount == 1)
|
||||
sctp_delete_ifn(sctp_ifap->ifn_p, 1);
|
||||
sctp_ifap->ifn_p = sctp_ifnp;
|
||||
atomic_add_int(&sctp_ifap->ifn_p->refcount, 1);
|
||||
}
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "Moving ifa %p from %s (0x%x) to %s (0x%x)\n",
|
||||
sctp_ifap, sctp_ifap->ifn_p->ifn_name,
|
||||
sctp_ifap->ifn_p->ifn_index, if_name,
|
||||
ifn_index);
|
||||
/* remove the address from the old ifn */
|
||||
sctp_remove_ifa_from_ifn(sctp_ifap);
|
||||
/* move the address over to the new ifn */
|
||||
sctp_add_ifa_to_ifn(sctp_ifnp, sctp_ifap);
|
||||
goto exit_stage_left;
|
||||
} else {
|
||||
/* repair ifnp which was NULL ? */
|
||||
sctp_ifap->localifa_flags = SCTP_ADDR_VALID;
|
||||
sctp_ifap->ifn_p = sctp_ifnp;
|
||||
atomic_add_int(&sctp_ifap->ifn_p->refcount, 1);
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "Repairing ifn %p for ifa %p\n",
|
||||
sctp_ifnp, sctp_ifap);
|
||||
sctp_add_ifa_to_ifn(sctp_ifnp, sctp_ifap);
|
||||
}
|
||||
goto exit_stage_left;
|
||||
}
|
||||
@ -594,9 +670,10 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
|
||||
* Gak, what can we do? We have lost an address
|
||||
* change can you say HOSED?
|
||||
*/
|
||||
SCTPDBG(SCTP_DEBUG_PCB1, "Lost and address change ???\n");
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "Lost an address change?\n");
|
||||
/* Opps, must decrement the count */
|
||||
sctp_del_addr_from_vrf(vrf_id, addr, ifn_index, if_name);
|
||||
sctp_del_addr_from_vrf(vrf_id, addr, ifn_index,
|
||||
if_name);
|
||||
return (NULL);
|
||||
}
|
||||
SCTP_INCR_LADDR_COUNT();
|
||||
@ -632,9 +709,13 @@ sctp_del_addr_from_vrf(uint32_t vrf_id, struct sockaddr *addr,
|
||||
SCTP_IPI_ADDR_WLOCK();
|
||||
vrf = sctp_find_vrf(vrf_id);
|
||||
if (vrf == NULL) {
|
||||
SCTP_PRINTF("Can't find vrf_id:%d\n", vrf_id);
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "Can't find vrf_id 0x%x\n", vrf_id);
|
||||
goto out_now;
|
||||
}
|
||||
#ifdef SCTP_DEBUG
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "vrf_id 0x%x: deleting address:", vrf_id);
|
||||
SCTPDBG_ADDR(SCTP_DEBUG_PCB4, addr);
|
||||
#endif
|
||||
sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED);
|
||||
if (sctp_ifap) {
|
||||
/* Validate the delete */
|
||||
@ -669,55 +750,24 @@ sctp_del_addr_from_vrf(uint32_t vrf_id, struct sockaddr *addr,
|
||||
}
|
||||
}
|
||||
if (!valid) {
|
||||
#ifdef SCTP_DEBUG
|
||||
SCTPDBG(SCTP_DEBUG_PCB1, "Deleting address:");
|
||||
SCTPDBG_ADDR(SCTP_DEBUG_PCB1, addr);
|
||||
SCTPDBG(SCTP_DEBUG_PCB1, "ifn:%d ifname:%s does not match addresses\n",
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "ifn:%d ifname:%s does not match addresses\n",
|
||||
ifn_index, ((if_name == NULL) ? "NULL" : if_name));
|
||||
SCTPDBG(SCTP_DEBUG_PCB1, "ifn:%d ifname:%s - ignoring delete\n",
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "ifn:%d ifname:%s - ignoring delete\n",
|
||||
sctp_ifap->ifn_p->ifn_index, sctp_ifap->ifn_p->ifn_name);
|
||||
#endif
|
||||
SCTP_IPI_ADDR_WUNLOCK();
|
||||
return;
|
||||
}
|
||||
}
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "Deleting ifa %p\n", sctp_ifap);
|
||||
sctp_ifap->localifa_flags &= SCTP_ADDR_VALID;
|
||||
sctp_ifap->localifa_flags |= SCTP_BEING_DELETED;
|
||||
vrf->total_ifa_count--;
|
||||
LIST_REMOVE(sctp_ifap, next_bucket);
|
||||
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;
|
||||
}
|
||||
sctp_remove_ifa_from_ifn(sctp_ifap);
|
||||
}
|
||||
#ifdef SCTP_DEBUG
|
||||
else {
|
||||
SCTPDBG(SCTP_DEBUG_PCB1, "Del Addr-ifn:%d Could not find address:",
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "Del Addr-ifn:%d Could not find address:",
|
||||
ifn_index);
|
||||
SCTPDBG_ADDR(SCTP_DEBUG_PCB1, addr);
|
||||
}
|
||||
@ -734,7 +784,7 @@ sctp_del_addr_from_vrf(uint32_t vrf_id, struct sockaddr *addr,
|
||||
* Gak, what can we do? We have lost an address
|
||||
* change can you say HOSED?
|
||||
*/
|
||||
SCTPDBG(SCTP_DEBUG_PCB1, "Lost an address change?\n");
|
||||
SCTPDBG(SCTP_DEBUG_PCB4, "Lost an address change?\n");
|
||||
|
||||
/* Oops, must decrement the count */
|
||||
sctp_free_ifa(sctp_ifap);
|
||||
@ -766,7 +816,7 @@ static struct sctp_tcb *
|
||||
sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from,
|
||||
struct sockaddr *to, struct sctp_nets **netp, uint32_t vrf_id)
|
||||
{
|
||||
/**** ASSUMSES THE CALLER holds the INP_INFO_RLOCK */
|
||||
/**** ASSUMES THE CALLER holds the INP_INFO_RLOCK */
|
||||
/*
|
||||
* If we support the TCP model, then we must now dig through to see
|
||||
* if we can find our endpoint in the list of tcp ep's.
|
||||
|
@ -4935,6 +4935,10 @@ sctp_sorecvmsg(struct socket *so,
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
if (from && fromlen <= 0) {
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
if (msg_flags) {
|
||||
in_flags = *msg_flags;
|
||||
if (in_flags & MSG_PEEK)
|
||||
@ -5362,12 +5366,12 @@ sctp_sorecvmsg(struct socket *so,
|
||||
struct sockaddr *to;
|
||||
|
||||
#ifdef INET
|
||||
cp_len = min(fromlen, control->whoFrom->ro._l_addr.sin.sin_len);
|
||||
cp_len = min((size_t)fromlen, (size_t)control->whoFrom->ro._l_addr.sin.sin_len);
|
||||
memcpy(from, &control->whoFrom->ro._l_addr, cp_len);
|
||||
((struct sockaddr_in *)from)->sin_port = control->port_from;
|
||||
#else
|
||||
/* No AF_INET use AF_INET6 */
|
||||
cp_len = min(fromlen, control->whoFrom->ro._l_addr.sin6.sin6_len);
|
||||
cp_len = min((size_t)fromlen, (size_t)control->whoFrom->ro._l_addr.sin6.sin6_len);
|
||||
memcpy(from, &control->whoFrom->ro._l_addr, cp_len);
|
||||
((struct sockaddr_in6 *)from)->sin6_port = control->port_from;
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user