X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Figmp%2Figmp_input.c;h=1858a1b4d66d57ce20d0270b05f07f1580c6e88d;hb=61717cc38;hp=83e11ec6cc597d48a78ce990d0bf5ad1a6dfd5d7;hpb=178cf493d009995b28fdf220f04c98860ff79a9b;p=vpp.git diff --git a/src/plugins/igmp/igmp_input.c b/src/plugins/igmp/igmp_input.c index 83e11ec6cc5..1858a1b4d66 100644 --- a/src/plugins/igmp/igmp_input.c +++ b/src/plugins/igmp/igmp_input.c @@ -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