FD.io VPP  v21.06
Vector Packet Processing
lcp_adj.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 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 <linux-cp/lcp_adj.h>
18 
19 #include <vppinfra/bihash_32_8.h>
21 
24 
25 /**
26  * The table of adjacencies indexed by the rewrite string
27  */
28 BVT (clib_bihash) lcp_adj_tbl;
29 
31 lcp_adj_mk_key_adj (const ip_adjacency_t *adj, lcp_adj_key_t *key)
32 {
33  lcp_adj_mk_key (adj->rewrite_header.data, adj->rewrite_header.data_bytes,
34  adj->rewrite_header.sw_if_index, key);
35 }
36 
37 static u8 *
39 {
40  return (format (s, "lcp"));
41 }
42 
43 static void
45 {
46  ip_adjacency_t *adj;
47  lcp_adj_kv_t kv;
48 
49  adj = adj_get (aed->ad_adj_index);
50 
51  lcp_adj_mk_key_adj (adj, &kv.k);
52 
53  BV (clib_bihash_add_del) (&lcp_adj_tbl, &kv.kv, 0);
54 
55  if (aed->ad_index != INDEX_INVALID)
56  pool_put_index (adj_keys, aed->ad_index);
57 }
58 
59 /* when an adj is modified:
60  *
61  * An existing hash entry may need to be deleted. This may occur when:
62  * * The newly modified adj does not have IP_LOOKUP_NEXT_REWRITE as next idx
63  * * The rewrite (== major component of hash key) changed
64  *
65  * A new hash entry may need to be added. This may occur when:
66  * * The newly modified adj has IP_LOOKUP_NEXT_REWRITE as next idx
67  * * The rewrite changed or there was no existing hash entry
68  */
69 static void
71 {
72  ip_adjacency_t *adj;
73  lcp_adj_kv_t kv;
74  lcp_adj_key_t *adj_key = NULL;
75  u8 save_adj, key_changed;
76 
77  key_changed = 0;
78 
79  adj = adj_get (aed->ad_adj_index);
80  save_adj = (IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index);
81 
82  if (aed->ad_index != INDEX_INVALID)
83  adj_key = pool_elt_at_index (adj_keys, aed->ad_index);
84 
85  /* return if there was no stored adj and we will not add one */
86  if (!adj_key && !save_adj)
87  return;
88 
89  /* build kv if a new entry should be stored */
90  if (save_adj)
91  {
92  lcp_adj_mk_key_adj (adj, &kv.k);
93  kv.v = aed->ad_adj_index;
94  if (adj_key)
95  key_changed = (clib_memcmp (adj_key, &kv.k, sizeof (*adj_key)) != 0);
96  }
97 
98  /* delete old entry if needed */
99  if (adj_key && ((save_adj && key_changed) || (!save_adj)))
100  {
101  lcp_adj_kv_t old_kv;
102 
103  clib_memcpy_fast (&old_kv.k, adj_key, sizeof (*adj_key));
104  old_kv.v = 0;
105 
106  BV (clib_bihash_add_del) (&lcp_adj_tbl, &old_kv.kv, 0);
107 
108  if (!save_adj)
109  {
110  pool_put (adj_keys, adj_key);
111  aed->ad_index = INDEX_INVALID;
112  }
113  }
114 
115  /* add new entry if needed */
116  if (save_adj)
117  {
118  BV (clib_bihash_add_del) (&lcp_adj_tbl, &kv.kv, 1);
119 
120  if (!adj_key)
121  {
122  pool_get (adj_keys, adj_key);
123  aed->ad_index = adj_key - adj_keys;
124  }
125  clib_memcpy_fast (adj_key, &kv.k, sizeof (*adj_key));
126  }
127 }
128 
129 static void
131 {
132  ip_adjacency_t *adj;
133  lcp_adj_kv_t kv;
134  index_t lai = INDEX_INVALID;
135  lcp_adj_key_t *adj_key;
136 
137  adj = adj_get (ai);
138 
140  {
141  lcp_adj_mk_key_adj (adj, &kv.k);
142  pool_get (adj_keys, adj_key);
143  clib_memcpy_fast (adj_key, &kv.k, sizeof (*adj_key));
144  kv.v = ai;
145 
146  BV (clib_bihash_add_del) (&lcp_adj_tbl, &kv.kv, 1);
147  lai = adj_key - adj_keys;
148  }
149 
150  adj_delegate_add (adj, adj_type, lai);
151 }
152 
153 u8 *
154 format_lcp_adj_kvp (u8 *s, va_list *args)
155 {
156  BVT (clib_bihash_kv) *kv = va_arg (*args, BVT (clib_bihash_kv) *);
157  CLIB_UNUSED (int verbose) = va_arg (*args, int);
158  lcp_adj_kv_t *akv = (lcp_adj_kv_t *) kv;
159 
160  s = format (s, " %U:%U\n %U", format_vnet_sw_if_index_name,
162  akv->k.rewrite, 18, format_adj_nbr, akv->v, 4);
163 
164  return (s);
165 }
166 
167 static clib_error_t *
169  vlib_cli_command_t *cmd)
170 {
171  u8 verbose = 0;
172 
173  if (unformat (input, "verbose"))
174  verbose = 1;
175 
176  vlib_cli_output (vm, "Linux-CP Adjs:\n%U", BV (format_bihash), &lcp_adj_tbl,
177  verbose);
178 
179  return 0;
180 }
181 
182 VLIB_CLI_COMMAND (lcp_itf_pair_show_cmd_node, static) = {
183  .path = "show lcp adj",
184  .function = lcp_adj_show_cmd,
185  .short_help = "show lcp adj",
186  .is_mp_safe = 1,
187 };
188 
189 const adj_delegate_vft_t lcp_adj_vft = {
191  .adv_adj_deleted = lcp_adj_delegate_adj_deleted,
192  .adv_adj_modified = lcp_adj_delegate_adj_modified,
193  .adv_adj_created = lcp_adj_delegate_adj_created,
194 };
195 
196 static clib_error_t *
198 {
199  adj_type = adj_delegate_register_new_type (&lcp_adj_vft);
200 
201  BV (clib_bihash_init) (&lcp_adj_tbl, "linux-cp ADJ table", 1024, 1 << 24);
202  BV (clib_bihash_set_kvp_format_fn) (&lcp_adj_tbl, format_lcp_adj_kvp);
203 
204  return (NULL);
205 }
206 
208 
209 /*
210  * fd.io coding-style-patch-verification: ON
211  *
212  * Local Variables:
213  * eval: (c-set-style "gnu")
214  * End:
215  */
static lcp_adj_key_t * adj_keys
Definition: lcp_adj.c:23
static void lcp_adj_delegate_adj_deleted(adj_delegate_t *aed)
Definition: lcp_adj.c:44
#define CLIB_UNUSED(x)
Definition: clib.h:90
u8 rewrite[28]
Definition: lcp_adj.h:24
u8 * format_adj_nbr(u8 *s, va_list *ap)
Format a neigbour (REWRITE) adjacency.
Definition: adj_nbr.c:1039
IP unicast adjacency.
Definition: adj.h:235
This packet is to be rewritten and forwarded to the next processing node.
Definition: adj.h:73
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:43
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:255
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
static ip_adjacency_t * adj_get(adj_index_t adj_index)
Get a pointer to an adjacency object from its index.
Definition: adj.h:470
#define static_always_inline
Definition: clib.h:112
static void lcp_adj_delegate_adj_modified(adj_delegate_t *aed)
Definition: lcp_adj.c:70
int clib_bihash_add_del(clib_bihash *h, clib_bihash_kv *add_v, int is_add)
Add or delete a (key,value) pair from a bi-hash table.
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
static void lcp_adj_delegate_adj_created(adj_index_t ai)
Definition: lcp_adj.c:130
static_always_inline void lcp_adj_mk_key(const u8 *rewrite, u8 len, u32 sw_if_index, lcp_adj_key_t *key)
Definition: lcp_adj.h:51
description fragment has unexpected format
Definition: map.api:433
u8 * format_hex_bytes(u8 *s, va_list *va)
Definition: std-formats.c:84
vnet_main_t * vnet_get_main(void)
Adj delegate.
Definition: adj_delegate.h:50
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:553
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
struct _unformat_input_t unformat_input_t
enum adj_delegate_type_t_ adj_delegate_type_t
A Delagate is a means to implement the Delagation design pattern; the extension of an object&#39;s functi...
adj_index_t ad_adj_index
The ADJ entry object to which the delagate is attached.
Definition: adj_delegate.h:55
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:305
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
void clib_bihash_init(clib_bihash *h, char *name, u32 nbuckets, uword memory_size)
initialize a bounded index extensible hash table
index_t ad_index
The index passed by the provider to identify its delegate instance.
Definition: adj_delegate.h:66
#define clib_memcmp(s1, s2, m1)
Definition: string.h:734
u32 adj_index_t
An index for adjacencies.
Definition: adj_types.h:30
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
lcp_adj_key_t k
Definition: lcp_adj.h:36
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:337
adj_delegate_type_t adj_delegate_register_new_type(const adj_delegate_vft_t *vft)
adj_delegate_register_new_type
Definition: adj_delegate.c:218
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
adj_delegate_format_t adv_format
Definition: adj_delegate.h:95
static clib_error_t * lcp_adj_show_cmd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: lcp_adj.c:168
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
Definition: string.h:92
typedef key
Definition: ipsec_types.api:88
static clib_error_t * lcp_adj_init(vlib_main_t *vm)
Definition: lcp_adj.c:197
ip_lookup_next_t lookup_next_index
Next hop after ip4-lookup.
Definition: adj.h:337
static adj_delegate_type_t adj_type
Definition: lcp_adj.c:22
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:49
An ADJ delegate virtual function table.
Definition: adj_delegate.h:94
static u8 * lcp_adj_delegate_format(const adj_delegate_t *aed, u8 *s)
Definition: lcp_adj.c:38
BVT(clib_bihash)
The table of adjacencies indexed by the rewrite string.
Definition: lcp_adj.c:28
u8 * format_lcp_adj_kvp(u8 *s, va_list *args)
Definition: lcp_adj.c:154
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
u32 sw_if_index
Definition: lcp_adj.h:23