Changeset View
Changeset View
Standalone View
Standalone View
head/sys/netipsec/key.c
| Show First 20 Lines • Show All 237 Lines • ▼ Show 20 Lines | static const int minsize[] = { | ||||
| sizeof(struct sadb_x_policy), /* SADB_X_EXT_POLICY */ | sizeof(struct sadb_x_policy), /* SADB_X_EXT_POLICY */ | ||||
| sizeof(struct sadb_x_sa2), /* SADB_X_SA2 */ | sizeof(struct sadb_x_sa2), /* SADB_X_SA2 */ | ||||
| sizeof(struct sadb_x_nat_t_type),/* SADB_X_EXT_NAT_T_TYPE */ | sizeof(struct sadb_x_nat_t_type),/* SADB_X_EXT_NAT_T_TYPE */ | ||||
| sizeof(struct sadb_x_nat_t_port),/* SADB_X_EXT_NAT_T_SPORT */ | sizeof(struct sadb_x_nat_t_port),/* SADB_X_EXT_NAT_T_SPORT */ | ||||
| sizeof(struct sadb_x_nat_t_port),/* SADB_X_EXT_NAT_T_DPORT */ | sizeof(struct sadb_x_nat_t_port),/* SADB_X_EXT_NAT_T_DPORT */ | ||||
| sizeof(struct sadb_address), /* SADB_X_EXT_NAT_T_OAI */ | sizeof(struct sadb_address), /* SADB_X_EXT_NAT_T_OAI */ | ||||
| sizeof(struct sadb_address), /* SADB_X_EXT_NAT_T_OAR */ | sizeof(struct sadb_address), /* SADB_X_EXT_NAT_T_OAR */ | ||||
| sizeof(struct sadb_x_nat_t_frag),/* SADB_X_EXT_NAT_T_FRAG */ | sizeof(struct sadb_x_nat_t_frag),/* SADB_X_EXT_NAT_T_FRAG */ | ||||
| sizeof(struct sadb_x_sa_replay), /* SADB_X_EXT_SA_REPLAY */ | |||||
| }; | }; | ||||
| _Static_assert(sizeof(minsize)/sizeof(int) == SADB_EXT_MAX + 1, "minsize size mismatch"); | |||||
| static const int maxsize[] = { | static const int maxsize[] = { | ||||
| sizeof(struct sadb_msg), /* SADB_EXT_RESERVED */ | sizeof(struct sadb_msg), /* SADB_EXT_RESERVED */ | ||||
| sizeof(struct sadb_sa), /* SADB_EXT_SA */ | sizeof(struct sadb_sa), /* SADB_EXT_SA */ | ||||
| sizeof(struct sadb_lifetime), /* SADB_EXT_LIFETIME_CURRENT */ | sizeof(struct sadb_lifetime), /* SADB_EXT_LIFETIME_CURRENT */ | ||||
| sizeof(struct sadb_lifetime), /* SADB_EXT_LIFETIME_HARD */ | sizeof(struct sadb_lifetime), /* SADB_EXT_LIFETIME_HARD */ | ||||
| sizeof(struct sadb_lifetime), /* SADB_EXT_LIFETIME_SOFT */ | sizeof(struct sadb_lifetime), /* SADB_EXT_LIFETIME_SOFT */ | ||||
| 0, /* SADB_EXT_ADDRESS_SRC */ | 0, /* SADB_EXT_ADDRESS_SRC */ | ||||
| 0, /* SADB_EXT_ADDRESS_DST */ | 0, /* SADB_EXT_ADDRESS_DST */ | ||||
| Show All 11 Lines | static const int maxsize[] = { | ||||
| 0, /* SADB_X_EXT_POLICY */ | 0, /* SADB_X_EXT_POLICY */ | ||||
| sizeof(struct sadb_x_sa2), /* SADB_X_SA2 */ | sizeof(struct sadb_x_sa2), /* SADB_X_SA2 */ | ||||
| sizeof(struct sadb_x_nat_t_type),/* SADB_X_EXT_NAT_T_TYPE */ | sizeof(struct sadb_x_nat_t_type),/* SADB_X_EXT_NAT_T_TYPE */ | ||||
| sizeof(struct sadb_x_nat_t_port),/* SADB_X_EXT_NAT_T_SPORT */ | sizeof(struct sadb_x_nat_t_port),/* SADB_X_EXT_NAT_T_SPORT */ | ||||
| sizeof(struct sadb_x_nat_t_port),/* SADB_X_EXT_NAT_T_DPORT */ | sizeof(struct sadb_x_nat_t_port),/* SADB_X_EXT_NAT_T_DPORT */ | ||||
| 0, /* SADB_X_EXT_NAT_T_OAI */ | 0, /* SADB_X_EXT_NAT_T_OAI */ | ||||
| 0, /* SADB_X_EXT_NAT_T_OAR */ | 0, /* SADB_X_EXT_NAT_T_OAR */ | ||||
| sizeof(struct sadb_x_nat_t_frag),/* SADB_X_EXT_NAT_T_FRAG */ | sizeof(struct sadb_x_nat_t_frag),/* SADB_X_EXT_NAT_T_FRAG */ | ||||
| sizeof(struct sadb_x_sa_replay), /* SADB_X_EXT_SA_REPLAY */ | |||||
| }; | }; | ||||
| _Static_assert(sizeof(maxsize)/sizeof(int) == SADB_EXT_MAX + 1, "minsize size mismatch"); | |||||
| static VNET_DEFINE(int, ipsec_esp_keymin) = 256; | static VNET_DEFINE(int, ipsec_esp_keymin) = 256; | ||||
| static VNET_DEFINE(int, ipsec_esp_auth) = 0; | static VNET_DEFINE(int, ipsec_esp_auth) = 0; | ||||
| static VNET_DEFINE(int, ipsec_ah_keymin) = 128; | static VNET_DEFINE(int, ipsec_ah_keymin) = 128; | ||||
| #define V_ipsec_esp_keymin VNET(ipsec_esp_keymin) | #define V_ipsec_esp_keymin VNET(ipsec_esp_keymin) | ||||
| #define V_ipsec_esp_auth VNET(ipsec_esp_auth) | #define V_ipsec_esp_auth VNET(ipsec_esp_auth) | ||||
| #define V_ipsec_ah_keymin VNET(ipsec_ah_keymin) | #define V_ipsec_ah_keymin VNET(ipsec_ah_keymin) | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| #ifdef IPSEC_NAT_T | #ifdef IPSEC_NAT_T | ||||
| static struct mbuf *key_setsadbxport(u_int16_t, u_int16_t); | static struct mbuf *key_setsadbxport(u_int16_t, u_int16_t); | ||||
| static struct mbuf *key_setsadbxtype(u_int16_t); | static struct mbuf *key_setsadbxtype(u_int16_t); | ||||
| #endif | #endif | ||||
| static void key_porttosaddr(struct sockaddr *, u_int16_t); | static void key_porttosaddr(struct sockaddr *, u_int16_t); | ||||
| #define KEY_PORTTOSADDR(saddr, port) \ | #define KEY_PORTTOSADDR(saddr, port) \ | ||||
| key_porttosaddr((struct sockaddr *)(saddr), (port)) | key_porttosaddr((struct sockaddr *)(saddr), (port)) | ||||
| static struct mbuf *key_setsadbxsa2(u_int8_t, u_int32_t, u_int32_t); | static struct mbuf *key_setsadbxsa2(u_int8_t, u_int32_t, u_int32_t); | ||||
| static struct mbuf *key_setsadbxsareplay(u_int32_t); | |||||
| static struct mbuf *key_setsadbxpolicy(u_int16_t, u_int8_t, | static struct mbuf *key_setsadbxpolicy(u_int16_t, u_int8_t, | ||||
| u_int32_t, u_int32_t); | u_int32_t, u_int32_t); | ||||
| static struct seckey *key_dup_keymsg(const struct sadb_key *, u_int, | static struct seckey *key_dup_keymsg(const struct sadb_key *, u_int, | ||||
| struct malloc_type *); | struct malloc_type *); | ||||
| static struct seclifetime *key_dup_lifemsg(const struct sadb_lifetime *src, | static struct seclifetime *key_dup_lifemsg(const struct sadb_lifetime *src, | ||||
| struct malloc_type *type); | struct malloc_type *type); | ||||
| #ifdef INET6 | #ifdef INET6 | ||||
| static int key_ismyaddr6(struct sockaddr_in6 *); | static int key_ismyaddr6(struct sockaddr_in6 *); | ||||
| ▲ Show 20 Lines • Show All 2,452 Lines • ▼ Show 20 Lines | if (sav->key_enc != NULL) { | ||||
| sav->key_enc = NULL; | sav->key_enc = NULL; | ||||
| } | } | ||||
| if (sav->sched) { | if (sav->sched) { | ||||
| bzero(sav->sched, sav->schedlen); | bzero(sav->sched, sav->schedlen); | ||||
| free(sav->sched, M_IPSEC_MISC); | free(sav->sched, M_IPSEC_MISC); | ||||
| sav->sched = NULL; | sav->sched = NULL; | ||||
| } | } | ||||
| if (sav->replay != NULL) { | if (sav->replay != NULL) { | ||||
| if (sav->replay->bitmap != NULL) | |||||
| free(sav->replay->bitmap, M_IPSEC_MISC); | |||||
| free(sav->replay, M_IPSEC_MISC); | free(sav->replay, M_IPSEC_MISC); | ||||
| sav->replay = NULL; | sav->replay = NULL; | ||||
| } | } | ||||
| if (sav->lft_c != NULL) { | if (sav->lft_c != NULL) { | ||||
| free(sav->lft_c, M_IPSEC_MISC); | free(sav->lft_c, M_IPSEC_MISC); | ||||
| sav->lft_c = NULL; | sav->lft_c = NULL; | ||||
| } | } | ||||
| if (sav->lft_h != NULL) { | if (sav->lft_h != NULL) { | ||||
| ▲ Show 20 Lines • Show All 152 Lines • ▼ Show 20 Lines | key_setsaval(struct secasvar *sav, struct mbuf *m, | ||||
| sav->tdb_compalgxform = NULL; /* compression algorithm */ | sav->tdb_compalgxform = NULL; /* compression algorithm */ | ||||
| /* Initialize even if NAT-T not compiled in: */ | /* Initialize even if NAT-T not compiled in: */ | ||||
| sav->natt_type = 0; | sav->natt_type = 0; | ||||
| sav->natt_esp_frag_len = 0; | sav->natt_esp_frag_len = 0; | ||||
| /* SA */ | /* SA */ | ||||
| if (mhp->ext[SADB_EXT_SA] != NULL) { | if (mhp->ext[SADB_EXT_SA] != NULL) { | ||||
| const struct sadb_sa *sa0; | const struct sadb_sa *sa0; | ||||
| u_int32_t replay; | |||||
| sa0 = (const struct sadb_sa *)mhp->ext[SADB_EXT_SA]; | sa0 = (const struct sadb_sa *)mhp->ext[SADB_EXT_SA]; | ||||
| if (mhp->extlen[SADB_EXT_SA] < sizeof(*sa0)) { | if (mhp->extlen[SADB_EXT_SA] < sizeof(*sa0)) { | ||||
| error = EINVAL; | error = EINVAL; | ||||
| goto fail; | goto fail; | ||||
| } | } | ||||
| sav->alg_auth = sa0->sadb_sa_auth; | sav->alg_auth = sa0->sadb_sa_auth; | ||||
| sav->alg_enc = sa0->sadb_sa_encrypt; | sav->alg_enc = sa0->sadb_sa_encrypt; | ||||
| sav->flags = sa0->sadb_sa_flags; | sav->flags = sa0->sadb_sa_flags; | ||||
| /* replay window */ | /* Optional replay window */ | ||||
| if ((sa0->sadb_sa_flags & SADB_X_EXT_OLD) == 0) { | replay = 0; | ||||
| if ((sa0->sadb_sa_flags & SADB_X_EXT_OLD) == 0) | |||||
| replay = sa0->sadb_sa_replay; | |||||
| if ((mhp->ext[SADB_X_EXT_SA_REPLAY]) != NULL) { | |||||
| replay = ((const struct sadb_x_sa_replay *) | |||||
| mhp->ext[SADB_X_EXT_SA_REPLAY])->sadb_x_sa_replay_replay; | |||||
| if (replay > UINT32_MAX - 32) { | |||||
| ipseclog((LOG_DEBUG, "%s: replay window too big.\n", | |||||
| __func__)); | |||||
| error = EINVAL; | |||||
| goto fail; | |||||
| } | |||||
| replay = (replay + 7) >> 3; | |||||
| } | |||||
| sav->replay = (struct secreplay *) | sav->replay = (struct secreplay *) | ||||
| malloc(sizeof(struct secreplay)+sa0->sadb_sa_replay, M_IPSEC_MISC, M_NOWAIT|M_ZERO); | malloc(sizeof(struct secreplay), | ||||
| M_IPSEC_MISC, M_NOWAIT|M_ZERO); | |||||
| if (sav->replay == NULL) { | if (sav->replay == NULL) { | ||||
| ipseclog((LOG_DEBUG, "%s: No more memory.\n", | ipseclog((LOG_DEBUG, "%s: No more memory.\n", | ||||
| __func__)); | __func__)); | ||||
| error = ENOBUFS; | error = ENOBUFS; | ||||
| goto fail; | goto fail; | ||||
| } | } | ||||
| if (sa0->sadb_sa_replay != 0) | |||||
| sav->replay->bitmap = (caddr_t)(sav->replay+1); | if (replay != 0) { | ||||
| sav->replay->wsize = sa0->sadb_sa_replay; | /* number of 32b blocks to be allocated */ | ||||
| u_int32_t bitmap_size; | |||||
| /* RFC 6479: | |||||
| * - the allocated replay window size must be a power of two | |||||
| * - use an extra 32b block as a redundant window | |||||
| */ | |||||
| bitmap_size = 1; | |||||
| while (replay + 4 > bitmap_size) | |||||
| bitmap_size <<= 1; | |||||
| bitmap_size = bitmap_size / 4; | |||||
| sav->replay->bitmap = malloc(bitmap_size*sizeof(u_int32_t), | |||||
| M_IPSEC_MISC, M_NOWAIT|M_ZERO); | |||||
| if (sav->replay->bitmap == NULL) { | |||||
| ipseclog((LOG_DEBUG, "%s: No more memory.\n", | |||||
| __func__)); | |||||
| error = ENOBUFS; | |||||
| goto fail; | |||||
| } | } | ||||
| sav->replay->bitmap_size = bitmap_size; | |||||
| sav->replay->wsize = replay; | |||||
| } | } | ||||
| } | |||||
| /* Authentication keys */ | /* Authentication keys */ | ||||
| if (mhp->ext[SADB_EXT_KEY_AUTH] != NULL) { | if (mhp->ext[SADB_EXT_KEY_AUTH] != NULL) { | ||||
| const struct sadb_key *key0; | const struct sadb_key *key0; | ||||
| int len; | int len; | ||||
| key0 = (const struct sadb_key *)mhp->ext[SADB_EXT_KEY_AUTH]; | key0 = (const struct sadb_key *)mhp->ext[SADB_EXT_KEY_AUTH]; | ||||
| len = mhp->extlen[SADB_EXT_KEY_AUTH]; | len = mhp->extlen[SADB_EXT_KEY_AUTH]; | ||||
| ▲ Show 20 Lines • Show All 256 Lines • ▼ Show 20 Lines | |||||
| */ | */ | ||||
| static struct mbuf * | static struct mbuf * | ||||
| key_setdumpsa(struct secasvar *sav, u_int8_t type, u_int8_t satype, | key_setdumpsa(struct secasvar *sav, u_int8_t type, u_int8_t satype, | ||||
| u_int32_t seq, u_int32_t pid) | u_int32_t seq, u_int32_t pid) | ||||
| { | { | ||||
| struct mbuf *result = NULL, *tres = NULL, *m; | struct mbuf *result = NULL, *tres = NULL, *m; | ||||
| int i; | int i; | ||||
| int dumporder[] = { | int dumporder[] = { | ||||
| SADB_EXT_SA, SADB_X_EXT_SA2, | SADB_EXT_SA, SADB_X_EXT_SA2, SADB_X_EXT_SA_REPLAY, | ||||
| SADB_EXT_LIFETIME_HARD, SADB_EXT_LIFETIME_SOFT, | SADB_EXT_LIFETIME_HARD, SADB_EXT_LIFETIME_SOFT, | ||||
| SADB_EXT_LIFETIME_CURRENT, SADB_EXT_ADDRESS_SRC, | SADB_EXT_LIFETIME_CURRENT, SADB_EXT_ADDRESS_SRC, | ||||
| SADB_EXT_ADDRESS_DST, SADB_EXT_ADDRESS_PROXY, SADB_EXT_KEY_AUTH, | SADB_EXT_ADDRESS_DST, SADB_EXT_ADDRESS_PROXY, SADB_EXT_KEY_AUTH, | ||||
| SADB_EXT_KEY_ENCRYPT, SADB_EXT_IDENTITY_SRC, | SADB_EXT_KEY_ENCRYPT, SADB_EXT_IDENTITY_SRC, | ||||
| SADB_EXT_IDENTITY_DST, SADB_EXT_SENSITIVITY, | SADB_EXT_IDENTITY_DST, SADB_EXT_SENSITIVITY, | ||||
| #ifdef IPSEC_NAT_T | #ifdef IPSEC_NAT_T | ||||
| SADB_X_EXT_NAT_T_TYPE, | SADB_X_EXT_NAT_T_TYPE, | ||||
| SADB_X_EXT_NAT_T_SPORT, SADB_X_EXT_NAT_T_DPORT, | SADB_X_EXT_NAT_T_SPORT, SADB_X_EXT_NAT_T_DPORT, | ||||
| SADB_X_EXT_NAT_T_OAI, SADB_X_EXT_NAT_T_OAR, | SADB_X_EXT_NAT_T_OAI, SADB_X_EXT_NAT_T_OAR, | ||||
| SADB_X_EXT_NAT_T_FRAG, | SADB_X_EXT_NAT_T_FRAG, | ||||
| #endif | #endif | ||||
| }; | }; | ||||
| u_int32_t replay_count; | |||||
| m = key_setsadbmsg(type, 0, satype, seq, pid, sav->refcnt); | m = key_setsadbmsg(type, 0, satype, seq, pid, sav->refcnt); | ||||
| if (m == NULL) | if (m == NULL) | ||||
| goto fail; | goto fail; | ||||
| result = m; | result = m; | ||||
| for (i = nitems(dumporder) - 1; i >= 0; i--) { | for (i = nitems(dumporder) - 1; i >= 0; i--) { | ||||
| m = NULL; | m = NULL; | ||||
| switch (dumporder[i]) { | switch (dumporder[i]) { | ||||
| case SADB_EXT_SA: | case SADB_EXT_SA: | ||||
| m = key_setsadbsa(sav); | m = key_setsadbsa(sav); | ||||
| if (!m) | if (!m) | ||||
| goto fail; | goto fail; | ||||
| break; | break; | ||||
| case SADB_X_EXT_SA2: | case SADB_X_EXT_SA2: | ||||
| m = key_setsadbxsa2(sav->sah->saidx.mode, | SECASVAR_LOCK(sav); | ||||
| sav->replay ? sav->replay->count : 0, | replay_count = sav->replay ? sav->replay->count : 0; | ||||
| SECASVAR_UNLOCK(sav); | |||||
| m = key_setsadbxsa2(sav->sah->saidx.mode, replay_count, | |||||
| sav->sah->saidx.reqid); | sav->sah->saidx.reqid); | ||||
| if (!m) | if (!m) | ||||
| goto fail; | goto fail; | ||||
| break; | break; | ||||
| case SADB_X_EXT_SA_REPLAY: | |||||
| if (sav->replay == NULL || | |||||
| sav->replay->wsize <= UINT8_MAX) | |||||
| continue; | |||||
| m = key_setsadbxsareplay(sav->replay->wsize); | |||||
| if (!m) | |||||
| goto fail; | |||||
| break; | |||||
| case SADB_EXT_ADDRESS_SRC: | case SADB_EXT_ADDRESS_SRC: | ||||
| m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC, | m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC, | ||||
| &sav->sah->saidx.src.sa, | &sav->sah->saidx.src.sa, | ||||
| FULLMASK, IPSEC_ULPROTO_ANY); | FULLMASK, IPSEC_ULPROTO_ANY); | ||||
| if (!m) | if (!m) | ||||
| goto fail; | goto fail; | ||||
| break; | break; | ||||
| ▲ Show 20 Lines • Show All 176 Lines • ▼ Show 20 Lines | if (m == NULL) | ||||
| return (NULL); | return (NULL); | ||||
| m_align(m, len); | m_align(m, len); | ||||
| m->m_len = len; | m->m_len = len; | ||||
| p = mtod(m, struct sadb_sa *); | p = mtod(m, struct sadb_sa *); | ||||
| bzero(p, len); | bzero(p, len); | ||||
| p->sadb_sa_len = PFKEY_UNIT64(len); | p->sadb_sa_len = PFKEY_UNIT64(len); | ||||
| p->sadb_sa_exttype = SADB_EXT_SA; | p->sadb_sa_exttype = SADB_EXT_SA; | ||||
| p->sadb_sa_spi = sav->spi; | p->sadb_sa_spi = sav->spi; | ||||
| p->sadb_sa_replay = (sav->replay != NULL ? sav->replay->wsize : 0); | p->sadb_sa_replay = sav->replay ? | ||||
| (sav->replay->wsize > UINT8_MAX ? | |||||
| UINT8_MAX : sav->replay->wsize) : 0; | |||||
| p->sadb_sa_state = sav->state; | p->sadb_sa_state = sav->state; | ||||
| p->sadb_sa_auth = sav->alg_auth; | p->sadb_sa_auth = sav->alg_auth; | ||||
| p->sadb_sa_encrypt = sav->alg_enc; | p->sadb_sa_encrypt = sav->alg_enc; | ||||
| p->sadb_sa_flags = sav->flags; | p->sadb_sa_flags = sav->flags; | ||||
| return m; | return m; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | key_setsadbxsa2(u_int8_t mode, u_int32_t seq, u_int32_t reqid) | ||||
| p->sadb_x_sa2_reserved1 = 0; | p->sadb_x_sa2_reserved1 = 0; | ||||
| p->sadb_x_sa2_reserved2 = 0; | p->sadb_x_sa2_reserved2 = 0; | ||||
| p->sadb_x_sa2_sequence = seq; | p->sadb_x_sa2_sequence = seq; | ||||
| p->sadb_x_sa2_reqid = reqid; | p->sadb_x_sa2_reqid = reqid; | ||||
| return m; | return m; | ||||
| } | } | ||||
| /* | |||||
| * Set data into sadb_x_sa_replay. | |||||
| */ | |||||
| static struct mbuf * | |||||
| key_setsadbxsareplay(u_int32_t replay) | |||||
| { | |||||
| struct mbuf *m; | |||||
| struct sadb_x_sa_replay *p; | |||||
| size_t len; | |||||
| len = PFKEY_ALIGN8(sizeof(struct sadb_x_sa_replay)); | |||||
| m = m_get2(len, M_NOWAIT, MT_DATA, 0); | |||||
| if (m == NULL) | |||||
| return (NULL); | |||||
| m_align(m, len); | |||||
| m->m_len = len; | |||||
| p = mtod(m, struct sadb_x_sa_replay *); | |||||
| bzero(p, len); | |||||
| p->sadb_x_sa_replay_len = PFKEY_UNIT64(len); | |||||
| p->sadb_x_sa_replay_exttype = SADB_X_EXT_SA_REPLAY; | |||||
| p->sadb_x_sa_replay_replay = (replay << 3); | |||||
| return m; | |||||
| } | |||||
| #ifdef IPSEC_NAT_T | #ifdef IPSEC_NAT_T | ||||
| /* | /* | ||||
| * Set a type in sadb_x_nat_t_type. | * Set a type in sadb_x_nat_t_type. | ||||
| */ | */ | ||||
| static struct mbuf * | static struct mbuf * | ||||
| key_setsadbxtype(u_int16_t type) | key_setsadbxtype(u_int16_t type) | ||||
| { | { | ||||
| struct mbuf *m; | struct mbuf *m; | ||||
| ▲ Show 20 Lines • Show All 3,118 Lines • ▼ Show 20 Lines | |||||
| static int | static int | ||||
| key_expire(struct secasvar *sav, int hard) | key_expire(struct secasvar *sav, int hard) | ||||
| { | { | ||||
| int satype; | int satype; | ||||
| struct mbuf *result = NULL, *m; | struct mbuf *result = NULL, *m; | ||||
| int len; | int len; | ||||
| int error = -1; | int error = -1; | ||||
| struct sadb_lifetime *lt; | struct sadb_lifetime *lt; | ||||
| u_int32_t replay_count; | |||||
| IPSEC_ASSERT (sav != NULL, ("null sav")); | IPSEC_ASSERT (sav != NULL, ("null sav")); | ||||
| IPSEC_ASSERT (sav->sah != NULL, ("null sa header")); | IPSEC_ASSERT (sav->sah != NULL, ("null sa header")); | ||||
| /* set msg header */ | /* set msg header */ | ||||
| satype = key_proto2satype(sav->sah->saidx.proto); | satype = key_proto2satype(sav->sah->saidx.proto); | ||||
| IPSEC_ASSERT(satype != 0, ("invalid proto, satype %u", satype)); | IPSEC_ASSERT(satype != 0, ("invalid proto, satype %u", satype)); | ||||
| m = key_setsadbmsg(SADB_EXPIRE, 0, satype, sav->seq, 0, sav->refcnt); | m = key_setsadbmsg(SADB_EXPIRE, 0, satype, sav->seq, 0, sav->refcnt); | ||||
| if (!m) { | if (!m) { | ||||
| error = ENOBUFS; | error = ENOBUFS; | ||||
| goto fail; | goto fail; | ||||
| } | } | ||||
| result = m; | result = m; | ||||
| /* create SA extension */ | /* create SA extension */ | ||||
| m = key_setsadbsa(sav); | m = key_setsadbsa(sav); | ||||
| if (!m) { | if (!m) { | ||||
| error = ENOBUFS; | error = ENOBUFS; | ||||
| goto fail; | goto fail; | ||||
| } | } | ||||
| m_cat(result, m); | m_cat(result, m); | ||||
| /* create SA extension */ | /* create SA extension */ | ||||
| m = key_setsadbxsa2(sav->sah->saidx.mode, | SECASVAR_LOCK(sav); | ||||
| sav->replay ? sav->replay->count : 0, | replay_count = sav->replay ? sav->replay->count : 0; | ||||
| SECASVAR_UNLOCK(sav); | |||||
| m = key_setsadbxsa2(sav->sah->saidx.mode, replay_count, | |||||
| sav->sah->saidx.reqid); | sav->sah->saidx.reqid); | ||||
| if (!m) { | if (!m) { | ||||
| error = ENOBUFS; | error = ENOBUFS; | ||||
| goto fail; | goto fail; | ||||
| } | } | ||||
| m_cat(result, m); | m_cat(result, m); | ||||
| if (sav->replay && sav->replay->wsize > UINT8_MAX) { | |||||
| m = key_setsadbxsareplay(sav->replay->wsize); | |||||
| if (!m) { | |||||
| error = ENOBUFS; | |||||
| goto fail; | |||||
| } | |||||
| m_cat(result, m); | |||||
| } | |||||
| /* create lifetime extension (current and soft) */ | /* create lifetime extension (current and soft) */ | ||||
| len = PFKEY_ALIGN8(sizeof(*lt)) * 2; | len = PFKEY_ALIGN8(sizeof(*lt)) * 2; | ||||
| m = m_get2(len, M_NOWAIT, MT_DATA, 0); | m = m_get2(len, M_NOWAIT, MT_DATA, 0); | ||||
| if (m == NULL) { | if (m == NULL) { | ||||
| error = ENOBUFS; | error = ENOBUFS; | ||||
| goto fail; | goto fail; | ||||
| } | } | ||||
| m_align(m, len); | m_align(m, len); | ||||
| ▲ Show 20 Lines • Show All 659 Lines • ▼ Show 20 Lines | |||||
| #ifdef IPSEC_NAT_T | #ifdef IPSEC_NAT_T | ||||
| case SADB_X_EXT_NAT_T_TYPE: | case SADB_X_EXT_NAT_T_TYPE: | ||||
| case SADB_X_EXT_NAT_T_SPORT: | case SADB_X_EXT_NAT_T_SPORT: | ||||
| case SADB_X_EXT_NAT_T_DPORT: | case SADB_X_EXT_NAT_T_DPORT: | ||||
| case SADB_X_EXT_NAT_T_OAI: | case SADB_X_EXT_NAT_T_OAI: | ||||
| case SADB_X_EXT_NAT_T_OAR: | case SADB_X_EXT_NAT_T_OAR: | ||||
| case SADB_X_EXT_NAT_T_FRAG: | case SADB_X_EXT_NAT_T_FRAG: | ||||
| #endif | #endif | ||||
| case SADB_X_EXT_SA_REPLAY: | |||||
| /* duplicate check */ | /* duplicate check */ | ||||
| /* | /* | ||||
| * XXX Are there duplication payloads of either | * XXX Are there duplication payloads of either | ||||
| * KEY_AUTH or KEY_ENCRYPT ? | * KEY_AUTH or KEY_ENCRYPT ? | ||||
| */ | */ | ||||
| if (mhp->ext[ext->sadb_ext_type] != NULL) { | if (mhp->ext[ext->sadb_ext_type] != NULL) { | ||||
| ipseclog((LOG_DEBUG, "%s: duplicate ext_type " | ipseclog((LOG_DEBUG, "%s: duplicate ext_type " | ||||
| "%u\n", __func__, ext->sadb_ext_type)); | "%u\n", __func__, ext->sadb_ext_type)); | ||||
| ▲ Show 20 Lines • Show All 361 Lines • Show Last 20 Lines | |||||