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

Allow per-packet override of IP parameters.

Signed-off-by: Dmitry Eremin-Solenikov <dmitry.ereminsoleni...@linaro.org>
Reviewed-by: Bill Fischofer <bill.fischo...@linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uva...@linaro.org>
---
/** Email created from pull request 505 (muvarov:devel/master_merge_api-next)
 ** https://github.com/Linaro/odp/pull/505
 ** Patch: https://github.com/Linaro/odp/pull/505.patch
 ** Base sha: 284f52d72ec19df3774c7409780f1f9eea33b8e6
 ** Merge commit sha: e8f50fefcd57a92e0971dc1172c5402c56b8370a
 **/
 .../linux-generic/include/odp_ipsec_internal.h     |  9 ++---
 platform/linux-generic/odp_ipsec.c                 | 38 ++++++++++++++--------
 platform/linux-generic/odp_ipsec_sad.c             | 20 ++++++++----
 3 files changed, 40 insertions(+), 27 deletions(-)

diff --git a/platform/linux-generic/include/odp_ipsec_internal.h 
b/platform/linux-generic/include/odp_ipsec_internal.h
index a449462ab..dfde4d574 100644
--- a/platform/linux-generic/include/odp_ipsec_internal.h
+++ b/platform/linux-generic/include/odp_ipsec_internal.h
@@ -161,22 +161,17 @@ struct ipsec_sa_s {
 
                        union {
                        struct {
+                               odp_ipsec_ipv4_param_t param;
                                odp_u32be_t     src_ip;
                                odp_u32be_t     dst_ip;
 
                                /* 32-bit from which low 16 are used */
                                odp_atomic_u32_t hdr_id;
-
-                               uint8_t         ttl;
-                               uint8_t         dscp;
-                               uint8_t         df;
                        } tun_ipv4;
                        struct {
+                               odp_ipsec_ipv6_param_t param;
                                uint8_t         src_ip[_ODP_IPV6ADDR_LEN];
                                uint8_t         dst_ip[_ODP_IPV6ADDR_LEN];
-                               uint8_t         hlimit;
-                               uint8_t         dscp;
-                               uint32_t        flabel;
                        } tun_ipv6;
                        };
                } out;
diff --git a/platform/linux-generic/odp_ipsec.c 
b/platform/linux-generic/odp_ipsec.c
index 80362672d..9d13e60ca 100644
--- a/platform/linux-generic/odp_ipsec.c
+++ b/platform/linux-generic/odp_ipsec.c
@@ -888,7 +888,8 @@ static int ipsec_out_tunnel_parse_ipv6(ipsec_state_t *state,
 
 static int ipsec_out_tunnel_ipv4(odp_packet_t *pkt,
                                 ipsec_state_t *state,
-                                ipsec_sa_t *ipsec_sa)
+                                ipsec_sa_t *ipsec_sa,
+                                const odp_ipsec_ipv4_param_t *ipv4_param)
 {
        _odp_ipv4hdr_t out_ip;
        uint16_t flags;
@@ -899,7 +900,7 @@ static int ipsec_out_tunnel_ipv4(odp_packet_t *pkt,
        else
                out_ip.tos = (state->out_tunnel.ip_tos &
                              ~_ODP_IP_TOS_DSCP_MASK) |
-                            (ipsec_sa->out.tun_ipv4.dscp <<
+                            (ipv4_param->dscp <<
                              _ODP_IP_TOS_DSCP_SHIFT);
        state->ip_tot_len = odp_packet_len(*pkt) - state->ip_offset;
        state->ip_tot_len += _ODP_IPV4HDR_LEN;
@@ -911,13 +912,15 @@ static int ipsec_out_tunnel_ipv4(odp_packet_t *pkt,
        if (ipsec_sa->copy_df)
                flags = state->out_tunnel.ip_df;
        else
-               flags = ((uint16_t)ipsec_sa->out.tun_ipv4.df) << 14;
+               flags = ((uint16_t)ipv4_param->df) << 14;
        out_ip.frag_offset = _odp_cpu_to_be_16(flags);
-       out_ip.ttl = ipsec_sa->out.tun_ipv4.ttl;
+       out_ip.ttl = ipv4_param->ttl;
        /* Will be filled later by packet checksum update */
        out_ip.chksum = 0;
-       out_ip.src_addr = ipsec_sa->out.tun_ipv4.src_ip;
-       out_ip.dst_addr = ipsec_sa->out.tun_ipv4.dst_ip;
+       memcpy(&out_ip.src_addr, ipv4_param->src_addr,
+              _ODP_IPV4ADDR_LEN);
+       memcpy(&out_ip.dst_addr, ipv4_param->dst_addr,
+              _ODP_IPV4ADDR_LEN);
 
        if (odp_packet_extend_head(pkt, _ODP_IPV4HDR_LEN,
                                   NULL, NULL) < 0)
@@ -947,7 +950,8 @@ static int ipsec_out_tunnel_ipv4(odp_packet_t *pkt,
 
 static int ipsec_out_tunnel_ipv6(odp_packet_t *pkt,
                                 ipsec_state_t *state,
-                                ipsec_sa_t *ipsec_sa)
+                                ipsec_sa_t *ipsec_sa,
+                                const odp_ipsec_ipv6_param_t *ipv6_param)
 {
        _odp_ipv6hdr_t out_ip;
        uint32_t ver;
@@ -958,23 +962,23 @@ static int ipsec_out_tunnel_ipv6(odp_packet_t *pkt,
        else
                ver |= ((state->out_tunnel.ip_tos &
                         ~_ODP_IP_TOS_DSCP_MASK) |
-                       (ipsec_sa->out.tun_ipv6.dscp <<
+                       (ipv6_param->dscp <<
                         _ODP_IP_TOS_DSCP_SHIFT)) <<
                        _ODP_IPV6HDR_TC_SHIFT;
        if (ipsec_sa->copy_flabel)
                ver |= state->out_tunnel.ip_flabel;
        else
-               ver |= ipsec_sa->out.tun_ipv6.flabel;
+               ver |= ipv6_param->flabel;
        out_ip.ver_tc_flow = odp_cpu_to_be_32(ver);
 
        state->ip_tot_len = odp_packet_len(*pkt) - state->ip_offset;
        out_ip.payload_len = _odp_cpu_to_be_16(state->ip_tot_len);
        state->ip_tot_len += _ODP_IPV6HDR_LEN;
 
-       out_ip.hop_limit = ipsec_sa->out.tun_ipv6.hlimit;
-       memcpy(&out_ip.src_addr, ipsec_sa->out.tun_ipv6.src_ip,
+       out_ip.hop_limit = ipv6_param->hlimit;
+       memcpy(&out_ip.src_addr, ipv6_param->src_addr,
               _ODP_IPV6ADDR_LEN);
-       memcpy(&out_ip.dst_addr, ipsec_sa->out.tun_ipv6.dst_ip,
+       memcpy(&out_ip.dst_addr, ipv6_param->dst_addr,
               _ODP_IPV6ADDR_LEN);
 
        if (odp_packet_extend_head(pkt, _ODP_IPV6HDR_LEN,
@@ -1352,9 +1356,15 @@ static ipsec_sa_t *ipsec_out_single(odp_packet_t pkt,
                }
 
                if (ipsec_sa->tun_ipv4)
-                       rc = ipsec_out_tunnel_ipv4(&pkt, &state, ipsec_sa);
+                       rc = ipsec_out_tunnel_ipv4(&pkt, &state, ipsec_sa,
+                                                  opt->flag.ip_param ?
+                                                  &opt->ipv4 :
+                                                  
&ipsec_sa->out.tun_ipv4.param);
                else
-                       rc = ipsec_out_tunnel_ipv6(&pkt, &state, ipsec_sa);
+                       rc = ipsec_out_tunnel_ipv6(&pkt, &state, ipsec_sa,
+                                                  opt->flag.ip_param ?
+                                                  &opt->ipv6 :
+                                                  
&ipsec_sa->out.tun_ipv6.param);
        }
        if (rc < 0) {
                status->error.alg = 1;
diff --git a/platform/linux-generic/odp_ipsec_sad.c 
b/platform/linux-generic/odp_ipsec_sad.c
index 3ac8c49c3..05865eb3a 100644
--- a/platform/linux-generic/odp_ipsec_sad.c
+++ b/platform/linux-generic/odp_ipsec_sad.c
@@ -326,11 +326,15 @@ odp_ipsec_sa_t odp_ipsec_sa_create(const 
odp_ipsec_sa_param_t *param)
                               param->outbound.tunnel.ipv4.dst_addr,
                               sizeof(ipsec_sa->out.tun_ipv4.dst_ip));
                        odp_atomic_init_u32(&ipsec_sa->out.tun_ipv4.hdr_id, 0);
-                       ipsec_sa->out.tun_ipv4.ttl =
+                       ipsec_sa->out.tun_ipv4.param.src_addr =
+                               &ipsec_sa->out.tun_ipv4.src_ip;
+                       ipsec_sa->out.tun_ipv4.param.dst_addr =
+                               &ipsec_sa->out.tun_ipv4.dst_ip;
+                       ipsec_sa->out.tun_ipv4.param.ttl =
                                param->outbound.tunnel.ipv4.ttl;
-                       ipsec_sa->out.tun_ipv4.dscp =
+                       ipsec_sa->out.tun_ipv4.param.dscp =
                                param->outbound.tunnel.ipv4.dscp;
-                       ipsec_sa->out.tun_ipv4.df =
+                       ipsec_sa->out.tun_ipv4.param.df =
                                param->outbound.tunnel.ipv4.df;
                } else {
                        ipsec_sa->tun_ipv4 = 0;
@@ -340,11 +344,15 @@ odp_ipsec_sa_t odp_ipsec_sa_create(const 
odp_ipsec_sa_param_t *param)
                        memcpy(&ipsec_sa->out.tun_ipv6.dst_ip,
                               param->outbound.tunnel.ipv6.dst_addr,
                               sizeof(ipsec_sa->out.tun_ipv6.dst_ip));
-                       ipsec_sa->out.tun_ipv6.hlimit =
+                       ipsec_sa->out.tun_ipv4.param.src_addr =
+                               &ipsec_sa->out.tun_ipv6.src_ip;
+                       ipsec_sa->out.tun_ipv4.param.dst_addr =
+                               &ipsec_sa->out.tun_ipv6.dst_ip;
+                       ipsec_sa->out.tun_ipv6.param.hlimit =
                                param->outbound.tunnel.ipv6.hlimit;
-                       ipsec_sa->out.tun_ipv6.dscp =
+                       ipsec_sa->out.tun_ipv6.param.dscp =
                                param->outbound.tunnel.ipv6.dscp;
-                       ipsec_sa->out.tun_ipv6.flabel =
+                       ipsec_sa->out.tun_ipv6.param.flabel =
                                param->outbound.tunnel.ipv6.flabel;
                }
        }

Reply via email to