uword * mac_changes_by_address;
pending_resolution_t * mac_changes;
- u32 * arp_input_next_index_by_hw_if_index;
-
ethernet_arp_ip4_entry_t * ip4_entry_pool;
mhash_t ip4_entry_by_key;
ethernet_arp_ip4_over_ethernet_address_t delme;
e = pool_elt_at_index (am->ip4_entry_pool, to_delete[i]);
- memcpy (&delme.ethernet, e->ethernet_address, 6);
+ clib_memcpy (&delme.ethernet, e->ethernet_address, 6);
delme.ip4.as_u32 = e->key.ip4_address.as_u32;
vnet_arp_unset_ip4_over_ethernet (vnm, e->key.sw_if_index,
args.fib_index = fib_index;
args.is_static = is_static;
args.is_remove = 0;
- memcpy (&args.a, a, sizeof (*a));
+ clib_memcpy (&args.a, a, sizeof (*a));
vl_api_rpc_call_main_thread (set_ip4_over_ethernet_rpc_callback,
(u8 *) &args, sizeof (args));
e = pool_elt_at_index (am->ip4_entry_pool, p[0]);
/* Refuse to over-write static arp. */
- if (e->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_STATIC)
+ if (!is_static &&
+ (e->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_STATIC))
return -2;
make_new_arp_cache_entry = 0;
}
/* Note: always install the route. It might have been deleted */
memset(&adj, 0, sizeof(adj));
adj.lookup_next_index = IP_LOOKUP_NEXT_REWRITE;
+ adj.n_adj = 1; /* otherwise signature compare fails */
vnet_rewrite_for_sw_interface
(vnm,
}
else
{
- /* create new adj */
- args.table_index_or_table_id = fib_index;
- args.flags = IP4_ROUTE_FLAG_FIB_INDEX | IP4_ROUTE_FLAG_ADD | IP4_ROUTE_FLAG_NEIGHBOR;
- args.dst_address = a->ip4;
- args.dst_address_length = 32;
- args.adj_index = ~0;
- args.add_adj = &adj;
- args.n_add_adj = 1;
- ip4_add_del_route (im, &args);
+ /* Check that new adjacency actually isn't exactly the same as
+ * what is already there. If we over-write the adjacency with
+ * exactly the same info, its technically a new adjacency with
+ * new counters, but to user it appears as counters reset.
+ */
+ if (vnet_ip_adjacency_share_compare (&adj, existing_adj) == 0) {
+ /* create new adj */
+ args.table_index_or_table_id = fib_index;
+ args.flags = IP4_ROUTE_FLAG_FIB_INDEX | IP4_ROUTE_FLAG_ADD | IP4_ROUTE_FLAG_NEIGHBOR;
+ args.dst_address = a->ip4;
+ args.dst_address_length = 32;
+ args.adj_index = ~0;
+ args.add_adj = &adj;
+ args.n_add_adj = 1;
+ ip4_add_del_route (im, &args);
+ }
}
if (make_new_arp_cache_entry)
}
/* Update time stamp and ethernet address. */
- memcpy (e->ethernet_address, a->ethernet, sizeof (e->ethernet_address));
+ clib_memcpy (e->ethernet_address, a->ethernet, sizeof (e->ethernet_address));
e->cpu_time_last_updated = clib_cpu_time_now ();
if (is_static)
e->flags |= ETHERNET_ARP_IP4_ENTRY_FLAG_STATIC;
/* Either we drop the packet or we send a reply to the sender. */
typedef enum {
ARP_INPUT_NEXT_DROP,
+ ARP_INPUT_NEXT_REPLY_TX,
ARP_INPUT_N_NEXT,
} arp_input_next_t;
e = pool_elt_at_index (am->ip4_entry_pool, index);
- memcpy (&delme.ethernet, e->ethernet_address, 6);
+ clib_memcpy (&delme.ethernet, e->ethernet_address, 6);
delme.ip4.as_u32 = e->key.ip4_address.as_u32;
vnet_arp_unset_ip4_over_ethernet (vnm, e->key.sw_if_index,
e->key.fib_index, &delme);
}
-static u32 arp_unnumbered (vlib_buffer_t * p0,
- u32 pi0,
- ethernet_header_t * eth0,
- ip_interface_address_t * ifa0)
+static void arp_unnumbered (vlib_buffer_t * p0,
+ u32 pi0,
+ ethernet_header_t * eth0,
+ ip_interface_address_t * ifa0)
{
- ethernet_arp_main_t * am = ðernet_arp_main;
vlib_main_t * vm = vlib_get_main();
vnet_main_t * vnm = vnet_get_main();
vnet_interface_main_t * vim = &vnm->interface_main;
ethernet_arp_header_t * arp0;
/* Save the dst mac address */
- memcpy(dst_mac_address, eth0->dst_address, sizeof (dst_mac_address));
+ clib_memcpy(dst_mac_address, eth0->dst_address, sizeof (dst_mac_address));
/* Figure out which sw_if_index supplied the address */
unnum_src_sw_if_index = ifa0->sw_if_index;
b0 = vlib_get_buffer (vm, buffers[i]);
/* xerox (partially built) ARP pkt */
- memcpy (b0->data, p0->data, p0->current_length + p0->current_data);
+ clib_memcpy (b0->data, p0->data, p0->current_length + p0->current_data);
b0->current_data = p0->current_data;
b0->current_length = p0->current_length;
vnet_buffer(b0)->sw_if_index[VLIB_RX] =
vnet_buffer(b0)->sw_if_index[VLIB_TX] = hi->sw_if_index;
/* Fix ARP pkt src address */
- memcpy (arp0->ip4_over_ethernet[0].ethernet, hi->hw_address, 6);
+ clib_memcpy (arp0->ip4_over_ethernet[0].ethernet, hi->hw_address, 6);
/* Build L2 encaps for this swif */
header_size = sizeof (ethernet_header_t);
}
/* Restore the original dst address, set src address */
- memcpy (eth0->dst_address, dst_mac_address, sizeof (eth0->dst_address));
- memcpy (eth0->src_address, hi->hw_address, sizeof (eth0->src_address));
+ clib_memcpy (eth0->dst_address, dst_mac_address, sizeof (eth0->dst_address));
+ clib_memcpy (eth0->src_address, hi->hw_address, sizeof (eth0->src_address));
/* Transmit replicas */
if (i > 0)
}
}
- hi = vnet_get_sup_hw_interface (vnm, broadcast_swifs[0]);
+ /* The regular path outputs the original pkt.. */
+ vnet_buffer (p0)->sw_if_index[VLIB_TX] = broadcast_swifs[0];
vec_free (broadcast_swifs);
vec_free (buffers);
-
- /* The regular path outputs the original pkt.. */
- return vec_elt (am->arp_input_next_index_by_hw_if_index, hi->hw_if_index);
}
static uword
vnet_buffer (p0)->sw_if_index[VLIB_TX] = sw_if_index0;
hw_if0 = vnet_get_sup_hw_interface (vnm, sw_if_index0);
- /* Can happen in a multi-core env. */
- if (PREDICT_FALSE(hw_if0->hw_if_index >= vec_len (am->arp_input_next_index_by_hw_if_index)))
- {
- error0 = ETHERNET_ARP_ERROR_missing_interface_address;
- goto drop2;
- }
-
- next0 = vec_elt (am->arp_input_next_index_by_hw_if_index, hw_if0->hw_if_index);
+ /* Send reply back through input interface */
+ vnet_buffer (p0)->sw_if_index[VLIB_TX] = sw_if_index0;
+ next0 = ARP_INPUT_NEXT_REPLY_TX;
arp0->opcode = clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply);
arp0->ip4_over_ethernet[1] = arp0->ip4_over_ethernet[0];
- memcpy (arp0->ip4_over_ethernet[0].ethernet, hw_if0->hw_address, 6);
+ clib_memcpy (arp0->ip4_over_ethernet[0].ethernet, hw_if0->hw_address, 6);
clib_mem_unaligned (&arp0->ip4_over_ethernet[0].ip4.data_u32, u32) = if_addr0->data_u32;
/* Hardware must be ethernet-like. */
ASSERT (vec_len (hw_if0->hw_address) == 6);
- memcpy (eth0->dst_address, eth0->src_address, 6);
- memcpy (eth0->src_address, hw_if0->hw_address, 6);
+ clib_memcpy (eth0->dst_address, eth0->src_address, 6);
+ clib_memcpy (eth0->src_address, hw_if0->hw_address, 6);
/* Figure out how much to rewind current data from adjacency. */
if (ifa0)
goto drop2;
}
if (is_unnum0)
- next0 = arp_unnumbered (p0, pi0, eth0, ifa0);
+ arp_unnumbered (p0, pi0, eth0, ifa0);
else
vlib_buffer_advance (p0, -adj0->rewrite_header.data_bytes);
}
.n_next_nodes = ARP_INPUT_N_NEXT,
.next_nodes = {
[ARP_INPUT_NEXT_DROP] = "error-drop",
+ [ARP_INPUT_NEXT_REPLY_TX] = "interface-output",
},
.format_buffer = format_ethernet_arp_header,
.format_trace = format_ethernet_arp_input_trace,
};
-clib_error_t *
-ethernet_arp_hw_interface_link_up_down (vnet_main_t * vnm,
- u32 hw_if_index,
- u32 flags)
-{
- ethernet_arp_main_t * am = ðernet_arp_main;
- vnet_hw_interface_t * hw_if;
-
- hw_if = vnet_get_hw_interface (vnm, hw_if_index);
-
- /* Fill in lookup tables with default table (0). */
- vec_validate_init_empty (am->arp_input_next_index_by_hw_if_index, hw_if_index, ~0);
- am->arp_input_next_index_by_hw_if_index[hw_if_index]
- = vlib_node_add_next (vnm->vlib_main, arp_input_node.index, hw_if->output_node_index);
-
- return 0;
-}
-
-VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION (ethernet_arp_hw_interface_link_up_down);
-
static int
ip4_arp_entry_sort (void *a1, void *a2)
{
{
if (!e)
clib_warning("Adjacency contains unknown ARP next hop %U (del)",
- format_ip4_address, &adj->arp.next_hop);
+ format_ip46_address, &adj->arp.next_hop, IP46_TYPE_IP4);
else
arp_ip4_entry_del_adj(e, adj->heap_handle);
}
{
if (!e)
clib_warning("Adjacency contains unknown ARP next hop %U (add)",
- format_ip4_address, &adj->arp.next_hop);
+ format_ip46_address, &adj->arp.next_hop, IP46_TYPE_IP4);
else
arp_ip4_entry_add_adj(e, adj->heap_handle);
}
args.sw_if_index = sw_if_index;
args.fib_index = fib_index;
args.is_remove = 1;
- memcpy (&args.a, a, sizeof (*a));
+ clib_memcpy (&args.a, a, sizeof (*a));
vl_api_rpc_call_main_thread (set_ip4_over_ethernet_rpc_callback,
(u8 *) &args, sizeof (args));
e->flags = ETHERNET_ARP_IP4_ENTRY_FLAG_GLEAN;
memset(&args, 0, sizeof(args));
- memcpy(&add_adj, adj, sizeof(add_adj));
- add_adj.arp.next_hop.ip4.as_u32 = next_hop->as_u32; /* install neighbor /32 route */
+ clib_memcpy(&add_adj, adj, sizeof(add_adj));
+ ip46_address_set_ip4(&add_adj.arp.next_hop, next_hop); /* install neighbor /32 route */
args.table_index_or_table_id = fib_index;
args.flags = IP4_ROUTE_FLAG_FIB_INDEX | IP4_ROUTE_FLAG_ADD| IP4_ROUTE_FLAG_NEIGHBOR;
args.dst_address.as_u32 = next_hop->as_u32;
VLIB_CLI_COMMAND (ip_arp_add_del_command, static) = {
.path = "set ip arp",
- .short_help = "set ip arp [del] <intfc> <ip-address> <mac-address>",
+ .short_help = "set ip arp [del] <intfc> <ip-address> <mac-address> [static] [count <count>] [fib-id <fib-id>] [proxy <lo-addr> - <hi-addr>]",
.function = ip_arp_add_del_command_fn,
};
{
u8 *t0 = vlib_add_trace (
vm, node, p0, sizeof(ethernet_arp_input_trace_t));
- memcpy (t0, l3h0, sizeof(ethernet_arp_input_trace_t));
+ clib_memcpy (t0, l3h0, sizeof(ethernet_arp_input_trace_t));
}
if (PREDICT_FALSE (
arp0->opcode = clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply);
arp0->ip4_over_ethernet[1] = arp0->ip4_over_ethernet[0];
arp0->ip4_over_ethernet[0].ip4.as_u32 = ip0;
- memcpy (arp0->ip4_over_ethernet[0].ethernet, macp0, 6);
- memcpy (eth0->dst_address, eth0->src_address, 6);
- memcpy (eth0->src_address, macp0, 6);
+ clib_memcpy (arp0->ip4_over_ethernet[0].ethernet, macp0, 6);
+ clib_memcpy (eth0->dst_address, eth0->src_address, 6);
+ clib_memcpy (eth0->src_address, macp0, 6);
n_replies_sent += 1;
// For BVI, need to use l2-fwd node to send ARP reply as