FD.io VPP  v19.01.2-3-gf61a1a8
Vector Packet Processing
fib_api.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 #include <vlibmemory/api.h>
18 #include <vnet/fib/fib_api.h>
19 #include <vnet/fib/fib_table.h>
20 #include <vnet/mfib/mfib_table.h>
22 #include <vnet/dpo/ip_null_dpo.h>
23 
24 #include <vnet/vnet_msg_enum.h>
25 
26 #define vl_typedefs /* define message structures */
27 #include <vnet/vnet_all_api_h.h>
28 #undef vl_typedefs
29 
30 #define vl_endianfun /* define message structures */
31 #include <vnet/vnet_all_api_h.h>
32 #undef vl_endianfun
33 
34 /* instantiate all the print functions we know about */
35 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
36 #define vl_printfun
37 #include <vnet/vnet_all_api_h.h>
38 #undef vl_printfun
39 
41 
42 int
44  fib_route_path_t *out)
45 {
46  fib_route_path_flags_t path_flags;
47  mpls_label_t next_hop_via_label;
48  int rv = 0, n_labels;
49  u8 ii;
50 
51  path_flags = FIB_ROUTE_PATH_FLAG_NONE;
52  next_hop_via_label = ntohl (in->via_label);
53  clib_memset(out, 0, sizeof(*out));
54  out->frp_sw_if_index = ~0;
55 
56  out->frp_proto = in->afi;
57  // .frp_addr = (NULL == next_hop ? zero_addr : *next_hop),
58  out->frp_sw_if_index = ntohl(in->sw_if_index);
59  out->frp_weight = in->weight;
60  out->frp_preference = in->preference;
61 
62  if (DPO_PROTO_IP4 == out->frp_proto ||
63  DPO_PROTO_IP6 == out->frp_proto ||
64  DPO_PROTO_MPLS == out->frp_proto)
65  {
67  ntohl (in->table_id));
68 
69  if (~0 == out->frp_fib_index)
70  return (VNET_API_ERROR_NO_SUCH_FIB);
71  }
72 
73  /*
74  * the special INVALID label meams we are not recursing via a
75  * label. Exp-null value is never a valid via-label so that
76  * also means it's not a via-label and means clients that set
77  * it to 0 by default get the expected behaviour
78  */
79  if ((MPLS_LABEL_INVALID != next_hop_via_label) &&
80  (0 != next_hop_via_label))
81  {
83  out->frp_local_label = next_hop_via_label;
84  out->frp_eos = MPLS_NON_EOS;
85  }
86 
87  n_labels = in->n_labels;
88  if (n_labels == 0)
89  ;
90  else
91  {
92  vec_validate (out->frp_label_stack, n_labels - 1);
93  for (ii = 0; ii < n_labels; ii++)
94  {
95  out->frp_label_stack[ii].fml_value =
96  ntohl(in->label_stack[ii].label);
97  out->frp_label_stack[ii].fml_ttl =
98  in->label_stack[ii].ttl;
99  out->frp_label_stack[ii].fml_exp =
100  in->label_stack[ii].exp;
101  out->frp_label_stack[ii].fml_mode =
102  (in->label_stack[ii].is_uniform ?
105  }
106  }
107 
108  if (in->is_dvr)
109  path_flags |= FIB_ROUTE_PATH_DVR;
110  if (in->is_resolve_host)
111  path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_HOST;
112  if (in->is_resolve_attached)
114  /* if (in->is_interface_rx) */
115  /* path_flags |= FIB_ROUTE_PATH_INTF_RX; */
116  /* if (in->is_rpf_id) */
117  /* path_flags |= FIB_ROUTE_PATH_RPF_ID; */
118  if (in->is_source_lookup)
119  path_flags |= FIB_ROUTE_PATH_SOURCE_LOOKUP;
120 
121  if (in->is_udp_encap)
122  {
123  path_flags |= FIB_ROUTE_PATH_UDP_ENCAP;
124  out->frp_udp_encap_id = ntohl(in->next_hop_id);
125  }
126  else
127  {
128  if (DPO_PROTO_IP4 == in->afi)
129  {
130  clib_memcpy (&out->frp_addr.ip4,
131  in->next_hop,
132  sizeof (out->frp_addr.ip4));
133  }
134  else if (DPO_PROTO_IP6 == in->afi)
135  {
136  clib_memcpy (&out->frp_addr.ip6,
137  in->next_hop,
138  sizeof (out->frp_addr.ip6));
139  }
140 
141  if (ip46_address_is_zero(&out->frp_addr))
142  {
143  if (DPO_PROTO_BIER == in->afi)
144  {
145  index_t bdti;
146 
147  bdti = bier_disp_table_find(ntohl(in->table_id));
148 
149  if (INDEX_INVALID != bdti)
150  {
151  out->frp_fib_index = bdti;
152  out->frp_proto = DPO_PROTO_BIER;
153  }
154  else
155  {
156  rv = VNET_API_ERROR_NO_SUCH_FIB;
157  }
158  }
159  else if (out->frp_sw_if_index == ~0 &&
160  out->frp_fib_index != ~0)
161  {
162  path_flags |= FIB_ROUTE_PATH_DEAG;
163  }
164  }
165  }
166 
167  out->frp_flags = path_flags;
168 
169  return (rv);
170 }
171 
172 void
174  u8 address[16],
175  u8 *length,
176  u8 *is_ip6)
177 {
178  *length = pfx->fp_len;
179  *is_ip6 = (FIB_PROTOCOL_IP6 == pfx->fp_proto ? 1 : 0);
180 
181  if (FIB_PROTOCOL_IP6 == pfx->fp_proto)
182  {
183  memcpy (address, &pfx->fp_addr.ip6, sizeof (pfx->fp_addr.ip6));
184  }
185  else
186  {
187  memcpy (address, &pfx->fp_addr.ip4, sizeof (pfx->fp_addr.ip4));
188  }
189 }
190 
191 static void
192 fib_api_path_copy_next_hop (const fib_route_path_encode_t * api_rpath, void *fp_arg)
193 {
194  int is_ip4;
195  vl_api_fib_path_t *fp = (vl_api_fib_path_t *) fp_arg;
196 
197  if (api_rpath->rpath.frp_proto == DPO_PROTO_IP4)
198  fp->afi = IP46_TYPE_IP4;
199  else if (api_rpath->rpath.frp_proto == DPO_PROTO_IP6)
200  fp->afi = IP46_TYPE_IP6;
201  else
202  {
203  is_ip4 = ip46_address_is_ip4 (&api_rpath->rpath.frp_addr);
204  if (is_ip4)
205  fp->afi = IP46_TYPE_IP4;
206  else
207  fp->afi = IP46_TYPE_IP6;
208  }
209  if (fp->afi == IP46_TYPE_IP4)
210  memcpy (fp->next_hop, &api_rpath->rpath.frp_addr.ip4,
211  sizeof (api_rpath->rpath.frp_addr.ip4));
212  else
213  memcpy (fp->next_hop, &api_rpath->rpath.frp_addr.ip6,
214  sizeof (api_rpath->rpath.frp_addr.ip6));
215 }
216 
217 void
219  vl_api_fib_path_t *out)
220 {
221  int ii;
222 
223  clib_memset (out, 0, sizeof (*out));
224  switch (api_rpath->dpo.dpoi_type)
225  {
226  case DPO_RECEIVE:
227  out->is_local = true;
228  break;
229  case DPO_DROP:
230  out->is_drop = true;
231  break;
232  case DPO_IP_NULL:
233  switch (ip_null_dpo_get_action(api_rpath->dpo.dpoi_index))
234  {
235  case IP_NULL_ACTION_NONE:
236  out->is_drop = true;
237  break;
239  out->is_unreach = true;
240  break;
242  out->is_prohibit = true;
243  break;
244  default:
245  break;
246  }
247  break;
248  default:
249  break;
250  }
251  out->weight = api_rpath->rpath.frp_weight;
252  out->preference = api_rpath->rpath.frp_preference;
253  out->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
254  out->afi = api_rpath->rpath.frp_proto;
255  fib_api_path_copy_next_hop (api_rpath, out);
256 
257  if (0 != api_rpath->rpath.frp_fib_index)
258  {
259  if ((DPO_PROTO_IP6 == api_rpath->rpath.frp_proto) ||
260  (DPO_PROTO_IP4 == api_rpath->rpath.frp_proto))
261  {
262  if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_RPF_ID)
263  {
264  out->table_id =
266  api_rpath->rpath.frp_fib_index,
267  dpo_proto_to_fib(api_rpath->rpath.frp_proto)));
268  }
269  else
270  {
271  out->table_id =
273  api_rpath->rpath.frp_fib_index,
274  dpo_proto_to_fib(api_rpath->rpath.frp_proto)));
275  }
276  }
277  }
278 
279  if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_DVR)
280  {
281  out->is_dvr = 1;
282  }
283  if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_UDP_ENCAP)
284  {
285  out->is_udp_encap = 1;
286  out->next_hop_id = api_rpath->rpath.frp_udp_encap_id;
287  }
288  if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_INTF_RX)
289  {
290  out->is_interface_rx = 1;
291  }
292  if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_LOCAL)
293  {
294  out->is_local = 1;
295  }
297  {
298  out->is_resolve_host = 1;
299  }
301  {
302  out->is_resolve_attached = 1;
303  }
304  /* if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_ATTACHED) { */
305  /* out->is_attached = 1; */
306  /* } */
307  /* if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_CONNECTED) { */
308  /* out->is_connected = 1; */
309  /* } */
310  if (api_rpath->rpath.frp_label_stack)
311  {
312  for (ii = 0; ii < vec_len(api_rpath->rpath.frp_label_stack); ii++)
313  {
314  out->label_stack[ii].label =
315  htonl(api_rpath->rpath.frp_label_stack[ii].fml_value);
316  out->label_stack[ii].ttl =
317  api_rpath->rpath.frp_label_stack[ii].fml_ttl;
318  out->label_stack[ii].exp =
319  api_rpath->rpath.frp_label_stack[ii].fml_exp;
320  }
321  out->n_labels = ii;
322  }
323 }
324 
327 {
328  switch (clib_net_to_host_u32 (af))
329  {
330  case ADDRESS_IP4:
331  return (FIB_PROTOCOL_IP4);
332  case ADDRESS_IP6:
333  return (FIB_PROTOCOL_IP6);
334  }
335 
336  ASSERT(0);
337  return (FIB_PROTOCOL_IP4);
338 }
339 
340 int
342 {
343  switch (fproto)
344  {
345  case FIB_PROTOCOL_IP4:
346  return (clib_net_to_host_u32 (ADDRESS_IP4));
347  case FIB_PROTOCOL_IP6:
348  return (clib_net_to_host_u32 (ADDRESS_IP6));
349  default:
350  break;
351  }
352 
353  ASSERT(0);
354  return (clib_net_to_host_u32 (ADDRESS_IP4));
355 }
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:439
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:212
ip46_address_t frp_addr
The next-hop address.
Definition: fib_types.h:486
typedef address
Definition: ip_types.api:30
A path that resolves via a DVR DPO.
Definition: fib_types.h:381
Pipe Mode - the default.
Definition: fib_types.h:404
A representation of a fib path for fib_path_encode to convey the information to the caller...
Definition: fib_types.h:588
mpls_eos_bit_t frp_eos
EOS bit for the resolving label.
Definition: fib_types.h:497
A representation of a path as described by a route producer.
Definition: fib_types.h:470
u32 mpls_label_t
A label value only, i.e.
Definition: packet.h:24
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
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
dpo_proto_t frp_proto
The protocol of the address below.
Definition: fib_types.h:475
static void fib_api_path_copy_next_hop(const fib_route_path_encode_t *api_rpath, void *fp_arg)
Definition: fib_api.c:192
A path that result in received traffic being recieved/recirculated so that it appears to have arrived...
Definition: fib_types.h:349
unsigned char u8
Definition: types.h:56
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
#define clib_memcpy(d, s, n)
Definition: string.h:180
A local path with a RPF-ID => multicast traffic.
Definition: fib_types.h:353
u32 frp_sw_if_index
The interface.
Definition: fib_types.h:505
fib_protocol_t fib_proto_from_api_address_family(int af)
Definition: fib_api.c:326
Recursion constraint of via a host prefix.
Definition: fib_types.h:324
Aggregrate type for a prefix.
Definition: fib_types.h:203
A path via a UDP encap object.
Definition: fib_types.h:361
enum fib_route_path_flags_t_ fib_route_path_flags_t
Path flags from the control plane.
ip_null_dpo_action_t ip_null_dpo_get_action(index_t indi)
Definition: ip_null_dpo.c:100
u32 fib_table_find(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1064
fib_protocol_t dpo_proto_to_fib(dpo_proto_t dpo_proto)
Definition: fib_types.c:253
u16 fp_len
The mask length.
Definition: fib_types.h:207
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:226
dpo_type_t dpoi_type
the type
Definition: dpo.h:172
fib_mpls_label_t * frp_label_stack
The outgoing MPLS label Stack.
Definition: fib_types.h:525
Recursion constraint of via an attahced prefix.
Definition: fib_types.h:328
int fib_proto_to_api_address_family(fib_protocol_t fproto)
Definition: fib_api.c:341
fib_mpls_lsp_mode_t fml_mode
The LSP mode.
Definition: fib_types.h:435
#define ip46_address_is_ip4(ip46)
Definition: ip6_packet.h:88
#define MPLS_LABEL_INVALID
Definition: mpls_types.h:48
mpls_label_t fml_value
The label value.
Definition: fib_types.h:430
index_t bier_disp_table_find(u32 table_id)
vl_api_fib_mpls_label_t label_stack[16]
Definition: fib_types.api:69
#define ASSERT(truth)
FIB path.
Definition: fib_types.api:47
u32 fib_table_get_table_id(u32 fib_index, fib_protocol_t proto)
Get the Table-ID of the FIB from protocol and index.
Definition: fib_table.c:1053
u8 frp_preference
A path preference.
Definition: fib_types.h:567
A deag path using the packet&#39;s source not destination address.
Definition: fib_types.h:357
fib_route_path_flags_t frp_flags
flags on the path
Definition: fib_types.h:571
u32 mfib_table_get_table_id(u32 fib_index, fib_protocol_t proto)
Get the Table-ID of the FIB from protocol and index.
Definition: mfib_table.c:493
A path that resolves via another table.
Definition: fib_types.h:377
void fib_api_path_encode(const fib_route_path_encode_t *api_rpath, vl_api_fib_path_t *out)
Definition: fib_api.c:218
mpls_label_t frp_local_label
The MPLS local Label to reursively resolve through.
Definition: fib_types.h:493
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:184
A for-us/local path.
Definition: fib_types.h:332
#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
int fib_path_api_parse(const vl_api_fib_path_t *in, fib_route_path_t *out)
Definition: fib_api.c:43
fib_route_path_t rpath
Definition: fib_types.h:589
u8 fml_exp
EXP bits; valid only at imposition.
Definition: fib_types.h:445
void fib_prefix_to_api(const fib_prefix_t *pfx, u8 address[16], u8 *length, u8 *is_ip6)
Definition: fib_api.c:173
u8 frp_weight
[un]equal cost path weight
Definition: fib_types.h:561
u32 frp_udp_encap_id
UDP encap ID.
Definition: fib_types.h:551
#define ip46_address_is_zero(ip46)
Definition: ip6_packet.h:93
u32 frp_fib_index
The FIB index to lookup the nexthop Only valid for recursive paths.
Definition: fib_types.h:516
Definition: dpo.h:96