@@ -55,6 +55,7 @@ typedef union {
uint32_t tcp_err:1; /**< TCP error, checks TBD */
uint32_t udp_err:1; /**< UDP error, checks TBD */
uint32_t l4_chksum:1; /**< L4 checksum error */
+ uint32_t ipsec_err:1; /**< IPsec error */
};
} error_flags_t;
@@ -286,6 +286,7 @@ static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt,
uint8_t ip_ttl; /**< Saved IP TTL value */
uint16_t ip_frag_offset; /**< Saved IP flags value */
odp_crypto_packet_result_t crypto; /**< Crypto operation result */
+ odp_packet_hdr_t *pkt_hdr;
ODP_ASSERT(ODP_PACKET_OFFSET_INVALID != ip_offset);
ODP_ASSERT(NULL != ip);
@@ -301,7 +302,7 @@ static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt,
if (_ODP_IPV4HDR_IS_FRAGMENT(odp_be_to_cpu_16(ip->frag_offset))) {
status->error.proto = 1;
- goto out;
+ goto err;
}
/* Check IP header for IPSec protocols and look it up */
@@ -311,7 +312,7 @@ static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt,
if (odp_packet_copy_to_mem(pkt, ipsec_offset,
sizeof(esp), &esp) < 0) {
status->error.alg = 1;
- goto out;
+ goto err;
}
if (ODP_IPSEC_SA_INVALID == sa) {
@@ -324,7 +325,7 @@ static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt,
ipsec_sa = _odp_ipsec_sa_lookup(&lookup);
if (NULL == ipsec_sa) {
status->error.sa_lookup = 1;
- goto out;
+ goto err;
}
} else {
ipsec_sa = _odp_ipsec_sa_use(sa);
@@ -332,7 +333,7 @@ static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt,
if (ipsec_sa->proto != ODP_IPSEC_ESP ||
ipsec_sa->spi != odp_be_to_cpu_32(esp.spi)) {
status->error.proto = 1;
- goto out;
+ goto err;
}
}
@@ -342,7 +343,7 @@ static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt,
ipsec_sa->esp_iv_len,
iv + ipsec_sa->salt_length) < 0) {
status->error.alg = 1;
- goto out;
+ goto err;
}
hdr_len = _ODP_ESPHDR_LEN + ipsec_sa->esp_iv_len;
@@ -376,7 +377,7 @@ static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt,
if (odp_packet_copy_to_mem(pkt, ipsec_offset,
sizeof(ah), &ah) < 0) {
status->error.alg = 1;
- goto out;
+ goto err;
}
if (ODP_IPSEC_SA_INVALID == sa) {
@@ -389,7 +390,7 @@ static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt,
ipsec_sa = _odp_ipsec_sa_lookup(&lookup);
if (NULL == ipsec_sa) {
status->error.sa_lookup = 1;
- goto out;
+ goto err;
}
} else {
ipsec_sa = _odp_ipsec_sa_use(sa);
@@ -397,7 +398,7 @@ static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt,
if (ipsec_sa->proto != ODP_IPSEC_AH ||
ipsec_sa->spi != odp_be_to_cpu_32(ah.spi)) {
status->error.proto = 1;
- goto out;
+ goto err;
}
}
@@ -431,16 +432,16 @@ static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt,
stats_length = param.auth_range.length;
} else {
status->error.proto = 1;
- goto out;
+ goto err;
}
if (_odp_ipsec_sa_replay_precheck(ipsec_sa,
odp_be_to_cpu_32(aad.seq_no),
status) < 0)
- goto out;
+ goto err;
if (_odp_ipsec_sa_stats_precheck(ipsec_sa, status) < 0)
- goto out;
+ goto err;
param.session = ipsec_sa->session;
@@ -448,14 +449,14 @@ static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt,
if (rc < 0) {
ODP_DBG("Crypto failed\n");
status->error.alg = 1;
- goto out;
+ goto err;
}
rc = odp_crypto_result(&crypto, pkt);
if (rc < 0) {
ODP_DBG("Crypto failed\n");
status->error.alg = 1;
- goto out;
+ goto err;
}
if (!crypto.ok) {
@@ -471,16 +472,16 @@ static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt,
ODP_CRYPTO_HW_ERR_NONE))
status->error.auth = 1;
- goto out;
+ goto err;
}
if (_odp_ipsec_sa_stats_update(ipsec_sa, stats_length, status) < 0)
- goto out;
+ goto err;
if (_odp_ipsec_sa_replay_update(ipsec_sa,
odp_be_to_cpu_32(aad.seq_no),
status) < 0)
- goto out;
+ goto err;
ip_offset = odp_packet_l3_offset(pkt);
ip = odp_packet_l3_ptr(pkt, NULL);
@@ -498,18 +499,18 @@ static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt,
if (odp_packet_copy_to_mem(pkt, esptrl_offset,
sizeof(esptrl), &esptrl) < 0) {
status->error.proto = 1;
- goto out;
+ goto err;
}
if (ip_offset + esptrl.pad_len > esptrl_offset) {
status->error.proto = 1;
- goto out;
+ goto err;
}
if (_odp_packet_cmp_data(pkt, esptrl_offset - esptrl.pad_len,
ipsec_padding, esptrl.pad_len) != 0) {
status->error.proto = 1;
- goto out;
+ goto err;
}
ip->proto = esptrl.next_header;
@@ -523,7 +524,7 @@ static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt,
if (odp_packet_copy_to_mem(pkt, ipsec_offset,
sizeof(ah), &ah) < 0) {
status->error.alg = 1;
- goto out;
+ goto err;
}
ip->proto = ah.next_header;
@@ -534,12 +535,12 @@ static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt,
ip->frag_offset = odp_cpu_to_be_16(ip_frag_offset);
} else {
status->error.proto = 1;
- goto out;
+ goto err;
}
if (odp_packet_trunc_tail(&pkt, trl_len, NULL, NULL) < 0) {
status->error.alg = 1;
- goto out;
+ goto err;
}
if (ODP_IPSEC_MODE_TUNNEL == ipsec_sa->mode) {
@@ -550,7 +551,7 @@ static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt,
if (odp_packet_trunc_head(&pkt, ip_hdr_len + hdr_len,
NULL, NULL) < 0) {
status->error.alg = 1;
- goto out;
+ goto err;
}
} else {
odp_packet_move_data(pkt, hdr_len, 0,
@@ -558,7 +559,7 @@ static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt,
if (odp_packet_trunc_head(&pkt, hdr_len,
NULL, NULL) < 0) {
status->error.alg = 1;
- goto out;
+ goto err;
}
}
@@ -573,15 +574,21 @@ static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt,
_odp_ipv4_csum_update(pkt);
}
- if (!status->error.all) {
- odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+ pkt_hdr = odp_packet_hdr(pkt);
- packet_parse_reset(pkt_hdr);
+ packet_parse_reset(pkt_hdr);
+
+ packet_parse_l3_l4(pkt_hdr, parse_layer(ipsec_config.inbound.parse),
+ ip_offset, _ODP_ETHTYPE_IPV4);
+
+ *pkt_out = pkt;
+
+ return ipsec_sa;
+
+err:
+ pkt_hdr = odp_packet_hdr(pkt);
+ pkt_hdr->p.error_flags.ipsec_err = 1;
- packet_parse_l3_l4(pkt_hdr, parse_layer(ipsec_config.inbound.parse),
- ip_offset, _ODP_ETHTYPE_IPV4);
- }
-out:
*pkt_out = pkt;
return ipsec_sa;
@@ -620,6 +627,7 @@ static ipsec_sa_t *ipsec_out_single(odp_packet_t pkt,
uint8_t ip_ttl; /**< Saved IP TTL value */
uint16_t ip_frag_offset; /**< Saved IP flags value */
odp_crypto_packet_result_t crypto; /**< Crypto operation result */
+ odp_packet_hdr_t *pkt_hdr;
ODP_ASSERT(ODP_PACKET_OFFSET_INVALID != ip_offset);
ODP_ASSERT(NULL != ip);
@@ -637,7 +645,7 @@ static ipsec_sa_t *ipsec_out_single(odp_packet_t pkt,
if (ODP_IPSEC_MODE_TRANSPORT == ipsec_sa->mode &&
_ODP_IPV4HDR_IS_FRAGMENT(odp_be_to_cpu_16(ip->frag_offset))) {
status->error.alg = 1;
- goto out;
+ goto err;
}
if (ODP_IPSEC_MODE_TUNNEL == ipsec_sa->mode) {
@@ -673,7 +681,7 @@ static ipsec_sa_t *ipsec_out_single(odp_packet_t pkt,
if (odp_packet_extend_head(&pkt, _ODP_IPV4HDR_LEN,
NULL, NULL) < 0) {
status->error.alg = 1;
- goto out;
+ goto err;
}
odp_packet_move_data(pkt, 0, _ODP_IPV4HDR_LEN, ip_offset);
@@ -719,7 +727,7 @@ static ipsec_sa_t *ipsec_out_single(odp_packet_t pkt,
1);
/* Check for overrun */
if (ctr == 0)
- goto out;
+ goto err;
memcpy(iv, ipsec_sa->salt, ipsec_sa->salt_length);
memcpy(iv + ipsec_sa->salt_length, &ctr,
@@ -733,7 +741,7 @@ static ipsec_sa_t *ipsec_out_single(odp_packet_t pkt,
if (len != ipsec_sa->esp_iv_len) {
status->error.alg = 1;
- goto out;
+ goto err;
}
}
@@ -741,12 +749,12 @@ static ipsec_sa_t *ipsec_out_single(odp_packet_t pkt,
if (odp_packet_extend_tail(&pkt, trl_len, NULL, NULL) < 0) {
status->error.alg = 1;
- goto out;
+ goto err;
}
if (odp_packet_extend_head(&pkt, hdr_len, NULL, NULL) < 0) {
status->error.alg = 1;
- goto out;
+ goto err;
}
odp_packet_move_data(pkt, 0, hdr_len, ipsec_offset);
@@ -819,12 +827,12 @@ static ipsec_sa_t *ipsec_out_single(odp_packet_t pkt,
if (odp_packet_extend_tail(&pkt, trl_len, NULL, NULL) < 0) {
status->error.alg = 1;
- goto out;
+ goto err;
}
if (odp_packet_extend_head(&pkt, hdr_len, NULL, NULL) < 0) {
status->error.alg = 1;
- goto out;
+ goto err;
}
odp_packet_move_data(pkt, 0, hdr_len, ipsec_offset);
@@ -866,12 +874,12 @@ static ipsec_sa_t *ipsec_out_single(odp_packet_t pkt,
stats_length = param.auth_range.length;
} else {
status->error.alg = 1;
- goto out;
+ goto err;
}
/* No need to run precheck here, we know that packet is authentic */
if (_odp_ipsec_sa_stats_update(ipsec_sa, stats_length, status) < 0)
- goto out;
+ goto err;
param.session = ipsec_sa->session;
@@ -879,14 +887,14 @@ static ipsec_sa_t *ipsec_out_single(odp_packet_t pkt,
if (rc < 0) {
ODP_DBG("Crypto failed\n");
status->error.alg = 1;
- goto out;
+ goto err;
}
rc = odp_crypto_result(&crypto, pkt);
if (rc < 0) {
ODP_DBG("Crypto failed\n");
status->error.alg = 1;
- goto out;
+ goto err;
}
if (!crypto.ok) {
@@ -902,7 +910,7 @@ static ipsec_sa_t *ipsec_out_single(odp_packet_t pkt,
ODP_CRYPTO_HW_ERR_NONE))
status->error.auth = 1;
- goto out;
+ goto err;
}
ip = odp_packet_l3_ptr(pkt, NULL);
@@ -916,7 +924,13 @@ static ipsec_sa_t *ipsec_out_single(odp_packet_t pkt,
_odp_ipv4_csum_update(pkt);
-out:
+ *pkt_out = pkt;
+ return ipsec_sa;
+
+err:
+ pkt_hdr = odp_packet_hdr(pkt);
+
+ pkt_hdr->p.error_flags.ipsec_err = 1;
*pkt_out = pkt;
return ipsec_sa;