Print this page
5045 use atomic_{inc,dec}_* instead of atomic_add_*


 281         uint32_t                ipa_refs;               /* refcount */
 282         ipsec_act_t             ipa_act;
 283         /*
 284          * The following bits are equivalent to an OR of bits included in the
 285          * ipau_apply fields of this and subsequent actions in an
 286          * action chain; this is an optimization for the sake of
 287          * ipsec_out_process() in ip.c and a few other places.
 288          */
 289         unsigned int
 290                 ipa_hval: 8,
 291                 ipa_allow_clear:1,              /* rule allows cleartext? */
 292                 ipa_want_ah:1,                  /* an action wants ah */
 293                 ipa_want_esp:1,                 /* an action wants esp */
 294                 ipa_want_se:1,                  /* an action wants se */
 295                 ipa_want_unique:1,              /* want unique sa's */
 296                 ipa_pad:19;
 297         uint32_t                ipa_ovhd;       /* per-packet encap ovhd */
 298 } ipsec_action_t;
 299 
 300 #define IPACT_REFHOLD(ipa) {                    \
 301         atomic_add_32(&(ipa)->ipa_refs, 1);      \
 302         ASSERT((ipa)->ipa_refs != 0);        \
 303 }
 304 #define IPACT_REFRELE(ipa) {                                    \
 305         ASSERT((ipa)->ipa_refs != 0);                                \
 306         membar_exit();                                          \
 307         if (atomic_add_32_nv(&(ipa)->ipa_refs, -1) == 0) \
 308                 ipsec_action_free(ipa);                         \
 309         (ipa) = 0;                                              \
 310 }
 311 
 312 /*
 313  * For now, use a trivially sized hash table for actions.
 314  * In the future we can add the structure canonicalization necessary
 315  * to get the hash function to behave correctly..
 316  */
 317 #define IPSEC_ACTION_HASH_SIZE 1
 318 
 319 /*
 320  * Merged address structure, for cheezy address-family independent
 321  * matches in policy code.
 322  */
 323 
 324 typedef union ipsec_addr
 325 {
 326         in6_addr_t      ipsad_v6;
 327         in_addr_t       ipsad_v4;


 397  * the parent rule structure.  If the selector is simple enough to
 398  * allow hashing, it gets filed under ipsec_policy_root_t->ipr_hash.
 399  * Otherwise it goes onto a linked list in ipsec_policy_root_t->ipr_nonhash[af]
 400  *
 401  * In addition, we file the rule into an avl tree keyed by the rule index.
 402  * (Duplicate rules are permitted; the comparison function breaks ties).
 403  */
 404 struct ipsec_policy_s
 405 {
 406         HASH_LINK(ipsp_hash, struct ipsec_policy_s);
 407         avl_node_t              ipsp_byid;
 408         uint64_t                ipsp_index;     /* unique id */
 409         uint32_t                ipsp_prio;      /* rule priority */
 410         uint32_t                ipsp_refs;
 411         ipsec_sel_t             *ipsp_sel;      /* selector set (shared) */
 412         ipsec_action_t          *ipsp_act;      /* action (may be shared) */
 413         netstack_t              *ipsp_netstack; /* No netstack_hold */
 414 };
 415 
 416 #define IPPOL_REFHOLD(ipp) {                    \
 417         atomic_add_32(&(ipp)->ipsp_refs, 1);     \
 418         ASSERT((ipp)->ipsp_refs != 0);               \
 419 }
 420 #define IPPOL_REFRELE(ipp) {                                    \
 421         ASSERT((ipp)->ipsp_refs != 0);                               \
 422         membar_exit();                                          \
 423         if (atomic_add_32_nv(&(ipp)->ipsp_refs, -1) == 0)        \
 424                 ipsec_policy_free(ipp);                         \
 425         (ipp) = 0;                                              \
 426 }
 427 
 428 #define IPPOL_UNCHAIN(php, ip)                                  \
 429         HASHLIST_UNCHAIN((ip), ipsp_hash);                      \
 430         avl_remove(&(php)->iph_rulebyid, (ip));                  \
 431         IPPOL_REFRELE(ip);
 432 
 433 /*
 434  * Policy ruleset.  One per (protocol * direction) for system policy.
 435  */
 436 
 437 #define IPSEC_AF_V4     0
 438 #define IPSEC_AF_V6     1
 439 #define IPSEC_NAF       2
 440 
 441 typedef struct ipsec_policy_root_s
 442 {
 443         ipsec_policy_t          *ipr_nonhash[IPSEC_NAF];
 444         int                     ipr_nchains;
 445         ipsec_policy_hash_t     *ipr_hash;
 446 } ipsec_policy_root_t;
 447 
 448 /*
 449  * Policy head.  One for system policy; there may also be one present
 450  * on ill_t's with interface-specific policy, as well as one present
 451  * for sockets with per-socket policy allocated.
 452  */
 453 
 454 typedef struct ipsec_policy_head_s
 455 {
 456         uint32_t        iph_refs;
 457         krwlock_t       iph_lock;
 458         uint64_t        iph_gen; /* generation number */
 459         ipsec_policy_root_t iph_root[IPSEC_NTYPES];
 460         avl_tree_t      iph_rulebyid;
 461 } ipsec_policy_head_t;
 462 
 463 #define IPPH_REFHOLD(iph) {                     \
 464         atomic_add_32(&(iph)->iph_refs, 1);      \
 465         ASSERT((iph)->iph_refs != 0);                \
 466 }
 467 #define IPPH_REFRELE(iph, ns) {                                 \
 468         ASSERT((iph)->iph_refs != 0);                                \
 469         membar_exit();                                          \
 470         if (atomic_add_32_nv(&(iph)->iph_refs, -1) == 0) \
 471                 ipsec_polhead_free(iph, ns);                    \
 472         (iph) = 0;                                              \
 473 }
 474 
 475 /*
 476  * IPsec fragment related structures
 477  */
 478 
 479 typedef struct ipsec_fragcache_entry {
 480         struct ipsec_fragcache_entry *itpfe_next;       /* hash list chain */
 481         mblk_t *itpfe_fraglist;                 /* list of fragments */
 482         time_t itpfe_exp;                       /* time when entry is stale */
 483         int itpfe_depth;                        /* # of fragments in list */
 484         ipsec_addr_t itpfe_frag_src;
 485         ipsec_addr_t itpfe_frag_dst;
 486 #define itpfe_src itpfe_frag_src.ipsad_v4
 487 #define itpfe_src6 itpfe_frag_src.ipsad_v6
 488 #define itpfe_dst itpfe_frag_dst.ipsad_v4
 489 #define itpfe_dst6 itpfe_frag_dst.ipsad_v6
 490         uint32_t itpfe_id;                      /* IP datagram ID */


 531 #define ITPF_I_PER_PORT_SECURITY 0x20
 532 #define ITPF_IFLAGS 0x38
 533 
 534 /* NOTE:  f cannot be an expression. */
 535 #define ITPF_CLONE(f) (f) = (((f) & ITPF_PFLAGS) | \
 536             (((f) & ITPF_PFLAGS) << ITPF_SHIFT));
 537 #define ITPF_SWAP(f) (f) = ((((f) & ITPF_PFLAGS) << ITPF_SHIFT) | \
 538             (((f) & ITPF_IFLAGS) >> ITPF_SHIFT))
 539 
 540 #define ITP_P_ISACTIVE(itp, iph) ((itp)->itp_flags & \
 541         (((itp)->itp_policy == (iph)) ? ITPF_P_ACTIVE : ITPF_I_ACTIVE))
 542 
 543 #define ITP_P_ISTUNNEL(itp, iph) ((itp)->itp_flags & \
 544         (((itp)->itp_policy == (iph)) ? ITPF_P_TUNNEL : ITPF_I_TUNNEL))
 545 
 546 #define ITP_P_ISPERPORT(itp, iph) ((itp)->itp_flags & \
 547         (((itp)->itp_policy == (iph)) ? ITPF_P_PER_PORT_SECURITY : \
 548         ITPF_I_PER_PORT_SECURITY))
 549 
 550 #define ITP_REFHOLD(itp) { \
 551         atomic_add_32(&((itp)->itp_refcnt), 1);  \
 552         ASSERT((itp)->itp_refcnt != 0); \
 553 }
 554 
 555 #define ITP_REFRELE(itp, ns) { \
 556         ASSERT((itp)->itp_refcnt != 0); \
 557         membar_exit(); \
 558         if (atomic_add_32_nv(&((itp)->itp_refcnt), -1) == 0) \
 559                 itp_free(itp, ns); \
 560 }
 561 
 562 /*
 563  * Certificate identity.
 564  */
 565 
 566 typedef struct ipsid_s
 567 {
 568         struct ipsid_s *ipsid_next;
 569         struct ipsid_s **ipsid_ptpn;
 570         uint32_t        ipsid_refcnt;
 571         int             ipsid_type;     /* id type */
 572         char            *ipsid_cid;     /* certificate id string */
 573 } ipsid_t;
 574 
 575 /*
 576  * ipsid_t reference hold/release macros, just like ipsa versions.
 577  */
 578 
 579 #define IPSID_REFHOLD(ipsid) {                  \
 580         atomic_add_32(&(ipsid)->ipsid_refcnt, 1);        \
 581         ASSERT((ipsid)->ipsid_refcnt != 0);  \
 582 }
 583 
 584 /*
 585  * Decrement the reference count on the ID.  Someone else will clean up
 586  * after us later.
 587  */
 588 
 589 #define IPSID_REFRELE(ipsid) {                                  \
 590         membar_exit();                                          \
 591         atomic_add_32(&(ipsid)->ipsid_refcnt, -1);               \
 592 }
 593 
 594 /*
 595  * Following are the estimates of what the maximum AH and ESP header size
 596  * would be. This is used to tell the upper layer the right value of MSS
 597  * it should use without consulting AH/ESP. If the size is something
 598  * different from this, ULP will learn the right one through
 599  * ICMP_FRAGMENTATION_NEEDED messages generated locally.
 600  *
 601  * AH : 12 bytes of constant header + 32 bytes of ICV checksum (SHA-512).
 602  */
 603 #define IPSEC_MAX_AH_HDR_SIZE   (44)
 604 
 605 /*
 606  * ESP : Is a bit more complex...
 607  *
 608  * A system of one inequality and one equation MUST be solved for proper ESP
 609  * overhead.  The inequality is:
 610  *
 611  *    MTU - sizeof (IP header + options) >=




 281         uint32_t                ipa_refs;               /* refcount */
 282         ipsec_act_t             ipa_act;
 283         /*
 284          * The following bits are equivalent to an OR of bits included in the
 285          * ipau_apply fields of this and subsequent actions in an
 286          * action chain; this is an optimization for the sake of
 287          * ipsec_out_process() in ip.c and a few other places.
 288          */
 289         unsigned int
 290                 ipa_hval: 8,
 291                 ipa_allow_clear:1,              /* rule allows cleartext? */
 292                 ipa_want_ah:1,                  /* an action wants ah */
 293                 ipa_want_esp:1,                 /* an action wants esp */
 294                 ipa_want_se:1,                  /* an action wants se */
 295                 ipa_want_unique:1,              /* want unique sa's */
 296                 ipa_pad:19;
 297         uint32_t                ipa_ovhd;       /* per-packet encap ovhd */
 298 } ipsec_action_t;
 299 
 300 #define IPACT_REFHOLD(ipa) {                    \
 301         atomic_inc_32(&(ipa)->ipa_refs); \
 302         ASSERT((ipa)->ipa_refs != 0);        \
 303 }
 304 #define IPACT_REFRELE(ipa) {                                    \
 305         ASSERT((ipa)->ipa_refs != 0);                                \
 306         membar_exit();                                          \
 307         if (atomic_dec_32_nv(&(ipa)->ipa_refs) == 0)     \
 308                 ipsec_action_free(ipa);                         \
 309         (ipa) = 0;                                              \
 310 }
 311 
 312 /*
 313  * For now, use a trivially sized hash table for actions.
 314  * In the future we can add the structure canonicalization necessary
 315  * to get the hash function to behave correctly..
 316  */
 317 #define IPSEC_ACTION_HASH_SIZE 1
 318 
 319 /*
 320  * Merged address structure, for cheezy address-family independent
 321  * matches in policy code.
 322  */
 323 
 324 typedef union ipsec_addr
 325 {
 326         in6_addr_t      ipsad_v6;
 327         in_addr_t       ipsad_v4;


 397  * the parent rule structure.  If the selector is simple enough to
 398  * allow hashing, it gets filed under ipsec_policy_root_t->ipr_hash.
 399  * Otherwise it goes onto a linked list in ipsec_policy_root_t->ipr_nonhash[af]
 400  *
 401  * In addition, we file the rule into an avl tree keyed by the rule index.
 402  * (Duplicate rules are permitted; the comparison function breaks ties).
 403  */
 404 struct ipsec_policy_s
 405 {
 406         HASH_LINK(ipsp_hash, struct ipsec_policy_s);
 407         avl_node_t              ipsp_byid;
 408         uint64_t                ipsp_index;     /* unique id */
 409         uint32_t                ipsp_prio;      /* rule priority */
 410         uint32_t                ipsp_refs;
 411         ipsec_sel_t             *ipsp_sel;      /* selector set (shared) */
 412         ipsec_action_t          *ipsp_act;      /* action (may be shared) */
 413         netstack_t              *ipsp_netstack; /* No netstack_hold */
 414 };
 415 
 416 #define IPPOL_REFHOLD(ipp) {                    \
 417         atomic_inc_32(&(ipp)->ipsp_refs);        \
 418         ASSERT((ipp)->ipsp_refs != 0);               \
 419 }
 420 #define IPPOL_REFRELE(ipp) {                                    \
 421         ASSERT((ipp)->ipsp_refs != 0);                               \
 422         membar_exit();                                          \
 423         if (atomic_dec_32_nv(&(ipp)->ipsp_refs) == 0)    \
 424                 ipsec_policy_free(ipp);                         \
 425         (ipp) = 0;                                              \
 426 }
 427 
 428 #define IPPOL_UNCHAIN(php, ip)                                  \
 429         HASHLIST_UNCHAIN((ip), ipsp_hash);                      \
 430         avl_remove(&(php)->iph_rulebyid, (ip));                  \
 431         IPPOL_REFRELE(ip);
 432 
 433 /*
 434  * Policy ruleset.  One per (protocol * direction) for system policy.
 435  */
 436 
 437 #define IPSEC_AF_V4     0
 438 #define IPSEC_AF_V6     1
 439 #define IPSEC_NAF       2
 440 
 441 typedef struct ipsec_policy_root_s
 442 {
 443         ipsec_policy_t          *ipr_nonhash[IPSEC_NAF];
 444         int                     ipr_nchains;
 445         ipsec_policy_hash_t     *ipr_hash;
 446 } ipsec_policy_root_t;
 447 
 448 /*
 449  * Policy head.  One for system policy; there may also be one present
 450  * on ill_t's with interface-specific policy, as well as one present
 451  * for sockets with per-socket policy allocated.
 452  */
 453 
 454 typedef struct ipsec_policy_head_s
 455 {
 456         uint32_t        iph_refs;
 457         krwlock_t       iph_lock;
 458         uint64_t        iph_gen; /* generation number */
 459         ipsec_policy_root_t iph_root[IPSEC_NTYPES];
 460         avl_tree_t      iph_rulebyid;
 461 } ipsec_policy_head_t;
 462 
 463 #define IPPH_REFHOLD(iph) {                     \
 464         atomic_inc_32(&(iph)->iph_refs); \
 465         ASSERT((iph)->iph_refs != 0);                \
 466 }
 467 #define IPPH_REFRELE(iph, ns) {                                 \
 468         ASSERT((iph)->iph_refs != 0);                                \
 469         membar_exit();                                          \
 470         if (atomic_dec_32_nv(&(iph)->iph_refs) == 0)     \
 471                 ipsec_polhead_free(iph, ns);                    \
 472         (iph) = 0;                                              \
 473 }
 474 
 475 /*
 476  * IPsec fragment related structures
 477  */
 478 
 479 typedef struct ipsec_fragcache_entry {
 480         struct ipsec_fragcache_entry *itpfe_next;       /* hash list chain */
 481         mblk_t *itpfe_fraglist;                 /* list of fragments */
 482         time_t itpfe_exp;                       /* time when entry is stale */
 483         int itpfe_depth;                        /* # of fragments in list */
 484         ipsec_addr_t itpfe_frag_src;
 485         ipsec_addr_t itpfe_frag_dst;
 486 #define itpfe_src itpfe_frag_src.ipsad_v4
 487 #define itpfe_src6 itpfe_frag_src.ipsad_v6
 488 #define itpfe_dst itpfe_frag_dst.ipsad_v4
 489 #define itpfe_dst6 itpfe_frag_dst.ipsad_v6
 490         uint32_t itpfe_id;                      /* IP datagram ID */


 531 #define ITPF_I_PER_PORT_SECURITY 0x20
 532 #define ITPF_IFLAGS 0x38
 533 
 534 /* NOTE:  f cannot be an expression. */
 535 #define ITPF_CLONE(f) (f) = (((f) & ITPF_PFLAGS) | \
 536             (((f) & ITPF_PFLAGS) << ITPF_SHIFT));
 537 #define ITPF_SWAP(f) (f) = ((((f) & ITPF_PFLAGS) << ITPF_SHIFT) | \
 538             (((f) & ITPF_IFLAGS) >> ITPF_SHIFT))
 539 
 540 #define ITP_P_ISACTIVE(itp, iph) ((itp)->itp_flags & \
 541         (((itp)->itp_policy == (iph)) ? ITPF_P_ACTIVE : ITPF_I_ACTIVE))
 542 
 543 #define ITP_P_ISTUNNEL(itp, iph) ((itp)->itp_flags & \
 544         (((itp)->itp_policy == (iph)) ? ITPF_P_TUNNEL : ITPF_I_TUNNEL))
 545 
 546 #define ITP_P_ISPERPORT(itp, iph) ((itp)->itp_flags & \
 547         (((itp)->itp_policy == (iph)) ? ITPF_P_PER_PORT_SECURITY : \
 548         ITPF_I_PER_PORT_SECURITY))
 549 
 550 #define ITP_REFHOLD(itp) { \
 551         atomic_inc_32(&((itp)->itp_refcnt));     \
 552         ASSERT((itp)->itp_refcnt != 0); \
 553 }
 554 
 555 #define ITP_REFRELE(itp, ns) { \
 556         ASSERT((itp)->itp_refcnt != 0); \
 557         membar_exit(); \
 558         if (atomic_dec_32_nv(&((itp)->itp_refcnt)) == 0) \
 559                 itp_free(itp, ns); \
 560 }
 561 
 562 /*
 563  * Certificate identity.
 564  */
 565 
 566 typedef struct ipsid_s
 567 {
 568         struct ipsid_s *ipsid_next;
 569         struct ipsid_s **ipsid_ptpn;
 570         uint32_t        ipsid_refcnt;
 571         int             ipsid_type;     /* id type */
 572         char            *ipsid_cid;     /* certificate id string */
 573 } ipsid_t;
 574 
 575 /*
 576  * ipsid_t reference hold/release macros, just like ipsa versions.
 577  */
 578 
 579 #define IPSID_REFHOLD(ipsid) {                  \
 580         atomic_inc_32(&(ipsid)->ipsid_refcnt);   \
 581         ASSERT((ipsid)->ipsid_refcnt != 0);  \
 582 }
 583 
 584 /*
 585  * Decrement the reference count on the ID.  Someone else will clean up
 586  * after us later.
 587  */
 588 
 589 #define IPSID_REFRELE(ipsid) {                                  \
 590         membar_exit();                                          \
 591         atomic_dec_32(&(ipsid)->ipsid_refcnt);           \
 592 }
 593 
 594 /*
 595  * Following are the estimates of what the maximum AH and ESP header size
 596  * would be. This is used to tell the upper layer the right value of MSS
 597  * it should use without consulting AH/ESP. If the size is something
 598  * different from this, ULP will learn the right one through
 599  * ICMP_FRAGMENTATION_NEEDED messages generated locally.
 600  *
 601  * AH : 12 bytes of constant header + 32 bytes of ICV checksum (SHA-512).
 602  */
 603 #define IPSEC_MAX_AH_HDR_SIZE   (44)
 604 
 605 /*
 606  * ESP : Is a bit more complex...
 607  *
 608  * A system of one inequality and one equation MUST be solved for proper ESP
 609  * overhead.  The inequality is:
 610  *
 611  *    MTU - sizeof (IP header + options) >=