1714 * Set up a global pfkey_q instance for AH, ESP, or some other consumer.
1715 */
1716 void
1717 sadb_keysock_hello(queue_t **pfkey_qp, queue_t *q, mblk_t *mp,
1718 void (*ager)(void *), void *agerarg, timeout_id_t *top, int satype)
1719 {
1720 keysock_hello_ack_t *kha;
1721 queue_t *oldq;
1722
1723 ASSERT(OTHERQ(q) != NULL);
1724
1725 /*
1726 * First, check atomically that I'm the first and only keysock
1727 * instance.
1728 *
1729 * Use OTHERQ(q), because qreply(q, mp) == putnext(OTHERQ(q), mp),
1730 * and I want this module to say putnext(*_pfkey_q, mp) for PF_KEY
1731 * messages.
1732 */
1733
1734 oldq = casptr((void **)pfkey_qp, NULL, OTHERQ(q));
1735 if (oldq != NULL) {
1736 ASSERT(oldq != q);
1737 cmn_err(CE_WARN, "Danger! Multiple keysocks on top of %s.\n",
1738 (satype == SADB_SATYPE_ESP)? "ESP" : "AH or other");
1739 freemsg(mp);
1740 return;
1741 }
1742
1743 kha = (keysock_hello_ack_t *)mp->b_rptr;
1744 kha->ks_hello_len = sizeof (keysock_hello_ack_t);
1745 kha->ks_hello_type = KEYSOCK_HELLO_ACK;
1746 kha->ks_hello_satype = (uint8_t)satype;
1747
1748 /*
1749 * If we made it past the casptr, then we have "exclusive" access
1750 * to the timeout handle. Fire it off after the default ager
1751 * interval.
1752 */
1753 *top = qtimeout(*pfkey_qp, ager, agerarg,
1754 drv_usectohz(SADB_AGE_INTERVAL_DEFAULT * 1000));
1755
1756 putnext(*pfkey_qp, mp);
1757 }
1758
1759 /*
1760 * Normalize IPv4-mapped IPv6 addresses (and prefixes) as appropriate.
1761 *
1762 * Check addresses themselves for wildcard or multicast.
1763 * Check ire table for local/non-local/broadcast.
1764 */
1765 int
1766 sadb_addrcheck(queue_t *pfkey_q, mblk_t *mp, sadb_ext_t *ext, uint_t serial,
1767 netstack_t *ns)
1768 {
1769 sadb_address_t *addr = (sadb_address_t *)ext;
1770 struct sockaddr_in *sin;
|
1714 * Set up a global pfkey_q instance for AH, ESP, or some other consumer.
1715 */
1716 void
1717 sadb_keysock_hello(queue_t **pfkey_qp, queue_t *q, mblk_t *mp,
1718 void (*ager)(void *), void *agerarg, timeout_id_t *top, int satype)
1719 {
1720 keysock_hello_ack_t *kha;
1721 queue_t *oldq;
1722
1723 ASSERT(OTHERQ(q) != NULL);
1724
1725 /*
1726 * First, check atomically that I'm the first and only keysock
1727 * instance.
1728 *
1729 * Use OTHERQ(q), because qreply(q, mp) == putnext(OTHERQ(q), mp),
1730 * and I want this module to say putnext(*_pfkey_q, mp) for PF_KEY
1731 * messages.
1732 */
1733
1734 oldq = atomic_cas_ptr((void **)pfkey_qp, NULL, OTHERQ(q));
1735 if (oldq != NULL) {
1736 ASSERT(oldq != q);
1737 cmn_err(CE_WARN, "Danger! Multiple keysocks on top of %s.\n",
1738 (satype == SADB_SATYPE_ESP)? "ESP" : "AH or other");
1739 freemsg(mp);
1740 return;
1741 }
1742
1743 kha = (keysock_hello_ack_t *)mp->b_rptr;
1744 kha->ks_hello_len = sizeof (keysock_hello_ack_t);
1745 kha->ks_hello_type = KEYSOCK_HELLO_ACK;
1746 kha->ks_hello_satype = (uint8_t)satype;
1747
1748 /*
1749 * If we made it past the atomic_cas_ptr, then we have "exclusive"
1750 * access to the timeout handle. Fire it off after the default ager
1751 * interval.
1752 */
1753 *top = qtimeout(*pfkey_qp, ager, agerarg,
1754 drv_usectohz(SADB_AGE_INTERVAL_DEFAULT * 1000));
1755
1756 putnext(*pfkey_qp, mp);
1757 }
1758
1759 /*
1760 * Normalize IPv4-mapped IPv6 addresses (and prefixes) as appropriate.
1761 *
1762 * Check addresses themselves for wildcard or multicast.
1763 * Check ire table for local/non-local/broadcast.
1764 */
1765 int
1766 sadb_addrcheck(queue_t *pfkey_q, mblk_t *mp, sadb_ext_t *ext, uint_t serial,
1767 netstack_t *ns)
1768 {
1769 sadb_address_t *addr = (sadb_address_t *)ext;
1770 struct sockaddr_in *sin;
|