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