Signed-off-by: Benoît Ganne <bga...@kalray.eu>
---
 example/classifier/odp_classifier.c | 95 +++++++++++++++++++++++++++++--------
 1 file changed, 76 insertions(+), 19 deletions(-)

diff --git a/example/classifier/odp_classifier.c 
b/example/classifier/odp_classifier.c
index 6d6dd59..5f8ec5c 100644
--- a/example/classifier/odp_classifier.c
+++ b/example/classifier/odp_classifier.c
@@ -53,11 +53,12 @@ typedef struct {
        odp_pmr_t pmr;          /**< Associated pmr handle */
        odp_atomic_u64_t packet_count;  /**< count of received packets */
        char queue_name[ODP_QUEUE_NAME_LEN];    /**< queue name */
-       int val_sz;     /**< size of the pmr term */
        struct {
                odp_pmr_term_e term;    /**< odp pmr term value */
-               uint32_t val;   /**< pmr term value */
-               uint32_t mask;  /**< pmr term mask */
+               uint64_t val;   /**< pmr term value */
+               uint64_t mask;  /**< pmr term mask */
+               uint32_t val_sz;        /**< size of the pmr term */
+               uint32_t offset;        /**< pmr term offset */
        } rule;
        char value[DISPLAY_STRING_LEN]; /**< Display string for value */
        char mask[DISPLAY_STRING_LEN];  /**< Display string for mask */
@@ -86,7 +87,8 @@ static void print_info(char *progname, appl_args_t 
*appl_args);
 static void usage(char *progname);
 static void configure_cos_queue(odp_pktio_t pktio, appl_args_t *args);
 static void configure_default_queue(odp_pktio_t pktio, appl_args_t *args);
-static int convert_str_to_pmr_enum(char *token, odp_pmr_term_e *term);
+static int convert_str_to_pmr_enum(char *token, odp_pmr_term_e *term,
+                                  uint32_t *offset);
 static int parse_pmr_policy(appl_args_t *appl_args, char *argv[], char 
*optarg);
  static inline
@@ -151,12 +153,13 @@ void print_cls_statistics(appl_args_t *args)
 }
  static inline
-int parse_ipv4_addr(const char *ipaddress, uint32_t *addr)
+int parse_ipv4_addr(const char *ipaddress, uint64_t *addr)
 {
-       int b[4];
+       uint32_t b[4];
        int converted;
 -      converted = sscanf(ipaddress, "%d.%d.%d.%d",
+       converted = sscanf(ipaddress, "%" SCNx32 ".%" SCNx32
+                          ".%" SCNx32 ".%" SCNx32,
                        &b[3], &b[2], &b[1], &b[0]);
        if (4 != converted)
                return -1;
@@ -170,16 +173,42 @@ int parse_ipv4_addr(const char *ipaddress, uint32_t *addr)
 }
  static inline
-int parse_ipv4_mask(const char *str, uint32_t *mask)
+int parse_mask(const char *str, uint64_t *mask)
 {
-       uint32_t b;
+       uint64_t b;
        int ret;
 -      ret = sscanf(str, "%" SCNx32, &b);
+       ret = sscanf(str, "%" SCNx64, &b);
        *mask = b;
        return ret != 1;
 }
 +static
+int parse_value(const char *str, uint64_t *val, unsigned int *val_sz)
+{
+       size_t len;
+       size_t i;
+       int converted;
+       union {
+               uint64_t u64;
+               uint8_t u8[8];
+       } buf = {.u64 = 0};
+
+       len = strlen(str);
+       if (len > 2 * sizeof(buf))
+               return -1;
+
+       for (i = 0; i < len; i += 2) {
+               converted = sscanf(&str[i], "%2" SCNx8, &buf.u8[i / 2]);
+               if (1 != converted)
+                       return -1;
+       }
+
+       *val = buf.u64;
+       *val_sz = len / 2;
+       return 0;
+}
+
 /**
  * Create a pktio handle, optionally associating a default input queue.
  *
@@ -348,10 +377,14 @@ static void configure_cos_queue(odp_pktio_t pktio, 
appl_args_t *args)
                sprintf(cos_name, "CoS%s", stats->queue_name);
                stats->cos = odp_cos_create(cos_name);
 -              stats->pmr = odp_pmr_create(stats->rule.term,
-                                           &stats->rule.val,
-                                           &stats->rule.mask,
-                                           stats->val_sz);
+               const odp_pmr_match_t match = {
+                       .term = stats->rule.term,
+                       .val = &stats->rule.val,
+                       .mask = &stats->rule.mask,
+                       .val_sz = stats->rule.val_sz,
+                       .offset = stats->rule.offset,
+               };
+               stats->pmr = odp_pmr_create(&match);
                qparam.sched.prio = i % odp_schedule_num_prio();
                qparam.sched.sync = ODP_SCHED_SYNC_NONE;
                qparam.sched.group = ODP_SCHED_GROUP_ALL;
@@ -556,7 +589,8 @@ static void swap_pkt_addrs(odp_packet_t pkt_tbl[], unsigned 
len)
        }
 }
 -static int convert_str_to_pmr_enum(char *token, odp_pmr_term_e *term)
+static int convert_str_to_pmr_enum(char *token, odp_pmr_term_e *term,
+                                  uint32_t *offset)
 {
        if (NULL == token)
                return -1;
@@ -564,6 +598,13 @@ static int convert_str_to_pmr_enum(char *token, 
odp_pmr_term_e *term)
        if (0 == strcasecmp(token, "ODP_PMR_SIP_ADDR")) {
                *term = ODP_PMR_SIP_ADDR;
                return 0;
+       } else {
+               errno = 0;
+               *offset = strtoul(token, NULL, 0);
+               if (errno)
+                       return -1;
+               *term = ODP_PMR_CUSTOM_FRAME;
+               return 0;
        }
        return -1;
 }
@@ -577,6 +618,7 @@ static int parse_pmr_policy(appl_args_t *appl_args, char 
*argv[], char *optarg)
        odp_pmr_term_e term;
        global_statistics *stats;
        char *pmr_str;
+       uint32_t offset;
        policy_count = appl_args->policy_count;
        stats = appl_args->stats;
@@ -594,7 +636,7 @@ static int parse_pmr_policy(appl_args_t *appl_args, char 
*argv[], char *optarg)
        /* PMR TERM */
        token = strtok(pmr_str, ":");
-       if (convert_str_to_pmr_enum(token, &term)) {
+       if (convert_str_to_pmr_enum(token, &term, &offset)) {
                EXAMPLE_ERR("Invalid ODP_PMR_TERM string\n");
                exit(EXIT_FAILURE);
        }
@@ -610,8 +652,21 @@ static int parse_pmr_policy(appl_args_t *appl_args, char 
*argv[], char *optarg)
                token = strtok(NULL, ":");
                strncpy(stats[policy_count].mask, token,
                        DISPLAY_STRING_LEN - 1);
-               parse_ipv4_mask(token, &stats[policy_count].rule.mask);
-               stats[policy_count].val_sz = 4;
+               parse_mask(token, &stats[policy_count].rule.mask);
+               stats[policy_count].rule.val_sz = 4;
+               stats[policy_count].rule.offset = 0;
+       break;
+       case ODP_PMR_CUSTOM_FRAME:
+               token = strtok(NULL, ":");
+               strncpy(stats[policy_count].value, token,
+                       DISPLAY_STRING_LEN - 1);
+               parse_value(token, &stats[policy_count].rule.val,
+                           &stats[policy_count].rule.val_sz);
+               token = strtok(NULL, ":");
+               strncpy(stats[policy_count].mask, token,
+                       DISPLAY_STRING_LEN - 1);
+               parse_mask(token, &stats[policy_count].rule.mask);
+               stats[policy_count].rule.offset = offset;
        break;
        default:
                usage(argv[0]);
@@ -765,10 +820,12 @@ static void usage(char *progname)
                        "\n"
                        "Mandatory OPTIONS:\n"
                        "  -i, --interface Eth interface\n"
-                       "  -p, --policy <odp_pmr_term_e>:<value>:<mask 
bits>:<queue name>\n"
+                       "  -p, --policy 
[<odp_pmr_term_e>|<offset>]:<value>:<mask bits>:<queue name>\n"
                        "\n"
                        "<odp_pmr_term_e>       Packet Matching Rule defined 
with odp_pmr_term_e "
                        "for the policy\n"
+                       "<offset>               Absolute offset in bytes from 
frame start to define a "
+                       "ODP_PMR_CUSTOM_FRAME Packet Matching Rule for the 
policy\n"
                        "\n"
                        "<value>                PMR value to be matched.\n"
                        "\n"
-- 
2.5.0

_______________________________________________
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to