X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Flisp-gpe%2Flisp_gpe_adjacency.c;h=7464af3d441485d4df6abd0e1a8c740bc6ad2c8e;hb=de5b08fb302e84142e4ba0cf0cbed4e740e4165c;hp=65006b81f1dddb4dcec75d85ff0c71a753ef4f46;hpb=82786c418ffec3eede70d747747a23153a27778d;p=vpp.git diff --git a/src/vnet/lisp-gpe/lisp_gpe_adjacency.c b/src/vnet/lisp-gpe/lisp_gpe_adjacency.c index 65006b81f1d..7464af3d441 100644 --- a/src/vnet/lisp-gpe/lisp_gpe_adjacency.c +++ b/src/vnet/lisp-gpe/lisp_gpe_adjacency.c @@ -19,12 +19,15 @@ */ #include +#include #include #include #include #include #include #include +#include +#include /** * Memory pool of all adjacencies @@ -221,9 +224,97 @@ lisp_gpe_adj_proto_from_vnet_link_type (vnet_link_t linkt) #define is_v4_packet(_h) ((*(u8*) _h) & 0xF0) == 0x40 +static lisp_afi_e +lisp_afi_from_vnet_link_type (vnet_link_t link) +{ + switch (link) + { + case VNET_LINK_IP4: + return LISP_AFI_IP; + case VNET_LINK_IP6: + return LISP_AFI_IP6; + case VNET_LINK_ETHERNET: + return LISP_AFI_MAC; + default: + return LISP_AFI_NO_ADDR; + } +} + +static void +lisp_gpe_increment_stats_counters (lisp_cp_main_t * lcm, ip_adjacency_t * adj, + vlib_buffer_t * b) +{ + lisp_gpe_main_t *lgm = vnet_lisp_gpe_get_main (); + lisp_gpe_adjacency_t *ladj; + ip_address_t rloc; + index_t lai; + u32 si, di; + gid_address_t src, dst; + uword *feip; + + ip46_address_to_ip_address (&adj->sub_type.nbr.next_hop, &rloc); + si = vnet_buffer (b)->sw_if_index[VLIB_TX]; + lai = lisp_adj_find (&rloc, si); + ASSERT (INDEX_INVALID != lai); + + ladj = pool_elt_at_index (lisp_adj_pool, lai); + + u8 *lisp_data = (u8 *) vlib_buffer_get_current (b); + + /* skip IP header */ + if (is_v4_packet (lisp_data)) + lisp_data += sizeof (ip4_header_t); + else + lisp_data += sizeof (ip6_header_t); + + /* skip UDP header */ + lisp_data += sizeof (udp_header_t); + // TODO: skip TCP? + + /* skip LISP GPE header */ + lisp_data += sizeof (lisp_gpe_header_t); + + i16 saved_current_data = b->current_data; + b->current_data = lisp_data - b->data; + + lisp_afi_e afi = lisp_afi_from_vnet_link_type (adj->ia_link); + get_src_and_dst_eids_from_buffer (lcm, b, &src, &dst, afi); + b->current_data = saved_current_data; + di = gid_dictionary_sd_lookup (&lcm->mapping_index_by_gid, &dst, &src); + if (PREDICT_FALSE (~0 == di)) + { + clib_warning ("dst mapping not found (%U, %U)", format_gid_address, + &src, format_gid_address, &dst); + return; + } + + feip = hash_get (lcm->fwd_entry_by_mapping_index, di); + if (PREDICT_FALSE (!feip)) + return; + + lisp_stats_key_t key; + memset (&key, 0, sizeof (key)); + key.fwd_entry_index = feip[0]; + key.tunnel_index = ladj->tunnel_index; + + uword *p = hash_get_mem (lgm->lisp_stats_index_by_key, &key); + ASSERT (p); + + /* compute payload length starting after GPE */ + u32 bytes = b->current_length - (lisp_data - b->data - b->current_data); + vlib_increment_combined_counter (&lgm->counters, vlib_get_thread_index (), + p[0], 1, bytes); +} + static void -lisp_gpe_fixup (vlib_main_t * vm, ip_adjacency_t * adj, vlib_buffer_t * b) +lisp_gpe_fixup (vlib_main_t * vm, + ip_adjacency_t * adj, vlib_buffer_t * b, const void *data) { + lisp_cp_main_t *lcm = vnet_lisp_cp_get_main (); + + if (lcm->flags & LISP_FLAG_STATS_ENABLED) + lisp_gpe_increment_stats_counters (lcm, adj, b); + /* Fixup the checksum and len fields in the LISP tunnel encap * that was applied at the midchain node */ ip_udp_fixup_one (vm, b, is_v4_packet (vlib_buffer_get_current (b))); @@ -258,9 +349,10 @@ lisp_gpe_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, adj_index_t ai) linkt = adj_get_link_type (ai); adj_nbr_midchain_update_rewrite (ai, lisp_gpe_fixup, + NULL, (VNET_LINK_ETHERNET == linkt ? - ADJ_MIDCHAIN_FLAG_NO_COUNT : - ADJ_MIDCHAIN_FLAG_NONE), + ADJ_FLAG_MIDCHAIN_NO_COUNT : + ADJ_FLAG_NONE), lisp_gpe_tunnel_build_rewrite (lgt, ladj, lisp_gpe_adj_proto_from_vnet_link_type (linkt)));