Print this page
8529 Extended and regular SADB_ACQUIREs should share address extension code
Portions contributed by: Bayard Bell <buffer.g.overflow@gmail.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/inet/ip/ipsecah.c
          +++ new/usr/src/uts/common/inet/ip/ipsecah.c
↓ open down ↓ 88 lines elided ↑ open up ↑
  89   89          { 1,    1800,                   90,     "ipsecah_larval_timeout"},
  90   90          /* Default lifetime values for ACQUIRE messages. */
  91   91          { 0,    0xffffffffU,            0,      "ipsecah_default_soft_bytes"},
  92   92          { 0,    0xffffffffU,            0,      "ipsecah_default_hard_bytes"},
  93   93          { 0,    0xffffffffU,            24000,  "ipsecah_default_soft_addtime"},
  94   94          { 0,    0xffffffffU,            28800,  "ipsecah_default_hard_addtime"},
  95   95          { 0,    0xffffffffU,            0,      "ipsecah_default_soft_usetime"},
  96   96          { 0,    0xffffffffU,            0,      "ipsecah_default_hard_usetime"},
  97   97          { 0,    1,                      0,      "ipsecah_log_unknown_spi"},
  98   98  };
  99      -#define ipsecah_debug                   ipsecah_params[0].ipsecah_param_value
 100      -#define ipsecah_age_interval            ipsecah_params[1].ipsecah_param_value
 101      -#define ipsecah_age_int_max             ipsecah_params[1].ipsecah_param_max
 102      -#define ipsecah_reap_delay              ipsecah_params[2].ipsecah_param_value
 103      -#define ipsecah_replay_size             ipsecah_params[3].ipsecah_param_value
 104      -#define ipsecah_acquire_timeout         ipsecah_params[4].ipsecah_param_value
 105      -#define ipsecah_larval_timeout          ipsecah_params[5].ipsecah_param_value
 106      -#define ipsecah_default_soft_bytes      ipsecah_params[6].ipsecah_param_value
 107      -#define ipsecah_default_hard_bytes      ipsecah_params[7].ipsecah_param_value
 108      -#define ipsecah_default_soft_addtime    ipsecah_params[8].ipsecah_param_value
 109      -#define ipsecah_default_hard_addtime    ipsecah_params[9].ipsecah_param_value
 110      -#define ipsecah_default_soft_usetime    ipsecah_params[10].ipsecah_param_value
 111      -#define ipsecah_default_hard_usetime    ipsecah_params[11].ipsecah_param_value
 112      -#define ipsecah_log_unknown_spi         ipsecah_params[12].ipsecah_param_value
 113   99  
 114  100  #define ah0dbg(a)       printf a
 115  101  /* NOTE:  != 0 instead of > 0 so lint doesn't complain. */
 116  102  #define ah1dbg(ahstack, a)      if (ahstack->ipsecah_debug != 0) printf a
 117  103  #define ah2dbg(ahstack, a)      if (ahstack->ipsecah_debug > 1) printf a
 118  104  #define ah3dbg(ahstack, a)      if (ahstack->ipsecah_debug > 2) printf a
 119  105  
 120  106  /*
 121  107   * XXX This is broken. Padding should be determined dynamically
 122  108   * depending on the ICV size and IP version number so that the
↓ open down ↓ 19 lines elided ↑ open up ↑
 142  128      boolean_t, ipsecah_stack_t *);
 143  129  static void ah_getspi(mblk_t *, keysock_in_t *, ipsecah_stack_t *);
 144  130  static void ah_inbound_restart(mblk_t *, ip_recv_attr_t *);
 145  131  
 146  132  static mblk_t *ah_outbound(mblk_t *, ip_xmit_attr_t *);
 147  133  static void ah_outbound_finish(mblk_t *, ip_xmit_attr_t *);
 148  134  
 149  135  static int ipsecah_open(queue_t *, dev_t *, int, int, cred_t *);
 150  136  static int ipsecah_close(queue_t *);
 151  137  static void ipsecah_wput(queue_t *, mblk_t *);
 152      -static void ah_send_acquire(ipsacq_t *, mblk_t *, netstack_t *);
 153  138  static boolean_t ah_register_out(uint32_t, uint32_t, uint_t, ipsecah_stack_t *,
 154  139      cred_t *);
 155  140  static void     *ipsecah_stack_init(netstackid_t stackid, netstack_t *ns);
 156  141  static void     ipsecah_stack_fini(netstackid_t stackid, void *arg);
 157  142  
 158  143  /* Setable in /etc/system */
 159  144  uint32_t ah_hash_size = IPSEC_DEFAULT_HASH_SIZE;
 160  145  
 161  146  static taskq_t *ah_taskq;
 162  147  
↓ open down ↓ 250 lines elided ↑ open up ↑
 413  398          ahp = (ipsecahparam_t *)kmem_alloc(sizeof (lcl_param_arr), KM_SLEEP);
 414  399          ahstack->ipsecah_params = ahp;
 415  400          bcopy(lcl_param_arr, ahp, sizeof (lcl_param_arr));
 416  401  
 417  402          (void) ipsecah_param_register(&ahstack->ipsecah_g_nd, ahp,
 418  403              A_CNT(lcl_param_arr));
 419  404  
 420  405          (void) ah_kstat_init(ahstack, stackid);
 421  406  
 422  407          ahstack->ah_sadb.s_acquire_timeout = &ahstack->ipsecah_acquire_timeout;
 423      -        ahstack->ah_sadb.s_acqfn = ah_send_acquire;
 424  408          sadbp_init("AH", &ahstack->ah_sadb, SADB_SATYPE_AH, ah_hash_size,
 425  409              ahstack->ipsecah_netstack);
 426  410  
 427  411          mutex_init(&ahstack->ipsecah_param_lock, NULL, MUTEX_DEFAULT, 0);
 428  412  
 429  413          ip_drop_register(&ahstack->ah_dropper, "IPsec AH");
 430  414          return (ahstack);
 431  415  }
 432  416  
 433  417  /*
↓ open down ↓ 10 lines elided ↑ open up ↑
 444  428   * Destroy things for AH for one stack... Never called?
 445  429   */
 446  430  static void
 447  431  ipsecah_stack_fini(netstackid_t stackid, void *arg)
 448  432  {
 449  433          ipsecah_stack_t *ahstack = (ipsecah_stack_t *)arg;
 450  434  
 451  435          if (ahstack->ah_pfkey_q != NULL) {
 452  436                  (void) quntimeout(ahstack->ah_pfkey_q, ahstack->ah_event);
 453  437          }
 454      -        ahstack->ah_sadb.s_acqfn = NULL;
 455  438          ahstack->ah_sadb.s_acquire_timeout = NULL;
 456  439          sadbp_destroy(&ahstack->ah_sadb, ahstack->ipsecah_netstack);
 457  440          ip_drop_unregister(&ahstack->ah_dropper);
 458  441          mutex_destroy(&ahstack->ipsecah_param_lock);
 459  442          nd_free(&ahstack->ipsecah_g_nd);
 460  443  
 461  444          kmem_free(ahstack->ipsecah_params, sizeof (lcl_param_arr));
 462  445          ahstack->ipsecah_params = NULL;
 463  446          kstat_delete_netstack(ahstack->ah_ksp, stackid);
 464  447          ahstack->ah_ksp = NULL;
↓ open down ↓ 1264 lines elided ↑ open up ↑
1729 1712           */
1730 1713          if (inbound) {
1731 1714                  IPSA_REFRELE(outassoc);
1732 1715          } else {
1733 1716                  IPSA_REFRELE(inassoc);
1734 1717          }
1735 1718  
1736 1719          return (inrc && outrc);
1737 1720  }
1738 1721  
1739      -/*
1740      - * Perform the really difficult work of inserting the proposed situation.
1741      - * Called while holding the algorithm lock.
1742      - */
1743      -static void
1744      -ah_insert_prop(sadb_prop_t *prop, ipsacq_t *acqrec, uint_t combs,
1745      -    netstack_t *ns)
1746      -{
1747      -        sadb_comb_t *comb = (sadb_comb_t *)(prop + 1);
1748      -        ipsec_action_t *ap;
1749      -        ipsec_prot_t *prot;
1750      -        ipsecah_stack_t *ahstack = ns->netstack_ipsecah;
1751      -        ipsec_stack_t   *ipss = ns->netstack_ipsec;
1752      -
1753      -        ASSERT(RW_READ_HELD(&ipss->ipsec_alg_lock));
1754      -
1755      -        prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
1756      -        prop->sadb_prop_len = SADB_8TO64(sizeof (sadb_prop_t));
1757      -        *(uint32_t *)(&prop->sadb_prop_replay) = 0;     /* Quick zero-out! */
1758      -
1759      -        prop->sadb_prop_replay = ahstack->ipsecah_replay_size;
1760      -
1761      -        /*
1762      -         * Based upon algorithm properties, and what-not, prioritize a
1763      -         * proposal, based on the ordering of the AH algorithms in the
1764      -         * alternatives in the policy rule or socket that was placed
1765      -         * in the acquire record.
1766      -         */
1767      -
1768      -        for (ap = acqrec->ipsacq_act; ap != NULL;
1769      -            ap = ap->ipa_next) {
1770      -                ipsec_alginfo_t *aalg;
1771      -
1772      -                if ((ap->ipa_act.ipa_type != IPSEC_POLICY_APPLY) ||
1773      -                    (!ap->ipa_act.ipa_apply.ipp_use_ah))
1774      -                        continue;
1775      -
1776      -                prot = &ap->ipa_act.ipa_apply;
1777      -
1778      -                ASSERT(prot->ipp_auth_alg > 0);
1779      -
1780      -                aalg = ipss->ipsec_alglists[IPSEC_ALG_AUTH]
1781      -                    [prot->ipp_auth_alg];
1782      -                if (aalg == NULL || !ALG_VALID(aalg))
1783      -                        continue;
1784      -
1785      -                /* XXX check aalg for duplicates??.. */
1786      -
1787      -                comb->sadb_comb_flags = 0;
1788      -                comb->sadb_comb_reserved = 0;
1789      -                comb->sadb_comb_encrypt = 0;
1790      -                comb->sadb_comb_encrypt_minbits = 0;
1791      -                comb->sadb_comb_encrypt_maxbits = 0;
1792      -
1793      -                comb->sadb_comb_auth = aalg->alg_id;
1794      -                comb->sadb_comb_auth_minbits =
1795      -                    MAX(prot->ipp_ah_minbits, aalg->alg_ef_minbits);
1796      -                comb->sadb_comb_auth_maxbits =
1797      -                    MIN(prot->ipp_ah_maxbits, aalg->alg_ef_maxbits);
1798      -
1799      -                /*
1800      -                 * The following may be based on algorithm
1801      -                 * properties, but in the meantime, we just pick
1802      -                 * some good, sensible numbers.  Key mgmt. can
1803      -                 * (and perhaps should) be the place to finalize
1804      -                 * such decisions.
1805      -                 */
1806      -
1807      -                /*
1808      -                 * No limits on allocations, since we really don't
1809      -                 * support that concept currently.
1810      -                 */
1811      -                comb->sadb_comb_soft_allocations = 0;
1812      -                comb->sadb_comb_hard_allocations = 0;
1813      -
1814      -                /*
1815      -                 * These may want to come from policy rule..
1816      -                 */
1817      -                comb->sadb_comb_soft_bytes =
1818      -                    ahstack->ipsecah_default_soft_bytes;
1819      -                comb->sadb_comb_hard_bytes =
1820      -                    ahstack->ipsecah_default_hard_bytes;
1821      -                comb->sadb_comb_soft_addtime =
1822      -                    ahstack->ipsecah_default_soft_addtime;
1823      -                comb->sadb_comb_hard_addtime =
1824      -                    ahstack->ipsecah_default_hard_addtime;
1825      -                comb->sadb_comb_soft_usetime =
1826      -                    ahstack->ipsecah_default_soft_usetime;
1827      -                comb->sadb_comb_hard_usetime =
1828      -                    ahstack->ipsecah_default_hard_usetime;
1829      -
1830      -                prop->sadb_prop_len += SADB_8TO64(sizeof (*comb));
1831      -                if (--combs == 0)
1832      -                        return; /* out of space.. */
1833      -                comb++;
1834      -        }
1835      -}
1836      -
1837      -/*
1838      - * Prepare and actually send the SADB_ACQUIRE message to PF_KEY.
1839      - */
1840      -static void
1841      -ah_send_acquire(ipsacq_t *acqrec, mblk_t *extended, netstack_t *ns)
1842      -{
1843      -        uint_t combs;
1844      -        sadb_msg_t *samsg;
1845      -        sadb_prop_t *prop;
1846      -        mblk_t *pfkeymp, *msgmp;
1847      -        ipsecah_stack_t *ahstack = ns->netstack_ipsecah;
1848      -        ipsec_stack_t   *ipss = ns->netstack_ipsec;
1849      -
1850      -        AH_BUMP_STAT(ahstack, acquire_requests);
1851      -
1852      -        if (ahstack->ah_pfkey_q == NULL) {
1853      -                mutex_exit(&acqrec->ipsacq_lock);
1854      -                return;
1855      -        }
1856      -
1857      -        /* Set up ACQUIRE. */
1858      -        pfkeymp = sadb_setup_acquire(acqrec, SADB_SATYPE_AH,
1859      -            ns->netstack_ipsec);
1860      -        if (pfkeymp == NULL) {
1861      -                ah0dbg(("sadb_setup_acquire failed.\n"));
1862      -                mutex_exit(&acqrec->ipsacq_lock);
1863      -                return;
1864      -        }
1865      -        ASSERT(RW_READ_HELD(&ipss->ipsec_alg_lock));
1866      -        combs = ipss->ipsec_nalgs[IPSEC_ALG_AUTH];
1867      -        msgmp = pfkeymp->b_cont;
1868      -        samsg = (sadb_msg_t *)(msgmp->b_rptr);
1869      -
1870      -        /* Insert proposal here. */
1871      -
1872      -        prop = (sadb_prop_t *)(((uint64_t *)samsg) + samsg->sadb_msg_len);
1873      -        ah_insert_prop(prop, acqrec, combs, ns);
1874      -        samsg->sadb_msg_len += prop->sadb_prop_len;
1875      -        msgmp->b_wptr += SADB_64TO8(samsg->sadb_msg_len);
1876      -
1877      -        rw_exit(&ipss->ipsec_alg_lock);
1878      -
1879      -        /*
1880      -         * Must mutex_exit() before sending PF_KEY message up, in
1881      -         * order to avoid recursive mutex_enter() if there are no registered
1882      -         * listeners.
1883      -         *
1884      -         * Once I've sent the message, I'm cool anyway.
1885      -         */
1886      -        mutex_exit(&acqrec->ipsacq_lock);
1887      -        if (extended != NULL) {
1888      -                putnext(ahstack->ah_pfkey_q, extended);
1889      -        }
1890      -        putnext(ahstack->ah_pfkey_q, pfkeymp);
1891      -}
1892      -
1893 1722  /* Refactor me */
1894 1723  /*
1895 1724   * Handle the SADB_GETSPI message.  Create a larval SA.
1896 1725   */
1897 1726  static void
1898 1727  ah_getspi(mblk_t *mp, keysock_in_t *ksi, ipsecah_stack_t *ahstack)
1899 1728  {
1900 1729          ipsa_t *newbie, *target;
1901 1730          isaf_t *outbound, *inbound;
1902 1731          int rc, diagnostic;
↓ open down ↓ 2111 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX