FD.io VPP  v20.05-21-gb1500e9ff
Vector Packet Processing
ip_punt_drop.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 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/ip/ip.h>
17 #include <vnet/ip/ip_punt_drop.h>
18 #include <vnet/policer/policer.h>
20 #include <vnet/fib/fib_path_list.h>
21 
23 
24 u8 *
25 format_ip_punt_redirect_trace (u8 * s, va_list * args)
26 {
27  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
28  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
30 
31  if (INDEX_INVALID == t->rrxi)
32  s = format (s, "ignore");
33  else
34  s = format (s, "via redirect:%d", t->rrxi);
35 
36  return s;
37 }
38 
39 static void
41 {
42  dpo_id_t dpo = DPO_INVALID;
43  vlib_node_t *pnode;
44 
46  ipr->payload_type,
48 
49  if (FIB_PROTOCOL_IP4 == ipr->fproto)
50  pnode =
51  vlib_get_node_by_name (vlib_get_main (), (u8 *) "ip4-punt-redirect");
52  else
53  pnode =
54  vlib_get_node_by_name (vlib_get_main (), (u8 *) "ip6-punt-redirect");
55 
56  dpo_stack_from_node (pnode->index, &ipr->dpo, &dpo);
57  dpo_reset (&dpo);
58 }
59 
60 index_t
61 ip_punt_redirect_find (fib_protocol_t fproto, u32 rx_sw_if_index)
62 {
63  index_t *rxs;
64 
65  rxs = ip_punt_redirect_cfg.redirect_by_rx_sw_if_index[fproto];
66 
67  if (vec_len (rxs) <= rx_sw_if_index)
68  return (INDEX_INVALID);
69 
70  return rxs[rx_sw_if_index];
71 }
72 
73 void
75  u32 rx_sw_if_index,
77 {
79  index_t ipri;
80 
81  if (~0 == rx_sw_if_index)
82  rx_sw_if_index = 0;
83 
85  [fproto], rx_sw_if_index, INDEX_INVALID);
86 
87  pool_get (ip_punt_redirect_cfg.pool, ipr);
88  ipri = ipr - ip_punt_redirect_cfg.pool;
89 
90  ip_punt_redirect_cfg.redirect_by_rx_sw_if_index[fproto][rx_sw_if_index] =
91  ipri;
92 
94  ipr->fproto = fproto;
95  ipr->payload_type = ct;
96 
98 
99  ipr->sibling = fib_path_list_child_add (ipr->pl,
101  ipri);
102 
104 }
105 
106 void
107 ip_punt_redirect_del (fib_protocol_t fproto, u32 rx_sw_if_index)
108 {
110  index_t *rxs;
111 
112  if (~0 == rx_sw_if_index)
113  rx_sw_if_index = 0;
114 
115  rxs = ip_punt_redirect_cfg.redirect_by_rx_sw_if_index[fproto];
116 
117  if ((vec_len (rxs) <= rx_sw_if_index) ||
118  (INDEX_INVALID == rxs[rx_sw_if_index]))
119  return;
120 
121  ipr = ip_punt_redirect_get (rxs[rx_sw_if_index]);
122 
124  dpo_reset (&ipr->dpo);
125  pool_put (ip_punt_redirect_cfg.pool, ipr);
126 
127  rxs[rx_sw_if_index] = INDEX_INVALID;
128 }
129 
130 u8 *
131 format_ip_punt_redirect (u8 * s, va_list * args)
132 {
133  fib_protocol_t fproto = va_arg (*args, int);
135  index_t *rxs;
136  u32 rx_sw_if_index;
137  vnet_main_t *vnm = vnet_get_main ();
138 
139  rxs = ip_punt_redirect_cfg.redirect_by_rx_sw_if_index[fproto];
140 
141  vec_foreach_index (rx_sw_if_index, rxs)
142  {
143  if (INDEX_INVALID == rxs[rx_sw_if_index])
144  continue;
145 
146  rx = ip_punt_redirect_get (rxs[rx_sw_if_index]);
147 
148  s = format (s, " rx %U via:\n",
150  vnet_get_sw_interface (vnm, rx_sw_if_index));
151  s = format (s, " %U", format_fib_path_list, rx->pl, 2);
152  s = format (s, " forwarding\n", format_dpo_id, &rx->dpo, 0);
153  s = format (s, " %U\n", format_dpo_id, &rx->dpo, 0);
154  }
155 
156  return (s);
157 }
158 
159 void
162 {
164  u32 ii, rx_sw_if_index;
165  index_t *rxs;
166 
167  rxs = ip_punt_redirect_cfg.redirect_by_rx_sw_if_index[fproto];
168 
169  vec_foreach_index (ii, rxs)
170  {
171  if (INDEX_INVALID == rxs[ii])
172  continue;
173 
174  rx = ip_punt_redirect_get (rxs[ii]);
175 
176  rx_sw_if_index = (ii == 0 ? ~0 : ii);
177  cb (rx_sw_if_index, rx, ctx);
178  }
179 }
180 
181 static fib_node_t *
183 {
185  return (&(ipr->node));
186 }
187 
188 static ip_punt_redirect_rx_t *
190 {
191  return ((ip_punt_redirect_rx_t *) (((char *) node) -
193  node)));
194 }
195 
196 static void
198 {
199  /*
200  * the lifetime of the entry is managed by the table.
201  */
202  ASSERT (0);
203 }
204 
205 /*
206  * A back walk has reached this BIER entry
207  */
211 {
212  /*
213  * re-populate the ECMP tables with new choices
214  */
216 
218 
219  /*
220  * no need to propagate further up the graph, since there's nothing there
221  */
223 }
224 
225 /*
226  * The BIER fmask's graph node virtual function table
227  */
228 static const fib_node_vft_t ip_punt_redirect_vft = {
230  .fnv_last_lock = ip_punt_redirect_last_lock_gone,
231  .fnv_back_walk = ip_punt_redirect_back_walk_notify,
232 };
233 
234 static clib_error_t *
236 {
238  &ip_punt_redirect_vft);
239 
240  return (NULL);
241 }
242 
244 
245 /*
246  * fd.io coding-style-patch-verification: ON
247  *
248  * Local Variables:
249  * eval: (c-set-style "gnu")
250  * End:
251  */
void dpo_stack_from_node(u32 child_node_index, dpo_id_t *dpo, const dpo_id_t *parent)
Stack one DPO object on another, and thus establish a child parent relationship.
Definition: dpo.c:531
ip_punt_redirect_cfg_t ip_punt_redirect_cfg
Definition: ip_punt_drop.c:22
ip_punt_redirect_rx_t * pool
Definition: ip_punt_drop.h:217
#define vec_foreach_index(var, v)
Iterate over vector indices.
#define CLIB_UNUSED(x)
Definition: clib.h:86
void fib_path_list_child_remove(fib_node_index_t path_list_index, u32 si)
A representation of a path as described by a route producer.
Definition: fib_types.h:490
static void ip_punt_redirect_last_lock_gone(fib_node_t *node)
Definition: ip_punt_drop.c:197
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
fib_protocol_t fproto
Definition: ip_punt_drop.h:201
void fib_node_init(fib_node_t *node, fib_node_type_t type)
Definition: fib_node.c:185
u8 * format_fib_path_list(u8 *s, va_list *args)
u8 * format_ip_punt_redirect_trace(u8 *s, va_list *args)
Definition: ip_punt_drop.c:25
u32 index
Definition: node.h:282
enum fib_node_back_walk_rc_t_ fib_node_back_walk_rc_t
Return code from a back walk function.
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 fib_node_back_walk_rc_t ip_punt_redirect_back_walk_notify(fib_node_t *node, fib_node_back_walk_ctx_t *ctx)
Definition: ip_punt_drop.c:209
#define STRUCT_OFFSET_OF(t, f)
Definition: clib.h:69
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:252
void ip_punt_redirect_add(fib_protocol_t fproto, u32 rx_sw_if_index, fib_forward_chain_type_t ct, fib_route_path_t *rpaths)
Add a punt redirect entry.
Definition: ip_punt_drop.c:74
u32 fib_path_list_child_add(fib_node_index_t path_list_index, fib_node_type_t child_type, fib_node_index_t child_index)
static ip_punt_redirect_rx_t * ip_punt_redirect_get_from_node(fib_node_t *node)
Definition: ip_punt_drop.c:189
unsigned char u8
Definition: types.h:56
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
index_t ip_punt_redirect_find(fib_protocol_t fproto, u32 rx_sw_if_index)
Definition: ip_punt_drop.c:61
void fib_node_register_type(fib_node_type_t type, const fib_node_vft_t *vft)
fib_node_register_type
Definition: fib_node.c:60
u8 * format_ip_punt_redirect(u8 *s, va_list *args)
Definition: ip_punt_drop.c:131
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
fib_forward_chain_type_t payload_type
Definition: ip_punt_drop.h:202
fib_node_index_t pl
Definition: ip_punt_drop.h:203
unsigned int u32
Definition: types.h:88
IP punt redirect configuration.
Definition: ip_punt_drop.h:215
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:170
format_function_t format_vnet_sw_interface_name
fib_node_t node
Node linkage into the FIB graph.
Definition: ip_punt_drop.h:199
fib_node_index_t fib_path_list_create(fib_path_list_flags_t flags, const fib_route_path_t *rpaths)
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
static clib_error_t * ip_punt_drop_init(vlib_main_t *vm)
Definition: ip_punt_drop.c:235
long ctx[MAX_CONNS]
Definition: main.c:144
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:302
An node in the FIB graph.
Definition: fib_node.h:295
vlib_main_t * vm
Definition: in2out_ed.c:1599
IP Punt redirect trace.
Definition: ip_punt_drop.h:243
static fib_node_t * ip_punt_redirect_get_node(fib_node_index_t index)
Definition: ip_punt_drop.c:182
static_always_inline ip_punt_redirect_rx_t * ip_punt_redirect_get(index_t rrxi)
Definition: ip_punt_drop.h:271
IP4 punt redirect per-rx interface configuration redirect punted traffic to another location...
Definition: ip_punt_drop.h:194
fib_node_get_t fnv_get
Definition: fib_node.h:283
dpo_id_t dpo
redirect forwarding
Definition: ip_punt_drop.h:209
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:30
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1599
Context passed between object during a back walk.
Definition: fib_node.h:208
#define ASSERT(truth)
enum fib_forward_chain_type_t_ fib_forward_chain_type_t
FIB output chain type.
walk_rc_t(* ip_punt_redirect_walk_cb_t)(u32 rx_sw_if_index, const ip_punt_redirect_rx_t *redirect, void *arg)
Definition: ip_punt_drop.h:264
u8 * format_dpo_id(u8 *s, va_list *args)
Format a DPO_id_t oject.
Definition: dpo.c:148
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
static void ip_punt_redirect_stack(ip_punt_redirect_rx_t *ipr)
Definition: ip_punt_drop.c:40
void ip_punt_redirect_del(fib_protocol_t fproto, u32 rx_sw_if_index)
Definition: ip_punt_drop.c:107
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:47
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:197
void fib_path_list_contribute_forwarding(fib_node_index_t path_list_index, fib_forward_chain_type_t fct, fib_path_list_fwd_flags_t flags, dpo_id_t *dpo)
A FIB graph nodes virtual function table.
Definition: fib_node.h:282
index_t * redirect_by_rx_sw_if_index[FIB_PROTOCOL_IP_MAX]
per-RX interface configuration.
Definition: ip_punt_drop.h:224
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:232
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
Definition: vec.h:554
void ip_punt_redirect_walk(fib_protocol_t fproto, ip_punt_redirect_walk_cb_t cb, void *ctx)
Definition: ip_punt_drop.c:160