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 --- |