| 1133 | } |
| 1134 | |
| 1135 | struct secasvar * |
| 1136 | key_allocsa_tunnel(union sockaddr_union *src, union sockaddr_union *dst, |
| 1137 | uint8_t proto) |
| 1138 | { |
| 1139 | SAHTREE_RLOCK_TRACKER; |
| 1140 | struct secasindex saidx; |
| 1141 | struct secashead *sah; |
| 1142 | struct secasvar *sav; |
| 1143 | |
| 1144 | IPSEC_ASSERT(src != NULL, ("null src address")); |
| 1145 | IPSEC_ASSERT(dst != NULL, ("null dst address")); |
| 1146 | |
| 1147 | KEY_SETSECASIDX(proto, IPSEC_MODE_TUNNEL, 0, &src->sa, |
| 1148 | &dst->sa, &saidx); |
| 1149 | |
| 1150 | sav = NULL; |
| 1151 | SAHTREE_RLOCK(); |
| 1152 | LIST_FOREACH(sah, SAHADDRHASH_HASH(&saidx), addrhash) { |
| 1153 | if (IPSEC_MODE_TUNNEL != sah->saidx.mode) |
| 1154 | continue; |
| 1155 | if (proto != sah->saidx.proto) |
| 1156 | continue; |
| 1157 | if (key_sockaddrcmp(&src->sa, &sah->saidx.src.sa, 0) != 0) |
| 1158 | continue; |
| 1159 | if (key_sockaddrcmp(&dst->sa, &sah->saidx.dst.sa, 0) != 0) |
| 1160 | continue; |
| 1161 | /* XXXAE: is key_preferred_oldsa reasonably?*/ |
| 1162 | if (V_key_preferred_oldsa) |
| 1163 | sav = TAILQ_LAST(&sah->savtree_alive, secasvar_queue); |
| 1164 | else |
| 1165 | sav = TAILQ_FIRST(&sah->savtree_alive); |
| 1166 | if (sav != NULL) { |
| 1167 | SAV_ADDREF(sav); |
| 1168 | break; |
| 1169 | } |
| 1170 | } |
| 1171 | SAHTREE_RUNLOCK(); |
| 1172 | KEYDBG(IPSEC_STAMP, |
| 1173 | printf("%s: return SA(%p)\n", __func__, sav)); |
| 1174 | if (sav != NULL) |
| 1175 | KEYDBG(IPSEC_DATA, kdebug_secasv(sav)); |
| 1176 | return (sav); |
| 1177 | } |
| 1178 | |
| 1179 | /* |
| 1180 | * Must be called after calling key_allocsp(). |
no test coverage detected