X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fip%2Fip4_forward.c;h=daffae410cc397b3ade0855e2e1a5018d9679712;hb=d91c1dbdb31f80db7d967f2f57c43d0a81d65297;hp=2d48e8a9ab5af3f37f4065df002558caf4de942e;hpb=20a14b9eac8f588356dfb7936100c2ca39171889;p=vpp.git diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c index 2d48e8a9ab5..daffae410cc 100755 --- a/src/vnet/ip/ip4_forward.c +++ b/src/vnet/ip/ip4_forward.c @@ -60,12 +60,6 @@ * This file contains the source code for IPv4 forwarding. */ -void -ip4_forward_next_trace (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame, - vlib_rx_or_tx_t which_adj_index); - always_inline uword ip4_lookup_inline (vlib_main_t * vm, vlib_node_runtime_t * node, @@ -1198,8 +1192,10 @@ ip4_lookup_init (vlib_main_t * vm) ip_lookup_init (&im->lookup_main, /* is_ip6 */ 0); /* Create FIB with index 0 and table id of 0. */ - fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, 0); - mfib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, 0); + fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, 0, + FIB_SOURCE_DEFAULT_ROUTE); + mfib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, 0, + MFIB_SOURCE_DEFAULT_ROUTE); { pg_node_t *pn; @@ -1256,7 +1252,7 @@ format_ip4_forward_next_trace (u8 * s, va_list * args) CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); ip4_forward_next_trace_t *t = va_arg (*args, ip4_forward_next_trace_t *); - uword indent = format_get_indent (s); + u32 indent = format_get_indent (s); s = format (s, "%U%U", format_white_space, indent, format_ip4_header, t->packet_data, sizeof (t->packet_data)); @@ -1269,7 +1265,7 @@ format_ip4_lookup_trace (u8 * s, va_list * args) CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); ip4_forward_next_trace_t *t = va_arg (*args, ip4_forward_next_trace_t *); - uword indent = format_get_indent (s); + u32 indent = format_get_indent (s); s = format (s, "fib %d dpo-idx %d flow hash: 0x%08x", t->fib_index, t->dpo_index, t->flow_hash); @@ -1285,7 +1281,7 @@ format_ip4_rewrite_trace (u8 * s, va_list * args) CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); ip4_forward_next_trace_t *t = va_arg (*args, ip4_forward_next_trace_t *); - uword indent = format_get_indent (s); + u32 indent = format_get_indent (s); s = format (s, "tx_sw_if_index %d dpo-idx %d : %U flow hash: 0x%08x", t->fib_index, t->dpo_index, format_ip_adjacency, @@ -1385,68 +1381,6 @@ ip4_forward_next_trace (vlib_main_t * vm, } } -static uword -ip4_drop_or_punt (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame, ip4_error_t error_code) -{ - u32 *buffers = vlib_frame_vector_args (frame); - uword n_packets = frame->n_vectors; - - vlib_error_drop_buffers (vm, node, buffers, - /* stride */ 1, - n_packets, - /* next */ 0, - ip4_input_node.index, error_code); - - if (node->flags & VLIB_NODE_FLAG_TRACE) - ip4_forward_next_trace (vm, node, frame, VLIB_TX); - - return n_packets; -} - -static uword -ip4_drop (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) -{ - return ip4_drop_or_punt (vm, node, frame, IP4_ERROR_ADJACENCY_DROP); -} - -static uword -ip4_punt (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) -{ - return ip4_drop_or_punt (vm, node, frame, IP4_ERROR_ADJACENCY_PUNT); -} - -/* *INDENT-OFF* */ -VLIB_REGISTER_NODE (ip4_drop_node, static) = -{ - .function = ip4_drop, - .name = "ip4-drop", - .vector_size = sizeof (u32), - .format_trace = format_ip4_forward_next_trace, - .n_next_nodes = 1, - .next_nodes = { - [0] = "error-drop", - }, -}; - -VLIB_NODE_FUNCTION_MULTIARCH (ip4_drop_node, ip4_drop); - -VLIB_REGISTER_NODE (ip4_punt_node, static) = -{ - .function = ip4_punt, - .name = "ip4-punt", - .vector_size = sizeof (u32), - .format_trace = format_ip4_forward_next_trace, - .n_next_nodes = 1, - .next_nodes = { - [0] = "error-punt", - }, -}; - -VLIB_NODE_FUNCTION_MULTIARCH (ip4_punt_node, ip4_punt); -/* *INDENT-ON */ - /* Compute TCP/UDP/ICMP4 checksum in software. */ u16 ip4_tcp_udp_compute_checksum (vlib_main_t * vm, vlib_buffer_t * p0, @@ -1481,11 +1415,12 @@ ip4_tcp_udp_compute_checksum (vlib_main_t * vm, vlib_buffer_t * p0, n_bytes_left = n_this_buffer = payload_length_host_byte_order; data_this_buffer = (void *) ip0 + ip_header_length; - n_ip_bytes_this_buffer = p0->current_length - (((u8 *) ip0 - p0->data) - p0->current_data); + n_ip_bytes_this_buffer = + p0->current_length - (((u8 *) ip0 - p0->data) - p0->current_data); if (n_this_buffer + ip_header_length > n_ip_bytes_this_buffer) { n_this_buffer = n_ip_bytes_this_buffer > ip_header_length ? - n_ip_bytes_this_buffer - ip_header_length : 0; + n_ip_bytes_this_buffer - ip_header_length : 0; } while (1) { @@ -1708,6 +1643,9 @@ ip4_local_inline (vlib_main_t * vm, * - uRPF check for any route to source - accept if passes. * - allow packets destined to the broadcast address from unknown sources */ + if (p0->flags & VNET_BUFFER_F_IS_NATED) + goto skip_check0; + error0 = ((error0 == IP4_ERROR_UNKNOWN_PROTOCOL && dpo0->dpoi_type == DPO_RECEIVE) ? IP4_ERROR_SPOOFED_LOCAL_PACKETS : error0); @@ -1715,6 +1653,11 @@ ip4_local_inline (vlib_main_t * vm, !fib_urpf_check_size (lb0->lb_urpf) && ip0->dst_address.as_u32 != 0xFFFFFFFF) ? IP4_ERROR_SRC_LOOKUP_MISS : error0); + + skip_check0: + if (p1->flags & VNET_BUFFER_F_IS_NATED) + goto skip_checks; + error1 = ((error1 == IP4_ERROR_UNKNOWN_PROTOCOL && dpo1->dpoi_type == DPO_RECEIVE) ? IP4_ERROR_SPOOFED_LOCAL_PACKETS : error1); @@ -1779,7 +1722,7 @@ ip4_local_inline (vlib_main_t * vm, until support of IP frag reassembly is implemented */ proto0 = ip4_is_fragment (ip0) ? 0xfe : ip0->protocol; - if (head_of_feature_arc == 0) + if (head_of_feature_arc == 0 || p0->flags & VNET_BUFFER_F_IS_NATED) goto skip_check; is_udp0 = proto0 == IP_PROTOCOL_UDP; @@ -1860,8 +1803,8 @@ VLIB_REGISTER_NODE (ip4_local_node) = .n_next_nodes = IP_LOCAL_N_NEXT, .next_nodes = { - [IP_LOCAL_NEXT_DROP] = "error-drop", - [IP_LOCAL_NEXT_PUNT] = "error-punt", + [IP_LOCAL_NEXT_DROP] = "ip4-drop", + [IP_LOCAL_NEXT_PUNT] = "ip4-punt", [IP_LOCAL_NEXT_UDP_LOOKUP] = "ip4-udp-lookup", [IP_LOCAL_NEXT_ICMP] = "ip4-icmp-input", }, @@ -1920,7 +1863,13 @@ show_ip_local_command_fn (vlib_main_t * vm, for (i = 0; i < ARRAY_LEN (lm->local_next_by_ip_protocol); i++) { if (lm->local_next_by_ip_protocol[i] != IP_LOCAL_NEXT_PUNT) - vlib_cli_output (vm, "%d", i); + { + u32 node_index = vlib_get_node (vm, + ip4_local_node.index)-> + next_nodes[lm->local_next_by_ip_protocol[i]]; + vlib_cli_output (vm, "%d: %U", i, format_vlib_node_name, vm, + node_index); + } } return 0; } @@ -2030,11 +1979,12 @@ ip4_arp_inline (vlib_main_t * vm, } b0 ^= sw_if_index0; + hash_v3_mix32 (a0, b0, c0); hash_v3_finalize32 (a0, b0, c0); c0 &= BITS (hash_bitmap) - 1; - c0 = c0 / BITS (uword); m0 = (uword) 1 << (c0 % BITS (uword)); + c0 = c0 / BITS (uword); bm0 = hash_bitmap[c0]; drop0 = (bm0 & m0) != 0; @@ -2128,6 +2078,7 @@ ip4_arp_inline (vlib_main_t * vm, vlib_buffer_copy_trace_flag (vm, p0, bi0); b0 = vlib_get_buffer (vm, bi0); + VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); vnet_buffer (b0)->sw_if_index[VLIB_TX] = sw_if_index0; vlib_buffer_advance (b0, -adj0->rewrite_header.data_bytes); @@ -2247,14 +2198,6 @@ ip4_probe_neighbor (vlib_main_t * vm, ip4_address_t * dst, u32 sw_if_index) sw_if_index); } - ip46_address_t nh = { - .ip4 = *dst, - }; - - ai = adj_nbr_add_or_lock (FIB_PROTOCOL_IP4, - VNET_LINK_IP4, &nh, sw_if_index); - adj = adj_get (ai); - h = vlib_packet_template_get_packet (vm, &im->ip4_arp_request_packet_template, &bi); @@ -2278,6 +2221,22 @@ ip4_probe_neighbor (vlib_main_t * vm, ip4_address_t * dst, u32 sw_if_index) vnet_buffer (b)->sw_if_index[VLIB_RX] = vnet_buffer (b)->sw_if_index[VLIB_TX] = sw_if_index; + ip46_address_t nh = { + .ip4 = *dst, + }; + + ai = adj_nbr_add_or_lock (FIB_PROTOCOL_IP4, + VNET_LINK_IP4, &nh, sw_if_index); + adj = adj_get (ai); + + /* Peer has been previously resolved, retrieve glean adj instead */ + if (adj->lookup_next_index == IP_LOOKUP_NEXT_REWRITE) + { + adj_unlock (ai); + ai = adj_glean_add_or_lock (FIB_PROTOCOL_IP4, sw_if_index, &nh); + adj = adj_get (ai); + } + /* Add encapsulation string for software interface (e.g. ethernet header). */ vnet_rewrite_one_header (adj[0], h, sizeof (ethernet_header_t)); vlib_buffer_advance (b, -adj->rewrite_header.data_bytes); @@ -2794,101 +2753,6 @@ VLIB_REGISTER_NODE (ip4_midchain_node) = { VLIB_NODE_FUNCTION_MULTIARCH (ip4_midchain_node, ip4_midchain); /* *INDENT-ON */ -static clib_error_t * -add_del_interface_table (vlib_main_t * vm, - unformat_input_t * input, vlib_cli_command_t * cmd) -{ - vnet_main_t *vnm = vnet_get_main (); - ip_interface_address_t *ia; - clib_error_t *error = 0; - u32 sw_if_index, table_id; - - sw_if_index = ~0; - - if (!unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index)) - { - error = clib_error_return (0, "unknown interface `%U'", - format_unformat_error, input); - goto done; - } - - if (unformat (input, "%d", &table_id)) - ; - else - { - error = clib_error_return (0, "expected table id `%U'", - format_unformat_error, input); - goto done; - } - - /* - * If the interface already has in IP address, then a change int - * VRF is not allowed. The IP address applied must first be removed. - * We do not do that automatically here, since VPP has no knowledge - * of whether thoses subnets are valid in the destination VRF. - */ - /* *INDENT-OFF* */ - foreach_ip_interface_address (&ip4_main.lookup_main, - ia, sw_if_index, - 1 /* honor unnumbered */, - ({ - ip4_address_t * a; - - a = ip_interface_address_get_address (&ip4_main.lookup_main, ia); - error = clib_error_return (0, "interface %U has address %U", - format_vnet_sw_if_index_name, vnm, - sw_if_index, - format_ip4_address, a); - goto done; - })); - /* *INDENT-ON* */ - -{ - ip4_main_t *im = &ip4_main; - u32 fib_index; - - fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, table_id); - - vec_validate (im->fib_index_by_sw_if_index, sw_if_index); - im->fib_index_by_sw_if_index[sw_if_index] = fib_index; - - fib_index = mfib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, table_id); - vec_validate (im->mfib_index_by_sw_if_index, sw_if_index); - im->mfib_index_by_sw_if_index[sw_if_index] = fib_index; -} - -done: -return error; -} - -/*? - * Place the indicated interface into the supplied IPv4 FIB table (also known - * as a VRF). If the FIB table does not exist, this command creates it. To - * display the current IPv4 FIB table, use the command 'show ip fib'. - * FIB table will only be displayed if a route has been added to the table, or - * an IP Address is assigned to an interface in the table (which adds a route - * automatically). - * - * @note IP addresses added after setting the interface IP table are added to - * the indicated FIB table. If an IP address is added prior to changing the - * table then this is an error. The control plane must remove these addresses - * first and then change the table. VPP will not automatically move the - * addresses from the old to the new table as it does not know the validity - * of such a change. - * - * @cliexpar - * Example of how to add an interface to an IPv4 FIB table (where 2 is the table-id): - * @cliexcmd{set interface ip table GigabitEthernet2/0/0 2} - ?*/ -/* *INDENT-OFF* */ -VLIB_CLI_COMMAND (set_interface_ip_table_command, static) = -{ - .path = "set interface ip table", - .function = add_del_interface_table, - .short_help = "set interface ip table ", -}; -/* *INDENT-ON* */ - int ip4_lookup_validate (ip4_address_t * a, u32 fib_index0) {