X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fadj%2Fadj_delegate.c;h=87a83fb42399841c4acdd2cec54185a6e5c6d632;hb=14053c9dbd75182f5302f7388d17508f3930f7ce;hp=701b36e2fd9a6e82f7e1b024d4d698d627e8196a;hpb=909c26bda66313b86168dda31003f76410c1d746;p=vpp.git diff --git a/src/vnet/adj/adj_delegate.c b/src/vnet/adj/adj_delegate.c index 701b36e2fd9..87a83fb4239 100644 --- a/src/vnet/adj/adj_delegate.c +++ b/src/vnet/adj/adj_delegate.c @@ -17,6 +17,16 @@ #include #include +/* + * The per-type vector of virtual function tables + */ +static adj_delegate_vft_t *ad_vfts; + +/** + * The value of the last dynamically allocated delegate value + */ +static adj_delegate_type_t ad_max_id = ADJ_DELEGATE_LAST; + static adj_delegate_t * adj_delegate_find_i (const ip_adjacency_t *adj, adj_delegate_type_t type, @@ -52,12 +62,14 @@ adj_delegate_get (const ip_adjacency_t *adj, } void -adj_delegate_remove (ip_adjacency_t *adj, +adj_delegate_remove (adj_index_t ai, adj_delegate_type_t type) { + ip_adjacency_t *adj; adj_delegate_t *aed; u32 index = ~0; + adj = adj_get(ai); aed = adj_delegate_find_i(adj, type, &index); ASSERT(NULL != aed); @@ -69,29 +81,32 @@ static int adj_delegate_cmp_for_sort (void * v1, void * v2) { - adj_delegate_t *delegate1 = v1, *delegate2 = v2; + adj_delegate_t *aed1 = v1, *aed2 = v2; - return (delegate1->ad_type - delegate2->ad_type); + return (aed1->ad_type - aed2->ad_type); } static void adj_delegate_init (ip_adjacency_t *adj, - adj_delegate_type_t type) + adj_delegate_type_t adt, + index_t adi) { - adj_delegate_t delegate = { - .ad_adj_index = adj_get_index(adj), - .ad_type = type, + adj_delegate_t aed = { + .ad_adj_index = adj_get_index(adj), + .ad_type = adt, + .ad_index = adi, }; - vec_add1(adj->ia_delegates, delegate); + vec_add1(adj->ia_delegates, aed); vec_sort_with_function(adj->ia_delegates, adj_delegate_cmp_for_sort); } -adj_delegate_t * -adj_delegate_find_or_add (ip_adjacency_t *adj, - adj_delegate_type_t adt) +int +adj_delegate_add (ip_adjacency_t *adj, + adj_delegate_type_t adt, + index_t adi) { adj_delegate_t *delegate; @@ -99,46 +114,101 @@ adj_delegate_find_or_add (ip_adjacency_t *adj, if (NULL == delegate) { - adj_delegate_init(adj, adt); + adj_delegate_init(adj, adt, adi); + } + else + { + return (-1); } - return (adj_delegate_get(adj, adt)); + return (0); } -/** - * typedef for printing a delegate - */ -typedef u8 * (*adj_delegate_format_t)(const adj_delegate_t *aed, - u8 *s); +void +adj_delegate_adj_deleted (ip_adjacency_t *adj) +{ + adj_delegate_t *aed; -/** - * Print a delegate that represents BFD tracking - */ -static u8 * -adj_delegate_fmt_bfd (const adj_delegate_t *aed, - u8 *s) + vec_foreach(aed, adj->ia_delegates) + { + if (ad_vfts[aed->ad_type].adv_adj_deleted) + { + ad_vfts[aed->ad_type].adv_adj_deleted(aed); + } + } + + vec_reset_length(adj->ia_delegates); +} + +void +adj_delegate_adj_created (ip_adjacency_t *adj) +{ + adj_delegate_vft_t *vft; + + vec_foreach(vft, ad_vfts) + { + if (vft->adv_adj_created) + { + vft->adv_adj_created(adj_get_index(adj)); + } + } +} + +u8* +adj_delegate_format (u8* s, ip_adjacency_t *adj) { - s = format(s, "BFD:[state:%d index:%d]", - aed->ad_bfd_state, - aed->ad_bfd_index); + adj_delegate_t *aed; + + vec_foreach(aed, adj->ia_delegates) + { + if (ad_vfts[aed->ad_type].adv_format) + { + s = format(s, "\n {"); + s = ad_vfts[aed->ad_type].adv_format(aed, s); + s = format(s, "}"); + } + else + { + s = format(s, "\n {unknown delegate}"); + } + } return (s); } /** - * A delegate type to formatter map + * adj_delegate_register_type + * + * Register the function table for a given type */ -static adj_delegate_format_t aed_formatters[] = +void +adj_delegate_register_type (adj_delegate_type_t type, + const adj_delegate_vft_t *vft) { - [ADJ_DELEGATE_BFD] = adj_delegate_fmt_bfd, -}; + /* + * assert that one only registration is made per-node type + */ + if (vec_len(ad_vfts) > type) + ASSERT(NULL == ad_vfts[type].adv_adj_deleted); + + vec_validate(ad_vfts, type); + ad_vfts[type] = *vft; +} -u8 * -format_adj_deletegate (u8 * s, va_list * args) +/** + * adj_delegate_register_new_type + * + * Register the function table for a new type + */ +adj_delegate_type_t +adj_delegate_register_new_type (const adj_delegate_vft_t *vft) { - adj_delegate_t *aed; + adj_delegate_type_t type; + + type = ++ad_max_id; - aed = va_arg (*args, adj_delegate_t *); + vec_validate(ad_vfts, type); + ad_vfts[type] = *vft; - return (aed_formatters[aed->ad_type](aed, s)); + return (type); }