bonding: coverity woe in bond_dev_class fuction
[vpp.git] / src / vnet / bonding / device.c
index 38759ee..c69d5a4 100644 (file)
 #include <vppinfra/lb_hash_hash.h>
 #include <vnet/ip/ip.h>
 #include <vnet/ip-neighbor/ip_neighbor.h>
+#include <vnet/ip-neighbor/ip4_neighbor.h>
+#include <vnet/ip-neighbor/ip6_neighbor.h>
 
-#define foreach_bond_tx_error     \
-  _(NONE, "no error")             \
-  _(IF_DOWN, "interface down")    \
-  _(NO_MEMBER, "no member")
+#define foreach_bond_tx_error                                                 \
+  _ (NONE, "no error")                                                        \
+  _ (IF_DOWN, "interface down")                                               \
+  _ (BAD_LB_MODE, "bad load balance mode")                                    \
+  _ (NO_MEMBER, "no member")
 
 typedef enum
 {
@@ -132,7 +135,7 @@ bond_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags)
   bond_if_t *bif = pool_elt_at_index (bm->interfaces, hif->dev_instance);
 
   bif->admin_up = is_up;
-  if (is_up && vec_len (bif->active_members))
+  if (is_up)
     vnet_hw_interface_set_flags (vnm, bif->hw_if_index,
                                 VNET_HW_INTERFACE_FLAG_LINK_UP);
   return 0;
@@ -651,25 +654,28 @@ bond_tx_trace (vlib_main_t * vm, vlib_node_runtime_t * node, bond_if_t * bif,
 
   while (n_trace > 0 && n_left > 0)
     {
-      bond_packet_trace_t *t0;
-      ethernet_header_t *eth;
-      u32 next0 = 0;
-
-      vlib_trace_buffer (vm, node, next0, b[0], 0 /* follow_chain */ );
-      vlib_set_trace_count (vm, node, --n_trace);
-      t0 = vlib_add_trace (vm, node, b[0], sizeof (*t0));
-      eth = vlib_buffer_get_current (b[0]);
-      t0->ethernet = *eth;
-      t0->sw_if_index = vnet_buffer (b[0])->sw_if_index[VLIB_TX];
-      if (!h)
+      if (PREDICT_TRUE
+         (vlib_trace_buffer (vm, node, 0, b[0], 0 /* follow_chain */ )))
        {
-         t0->bond_sw_if_index = *vec_elt_at_index (bif->active_members, 0);
-       }
-      else
-       {
-         t0->bond_sw_if_index =
-           *vec_elt_at_index (bif->active_members, h[0]);
-         h++;
+         bond_packet_trace_t *t0;
+         ethernet_header_t *eth;
+
+         vlib_set_trace_count (vm, node, --n_trace);
+         t0 = vlib_add_trace (vm, node, b[0], sizeof (*t0));
+         eth = vlib_buffer_get_current (b[0]);
+         t0->ethernet = *eth;
+         t0->sw_if_index = vnet_buffer (b[0])->sw_if_index[VLIB_TX];
+         if (!h)
+           {
+             t0->bond_sw_if_index =
+               *vec_elt_at_index (bif->active_members, 0);
+           }
+         else
+           {
+             t0->bond_sw_if_index =
+               *vec_elt_at_index (bif->active_members, h[0]);
+             h++;
+           }
        }
       b++;
       n_left--;
@@ -757,7 +763,15 @@ VNET_DEVICE_CLASS_TX_FN (bond_dev_class) (vlib_main_t * vm,
   else if (bif->lb == BOND_LB_RR)
     bond_tx_inline (vm, bif, bufs, hashes, n_left, n_members, BOND_LB_RR);
   else
-    ASSERT (0);
+    {
+      vlib_buffer_free (vm, vlib_frame_vector_args (frame), frame->n_vectors);
+      vlib_increment_simple_counter (
+       vnet_main.interface_main.sw_if_counters + VNET_INTERFACE_COUNTER_DROP,
+       thread_index, bif->sw_if_index, frame->n_vectors);
+      vlib_error_count (vm, node->node_index, BOND_TX_ERROR_BAD_LB_MODE,
+                       frame->n_vectors);
+      return frame->n_vectors;
+    }
 
   /* calculate port out of hash */
   h = hashes;
@@ -798,7 +812,8 @@ bond_active_interface_switch_cb (vnet_main_t * vnm, u32 sw_if_index,
 {
   bond_main_t *bm = &bond_main;
 
-  ip_neighbor_advertise (bm->vlib_main, IP46_TYPE_BOTH, NULL, sw_if_index);
+  ip4_neighbor_advertise (bm->vlib_main, bm->vnet_main, sw_if_index, NULL);
+  ip6_neighbor_advertise (bm->vlib_main, bm->vnet_main, sw_if_index, NULL);
 
   return (WALK_CONTINUE);
 }