ipsec: remove WITH_LIBSSL macros
[vpp.git] / src / vnet / l2 / l2_learn.c
index c6ecef3..3b9b1db 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <vlib/vlib.h>
 #include <vnet/vnet.h>
-#include <vnet/pg/pg.h>
 #include <vnet/ethernet/ethernet.h>
 #include <vlib/cli.h>
 
@@ -74,7 +73,7 @@ format_l2learn_trace (u8 * s, va_list * args)
   return s;
 }
 
-static vlib_node_registration_t l2learn_node;
+extern vlib_node_registration_t l2learn_node;
 
 #define foreach_l2learn_error                          \
 _(L2LEARN,           "L2 learn packets")               \
@@ -120,6 +119,8 @@ l2learn_process (vlib_node_runtime_t * node,
                 u32 * count,
                 l2fib_entry_result_t * result0, u16 * next0, u8 timestamp)
 {
+  l2_bridge_domain_t *bd_config =
+    vec_elt_at_index (l2input_main.bd_configs, vnet_buffer (b0)->l2.bd_index);
   /* Set up the default next node (typically L2FWD) */
   *next0 = vnet_l2_feature_next (b0, msm->feat_next_node_index,
                                 L2INPUT_FEAT_LEARN);
@@ -129,7 +130,7 @@ l2learn_process (vlib_node_runtime_t * node,
     {
       /* Entry in L2FIB with matching sw_if_index matched - normal fast path */
       u32 dtime = timestamp - result0->fields.timestamp;
-      u32 dsn = result0->fields.sn.as_u16 - vnet_buffer (b0)->l2.l2fib_sn;
+      u32 dsn = (result0->fields.sn - vnet_buffer (b0)->l2.l2fib_sn);
       u32 check = (dtime && vnet_buffer (b0)->l2.bd_age) || dsn;
 
       if (PREDICT_TRUE (check == 0))
@@ -138,6 +139,8 @@ l2learn_process (vlib_node_runtime_t * node,
        return;                 /* Static MAC always age_not */
       if (msm->global_learn_count > msm->global_learn_limit)
        return;                 /* Above learn limit - do not update */
+      if (bd_config->learn_count > bd_config->learn_limit)
+       return; /* Above bridge domain learn limit - do not update */
 
       /* Limit updates per l2-learn node call to avoid prolonged update burst
        * as dtime advance over 1 minute mark, unless more than 1 min behind
@@ -153,7 +156,8 @@ l2learn_process (vlib_node_runtime_t * node,
       /* Entry not in L2FIB - add it  */
       counter_base[L2LEARN_ERROR_MISS] += 1;
 
-      if (msm->global_learn_count >= msm->global_learn_limit)
+      if ((msm->global_learn_count >= msm->global_learn_limit) ||
+         (bd_config->learn_count >= bd_config->learn_limit))
        {
          /*
           * Global limit reached. Do not learn the mac but forward the packet.
@@ -170,7 +174,11 @@ l2learn_process (vlib_node_runtime_t * node,
        return;
 
       /* It is ok to learn */
+      /* learn_count variable may have little inaccuracy because they are not
+       * incremented/decremented with atomic operations */
+      /* l2fib_scan is call every 2sec fixing potential inaccuracy */
       msm->global_learn_count++;
+      bd_config->learn_count++;
       result0->raw = 0;                /* clear all fields */
       result0->fields.sw_if_index = sw_if_index0;
       if (msm->client_pid != 0)
@@ -209,7 +217,12 @@ l2learn_process (vlib_node_runtime_t * node,
       if (l2fib_entry_result_is_set_AGE_NOT (result0))
        {
          /* The mac was provisioned */
+         /* learn_count variable may have little inaccuracy because they are
+          * not incremented/decremented with atomic operations */
+         /* l2fib_scan is call every 2sec fixing potential inaccuracy */
          msm->global_learn_count++;
+         bd_config->learn_count++;
+
          l2fib_entry_result_clear_AGE_NOT (result0);
        }
       if (msm->client_pid != 0)
@@ -225,7 +238,7 @@ l2learn_process (vlib_node_runtime_t * node,
 
   /* Update the entry */
   result0->fields.timestamp = timestamp;
-  result0->fields.sn.as_u16 = vnet_buffer (b0)->l2.l2fib_sn;
+  result0->fields.sn = vnet_buffer (b0)->l2.l2fib_sn;
 
   BVT (clib_bihash_kv) kv;
   kv.key = key0->raw;
@@ -306,8 +319,8 @@ l2learn_node_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
                vlib_add_trace (vm, node, b[0], sizeof (*t));
              t->sw_if_index = sw_if_index0;
              t->bd_index = vnet_buffer (b[0])->l2.bd_index;
-             clib_memcpy (t->src, h0->src_address, 6);
-             clib_memcpy (t->dst, h0->dst_address, 6);
+             clib_memcpy_fast (t->src, h0->src_address, 6);
+             clib_memcpy_fast (t->dst, h0->dst_address, 6);
            }
          if (b[1]->flags & VLIB_BUFFER_IS_TRACED)
            {
@@ -315,8 +328,8 @@ l2learn_node_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
                vlib_add_trace (vm, node, b[1], sizeof (*t));
              t->sw_if_index = sw_if_index1;
              t->bd_index = vnet_buffer (b[1])->l2.bd_index;
-             clib_memcpy (t->src, h1->src_address, 6);
-             clib_memcpy (t->dst, h1->dst_address, 6);
+             clib_memcpy_fast (t->src, h1->src_address, 6);
+             clib_memcpy_fast (t->dst, h1->dst_address, 6);
            }
          if (b[2]->flags & VLIB_BUFFER_IS_TRACED)
            {
@@ -324,8 +337,8 @@ l2learn_node_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
                vlib_add_trace (vm, node, b[2], sizeof (*t));
              t->sw_if_index = sw_if_index2;
              t->bd_index = vnet_buffer (b[2])->l2.bd_index;
-             clib_memcpy (t->src, h2->src_address, 6);
-             clib_memcpy (t->dst, h2->dst_address, 6);
+             clib_memcpy_fast (t->src, h2->src_address, 6);
+             clib_memcpy_fast (t->dst, h2->dst_address, 6);
            }
          if (b[3]->flags & VLIB_BUFFER_IS_TRACED)
            {
@@ -333,8 +346,8 @@ l2learn_node_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
                vlib_add_trace (vm, node, b[3], sizeof (*t));
              t->sw_if_index = sw_if_index3;
              t->bd_index = vnet_buffer (b[3])->l2.bd_index;
-             clib_memcpy (t->src, h3->src_address, 6);
-             clib_memcpy (t->dst, h3->dst_address, 6);
+             clib_memcpy_fast (t->src, h3->src_address, 6);
+             clib_memcpy_fast (t->dst, h3->dst_address, 6);
            }
        }
 
@@ -391,8 +404,8 @@ l2learn_node_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
          l2learn_trace_t *t = vlib_add_trace (vm, node, b[0], sizeof (*t));
          t->sw_if_index = sw_if_index0;
          t->bd_index = vnet_buffer (b[0])->l2.bd_index;
-         clib_memcpy (t->src, h0->src_address, 6);
-         clib_memcpy (t->dst, h0->dst_address, 6);
+         clib_memcpy_fast (t->src, h0->src_address, 6);
+         clib_memcpy_fast (t->dst, h0->dst_address, 6);
        }
 
       /* process 1 pkt */
@@ -427,7 +440,7 @@ VLIB_NODE_FN (l2learn_node) (vlib_main_t * vm,
 }
 
 /* *INDENT-OFF* */
-VLIB_REGISTER_NODE (l2learn_node,static) = {
+VLIB_REGISTER_NODE (l2learn_node) = {
   .name = "l2-learn",
   .vector_size = sizeof (u32),
   .format_trace = format_l2learn_trace,
@@ -471,6 +484,11 @@ l2learn_init (vlib_main_t * vm)
    */
   mp->global_learn_limit = L2LEARN_DEFAULT_LIMIT;
 
+  /*
+   * Set the default number of dynamically learned macs to the number
+   * of buckets.
+   */
+  mp->bd_default_learn_limit = L2LEARN_DEFAULT_LIMIT;
   return 0;
 }