X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fip%2Fip6_forward.c;h=28c84d1c2ee2b9e2279a819c9627868c7d2fb6fa;hb=630198f04916deb35c5b7774823ae1a5dd168a6c;hp=ecc3bd2cc6ee27a2aac797c420d00d07571f9bc4;hpb=2e7fbcc08152da5c6a17ed80ba08cd37edec6c8c;p=vpp.git diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c index ecc3bd2cc6e..28c84d1c2ee 100644 --- a/src/vnet/ip/ip6_forward.c +++ b/src/vnet/ip/ip6_forward.c @@ -45,7 +45,7 @@ #include /* for FIB uRPF check */ #include #include -#include +#include #include #include @@ -74,7 +74,7 @@ ip6_lookup_inline (vlib_main_t * vm, vlib_combined_counter_main_t *cm = &load_balance_main.lbm_to_counters; u32 n_left_from, n_left_to_next, *from, *to_next; ip_lookup_next_t next; - u32 cpu_index = os_get_cpu_number (); + u32 thread_index = vlib_get_thread_index (); from = vlib_frame_vector_args (frame); n_left_from = frame->n_vectors; @@ -138,6 +138,10 @@ ip6_lookup_inline (vlib_main_t * vm, lb0 = load_balance_get (lbi0); lb1 = load_balance_get (lbi1); + ASSERT (lb0->lb_n_buckets > 0); + ASSERT (lb1->lb_n_buckets > 0); + ASSERT (is_pow2 (lb0->lb_n_buckets)); + ASSERT (is_pow2 (lb1->lb_n_buckets)); vnet_buffer (p0)->ip.flow_hash = vnet_buffer (p1)->ip.flow_hash = 0; @@ -146,25 +150,29 @@ ip6_lookup_inline (vlib_main_t * vm, flow_hash_config0 = lb0->lb_hash_config; vnet_buffer (p0)->ip.flow_hash = ip6_compute_flow_hash (ip0, flow_hash_config0); + dpo0 = + load_balance_get_fwd_bucket (lb0, + (vnet_buffer (p0)->ip.flow_hash & + (lb0->lb_n_buckets_minus_1))); + } + else + { + dpo0 = load_balance_get_bucket_i (lb0, 0); } if (PREDICT_FALSE (lb1->lb_n_buckets > 1)) { flow_hash_config1 = lb1->lb_hash_config; vnet_buffer (p1)->ip.flow_hash = ip6_compute_flow_hash (ip1, flow_hash_config1); + dpo1 = + load_balance_get_fwd_bucket (lb1, + (vnet_buffer (p1)->ip.flow_hash & + (lb1->lb_n_buckets_minus_1))); + } + else + { + dpo1 = load_balance_get_bucket_i (lb1, 0); } - - ASSERT (lb0->lb_n_buckets > 0); - ASSERT (lb1->lb_n_buckets > 0); - ASSERT (is_pow2 (lb0->lb_n_buckets)); - ASSERT (is_pow2 (lb1->lb_n_buckets)); - dpo0 = load_balance_get_bucket_i (lb0, - (vnet_buffer (p0)->ip.flow_hash & - lb0->lb_n_buckets_minus_1)); - dpo1 = load_balance_get_bucket_i (lb1, - (vnet_buffer (p1)->ip.flow_hash & - lb1->lb_n_buckets_minus_1)); - next0 = dpo0->dpoi_next_node; next1 = dpo1->dpoi_next_node; @@ -185,9 +193,9 @@ ip6_lookup_inline (vlib_main_t * vm, vnet_buffer (p1)->ip.adj_index[VLIB_TX] = dpo1->dpoi_index; vlib_increment_combined_counter - (cm, cpu_index, lbi0, 1, vlib_buffer_length_in_chain (vm, p0)); + (cm, thread_index, lbi0, 1, vlib_buffer_length_in_chain (vm, p0)); vlib_increment_combined_counter - (cm, cpu_index, lbi1, 1, vlib_buffer_length_in_chain (vm, p1)); + (cm, thread_index, lbi1, 1, vlib_buffer_length_in_chain (vm, p1)); from += 2; to_next += 2; @@ -259,23 +267,30 @@ ip6_lookup_inline (vlib_main_t * vm, (vnet_buffer (p0)->sw_if_index[VLIB_TX] == (u32) ~ 0) ? fib_index0 : vnet_buffer (p0)->sw_if_index[VLIB_TX]; - flow_hash_config0 = ip6_fib_get (fib_index0)->flow_hash_config; - lbi0 = ip6_fib_table_fwding_lookup (im, fib_index0, dst_addr0); lb0 = load_balance_get (lbi0); + flow_hash_config0 = lb0->lb_hash_config; vnet_buffer (p0)->ip.flow_hash = 0; + ASSERT (lb0->lb_n_buckets > 0); + ASSERT (is_pow2 (lb0->lb_n_buckets)); if (PREDICT_FALSE (lb0->lb_n_buckets > 1)) { flow_hash_config0 = lb0->lb_hash_config; vnet_buffer (p0)->ip.flow_hash = ip6_compute_flow_hash (ip0, flow_hash_config0); + dpo0 = + load_balance_get_fwd_bucket (lb0, + (vnet_buffer (p0)->ip.flow_hash & + (lb0->lb_n_buckets_minus_1))); + } + else + { + dpo0 = load_balance_get_bucket_i (lb0, 0); } - ASSERT (lb0->lb_n_buckets > 0); - ASSERT (is_pow2 (lb0->lb_n_buckets)); dpo0 = load_balance_get_bucket_i (lb0, (vnet_buffer (p0)->ip.flow_hash & lb0->lb_n_buckets_minus_1)); @@ -291,7 +306,7 @@ ip6_lookup_inline (vlib_main_t * vm, vnet_buffer (p0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index; vlib_increment_combined_counter - (cm, cpu_index, lbi0, 1, vlib_buffer_length_in_chain (vm, p0)); + (cm, thread_index, lbi0, 1, vlib_buffer_length_in_chain (vm, p0)); from += 1; to_next += 1; @@ -337,10 +352,18 @@ ip6_add_interface_routes (vnet_main_t * vnm, u32 sw_if_index, { fib_node_index_t fei; - fei = fib_table_entry_update_one_path (fib_index, &pfx, FIB_SOURCE_INTERFACE, (FIB_ENTRY_FLAG_CONNECTED | FIB_ENTRY_FLAG_ATTACHED), FIB_PROTOCOL_IP6, NULL, /* No next-hop address */ - sw_if_index, ~0, // invalid FIB index - 1, NULL, // no label stack - FIB_ROUTE_PATH_FLAG_NONE); + fei = fib_table_entry_update_one_path (fib_index, + &pfx, + FIB_SOURCE_INTERFACE, + (FIB_ENTRY_FLAG_CONNECTED | + FIB_ENTRY_FLAG_ATTACHED), + FIB_PROTOCOL_IP6, + /* No next-hop address */ + NULL, sw_if_index, + /* invalid FIB index */ + ~0, 1, + /* no label stack */ + NULL, FIB_ROUTE_PATH_FLAG_NONE); a->neighbor_probe_adj_index = fib_entry_get_adj (fei); } @@ -366,7 +389,13 @@ ip6_add_interface_routes (vnet_main_t * vnm, u32 sw_if_index, } } - fib_table_entry_update_one_path (fib_index, &pfx, FIB_SOURCE_INTERFACE, (FIB_ENTRY_FLAG_CONNECTED | FIB_ENTRY_FLAG_LOCAL), FIB_PROTOCOL_IP6, &pfx.fp_addr, sw_if_index, ~0, // invalid FIB index + fib_table_entry_update_one_path (fib_index, &pfx, + FIB_SOURCE_INTERFACE, + (FIB_ENTRY_FLAG_CONNECTED | + FIB_ENTRY_FLAG_LOCAL), + FIB_PROTOCOL_IP6, + &pfx.fp_addr, + sw_if_index, ~0, 1, NULL, FIB_ROUTE_PATH_FLAG_NONE); } @@ -415,12 +444,11 @@ ip6_sw_interface_enable_disable (u32 sw_if_index, u32 is_enable) return; } - vnet_feature_enable_disable ("ip6-unicast", "ip6-lookup", sw_if_index, - is_enable, 0, 0); - - vnet_feature_enable_disable ("ip6-multicast", "ip6-mfib-forward-lookup", - sw_if_index, is_enable, 0, 0); + vnet_feature_enable_disable ("ip6-unicast", "ip6-drop", sw_if_index, + !is_enable, 0, 0); + vnet_feature_enable_disable ("ip6-multicast", "ip6-drop", sw_if_index, + !is_enable, 0, 0); } /* get first interface address */ @@ -595,17 +623,17 @@ VNET_FEATURE_INIT (ip6_vxlan_bypass, static) = .runs_before = VNET_FEATURES ("ip6-lookup"), }; -VNET_FEATURE_INIT (ip6_lookup, static) = +VNET_FEATURE_INIT (ip6_drop, static) = { .arc_name = "ip6-unicast", - .node_name = "ip6-lookup", - .runs_before = VNET_FEATURES ("ip6-drop"), + .node_name = "ip6-drop", + .runs_before = VNET_FEATURES ("ip6-lookup"), }; -VNET_FEATURE_INIT (ip6_drop, static) = +VNET_FEATURE_INIT (ip6_lookup, static) = { .arc_name = "ip6-unicast", - .node_name = "ip6-drop", + .node_name = "ip6-lookup", .runs_before = 0, /*last feature*/ }; @@ -623,15 +651,15 @@ VNET_FEATURE_INIT (ip6_vpath_mc, static) = { .runs_before = VNET_FEATURES ("ip6-mfib-forward-lookup"), }; -VNET_FEATURE_INIT (ip6_mc_lookup, static) = { +VNET_FEATURE_INIT (ip6_drop_mc, static) = { .arc_name = "ip6-multicast", - .node_name = "ip6-mfib-forward-lookup", - .runs_before = VNET_FEATURES ("ip6-drop"), + .node_name = "ip6-drop", + .runs_before = VNET_FEATURES ("ip6-mfib-forward-lookup"), }; -VNET_FEATURE_INIT (ip6_drop_mc, static) = { +VNET_FEATURE_INIT (ip6_mc_lookup, static) = { .arc_name = "ip6-multicast", - .node_name = "ip6-drop", + .node_name = "ip6-mfib-forward-lookup", .runs_before = 0, /* last feature */ }; @@ -659,15 +687,17 @@ VNET_FEATURE_INIT (ip6_interface_output, static) = { clib_error_t * ip6_sw_interface_add_del (vnet_main_t * vnm, u32 sw_if_index, u32 is_add) { + ip6_main_t *im = &ip6_main; + + vec_validate (im->fib_index_by_sw_if_index, sw_if_index); + vec_validate (im->mfib_index_by_sw_if_index, sw_if_index); + vnet_feature_enable_disable ("ip6-unicast", "ip6-drop", sw_if_index, is_add, 0, 0); vnet_feature_enable_disable ("ip6-multicast", "ip6-drop", sw_if_index, is_add, 0, 0); - vnet_feature_enable_disable ("ip6-output", "interface-output", sw_if_index, - is_add, 0, 0); - return /* no error */ 0; } @@ -703,7 +733,7 @@ ip6_load_balance (vlib_main_t * vm, vlib_combined_counter_main_t *cm = &load_balance_main.lbm_via_counters; u32 n_left_from, n_left_to_next, *from, *to_next; ip_lookup_next_t next; - u32 cpu_index = os_get_cpu_number (); + u32 thread_index = vlib_get_thread_index (); ip6_main_t *im = &ip6_main; from = vlib_frame_vector_args (frame); @@ -780,6 +810,14 @@ ip6_load_balance (vlib_main_t * vm, hc0 = vnet_buffer (p0)->ip.flow_hash = ip6_compute_flow_hash (ip0, lb0->lb_hash_config); } + dpo0 = + load_balance_get_fwd_bucket (lb0, + (hc0 & + lb0->lb_n_buckets_minus_1)); + } + else + { + dpo0 = load_balance_get_bucket_i (lb0, 0); } if (PREDICT_FALSE (lb1->lb_n_buckets > 1)) { @@ -793,14 +831,15 @@ ip6_load_balance (vlib_main_t * vm, hc1 = vnet_buffer (p1)->ip.flow_hash = ip6_compute_flow_hash (ip1, lb1->lb_hash_config); } + dpo1 = + load_balance_get_fwd_bucket (lb1, + (hc1 & + lb1->lb_n_buckets_minus_1)); + } + else + { + dpo1 = load_balance_get_bucket_i (lb1, 0); } - - dpo0 = - load_balance_get_bucket_i (lb0, - hc0 & (lb0->lb_n_buckets_minus_1)); - dpo1 = - load_balance_get_bucket_i (lb1, - hc1 & (lb1->lb_n_buckets_minus_1)); next0 = dpo0->dpoi_next_node; next1 = dpo1->dpoi_next_node; @@ -824,9 +863,9 @@ ip6_load_balance (vlib_main_t * vm, vnet_buffer (p1)->ip.adj_index[VLIB_TX] = dpo1->dpoi_index; vlib_increment_combined_counter - (cm, cpu_index, lbi0, 1, vlib_buffer_length_in_chain (vm, p0)); + (cm, thread_index, lbi0, 1, vlib_buffer_length_in_chain (vm, p0)); vlib_increment_combined_counter - (cm, cpu_index, lbi1, 1, vlib_buffer_length_in_chain (vm, p1)); + (cm, thread_index, lbi1, 1, vlib_buffer_length_in_chain (vm, p1)); vlib_validate_buffer_enqueue_x2 (vm, node, next, to_next, n_left_to_next, @@ -869,10 +908,15 @@ ip6_load_balance (vlib_main_t * vm, hc0 = vnet_buffer (p0)->ip.flow_hash = ip6_compute_flow_hash (ip0, lb0->lb_hash_config); } + dpo0 = + load_balance_get_fwd_bucket (lb0, + (hc0 & + lb0->lb_n_buckets_minus_1)); + } + else + { + dpo0 = load_balance_get_bucket_i (lb0, 0); } - dpo0 = - load_balance_get_bucket_i (lb0, - hc0 & (lb0->lb_n_buckets_minus_1)); next0 = dpo0->dpoi_next_node; vnet_buffer (p0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index; @@ -886,7 +930,7 @@ ip6_load_balance (vlib_main_t * vm, } vlib_increment_combined_counter - (cm, cpu_index, lbi0, 1, vlib_buffer_length_in_chain (vm, p0)); + (cm, thread_index, lbi0, 1, vlib_buffer_length_in_chain (vm, p0)); vlib_validate_buffer_enqueue_x1 (vm, node, next, to_next, n_left_to_next, @@ -1611,7 +1655,7 @@ ip6_discover_neighbor_inline (vlib_main_t * vm, ip0 = vlib_buffer_get_current (p0); - adj0 = ip_get_adjacency (lm, adj_index0); + adj0 = adj_get (adj_index0); if (!is_glean) { @@ -1862,7 +1906,7 @@ ip6_probe_neighbor (vlib_main_t * vm, ip6_address_t * dst, u32 sw_if_index) vnet_buffer (b)->sw_if_index[VLIB_TX] = sw_if_index; /* Add encapsulation string for software interface (e.g. ethernet header). */ - adj = ip_get_adjacency (&im->lookup_main, ia->neighbor_probe_adj_index); + adj = adj_get (ia->neighbor_probe_adj_index); vnet_rewrite_one_header (adj[0], h, sizeof (ethernet_header_t)); vlib_buffer_advance (b, -adj->rewrite_header.data_bytes); @@ -1897,7 +1941,7 @@ ip6_rewrite_inline (vlib_main_t * vm, n_left_from = frame->n_vectors; next_index = node->cached_next_index; - u32 cpu_index = os_get_cpu_number (); + u32 thread_index = vlib_get_thread_index (); while (n_left_from > 0) { @@ -1943,9 +1987,6 @@ ip6_rewrite_inline (vlib_main_t * vm, adj_index0 = vnet_buffer (p0)->ip.adj_index[VLIB_TX]; adj_index1 = vnet_buffer (p1)->ip.adj_index[VLIB_TX]; - /* We should never rewrite a pkt using the MISS adjacency */ - ASSERT (adj_index0 && adj_index1); - ip0 = vlib_buffer_get_current (p0); ip1 = vlib_buffer_get_current (p1); @@ -2010,8 +2051,8 @@ ip6_rewrite_inline (vlib_main_t * vm, { p1->flags &= ~VNET_BUFFER_LOCALLY_ORIGINATED; } - adj0 = ip_get_adjacency (lm, adj_index0); - adj1 = ip_get_adjacency (lm, adj_index1); + adj0 = adj_get (adj_index0); + adj1 = adj_get (adj_index1); rw_len0 = adj0[0].rewrite_header.data_bytes; rw_len1 = adj1[0].rewrite_header.data_bytes; @@ -2022,11 +2063,11 @@ ip6_rewrite_inline (vlib_main_t * vm, { vlib_increment_combined_counter (&adjacency_counters, - cpu_index, adj_index0, 1, + thread_index, adj_index0, 1, vlib_buffer_length_in_chain (vm, p0) + rw_len0); vlib_increment_combined_counter (&adjacency_counters, - cpu_index, adj_index1, 1, + thread_index, adj_index1, 1, vlib_buffer_length_in_chain (vm, p1) + rw_len1); } @@ -2111,10 +2152,7 @@ ip6_rewrite_inline (vlib_main_t * vm, adj_index0 = vnet_buffer (p0)->ip.adj_index[VLIB_TX]; - /* We should never rewrite a pkt using the MISS adjacency */ - ASSERT (adj_index0); - - adj0 = ip_get_adjacency (lm, adj_index0); + adj0 = adj_get (adj_index0); ip0 = vlib_buffer_get_current (p0); @@ -2162,7 +2200,7 @@ ip6_rewrite_inline (vlib_main_t * vm, { vlib_increment_combined_counter (&adjacency_counters, - cpu_index, adj_index0, 1, + thread_index, adj_index0, 1, vlib_buffer_length_in_chain (vm, p0) + rw_len0); } @@ -2252,6 +2290,16 @@ ip6_midchain (vlib_main_t * vm, return ip6_rewrite_inline (vm, node, frame, 0, 1, 0); } +static uword +ip6_mcast_midchain (vlib_main_t * vm, + vlib_node_runtime_t * node, vlib_frame_t * frame) +{ + if (adj_are_counters_enabled ()) + return ip6_rewrite_inline (vm, node, frame, 1, 1, 1); + else + return ip6_rewrite_inline (vm, node, frame, 0, 1, 1); +} + /* *INDENT-OFF* */ VLIB_REGISTER_NODE (ip6_midchain_node) = { @@ -2296,6 +2344,19 @@ VLIB_REGISTER_NODE (ip6_rewrite_mcast_node) = VLIB_NODE_FUNCTION_MULTIARCH (ip6_rewrite_mcast_node, ip6_rewrite_mcast); +/* *INDENT-OFF* */ +VLIB_REGISTER_NODE (ip6_mcast_midchain_node, static) = +{ + .function = ip6_mcast_midchain, + .name = "ip6-mcast-midchain", + .vector_size = sizeof (u32), + .format_trace = format_ip6_rewrite_trace, + .sibling_of = "ip6-rewrite", +}; +/* *INDENT-ON* */ + +VLIB_NODE_FUNCTION_MULTIARCH (ip6_mcast_midchain_node, ip6_mcast_midchain); + /* * Hop-by-Hop handling */ @@ -2514,8 +2575,6 @@ ip6_hop_by_hop (vlib_main_t * vm, ip6_hop_by_hop_main_t *hm = &ip6_hop_by_hop_main; u32 n_left_from, *from, *to_next; ip_lookup_next_t next_index; - ip6_main_t *im = &ip6_main; - ip_lookup_main_t *lm = &im->lookup_main; from = vlib_frame_vector_args (frame); n_left_from = frame->n_vectors; @@ -2564,9 +2623,9 @@ ip6_hop_by_hop (vlib_main_t * vm, /* Default use the next_index from the adjacency. A HBH option rarely redirects to a different node */ u32 adj_index0 = vnet_buffer (b0)->ip.adj_index[VLIB_TX]; - ip_adjacency_t *adj0 = ip_get_adjacency (lm, adj_index0); + ip_adjacency_t *adj0 = adj_get (adj_index0); u32 adj_index1 = vnet_buffer (b1)->ip.adj_index[VLIB_TX]; - ip_adjacency_t *adj1 = ip_get_adjacency (lm, adj_index1); + ip_adjacency_t *adj1 = adj_get (adj_index1); /* Default use the next_index from the adjacency. A HBH option rarely redirects to a different node */ next0 = adj0->lookup_next_index; @@ -2687,7 +2746,7 @@ ip6_hop_by_hop (vlib_main_t * vm, * A HBH option rarely redirects to a different node */ u32 adj_index0 = vnet_buffer (b0)->ip.adj_index[VLIB_TX]; - ip_adjacency_t *adj0 = ip_get_adjacency (lm, adj_index0); + ip_adjacency_t *adj0 = adj_get (adj_index0); next0 = adj0->lookup_next_index; ip0 = vlib_buffer_get_current (b0); @@ -3097,17 +3156,17 @@ VLIB_CLI_COMMAND (test_link_command, static) = int vnet_set_ip6_flow_hash (u32 table_id, u32 flow_hash_config) { - ip6_main_t *im6 = &ip6_main; - ip6_fib_t *fib; - uword *p = hash_get (im6->fib_index_by_table_id, table_id); + u32 fib_index; + + fib_index = fib_table_find (FIB_PROTOCOL_IP6, table_id); - if (p == 0) - return -1; + if (~0 == fib_index) + return VNET_API_ERROR_NO_SUCH_FIB; - fib = ip6_fib_get (p[0]); + fib_table_set_flow_hash_config (fib_index, FIB_PROTOCOL_IP6, + flow_hash_config); - fib->flow_hash_config = flow_hash_config; - return 1; + return 0; } static clib_error_t * @@ -3139,7 +3198,7 @@ set_ip6_flow_hash_command_fn (vlib_main_t * vm, rv = vnet_set_ip6_flow_hash (table_id, flow_hash_config); switch (rv) { - case 1: + case 0: break; case -1: