FD.io VPP  v18.04-17-g3a0d853
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_fib_index = ntohl(in->table_id);
59  out->frp_weight = in->weight;
60  out->frp_preference = in->preference;
61 
62  /*
63  * the special INVALID label meams we are not recursing via a
64  * label. Exp-null value is never a valid via-label so that
65  * also means it's not a via-label and means clients that set
66  * it to 0 by default get the expected behaviour
67  */
68  if ((MPLS_LABEL_INVALID != next_hop_via_label) &&
69  (0 != next_hop_via_label))
70  {
72  out->frp_local_label = next_hop_via_label;
73  out->frp_eos = MPLS_NON_EOS;
74  }
75 
76  n_labels = in->n_labels;
77  if (n_labels == 0)
78  ;
79  else
80  {
81  vec_validate (out->frp_label_stack, n_labels - 1);
82  for (ii = 0; ii < n_labels; ii++)
83  {
84  out->frp_label_stack[ii].fml_value =
85  ntohl(in->label_stack[ii].label);
86  out->frp_label_stack[ii].fml_ttl =
87  in->label_stack[ii].ttl;
88  out->frp_label_stack[ii].fml_exp =
89  in->label_stack[ii].exp;
90  out->frp_label_stack[ii].fml_mode =
91  (in->label_stack[ii].is_uniform ?
94  }
95  }
96 
97  if (in->is_dvr)
98  path_flags |= FIB_ROUTE_PATH_DVR;
99  if (in->is_resolve_host)
100  path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_HOST;
101  if (in->is_resolve_attached)
103  /* if (in->is_interface_rx) */
104  /* path_flags |= FIB_ROUTE_PATH_INTF_RX; */
105  /* if (in->is_rpf_id) */
106  /* path_flags |= FIB_ROUTE_PATH_RPF_ID; */
107  if (in->is_source_lookup)
108  path_flags |= FIB_ROUTE_PATH_SOURCE_LOOKUP;
109 
110  if (in->is_udp_encap)
111  {
112  path_flags |= FIB_ROUTE_PATH_UDP_ENCAP;
113  out->frp_udp_encap_id = ntohl(in->next_hop_id);
114  }
115  else
116  {
117  if (DPO_PROTO_IP4 == in->afi)
118  {
119  clib_memcpy (&out->frp_addr.ip4,
120  in->next_hop,
121  sizeof (out->frp_addr.ip4));
122  }
123  else if (DPO_PROTO_IP6 == in->afi)
124  {
125  clib_memcpy (&out->frp_addr.ip6,
126  in->next_hop,
127  sizeof (out->frp_addr.ip6));
128  }
129 
130  if (ip46_address_is_zero(&out->frp_addr))
131  {
132  if (DPO_PROTO_BIER == in->afi)
133  {
134  index_t bdti;
135 
136  bdti = bier_disp_table_find(ntohl(in->table_id));
137 
138  if (INDEX_INVALID != bdti)
139  {
140  out->frp_fib_index = bdti;
141  out->frp_proto = DPO_PROTO_BIER;
142  }
143  else
144  {
145  rv = VNET_API_ERROR_NO_SUCH_FIB;
146  }
147  }
148  else if (out->frp_sw_if_index == ~0 &&
149  out->frp_fib_index != ~0)
150  {
151  path_flags |= FIB_ROUTE_PATH_DEAG;
152  }
153  }
154  }
155 
156  out->frp_flags = path_flags;
157 
158  return (rv);
159 }
160 
161 void
163  u8 address[16],
164  u8 *length,
165  u8 *is_ip6)
166 {
167  *length = pfx->fp_len;
168  *is_ip6 = (FIB_PROTOCOL_IP6 == pfx->fp_proto ? 1 : 0);
169 
170  if (FIB_PROTOCOL_IP6 == pfx->fp_proto)
171  {
172  memcpy (address, &pfx->fp_addr.ip6, sizeof (pfx->fp_addr.ip6));
173  }
174  else
175  {
176  memcpy (address, &pfx->fp_addr.ip4, sizeof (pfx->fp_addr.ip4));
177  }
178 }
179 
180 static void
181 fib_api_path_copy_next_hop (const fib_route_path_encode_t * api_rpath, void *fp_arg)
182 {
183  int is_ip4;
184  vl_api_fib_path_t *fp = (vl_api_fib_path_t *) fp_arg;
185 
186  if (api_rpath->rpath.frp_proto == DPO_PROTO_IP4)
187  fp->afi = IP46_TYPE_IP4;
188  else if (api_rpath->rpath.frp_proto == DPO_PROTO_IP6)
189  fp->afi = IP46_TYPE_IP6;
190  else
191  {
192  is_ip4 = ip46_address_is_ip4 (&api_rpath->rpath.frp_addr);
193  if (is_ip4)
194  fp->afi = IP46_TYPE_IP4;
195  else
196  fp->afi = IP46_TYPE_IP6;
197  }
198  if (fp->afi == IP46_TYPE_IP4)
199  memcpy (fp->next_hop, &api_rpath->rpath.frp_addr.ip4,
200  sizeof (api_rpath->rpath.frp_addr.ip4));
201  else
202  memcpy (fp->next_hop, &api_rpath->rpath.frp_addr.ip6,
203  sizeof (api_rpath->rpath.frp_addr.ip6));
204 }
205 
206 void
208  vl_api_fib_path_t *out)
209 {
210  memset (out, 0, sizeof (*out));
211  switch (api_rpath->dpo.dpoi_type)
212  {
213  case DPO_RECEIVE:
214  out->is_local = true;
215  break;
216  case DPO_DROP:
217  out->is_drop = true;
218  break;
219  case DPO_IP_NULL:
220  switch (ip_null_dpo_get_action(api_rpath->dpo.dpoi_index))
221  {
222  case IP_NULL_ACTION_NONE:
223  out->is_drop = true;
224  break;
226  out->is_unreach = true;
227  break;
229  out->is_prohibit = true;
230  break;
231  default:
232  break;
233  }
234  break;
235  default:
236  break;
237  }
238  out->weight = api_rpath->rpath.frp_weight;
239  out->preference = api_rpath->rpath.frp_preference;
240  out->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
241  out->afi = api_rpath->rpath.frp_proto;
242  fib_api_path_copy_next_hop (api_rpath, out);
243 
244  if (~0 == api_rpath->rpath.frp_sw_if_index &&
245  !ip46_address_is_zero(&api_rpath->rpath.frp_addr))
246  {
247  if ((DPO_PROTO_IP6 == api_rpath->rpath.frp_proto) ||
248  (DPO_PROTO_IP4 == api_rpath->rpath.frp_proto))
249  {
250  fib_table_t *fib;
251 
252  fib = fib_table_get (api_rpath->rpath.frp_fib_index,
253  dpo_proto_to_fib(api_rpath->rpath.frp_proto));
254 
255  out->table_id = htonl (fib->ft_table_id);
256  }
257  }
258 
259  if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_DVR)
260  {
261  out->is_dvr = 1;
262  }
263  if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_UDP_ENCAP)
264  {
265  out->is_udp_encap = 1;
266  out->next_hop_id = api_rpath->rpath.frp_udp_encap_id;
267  }
268 }
269 
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:434
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:197
ip46_address_t frp_addr
The next-hop address.
Definition: fib_types.h:471
A path that resolves via a DVR DPO.
Definition: fib_types.h:366
Pipe Mode - the default.
Definition: fib_types.h:389
A representation of a fib path for fib_path_encode to convey the information to the caller...
Definition: fib_types.h:564
mpls_eos_bit_t frp_eos
EOS bit for the resolving label.
Definition: fib_types.h:482
A representation of a path as described by a route producer.
Definition: fib_types.h:455
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:460
static void fib_api_path_copy_next_hop(const fib_route_path_encode_t *api_rpath, void *fp_arg)
Definition: fib_api.c:181
u32 frp_sw_if_index
The interface.
Definition: fib_types.h:490
Recursion constraint of via a host prefix.
Definition: fib_types.h:309
Aggregrate type for a prefix.
Definition: fib_types.h:188
A path via a UDP encap object.
Definition: fib_types.h:346
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:252
u16 fp_len
The mask length.
Definition: fib_types.h:192
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:211
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:510
Recursion constraint of via an attahced prefix.
Definition: fib_types.h:313
fib_mpls_lsp_mode_t fml_mode
The LSP mode.
Definition: fib_types.h:420
#define ip46_address_is_ip4(ip46)
Definition: ip6_packet.h:76
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:415
index_t bier_disp_table_find(u32 table_id)
vl_api_fib_mpls_label_t label_stack[16]
Definition: fib_types.api:68
FIB path.
Definition: fib_types.api:47
u8 frp_preference
A path preference.
Definition: fib_types.h:543
A deag path using the packet&#39;s source not destination address.
Definition: fib_types.h:342
fib_route_path_flags_t frp_flags
flags on the path
Definition: fib_types.h:547
A path that resolves via another table.
Definition: fib_types.h:362
void fib_api_path_encode(const fib_route_path_encode_t *api_rpath, vl_api_fib_path_t *out)
Definition: fib_api.c:207
mpls_label_t frp_local_label
The MPLS local Label to reursively resolve through.
Definition: fib_types.h:478
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:184
unsigned char u8
Definition: types.h:56
#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:565
u8 fml_exp
EXP bits; valid only at imposition.
Definition: fib_types.h:430
void fib_prefix_to_api(const fib_prefix_t *pfx, u8 address[16], u8 *length, u8 *is_ip6)
Definition: fib_api.c:162
u8 frp_weight
[un]equal cost path weight
Definition: fib_types.h:537
u32 frp_udp_encap_id
UDP encap ID.
Definition: fib_types.h:527
#define ip46_address_is_zero(ip46)
Definition: ip6_packet.h:81
u32 frp_fib_index
The FIB index to lookup the nexthop Only valid for recursive paths.
Definition: fib_types.h:501
Definition: dpo.h:96
A protocol Independent FIB table.
Definition: fib_table.h:69