BFD-FIB interactions
[vpp.git] / src / vnet / adj / adj_delegate.c
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <vnet/adj/adj_delegate.h>
17 #include <vnet/adj/adj.h>
18 #include <vnet/adj/adj_internal.h>
19
20 static adj_delegate_t *
21 adj_delegate_find_i (const ip_adjacency_t *adj,
22                      adj_delegate_type_t type,
23                      u32 *index)
24 {
25     adj_delegate_t *delegate;
26     int ii;
27
28     ii = 0;
29     vec_foreach(delegate, adj->ia_delegates)
30     {
31         if (delegate->ad_type == type)
32         {
33             if (NULL != index)
34                 *index = ii;
35
36             return (delegate);
37         }
38         else
39         {
40             ii++;
41         }
42     }
43
44     return (NULL);
45 }
46
47 adj_delegate_t *
48 adj_delegate_get (const ip_adjacency_t *adj,
49                   adj_delegate_type_t type)
50 {
51     return (adj_delegate_find_i(adj, type, NULL));
52 }
53
54 void
55 adj_delegate_remove (ip_adjacency_t *adj,
56                      adj_delegate_type_t type)
57 {
58     adj_delegate_t *aed;
59     u32 index = ~0;
60
61     aed = adj_delegate_find_i(adj, type, &index);
62
63     ASSERT(NULL != aed);
64
65     vec_del1(adj->ia_delegates, index);
66 }
67
68 static int
69 adj_delegate_cmp_for_sort (void * v1,
70                            void * v2)
71 {
72     adj_delegate_t *delegate1 = v1, *delegate2 = v2;
73
74     return (delegate1->ad_type - delegate2->ad_type);
75 }
76
77 static void
78 adj_delegate_init (ip_adjacency_t *adj,
79                    adj_delegate_type_t type)
80
81 {
82     adj_delegate_t delegate = {
83         .ad_adj_index = adj_get_index(adj),
84         .ad_type = type,
85     };
86
87     vec_add1(adj->ia_delegates, delegate);
88     vec_sort_with_function(adj->ia_delegates,
89                            adj_delegate_cmp_for_sort);
90 }
91
92 adj_delegate_t *
93 adj_delegate_find_or_add (ip_adjacency_t *adj,
94                           adj_delegate_type_t adt)
95 {
96     adj_delegate_t *delegate;
97
98     delegate = adj_delegate_get(adj, adt);
99
100     if (NULL == delegate)
101     {
102         adj_delegate_init(adj, adt);
103     }
104
105     return (adj_delegate_get(adj, adt));
106 }
107
108 /**
109  * typedef for printing a delegate
110  */
111 typedef u8 * (*adj_delegate_format_t)(const adj_delegate_t *aed,
112                                       u8 *s);
113
114 /**
115  * Print a delegate that represents BFD tracking
116  */
117 static u8 *
118 adj_delegate_fmt_bfd (const adj_delegate_t *aed,
119                       u8 *s)
120 {
121     s = format(s, "BFD:[state:%d index:%d]",
122                aed->ad_bfd_state,
123                aed->ad_bfd_index);
124
125     return (s);
126 }
127
128 /**
129  * A delegate type to formatter map
130  */
131 static adj_delegate_format_t aed_formatters[] =
132 {
133     [ADJ_DELEGATE_BFD] = adj_delegate_fmt_bfd,
134 };
135
136 u8 *
137 format_adj_deletegate (u8 * s, va_list * args)
138 {
139     adj_delegate_t *aed;
140
141     aed = va_arg (*args, adj_delegate_t *);
142
143     return (aed_formatters[aed->ad_type](aed, s));
144 }