FD.io VPP  v18.10-34-gcce845e
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>
21 #include <vnet/dpo/ip_null_dpo.h>
22 
23 #include <vnet/vnet_msg_enum.h>
24 
25 #define vl_typedefs /* define message structures */
26 #include <vnet/vnet_all_api_h.h>
27 #undef vl_typedefs
28 
29 #define vl_endianfun /* define message structures */
30 #include <vnet/vnet_all_api_h.h>
31 #undef vl_endianfun
32 
33 /* instantiate all the print functions we know about */
34 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
35 #define vl_printfun
36 #include <vnet/vnet_all_api_h.h>
37 #undef vl_printfun
38 
40 
41 int
43  fib_route_path_t *out)
44 {
45  fib_route_path_flags_t path_flags;
46  mpls_label_t next_hop_via_label;
47  int rv = 0, n_labels;
48  u8 ii;
49 
50  path_flags = FIB_ROUTE_PATH_FLAG_NONE;
51  next_hop_via_label = ntohl (in->via_label);
52  memset(out, 0, sizeof(*out));
53  out->frp_sw_if_index = ~0;
54 
55  out->frp_proto = in->afi;
56  // .frp_addr = (NULL == next_hop ? zero_addr : *next_hop),
57  out->frp_sw_if_index = ntohl(in->sw_if_index);
58  out->frp_weight = in->weight;
59  out->frp_preference = in->preference;
60 
61  if (DPO_PROTO_IP4 == out->frp_proto ||
62  DPO_PROTO_IP6 == out->frp_proto ||
63  DPO_PROTO_MPLS == out->frp_proto)
64  {
66  ntohl (in->table_id));
67 
68  if (~0 == out->frp_fib_index)
69  return (VNET_API_ERROR_NO_SUCH_FIB);
70  }
71 
72  /*
73  * the special INVALID label meams we are not recursing via a
74  * label. Exp-null value is never a valid via-label so that
75  * also means it's not a via-label and means clients that set
76  * it to 0 by default get the expected behaviour
77  */
78  if ((MPLS_LABEL_INVALID != next_hop_via_label) &&
79  (0 != next_hop_via_label))
80  {
82  out->frp_local_label = next_hop_via_label;
83  out->frp_eos = MPLS_NON_EOS;
84  }
85 
86  n_labels = in->n_labels;
87  if (n_labels == 0)
88  ;
89  else
90  {
91  vec_validate (out->frp_label_stack, n_labels - 1);
92  for (ii = 0; ii < n_labels; ii++)
93  {
94  out->frp_label_stack[ii].fml_value =
95  ntohl(in->label_stack[ii].label);
96  out->frp_label_stack[ii].fml_ttl =
97  in->label_stack[ii].ttl;
98  out->frp_label_stack[ii].fml_exp =
99  in->label_stack[ii].exp;
100  out->frp_label_stack[ii].fml_mode =
101  (in->label_stack[ii].is_uniform ?
104  }
105  }
106 
107  if (in->is_dvr)
108  path_flags |= FIB_ROUTE_PATH_DVR;
109  if (in->is_resolve_host)
110  path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_HOST;
111  if (in->is_resolve_attached)
113  /* if (in->is_interface_rx) */
114  /* path_flags |= FIB_ROUTE_PATH_INTF_RX; */
115  /* if (in->is_rpf_id) */
116  /* path_flags |= FIB_ROUTE_PATH_RPF_ID; */
117  if (in->is_source_lookup)
118  path_flags |= FIB_ROUTE_PATH_SOURCE_LOOKUP;
119 
120  if (in->is_udp_encap)
121  {
122  path_flags |= FIB_ROUTE_PATH_UDP_ENCAP;
123  out->frp_udp_encap_id = ntohl(in->next_hop_id);
124  }
125  else
126  {
127  if (DPO_PROTO_IP4 == in->afi)
128  {
129  clib_memcpy (&out->frp_addr.ip4,
130  in->next_hop,
131  sizeof (out->frp_addr.ip4));
132  }
133  else if (DPO_PROTO_IP6 == in->afi)
134  {
135  clib_memcpy (&out->frp_addr.ip6,
136  in->next_hop,
137  sizeof (out->frp_addr.ip6));
138  }
139 
140  if (ip46_address_is_zero(&out->frp_addr))
141  {
142  if (DPO_PROTO_BIER == in->afi)
143  {
144  index_t bdti;
145 
146  bdti = bier_disp_table_find(ntohl(in->table_id));
147 
148  if (INDEX_INVALID != bdti)
149  {
150  out->frp_fib_index = bdti;
151  out->frp_proto = DPO_PROTO_BIER;
152  }
153  else
154  {
155  rv = VNET_API_ERROR_NO_SUCH_FIB;
156  }
157  }
158  else if (out->frp_sw_if_index == ~0 &&
159  out->frp_fib_index != ~0)
160  {
161  path_flags |= FIB_ROUTE_PATH_DEAG;
162  }
163  }
164  }
165 
166  out->frp_flags = path_flags;
167 
168  return (rv);
169 }
170 
171 void
173  u8 address[16],
174  u8 *length,
175  u8 *is_ip6)
176 {
177  *length = pfx->fp_len;
178  *is_ip6 = (FIB_PROTOCOL_IP6 == pfx->fp_proto ? 1 : 0);
179 
180  if (FIB_PROTOCOL_IP6 == pfx->fp_proto)
181  {
182  memcpy (address, &pfx->fp_addr.ip6, sizeof (pfx->fp_addr.ip6));
183  }
184  else
185  {
186  memcpy (address, &pfx->fp_addr.ip4, sizeof (pfx->fp_addr.ip4));
187  }
188 }
189 
190 static void
191 fib_api_path_copy_next_hop (const fib_route_path_encode_t * api_rpath, void *fp_arg)
192 {
193  int is_ip4;
194  vl_api_fib_path_t *fp = (vl_api_fib_path_t *) fp_arg;
195 
196  if (api_rpath->rpath.frp_proto == DPO_PROTO_IP4)
197  fp->afi = IP46_TYPE_IP4;
198  else if (api_rpath->rpath.frp_proto == DPO_PROTO_IP6)
199  fp->afi = IP46_TYPE_IP6;
200  else
201  {
202  is_ip4 = ip46_address_is_ip4 (&api_rpath->rpath.frp_addr);
203  if (is_ip4)
204  fp->afi = IP46_TYPE_IP4;
205  else
206  fp->afi = IP46_TYPE_IP6;
207  }
208  if (fp->afi == IP46_TYPE_IP4)
209  memcpy (fp->next_hop, &api_rpath->rpath.frp_addr.ip4,
210  sizeof (api_rpath->rpath.frp_addr.ip4));
211  else
212  memcpy (fp->next_hop, &api_rpath->rpath.frp_addr.ip6,
213  sizeof (api_rpath->rpath.frp_addr.ip6));
214 }
215 
216 void
218  vl_api_fib_path_t *out)
219 {
220  memset (out, 0, sizeof (*out));
221  switch (api_rpath->dpo.dpoi_type)
222  {
223  case DPO_RECEIVE:
224  out->is_local = true;
225  break;
226  case DPO_DROP:
227  out->is_drop = true;
228  break;
229  case DPO_IP_NULL:
230  switch (ip_null_dpo_get_action(api_rpath->dpo.dpoi_index))
231  {
232  case IP_NULL_ACTION_NONE:
233  out->is_drop = true;
234  break;
236  out->is_unreach = true;
237  break;
239  out->is_prohibit = true;
240  break;
241  default:
242  break;
243  }
244  break;
245  default:
246  break;
247  }
248  out->weight = api_rpath->rpath.frp_weight;
249  out->preference = api_rpath->rpath.frp_preference;
250  out->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
251  out->afi = api_rpath->rpath.frp_proto;
252  fib_api_path_copy_next_hop (api_rpath, out);
253 
254  if (0 != api_rpath->rpath.frp_fib_index)
255  {
256  if ((DPO_PROTO_IP6 == api_rpath->rpath.frp_proto) ||
257  (DPO_PROTO_IP4 == api_rpath->rpath.frp_proto))
258  {
259  fib_table_t *fib;
260 
261  fib = fib_table_get (api_rpath->rpath.frp_fib_index,
262  dpo_proto_to_fib(api_rpath->rpath.frp_proto));
263 
264  out->table_id = htonl (fib->ft_table_id);
265  }
266  }
267 
268  if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_DVR)
269  {
270  out->is_dvr = 1;
271  }
272  if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_UDP_ENCAP)
273  {
274  out->is_udp_encap = 1;
275  out->next_hop_id = api_rpath->rpath.frp_udp_encap_id;
276  }
277 }
278 
281 {
282  switch (clib_net_to_host_u32 (af))
283  {
284  case ADDRESS_IP4:
285  return (FIB_PROTOCOL_IP4);
286  case ADDRESS_IP6:
287  return (FIB_PROTOCOL_IP6);
288  }
289 
290  ASSERT(0);
291  return (FIB_PROTOCOL_IP4);
292 }
293 
294 int
296 {
297  switch (fproto)
298  {
299  case FIB_PROTOCOL_IP4:
300  return (clib_net_to_host_u32 (ADDRESS_IP4));
301  case FIB_PROTOCOL_IP6:
302  return (clib_net_to_host_u32 (ADDRESS_IP6));
303  default:
304  break;
305  }
306 
307  ASSERT(0);
308  return (clib_net_to_host_u32 (ADDRESS_IP4));
309 }
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:437
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:35
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:584
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
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:191
unsigned char u8
Definition: types.h:56
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
memset(h->entries, 0, sizeof(h->entries[0])*entries)
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:280
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:295
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
u32 ft_table_id
Table ID (hash key) for this FIB.
Definition: fib_table.h:89
#define MPLS_LABEL_INVALID
Definition: mpls_types.h:48
#define clib_memcpy(a, b, c)
Definition: string.h:75
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:68
#define ASSERT(truth)
FIB path.
Definition: fib_types.api:47
u8 frp_preference
A path preference.
Definition: fib_types.h:563
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:567
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:217
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
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:47
fib_table_t * fib_table_get(fib_node_index_t index, fib_protocol_t proto)
Get a pointer to a FIB table.
Definition: fib_table.c:27
int fib_path_api_parse(const vl_api_fib_path_t *in, fib_route_path_t *out)
Definition: fib_api.c:42
fib_route_path_t rpath
Definition: fib_types.h:585
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:172
u8 frp_weight
[un]equal cost path weight
Definition: fib_types.h:557
u32 frp_udp_encap_id
UDP encap ID.
Definition: fib_types.h:547
#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
A protocol Independent FIB table.
Definition: fib_table.h:69