FD.io VPP  v19.01-18-gcbd68cb
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_fib_index = ntohl(in->table_id);
60  out->frp_weight = in->weight;
61  out->frp_preference = in->preference;
62 
63  /*
64  * the special INVALID label meams we are not recursing via a
65  * label. Exp-null value is never a valid via-label so that
66  * also means it's not a via-label and means clients that set
67  * it to 0 by default get the expected behaviour
68  */
69  if ((MPLS_LABEL_INVALID != next_hop_via_label) &&
70  (0 != next_hop_via_label))
71  {
73  out->frp_local_label = next_hop_via_label;
74  out->frp_eos = MPLS_NON_EOS;
75  }
76 
77  n_labels = in->n_labels;
78  if (n_labels == 0)
79  ;
80  else
81  {
82  vec_validate (out->frp_label_stack, n_labels - 1);
83  for (ii = 0; ii < n_labels; ii++)
84  {
85  out->frp_label_stack[ii].fml_value =
86  ntohl(in->label_stack[ii].label);
87  out->frp_label_stack[ii].fml_ttl =
88  in->label_stack[ii].ttl;
89  out->frp_label_stack[ii].fml_exp =
90  in->label_stack[ii].exp;
91  out->frp_label_stack[ii].fml_mode =
92  (in->label_stack[ii].is_uniform ?
95  }
96  }
97 
98  if (in->is_dvr)
99  path_flags |= FIB_ROUTE_PATH_DVR;
100  if (in->is_resolve_host)
101  path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_HOST;
102  if (in->is_resolve_attached)
104  /* if (in->is_interface_rx) */
105  /* path_flags |= FIB_ROUTE_PATH_INTF_RX; */
106  /* if (in->is_rpf_id) */
107  /* path_flags |= FIB_ROUTE_PATH_RPF_ID; */
108  if (in->is_source_lookup)
109  path_flags |= FIB_ROUTE_PATH_SOURCE_LOOKUP;
110 
111  if (in->is_udp_encap)
112  {
113  path_flags |= FIB_ROUTE_PATH_UDP_ENCAP;
114  out->frp_udp_encap_id = ntohl(in->next_hop_id);
115  }
116  else
117  {
118  if (DPO_PROTO_IP4 == in->afi)
119  {
120  clib_memcpy (&out->frp_addr.ip4,
121  in->next_hop,
122  sizeof (out->frp_addr.ip4));
123  }
124  else if (DPO_PROTO_IP6 == in->afi)
125  {
126  clib_memcpy (&out->frp_addr.ip6,
127  in->next_hop,
128  sizeof (out->frp_addr.ip6));
129  }
130 
131  if (ip46_address_is_zero(&out->frp_addr))
132  {
133  if (DPO_PROTO_BIER == in->afi)
134  {
135  index_t bdti;
136 
137  bdti = bier_disp_table_find(ntohl(in->table_id));
138 
139  if (INDEX_INVALID != bdti)
140  {
141  out->frp_fib_index = bdti;
142  out->frp_proto = DPO_PROTO_BIER;
143  }
144  else
145  {
146  rv = VNET_API_ERROR_NO_SUCH_FIB;
147  }
148  }
149  else if (out->frp_sw_if_index == ~0 &&
150  out->frp_fib_index != ~0)
151  {
152  path_flags |= FIB_ROUTE_PATH_DEAG;
153  }
154  }
155  }
156 
157  out->frp_flags = path_flags;
158 
159  return (rv);
160 }
161 
162 void
164  u8 address[16],
165  u8 *length,
166  u8 *is_ip6)
167 {
168  *length = pfx->fp_len;
169  *is_ip6 = (FIB_PROTOCOL_IP6 == pfx->fp_proto ? 1 : 0);
170 
171  if (FIB_PROTOCOL_IP6 == pfx->fp_proto)
172  {
173  memcpy (address, &pfx->fp_addr.ip6, sizeof (pfx->fp_addr.ip6));
174  }
175  else
176  {
177  memcpy (address, &pfx->fp_addr.ip4, sizeof (pfx->fp_addr.ip4));
178  }
179 }
180 
181 static void
182 fib_api_path_copy_next_hop (const fib_route_path_encode_t * api_rpath, void *fp_arg)
183 {
184  int is_ip4;
185  vl_api_fib_path_t *fp = (vl_api_fib_path_t *) fp_arg;
186 
187  if (api_rpath->rpath.frp_proto == DPO_PROTO_IP4)
188  fp->afi = IP46_TYPE_IP4;
189  else if (api_rpath->rpath.frp_proto == DPO_PROTO_IP6)
190  fp->afi = IP46_TYPE_IP6;
191  else
192  {
193  is_ip4 = ip46_address_is_ip4 (&api_rpath->rpath.frp_addr);
194  if (is_ip4)
195  fp->afi = IP46_TYPE_IP4;
196  else
197  fp->afi = IP46_TYPE_IP6;
198  }
199  if (fp->afi == IP46_TYPE_IP4)
200  memcpy (fp->next_hop, &api_rpath->rpath.frp_addr.ip4,
201  sizeof (api_rpath->rpath.frp_addr.ip4));
202  else
203  memcpy (fp->next_hop, &api_rpath->rpath.frp_addr.ip6,
204  sizeof (api_rpath->rpath.frp_addr.ip6));
205 }
206 
207 void
209  vl_api_fib_path_t *out)
210 {
211  int ii;
212 
213  clib_memset (out, 0, sizeof (*out));
214  switch (api_rpath->dpo.dpoi_type)
215  {
216  case DPO_RECEIVE:
217  out->is_local = true;
218  break;
219  case DPO_DROP:
220  out->is_drop = true;
221  break;
222  case DPO_IP_NULL:
223  switch (ip_null_dpo_get_action(api_rpath->dpo.dpoi_index))
224  {
225  case IP_NULL_ACTION_NONE:
226  out->is_drop = true;
227  break;
229  out->is_unreach = true;
230  break;
232  out->is_prohibit = true;
233  break;
234  default:
235  break;
236  }
237  break;
238  default:
239  break;
240  }
241  out->weight = api_rpath->rpath.frp_weight;
242  out->preference = api_rpath->rpath.frp_preference;
243  out->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
244  out->afi = api_rpath->rpath.frp_proto;
245  fib_api_path_copy_next_hop (api_rpath, out);
246 
247  if (0 != api_rpath->rpath.frp_fib_index)
248  {
249  if ((DPO_PROTO_IP6 == api_rpath->rpath.frp_proto) ||
250  (DPO_PROTO_IP4 == api_rpath->rpath.frp_proto))
251  {
252  if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_RPF_ID)
253  {
254  out->table_id =
256  api_rpath->rpath.frp_fib_index,
257  dpo_proto_to_fib(api_rpath->rpath.frp_proto)));
258  }
259  else
260  {
261  out->table_id =
263  api_rpath->rpath.frp_fib_index,
264  dpo_proto_to_fib(api_rpath->rpath.frp_proto)));
265  }
266  }
267  }
268 
269  if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_DVR)
270  {
271  out->is_dvr = 1;
272  }
273  if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_UDP_ENCAP)
274  {
275  out->is_udp_encap = 1;
276  out->next_hop_id = api_rpath->rpath.frp_udp_encap_id;
277  }
278  if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_INTF_RX)
279  {
280  out->is_interface_rx = 1;
281  }
282  if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_LOCAL)
283  {
284  out->is_local = 1;
285  }
287  {
288  out->is_resolve_host = 1;
289  }
291  {
292  out->is_resolve_attached = 1;
293  }
294  /* if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_ATTACHED) { */
295  /* out->is_attached = 1; */
296  /* } */
297  /* if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_CONNECTED) { */
298  /* out->is_connected = 1; */
299  /* } */
300  if (api_rpath->rpath.frp_label_stack)
301  {
302  for (ii = 0; ii < vec_len(api_rpath->rpath.frp_label_stack); ii++)
303  {
304  out->label_stack[ii].label =
305  htonl(api_rpath->rpath.frp_label_stack[ii].fml_value);
306  out->label_stack[ii].ttl =
307  api_rpath->rpath.frp_label_stack[ii].fml_ttl;
308  out->label_stack[ii].exp =
309  api_rpath->rpath.frp_label_stack[ii].fml_exp;
310  }
311  out->n_labels = ii;
312  }
313 }
314 
317 {
318  switch (clib_net_to_host_u32 (af))
319  {
320  case ADDRESS_IP4:
321  return (FIB_PROTOCOL_IP4);
322  case ADDRESS_IP6:
323  return (FIB_PROTOCOL_IP6);
324  }
325 
326  ASSERT(0);
327  return (FIB_PROTOCOL_IP4);
328 }
329 
330 int
332 {
333  switch (fproto)
334  {
335  case FIB_PROTOCOL_IP4:
336  return (clib_net_to_host_u32 (ADDRESS_IP4));
337  case FIB_PROTOCOL_IP6:
338  return (clib_net_to_host_u32 (ADDRESS_IP6));
339  default:
340  break;
341  }
342 
343  ASSERT(0);
344  return (clib_net_to_host_u32 (ADDRESS_IP4));
345 }
#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:182
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:316
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
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:331
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:208
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:163
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