vpp-20.01-ip_neighbor

/
* *INDENT-OFF* */ typedef CLIB_PACKED (struct { mac_address_t mac; ip4_address_t ip4; }) ethernet_arp_ip4_over_ethernet_address_t; /* *INDENT-ON* */ /* *INDENT-OFF* */ typedef CLIB_PACKED (struct { u8 mac[6]; ip4_address_t ip4; }) ethernet_arp_ip4_over_ethernet_address_t; /* *INDENT-ON* */

  

ip_neighbor_add
/**
 * @brief Control Plane hook to remove an ARP entry
 */
int
vnet_arp_unset_ip4_over_ethernet (vnet_main_t * vnm,
                                  u32 sw_if_index, void *a_arg)
{
  ethernet_arp_ip4_over_ethernet_address_t *a = a_arg;
  vnet_arp_set_ip4_over_ethernet_rpc_args_t args;

  args.sw_if_index = sw_if_index;
  args.flags = ETHERNET_ARP_ARGS_REMOVE;
  clib_memcpy (&args.a, a, sizeof (*a));

  vl_api_rpc_call_main_thread (set_ip4_over_ethernet_rpc_callback,
                               (u8 *) & args, sizeof (args));
  return 0;
}
add_ip4_neighbor (test_main_t * tm, int add_del)
{
  vl_api_ip_neighbor_add_del_t *mp;
  u32 tmp;

  mp = vl_msg_api_alloc (sizeof (*mp));
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = ntohs (VL_API_IP_NEIGHBOR_ADD_DEL);
  mp->client_index = tm->my_client_index;
  mp->context = 0xdeadbeef;
  mp->sw_if_index = ntohl (6);
  mp->is_add = add_del;

  clib_memset (mp->mac_address, 0xbe, sizeof (mp->mac_address));

  tmp = ntohl (0x0101010a);
  clib_memcpy (mp->dst_address, &tmp, 4);

  vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *) & mp);
}
vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t * mp,
                                      vlib_main_t * vm)
vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t * mp,
                                      vlib_main_t * vm)
{

if (mp->is_add)
        rv = vnet_arp_set_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index),
                                             &a, mp->is_static,
                                             mp->is_no_adj_fib);
      else
        rv =
          vnet_arp_unset_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index), &a);
20.01

vl_api_ip_neighbor_add_del_t_handler
if (mp->is_add)
    rv = ip_neighbor_add (&ip, type, &mac,
                          ntohl (mp->neighbor.sw_if_index),
                          flags, &stats_index);
  else
    rv = ip_neighbor_del (&ip, type, ntohl (mp->neighbor.sw_if_index));
ip_neighbor_learn (const ip_neighbor_learn_t * l)
{
  ip_neighbor_add (&l->ip, l->type, &l->mac, l->sw_if_index,
                   IP_NEIGHBOR_FLAG_DYNAMIC, NULL);
}
 flags = ip_neighbor_flags_decode (mp->neighbor.flags);
  type = ip_address_decode (&mp->neighbor.ip_address, &ip);
  mac_address_decode (mp->neighbor.mac_address, &mac);

  /* must be static or dynamic, default to dynamic */
  if (!(flags & IP_NEIGHBOR_FLAG_STATIC) &&
      !(flags & IP_NEIGHBOR_FLAG_DYNAMIC))
    flags |= IP_NEIGHBOR_FLAG_DYNAMIC;
static void
vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t * mp,
                      vlib_main_t * vm)
{
  vl_api_ip_neighbor_add_del_reply_t *rmp;
  ip_neighbor_flags_t flags;
  u32 stats_index = ~0;
  ip46_address_t ip = ip46_address_initializer;
  mac_address_t mac;
  ip46_type_t type;
  int rv;

  VALIDATE_SW_IF_INDEX ((&mp->neighbor));

  flags = ip_neighbor_flags_decode (mp->neighbor.flags);
  type = ip_address_decode (&mp->neighbor.ip_address, &ip);
  mac_address_decode (mp->neighbor.mac_address, &mac);

  /* must be static or dynamic, default to dynamic */
  if (!(flags & IP_NEIGHBOR_FLAG_STATIC) &&
      !(flags & IP_NEIGHBOR_FLAG_DYNAMIC))
    flags |= IP_NEIGHBOR_FLAG_DYNAMIC;

  /*
   * there's no validation here of the ND/ARP entry being added.
   * The expectation is that the FIB will ensure that nothing bad
   * will come of adding bogus entries.
   */
  if (mp->is_add)
    rv = ip_neighbor_add (&ip, type, &mac,
              ntohl (mp->neighbor.sw_if_index),
              flags, &stats_index);
  else
    rv = ip_neighbor_del (&ip, type, ntohl (mp->neighbor.sw_if_index));

  BAD_SW_IF_INDEX_LABEL;

  /* *INDENT-OFF* */
  REPLY_MACRO2 (VL_API_IP_NEIGHBOR_ADD_DEL_REPLY,
  ({
    rmp->stats_index = htonl (stats_index);
  }));
  /* *INDENT-ON* */
}
void
add_ip4_neighbor (test_main_t * tm, int add_del)
{
  vl_api_ip_neighbor_add_del_t *mp;
  u32 tmp;

  mp = vl_msg_api_alloc (sizeof (*mp));
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = ntohs (VL_API_IP_NEIGHBOR_ADD_DEL);
  mp->client_index = tm->my_client_index;
  mp->context = 0xdeadbeef;
  mp->sw_if_index = ntohl (6);
  mp->is_add = add_del;

  clib_memset (mp->mac_address, 0xbe, sizeof (mp->mac_address));

  tmp = ntohl (0x0101010a);
  clib_memcpy (mp->dst_address, &tmp, 4);

  vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *) & mp);
}

void
add_ip6_neighbor (test_main_t * tm, int add_del)
{
  vl_api_ip_neighbor_add_del_t *mp;
  u64 tmp[2];

  mp = vl_msg_api_alloc (sizeof (*mp));
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = ntohs (VL_API_IP_NEIGHBOR_ADD_DEL);
  mp->client_index = tm->my_client_index;
  mp->context = 0xdeadbeef;
  mp->sw_if_index = ntohl (6);
  mp->is_add = add_del;
  mp->is_ipv6 = 1;

  clib_memset (mp->mac_address, 0xbe, sizeof (mp->mac_address));

  tmp[0] = clib_host_to_net_u64 (0xdb01000000000000ULL);
  tmp[1] = clib_host_to_net_u64 (0x11ULL);

  clib_memcpy (mp->dst_address, &tmp[0], 8);
  clib_memcpy (&mp->dst_address[8], &tmp[1], 8);

  vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *) & mp);
}
typedef enum __attribute__((packed)) {
    IP_API_NEIGHBOR_FLAG_NONE = 0,
    IP_API_NEIGHBOR_FLAG_STATIC = 1,
    IP_API_NEIGHBOR_FLAG_NO_FIB_ENTRY = 2,
} vl_api_ip_neighbor_flags_t;
STATIC_ASSERT(sizeof(vl_api_ip_neighbor_flags_t) == sizeof(u8), "size of API enum ip_neighbor_flags is wrong");
typedef struct __attribute__ ((packed)) _vl_api_ip_neighbor {
    vl_api_interface_index_t sw_if_index;
    vl_api_ip_neighbor_flags_t flags;
    vl_api_mac_address_t mac_address;
    vl_api_address_t ip_address;
} vl_api_ip_neighbor_t;
typedef struct __attribute__ ((packed)) _vl_api_ip_neighbor_add_del {
    u16 _vl_msg_id;
    u32 client_index;
    u32 context;
    bool is_add;
    vl_api_ip_neighbor_t neighbor;
} vl_api_ip_neighbor_add_del_t;

static void
ip_neighbor_encode (vl_api_ip_neighbor_t * api, const ip_neighbor_t * ipn)
{
api->sw_if_index = htonl (ipn->ipn_key->ipnk_sw_if_index);
api->flags = ip_neighbor_flags_encode (ipn->ipn_flags);

ip_address_encode (&ipn->ipn_key->ipnk_ip,
ipn->ipn_key->ipnk_type, &api->ip_address);
mac_address_encode (&ipn->ipn_mac, api->mac_address);
}

ip46_type_t
ip_address_decode (const vl_api_address_t * in, ip46_address_t * out)
{
  return (ip_address_union_decode (&in->un, in->af, out));
}
ip4_address_decode (const vl_api_ip4_address_t in, ip4_address_t * out)
{
  clib_memcpy (out, in, sizeof (*out));
}
void
ip4_address_encode (const ip4_address_t * in, vl_api_ip4_address_t out)
{
  clib_memcpy (out, in, sizeof (*in));
}

ip46_type_t
ip_address_decode (const vl_api_address_t * in, ip46_address_t * out)
{
return (ip_address_union_decode (&in->un, in->af, out));
}

ip_address_encode (const ip46_address_t * in,
ip46_type_t type, vl_api_address_t * out)

 
ip_neighbor_learn_dp (const ip_neighbor_learn_t * l)
{
  vl_api_rpc_call_main_thread (ip_neighbor_learn, (u8 *) l, sizeof (*l));
}
int
vnet_arp_set_ip4_over_ethernet (vnet_main_t * vnm,
                                u32 sw_if_index, void *a_arg,
                                int is_static, int is_no_fib_entry)
{
  ethernet_arp_ip4_over_ethernet_address_t *a = a_arg;
  vnet_arp_set_ip4_over_ethernet_rpc_args_t args;

  args.sw_if_index = sw_if_index;
  args.is_static = is_static;
  args.is_no_fib_entry = is_no_fib_entry;
  args.flags = 0;
  clib_memcpy (&args.a, a, sizeof (*a));

  vl_api_rpc_call_main_thread (set_ip4_over_ethernet_rpc_callback,
                               (u8 *) & args, sizeof (args));
  return 0;
}
ip_neighbor_api_init (vlib_main_t * vm)
{
/* Ask for a correctly-sized block of API message decode slots */
msg_id_base = setup_message_id_table ();

return 0;
}

 

 


/* *INDENT-OFF* */
typedef CLIB_PACKED (union ip46_address_t_ {
struct {
u32 pad[3];
ip4_address_t ip4;
};
ip6_address_t ip6;
u8 as_u8[16];
u64 as_u64[2];
}) ip46_address_t;
/* *INDENT-ON* */

 20.01

always_inline u32
arp_learn (u32 sw_if_index,
const ethernet_arp_ip4_over_ethernet_address_t * addr)
{
ip_neighbor_learn_t l = {
.ip.ip4 = addr->ip4,
.type = IP46_TYPE_IP4,
.mac = addr->mac,
.sw_if_index = sw_if_index,
};

ip_neighbor_learn_dp (&l);

return (ETHERNET_ARP_ERROR_l3_src_address_learned);
}
原文地址:https://www.cnblogs.com/dream397/p/12789828.html