1551 }
1552 /*
1553 * Since we've made it here, keysock_get_ext will work!
1554 */
1555 (void) keysock_get_ext(downextv,
1556 (sadb_msg_t *)downmp->b_rptr, msgdsize(downmp),
1557 keystack);
1558 keysock_passdown(ks, downmp, *satypes, downextv,
1559 B_FALSE);
1560 ++satypes;
1561 }
1562 freemsg(mp);
1563 }
1564
1565 /*
1566 * Set global to indicate we prefer an extended ACQUIRE.
1567 */
1568 atomic_inc_32(&keystack->keystack_num_extended);
1569 }
1570
1571 static void
1572 keysock_delpair_all(keysock_t *ks, mblk_t *mp, sadb_ext_t *extv[])
1573 {
1574 int i, start, finish;
1575 mblk_t *mp1 = NULL;
1576 keysock_stack_t *keystack = ks->keysock_keystack;
1577
1578 start = 0;
1579 finish = KEYSOCK_MAX_CONSUMERS - 1;
1580
1581 for (i = start; i <= finish; i++) {
1582 if (keystack->keystack_consumers[i] != NULL) {
1583 mp1 = copymsg(mp);
1584 if (mp1 == NULL) {
1585 keysock_error(ks, mp, ENOMEM,
1586 SADB_X_DIAGNOSTIC_NONE);
1587 return;
1588 }
1589 keysock_passdown(ks, mp1, i, extv, B_FALSE);
1590 }
1591 }
1592 }
1593
1594 /*
1595 * Handle PF_KEY messages.
1596 */
1597 static void
1598 keysock_parse(queue_t *q, mblk_t *mp)
1599 {
1600 sadb_msg_t *samsg;
1601 sadb_ext_t *extv[SADB_EXT_MAX + 1];
1602 keysock_t *ks = (keysock_t *)q->q_ptr;
1603 uint_t msgsize;
1604 uint8_t satype;
1605 keysock_stack_t *keystack = ks->keysock_keystack;
1606
1607 /* Make sure I'm a PF_KEY socket. (i.e. nothing's below me) */
1608 ASSERT(WR(q)->q_next == NULL);
1609
1610 samsg = (sadb_msg_t *)mp->b_rptr;
1611 ks2dbg(keystack, ("Received possible PF_KEY message, type %d.\n",
1612 samsg->sadb_msg_type));
1613
1695 keysock_error(ks, mp, EBUSY, 0);
1696 return;
1697 }
1698 /* FALLTHRU */
1699 case SADB_GETSPI:
1700 case SADB_ADD:
1701 case SADB_UPDATE:
1702 case SADB_X_UPDATEPAIR:
1703 case SADB_DELETE:
1704 case SADB_X_DELPAIR:
1705 case SADB_GET:
1706 /*
1707 * Pass down to appropriate consumer.
1708 */
1709 if (samsg->sadb_msg_satype != SADB_SATYPE_UNSPEC)
1710 keysock_passdown(ks, mp, samsg->sadb_msg_satype, extv,
1711 B_FALSE);
1712 else keysock_error(ks, mp, EINVAL,
1713 SADB_X_DIAGNOSTIC_SATYPE_NEEDED);
1714 return;
1715 case SADB_X_DELPAIR_STATE:
1716 if (samsg->sadb_msg_satype == SADB_SATYPE_UNSPEC) {
1717 keysock_delpair_all(ks, mp, extv);
1718 } else {
1719 keysock_passdown(ks, mp, samsg->sadb_msg_satype, extv,
1720 B_FALSE);
1721 }
1722 return;
1723 case SADB_ACQUIRE:
1724 /*
1725 * If I _receive_ an acquire, this means I should spread it
1726 * out to registered sockets. Unless there's an errno...
1727 *
1728 * Need ADDRESS, may have ID, SENS, and PROP, unless errno,
1729 * in which case there should be NO extensions.
1730 *
1731 * Return to registered.
1732 */
1733 if (samsg->sadb_msg_errno != 0) {
1734 satype = samsg->sadb_msg_satype;
1735 if (satype == SADB_SATYPE_UNSPEC) {
1736 if (!(ks->keysock_flags & KEYSOCK_EXTENDED)) {
1737 keysock_error(ks, mp, EINVAL,
1738 SADB_X_DIAGNOSTIC_SATYPE_NEEDED);
1739 return;
1740 }
1741 /*
1742 * Reassign satype based on the first
1757 if (samsg->sadb_msg_satype == SADB_SATYPE_UNSPEC) {
1758 keysock_error(ks, mp, EINVAL,
1759 SADB_X_DIAGNOSTIC_SATYPE_NEEDED);
1760 } else {
1761 keysock_passup(mp, samsg, 0, NULL, B_FALSE,
1762 keystack);
1763 }
1764 }
1765 return;
1766 case SADB_EXPIRE:
1767 /*
1768 * If someone sends this in, then send out to all senders.
1769 * (Save maybe ESP or AH, I have to be careful here.)
1770 *
1771 * Need ADDRESS, may have ID and SENS.
1772 *
1773 * XXX for now this is unsupported.
1774 */
1775 break;
1776 case SADB_FLUSH:
1777 /*
1778 * Nuke all SAs.
1779 *
1780 * No extensions at all. Return to all listeners.
1781 *
1782 * Question: Should I hold a lock here to prevent
1783 * additions/deletions while flushing?
1784 * Answer: No. (See keysock_passdown() for details.)
1785 */
1786 if (extv[0] != NULL) {
1787 /*
1788 * FLUSH messages shouldn't have extensions.
1789 * Return EINVAL.
1790 */
1791 ks2dbg(keystack, ("FLUSH message with extension.\n"));
1792 keysock_error(ks, mp, EINVAL, SADB_X_DIAGNOSTIC_NO_EXT);
1793 return;
1794 }
1795
1796 /* Passing down of DUMP/FLUSH messages are special. */
1797 qwriter(q, mp, keysock_do_flushdump, PERIM_INNER);
1798 return;
1799 case SADB_DUMP: /* not used by normal applications */
1800 if ((extv[0] != NULL) &&
1801 ((msgsize >
1802 (sizeof (sadb_msg_t) + sizeof (sadb_x_edump_t))) ||
1803 (extv[SADB_X_EXT_EDUMP] == NULL))) {
1804 keysock_error(ks, mp, EINVAL,
1805 SADB_X_DIAGNOSTIC_NO_EXT);
1806 return;
1807 }
1808 qwriter(q, mp, keysock_do_flushdump, PERIM_INNER);
1809 return;
1810 case SADB_X_PROMISC:
1811 /*
1812 * Promiscuous processing message.
1813 */
1814 if (samsg->sadb_msg_satype == 0)
1815 ks->keysock_flags &= ~KEYSOCK_PROMISC;
1816 else
1817 ks->keysock_flags |= KEYSOCK_PROMISC;
1818 keysock_passup(mp, samsg, ks->keysock_serial, NULL, B_FALSE,
1819 keystack);
1820 return;
1821 case SADB_X_INVERSE_ACQUIRE:
1822 keysock_inverse_acquire(mp, samsg, extv, ks);
1823 return;
1824 default:
1825 ks2dbg(keystack, ("Got unknown message type %d.\n",
1826 samsg->sadb_msg_type));
1827 keysock_error(ks, mp, EINVAL, SADB_X_DIAGNOSTIC_UNKNOWN_MSG);
1828 return;
1829 }
|
1551 }
1552 /*
1553 * Since we've made it here, keysock_get_ext will work!
1554 */
1555 (void) keysock_get_ext(downextv,
1556 (sadb_msg_t *)downmp->b_rptr, msgdsize(downmp),
1557 keystack);
1558 keysock_passdown(ks, downmp, *satypes, downextv,
1559 B_FALSE);
1560 ++satypes;
1561 }
1562 freemsg(mp);
1563 }
1564
1565 /*
1566 * Set global to indicate we prefer an extended ACQUIRE.
1567 */
1568 atomic_inc_32(&keystack->keystack_num_extended);
1569 }
1570
1571 /*
1572 * Handle PF_KEY messages.
1573 */
1574 static void
1575 keysock_parse(queue_t *q, mblk_t *mp)
1576 {
1577 sadb_msg_t *samsg;
1578 sadb_ext_t *extv[SADB_EXT_MAX + 1];
1579 keysock_t *ks = (keysock_t *)q->q_ptr;
1580 uint_t msgsize;
1581 uint8_t satype;
1582 keysock_stack_t *keystack = ks->keysock_keystack;
1583
1584 /* Make sure I'm a PF_KEY socket. (i.e. nothing's below me) */
1585 ASSERT(WR(q)->q_next == NULL);
1586
1587 samsg = (sadb_msg_t *)mp->b_rptr;
1588 ks2dbg(keystack, ("Received possible PF_KEY message, type %d.\n",
1589 samsg->sadb_msg_type));
1590
1672 keysock_error(ks, mp, EBUSY, 0);
1673 return;
1674 }
1675 /* FALLTHRU */
1676 case SADB_GETSPI:
1677 case SADB_ADD:
1678 case SADB_UPDATE:
1679 case SADB_X_UPDATEPAIR:
1680 case SADB_DELETE:
1681 case SADB_X_DELPAIR:
1682 case SADB_GET:
1683 /*
1684 * Pass down to appropriate consumer.
1685 */
1686 if (samsg->sadb_msg_satype != SADB_SATYPE_UNSPEC)
1687 keysock_passdown(ks, mp, samsg->sadb_msg_satype, extv,
1688 B_FALSE);
1689 else keysock_error(ks, mp, EINVAL,
1690 SADB_X_DIAGNOSTIC_SATYPE_NEEDED);
1691 return;
1692 case SADB_ACQUIRE:
1693 /*
1694 * If I _receive_ an acquire, this means I should spread it
1695 * out to registered sockets. Unless there's an errno...
1696 *
1697 * Need ADDRESS, may have ID, SENS, and PROP, unless errno,
1698 * in which case there should be NO extensions.
1699 *
1700 * Return to registered.
1701 */
1702 if (samsg->sadb_msg_errno != 0) {
1703 satype = samsg->sadb_msg_satype;
1704 if (satype == SADB_SATYPE_UNSPEC) {
1705 if (!(ks->keysock_flags & KEYSOCK_EXTENDED)) {
1706 keysock_error(ks, mp, EINVAL,
1707 SADB_X_DIAGNOSTIC_SATYPE_NEEDED);
1708 return;
1709 }
1710 /*
1711 * Reassign satype based on the first
1726 if (samsg->sadb_msg_satype == SADB_SATYPE_UNSPEC) {
1727 keysock_error(ks, mp, EINVAL,
1728 SADB_X_DIAGNOSTIC_SATYPE_NEEDED);
1729 } else {
1730 keysock_passup(mp, samsg, 0, NULL, B_FALSE,
1731 keystack);
1732 }
1733 }
1734 return;
1735 case SADB_EXPIRE:
1736 /*
1737 * If someone sends this in, then send out to all senders.
1738 * (Save maybe ESP or AH, I have to be careful here.)
1739 *
1740 * Need ADDRESS, may have ID and SENS.
1741 *
1742 * XXX for now this is unsupported.
1743 */
1744 break;
1745 case SADB_FLUSH:
1746 case SADB_DUMP: /* not used by normal applications */
1747 /*
1748 * Nuke all SAs.
1749 *
1750 * No extensions at all. Return to all listeners.
1751 *
1752 * Question: Should I hold a lock here to prevent
1753 * additions/deletions while flushing?
1754 * Answer: No. (See keysock_passdown() for details.)
1755 */
1756 if (extv[0] != NULL) {
1757 /*
1758 * FLUSH messages shouldn't have extensions.
1759 * Return EINVAL.
1760 */
1761 ks2dbg(keystack, ("FLUSH message with extension.\n"));
1762 keysock_error(ks, mp, EINVAL, SADB_X_DIAGNOSTIC_NO_EXT);
1763 return;
1764 }
1765
1766 /* Passing down of DUMP/FLUSH messages are special. */
1767 qwriter(q, mp, keysock_do_flushdump, PERIM_INNER);
1768 return;
1769 case SADB_X_PROMISC:
1770 /*
1771 * Promiscuous processing message.
1772 */
1773 if (samsg->sadb_msg_satype == 0)
1774 ks->keysock_flags &= ~KEYSOCK_PROMISC;
1775 else
1776 ks->keysock_flags |= KEYSOCK_PROMISC;
1777 keysock_passup(mp, samsg, ks->keysock_serial, NULL, B_FALSE,
1778 keystack);
1779 return;
1780 case SADB_X_INVERSE_ACQUIRE:
1781 keysock_inverse_acquire(mp, samsg, extv, ks);
1782 return;
1783 default:
1784 ks2dbg(keystack, ("Got unknown message type %d.\n",
1785 samsg->sadb_msg_type));
1786 keysock_error(ks, mp, EINVAL, SADB_X_DIAGNOSTIC_UNKNOWN_MSG);
1787 return;
1788 }
|