aboutsummaryrefslogtreecommitdiffstats
path: root/test/vpp_neighbor.py
blob: 5919cf8e48ba80d212985d95c7a5e0a65fcadce4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
"""
  Neighbour Entries

  object abstractions for ARP and ND
"""

from socket import inet_pton, inet_ntop, AF_INET, AF_INET6
from vpp_object import *
from util import mactobinary


def find_nbr(test, sw_if_index, ip_addr, is_static=0, inet=AF_INET):
    nbrs = test.vapi.ip_neighbor_dump(sw_if_index,
                                      is_ipv6=1 if AF_INET6 == inet else 0)
    if inet == AF_INET:
        s = 4
    else:
        s = 16
    nbr_addr = inet_pton(inet, ip_addr)

    for n in nbrs:
        if nbr_addr == n.ip_address[:s] \
           and is_static == n.is_static:
            return True
    return False


class VppNeighbor(VppObject):
    """
    ARP Entry
    """

    def __init__(self, test, sw_if_index, mac_addr, nbr_addr,
                 af=AF_INET, is_static=False, is_no_fib_entry=0):
        self._test = test
        self.sw_if_index = sw_if_index
        self.mac_addr = mactobinary(mac_addr)
        self.af = af
        self.is_static = is_static
        self.is_no_fib_entry = is_no_fib_entry
        self.nbr_addr = inet_pton(af, nbr_addr)

    def add_vpp_config(self):
        self._test.vapi.ip_neighbor_add_del(
            self.sw_if_index,
            self.mac_addr,
            self.nbr_addr,
            is_add=1,
            is_ipv6=1 if AF_INET6 == self.af else 0,
            is_static=self.is_static,
            is_no_adj_fib=self.is_no_fib_entry)
        self._test.registry.register(self, self._test.logger)

    def remove_vpp_config(self):
        self._test.vapi.ip_neighbor_add_del(
            self.sw_if_index,
            self.mac_addr,
            self.nbr_addr,
            is_ipv6=1 if AF_INET6 == self.af else 0,
            is_add=0,
            is_static=self.is_static)

    def query_vpp_config(self):
        dump = self._test.vapi.ip_neighbor_dump(
            self.sw_if_index,
            is_ipv6=1 if AF_INET6 == self.af else 0)
        for n in dump:
            if self.nbr_addr == n.ip_address \
               and self.is_static == n.is_static:
                return True
        return False

    def __str__(self):
        return self.object_id()

    def object_id(self):
        return ("%d:%s"
                % (self.sw_if_index,
                   inet_ntop(self.af, self.nbr_addr)))
/span> int rv = 0; vnet_vxlan_gpe_add_del_tunnel_args_t _a, *a = &_a; u32 encap_fib_index, decap_fib_index; u8 protocol; uword *p; ip4_main_t *im = &ip4_main; u32 sw_if_index = ~0; p = hash_get (im->fib_index_by_table_id, ntohl (mp->encap_vrf_id)); if (!p) { rv = VNET_API_ERROR_NO_SUCH_FIB; goto out; } encap_fib_index = p[0]; protocol = mp->protocol; /* Interpret decap_vrf_id as an opaque if sending to other-than-ip4-input */ if (protocol == VXLAN_GPE_INPUT_NEXT_IP4_INPUT) { p = hash_get (im->fib_index_by_table_id, ntohl (mp->decap_vrf_id)); if (!p) { rv = VNET_API_ERROR_NO_SUCH_INNER_FIB; goto out; } decap_fib_index = p[0]; } else { decap_fib_index = ntohl (mp->decap_vrf_id); } /* Check src & dst are different */ if ((mp->is_ipv6 && memcmp (mp->local, mp->remote, 16) == 0) || (!mp->is_ipv6 && memcmp (mp->local, mp->remote, 4) == 0)) { rv = VNET_API_ERROR_SAME_SRC_DST; goto out; } clib_memset (a, 0, sizeof (*a)); a->is_add = mp->is_add; a->is_ip6 = mp->is_ipv6; /* ip addresses sent in network byte order */ if (a->is_ip6) { clib_memcpy (&(a->local.ip6), mp->local, 16); clib_memcpy (&(a->remote.ip6), mp->remote, 16); } else { clib_memcpy (&(a->local.ip4), mp->local, 4); clib_memcpy (&(a->remote.ip4), mp->remote, 4); } a->mcast_sw_if_index = ntohl (mp->mcast_sw_if_index); a->encap_fib_index = encap_fib_index; a->decap_fib_index = decap_fib_index; a->protocol = protocol; a->vni = ntohl (mp->vni); rv = vnet_vxlan_gpe_add_del_tunnel (a, &sw_if_index); out: /* *INDENT-OFF* */ REPLY_MACRO2(VL_API_VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, ({ rmp->sw_if_index = ntohl (sw_if_index); })); /* *INDENT-ON* */ } static void send_vxlan_gpe_tunnel_details (vxlan_gpe_tunnel_t * t, vl_api_registration_t * reg, u32 context) { vl_api_vxlan_gpe_tunnel_details_t *rmp; ip4_main_t *im4 = &ip4_main; ip6_main_t *im6 = &ip6_main; u8 is_ipv6 = !(t->flags & VXLAN_GPE_TUNNEL_IS_IPV4); rmp = vl_msg_api_alloc (sizeof (*rmp)); clib_memset (rmp, 0, sizeof (*rmp)); rmp->_vl_msg_id = ntohs (VL_API_VXLAN_GPE_TUNNEL_DETAILS); if (is_ipv6) { memcpy (rmp->local, &(t->local.ip6.as_u8), 16); memcpy (rmp->remote, &(t->remote.ip6.as_u8), 16); rmp->encap_vrf_id = htonl (im6->fibs[t->encap_fib_index].ft_table_id); rmp->decap_vrf_id = htonl (im6->fibs[t->decap_fib_index].ft_table_id); } else { memcpy (rmp->local, &(t->local.ip4.as_u8), 4); memcpy (rmp->remote, &(t->remote.ip4.as_u8), 4); rmp->encap_vrf_id = htonl (im4->fibs[t->encap_fib_index].ft_table_id); rmp->decap_vrf_id = htonl (im4->fibs[t->decap_fib_index].ft_table_id); } rmp->mcast_sw_if_index = htonl (t->mcast_sw_if_index); rmp->vni = htonl (t->vni); rmp->protocol = t->protocol; rmp->sw_if_index = htonl (t->sw_if_index); rmp->is_ipv6 = is_ipv6; rmp->context = context; vl_api_send_msg (reg, (u8 *) rmp); } static void vl_api_vxlan_gpe_tunnel_dump_t_handler (vl_api_vxlan_gpe_tunnel_dump_t * mp) { vl_api_registration_t *reg; vxlan_gpe_main_t *vgm = &vxlan_gpe_main; vxlan_gpe_tunnel_t *t; u32 sw_if_index; reg = vl_api_client_index_to_registration (mp->client_index); if (!reg) return; sw_if_index = ntohl (mp->sw_if_index); if (~0 == sw_if_index) { /* *INDENT-OFF* */ pool_foreach (t, vgm->tunnels, ({ send_vxlan_gpe_tunnel_details(t, reg, mp->context); })); /* *INDENT-ON* */ } else { if ((sw_if_index >= vec_len (vgm->tunnel_index_by_sw_if_index)) || (~0 == vgm->tunnel_index_by_sw_if_index[sw_if_index])) { return; } t = &vgm->tunnels[vgm->tunnel_index_by_sw_if_index[sw_if_index]]; send_vxlan_gpe_tunnel_details (t, reg, mp->context); } } /* * vpe_api_hookup * Add vpe's API message handlers to the table. * vlib has already mapped shared memory and * added the client registration handlers. * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process() */ #define vl_msg_name_crc_list #include <vnet/vnet_all_api_h.h> #undef vl_msg_name_crc_list static void setup_message_id_table (api_main_t * am) { #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id); foreach_vl_msg_name_crc_vxlan_gpe; #undef _ } static clib_error_t * vxlan_gpe_api_hookup (vlib_main_t * vm) { api_main_t *am = &api_main; #define _(N,n) \ vl_msg_api_set_handlers(VL_API_##N, #n, \ vl_api_##n##_t_handler, \ vl_noop_handler, \ vl_api_##n##_t_endian, \ vl_api_##n##_t_print, \ sizeof(vl_api_##n##_t), 1); foreach_vpe_api_msg; #undef _ am->api_trace_cfg[VL_API_VXLAN_GPE_ADD_DEL_TUNNEL].size += 17 * sizeof (u32); /* * Set up the (msg_name, crc, message-id) table */ setup_message_id_table (am); return 0; } VLIB_API_INIT_FUNCTION (vxlan_gpe_api_hookup); /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "gnu") * End: */