X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fip%2Fip6_forward.c;h=5ea7d8d6e9d45fa382225a35bf62af0e4e41cbde;hb=refs%2Fchanges%2F95%2F12995%2F2;hp=f4c51e22bfc9382c4d5582b61ab58a7c44628cfc;hpb=da6e11b47d47c764b11304524de559dda0d0d223;p=vpp.git diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c index f4c51e22bfc..5ea7d8d6e9d 100644 --- a/src/vnet/ip/ip6_forward.c +++ b/src/vnet/ip/ip6_forward.c @@ -39,6 +39,7 @@ #include #include +#include #include #include /* for ethernet_header_t */ #include /* for srp_hw_interface_class */ @@ -1213,23 +1214,15 @@ ip6_local_inline (vlib_main_t * vm, vlib_node_runtime_t * node, ? IP6_ERROR_SRC_LOOKUP_MISS : error1); } - /* TODO maybe move to lookup? */ vnet_buffer (p0)->ip.fib_index = - vec_elt (im->fib_index_by_sw_if_index, - vnet_buffer (p0)->sw_if_index[VLIB_RX]); - vnet_buffer (p0)->ip.fib_index = - (vnet_buffer (p0)->sw_if_index[VLIB_TX] == - (u32) ~ 0) ? vnet_buffer (p0)->ip. - fib_index : vnet_buffer (p0)->sw_if_index[VLIB_TX]; + vnet_buffer (p0)->sw_if_index[VLIB_TX] != ~0 ? + vnet_buffer (p0)->sw_if_index[VLIB_TX] : + vnet_buffer (p0)->ip.fib_index; vnet_buffer (p1)->ip.fib_index = - vec_elt (im->fib_index_by_sw_if_index, - vnet_buffer (p1)->sw_if_index[VLIB_RX]); - vnet_buffer (p1)->ip.fib_index = - (vnet_buffer (p1)->sw_if_index[VLIB_TX] == - (u32) ~ 0) ? vnet_buffer (p1)->ip. - fib_index : vnet_buffer (p1)->sw_if_index[VLIB_TX]; - + vnet_buffer (p1)->sw_if_index[VLIB_TX] != ~0 ? + vnet_buffer (p1)->sw_if_index[VLIB_TX] : + vnet_buffer (p1)->ip.fib_index; skip_checks: @@ -1345,12 +1338,9 @@ ip6_local_inline (vlib_main_t * vm, vlib_node_runtime_t * node, } vnet_buffer (p0)->ip.fib_index = - vec_elt (im->fib_index_by_sw_if_index, - vnet_buffer (p0)->sw_if_index[VLIB_RX]); - vnet_buffer (p0)->ip.fib_index = - (vnet_buffer (p0)->sw_if_index[VLIB_TX] == - (u32) ~ 0) ? vnet_buffer (p0)->ip. - fib_index : vnet_buffer (p0)->sw_if_index[VLIB_TX]; + vnet_buffer (p0)->sw_if_index[VLIB_TX] != ~0 ? + vnet_buffer (p0)->sw_if_index[VLIB_TX] : + vnet_buffer (p0)->ip.fib_index; skip_check: @@ -1445,7 +1435,8 @@ ip6_register_protocol (u32 protocol, u32 node_index) } clib_error_t * -ip6_probe_neighbor (vlib_main_t * vm, ip6_address_t * dst, u32 sw_if_index) +ip6_probe_neighbor (vlib_main_t * vm, ip6_address_t * dst, u32 sw_if_index, + u8 refresh) { vnet_main_t *vnm = vnet_get_main (); ip6_main_t *im = &ip6_main; @@ -1526,7 +1517,7 @@ ip6_probe_neighbor (vlib_main_t * vm, ip6_address_t * dst, u32 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) + if (adj->lookup_next_index == IP_LOOKUP_NEXT_REWRITE && refresh == 0) { adj_unlock (ai); ai = adj_glean_add_or_lock (FIB_PROTOCOL_IP6, @@ -1553,6 +1544,8 @@ typedef enum { IP6_REWRITE_NEXT_DROP, IP6_REWRITE_NEXT_ICMP_ERROR, + IP6_REWRITE_NEXT_FRAGMENT, + IP6_REWRITE_N_NEXT /* Last */ } ip6_rewrite_next_t; /** @@ -1563,14 +1556,25 @@ typedef enum always_inline void ip6_mtu_check (vlib_buffer_t * b, u16 packet_bytes, - u16 adj_packet_bytes, u32 * next, u32 * error) + u16 adj_packet_bytes, bool is_locally_generated, + u32 * next, u32 * error) { if (adj_packet_bytes >= 1280 && packet_bytes > adj_packet_bytes) { - *error = IP6_ERROR_MTU_EXCEEDED; - icmp6_error_set_vnet_buffer (b, ICMP6_packet_too_big, 0, - adj_packet_bytes); - *next = IP6_REWRITE_NEXT_ICMP_ERROR; + if (is_locally_generated) + { + /* IP fragmentation */ + ip_frag_set_vnet_buffer (b, 0, adj_packet_bytes, + IP6_FRAG_NEXT_IP6_LOOKUP, 0); + *next = IP6_REWRITE_NEXT_FRAGMENT; + } + else + { + *error = IP6_ERROR_MTU_EXCEEDED; + icmp6_error_set_vnet_buffer (b, ICMP6_packet_too_big, 0, + adj_packet_bytes); + *next = IP6_REWRITE_NEXT_ICMP_ERROR; + } } } @@ -1602,6 +1606,7 @@ ip6_rewrite_inline (vlib_main_t * vm, u32 pi0, rw_len0, next0, error0, adj_index0; u32 pi1, rw_len1, next1, error1, adj_index1; u32 tx_sw_if_index0, tx_sw_if_index1; + bool is_locally_originated0, is_locally_originated1; /* Prefetch next iteration. */ { @@ -1640,7 +1645,9 @@ ip6_rewrite_inline (vlib_main_t * vm, error0 = error1 = IP6_ERROR_NONE; next0 = next1 = IP6_REWRITE_NEXT_DROP; - if (PREDICT_TRUE (!(p0->flags & VNET_BUFFER_F_LOCALLY_ORIGINATED))) + is_locally_originated0 = + p0->flags & VNET_BUFFER_F_LOCALLY_ORIGINATED; + if (PREDICT_TRUE (!is_locally_originated0)) { i32 hop_limit0 = ip0->hop_limit; @@ -1669,7 +1676,9 @@ ip6_rewrite_inline (vlib_main_t * vm, { p0->flags &= ~VNET_BUFFER_F_LOCALLY_ORIGINATED; } - if (PREDICT_TRUE (!(p1->flags & VNET_BUFFER_F_LOCALLY_ORIGINATED))) + is_locally_originated1 = + p1->flags & VNET_BUFFER_F_LOCALLY_ORIGINATED; + if (PREDICT_TRUE (!is_locally_originated1)) { i32 hop_limit1 = ip1->hop_limit; @@ -1722,11 +1731,11 @@ ip6_rewrite_inline (vlib_main_t * vm, ip6_mtu_check (p0, clib_net_to_host_u16 (ip0->payload_length) + sizeof (ip6_header_t), adj0[0].rewrite_header.max_l3_packet_bytes, - &next0, &error0); + is_locally_originated0, &next0, &error0); ip6_mtu_check (p1, clib_net_to_host_u16 (ip1->payload_length) + sizeof (ip6_header_t), adj1[0].rewrite_header.max_l3_packet_bytes, - &next1, &error1); + is_locally_originated1, &next1, &error1); /* Don't adjust the buffer for hop count issue; icmp-error node * wants to see the IP headerr */ @@ -1800,6 +1809,7 @@ ip6_rewrite_inline (vlib_main_t * vm, u32 pi0, rw_len0; u32 adj_index0, next0, error0; u32 tx_sw_if_index0; + bool is_locally_originated0; pi0 = to_next[0] = from[0]; @@ -1815,7 +1825,9 @@ ip6_rewrite_inline (vlib_main_t * vm, next0 = IP6_REWRITE_NEXT_DROP; /* Check hop limit */ - if (PREDICT_TRUE (!(p0->flags & VNET_BUFFER_F_LOCALLY_ORIGINATED))) + is_locally_originated0 = + p0->flags & VNET_BUFFER_F_LOCALLY_ORIGINATED; + if (PREDICT_TRUE (!is_locally_originated0)) { i32 hop_limit0 = ip0->hop_limit; @@ -1863,7 +1875,7 @@ ip6_rewrite_inline (vlib_main_t * vm, ip6_mtu_check (p0, clib_net_to_host_u16 (ip0->payload_length) + sizeof (ip6_header_t), adj0[0].rewrite_header.max_l3_packet_bytes, - &next0, &error0); + is_locally_originated0, &next0, &error0); /* Don't adjust the buffer for hop count issue; icmp-error node * wants to see the IP header */ @@ -1979,11 +1991,12 @@ VLIB_REGISTER_NODE (ip6_rewrite_node) = .name = "ip6-rewrite", .vector_size = sizeof (u32), .format_trace = format_ip6_rewrite_trace, - .n_next_nodes = 2, + .n_next_nodes = IP6_REWRITE_N_NEXT, .next_nodes = { [IP6_REWRITE_NEXT_DROP] = "ip6-drop", [IP6_REWRITE_NEXT_ICMP_ERROR] = "ip6-icmp-error", + [IP6_REWRITE_NEXT_FRAGMENT] = "ip6-frag", }, }; /* *INDENT-ON* */