+ if (!cmpspidxwild(spidx, &p->spidx)) {
+ if (spidx->dir != IPSEC_DIR_ANY) {
+ struct ipsecrequest *isr;
+ for (isr = p->req; isr != NULL; isr = isr->next) {
+ if (isr->saidx.mode != IPSEC_MODE_TUNNEL) {
+ plog(ASL_LEVEL_DEBUG, "%s, skipping policy. dir %d, mode %d\n",
+ __FUNCTION__, spidx->dir, isr->saidx.mode);
+ continue;
+ }
+
+ // for tunnel mode: verify the outer ip addresses match the phase2's addresses
+ if (spidx->dir == IPSEC_DIR_INBOUND) {
+ // TODO: look out for wildcards
+ if (!cmpsaddrwop(iph2->dst, &isr->saidx.src) &&
+ !cmpsaddrwop(iph2->src, &isr->saidx.dst)) {
+ plog(ASL_LEVEL_DEBUG, "%s, inbound policy outer addresses matched Phase 2 addresses\n",
+ __FUNCTION__);
+ return p;
+ } else {
+ mismatched_outer_addr = 1;
+ }
+ } else if (spidx->dir == IPSEC_DIR_OUTBOUND) {
+ // TODO: look out for wildcards
+ if (!cmpsaddrwop(iph2->src, &isr->saidx.src) &&
+ !cmpsaddrwop(iph2->dst, &isr->saidx.dst)) {
+ plog(ASL_LEVEL_DEBUG, "%s, outbound policy outer addresses matched Phase 2 addresses\n",
+ __FUNCTION__);
+ return p;
+ } else {
+ mismatched_outer_addr = 1;
+ }
+ } else {
+ mismatched_outer_addr = 1;
+ }
+ if (mismatched_outer_addr) {
+ plog(ASL_LEVEL_DEBUG, "%s, policy outer addresses matched Phase 2 addresses: dir %d\n",
+ __FUNCTION__, spidx->dir);
+ plog(ASL_LEVEL_DEBUG, "src1: %s\n",
+ saddr2str((struct sockaddr *)iph2->src));
+ plog(ASL_LEVEL_DEBUG, "src2: %s\n",
+ saddr2str((struct sockaddr *)&isr->saidx.src));
+ plog(ASL_LEVEL_DEBUG, "dst1: %s\n",
+ saddr2str((struct sockaddr *)iph2->dst));
+ plog(ASL_LEVEL_DEBUG, "dst2: %s\n",
+ saddr2str((struct sockaddr *)&isr->saidx.dst));
+ }
+ }
+ }
+ if (!mismatched_outer_addr) {
+ return p;
+ }
+ }