Bill Fischofer(Bill-Fischofer-Linaro) replied on github web page:

example/ipsec_offload/odp_ipsec_offload.c
line 319
@@ -0,0 +1,855 @@
+/* Copyright (c) 2017, Linaro Limited
+ * Copyright (C) 2017 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * @example odp_ipsec_offload.c  ODP basic packet IO cross connect with IPsec
+ * test application
+ */
+
+#define _DEFAULT_SOURCE
+/* enable strtok */
+#define _POSIX_C_SOURCE 200112L
+#include <stdlib.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include <example_debug.h>
+
+#include <odp_api.h>
+#include <odp/helper/linux.h>
+#include <odp/helper/eth.h>
+#include <odp/helper/ip.h>
+#include <odp/helper/icmp.h>
+#include <odp/helper/udp.h>
+#include <odp/helper/ipsec.h>
+
+#include <stdbool.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netpacket/packet.h>
+#include <net/ethernet.h>
+#include <arpa/inet.h>
+
+#include <odp_ipsec_offload_misc.h>
+#include <odp_ipsec_offload_sa_db.h>
+#include <odp_ipsec_offload_sp_db.h>
+#include <odp_ipsec_offload_fwd_db.h>
+#include <odp_ipsec_offload_cache.h>
+
+#define MAX_WORKERS     32   /**< maximum number of worker threads */
+
+/**
+ * Parsed command line application arguments
+ */
+typedef struct {
+       int cpu_count;
+       int flows;
+       int if_count;           /**< Number of interfaces to be used */
+       char **if_names;        /**< Array of pointers to interface names */
+       char *if_str;           /**< Storage for interface names */
+       int queue_type;         /**< Queue synchronization type*/
+} appl_args_t;
+/**
+ * Grouping of both parsed CL args and thread specific args - alloc together
+ */
+typedef struct {
+       /** Application (parsed) arguments */
+       appl_args_t appl;
+} args_t;
+
+/* helper funcs */
+static void parse_args(int argc, char *argv[], appl_args_t *appl_args);
+static void print_info(char *progname, appl_args_t *appl_args);
+static void usage(char *progname);
+
+/** Global pointer to args */
+static args_t *args;
+
+/**
+ * Buffer pool for packet IO
+ */
+#define SHM_PKT_POOL_BUF_COUNT 1024
+#define SHM_PKT_POOL_BUF_SIZE  4096
+#define SHM_PKT_POOL_SIZE      (SHM_PKT_POOL_BUF_COUNT * SHM_PKT_POOL_BUF_SIZE)
+
+static odp_pool_t pkt_pool = ODP_POOL_INVALID;
+
+/** Synchronize threads before packet processing begins */
+static odp_barrier_t sync_barrier;
+
+/**
+ * Packet processing result codes
+ */
+typedef enum {
+       PKT_CONTINUE,    /**< No events posted, keep processing */
+       PKT_POSTED,      /**< Event posted, stop processing */
+       PKT_DROP,        /**< Reason to drop detected, stop processing */
+       PKT_DONE         /**< Finished with packet, stop processing */
+} pkt_disposition_e;
+
+#define MAX_COMPL_QUEUES               32
+#define GET_THR_QUEUE_ID(x)            ((odp_thread_id() - 1) % (x))
+
+/** Atomic queue IPSEC completion events */
+static odp_queue_t completionq[MAX_COMPL_QUEUES];
+
+static int num_compl_queues;
+static int num_workers;
+
+/**
+ * Calculate hash value on given 2-tuple i.e. sip, dip
+ *
+ * @param ip_src       Source IP Address
+ * @param ip_dst       Destination IP Address
+ *
+ * @return Resultant hash value
+ */
+static inline uint64_t calculate_flow_hash(uint32_t ip_src, uint32_t ip_dst)
+{
+       uint64_t hash = 0;
+
+       ip_dst += JHASH_GOLDEN_RATIO;
+       BJ3_MIX(ip_src, ip_dst, hash);
+       return hash;
+}
+
+/**
+ * IPsec pre argument processing initialization
+ */
+static
+void ipsec_init_pre(void)
+{
+       /* Initialize our data bases */
+       init_sp_db();
+       init_sa_db();
+       init_tun_db();
+       init_ipsec_cache();
+}
+
+/**
+ * IPsec post argument processing initialization
+ *
+ * Resolve SP DB with SA DB and create corresponding IPsec cache entries
+ */
+static
+void ipsec_init_post(void)
+{
+       sp_db_entry_t *entry;
+       int queue_id = 0;
+
+       /* Attempt to find appropriate SA for each SP */
+       for (entry = sp_db->list; NULL != entry; entry = entry->next) {
+               sa_db_entry_t *cipher_sa = NULL;
+               sa_db_entry_t *auth_sa = NULL;
+               tun_db_entry_t *tun = NULL;
+
+               queue_id %= num_workers;
+               if (num_compl_queues < num_workers)
+                       num_compl_queues++;
+               queue_id++;
+               if (entry->esp) {
+                       cipher_sa = find_sa_db_entry(&entry->src_subnet,
+                                                    &entry->dst_subnet, 1);
+                       tun = find_tun_db_entry(cipher_sa->src_ip,
+                                               cipher_sa->dst_ip);
+               }
+               if (entry->ah) {
+                       auth_sa = find_sa_db_entry(&entry->src_subnet,
+                                                  &entry->dst_subnet, 0);
+                       tun = find_tun_db_entry(auth_sa->src_ip,
+                                               auth_sa->dst_ip);
+               }
+
+               if (cipher_sa && auth_sa) {
+                       if (create_ipsec_cache_entry(cipher_sa,
+                                                    auth_sa,
+                                                    tun,
+                                                    entry->input,
+                                                    completionq[queue_id - 
1])) {
+                               EXAMPLE_ABORT("Error: IPSec cache entry 
failed.\n");
+                       }
+               } else {
+                       printf(" WARNING: SA not found for SP\n");
+                       dump_sp_db_entry(entry);
+               }
+       }
+}
+
+/**
+ * Initialize interface
+ *
+ * Initialize ODP pktio and queues, query MAC address and update
+ * forwarding database.
+ *
+ * @param intf         Interface name string
+ * @param queue_type   Type of queue to configure.
+ */
+static void initialize_intf(char *intf, int queue_type)
+{
+       odp_pktio_t pktio;
+       odp_pktout_queue_t pktout;
+       int ret;
+       uint8_t src_mac[ODPH_ETHADDR_LEN];
+       odp_pktio_param_t pktio_param;
+       odp_pktio_capability_t capa;
+       odp_pktin_queue_param_t pktin_param;
+
+       odp_pktio_param_init(&pktio_param);
+
+       pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;
+
+       /*
+        * Open a packet IO instance for thread and get default output queue
+        */
+       pktio = odp_pktio_open(intf, pkt_pool, &pktio_param);
+       if (ODP_PKTIO_INVALID == pktio)
+               EXAMPLE_ABORT("Error: pktio create failed for %s\n", intf);
+
+       odp_pktin_queue_param_init(&pktin_param);
+
+       ret = odp_pktio_capability(pktio, &capa);
+       if (ret != 0)
+               EXAMPLE_ABORT("Error: Unable to get pktio capability %s\n",
+                             intf);
+
+       pktin_param.queue_param.type = ODP_QUEUE_TYPE_SCHED;
+       pktin_param.queue_param.sched.sync = queue_type;
+       pktin_param.queue_param.sched.prio = ODP_SCHED_PRIO_DEFAULT;
+       pktin_param.num_queues = capa.max_input_queues;
+
+       if (pktin_param.num_queues > 1)
+               pktin_param.hash_enable = 1;
+
+       if (odp_pktin_queue_config(pktio, &pktin_param))
+               EXAMPLE_ABORT("Error: pktin config failed for %s\n", intf);
+
+       if (odp_pktout_queue_config(pktio, NULL))
+               EXAMPLE_ABORT("Error: pktout config failed for %s\n", intf);
+
+       if (odp_pktout_queue(pktio, &pktout, 1) != 1)
+               EXAMPLE_ABORT("Error: failed to get pktout queue for %s\n",
+                             intf);
+
+       ret = odp_pktio_start(pktio);
+       if (ret)
+               EXAMPLE_ABORT("Error: unable to start %s\n", intf);
+
+       /* Read the source MAC address for this interface */
+       ret = odp_pktio_mac_addr(pktio, src_mac, sizeof(src_mac));
+       if (ret < 0) {
+               EXAMPLE_ABORT("Error: failed during MAC address get for %s\n",
+                             intf);
+       }
+
+       printf("Created pktio:%02" PRIu64 "\n", odp_pktio_to_u64(pktio));
+
+       /* Resolve any routes using this interface for output */
+       resolve_fwd_db(intf, pktout, src_mac);
+}
+
+/**
+ * Packet Processing - Input verification
+ *
+ * @param pkt  Packet to inspect
+ *
+ * @return PKT_CONTINUE if good, supported packet else PKT_DROP
+ */
+static pkt_disposition_e do_input_verify(odp_packet_t pkt)
+{
+       if (odp_unlikely(odp_packet_has_error(pkt))) {
+               odp_packet_free(pkt);
+               return PKT_DROP;
+       }
+
+       if (!odp_packet_has_eth(pkt)) {
+               odp_packet_free(pkt);
+               return PKT_DROP;
+       }
+
+       if (!odp_packet_has_ipv4(pkt)) {
+               odp_packet_free(pkt);
+               return PKT_DROP;
+       }
+
+       return PKT_CONTINUE;
+}
+
+/**
+ * Packet Processing - Route lookup in forwarding database
+ *
+ * @param pkt  Packet to route
+ *
+ * @return PKT_CONTINUE if route found else PKT_DROP
+ */
+static
+pkt_disposition_e do_route_fwd_db(odp_packet_t pkt)
+{
+       odph_ipv4hdr_t *ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
+       fwd_db_entry_t *fwd_entry;
+       ipsec_cache_entry_t *ipsec_entry;
+       uint32_t        sip, dip;
+       uint64_t        hash;
+       odp_flow_entry_t *flow = NULL;
+
+       if (ip->ttl > 1) {
+               ip->ttl -= 1;
+               if (ip->chksum >= odp_cpu_to_be_16(0xffff - 0x100))
+                       ip->chksum += odp_cpu_to_be_16(0x100) + 1;
+               else
+                       ip->chksum += odp_cpu_to_be_16(0x100);
+       } else {
+               odp_packet_free(pkt);
+               return PKT_DROP;
+       }
+
+       sip = odp_be_to_cpu_32(ip->src_addr);
+       dip = odp_be_to_cpu_32(ip->dst_addr);
+
+       hash = calculate_flow_hash(sip, dip);
+
+       flow = odp_route_flow_lookup_in_bucket(sip, dip,


Comment:
Don't use the `odp_` prefix for application routines. It's not a good practice, 
especially in an example.

https://github.com/Linaro/odp/pull/339#discussion_r157375103
updated_at 2017-12-17 18:09:27

Reply via email to