blob: 701b36e2fd9a6e82f7e1b024d4d698d627e8196a [file] [log] [blame]
Neale Ranns88fc83e2017-04-05 08:11:14 -07001/*
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
20static adj_delegate_t *
21adj_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
47adj_delegate_t *
48adj_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
54void
55adj_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
68static int
69adj_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
77static void
78adj_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
92adj_delegate_t *
93adj_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 */
111typedef u8 * (*adj_delegate_format_t)(const adj_delegate_t *aed,
112 u8 *s);
113
114/**
115 * Print a delegate that represents BFD tracking
116 */
117static u8 *
118adj_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 */
131static adj_delegate_format_t aed_formatters[] =
132{
133 [ADJ_DELEGATE_BFD] = adj_delegate_fmt_bfd,
134};
135
136u8 *
137format_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}