X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Figmp%2Figmp_input.c;h=83e11ec6cc597d48a78ce990d0bf5ad1a6dfd5d7;hb=178cf493d009995b28fdf220f04c98860ff79a9b;hp=d4563bf366d6b29b74a74d20ff0f4125f4e41cf9;hpb=947ea6222dad1ef04595c34273e9231395aef443;p=vpp.git diff --git a/src/plugins/igmp/igmp_input.c b/src/plugins/igmp/igmp_input.c index d4563bf366d..83e11ec6cc5 100644 --- a/src/plugins/igmp/igmp_input.c +++ b/src/plugins/igmp/igmp_input.c @@ -203,8 +203,8 @@ 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]; - clib_memcpy (tr->packet_data, vlib_buffer_get_current (b), - sizeof (tr->packet_data)); + clib_memcpy_fast (tr->packet_data, vlib_buffer_get_current (b), + sizeof (tr->packet_data)); } vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, @@ -259,8 +259,8 @@ igmp_parse_query (vlib_main_t * vm, vlib_node_runtime_t * node, { igmp_membership_query_v3_t *igmp; igmp_query_args_t *args; + u32 bi, next, len; vlib_buffer_t *b; - u32 bi, next; next = IGMP_PARSE_QUERY_NEXT_DROP; bi = from[0]; @@ -280,23 +280,32 @@ 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]; - clib_memcpy (tr->packet_data, vlib_buffer_get_current (b), - sizeof (tr->packet_data)); + clib_memcpy_fast (tr->packet_data, vlib_buffer_get_current (b), + sizeof (tr->packet_data)); } + len = igmp_membership_query_v3_length (igmp); /* - * copy the contents of the query, and the interface, over - * to the main thread for processing + * 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) + { + /* + * copy the contents of the query, and the interface, over + * to the main thread for processing + */ + vlib_buffer_advance (b, -sizeof (u32)); + args = vlib_buffer_get_current (b); + args->sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX]; + + 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 */ - vlib_buffer_advance (b, -sizeof (u32)); - args = vlib_buffer_get_current (b); - args->sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX]; - - vl_api_rpc_call_main_thread (igmp_handle_query, - (u8 *) args, - sizeof (*args) + - igmp_membership_query_v3_length - (igmp)); vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, n_left_to_next, bi, next); @@ -351,7 +360,7 @@ igmp_parse_report (vlib_main_t * vm, vlib_node_runtime_t * node, { igmp_membership_report_v3_t *igmp; igmp_report_args_t *args; - u32 bi, next; + u32 bi, next, len; vlib_buffer_t *b; next = IGMP_PARSE_REPORT_NEXT_DROP; @@ -368,6 +377,7 @@ igmp_parse_report (vlib_main_t * vm, vlib_node_runtime_t * node, error = IGMP_ERROR_NONE; b->error = error_node->errors[error]; igmp = vlib_buffer_get_current (b); + len = igmp_membership_report_v3_length (igmp); ASSERT (igmp->header.type == IGMP_TYPE_membership_report_v3); @@ -377,24 +387,32 @@ igmp_parse_report (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]; - clib_memcpy (tr->packet_data, vlib_buffer_get_current (b), - sizeof (tr->packet_data)); + clib_memcpy_fast (tr->packet_data, vlib_buffer_get_current (b), + sizeof (tr->packet_data)); } /* - * copy the contents of the query, and the interface, over - * to the main thread for processing + * 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) + { + /* + * copy the contents of the query, and the interface, over + * to the main thread for processing + */ + vlib_buffer_advance (b, -sizeof (u32)); + args = vlib_buffer_get_current (b); + args->sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX]; + + 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 */ - vlib_buffer_advance (b, -sizeof (u32)); - args = vlib_buffer_get_current (b); - args->sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX]; - - vl_api_rpc_call_main_thread (igmp_handle_report, - (u8 *) args, - sizeof (*args) + - igmp_membership_report_v3_length - (igmp)); - vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, n_left_to_next, bi, next); }