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