Deleted Added
full compact
sctp_asconf.c (172157) sctp_asconf.c (172190)
1/*-
2 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * a) Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.

--- 17 unchanged lines hidden (view full) ---

26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28 * THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/* $KAME: sctp_asconf.c,v 1.24 2005/03/06 16:04:16 itojun Exp $ */
32
33#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * a) Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.

--- 17 unchanged lines hidden (view full) ---

26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28 * THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/* $KAME: sctp_asconf.c,v 1.24 2005/03/06 16:04:16 itojun Exp $ */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 172157 2007-09-13 14:43:54Z rrs $");
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 172190 2007-09-15 19:07:42Z rrs $");
35#include <netinet/sctp_os.h>
36#include <netinet/sctp_var.h>
37#include <netinet/sctp_sysctl.h>
38#include <netinet/sctp_pcb.h>
39#include <netinet/sctp_header.h>
40#include <netinet/sctputil.h>
41#include <netinet/sctp_output.h>
42#include <netinet/sctp_asconf.h>

--- 1156 unchanged lines hidden (view full) ---

1199 /*
1200 * Note: this will only occur for ADD_IP_ADDRESS, since
1201 * DEL_IP_ADDRESS is never actually added to the list...
1202 */
1203 if (flag) {
1204 /* success case, so remove from the restricted list */
1205 sctp_del_local_addr_restricted(stcb, addr);
1206
35#include <netinet/sctp_os.h>
36#include <netinet/sctp_var.h>
37#include <netinet/sctp_sysctl.h>
38#include <netinet/sctp_pcb.h>
39#include <netinet/sctp_header.h>
40#include <netinet/sctputil.h>
41#include <netinet/sctp_output.h>
42#include <netinet/sctp_asconf.h>

--- 1156 unchanged lines hidden (view full) ---

1199 /*
1200 * Note: this will only occur for ADD_IP_ADDRESS, since
1201 * DEL_IP_ADDRESS is never actually added to the list...
1202 */
1203 if (flag) {
1204 /* success case, so remove from the restricted list */
1205 sctp_del_local_addr_restricted(stcb, addr);
1206
1207 if (sctp_is_mobility_feature_on(stcb->sctp_ep, SCTP_MOBILITY_BASE)) {
1207 if (sctp_is_mobility_feature_on(stcb->sctp_ep,
1208 SCTP_MOBILITY_BASE)) {
1208 sctp_path_check_and_react(stcb, addr);
1209 return;
1210 }
1209 sctp_path_check_and_react(stcb, addr);
1210 return;
1211 }
1211 /*
1212 * clear any cached, topologically incorrect source
1213 * addresses
1214 */
1212 /* clear any cached/topologically incorrect source addresses */
1215 sctp_asconf_nets_cleanup(stcb, addr->ifn_p);
1216 }
1217 /* else, leave it on the list */
1218}
1219
1220/*
1221 * add an asconf add/delete/set primary IP address parameter to the queue.
1222 * type = SCTP_ADD_IP_ADDRESS, SCTP_DEL_IP_ADDRESS, SCTP_SET_PRIM_ADDR.

--- 82 unchanged lines hidden (view full) ---

1305 aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
1306 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
1307 sizeof(struct sctp_ipv4addr_param);
1308 memcpy(&aa->ap.addrp.addr, &sin->sin_addr,
1309 sizeof(struct in_addr));
1310 } else {
1311 /* invalid family! */
1312 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1213 sctp_asconf_nets_cleanup(stcb, addr->ifn_p);
1214 }
1215 /* else, leave it on the list */
1216}
1217
1218/*
1219 * add an asconf add/delete/set primary IP address parameter to the queue.
1220 * type = SCTP_ADD_IP_ADDRESS, SCTP_DEL_IP_ADDRESS, SCTP_SET_PRIM_ADDR.

--- 82 unchanged lines hidden (view full) ---

1303 aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
1304 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
1305 sizeof(struct sctp_ipv4addr_param);
1306 memcpy(&aa->ap.addrp.addr, &sin->sin_addr,
1307 sizeof(struct in_addr));
1308 } else {
1309 /* invalid family! */
1310 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1311 sctp_free_ifa(ifa);
1313 return (-1);
1314 }
1315 aa->sent = 0; /* clear sent flag */
1316
1317 /*
1318 * if we are deleting an address it should go out last otherwise,
1319 * add it to front of the pending queue
1320 */

--- 102 unchanged lines hidden (view full) ---

1423 /* queue in an advisory set primary too */
1424 (void)sctp_asconf_queue_mgmt(stcb, ifa, SCTP_SET_PRIM_ADDR);
1425 /* let caller know we should send this out immediately */
1426 status = 1;
1427 }
1428 return (status);
1429}
1430
1312 return (-1);
1313 }
1314 aa->sent = 0; /* clear sent flag */
1315
1316 /*
1317 * if we are deleting an address it should go out last otherwise,
1318 * add it to front of the pending queue
1319 */

--- 102 unchanged lines hidden (view full) ---

1422 /* queue in an advisory set primary too */
1423 (void)sctp_asconf_queue_mgmt(stcb, ifa, SCTP_SET_PRIM_ADDR);
1424 /* let caller know we should send this out immediately */
1425 status = 1;
1426 }
1427 return (status);
1428}
1429
1431/*
1432 * add an asconf add/delete IP address parameter to the queue by addr.
1433 * type = SCTP_ADD_IP_ADDRESS, SCTP_DEL_IP_ADDRESS, SCTP_SET_PRIM_ADDR.
1430/*-
1431 * add an asconf delete IP address parameter to the queue by sockaddr and
1432 * possibly with no sctp_ifa available. This is only called by the routine
1433 * that checks the addresses in an INIT-ACK against the current address list.
1434 * returns 0 if completed, non-zero if not completed.
1434 * returns 0 if completed, non-zero if not completed.
1435 * NOTE: if adding, but delete already scheduled (and not yet sent out),
1436 * simply remove from queue. Same for deleting an address already scheduled
1437 * for add. If a duplicate operation is found, ignore the new one.
1435 * NOTE: if an add is already scheduled (and not yet sent out), simply
1436 * remove it from queue. If a duplicate operation is found, ignore the
1437 * new one.
1438 */
1439static int
1438 */
1439static int
1440sctp_asconf_queue_add_sa(struct sctp_tcb *stcb, struct sockaddr *sa,
1441 uint16_t type)
1440sctp_asconf_queue_sa_delete(struct sctp_tcb *stcb, struct sockaddr *sa)
1442{
1443 struct sctp_ifa *ifa;
1444 struct sctp_asconf_addr *aa, *aa_next;
1445 uint32_t vrf_id;
1446
1447 if (stcb == NULL) {
1448 return (-1);
1449 }

--- 4 unchanged lines hidden (view full) ---

1454 /* make sure the request isn't already in the queue */
1455 for (aa = TAILQ_FIRST(&stcb->asoc.asconf_queue); aa != NULL;
1456 aa = aa_next) {
1457 aa_next = TAILQ_NEXT(aa, next);
1458 /* address match? */
1459 if (sctp_asconf_addr_match(aa, sa) == 0)
1460 continue;
1461 /* is the request already in queue (sent or not) */
1441{
1442 struct sctp_ifa *ifa;
1443 struct sctp_asconf_addr *aa, *aa_next;
1444 uint32_t vrf_id;
1445
1446 if (stcb == NULL) {
1447 return (-1);
1448 }

--- 4 unchanged lines hidden (view full) ---

1453 /* make sure the request isn't already in the queue */
1454 for (aa = TAILQ_FIRST(&stcb->asoc.asconf_queue); aa != NULL;
1455 aa = aa_next) {
1456 aa_next = TAILQ_NEXT(aa, next);
1457 /* address match? */
1458 if (sctp_asconf_addr_match(aa, sa) == 0)
1459 continue;
1460 /* is the request already in queue (sent or not) */
1462 if (aa->ap.aph.ph.param_type == type) {
1461 if (aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS) {
1463 return (-1);
1464 }
1465 /* is the negative request already in queue, and not sent */
1466 if (aa->sent == 1)
1467 continue;
1462 return (-1);
1463 }
1464 /* is the negative request already in queue, and not sent */
1465 if (aa->sent == 1)
1466 continue;
1468 if (type == SCTP_ADD_IP_ADDRESS &&
1469 aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS) {
1470 /* add requested, delete already queued */
1471
1472 /* delete the existing entry in the queue */
1467 if (aa->ap.aph.ph.param_type == SCTP_ADD_IP_ADDRESS) {
1468 /* add already queued, so remove existing entry */
1473 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1469 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1474 sctp_free_ifa(aa->ifa);
1475 /* free the entry */
1476 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1477 return (-1);
1478 } else if (type == SCTP_DEL_IP_ADDRESS &&
1479 aa->ap.aph.ph.param_type == SCTP_ADD_IP_ADDRESS) {
1480 /* delete requested, add already queued */
1481
1482 /* delete the existing entry in the queue */
1483 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1484 sctp_del_local_addr_restricted(stcb, aa->ifa);
1485 /* free the entry */
1486 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1487 return (-1);
1488 }
1489 } /* for each aa */
1470 sctp_del_local_addr_restricted(stcb, aa->ifa);
1471 /* free the entry */
1472 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1473 return (-1);
1474 }
1475 } /* for each aa */
1476
1477 /* find any existing ifa-- NOTE ifa CAN be allowed to be NULL */
1490 if (stcb) {
1491 vrf_id = stcb->asoc.vrf_id;
1492 } else {
1493 vrf_id = SCTP_DEFAULT_VRFID;
1494 }
1478 if (stcb) {
1479 vrf_id = stcb->asoc.vrf_id;
1480 } else {
1481 vrf_id = SCTP_DEFAULT_VRFID;
1482 }
1495
1496 ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED);
1483 ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED);
1497 if (ifa == NULL) {
1498 /* Invalid address */
1499 return (-1);
1500 }
1484
1501 /* adding new request to the queue */
1502 SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
1503 SCTP_M_ASC_ADDR);
1504 if (aa == NULL) {
1505 /* didn't get memory */
1506 SCTPDBG(SCTP_DEBUG_ASCONF1,
1485 /* adding new request to the queue */
1486 SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
1487 SCTP_M_ASC_ADDR);
1488 if (aa == NULL) {
1489 /* didn't get memory */
1490 SCTPDBG(SCTP_DEBUG_ASCONF1,
1507 "asconf_queue_add_sa: failed to get memory!\n");
1491 "sctp_asconf_queue_sa_delete: failed to get memory!\n");
1508 return (-1);
1509 }
1510 /* fill in asconf address parameter fields */
1511 /* top level elements are "networked" during send */
1492 return (-1);
1493 }
1494 /* fill in asconf address parameter fields */
1495 /* top level elements are "networked" during send */
1512 aa->ap.aph.ph.param_type = type;
1496 aa->ap.aph.ph.param_type = SCTP_DEL_IP_ADDRESS;
1513 aa->ifa = ifa;
1497 aa->ifa = ifa;
1514 atomic_add_int(&ifa->refcount, 1);
1498 if (ifa)
1499 atomic_add_int(&ifa->refcount, 1);
1515 /* correlation_id filled in during send routine later... */
1516 if (sa->sa_family == AF_INET6) {
1517 /* IPv6 address */
1518 struct sockaddr_in6 *sin6;
1519
1520 sin6 = (struct sockaddr_in6 *)sa;
1521 aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
1522 aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));

--- 7 unchanged lines hidden (view full) ---

1530 aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
1531 aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
1532 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_ipv4addr_param);
1533 memcpy(&aa->ap.addrp.addr, &sin->sin_addr,
1534 sizeof(struct in_addr));
1535 } else {
1536 /* invalid family! */
1537 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1500 /* correlation_id filled in during send routine later... */
1501 if (sa->sa_family == AF_INET6) {
1502 /* IPv6 address */
1503 struct sockaddr_in6 *sin6;
1504
1505 sin6 = (struct sockaddr_in6 *)sa;
1506 aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
1507 aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));

--- 7 unchanged lines hidden (view full) ---

1515 aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
1516 aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
1517 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_ipv4addr_param);
1518 memcpy(&aa->ap.addrp.addr, &sin->sin_addr,
1519 sizeof(struct in_addr));
1520 } else {
1521 /* invalid family! */
1522 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1523 if (ifa)
1524 sctp_free_ifa(ifa);
1538 return (-1);
1539 }
1540 aa->sent = 0; /* clear sent flag */
1541
1525 return (-1);
1526 }
1527 aa->sent = 0; /* clear sent flag */
1528
1542 /*
1543 * if we are deleting an address it should go out last otherwise,
1544 * add it to front of the pending queue
1545 */
1546 if (type == SCTP_ADD_IP_ADDRESS) {
1547 /* add goes to the front of the queue */
1548 TAILQ_INSERT_HEAD(&stcb->asoc.asconf_queue, aa, next);
1549 } else {
1550 /* delete and set primary goes to the back of the queue */
1551 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
1552 }
1529 /* delete goes to the back of the queue */
1530 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
1553
1554 return (0);
1555}
1556
1557/*
1558 * find a specific asconf param on our "sent" queue
1559 */
1560static struct sctp_asconf_addr *

--- 97 unchanged lines hidden (view full) ---

1658 break;
1659 default:
1660 /* should NEVER happen */
1661 break;
1662 }
1663
1664 /* remove the param and free it */
1665 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aparam, next);
1531
1532 return (0);
1533}
1534
1535/*
1536 * find a specific asconf param on our "sent" queue
1537 */
1538static struct sctp_asconf_addr *

--- 97 unchanged lines hidden (view full) ---

1636 break;
1637 default:
1638 /* should NEVER happen */
1639 break;
1640 }
1641
1642 /* remove the param and free it */
1643 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aparam, next);
1666 sctp_free_ifa(aparam->ifa);
1644 if (aparam->ifa)
1645 sctp_free_ifa(aparam->ifa);
1667 SCTP_FREE(aparam, SCTP_M_ASC_ADDR);
1668}
1669
1670/*
1671 * cleanup from a bad asconf ack parameter
1672 */
1673static void
1674sctp_asconf_ack_clear(struct sctp_tcb *stcb)
1675{
1676 /* assume peer doesn't really know how to do asconfs */
1677 stcb->asoc.peer_supports_asconf = 0;
1678 /* XXX we could free the pending queue here */
1679}
1680
1681void
1682sctp_handle_asconf_ack(struct mbuf *m, int offset,
1683 struct sctp_asconf_ack_chunk *cp, struct sctp_tcb *stcb,
1646 SCTP_FREE(aparam, SCTP_M_ASC_ADDR);
1647}
1648
1649/*
1650 * cleanup from a bad asconf ack parameter
1651 */
1652static void
1653sctp_asconf_ack_clear(struct sctp_tcb *stcb)
1654{
1655 /* assume peer doesn't really know how to do asconfs */
1656 stcb->asoc.peer_supports_asconf = 0;
1657 /* XXX we could free the pending queue here */
1658}
1659
1660void
1661sctp_handle_asconf_ack(struct mbuf *m, int offset,
1662 struct sctp_asconf_ack_chunk *cp, struct sctp_tcb *stcb,
1684 struct sctp_nets *net)
1663 struct sctp_nets *net, int *abort_no_unlock)
1685{
1686 struct sctp_association *asoc;
1687 uint32_t serial_num;
1688 uint16_t ack_length;
1689 struct sctp_asconf_paramhdr *aph;
1690 struct sctp_asconf_addr *aa, *aa_next;
1691 uint32_t last_error_id = 0; /* last error correlation id */
1692 uint32_t id;

--- 23 unchanged lines hidden (view full) ---

1716 /*
1717 * if the serial number is the next expected, but I didn't send it,
1718 * abort the asoc, since someone probably just hijacked us...
1719 */
1720 if (serial_num == (asoc->asconf_seq_out + 1)) {
1721 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got unexpected next serial number! Aborting asoc!\n");
1722 sctp_abort_an_association(stcb->sctp_ep, stcb,
1723 SCTP_CAUSE_ILLEGAL_ASCONF_ACK, NULL, SCTP_SO_NOT_LOCKED);
1664{
1665 struct sctp_association *asoc;
1666 uint32_t serial_num;
1667 uint16_t ack_length;
1668 struct sctp_asconf_paramhdr *aph;
1669 struct sctp_asconf_addr *aa, *aa_next;
1670 uint32_t last_error_id = 0; /* last error correlation id */
1671 uint32_t id;

--- 23 unchanged lines hidden (view full) ---

1695 /*
1696 * if the serial number is the next expected, but I didn't send it,
1697 * abort the asoc, since someone probably just hijacked us...
1698 */
1699 if (serial_num == (asoc->asconf_seq_out + 1)) {
1700 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got unexpected next serial number! Aborting asoc!\n");
1701 sctp_abort_an_association(stcb->sctp_ep, stcb,
1702 SCTP_CAUSE_ILLEGAL_ASCONF_ACK, NULL, SCTP_SO_NOT_LOCKED);
1703 *abort_no_unlock = 1;
1724 return;
1725 }
1726 if (serial_num != asoc->asconf_seq_out) {
1727 /* got a duplicate/unexpected ASCONF-ACK */
1728 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got duplicate/unexpected serial number = %xh (expected = %xh)\n",
1729 serial_num, asoc->asconf_seq_out);
1730 return;
1731 }

--- 128 unchanged lines hidden (view full) ---

1860 asoc->asconf_sent = 0;
1861 if (!TAILQ_EMPTY(&stcb->asoc.asconf_queue)) {
1862#ifdef SCTP_TIMER_BASED_ASCONF
1863 /* we have more params, so restart our timer */
1864 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep,
1865 stcb, net);
1866#else
1867 /* we have more params, so send out more */
1704 return;
1705 }
1706 if (serial_num != asoc->asconf_seq_out) {
1707 /* got a duplicate/unexpected ASCONF-ACK */
1708 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got duplicate/unexpected serial number = %xh (expected = %xh)\n",
1709 serial_num, asoc->asconf_seq_out);
1710 return;
1711 }

--- 128 unchanged lines hidden (view full) ---

1840 asoc->asconf_sent = 0;
1841 if (!TAILQ_EMPTY(&stcb->asoc.asconf_queue)) {
1842#ifdef SCTP_TIMER_BASED_ASCONF
1843 /* we have more params, so restart our timer */
1844 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep,
1845 stcb, net);
1846#else
1847 /* we have more params, so send out more */
1868 sctp_send_asconf(stcb, net);
1848 sctp_send_asconf(stcb, net, SCTP_ADDR_NOT_LOCKED);
1869#endif
1870 }
1871}
1872
1873static uint32_t
1874sctp_is_scopeid_in_nets(struct sctp_tcb *stcb, struct sockaddr *sa)
1875{
1876 struct sockaddr_in6 *sin6, *net6;

--- 25 unchanged lines hidden (view full) ---

1902 return (0);
1903}
1904
1905/*
1906 * address management functions
1907 */
1908static void
1909sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1849#endif
1850 }
1851}
1852
1853static uint32_t
1854sctp_is_scopeid_in_nets(struct sctp_tcb *stcb, struct sockaddr *sa)
1855{
1856 struct sockaddr_in6 *sin6, *net6;

--- 25 unchanged lines hidden (view full) ---

1882 return (0);
1883}
1884
1885/*
1886 * address management functions
1887 */
1888static void
1889sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1910 struct sctp_ifa *ifa, uint16_t type)
1890 struct sctp_ifa *ifa, uint16_t type, int addr_locked)
1911{
1912 int status;
1913
1914
1915 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0 &&
1916 sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF)) {
1917 /* subset bound, no ASCONF allowed case, so ignore */
1918 return;

--- 83 unchanged lines hidden (view full) ---

2002 * sent when the state goes open.
2003 */
2004 if (status == 0 &&
2005 SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
2006#ifdef SCTP_TIMER_BASED_ASCONF
2007 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, inp,
2008 stcb, stcb->asoc.primary_destination);
2009#else
1891{
1892 int status;
1893
1894
1895 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0 &&
1896 sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF)) {
1897 /* subset bound, no ASCONF allowed case, so ignore */
1898 return;

--- 83 unchanged lines hidden (view full) ---

1982 * sent when the state goes open.
1983 */
1984 if (status == 0 &&
1985 SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
1986#ifdef SCTP_TIMER_BASED_ASCONF
1987 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, inp,
1988 stcb, stcb->asoc.primary_destination);
1989#else
2010 sctp_send_asconf(stcb, stcb->asoc.primary_destination);
1990 sctp_send_asconf(stcb, stcb->asoc.primary_destination,
1991 addr_locked);
2011#endif
2012 }
2013 }
2014 }
2015}
2016
2017
2018int

--- 225 unchanged lines hidden (view full) ---

2244 }
2245 }
2246 }
2247 }
2248 /*
2249 * If we have queued params in the open state, send out an ASCONF.
2250 */
2251 if (num_queued > 0) {
1992#endif
1993 }
1994 }
1995 }
1996}
1997
1998
1999int

--- 225 unchanged lines hidden (view full) ---

2225 }
2226 }
2227 }
2228 }
2229 /*
2230 * If we have queued params in the open state, send out an ASCONF.
2231 */
2232 if (num_queued > 0) {
2252 sctp_send_asconf(stcb, stcb->asoc.primary_destination);
2233 sctp_send_asconf(stcb, stcb->asoc.primary_destination,
2234 SCTP_ADDR_NOT_LOCKED);
2253 }
2254}
2255
2256void
2257sctp_asconf_iterator_end(void *ptr, uint32_t val)
2258{
2259 struct sctp_asconf_iterator *asc;
2260 struct sctp_ifa *ifa;

--- 18 unchanged lines hidden (view full) ---

2279
2280/*
2281 * sa is the sockaddr to ask the peer to set primary to.
2282 * returns: 0 = completed, -1 = error
2283 */
2284int32_t
2285sctp_set_primary_ip_address_sa(struct sctp_tcb *stcb, struct sockaddr *sa)
2286{
2235 }
2236}
2237
2238void
2239sctp_asconf_iterator_end(void *ptr, uint32_t val)
2240{
2241 struct sctp_asconf_iterator *asc;
2242 struct sctp_ifa *ifa;

--- 18 unchanged lines hidden (view full) ---

2261
2262/*
2263 * sa is the sockaddr to ask the peer to set primary to.
2264 * returns: 0 = completed, -1 = error
2265 */
2266int32_t
2267sctp_set_primary_ip_address_sa(struct sctp_tcb *stcb, struct sockaddr *sa)
2268{
2287 /* NOTE: we currently don't check the validity of the address! */
2269 uint32_t vrf_id;
2270 struct sctp_ifa *ifa;
2288
2271
2272 /* find the ifa for the desired set primary */
2273 if (stcb) {
2274 vrf_id = stcb->asoc.vrf_id;
2275 } else {
2276 vrf_id = SCTP_DEFAULT_VRFID;
2277 }
2278 ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED);
2279 if (ifa == NULL) {
2280 /* Invalid address */
2281 return (-1);
2282 }
2289 /* queue an ASCONF:SET_PRIM_ADDR to be sent */
2283 /* queue an ASCONF:SET_PRIM_ADDR to be sent */
2290 if (!sctp_asconf_queue_add_sa(stcb, sa, SCTP_SET_PRIM_ADDR)) {
2284 if (!sctp_asconf_queue_add(stcb, ifa, SCTP_SET_PRIM_ADDR)) {
2291 /* set primary queuing succeeded */
2292 SCTPDBG(SCTP_DEBUG_ASCONF1,
2293 "set_primary_ip_address_sa: queued on tcb=%p, ",
2294 stcb);
2295 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
2296 if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
2297#ifdef SCTP_TIMER_BASED_ASCONF
2298 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
2299 stcb->sctp_ep, stcb,
2300 stcb->asoc.primary_destination);
2301#else
2285 /* set primary queuing succeeded */
2286 SCTPDBG(SCTP_DEBUG_ASCONF1,
2287 "set_primary_ip_address_sa: queued on tcb=%p, ",
2288 stcb);
2289 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
2290 if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
2291#ifdef SCTP_TIMER_BASED_ASCONF
2292 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
2293 stcb->sctp_ep, stcb,
2294 stcb->asoc.primary_destination);
2295#else
2302 sctp_send_asconf(stcb, stcb->asoc.primary_destination);
2296 sctp_send_asconf(stcb, stcb->asoc.primary_destination,
2297 SCTP_ADDR_NOT_LOCKED);
2303#endif
2304 }
2305 } else {
2306 SCTPDBG(SCTP_DEBUG_ASCONF1, "set_primary_ip_address_sa: failed to add to queue on tcb=%p, ",
2307 stcb);
2308 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
2309 return (-1);
2310 }

--- 19 unchanged lines hidden (view full) ---

2330 stcb);
2331 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &ifa->address.sa);
2332 if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
2333#ifdef SCTP_TIMER_BASED_ASCONF
2334 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
2335 stcb->sctp_ep, stcb,
2336 stcb->asoc.primary_destination);
2337#else
2298#endif
2299 }
2300 } else {
2301 SCTPDBG(SCTP_DEBUG_ASCONF1, "set_primary_ip_address_sa: failed to add to queue on tcb=%p, ",
2302 stcb);
2303 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
2304 return (-1);
2305 }

--- 19 unchanged lines hidden (view full) ---

2325 stcb);
2326 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &ifa->address.sa);
2327 if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
2328#ifdef SCTP_TIMER_BASED_ASCONF
2329 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
2330 stcb->sctp_ep, stcb,
2331 stcb->asoc.primary_destination);
2332#else
2338 sctp_send_asconf(stcb, stcb->asoc.primary_destination);
2333 sctp_send_asconf(stcb, stcb->asoc.primary_destination,
2334 SCTP_ADDR_NOT_LOCKED);
2339#endif
2340 }
2341 }
2342 } /* for each stcb */
2343 } /* for each inp */
2344}
2345
2346static struct sockaddr *
2335#endif
2336 }
2337 }
2338 } /* for each stcb */
2339 } /* for each inp */
2340}
2341
2342static struct sockaddr *
2347sctp_find_valid_localaddr(struct sctp_tcb *stcb)
2343sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
2348{
2349 struct sctp_vrf *vrf = NULL;
2350 struct sctp_ifn *sctp_ifn;
2351 struct sctp_ifa *sctp_ifa;
2352
2344{
2345 struct sctp_vrf *vrf = NULL;
2346 struct sctp_ifn *sctp_ifn;
2347 struct sctp_ifa *sctp_ifa;
2348
2353 SCTP_IPI_ADDR_LOCK();
2349 if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2350 SCTP_IPI_ADDR_LOCK();
2354 vrf = sctp_find_vrf(stcb->asoc.vrf_id);
2355 if (vrf == NULL) {
2351 vrf = sctp_find_vrf(stcb->asoc.vrf_id);
2352 if (vrf == NULL) {
2356 SCTP_IPI_ADDR_UNLOCK();
2353 if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2354 SCTP_IPI_ADDR_UNLOCK();
2357 return (NULL);
2358 }
2359 LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
2360 if (stcb->asoc.loopback_scope == 0 &&
2361 SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
2362 /* Skip if loopback_scope not set */
2363 continue;
2364 }

--- 9 unchanged lines hidden (view full) ---

2374 }
2375 if (stcb->asoc.ipv4_local_scope == 0 &&
2376 IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))
2377 continue;
2378
2379 if (sctp_is_addr_restricted(stcb, sctp_ifa))
2380 continue;
2381 /* found a valid local v4 address to use */
2355 return (NULL);
2356 }
2357 LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
2358 if (stcb->asoc.loopback_scope == 0 &&
2359 SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
2360 /* Skip if loopback_scope not set */
2361 continue;
2362 }

--- 9 unchanged lines hidden (view full) ---

2372 }
2373 if (stcb->asoc.ipv4_local_scope == 0 &&
2374 IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))
2375 continue;
2376
2377 if (sctp_is_addr_restricted(stcb, sctp_ifa))
2378 continue;
2379 /* found a valid local v4 address to use */
2382 SCTP_IPI_ADDR_UNLOCK();
2380 if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2381 SCTP_IPI_ADDR_UNLOCK();
2383 return (&sctp_ifa->address.sa);
2384 } else if (sctp_ifa->address.sa.sa_family == AF_INET6 &&
2385 stcb->asoc.ipv6_addr_legal) {
2386 struct sockaddr_in6 *sin6;
2387
2388 if (sctp_ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
2389 continue;
2390 }

--- 5 unchanged lines hidden (view full) ---

2396 if (stcb->asoc.local_scope == 0 &&
2397 IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
2398 continue;
2399 if (stcb->asoc.site_scope == 0 &&
2400 IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))
2401 continue;
2402
2403 /* found a valid local v6 address to use */
2382 return (&sctp_ifa->address.sa);
2383 } else if (sctp_ifa->address.sa.sa_family == AF_INET6 &&
2384 stcb->asoc.ipv6_addr_legal) {
2385 struct sockaddr_in6 *sin6;
2386
2387 if (sctp_ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
2388 continue;
2389 }

--- 5 unchanged lines hidden (view full) ---

2395 if (stcb->asoc.local_scope == 0 &&
2396 IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
2397 continue;
2398 if (stcb->asoc.site_scope == 0 &&
2399 IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))
2400 continue;
2401
2402 /* found a valid local v6 address to use */
2404 SCTP_IPI_ADDR_UNLOCK();
2403 if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2404 SCTP_IPI_ADDR_UNLOCK();
2405 return (&sctp_ifa->address.sa);
2406 }
2407 }
2408 }
2409 /* no valid addresses found */
2405 return (&sctp_ifa->address.sa);
2406 }
2407 }
2408 }
2409 /* no valid addresses found */
2410 SCTP_IPI_ADDR_UNLOCK();
2410 if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2411 SCTP_IPI_ADDR_UNLOCK();
2411 return (NULL);
2412}
2413
2414static struct sockaddr *
2415sctp_find_valid_localaddr_ep(struct sctp_tcb *stcb)
2416{
2417 struct sctp_laddr *laddr;
2418

--- 12 unchanged lines hidden (view full) ---

2431 return (NULL);
2432}
2433
2434/*
2435 * builds an ASCONF chunk from queued ASCONF params.
2436 * returns NULL on error (no mbuf, no ASCONF params queued, etc).
2437 */
2438struct mbuf *
2412 return (NULL);
2413}
2414
2415static struct sockaddr *
2416sctp_find_valid_localaddr_ep(struct sctp_tcb *stcb)
2417{
2418 struct sctp_laddr *laddr;
2419

--- 12 unchanged lines hidden (view full) ---

2432 return (NULL);
2433}
2434
2435/*
2436 * builds an ASCONF chunk from queued ASCONF params.
2437 * returns NULL on error (no mbuf, no ASCONF params queued, etc).
2438 */
2439struct mbuf *
2439sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen)
2440sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
2440{
2441 struct mbuf *m_asconf, *m_asconf_chk;
2442 struct sctp_asconf_addr *aa;
2443 struct sctp_asconf_chunk *acp;
2444 struct sctp_asconf_paramhdr *aph;
2445 struct sctp_asconf_addr_param *aap;
2446 uint32_t p_length;
2447 uint32_t correlation_id = 1; /* 0 is reserved... */

--- 108 unchanged lines hidden (view full) ---

2556 /* NOTE: if the address param is optional, can skip this... */
2557 /* add any valid (existing) address... */
2558 struct sctp_ipv6addr_param *lookup;
2559 uint16_t p_size, addr_size;
2560 struct sockaddr *found_addr;
2561 caddr_t addr_ptr;
2562
2563 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL)
2441{
2442 struct mbuf *m_asconf, *m_asconf_chk;
2443 struct sctp_asconf_addr *aa;
2444 struct sctp_asconf_chunk *acp;
2445 struct sctp_asconf_paramhdr *aph;
2446 struct sctp_asconf_addr_param *aap;
2447 uint32_t p_length;
2448 uint32_t correlation_id = 1; /* 0 is reserved... */

--- 108 unchanged lines hidden (view full) ---

2557 /* NOTE: if the address param is optional, can skip this... */
2558 /* add any valid (existing) address... */
2559 struct sctp_ipv6addr_param *lookup;
2560 uint16_t p_size, addr_size;
2561 struct sockaddr *found_addr;
2562 caddr_t addr_ptr;
2563
2564 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL)
2564 found_addr = sctp_find_valid_localaddr(stcb);
2565 found_addr = sctp_find_valid_localaddr(stcb,
2566 addr_locked);
2565 else
2566 found_addr = sctp_find_valid_localaddr_ep(stcb);
2567
2568 lookup = (struct sctp_ipv6addr_param *)lookup_ptr;
2569 if (found_addr != NULL) {
2570 if (found_addr->sa_family == AF_INET6) {
2571 /* copy IPv6 address */
2572 lookup->ph.param_type =

--- 119 unchanged lines hidden (view full) ---

2692 }
2693
2694 /* see if this address really (still) exists */
2695 if (stcb) {
2696 vrf_id = stcb->asoc.vrf_id;
2697 } else {
2698 vrf_id = SCTP_DEFAULT_VRFID;
2699 }
2567 else
2568 found_addr = sctp_find_valid_localaddr_ep(stcb);
2569
2570 lookup = (struct sctp_ipv6addr_param *)lookup_ptr;
2571 if (found_addr != NULL) {
2572 if (found_addr->sa_family == AF_INET6) {
2573 /* copy IPv6 address */
2574 lookup->ph.param_type =

--- 119 unchanged lines hidden (view full) ---

2694 }
2695
2696 /* see if this address really (still) exists */
2697 if (stcb) {
2698 vrf_id = stcb->asoc.vrf_id;
2699 } else {
2700 vrf_id = SCTP_DEFAULT_VRFID;
2701 }
2700
2701 sctp_ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED);
2702 sctp_ifa = sctp_find_ifa_by_addr(sa, vrf_id,
2703 SCTP_ADDR_NOT_LOCKED);
2702 if (sctp_ifa == NULL) {
2703 /* address doesn't exist anymore */
2704 int status;
2705
2706 /* are ASCONFs allowed ? */
2707 if ((sctp_is_feature_on(stcb->sctp_ep,
2708 SCTP_PCB_FLAGS_DO_ASCONF)) &&
2709 stcb->asoc.peer_supports_asconf) {
2710 /* queue an ASCONF DEL_IP_ADDRESS */
2704 if (sctp_ifa == NULL) {
2705 /* address doesn't exist anymore */
2706 int status;
2707
2708 /* are ASCONFs allowed ? */
2709 if ((sctp_is_feature_on(stcb->sctp_ep,
2710 SCTP_PCB_FLAGS_DO_ASCONF)) &&
2711 stcb->asoc.peer_supports_asconf) {
2712 /* queue an ASCONF DEL_IP_ADDRESS */
2711 status = sctp_asconf_queue_add_sa(stcb, sa,
2712 SCTP_DEL_IP_ADDRESS);
2713 status = sctp_asconf_queue_sa_delete(stcb, sa);
2713 /*
2714 * if queued ok, and in correct state, send
2715 * out the ASCONF.
2716 */
2717 if (status == 0 &&
2718 SCTP_GET_STATE(&stcb->asoc) ==
2719 SCTP_STATE_OPEN) {
2720#ifdef SCTP_TIMER_BASED_ASCONF
2721 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
2722 stcb->sctp_ep, stcb,
2723 stcb->asoc.primary_destination);
2724#else
2714 /*
2715 * if queued ok, and in correct state, send
2716 * out the ASCONF.
2717 */
2718 if (status == 0 &&
2719 SCTP_GET_STATE(&stcb->asoc) ==
2720 SCTP_STATE_OPEN) {
2721#ifdef SCTP_TIMER_BASED_ASCONF
2722 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
2723 stcb->sctp_ep, stcb,
2724 stcb->asoc.primary_destination);
2725#else
2725 sctp_send_asconf(stcb, stcb->asoc.primary_destination);
2726 sctp_send_asconf(stcb, stcb->asoc.primary_destination,
2727 SCTP_ADDR_NOT_LOCKED);
2726#endif
2727 }
2728 }
2729 }
2730next_addr:
2731 /*
2732 * Sanity check: Make sure the length isn't 0, otherwise
2733 * we'll be stuck in this loop for a long time...

--- 141 unchanged lines hidden (view full) ---

2875 if (sctp_cmpaddr(&laddr->ifa->address.sa, init_addr)) {
2876 continue;
2877 }
2878 /* check to see if in the init-ack */
2879 if (!sctp_addr_in_initack(stcb, m, offset, length,
2880 &laddr->ifa->address.sa)) {
2881 /* try to add it */
2882 sctp_addr_mgmt_assoc(stcb->sctp_ep, stcb, laddr->ifa,
2728#endif
2729 }
2730 }
2731 }
2732next_addr:
2733 /*
2734 * Sanity check: Make sure the length isn't 0, otherwise
2735 * we'll be stuck in this loop for a long time...

--- 141 unchanged lines hidden (view full) ---

2877 if (sctp_cmpaddr(&laddr->ifa->address.sa, init_addr)) {
2878 continue;
2879 }
2880 /* check to see if in the init-ack */
2881 if (!sctp_addr_in_initack(stcb, m, offset, length,
2882 &laddr->ifa->address.sa)) {
2883 /* try to add it */
2884 sctp_addr_mgmt_assoc(stcb->sctp_ep, stcb, laddr->ifa,
2883 SCTP_ADD_IP_ADDRESS);
2885 SCTP_ADD_IP_ADDRESS, SCTP_ADDR_NOT_LOCKED);
2884 }
2885 }
2886}
2887
2888/*
2889 * makes sure that the current kernel address list is consistent with the new
2890 * association (with all addrs bound) adds addresses as necessary
2891 */

--- 31 unchanged lines hidden (view full) ---

2923 if (sctp_cmpaddr(&sctp_ifa->address.sa, init_addr)) {
2924 continue;
2925 }
2926 /* check to see if in the init-ack */
2927 if (!sctp_addr_in_initack(stcb, m, offset, length,
2928 &sctp_ifa->address.sa)) {
2929 /* try to add it */
2930 sctp_addr_mgmt_assoc(stcb->sctp_ep, stcb,
2886 }
2887 }
2888}
2889
2890/*
2891 * makes sure that the current kernel address list is consistent with the new
2892 * association (with all addrs bound) adds addresses as necessary
2893 */

--- 31 unchanged lines hidden (view full) ---

2925 if (sctp_cmpaddr(&sctp_ifa->address.sa, init_addr)) {
2926 continue;
2927 }
2928 /* check to see if in the init-ack */
2929 if (!sctp_addr_in_initack(stcb, m, offset, length,
2930 &sctp_ifa->address.sa)) {
2931 /* try to add it */
2932 sctp_addr_mgmt_assoc(stcb->sctp_ep, stcb,
2931 sctp_ifa, SCTP_ADD_IP_ADDRESS);
2933 sctp_ifa, SCTP_ADD_IP_ADDRESS,
2934 SCTP_ADDR_LOCKED);
2932 }
2933 } /* end foreach ifa */
2934 } /* end foreach ifn */
2935 SCTP_IPI_ADDR_UNLOCK();
2936}
2937
2938/*
2939 * validates an init-ack chunk (from a cookie-echo) with current addresses

--- 116 unchanged lines hidden ---
2935 }
2936 } /* end foreach ifa */
2937 } /* end foreach ifn */
2938 SCTP_IPI_ADDR_UNLOCK();
2939}
2940
2941/*
2942 * validates an init-ack chunk (from a cookie-echo) with current addresses

--- 116 unchanged lines hidden ---