session: only notify server on ct connect failure
[vpp.git] / src / vnet / classify / vnet_classify.c
index 72ab33e..4fb4f33 100644 (file)
@@ -139,7 +139,7 @@ vnet_classify_new_table (vnet_classify_main_t *cm, const u8 *mask,
 
   pool_get_aligned_zero (cm->tables, t, CLIB_CACHE_LINE_BYTES);
 
-  vec_validate_aligned (t->mask, match_n_vectors - 1, sizeof (u32x4));
+  clib_memset_u32 (t->mask, 0, 4 * ARRAY_LEN (t->mask));
   clib_memcpy_fast (t->mask, mask, match_n_vectors * sizeof (u32x4));
 
   t->next_table_index = ~0;
@@ -148,6 +148,7 @@ vnet_classify_new_table (vnet_classify_main_t *cm, const u8 *mask,
   t->match_n_vectors = match_n_vectors;
   t->skip_n_vectors = skip_n_vectors;
   t->entries_per_page = 2;
+  t->load_mask = pow2_mask (match_n_vectors * 2);
 
   t->mheap = clib_mem_create_heap (0, memory_size, 1 /* locked */ ,
                                   "classify");
@@ -175,7 +176,6 @@ vnet_classify_delete_table_index (vnet_classify_main_t * cm,
     /* Recursively delete the entire chain */
     vnet_classify_delete_table_index (cm, t->next_table_index, del_chain);
 
-  vec_free (t->mask);
   vec_free (t->buckets);
   clib_mem_destroy_heap (t->mheap);
   pool_put (cm->tables, t);
@@ -911,7 +911,7 @@ unformat_l4_mask (unformat_input_t * input, va_list * args)
       else if (unformat (input, "dst_port"))
        dst_port = 0xFFFF;
       else
-       return 0;
+       break;
     }
 
   if (!src_port && !dst_port)
@@ -980,6 +980,7 @@ unformat_ip4_mask (unformat_input_t * input, va_list * args)
        break;
     }
 
+  found_something = version + hdr_length;
 #define _(a) found_something += a;
   foreach_ip4_proto_field;
 #undef _
@@ -1648,13 +1649,13 @@ filter_table_mask_compare (void *a1, void *a2)
   m1 = (u8 *) (t1->mask);
   m2 = (u8 *) (t2->mask);
 
-  for (i = 0; i < vec_len (t1->mask) * sizeof (u32x4); i++)
+  for (i = 0; i < t1->match_n_vectors * sizeof (u32x4); i++)
     {
       n1 += count_set_bits (m1[0]);
       m1++;
     }
 
-  for (i = 0; i < vec_len (t2->mask) * sizeof (u32x4); i++)
+  for (i = 0; i < t2->match_n_vectors * sizeof (u32x4); i++)
     {
       n2 += count_set_bits (m2[0]);
       m2++;
@@ -1814,11 +1815,11 @@ classify_lookup_chain (u32 table_index, u8 * mask, u32 n_skip, u32 n_match)
        continue;
 
       /* Masks aren't congruent, can't use this table. */
-      if (vec_len (t->mask) * sizeof (u32x4) != vec_len (mask))
+      if (t->match_n_vectors * sizeof (u32x4) != vec_len (mask))
        continue;
 
       /* Masks aren't bit-for-bit identical, can't use this table. */
-      if (memcmp (t->mask, mask, vec_len (mask)))
+      if (memcmp (t->mask, mask, t->match_n_vectors * sizeof (u32x4)))
        continue;
 
       /* Winner... */
@@ -1886,13 +1887,13 @@ classify_filter_command_fn (vlib_main_t * vm,
        break;
     }
 
-  if (is_add && mask == 0 && table_index == ~0)
+  if (is_add && mask == 0)
     err = clib_error_return (0, "Mask required");
 
-  else if (is_add && skip == ~0 && table_index == ~0)
+  else if (is_add && skip == ~0)
     err = clib_error_return (0, "skip count required");
 
-  else if (is_add && match == ~0 && table_index == ~0)
+  else if (is_add && match == ~0)
     err = clib_error_return (0, "match count required");
 
   else if (sw_if_index == ~0 && pkt_trace == 0 && pcap == 0)
@@ -1936,20 +1937,30 @@ classify_filter_command_fn (vlib_main_t * vm,
     table_index = classify_get_pcap_chain (cm, sw_if_index);
 
   if (table_index != ~0)
-    table_index = classify_lookup_chain (table_index, mask, skip, match);
+    {
+      /*
+       * look for a compatible table in the existing chain
+       *  - if a compatible table is found, table_index is updated with it
+       *  - if not, table_index is updated to ~0 (aka nil) and because of that
+       *    we are going to create one (see below). We save the original head
+       *    in next_table_index so we can chain it with the newly created
+       *    table
+       */
+      next_table_index = table_index;
+      table_index = classify_lookup_chain (table_index, mask, skip, match);
+    }
 
   /*
    * When no table is found, make one.
    */
   if (table_index == ~0)
     {
+      u32 new_head_index;
+
       /*
        * Matching table wasn't found, so create a new one at the
        * head of the next_table_index chain.
        */
-      next_table_index = table_index;
-      table_index = ~0;
-
       rv = vnet_classify_add_del_table (cm, mask, nbuckets, memory_size,
                                        skip, match, next_table_index,
                                        miss_next_index, &table_index,
@@ -1968,16 +1979,16 @@ classify_filter_command_fn (vlib_main_t * vm,
       /*
        * Reorder tables such that masks are most-specify to least-specific.
        */
-      table_index = classify_sort_table_chain (cm, table_index);
+      new_head_index = classify_sort_table_chain (cm, table_index);
 
       /*
        * Put first classifier table in chain in a place where
        * other data structures expect to find and use it.
        */
       if (pkt_trace)
-       classify_set_trace_chain (cm, table_index);
+       classify_set_trace_chain (cm, new_head_index);
       else
-       classify_set_pcap_chain (cm, sw_if_index, table_index);
+       classify_set_pcap_chain (cm, sw_if_index, new_head_index);
     }
 
   vec_free (mask);
@@ -2032,7 +2043,7 @@ vlib_enable_disable_pkt_trace_filter (int enable)
  * It's reasonably likely that folks will configure a single
  * table with one or two matches. As a result, we configure
  * 8 hash buckets and 128K of match rule space. One can override
- * the defaults by specifiying "buckets <nnn>" and "memory-size <xxx>"
+ * the defaults by specifying "buckets <nnn>" and "memory-size <xxx>"
  * as desired.
  *
  * To build up complex filter chains, repeatedly issue the
@@ -2068,16 +2079,18 @@ vlib_enable_disable_pkt_trace_filter (int enable)
  *
  * Configure a simple classify filter, and configure pcap rx trace to use it:
  *
- * <b><em>classify filter rx mask l3 ip4 src match l3 ip4 src 192.168.1.11"</em></b><br>
+ * @cliexcmd{classify filter rx mask l3 ip4 src match l3 ip4 src 192.168.1.11}
  * <b><em>pcap rx trace on max 100 filter</em></b>
  *
  * Configure another fairly simple filter
  *
- * <b><em>classify filter mask l3 ip4 src dst match l3 ip4 src 192.168.1.10 dst 192.168.2.10"</em></b>
+ * @cliexcmd{classify filter mask l3 ip4 src dst match l3 ip4 src 192.168.1.10
+ * dst 192.168.2.10}
  *
  *
  * Configure a filter for use with the vpp packet tracer:
- * <b><em>classify filter trace mask l3 ip4 src dst match l3 ip4 src 192.168.1.10 dst 192.168.2.10"</em></b>
+ * @cliexcmd{classify filter trace mask l3 ip4 src dst match l3 ip4 src
+ * 192.168.1.10 dst 192.168.2.10}
  * <b><em>trace add dpdk-input 100 filter</em></b>
  *
  * Clear classifier filters
@@ -2085,7 +2098,7 @@ vlib_enable_disable_pkt_trace_filter (int enable)
  * <b><em>classify filter [trace | rx | tx  | <intfc>] del</em></b>
  *
  * To display the top-level classifier tables for each use case:
- * <b><em>show classify filter</em/></b>
+ * <b><em>show classify filter</em></b>
  *
  * To inspect the classifier tables, use
  *
@@ -2202,7 +2215,7 @@ format_vnet_classify_table (u8 *s, va_list *args)
 
   if (index == ~0)
     {
-      s = format (s, "%10s%10s%10s%10s", "TableIdx", "Sessions", "NextTbl",
+      s = format (s, "\n%10s%10s%10s%10s", "TableIdx", "Sessions", "NextTbl",
                  "NextNode", verbose ? "Details" : "");
       return s;
     }
@@ -2263,11 +2276,13 @@ show_classify_tables_command_fn (vlib_main_t * vm,
 
   if (vec_len (indices))
     {
-      vlib_cli_output (vm, "%U", format_vnet_classify_table, cm, verbose,
-                      ~0 /* hdr */ );
       for (i = 0; i < vec_len (indices); i++)
-       vlib_cli_output (vm, "%U", format_vnet_classify_table, cm,
-                        verbose, indices[i]);
+       {
+         vlib_cli_output (vm, "%U", format_vnet_classify_table, cm, verbose,
+                          ~0 /* hdr */);
+         vlib_cli_output (vm, "%U", format_vnet_classify_table, cm, verbose,
+                          indices[i]);
+       }
     }
   else
     vlib_cli_output (vm, "No classifier tables configured");
@@ -2303,7 +2318,7 @@ unformat_l4_match (unformat_input_t * input, va_list * args)
       else if (unformat (input, "dst_port %d", &dst_port))
        ;
       else
-       return 0;
+       break;
     }
 
   h.src_port = clib_host_to_net_u16 (src_port);