#include <vnet/vnet.h>
#include <vnet/ip/ip.h>
+#include <vnet/ip/ip6_neighbor.h>
#include <vnet/ethernet/ethernet.h> /* for ethernet_header_t */
#include <vnet/srp/srp.h> /* for srp_hw_interface_class */
#include <vppinfra/cache.h>
.fp_addr.ip6 = *address,
};
- a->neighbor_probe_adj_index = ~0;
if (a->address_length < 128)
{
- 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,
- /* 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);
+ fib_table_entry_update_one_path (fib_index,
+ &pfx,
+ FIB_SOURCE_INTERFACE,
+ (FIB_ENTRY_FLAG_CONNECTED |
+ FIB_ENTRY_FLAG_ATTACHED),
+ DPO_PROTO_IP6,
+ /* No next-hop address */
+ NULL, sw_if_index,
+ /* invalid FIB index */
+ ~0, 1,
+ /* no label stack */
+ NULL, FIB_ROUTE_PATH_FLAG_NONE);
}
pfx.fp_len = 128;
FIB_SOURCE_INTERFACE,
(FIB_ENTRY_FLAG_CONNECTED |
FIB_ENTRY_FLAG_LOCAL),
- FIB_PROTOCOL_IP6,
+ DPO_PROTO_IP6,
&pfx.fp_addr,
sw_if_index, ~0,
1, NULL, FIB_ROUTE_PATH_FLAG_NONE);
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 */
u32 if_address_index;
ip6_address_fib_t ip6_af, *addr_fib = 0;
+ /* local0 interface doesn't support IP addressing */
+ if (sw_if_index == 0)
+ {
+ return
+ clib_error_create ("local0 interface doesn't support IP addressing");
+ }
+
vec_validate (im->fib_index_by_sw_if_index, sw_if_index);
vec_validate (im->mfib_index_by_sw_if_index, sw_if_index);
.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*/
};
.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 */
};
vec_validate (im->fib_index_by_sw_if_index, sw_if_index);
vec_validate (im->mfib_index_by_sw_if_index, sw_if_index);
+ if (!is_add)
+ {
+ /* Ensure that IPv6 is disabled */
+ ip6_main_t *im6 = &ip6_main;
+ ip_lookup_main_t *lm6 = &im6->lookup_main;
+ ip_interface_address_t *ia = 0;
+ ip6_address_t *address;
+ vlib_main_t *vm = vlib_get_main ();
+
+ ip6_neighbor_sw_interface_add_del (vnm, sw_if_index, 0 /* is_add */ );
+ /* *INDENT-OFF* */
+ foreach_ip_interface_address (lm6, ia, sw_if_index, 1 /* honor unnumbered */,
+ ({
+ address = ip_interface_address_get_address (lm6, ia);
+ ip6_add_del_interface_address(vm, sw_if_index, address, ia->address_length, 1);
+ }));
+ /* *INDENT-ON* */
+ ip6_mfib_interface_enable_disable (sw_if_index, 0);
+ }
+
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;
}
udp0 = (void *) (ip0 + 1);
if (ip0->protocol == IP_PROTOCOL_UDP && udp0->checksum == 0)
{
- p0->flags |= (IP_BUFFER_L4_CHECKSUM_COMPUTED
- | IP_BUFFER_L4_CHECKSUM_CORRECT);
+ p0->flags |= (VNET_BUFFER_F_L4_CHECKSUM_COMPUTED
+ | VNET_BUFFER_F_L4_CHECKSUM_CORRECT);
return p0->flags;
}
sum16 = ip6_tcp_udp_icmp_compute_checksum (vm, p0, ip0, &bogus_length);
- p0->flags |= (IP_BUFFER_L4_CHECKSUM_COMPUTED
- | ((sum16 == 0) << LOG2_IP_BUFFER_L4_CHECKSUM_CORRECT));
+ p0->flags |= (VNET_BUFFER_F_L4_CHECKSUM_COMPUTED
+ | ((sum16 == 0) << VNET_BUFFER_F_LOG2_L4_CHECKSUM_CORRECT));
return p0->flags;
}
ip0 = vlib_buffer_get_current (p0);
ip1 = vlib_buffer_get_current (p1);
- vnet_buffer (p0)->ip.start_of_ip_header = p0->current_data;
- vnet_buffer (p1)->ip.start_of_ip_header = p1->current_data;
+ vnet_buffer (p0)->l3_hdr_offset = p0->current_data;
+ vnet_buffer (p1)->l3_hdr_offset = p1->current_data;
type0 = lm->builtin_protocol_by_ip_protocol[ip0->protocol];
type1 = lm->builtin_protocol_by_ip_protocol[ip1->protocol];
flags0 = p0->flags;
flags1 = p1->flags;
- good_l4_checksum0 = (flags0 & IP_BUFFER_L4_CHECKSUM_CORRECT) != 0;
- good_l4_checksum1 = (flags1 & IP_BUFFER_L4_CHECKSUM_CORRECT) != 0;
+ good_l4_checksum0 =
+ (flags0 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
+ good_l4_checksum1 =
+ (flags1 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
len_diff0 = 0;
len_diff1 = 0;
if (PREDICT_FALSE (type0 != IP_BUILTIN_PROTOCOL_UNKNOWN
&& !good_l4_checksum0
- && !(flags0 & IP_BUFFER_L4_CHECKSUM_COMPUTED)))
+ && !(flags0 &
+ VNET_BUFFER_F_L4_CHECKSUM_COMPUTED)))
{
flags0 = ip6_tcp_udp_icmp_validate_checksum (vm, p0);
good_l4_checksum0 =
- (flags0 & IP_BUFFER_L4_CHECKSUM_CORRECT) != 0;
+ (flags0 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
}
if (PREDICT_FALSE (type1 != IP_BUILTIN_PROTOCOL_UNKNOWN
&& !good_l4_checksum1
- && !(flags1 & IP_BUFFER_L4_CHECKSUM_COMPUTED)))
+ && !(flags1 &
+ VNET_BUFFER_F_L4_CHECKSUM_COMPUTED)))
{
flags1 = ip6_tcp_udp_icmp_validate_checksum (vm, p1);
good_l4_checksum1 =
- (flags1 & IP_BUFFER_L4_CHECKSUM_CORRECT) != 0;
+ (flags1 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
}
error0 = error1 = IP6_ERROR_UNKNOWN_PROTOCOL;
ip0 = vlib_buffer_get_current (p0);
- vnet_buffer (p0)->ip.start_of_ip_header = p0->current_data;
+ vnet_buffer (p0)->l3_hdr_offset = p0->current_data;
type0 = lm->builtin_protocol_by_ip_protocol[ip0->protocol];
next0 = lm->local_next_by_ip_protocol[ip0->protocol];
flags0 = p0->flags;
- good_l4_checksum0 = (flags0 & IP_BUFFER_L4_CHECKSUM_CORRECT) != 0;
+ good_l4_checksum0 =
+ (flags0 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
len_diff0 = 0;
if (PREDICT_TRUE (IP_PROTOCOL_UDP == ip6_locate_header (p0, ip0,
if (PREDICT_FALSE (type0 != IP_BUILTIN_PROTOCOL_UNKNOWN
&& !good_l4_checksum0
- && !(flags0 & IP_BUFFER_L4_CHECKSUM_COMPUTED)))
+ && !(flags0 &
+ VNET_BUFFER_F_L4_CHECKSUM_COMPUTED)))
{
flags0 = ip6_tcp_udp_icmp_validate_checksum (vm, p0);
good_l4_checksum0 =
- (flags0 & IP_BUFFER_L4_CHECKSUM_CORRECT) != 0;
+ (flags0 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
}
error0 = IP6_ERROR_UNKNOWN_PROTOCOL;
vnet_hw_interface_t *hi;
vnet_sw_interface_t *si;
vlib_buffer_t *b;
+ adj_index_t ai;
u32 bi = 0;
int bogus_length;
h->ip.src_address = src[0];
h->neighbor.target_address = dst[0];
+ if (PREDICT_FALSE (!hi->hw_address))
+ {
+ return clib_error_return (0, "%U: interface %U do not support ip probe",
+ format_ip6_address, dst,
+ format_vnet_sw_if_index_name, vnm,
+ sw_if_index);
+ }
+
clib_memcpy (h->link_layer_option.ethernet_address, hi->hw_address,
vec_len (hi->hw_address));
vnet_buffer (b)->sw_if_index[VLIB_TX] = sw_if_index;
/* Add encapsulation string for software interface (e.g. ethernet header). */
- adj = adj_get (ia->neighbor_probe_adj_index);
+ ip46_address_t nh = {
+ .ip6 = *dst,
+ };
+
+ ai = adj_nbr_add_or_lock (FIB_PROTOCOL_IP6,
+ VNET_LINK_IP6, &nh, sw_if_index);
+ adj = adj_get (ai);
+
vnet_rewrite_one_header (adj[0], h, sizeof (ethernet_header_t));
vlib_buffer_advance (b, -adj->rewrite_header.data_bytes);
vlib_put_frame_to_node (vm, hi->output_node_index, f);
}
+ adj_unlock (ai);
return /* no error */ 0;
}
error0 = error1 = IP6_ERROR_NONE;
next0 = next1 = IP6_REWRITE_NEXT_DROP;
- if (PREDICT_TRUE (!(p0->flags & VNET_BUFFER_LOCALLY_ORIGINATED)))
+ if (PREDICT_TRUE (!(p0->flags & VNET_BUFFER_F_LOCALLY_ORIGINATED)))
{
i32 hop_limit0 = ip0->hop_limit;
}
else
{
- p0->flags &= ~VNET_BUFFER_LOCALLY_ORIGINATED;
+ p0->flags &= ~VNET_BUFFER_F_LOCALLY_ORIGINATED;
}
- if (PREDICT_TRUE (!(p1->flags & VNET_BUFFER_LOCALLY_ORIGINATED)))
+ if (PREDICT_TRUE (!(p1->flags & VNET_BUFFER_F_LOCALLY_ORIGINATED)))
{
i32 hop_limit1 = ip1->hop_limit;
}
else
{
- p1->flags &= ~VNET_BUFFER_LOCALLY_ORIGINATED;
+ p1->flags &= ~VNET_BUFFER_F_LOCALLY_ORIGINATED;
}
adj0 = adj_get (adj_index0);
adj1 = adj_get (adj_index1);
next0 = IP6_REWRITE_NEXT_DROP;
/* Check hop limit */
- if (PREDICT_TRUE (!(p0->flags & VNET_BUFFER_LOCALLY_ORIGINATED)))
+ if (PREDICT_TRUE (!(p0->flags & VNET_BUFFER_F_LOCALLY_ORIGINATED)))
{
i32 hop_limit0 = ip0->hop_limit;
}
else
{
- p0->flags &= ~VNET_BUFFER_LOCALLY_ORIGINATED;
+ p0->flags &= ~VNET_BUFFER_F_LOCALLY_ORIGINATED;
}
/* Guess we are only writing on simple Ethernet header. */