FD.io VPP  v20.09-64-g4f7b92f0a
Vector Packet Processing
teib.c
Go to the documentation of this file.
1 /*
2  * teib.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/teib/teib.h>
20 #include <vnet/fib/fib_table.h>
21 #include <vnet/adj/adj_midchain.h>
22 
23 typedef struct teib_key_t_
24 {
25  ip46_address_t tk_peer;
27 } teib_key_t;
28 
30 {
34 };
35 
36 static uword *teib_db;
39 
40 #define TEIB_NOTIFY(_te, _fn) { \
41  teib_vft_t *_vft; \
42  vec_foreach(_vft, teib_vfts) { \
43  if (_vft->_fn) { \
44  _vft->_fn(_te); \
45  } \
46  } \
47 }
48 
49 u32
51 {
52  return (te->te_key->tk_sw_if_index);
53 }
54 
55 u32
57 {
58  return (te->te_fib_index);
59 }
60 
61 const ip46_address_t *
63 {
64  return (&te->te_key->tk_peer);
65 }
66 
67 const fib_prefix_t *
69 {
70  return (&te->te_nh);
71 }
72 
73 void
75 {
77 }
78 
81 {
82  return pool_elt_at_index (teib_pool, tei);
83 }
84 
86 teib_entry_find (u32 sw_if_index, const ip46_address_t * peer)
87 {
88  teib_key_t nk = {
89  .tk_peer = *peer,
90  .tk_sw_if_index = sw_if_index,
91  };
92  uword *p;
93 
94  p = hash_get_mem (teib_db, &nk);
95 
96  if (NULL != p)
97  return teib_entry_get (p[0]);
98 
99  return (NULL);
100 }
101 
102 int
104  const ip46_address_t * peer,
105  u32 nh_table_id, const ip46_address_t * nh)
106 {
107  fib_protocol_t fproto;
108  teib_entry_t *te;
109  u32 fib_index;
110  index_t tei;
111 
113 
114  fib_index = fib_table_find (fproto, nh_table_id);
115 
116  if (~0 == fib_index)
117  {
118  return (VNET_API_ERROR_NO_SUCH_FIB);
119  }
120 
121  te = teib_entry_find (sw_if_index, peer);
122 
123  if (NULL == te)
124  {
125  teib_key_t nk = {
126  .tk_peer = *peer,
127  .tk_sw_if_index = sw_if_index,
128  };
129  teib_entry_t *te;
130 
131  pool_get_zero (teib_pool, te);
132 
133  tei = te - teib_pool;
134  te->te_key = clib_mem_alloc (sizeof (*te->te_key));
135  clib_memcpy (te->te_key, &nk, sizeof (*te->te_key));
136 
137  ip46_address_copy (&te->te_nh.fp_addr, nh);
138  te->te_nh.fp_proto = fproto;
139  te->te_nh.fp_len = (te->te_nh.fp_proto == FIB_PROTOCOL_IP4 ? 32 : 128);
140  te->te_fib_index = fib_index;
141 
142  hash_set_mem (teib_db, te->te_key, tei);
143 
144  TEIB_NOTIFY (te, nv_added);
145  }
146  else
147  return (VNET_API_ERROR_ENTRY_ALREADY_EXISTS);
148 
149  return 0;
150 }
151 
152 int
153 teib_entry_del (u32 sw_if_index, const ip46_address_t * peer)
154 {
155  teib_entry_t *te;
156 
157  te = teib_entry_find (sw_if_index, peer);
158 
159  if (te != NULL)
160  {
162 
163  TEIB_NOTIFY (te, nv_deleted);
164 
165  clib_mem_free (te->te_key);
166  pool_put (teib_pool, te);
167  }
168  else
169  return (VNET_API_ERROR_ENTRY_ALREADY_EXISTS);
170 
171  return 0;
172 }
173 
174 u8 *
175 format_teib_entry (u8 * s, va_list * args)
176 {
177  index_t tei = va_arg (*args, index_t);
178  vnet_main_t *vnm = vnet_get_main ();
179  teib_entry_t *te;
180 
181  te = teib_entry_get (tei);
182 
183  s = format (s, "[%d] ", tei);
184  s = format (s, "%U:", format_vnet_sw_if_index_name,
185  vnm, te->te_key->tk_sw_if_index);
186  s = format (s, " %U", format_ip46_address,
187  &te->te_key->tk_peer, IP46_TYPE_ANY);
188  s = format (s, " via [%d]:%U",
190  format_fib_prefix, &te->te_nh);
191 
192  return (s);
193 }
194 
195 void
197 {
198  index_t tei;
199 
200  /* *INDENT-OFF* */
201  pool_foreach_index(tei, teib_pool,
202  ({
203  fn(tei, ctx);
204  }));
205  /* *INDENT-ON* */
206 }
207 
208 void
210 {
211  index_t tei;
212 
213  /* *INDENT-OFF* */
214  pool_foreach_index(tei, teib_pool,
215  ({
216  if (sw_if_index == teib_entry_get_sw_if_index(teib_entry_get(tei)))
217  fn(tei, ctx);
218  }));
219  /* *INDENT-ON* */
220 }
221 
222 void
224 {
225  vec_add1 (teib_vfts, *vft);
226 }
227 
228 static clib_error_t *
230 {
231  teib_db = hash_create_mem (0, sizeof (teib_key_t), sizeof (u32));
232 
233  return (NULL);
234 }
235 
237 
238 /*
239  * fd.io coding-style-patch-verification: ON
240  *
241  * Local Variables:
242  * eval: (c-set-style "gnu")
243  * End:
244  */
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:212
u32 te_fib_index
Definition: teib.c:33
u32 tk_sw_if_index
Definition: teib.c:26
int teib_entry_del(u32 sw_if_index, const ip46_address_t *peer)
Definition: teib.c:153
teib_entry_t * teib_entry_get(index_t tei)
Definition: teib.c:80
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:255
vl_api_fib_path_nh_t nh
Definition: fib_types.api:126
void teib_walk(teib_walk_cb_t fn, void *ctx)
Definition: teib.c:196
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
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:592
static clib_error_t * teib_init(vlib_main_t *vm)
Definition: teib.c:229
#define hash_set_mem(h, key, value)
Definition: hash.h:275
vlib_main_t * vm
Definition: in2out_ed.c:1582
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
static uword * teib_db
Definition: teib.c:36
teib_key_t * te_key
Definition: teib.c:31
fib_prefix_t te_nh
Definition: teib.c:32
static u8 ip46_address_is_ip4(const ip46_address_t *ip46)
Definition: ip46_address.h:55
const ip46_address_t * teib_entry_get_peer(const teib_entry_t *te)
Definition: teib.c:62
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
void teib_walk_itf(u32 sw_if_index, teib_walk_cb_t fn, void *ctx)
Definition: teib.c:209
u8 * format_teib_entry(u8 *s, va_list *args)
Definition: teib.c:175
#define clib_memcpy(d, s, n)
Definition: string.h:180
u32 teib_entry_get_fib_index(const teib_entry_t *te)
Definition: teib.c:56
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
ip46_address_t tk_peer
Definition: teib.c:25
u8 * format_fib_prefix(u8 *s, va_list *args)
Definition: fib_types.c:264
Aggregate type for a prefix.
Definition: fib_types.h:203
unsigned int u32
Definition: types.h:88
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
#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:534
#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
u32 teib_entry_get_sw_if_index(const teib_entry_t *te)
accessors for the opaque struct
Definition: teib.c:50
walk_rc_t(* teib_walk_cb_t)(index_t nei, void *ctx)
Definition: teib.h:58
long ctx[MAX_CONNS]
Definition: main.c:144
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:302
vl_api_address_t peer
Definition: teib.api:28
format_function_t format_ip46_address
Definition: ip46_address.h:50
void teib_entry_adj_stack(const teib_entry_t *te, adj_index_t ai)
Definition: teib.c:74
static teib_entry_t * teib_pool
Definition: teib.c:37
Definition: teib.c:29
u32 adj_index_t
An index for adjacencies.
Definition: adj_types.h:30
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 void clib_mem_free(void *p)
Definition: mem.h:215
struct teib_key_t_ teib_key_t
static void * clib_mem_alloc(uword size)
Definition: mem.h:157
#define TEIB_NOTIFY(_te, _fn)
Definition: teib.c:40
teib_entry_t * teib_entry_find(u32 sw_if_index, const ip46_address_t *peer)
Definition: teib.c:86
int teib_entry_add(u32 sw_if_index, const ip46_address_t *peer, u32 nh_table_id, const ip46_address_t *nh)
Create a new TEIB entry.
Definition: teib.c:103
static teib_vft_t * teib_vfts
Definition: teib.c:38
u64 uword
Definition: types.h:112
#define hash_get_mem(h, key)
Definition: hash.h:269
#define pool_foreach_index(i, v, body)
Iterate pool by index.
Definition: pool.h:558
void teib_register(const teib_vft_t *vft)
Definition: teib.c:223
u32 nh_table_id
Definition: teib.api:30
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:33
const fib_prefix_t * teib_entry_get_nh(const teib_entry_t *te)
Definition: teib.c:68