-static void serialize_ip4_address (serialize_main_t * m, va_list * va)
-{
- ip4_address_t * a = va_arg (*va, ip4_address_t *);
- u8 * p = serialize_get (m, sizeof (a->as_u8));
- memcpy (p, a->as_u8, sizeof (a->as_u8));
-}
-
-static void unserialize_ip4_address (serialize_main_t * m, va_list * va)
-{
- ip4_address_t * a = va_arg (*va, ip4_address_t *);
- u8 * p = unserialize_get (m, sizeof (a->as_u8));
- memcpy (a->as_u8, p, sizeof (a->as_u8));
-}
-
-static void serialize_ip4_address_and_length (serialize_main_t * m, va_list * va)
-{
- ip4_address_t * a = va_arg (*va, ip4_address_t *);
- u32 l = va_arg (*va, u32);
- u32 n_bytes = (l / 8) + ((l % 8) != 0);
- u8 * p = serialize_get (m, 1 + n_bytes);
- ASSERT (l <= 32);
- p[0] = l;
- memcpy (p + 1, a->as_u8, n_bytes);
-}
-
-static void unserialize_ip4_address_and_length (serialize_main_t * m, va_list * va)
-{
- ip4_address_t * a = va_arg (*va, ip4_address_t *);
- u32 * al = va_arg (*va, u32 *);
- u8 * p = unserialize_get (m, 1);
- u32 l, n_bytes;
-
- al[0] = l = p[0];
- ASSERT (l <= 32);
- n_bytes = (l / 8) + ((l % 8) != 0);
-
- if (n_bytes)
- {
- p = unserialize_get (m, n_bytes);
- memcpy (a->as_u8, p, n_bytes);
- }
-}
-
-static void serialize_ip4_add_del_route_msg (serialize_main_t * m, va_list * va)
-{
- ip4_add_del_route_args_t * a = va_arg (*va, ip4_add_del_route_args_t *);
-
- serialize_likely_small_unsigned_integer (m, a->table_index_or_table_id);
- serialize_likely_small_unsigned_integer (m, a->flags);
- serialize (m, serialize_ip4_address_and_length, &a->dst_address, a->dst_address_length);
- serialize_likely_small_unsigned_integer (m, a->adj_index);
- serialize_likely_small_unsigned_integer (m, a->n_add_adj);
- if (a->n_add_adj > 0)
- serialize (m, serialize_vec_ip_adjacency, a->add_adj, a->n_add_adj);
-}
-
-/* Serialized adjacencies for arp/rewrite do not send graph next_index
- since graph hookup is not guaranteed to be the same for both sides
- of serialize/unserialize. */
-static void
-unserialize_fixup_ip4_rewrite_adjacencies (vlib_main_t * vm,
- ip_adjacency_t * adj,
- u32 n_adj)
-{
- vnet_main_t * vnm = vnet_get_main();
- u32 i, ni, sw_if_index, is_arp;
- vnet_hw_interface_t * hw;
-
- for (i = 0; i < n_adj; i++)
- {
- switch (adj[i].lookup_next_index)
- {
- case IP_LOOKUP_NEXT_REWRITE:
- case IP_LOOKUP_NEXT_ARP:
- is_arp = adj[i].lookup_next_index == IP_LOOKUP_NEXT_ARP;
- sw_if_index = adj[i].rewrite_header.sw_if_index;
- hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
- ni = is_arp ? ip4_arp_node.index : ip4_rewrite_node.index;
- adj[i].rewrite_header.node_index = ni;
- adj[i].rewrite_header.next_index = vlib_node_add_next (vm, ni, hw->output_node_index);
- if (is_arp)
- vnet_rewrite_for_sw_interface
- (vnm,
- VNET_L3_PACKET_TYPE_ARP,
- sw_if_index,
- ni,
- VNET_REWRITE_FOR_SW_INTERFACE_ADDRESS_BROADCAST,
- &adj[i].rewrite_header,
- sizeof (adj->rewrite_data));
- break;
-
- default:
- break;
- }
- }
-}
-
-static void unserialize_ip4_add_del_route_msg (serialize_main_t * m, va_list * va)
-{
- ip4_main_t * i4m = &ip4_main;
- ip4_add_del_route_args_t a;
-
- a.table_index_or_table_id = unserialize_likely_small_unsigned_integer (m);
- a.flags = unserialize_likely_small_unsigned_integer (m);
- unserialize (m, unserialize_ip4_address_and_length, &a.dst_address, &a.dst_address_length);
- a.adj_index = unserialize_likely_small_unsigned_integer (m);
- a.n_add_adj = unserialize_likely_small_unsigned_integer (m);
- a.add_adj = 0;
- if (a.n_add_adj > 0)
- {
- vec_resize (a.add_adj, a.n_add_adj);
- unserialize (m, unserialize_vec_ip_adjacency, a.add_adj, a.n_add_adj);
- unserialize_fixup_ip4_rewrite_adjacencies (vlib_get_main(),
- a.add_adj, a.n_add_adj);
- }
-
- /* Prevent re-re-distribution. */
- a.flags |= IP4_ROUTE_FLAG_NO_REDISTRIBUTE;
-
- ip4_add_del_route (i4m, &a);
-
- vec_free (a.add_adj);
-}
-
-MC_SERIALIZE_MSG (ip4_add_del_route_msg, static) = {
- .name = "vnet_ip4_add_del_route",
- .serialize = serialize_ip4_add_del_route_msg,
- .unserialize = unserialize_ip4_add_del_route_msg,
-};
-