lpm: check rule existence
authorCristian Dumitrescu <cristian.dumitrescu@intel.com>
Wed, 4 Jun 2014 18:08:17 +0000 (19:08 +0100)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Tue, 17 Jun 2014 00:37:28 +0000 (02:37 +0200)
Added API function for LPM IPv4 and IPv6 to query for the existence
of a rule/route and return the next hop ID associated with the route
if route is present.
This is used by the Packet Framework LPM table for implementing a
routing table.

Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Acked-by: Pablo de Lara Guarch <pablo.de.lara.guarch@intel.com>
Acked by: Ivan Boule <ivan.boule@6wind.com>

lib/librte_lpm/rte_lpm.c
lib/librte_lpm/rte_lpm.h
lib/librte_lpm/rte_lpm6.c
lib/librte_lpm/rte_lpm6.h

index 592750e..35209c3 100644 (file)
@@ -619,6 +619,35 @@ rte_lpm_add(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
        return 0;
 }
 
+/*
+ * Look for a rule in the high-level rules table
+ */
+int
+rte_lpm_is_rule_present(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
+uint8_t *next_hop)
+{
+       uint32_t ip_masked;
+       int32_t rule_index;
+
+       /* Check user arguments. */
+       if ((lpm == NULL) ||
+               (next_hop == NULL) ||
+               (depth < 1) || (depth > RTE_LPM_MAX_DEPTH))
+               return -EINVAL;
+
+       /* Look for the rule using rule_find. */
+       ip_masked = ip & depth_to_mask(depth);
+       rule_index = rule_find(lpm, ip_masked, depth);
+
+       if (rule_index >= 0) {
+               *next_hop = lpm->rules_tbl[rule_index].next_hop;
+               return 1;
+       }
+
+       /* If rule is not found return 0. */
+       return 0;
+}
+
 static inline int32_t
 find_previous_rule(struct rte_lpm *lpm, uint32_t ip, uint8_t depth, uint8_t *sub_rule_depth)
 {
index d35565d..840d871 100644 (file)
@@ -215,6 +215,25 @@ rte_lpm_free(struct rte_lpm *lpm);
 int
 rte_lpm_add(struct rte_lpm *lpm, uint32_t ip, uint8_t depth, uint8_t next_hop);
 
+/**
+ * Check if a rule is present in the LPM table,
+ * and provide its next hop if it is.
+ *
+ * @param lpm
+ *   LPM object handle
+ * @param ip
+ *   IP of the rule to be searched
+ * @param depth
+ *   Depth of the rule to searched
+ * @param next_hop
+ *   Next hop of the rule (valid only if it is found)
+ * @return
+ *   1 if the rule exists, 0 if it does not, a negative value on failure
+ */
+int
+rte_lpm_is_rule_present(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
+uint8_t *next_hop);
+
 /**
  * Delete a rule from the LPM table.
  *
index 56c74a1..32690cb 100644 (file)
@@ -663,6 +663,37 @@ rule_find(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth)
        return -ENOENT;
 }
 
+/*
+ * Look for a rule in the high-level rules table
+ */
+int
+rte_lpm6_is_rule_present(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
+uint8_t *next_hop)
+{
+       uint8_t ip_masked[RTE_LPM6_IPV6_ADDR_SIZE];
+       int32_t rule_index;
+
+       /* Check user arguments. */
+       if ((lpm == NULL) || next_hop == NULL || ip == NULL ||
+                       (depth < 1) || (depth > RTE_LPM6_MAX_DEPTH))
+               return -EINVAL;
+
+       /* Copy the IP and mask it to avoid modifying user's input data. */
+       memcpy(ip_masked, ip, RTE_LPM6_IPV6_ADDR_SIZE);
+       mask_ip(ip_masked, depth);
+
+       /* Look for the rule using rule_find. */
+       rule_index = rule_find(lpm, ip_masked, depth);
+
+       if (rule_index >= 0) {
+               *next_hop = lpm->rules_tbl[rule_index].next_hop;
+               return 1;
+       }
+
+       /* If rule is not found return 0. */
+       return 0;
+}
+
 /*
  * Delete a rule from the rule table.
  * NOTE: Valid range for depth parameter is 1 .. 128 inclusive.
index 856e540..4db810f 100644 (file)
@@ -124,6 +124,25 @@ int
 rte_lpm6_add(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
                uint8_t next_hop);
 
+/**
+ * Check if a rule is present in the LPM table,
+ * and provide its next hop if it is.
+ *
+ * @param lpm
+ *   LPM object handle
+ * @param ip
+ *   IP of the rule to be searched
+ * @param depth
+ *   Depth of the rule to searched
+ * @param next_hop
+ *   Next hop of the rule (valid only if it is found)
+ * @return
+ *   1 if the rule exists, 0 if it does not, a negative value on failure
+ */
+int
+rte_lpm6_is_rule_present(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
+uint8_t *next_hop);
+
 /**
  * Delete a rule from the LPM table.
  *