FD.io VPP  v21.01.1
Vector Packet Processing
mfib_itf.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/vnet.h>
17 
18 #include <vnet/mfib/mfib_itf.h>
19 #include <vnet/mfib/mfib_signal.h>
20 #include <vnet/fib/fib_path.h>
22 
24 
25 index_t
27  mfib_itf_flags_t mfi_flags)
28 {
29  mfib_itf_t *mfib_itf;
30 
31  pool_get_aligned(mfib_itf_pool, mfib_itf,
33 
34  mfib_itf->mfi_sw_if_index = fib_path_get_resolving_interface(path_index);
35  mfib_itf->mfi_si = INDEX_INVALID;
36 
37  /*
38  * add the path index to the per-path hash
39  */
40  mfib_itf->mfi_hash = hash_set(mfib_itf->mfi_hash, path_index, mfi_flags);
41 
42  /*
43  * the combined flags from all the paths is from just the one contributor
44  */
45  mfib_itf->mfi_flags = mfi_flags;
46 
47  return (mfib_itf - mfib_itf_pool);
48 }
49 
50 static mfib_itf_flags_t
51 mfib_itf_mk_flags (const mfib_itf_t *mfib_itf)
52 {
53  mfib_itf_flags_t combined_flags, flags;
54  fib_node_index_t *path_index;
55 
56  combined_flags = MFIB_ITF_FLAG_NONE;
57 
58  hash_foreach(path_index, flags, mfib_itf->mfi_hash,
59  {
60  combined_flags |= flags;
61  });
62 
63  return (combined_flags);
64 }
65 
66 int
68  fib_node_index_t path_index,
69  mfib_itf_flags_t mfi_flags)
70 {
71  /*
72  * add or remove the path index to the per-path hash
73  */
74  if (MFIB_ITF_FLAG_NONE == mfi_flags)
75  {
76  hash_unset(mfib_itf->mfi_hash, path_index);
77  }
78  else
79  {
80  mfib_itf->mfi_hash = hash_set(mfib_itf->mfi_hash,
81  path_index,
82  mfi_flags);
83  }
84 
85  /*
86  * re-generate the combined flags from all the paths.
87  */
88  mfib_itf->mfi_flags = mfib_itf_mk_flags(mfib_itf);
89 
90  /*
91  * The interface can be removed if there are no more flags
92  */
93  return (MFIB_ITF_FLAG_NONE == mfib_itf->mfi_flags);
94 }
95 
96 static void
98 {
99  fib_node_index_t path_index, *path_indexp, *all = NULL;
101 
102  hash_foreach(path_index, flags, mfi->mfi_hash,
103  {
104  vec_add1(all, path_index);
105  });
106 
107  vec_foreach(path_indexp, all)
108  {
109  hash_unset(mfi->mfi_hash, *path_indexp);
110  };
111 }
112 
113 static void
116 {
117  mac->bytes[0] = 0x01;
118  mac->bytes[1] = 0x0;
119  mac->bytes[2] = 0x5e;
120  mac->bytes[3] = pfx->fp_grp_addr.ip4.as_u8[1] & 0x7f;
121  mac->bytes[4] = pfx->fp_grp_addr.ip4.as_u8[2];
122  mac->bytes[5] = pfx->fp_grp_addr.ip4.as_u8[3];
123 }
124 
125 static void
128 {
129  mac->bytes[0] = 0x33;
130  mac->bytes[1] = 0x33;
131  mac->bytes[2] = pfx->fp_grp_addr.ip6.as_u8[12];
132  mac->bytes[3] = pfx->fp_grp_addr.ip6.as_u8[13];
133  mac->bytes[4] = pfx->fp_grp_addr.ip6.as_u8[14];
134  mac->bytes[5] = pfx->fp_grp_addr.ip6.as_u8[15];
135 }
136 
137 static void
140 {
141  switch (pfx->fp_proto)
142  {
143  case FIB_PROTOCOL_IP4:
144  mfib_itf_prefix4_to_mac(pfx, mac);
145  break;
146  case FIB_PROTOCOL_IP6:
147  mfib_itf_prefix6_to_mac(pfx, mac);
148  break;
149  case FIB_PROTOCOL_MPLS:
150  break;
151  }
152 }
153 
154 static void
156  const mfib_prefix_t *pfx,
157  int add)
158 {
160  vnet_main_t *vnm;
162 
163  vnm = vnet_get_main();
164  mfib_itf_prefix_to_mac(pfx, &mac);
165 
166  si = vnet_get_sw_interface(vnm, itf->mfi_sw_if_index);
168  si->hw_if_index,
169  mac.bytes, add);
170 }
171 
172 void
174  const mfib_prefix_t *pfx)
175 {
176  mfib_itf_mac_add_del(itf, pfx, 1);
177 }
178 
179 void
181  const mfib_prefix_t *pfx)
182 {
183  mfib_itf_mac_add_del(itf, pfx, 0);
184 }
185 
186 void
188 {
189  mfib_itf_hash_flush(mfi);
191  pool_put(mfib_itf_pool, mfi);
192 }
193 
194 u8 *
195 format_mfib_itf (u8 * s, va_list * args)
196 {
197  mfib_itf_t *mfib_itf;
198  vnet_main_t *vnm;
199  index_t mfi;
200 
201  mfi = va_arg (*args, index_t);
202 
203  vnm = vnet_get_main();
204  mfib_itf = mfib_itf_get(mfi);
205 
206  if (~0 != mfib_itf->mfi_sw_if_index)
207  {
208  return (format(s, " %U: %U",
210  vnm,
212  mfib_itf->mfi_sw_if_index),
213  format_mfib_itf_flags, mfib_itf->mfi_flags));
214  }
215  else
216  {
217  return (format(s, " local: %U",
218  format_mfib_itf_flags, mfib_itf->mfi_flags));
219  }
220  return (s);
221 }
222 
223 static clib_error_t *
225  unformat_input_t * input,
226  vlib_cli_command_t * cmd)
227 {
228  index_t mfii;
229 
230  if (unformat (input, "%d", &mfii))
231  {
232  /*
233  * show one in detail
234  */
235  if (!pool_is_free_index(mfib_itf_pool, mfii))
236  {
237  vlib_cli_output (vm, "%d@%U",
238  mfii,
239  format_mfib_itf, mfii);
240  }
241  else
242  {
243  vlib_cli_output (vm, "itf %d invalid", mfii);
244  }
245  }
246  else
247  {
248  /*
249  * show all
250  */
251  vlib_cli_output (vm, "mFIB interfaces::");
252  pool_foreach_index (mfii, mfib_itf_pool)
253  {
254  vlib_cli_output (vm, "%d@%U",
255  mfii,
256  format_mfib_itf, mfii);
257  }
258  }
259 
260  return (NULL);
261 }
262 
263 /*?
264  * This commnad displays an MFIB interface, or all interfaces, indexed by their unique
265  * numerical indentifier.
266  ?*/
267 VLIB_CLI_COMMAND (show_mfib_itf, static) = {
268  .path = "show mfib interface",
269  .function = show_mfib_itf_command,
270  .short_help = "show mfib interface",
271 };
int mfib_itf_update(mfib_itf_t *mfib_itf, fib_node_index_t path_index, mfib_itf_flags_t mfi_flags)
update an interface from a path.
Definition: mfib_itf.c:67
#define hash_set(h, key, value)
Definition: hash.h:255
#define pool_foreach_index(i, v)
Definition: pool.h:569
vl_api_mac_address_t mac
Definition: l2.api:502
#define hash_unset(h, key)
Definition: hash.h:261
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
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
static void mfib_itf_mac_add_del(mfib_itf_t *itf, const mfib_prefix_t *pfx, int add)
Definition: mfib_itf.c:155
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
vlib_main_t * vm
Definition: in2out_ed.c:1580
static clib_error_t * show_mfib_itf_command(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: mfib_itf.c:224
unsigned char u8
Definition: types.h:56
static mfib_itf_flags_t mfib_itf_mk_flags(const mfib_itf_t *mfib_itf)
Definition: mfib_itf.c:51
void mfib_itf_mac_del(mfib_itf_t *itf, const mfib_prefix_t *pfx)
Definition: mfib_itf.c:180
description fragment has unexpected format
Definition: map.api:433
#define hash_foreach(key_var, value_var, h, body)
Definition: hash.h:442
mfib_itf_t * mfib_itf_pool
Definition: mfib_itf.c:23
uword * mfi_hash
A hash table of path-inidices that are contributing flags to this interface.
Definition: mfib_itf.h:53
clib_error_t * vnet_hw_interface_add_del_mac_address(vnet_main_t *vnm, u32 hw_if_index, const u8 *mac_address, u8 is_add)
Definition: interface.c:1487
static void mfib_itf_prefix_to_mac(const mfib_prefix_t *pfx, mac_address_t *mac)
Definition: mfib_itf.c:138
static void mfib_itf_hash_flush(mfib_itf_t *mfi)
Definition: mfib_itf.c:97
format_function_t format_vnet_sw_interface_name
static mfib_itf_t * mfib_itf_get(index_t mi)
Get the MFIB interface representation.
Definition: mfib_itf.h:83
void mfib_itf_mac_add(mfib_itf_t *itf, const mfib_prefix_t *pfx)
Definition: mfib_itf.c:173
struct _unformat_input_t unformat_input_t
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:301
u32 mfi_si
The index of the signal in the pending list.
Definition: mfib_itf.h:45
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P with alignment A.
Definition: pool.h:245
void mfib_signal_remove_itf(const mfib_itf_t *mfi)
Definition: mfib_signal.c:184
mfib_itf_flags_t mfi_flags
Forwarding Flags on the entry - checked in the data-path.
Definition: mfib_itf.h:35
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:29
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:298
Aggregate type for a prefix.
Definition: mfib_types.h:24
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:158
static void mfib_itf_prefix4_to_mac(const mfib_prefix_t *pfx, mac_address_t *mac)
Definition: mfib_itf.c:114
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:696
u8 * format_mfib_itf(u8 *s, va_list *args)
Definition: mfib_itf.c:195
An interface associated with a particular MFIB entry.
Definition: mfib_itf.h:25
static void mfib_itf_prefix6_to_mac(const mfib_prefix_t *pfx, mac_address_t *mac)
Definition: mfib_itf.c:126
index_t mfib_itf_create(fib_node_index_t path_index, mfib_itf_flags_t mfi_flags)
Definition: mfib_itf.c:26
fib_protocol_t fp_proto
protocol type
Definition: mfib_types.h:33
u32 fib_path_get_resolving_interface(fib_node_index_t path_index)
Definition: fib_path.c:2149
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:47
u8 * format_mfib_itf_flags(u8 *s, va_list *args)
Definition: mfib_types.c:181
enum mfib_itf_flags_t_ mfib_itf_flags_t
u32 mfi_sw_if_index
The SW IF index that this MFIB interface represents.
Definition: mfib_itf.h:40
#define vec_foreach(var, vec)
Vector iterator.
void mfib_itf_delete(mfib_itf_t *mfi)
Definition: mfib_itf.c:187
u8 si
Definition: lisp_types.api:47
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
ip46_address_t fp_grp_addr
The address type is not deriveable from the fp_addr member.
Definition: mfib_types.h:46