FD.io VPP  v20.01-48-g3e0dafb74
Vector Packet Processing
nhrp.c
Go to the documentation of this file.
1 /*
2  * nhrp.h: next-hop resolution
3  *
4  * Copyright (c) 2016 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 
19 #include <vnet/nhrp/nhrp.h>
20 #include <vnet/fib/fib_table.h>
21 #include <vnet/adj/adj_midchain.h>
22 
23 typedef struct nhrp_key_t_
24 {
25  ip46_address_t nk_peer;
27 } nhrp_key_t;
28 
30 {
34 };
35 
36 static uword *nhrp_db;
39 
40 #define NHRP_NOTIFY(_ne, _fn) { \
41  nhrp_vft_t *_vft; \
42  vec_foreach(_vft, nhrp_vfts) { \
43  if (_vft->_fn) { \
44  _vft->_fn(_ne); \
45  } \
46  } \
47 }
48 
49 u32
51 {
52  return (ne->ne_key->nk_sw_if_index);
53 }
54 
55 u32
57 {
58  return (ne->ne_fib_index);
59 }
60 
61 const ip46_address_t *
63 {
64  return (&ne->ne_key->nk_peer);
65 }
66 
67 const fib_prefix_t *
69 {
70  return (&ne->ne_nh);
71 }
72 
73 void
75 {
77 }
78 
79 static adj_walk_rc_t
81 {
82  nhrp_entry_adj_stack (ctx, ai);
83 
84  return (ADJ_WALK_RC_CONTINUE);
85 }
86 
87 static adj_walk_rc_t
89 {
91 
92  return (ADJ_WALK_RC_CONTINUE);
93 }
94 
97 {
98  return pool_elt_at_index (nhrp_pool, nei);
99 }
100 
101 nhrp_entry_t *
102 nhrp_entry_find (u32 sw_if_index, const ip46_address_t * peer)
103 {
104  nhrp_key_t nk = {
105  .nk_peer = *peer,
106  .nk_sw_if_index = sw_if_index,
107  };
108  uword *p;
109 
110  p = hash_get_mem (nhrp_db, &nk);
111 
112  if (NULL != p)
113  return nhrp_entry_get (p[0]);
114 
115  return (NULL);
116 }
117 
118 int
120  const ip46_address_t * peer,
121  u32 nh_table_id, const ip46_address_t * nh)
122 {
123  fib_protocol_t fproto;
124  nhrp_entry_t *ne;
125  u32 fib_index;
126  index_t nei;
127 
129 
130  fib_index = fib_table_find (fproto, nh_table_id);
131 
132  if (~0 == fib_index)
133  {
134  return (VNET_API_ERROR_NO_SUCH_FIB);
135  }
136 
137  ne = nhrp_entry_find (sw_if_index, peer);
138 
139  if (NULL == ne)
140  {
141  nhrp_key_t nk = {
142  .nk_peer = *peer,
143  .nk_sw_if_index = sw_if_index,
144  };
145  nhrp_entry_t *ne;
146 
147  pool_get_zero (nhrp_pool, ne);
148 
149  nei = ne - nhrp_pool;
150  ne->ne_key = clib_mem_alloc (sizeof (*ne->ne_key));
151  clib_memcpy (ne->ne_key, &nk, sizeof (*ne->ne_key));
152 
153  ip46_address_copy (&ne->ne_nh.fp_addr, nh);
154  ne->ne_nh.fp_proto = fproto;
155  ne->ne_nh.fp_len = (ne->ne_nh.fp_proto == FIB_PROTOCOL_IP4 ? 32 : 128);
156  ne->ne_fib_index = fib_index;
157 
158  hash_set_mem (nhrp_db, ne->ne_key, nei);
159 
160  adj_nbr_walk_nh (sw_if_index,
161  ne->ne_nh.fp_proto,
163 
164  NHRP_NOTIFY (ne, nv_added);
165  }
166  else
167  return (VNET_API_ERROR_ENTRY_ALREADY_EXISTS);
168 
169  return 0;
170 }
171 
172 int
173 nhrp_entry_del (u32 sw_if_index, const ip46_address_t * peer)
174 {
175  nhrp_entry_t *ne;
176 
177  ne = nhrp_entry_find (sw_if_index, peer);
178 
179  if (ne != NULL)
180  {
182 
183  adj_nbr_walk_nh (sw_if_index,
184  ne->ne_nh.fp_proto,
186 
187  NHRP_NOTIFY (ne, nv_deleted);
188 
189  clib_mem_free (ne->ne_key);
190  pool_put (nhrp_pool, ne);
191  }
192  else
193  return (VNET_API_ERROR_ENTRY_ALREADY_EXISTS);
194 
195  return 0;
196 }
197 
198 u8 *
199 format_nhrp_entry (u8 * s, va_list * args)
200 {
201  index_t nei = va_arg (*args, index_t);
202  vnet_main_t *vnm = vnet_get_main ();
203  nhrp_entry_t *ne;
204 
205  ne = nhrp_entry_get (nei);
206 
207  s = format (s, "[%d] ", nei);
208  s = format (s, "%U:", format_vnet_sw_if_index_name,
209  vnm, ne->ne_key->nk_sw_if_index);
210  s = format (s, " %U", format_ip46_address,
211  &ne->ne_key->nk_peer, IP46_TYPE_ANY);
212  s = format (s, " via [%d]:%U",
214  format_fib_prefix, &ne->ne_nh);
215 
216  return (s);
217 }
218 
219 void
221 {
222  index_t nei;
223 
224  /* *INDENT-OFF* */
225  pool_foreach_index(nei, nhrp_pool,
226  ({
227  fn(nei, ctx);
228  }));
229  /* *INDENT-ON* */
230 }
231 
232 void
234 {
235  index_t nei;
236 
237  /* *INDENT-OFF* */
238  pool_foreach_index(nei, nhrp_pool,
239  ({
240  if (sw_if_index == nhrp_entry_get_sw_if_index(nhrp_entry_get(nei)))
241  fn(nei, ctx);
242  }));
243  /* *INDENT-ON* */
244 }
245 
246 void
248 {
249  vec_add1 (nhrp_vfts, *vft);
250 }
251 
252 static clib_error_t *
254 {
255  nhrp_db = hash_create_mem (0, sizeof (nhrp_key_t), sizeof (u32));
256 
257  return (NULL);
258 }
259 
261 
262 /*
263  * fd.io coding-style-patch-verification: ON
264  *
265  * Local Variables:
266  * eval: (c-set-style "gnu")
267  * End:
268  */
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:212
void adj_nbr_walk_nh(u32 sw_if_index, fib_protocol_t adj_nh_proto, const ip46_address_t *nh, adj_walk_cb_t cb, void *ctx)
Walk adjacencies on a link with a given next-hop.
Definition: adj_nbr.c:668
Definition: nhrp.c:29
#define NHRP_NOTIFY(_ne, _fn)
Definition: nhrp.c:40
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
#define pool_get_zero(P, E)
Allocate an object E from a pool P and zero it.
Definition: pool.h:240
vl_api_fib_path_nh_t nh
Definition: fib_types.api:126
void adj_midchain_delegate_stack(adj_index_t ai, u32 fib_index, const fib_prefix_t *pfx)
create/attach a midchain delegate and stack it on the prefix passed
#define NULL
Definition: clib.h:58
nhrp_entry_t * nhrp_entry_get(index_t nei)
Definition: nhrp.c:96
nhrp_key_t * ne_key
Definition: nhrp.c:31
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
Definition: dpo.h:41
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:523
#define hash_set_mem(h, key, value)
Definition: hash.h:275
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
static u8 ip46_address_is_ip4(const ip46_address_t *ip46)
Definition: ip46_address.h:55
void nhrp_walk(nhrp_walk_cb_t fn, void *ctx)
Definition: nhrp.c:220
ip46_address_t nk_peer
Definition: nhrp.c:25
u8 * format_nhrp_entry(u8 *s, va_list *args)
Definition: nhrp.c:199
u32 nk_sw_if_index
Definition: nhrp.c:26
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
static adj_walk_rc_t nhrp_entry_del_adj_walk(adj_index_t ai, void *ctx)
Definition: nhrp.c:88
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
#define clib_memcpy(d, s, n)
Definition: string.h:180
int nhrp_entry_add(u32 sw_if_index, const ip46_address_t *peer, u32 nh_table_id, const ip46_address_t *nh)
Create a new NHRP entry.
Definition: nhrp.c:119
vl_api_interface_index_t sw_if_index
Definition: gre.api:59
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
enum adj_walk_rc_t_ adj_walk_rc_t
return codes from a adjacency walker callback function
u8 * format_fib_prefix(u8 *s, va_list *args)
Definition: fib_types.c:200
Aggregate type for a prefix.
Definition: fib_types.h:203
unsigned int u32
Definition: types.h:88
vl_api_address_t peer
Definition: nhrp.api:28
u32 fib_table_find(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1097
u16 fp_len
The mask length.
Definition: fib_types.h:207
static clib_error_t * nhrp_init(vlib_main_t *vm)
Definition: nhrp.c:253
#define hash_create_mem(elts, key_bytes, value_bytes)
Definition: hash.h:661
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:519
#define hash_unset_mem(h, key)
Definition: hash.h:291
static_always_inline void ip46_address_copy(ip46_address_t *dst, const ip46_address_t *src)
Definition: ip46_address.h:123
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:226
long ctx[MAX_CONNS]
Definition: main.c:144
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:287
static nhrp_vft_t * nhrp_vfts
Definition: nhrp.c:38
vlib_main_t * vm
Definition: in2out_ed.c:1810
walk_rc_t(* nhrp_walk_cb_t)(index_t nei, void *ctx)
Definition: nhrp.h:54
format_function_t format_ip46_address
Definition: ip46_address.h:50
u32 nhrp_entry_get_fib_index(const nhrp_entry_t *ne)
Definition: nhrp.c:56
const ip46_address_t * nhrp_entry_get_peer(const nhrp_entry_t *ne)
Definition: nhrp.c:62
struct nhrp_key_t_ nhrp_key_t
int nhrp_entry_del(u32 sw_if_index, const ip46_address_t *peer)
Definition: nhrp.c:173
fib_prefix_t ne_nh
Definition: nhrp.c:32
static adj_walk_rc_t nhrp_entry_add_adj_walk(adj_index_t ai, void *ctx)
Definition: nhrp.c:80
u32 adj_index_t
An index for adjacencies.
Definition: adj_types.h:30
void adj_midchain_delegate_unstack(adj_index_t ai)
unstack a midchain delegate (this stacks it on a drop)
u32 fib_table_get_table_id(u32 fib_index, fib_protocol_t proto)
Get the Table-ID of the FIB from protocol and index.
Definition: fib_table.c:1086
static uword * nhrp_db
Definition: nhrp.c:36
static void clib_mem_free(void *p)
Definition: mem.h:226
static void * clib_mem_alloc(uword size)
Definition: mem.h:153
void nhrp_walk_itf(u32 sw_if_index, nhrp_walk_cb_t fn, void *ctx)
Definition: nhrp.c:233
const fib_prefix_t * nhrp_entry_get_nh(const nhrp_entry_t *ne)
Definition: nhrp.c:68
u64 uword
Definition: types.h:112
#define hash_get_mem(h, key)
Definition: hash.h:269
nhrp_entry_t * nhrp_entry_find(u32 sw_if_index, const ip46_address_t *peer)
Definition: nhrp.c:102
void nhrp_entry_adj_stack(const nhrp_entry_t *ne, adj_index_t ai)
Definition: nhrp.c:74
void nhrp_register(const nhrp_vft_t *vft)
Definition: nhrp.c:247
u32 nhrp_entry_get_sw_if_index(const nhrp_entry_t *ne)
accessors for the opaque struct
Definition: nhrp.c:50
#define pool_foreach_index(i, v, body)
Iterate pool by index.
Definition: pool.h:543
u32 ne_fib_index
Definition: nhrp.c:33
u32 nh_table_id
Definition: nhrp.api:30
static nhrp_entry_t * nhrp_pool
Definition: nhrp.c:37