FD.io VPP  v18.04-17-g3a0d853
Vector Packet Processing
adj_bfd.c
Go to the documentation of this file.
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/bfd/bfd_main.h>
17 
18 #include <vnet/adj/adj_delegate.h>
19 #include <vnet/adj/adj_nbr.h>
20 #include <vnet/fib/fib_walk.h>
21 
22 /**
23  * Distillation of the BFD session states into a go/no-go for using
24  * the associated tracked adjacency
25  */
26 typedef enum adj_bfd_state_t_
27 {
31 
32 /**
33  * BFD delegate daa
34  */
35 typedef struct adj_bfd_delegate_t_
36 {
37  /**
38  * BFD session state
39  */
41 
42  /**
43  * BFD session index
44  */
47 
48 /**
49  * Pool of delegates
50 */
52 
53 static inline adj_bfd_delegate_t*
55 {
56  if (NULL != ad)
57  {
58  return (pool_elt_at_index(abd_pool, ad->ad_index));
59  }
60  return (NULL);
61 }
62 
63 static inline const adj_bfd_delegate_t*
65 {
66  if (NULL != ad)
67  {
68  return (pool_elt_at_index(abd_pool, ad->ad_index));
69  }
70  return (NULL);
71 }
72 
73 static adj_bfd_state_t
75 {
76  switch (bstate)
77  {
78  case BFD_STATE_up:
79  return (ADJ_BFD_STATE_UP);
80  case BFD_STATE_down:
81  case BFD_STATE_admin_down:
82  case BFD_STATE_init:
83  return (ADJ_BFD_STATE_DOWN);
84  }
85  return (ADJ_BFD_STATE_DOWN);
86 }
87 
88 static void
90 {
91  /*
92  * initiate a backwalk of dependent children
93  * to notify of the state change of this adj.
94  */
97  };
99 }
100 
101 /**
102  * @brief Callback function registered with BFD module to receive notifications
103  * of the CRUD of BFD sessions
104  * would be static but for the fact it's called from the unit-tests
105  */
106 void
108  const bfd_session_t *session)
109 {
110  const bfd_udp_key_t *key;
111  adj_bfd_delegate_t *abd;
112  fib_protocol_t fproto;
113  adj_delegate_t *aed;
114  adj_index_t ai;
115 
116  if (BFD_HOP_TYPE_SINGLE != session->hop_type)
117  {
118  /*
119  * multi-hop BFD sessions attach directly to the FIB entry
120  * single-hop adj to the associate adjacency.
121  */
122  return;
123  }
124 
125  key = &session->udp.key;
126 
127  fproto = (ip46_address_is_ip4 (&key->peer_addr) ?
130 
131  /*
132  * find the adj that corresponds to the BFD session.
133  */
134  ai = adj_nbr_add_or_lock(fproto,
135  fib_proto_to_link(fproto),
136  &key->peer_addr,
137  key->sw_if_index);
138 
139  switch (event)
140  {
141  case BFD_LISTEN_EVENT_CREATE:
142  /*
143  * The creation of a new session
144  */
145  if ((ADJ_INDEX_INVALID != ai) &&
146  (aed = adj_delegate_get(adj_get(ai),
148  {
149  /*
150  * already got state for this adj
151  */
152  }
153  else
154  {
155  /*
156  * lock the adj. add the delegate.
157  * Lockinging the adj prevents it being removed and thus maintains
158  * the BFD derived states
159  */
160  adj_lock(ai);
161 
162  /*
163  * allocate and init a new delegate struct
164  */
165  pool_get(abd_pool, abd);
166 
167  /*
168  * pretend the session is up and skip the walk.
169  * If we set it down then we get traffic loss on new children.
170  * if we walk then we lose traffic for existing children. Wait
171  * for the first BFD UP/DOWN before we let the session's state
172  * influence forwarding.
173  */
175  abd->abd_index = session->bs_idx;
176 
177  adj_delegate_add(adj_get(ai), ADJ_DELEGATE_BFD, abd - abd_pool);
178  }
179  break;
180 
181  case BFD_LISTEN_EVENT_UPDATE:
182  /*
183  * state change up/dowm and
184  */
186 
187  if (NULL != abd)
188  {
191  }
192  /*
193  * else
194  * not an adj with BFD state
195  */
196  break;
197 
198  case BFD_LISTEN_EVENT_DELETE:
199  /*
200  * session has been removed.
201  */
203 
204  if (NULL != abd)
205  {
206  /*
207  * has an associated BFD tracking delegate
208  * remove the BFD tracking deletgate, update children, then
209  * unlock the adj
210  */
212  pool_put(abd_pool, abd);
213 
215  adj_unlock(ai);
216  }
217  /*
218  * else
219  * no BFD associated state
220  */
221  break;
222  }
223 
224  /*
225  * unlock match of the add-or-lock at the start
226  */
227  adj_unlock(ai);
228 }
229 
230 int
232 {
233  const adj_bfd_delegate_t *abd;
234 
236 
237  if (NULL == abd)
238  {
239  /*
240  * no BFD tracking - resolved
241  */
242  return (!0);
243  }
244  else
245  {
246  /*
247  * defer to the state of the BFD tracking
248  */
249  return (ADJ_BFD_STATE_UP == abd->abd_state);
250  }
251 }
252 
253 /**
254  * Print a delegate that represents BFD tracking
255  */
256 static u8 *
258 {
260 
261  s = format(s, "BFD:[state:%d index:%d]",
262  abd->abd_state,
263  abd->abd_index);
264 
265  return (s);
266 }
267 
268 const static adj_delegate_vft_t adj_delegate_vft = {
270 };
271 
272 static clib_error_t *
274 {
275  clib_error_t * error = NULL;
276 
277  if ((error = vlib_call_init_function (vm, bfd_main_init)))
278  return (error);
279 
281 
282  adj_delegate_register_type (ADJ_DELEGATE_BFD, &adj_delegate_vft);
283 
284  return (error);
285 }
286 
static const adj_bfd_delegate_t * adj_bfd_from_const_base(const adj_delegate_t *ad)
Definition: adj_bfd.c:64
void adj_lock(adj_index_t adj_index)
Take a reference counting lock on the adjacency.
Definition: adj.c:223
#define NULL
Definition: clib.h:55
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:227
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
static ip_adjacency_t * adj_get(adj_index_t adj_index)
Get a pointer to an adjacency object from its index.
Definition: adj.h:376
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
adj_bfd_state_t_
Distillation of the BFD session states into a go/no-go for using the associated tracked adjacency...
Definition: adj_bfd.c:26
void fib_walk_sync(fib_node_type_t parent_type, fib_node_index_t parent_index, fib_node_back_walk_ctx_t *ctx)
Back walk all the children of a FIB node.
Definition: fib_walk.c:727
void adj_unlock(adj_index_t adj_index)
Release a reference counting lock on the adjacency.
Definition: adj.c:240
Adj delegate.
Definition: adj_delegate.h:44
int adj_bfd_is_up(adj_index_t ai)
Definition: adj_bfd.c:231
#define vlib_call_init_function(vm, x)
Definition: init.h:162
static adj_bfd_state_t adj_bfd_bfd_state_to_fib(bfd_state_e bstate)
Definition: adj_bfd.c:74
struct adj_bfd_delegate_t_ adj_bfd_delegate_t
BFD delegate daa.
bfd_udp_key_t key
key identifying this session
Definition: bfd_udp.h:47
#define ADJ_INDEX_INVALID
Invalid ADJ index - used when no adj is known likewise blazoned capitals INVALID speak volumes where ...
Definition: adj_types.h:36
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:461
enum adj_bfd_state_t_ adj_bfd_state_t
Distillation of the BFD session states into a go/no-go for using the associated tracked adjacency...
int adj_delegate_add(ip_adjacency_t *adj, adj_delegate_type_t adt, index_t adi)
Add a delegate to an adjacency.
Definition: adj_delegate.c:107
BFD global declarations.
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:273
static void adj_bfd_update_walk(adj_index_t ai)
Definition: adj_bfd.c:89
bfd_udp_session_t udp
Definition: bfd_main.h:236
#define ip46_address_is_ip4(ip46)
Definition: ip6_packet.h:76
vlib_main_t * vm
Definition: buffer.c:294
index_t ad_index
The index passed by the provider to identify its delegate instance.
Definition: adj_delegate.h:60
static clib_error_t * adj_bfd_main_init(vlib_main_t *vm)
Definition: adj_bfd.c:273
u32 adj_index_t
An index for adjacencies.
Definition: adj_types.h:30
bfd_state_e
Definition: bfd_protocol.h:195
Context passed between object during a back walk.
Definition: fib_node.h:199
BFD session state.
Definition: adj_delegate.h:38
void adj_delegate_register_type(adj_delegate_type_t type, const adj_delegate_vft_t *vft)
adj_delegate_register_type
Definition: adj_delegate.c:171
unsigned int u32
Definition: types.h:88
adj_delegate_t * adj_delegate_get(const ip_adjacency_t *adj, adj_delegate_type_t type)
Get a delegate from an adjacency.
Definition: adj_delegate.c:58
long ctx[MAX_CONNS]
Definition: main.c:126
adj_delegate_format_t adv_format
Definition: adj_delegate.h:78
bfd_hop_type_e hop_type
BFD hop type.
Definition: bfd_main.h:95
static adj_bfd_delegate_t * adj_bfd_from_base(adj_delegate_t *ad)
Definition: adj_bfd.c:54
static u8 * adj_delegate_fmt_bfd(const adj_delegate_t *aed, u8 *s)
Print a delegate that represents BFD tracking.
Definition: adj_bfd.c:257
bfd_state_e local_state
session state
Definition: bfd_main.h:89
static adj_bfd_delegate_t * abd_pool
Pool of delegates.
Definition: adj_bfd.c:51
void bfd_register_listener(bfd_notify_fn_t fn)
Register a callback function to receive session notifications.
Definition: bfd_main.c:1139
BFD delegate daa.
Definition: adj_bfd.c:35
unsigned char u8
Definition: types.h:56
An ADJ delegate virtual function table.
Definition: adj_delegate.h:77
u32 bs_idx
index in bfd_main.sessions pool
Definition: bfd_main.h:86
adj_index_t adj_nbr_add_or_lock(fib_protocol_t nh_proto, vnet_link_t link_type, const ip46_address_t *nh_addr, u32 sw_if_index)
Neighbour Adjacency sub-type.
Definition: adj_nbr.c:214
adj_bfd_state_t abd_state
BFD session state.
Definition: adj_bfd.c:40
vnet_link_t fib_proto_to_link(fib_protocol_t proto)
Convert from a protocol to a link type.
Definition: fib_types.c:270
void adj_bfd_notify(bfd_listen_event_e event, const bfd_session_t *session)
Callback function registered with BFD module to receive notifications of the CRUD of BFD sessions wou...
Definition: adj_bfd.c:107
void adj_delegate_remove(adj_index_t ai, adj_delegate_type_t type)
Remove a delegate from an adjacency.
Definition: adj_delegate.c:65
static clib_error_t * bfd_main_init(vlib_main_t *vm)
Definition: bfd_main.c:1150
bfd_listen_event_e
Definition: bfd_main.h:248
u32 abd_index
BFD session index.
Definition: adj_bfd.c:45