* SADB_ACQUIRE processing called by key_checkrequest() and key_acquire2(). * send * * to KMD, and expect to receive * with SADB_ACQUIRE if error occurred, * or * with SADB_GETSPI * from KMD by PF_KEY. * * XXX x_policy is outside of RF
| 6539 | * others: error number |
| 6540 | */ |
| 6541 | static int |
| 6542 | key_acquire(const struct secasindex *saidx, struct secpolicy *sp) |
| 6543 | { |
| 6544 | union sockaddr_union addr; |
| 6545 | struct mbuf *result, *m; |
| 6546 | uint32_t seq; |
| 6547 | int error; |
| 6548 | uint16_t ul_proto; |
| 6549 | uint8_t mask, satype; |
| 6550 | |
| 6551 | IPSEC_ASSERT(saidx != NULL, ("null saidx")); |
| 6552 | satype = key_proto2satype(saidx->proto); |
| 6553 | IPSEC_ASSERT(satype != 0, ("null satype, protocol %u", saidx->proto)); |
| 6554 | |
| 6555 | error = -1; |
| 6556 | result = NULL; |
| 6557 | ul_proto = IPSEC_ULPROTO_ANY; |
| 6558 | |
| 6559 | /* Get seq number to check whether sending message or not. */ |
| 6560 | seq = key_getacq(saidx, &error); |
| 6561 | if (seq == 0) |
| 6562 | return (error); |
| 6563 | |
| 6564 | m = key_setsadbmsg(SADB_ACQUIRE, 0, satype, seq, 0, 0); |
| 6565 | if (!m) { |
| 6566 | error = ENOBUFS; |
| 6567 | goto fail; |
| 6568 | } |
| 6569 | result = m; |
| 6570 | |
| 6571 | /* |
| 6572 | * set sadb_address for saidx's. |
| 6573 | * |
| 6574 | * Note that if sp is supplied, then we're being called from |
| 6575 | * key_allocsa_policy() and should supply port and protocol |
| 6576 | * information. |
| 6577 | * XXXAE: why only TCP and UDP? ICMP and SCTP looks applicable too. |
| 6578 | * XXXAE: probably we can handle this in the ipsec[46]_allocsa(). |
| 6579 | * XXXAE: it looks like we should save this info in the ACQ entry. |
| 6580 | */ |
| 6581 | if (sp != NULL && (sp->spidx.ul_proto == IPPROTO_TCP || |
| 6582 | sp->spidx.ul_proto == IPPROTO_UDP)) |
| 6583 | ul_proto = sp->spidx.ul_proto; |
| 6584 | |
| 6585 | addr = saidx->src; |
| 6586 | mask = FULLMASK; |
| 6587 | if (ul_proto != IPSEC_ULPROTO_ANY) { |
| 6588 | switch (sp->spidx.src.sa.sa_family) { |
| 6589 | case AF_INET: |
| 6590 | if (sp->spidx.src.sin.sin_port != IPSEC_PORT_ANY) { |
| 6591 | addr.sin.sin_port = sp->spidx.src.sin.sin_port; |
| 6592 | mask = sp->spidx.prefs; |
| 6593 | } |
| 6594 | break; |
| 6595 | case AF_INET6: |
| 6596 | if (sp->spidx.src.sin6.sin6_port != IPSEC_PORT_ANY) { |
| 6597 | addr.sin6.sin6_port = |
| 6598 | sp->spidx.src.sin6.sin6_port; |
no test coverage detected