FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
ip4_fib_hash.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/fib/fib_table.h>
17 #include <vnet/fib/fib_entry.h>
18 #include <vnet/fib/ip4_fib.h>
19 
20 /*
21  * ip4_fib_hash_table_lookup_exact_match
22  *
23  * Exact match prefix lookup
24  */
27  const ip4_address_t *addr,
28  u32 len)
29 {
30  uword * hash, * result;
31  u32 key;
32 
33  hash = fib->fib_entry_by_dst_address[len];
34  key = (addr->data_u32 & ip4_main.fib_masks[len]);
35 
36  result = hash_get(hash, key);
37 
38  if (NULL != result) {
39  return (result[0]);
40  }
41  return (FIB_NODE_INDEX_INVALID);
42 }
43 
44 /*
45  * ip4_fib_hash_table_lookup_adj
46  *
47  * Longest prefix match
48  */
49 index_t
51  const ip4_address_t *addr)
52 {
53  fib_node_index_t fei;
54 
55  fei = ip4_fib_hash_table_lookup(fib, addr, 32);
56 
57  if (FIB_NODE_INDEX_INVALID != fei)
58  {
59  const dpo_id_t *dpo;
60 
62 
63  return (dpo->dpoi_index);
64  }
65  return (INDEX_INVALID);
66 }
67 
68 /*
69  * ip4_fib_hash_table_lookup
70  *
71  * Longest prefix match
72  */
75  const ip4_address_t *addr,
76  u32 len)
77 {
78  uword * hash, * result;
79  i32 mask_len;
80  u32 key;
81 
82  for (mask_len = len; mask_len >= 0; mask_len--)
83  {
84  hash = fib->fib_entry_by_dst_address[mask_len];
85  key = (addr->data_u32 & ip4_main.fib_masks[mask_len]);
86 
87  result = hash_get (hash, key);
88 
89  if (NULL != result) {
90  return (result[0]);
91  }
92  }
93  return (FIB_NODE_INDEX_INVALID);
94 }
95 
96 void
98  const ip4_address_t *addr,
99  u32 len,
100  fib_node_index_t fib_entry_index)
101 {
102  uword * hash, * result;
103  u32 key;
104 
105  key = (addr->data_u32 & ip4_main.fib_masks[len]);
106  hash = fib->fib_entry_by_dst_address[len];
107  result = hash_get (hash, key);
108 
109  if (NULL == result) {
110  /*
111  * adding a new entry
112  */
113 
114  if (NULL == hash) {
115  hash = hash_create (32 /* elts */, sizeof (uword));
117 
118  }
119  hash = hash_set(hash, key, fib_entry_index);
120  fib->fib_entry_by_dst_address[len] = hash;
121  }
122  else
123  {
124  ASSERT(0);
125  }
126 }
127 
128 void
130  const ip4_address_t *addr,
131  u32 len)
132 {
133  uword * hash, * result;
134  u32 key;
135 
136  key = (addr->data_u32 & ip4_main.fib_masks[len]);
137  hash = fib->fib_entry_by_dst_address[len];
138  result = hash_get (hash, key);
139 
140  if (NULL == result)
141  {
142  /*
143  * removing a non-existent entry. i'll allow it.
144  */
145  }
146  else
147  {
148  hash_unset(hash, key);
149  }
150 
151  fib->fib_entry_by_dst_address[len] = hash;
152 }
153 
154 void
157  void *ctx)
158 {
159  fib_prefix_t root = {
161  // address and length default to all 0
162  };
163 
164  /*
165  * A full tree walk is the dengenerate case of a sub-tree from
166  * the very root
167  */
168  return (ip4_fib_hash_table_sub_tree_walk(fib, &root, fn, ctx));
169 }
170 
171 void
173  const fib_prefix_t *root,
175  void *ctx)
176 {
177  fib_prefix_t *sub_trees = NULL;
178  int i;
179 
180  /*
181  * There is no efficient way to walk this array of hash tables.
182  * so we walk each table with a mask length greater than and equal to
183  * the required root and check it is covered by the root.
184  */
185  for (i = root->fp_len;
187  i++)
188  {
189  uword * hash = fib->fib_entry_by_dst_address[i];
190 
191  if (NULL != hash)
192  {
194  hash_pair_t * p;
195 
196  hash_foreach_pair (p, hash,
197  ({
198  key.as_u32 = p->key;
200  &key,
201  &root->fp_addr.ip4,
202  root->fp_len))
203  {
204  const fib_prefix_t *sub_tree;
205  int skip = 0;
206 
207  /*
208  * exclude sub-trees the walk does not want to explore
209  */
210  vec_foreach(sub_tree, sub_trees)
211  {
212  if (ip4_destination_matches_route(&ip4_main,
213  &key,
214  &sub_tree->fp_addr.ip4,
215  sub_tree->fp_len))
216  {
217  skip = 1;
218  break;
219  }
220  }
221 
222  if (!skip)
223  {
224  switch (fn(p->value[0], ctx))
225  {
226  case FIB_TABLE_WALK_CONTINUE:
227  break;
228  case FIB_TABLE_WALK_SUB_TREE_STOP: {
229  fib_prefix_t pfx = {
230  .fp_proto = FIB_PROTOCOL_IP4,
231  .fp_len = i,
232  .fp_addr.ip4 = key,
233  };
234  vec_add1(sub_trees, pfx);
235  break;
236  }
237  case FIB_TABLE_WALK_STOP:
238  goto done;
239  }
240  }
241  }
242  }));
243  }
244  }
245 done:
246  vec_free(sub_trees);
247  return;
248 }
249 
fib_entry.h
dpo_id_t_::dpoi_index
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:190
hash_set
#define hash_set(h, key, value)
Definition: hash.h:255
ip4_fib_hash_table_lookup_lb
index_t ip4_fib_hash_table_lookup_lb(const ip4_fib_hash_t *fib, const ip4_address_t *addr)
Definition: ip4_fib_hash.c:50
ip4_fib_hash_table_entry_remove
void ip4_fib_hash_table_entry_remove(ip4_fib_hash_t *fib, const ip4_address_t *addr, u32 len)
Definition: ip4_fib_hash.c:129
ip4_main
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1104
HASH_FLAG_NO_AUTO_SHRINK
#define HASH_FLAG_NO_AUTO_SHRINK
Definition: hash.h:64
hash_foreach_pair
#define hash_foreach_pair(p, v, body)
Iterate over hash pairs.
Definition: hash.h:373
FIB_NODE_INDEX_INVALID
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:30
fib_table.h
fib_prefix_t_::fp_len
u16 fp_len
The mask length.
Definition: fib_types.h:206
ip4_main_t::fib_masks
u32 fib_masks[33]
Definition: ip4.h:117
ip4_fib_hash_table_entry_insert
void ip4_fib_hash_table_entry_insert(ip4_fib_hash_t *fib, const ip4_address_t *addr, u32 len, fib_node_index_t fib_entry_index)
Definition: ip4_fib_hash.c:97
addr
vhost_vring_addr_t addr
Definition: vhost_user.h:130
ip4_fib_hash_table_sub_tree_walk
void ip4_fib_hash_table_sub_tree_walk(ip4_fib_hash_t *fib, const fib_prefix_t *root, fib_table_walk_fn_t fn, void *ctx)
Walk all entries in a sub-tree of the FIB table N.B: This is NOT safe to deletes.
Definition: ip4_fib_hash.c:172
ip4_fib_hash_table_lookup_exact_match
fib_node_index_t ip4_fib_hash_table_lookup_exact_match(const ip4_fib_hash_t *fib, const ip4_address_t *addr, u32 len)
Definition: ip4_fib_hash.c:26
hash_unset
#define hash_unset(h, key)
Definition: hash.h:261
key
typedef key
Definition: ipsec_types.api:91
i32
signed int i32
Definition: types.h:77
len
u8 len
Definition: ip_types.api:103
hash_pair_t::value
uword value[0]
Definition: hash.h:165
fib_entry_contribute_ip_forwarding
const dpo_id_t * fib_entry_contribute_ip_forwarding(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:506
ip4_fib_hash_t_
The IPv4 FIB Hash table.
Definition: ip4_fib_hash.h:25
hash_get
#define hash_get(h, key)
Definition: hash.h:249
ARRAY_LEN
#define ARRAY_LEN(x)
Definition: clib.h:70
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
fib_node_index_t
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:29
uword
u64 uword
Definition: types.h:112
if
if(node->flags &VLIB_NODE_FLAG_TRACE) vnet_interface_output_trace(vm
ip4_address_t
Definition: ip4_packet.h:50
FIB_PROTOCOL_IP4
@ FIB_PROTOCOL_IP4
Definition: fib_types.h:36
fib_prefix_t_::fp_addr
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:225
fib_table_walk_fn_t
fib_table_walk_rc_t(* fib_table_walk_fn_t)(fib_node_index_t fei, void *ctx)
Call back function when walking entries in a FIB table.
Definition: fib_table.h:930
ip4_destination_matches_route
static uword ip4_destination_matches_route(const ip4_main_t *im, const ip4_address_t *key, const ip4_address_t *dest, uword dest_length)
Definition: ip4.h:187
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
ip4_fib_hash_table_lookup
fib_node_index_t ip4_fib_hash_table_lookup(const ip4_fib_hash_t *fib, const ip4_address_t *addr, u32 len)
Definition: ip4_fib_hash.c:74
FIB_TABLE_WALK_STOP
@ FIB_TABLE_WALK_STOP
Stop the walk completely.
Definition: fib_table.h:924
u32
unsigned int u32
Definition: types.h:88
ctx
long ctx[MAX_CONNS]
Definition: main.c:144
ip4_fib_hash_t_::fib_entry_by_dst_address
uword * fib_entry_by_dst_address[33]
Definition: ip4_fib_hash.h:28
hash_pair_t::key
uword key
Definition: hash.h:162
fib_prefix_t_::fp_proto
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:211
ip4_fib.h
hash_set_flags
static void hash_set_flags(void *v, uword flags)
Definition: hash.h:153
i
int i
Definition: flowhash_template.h:376
dpo_id_t_
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:172
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
hash_create
#define hash_create(elts, value_bytes)
Definition: hash.h:695
fib_prefix_t_
Aggregate type for a prefix.
Definition: fib_types.h:202
hash_pair_t
Definition: hash.h:159
ip4_fib_hash_table_walk
void ip4_fib_hash_table_walk(ip4_fib_hash_t *fib, fib_table_walk_fn_t fn, void *ctx)
Walk all entries in a FIB table N.B: This is NOT safe to deletes.
Definition: ip4_fib_hash.c:155