From: Dmitry Eremin-Solenikov <dmitry.ereminsoleni...@linaro.org>

lookup_mode was valid only for inbound SAs but contained garbage for
outbound SAs. Thus it was possible for lookup to match SA with outbound
SA. Prevent that by marking all outbound SAs as
ODP_IPSEC_LOOKUP_DISABLED.

Signed-off-by: Dmitry Eremin-Solenikov <dmitry.ereminsoleni...@linaro.org>
---
/** Email created from pull request 427 (lumag:ipsec-fix-sad)
 ** https://github.com/Linaro/odp/pull/427
 ** Patch: https://github.com/Linaro/odp/pull/427.patch
 ** Base sha: 27480d82bd93a881ae683a3c314c11042a68ce29
 ** Merge commit sha: 67c9dbf28c41ea7a53782ba841276b03f154c4ef
 **/
 platform/linux-generic/include/odp_ipsec_internal.h |  2 +-
 platform/linux-generic/odp_ipsec_sad.c              | 14 ++++++--------
 2 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/platform/linux-generic/include/odp_ipsec_internal.h 
b/platform/linux-generic/include/odp_ipsec_internal.h
index dbdcbb917..bdb86c400 100644
--- a/platform/linux-generic/include/odp_ipsec_internal.h
+++ b/platform/linux-generic/include/odp_ipsec_internal.h
@@ -122,6 +122,7 @@ struct ipsec_sa_s {
 
        uint8_t         salt[IPSEC_MAX_SALT_LEN];
        uint32_t        salt_length;
+       odp_ipsec_lookup_mode_t lookup_mode;
 
        union {
                unsigned flags;
@@ -144,7 +145,6 @@ struct ipsec_sa_s {
 
        union {
                struct {
-                       odp_ipsec_lookup_mode_t lookup_mode;
                        odp_ipsec_ip_version_t lookup_ver;
                        union {
                                odp_u32be_t     lookup_dst_ipv4;
diff --git a/platform/linux-generic/odp_ipsec_sad.c 
b/platform/linux-generic/odp_ipsec_sad.c
index ad229e754..2af72bbb5 100644
--- a/platform/linux-generic/odp_ipsec_sad.c
+++ b/platform/linux-generic/odp_ipsec_sad.c
@@ -274,8 +274,8 @@ odp_ipsec_sa_t odp_ipsec_sa_create(const 
odp_ipsec_sa_param_t *param)
        ipsec_sa->mode = param->mode;
        ipsec_sa->flags = 0;
        if (ODP_IPSEC_DIR_INBOUND == param->dir) {
-               ipsec_sa->in.lookup_mode = param->inbound.lookup_mode;
-               if (ODP_IPSEC_LOOKUP_DSTADDR_SPI == ipsec_sa->in.lookup_mode) {
+               ipsec_sa->lookup_mode = param->inbound.lookup_mode;
+               if (ODP_IPSEC_LOOKUP_DSTADDR_SPI == ipsec_sa->lookup_mode) {
                        ipsec_sa->in.lookup_ver =
                                param->inbound.lookup_param.ip_version;
                        if (ODP_IPSEC_IPV4 == ipsec_sa->in.lookup_ver)
@@ -293,6 +293,7 @@ odp_ipsec_sa_t odp_ipsec_sa_create(const 
odp_ipsec_sa_param_t *param)
                ipsec_sa->antireplay = (param->inbound.antireplay_ws != 0);
                odp_atomic_init_u64(&ipsec_sa->in.antireplay, 0);
        } else {
+               ipsec_sa->lookup_mode = ODP_IPSEC_LOOKUP_DISABLED;
                odp_atomic_store_u32(&ipsec_sa->out.seq, 1);
                ipsec_sa->out.frag_mode = param->outbound.frag_mode;
                ipsec_sa->out.mtu = param->outbound.mtu;
@@ -552,19 +553,16 @@ int odp_ipsec_sa_mtu_update(odp_ipsec_sa_t sa, uint32_t 
mtu)
 
 ipsec_sa_t *_odp_ipsec_sa_lookup(const ipsec_sa_lookup_t *lookup)
 {
-       (void)lookup;
-
        int i;
-       ipsec_sa_t *ipsec_sa;
        ipsec_sa_t *best = NULL;
 
        for (i = 0; i < ODP_CONFIG_IPSEC_SAS; i++) {
-               ipsec_sa = ipsec_sa_entry(i);
+               ipsec_sa_t *ipsec_sa = ipsec_sa_entry(i);
 
                if (ipsec_sa_lock(ipsec_sa) < 0)
                        continue;
 
-               if (ODP_IPSEC_LOOKUP_DSTADDR_SPI == ipsec_sa->in.lookup_mode &&
+               if (ODP_IPSEC_LOOKUP_DSTADDR_SPI == ipsec_sa->lookup_mode &&
                    lookup->proto == ipsec_sa->proto &&
                    lookup->spi == ipsec_sa->spi &&
                    lookup->ver == ipsec_sa->in.lookup_ver &&
@@ -576,7 +574,7 @@ ipsec_sa_t *_odp_ipsec_sa_lookup(const ipsec_sa_lookup_t 
*lookup)
                                _odp_ipsec_sa_unuse(best);
                        return ipsec_sa;
                } else if (NULL == best &&
-                          ODP_IPSEC_LOOKUP_SPI == ipsec_sa->in.lookup_mode &&
+                          ODP_IPSEC_LOOKUP_SPI == ipsec_sa->lookup_mode &&
                           lookup->proto == ipsec_sa->proto &&
                           lookup->spi == ipsec_sa->spi) {
                        best = ipsec_sa;

Reply via email to