ikev2: add support for custom ipsec-over-udp port
[vpp.git] / src / plugins / igmp / igmp_input.c
index 83e11ec..1858a1b 100644 (file)
@@ -61,7 +61,7 @@ typedef struct
 {
   u32 next_index;
   u32 sw_if_index;
-
+  u32 len;
   u8 packet_data[64];
 } igmp_input_trace_t;
 
@@ -100,10 +100,12 @@ format_igmp_parse_query_trace (u8 * s, va_list * va)
   CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
   igmp_input_trace_t *t = va_arg (*va, igmp_input_trace_t *);
 
-  s = format (s, "sw_if_index %u next-input %u",
-             t->sw_if_index, t->next_index);
+  s = format (s, "sw_if_index %u next-input %u len %u",
+             t->sw_if_index, t->next_index, t->len);
   s = format (s, "\n%U", format_igmp_query_v3, t->packet_data,
              sizeof (t->packet_data));
+  s = format (s, "\n%U", format_hex_bytes,
+             t->packet_data, sizeof (t->packet_data));
   return s;
 }
 
@@ -203,6 +205,7 @@ igmp_input (vlib_main_t * vm, vlib_node_runtime_t * node,
              tr = vlib_add_trace (vm, node, b, sizeof (*tr));
              tr->next_index = next;
              tr->sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];
+             tr->len = vlib_buffer_length_in_chain (vm, b);
              clib_memcpy_fast (tr->packet_data, vlib_buffer_get_current (b),
                                sizeof (tr->packet_data));
            }
@@ -273,6 +276,7 @@ igmp_parse_query (vlib_main_t * vm, vlib_node_runtime_t * node,
          b = vlib_get_buffer (vm, bi);
          igmp = vlib_buffer_get_current (b);
          ASSERT (igmp->header.type == IGMP_TYPE_membership_query);
+         len = igmp_membership_query_v3_length (igmp);
 
          if (node->flags & VLIB_NODE_FLAG_TRACE)
            {
@@ -280,16 +284,17 @@ igmp_parse_query (vlib_main_t * vm, vlib_node_runtime_t * node,
              tr = vlib_add_trace (vm, node, b, sizeof (*tr));
              tr->next_index = next;
              tr->sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];
+             tr->len = len;
              clib_memcpy_fast (tr->packet_data, vlib_buffer_get_current (b),
                                sizeof (tr->packet_data));
            }
-         len = igmp_membership_query_v3_length (igmp);
 
          /*
-          * validate that the length on the packet on the wire
-          * corresponds to the length on the calculated v3 query
+          * validate that the length on the packet on the wire  corresponds
+          * to at least the length of the calculated v3 query.
+          * If there's extra, then it will be ignored.
           */
-         if (vlib_buffer_length_in_chain (vm, b) == len)
+         if (vlib_buffer_length_in_chain (vm, b) >= len)
            {
              /*
               * copy the contents of the query, and the interface, over
@@ -302,10 +307,14 @@ igmp_parse_query (vlib_main_t * vm, vlib_node_runtime_t * node,
              vl_api_rpc_call_main_thread (igmp_handle_query,
                                           (u8 *) args, sizeof (*args) + len);
            }
-         /*
-          * else a packet that is reporting more or less sources
-          * than it really has, bin it
-          */
+         else
+           {
+             /*
+              * else a packet that is reporting more sources than it really
+              * has; bin it
+              */
+             b->error = node->errors[IGMP_ERROR_BAD_LENGTH];
+           }
 
          vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
                                           n_left_to_next, bi, next);
@@ -386,6 +395,7 @@ igmp_parse_report (vlib_main_t * vm, vlib_node_runtime_t * node,
              igmp_input_trace_t *tr;
              tr = vlib_add_trace (vm, node, b, sizeof (*tr));
              tr->next_index = next;
+             tr->len = len;
              tr->sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];
              clib_memcpy_fast (tr->packet_data, vlib_buffer_get_current (b),
                                sizeof (tr->packet_data));
@@ -395,7 +405,7 @@ igmp_parse_report (vlib_main_t * vm, vlib_node_runtime_t * node,
           * validate that the length on the packet on the wire
           * corresponds to the length on the calculated v3 query
           */
-         if (vlib_buffer_length_in_chain (vm, b) == len)
+         if (vlib_buffer_length_in_chain (vm, b) >= len)
            {
              /*
               * copy the contents of the query, and the interface, over
@@ -408,11 +418,15 @@ igmp_parse_report (vlib_main_t * vm, vlib_node_runtime_t * node,
              vl_api_rpc_call_main_thread (igmp_handle_report,
                                           (u8 *) args, sizeof (*args) + len);
            }
-         /*
-          * else
-          *   this is a packet with more groups/sources than the
-          *   header reports. bin it
-          */
+         else
+           {
+             /*
+              * this is a packet with more groups/sources than the
+              * header reports. bin it
+              */
+             b->error = node->errors[IGMP_ERROR_BAD_LENGTH];
+           }
+
          vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
                                           n_left_to_next, bi, next);
        }
@@ -445,19 +459,19 @@ VLIB_REGISTER_NODE (igmp_parse_report_node) =
 static clib_error_t *
 igmp_input_init (vlib_main_t * vm)
 {
-  clib_error_t *error;
-
-  if ((error = vlib_call_init_function (vm, igmp_init)))
-    return error;
-
   ip4_register_protocol (IP_PROTOCOL_IGMP, igmp_input_node.index);
 
   IGMP_DBG ("input-initialized");
 
-  return (error);
+  return (0);
 }
 
-VLIB_INIT_FUNCTION (igmp_input_init);
+/* *INDENT-OFF* */
+VLIB_INIT_FUNCTION (igmp_input_init) =
+{
+  .runs_after = VLIB_INITS("igmp_init"),
+};
+/* *INDENT-ON* */
 
 /*
  * fd.io coding-style-patch-verification: ON