FD.io VPP  v21.01.1
Vector Packet Processing
flow_api.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * flow_api.c - flow api
4  *
5  * Copyright (c) 2020 Intel and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19 
20 #include <stddef.h>
21 
22 #include <vnet/vnet.h>
23 #include <vlibmemory/api.h>
24 #include <vnet/interface.h>
25 #include <vnet/api_errno.h>
26 #include <vnet/flow/flow.h>
27 #include <vnet/fib/fib_table.h>
28 #include <vnet/udp/udp_local.h>
30 #include <vnet/ip/ip_types_api.h>
31 #include <vnet/vnet_msg_enum.h>
32 
33 #define vl_typedefs /* define message structures */
34 #include <vnet/vnet_all_api_h.h>
35 #undef vl_typedefs
36 
37 #define vl_endianfun /* define message structures */
38 #include <vnet/vnet_all_api_h.h>
39 #undef vl_endianfun
40 
41 /* instantiate all the print functions we know about */
42 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
43 #define vl_printfun
44 #include <vnet/vnet_all_api_h.h>
45 #undef vl_printfun
46 
48 
49 #define foreach_vpe_api_msg \
50 _(FLOW_ADD, flow_add) \
51 _(FLOW_DEL, flow_del) \
52 _(FLOW_ENABLE, flow_enable) \
53 _(FLOW_DISABLE, flow_disable)
54 
55 static inline void
56 ipv4_addr_and_mask_convert (vl_api_ip4_address_and_mask_t * vl_api_addr,
57  ip4_address_and_mask_t * vnet_addr)
58 {
59  clib_memcpy (vnet_addr, vl_api_addr, sizeof (*vnet_addr));
60 }
61 
62 static inline void
63 ipv6_addr_and_mask_convert (vl_api_ip6_address_and_mask_t * vl_api_addr,
64  ip6_address_and_mask_t * vnet_addr)
65 {
66  clib_memcpy (vnet_addr, vl_api_addr, sizeof (*vnet_addr));
67 }
68 
69 static inline void
70 protocol_and_mask_convert (vl_api_ip_prot_and_mask_t * vl_api_protocol,
71  ip_prot_and_mask_t * vnet_protocol)
72 {
73  vnet_protocol->prot = (ip_protocol_t) vl_api_protocol->prot;
74  vnet_protocol->mask = vl_api_protocol->mask;
75 }
76 
77 static inline void
78 port_and_mask_convert (vl_api_ip_port_and_mask_t * vl_api_port,
79  ip_port_and_mask_t * vnet_port)
80 {
81  vnet_port->port = ntohs (vl_api_port->port);
82  vnet_port->mask = ntohs (vl_api_port->mask);
83 }
84 
85 static inline void
86 ipv4_n_tuple_flow_convert (vl_api_flow_ip4_n_tuple_t * vl_api_flow,
87  vnet_flow_ip4_n_tuple_t * f)
88 {
89  ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
90  ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
91  protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
92 
93  port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
94  port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
95 }
96 
97 static void
98 ipv6_n_tuple_flow_convert (vl_api_flow_ip6_n_tuple_t * vl_api_flow,
99  vnet_flow_ip6_n_tuple_t * f)
100 {
101  ipv6_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
102  ipv6_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
103  protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
104 
105  port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
106  port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
107 }
108 
109 static inline void
110 ipv4_n_tuple_tagged_flow_convert (vl_api_flow_ip4_n_tuple_tagged_t *
111  vl_api_flow,
112  vnet_flow_ip4_n_tuple_tagged_t * f)
113 {
114  return ipv4_n_tuple_flow_convert ((vl_api_flow_ip4_n_tuple_t *) vl_api_flow,
115  (vnet_flow_ip4_n_tuple_t *) f);
116 }
117 
118 static inline void
119 ipv6_n_tuple_tagged_flow_convert (vl_api_flow_ip6_n_tuple_tagged_t *
120  vl_api_flow,
121  vnet_flow_ip6_n_tuple_tagged_t * f)
122 {
123  return ipv6_n_tuple_flow_convert ((vl_api_flow_ip6_n_tuple_t *) vl_api_flow,
124  (vnet_flow_ip6_n_tuple_t *) f);
125 }
126 
127 static inline void
128 ipv4_l2tpv3oip_flow_convert (vl_api_flow_ip4_l2tpv3oip_t * vl_api_flow,
129  vnet_flow_ip4_l2tpv3oip_t * f)
130 {
131  ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
132  ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
133 
134  protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
135  f->session_id = ntohl (vl_api_flow->session_id);
136 }
137 
138 static inline void
139 ipv4_ipsec_esp_flow_convert (vl_api_flow_ip4_ipsec_esp_t * vl_api_flow,
140  vnet_flow_ip4_ipsec_esp_t * f)
141 {
142  ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
143  ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
144 
145  protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
146  f->spi = ntohl (vl_api_flow->spi);
147 }
148 
149 static inline void
150 ipv4_ipsec_ah_flow_convert (vl_api_flow_ip4_ipsec_ah_t * vl_api_flow,
151  vnet_flow_ip4_ipsec_ah_t * f)
152 {
153  ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
154  ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
155 
156  protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
157  f->spi = ntohl (vl_api_flow->spi);
158 }
159 
160 static inline void
161 ipv4_gtpu_flow_convert (vl_api_flow_ip4_gtpu_t * vl_api_flow,
162  vnet_flow_ip4_gtpu_t * f)
163 {
164  ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
165  ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
166 
167  port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
168  port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
169 
170  protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
171  f->teid = ntohl (vl_api_flow->teid);
172 }
173 
174 static inline void
175 ipv4_gtpc_flow_convert (vl_api_flow_ip4_gtpc_t * vl_api_flow,
176  vnet_flow_ip4_gtpc_t * f)
177 {
178  ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
179  ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
180 
181  port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
182  port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
183 
184  protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
185  f->teid = ntohl (vl_api_flow->teid);
186 }
187 
188 static void
190 {
192  int rv = 0;
194  u32 flow_index = ~0;
195  vl_api_flow_rule_t *f = &mp->flow;
196 
197  vnet_main_t *vnm = vnet_get_main ();
198 
199  flow.type = ntohl (f->type);
200  flow.actions = ntohl (f->actions);
201  flow.mark_flow_id = ntohl (f->mark_flow_id);
202  flow.redirect_node_index = ntohl (f->redirect_node_index);
204  ntohl (f->redirect_device_input_next_index);
205  flow.redirect_queue = ntohl (f->redirect_queue);
206  flow.buffer_advance = ntohl (f->buffer_advance);
207 
208  switch (flow.type)
209  {
210  case VNET_FLOW_TYPE_IP4_N_TUPLE:
211  ipv4_n_tuple_flow_convert (&f->flow.ip4_n_tuple, &flow.ip4_n_tuple);
212  break;
213  case VNET_FLOW_TYPE_IP6_N_TUPLE:
214  ipv6_n_tuple_flow_convert (&f->flow.ip6_n_tuple, &flow.ip6_n_tuple);
215  break;
216  case VNET_FLOW_TYPE_IP4_N_TUPLE_TAGGED:
217  ipv4_n_tuple_tagged_flow_convert (&f->flow.ip4_n_tuple_tagged,
218  &flow.ip4_n_tuple_tagged);
219  break;
220  case VNET_FLOW_TYPE_IP6_N_TUPLE_TAGGED:
221  ipv6_n_tuple_tagged_flow_convert (&f->flow.ip6_n_tuple_tagged,
222  &flow.ip6_n_tuple_tagged);
223  break;
224  case VNET_FLOW_TYPE_IP4_L2TPV3OIP:
225  ipv4_l2tpv3oip_flow_convert (&f->flow.ip4_l2tpv3oip,
226  &flow.ip4_l2tpv3oip);
227  break;
228  case VNET_FLOW_TYPE_IP4_IPSEC_ESP:
229  ipv4_ipsec_esp_flow_convert (&f->flow.ip4_ipsec_esp,
230  &flow.ip4_ipsec_esp);
231  break;
232  case VNET_FLOW_TYPE_IP4_IPSEC_AH:
233  ipv4_ipsec_ah_flow_convert (&f->flow.ip4_ipsec_ah, &flow.ip4_ipsec_ah);
234  break;
235  case VNET_FLOW_TYPE_IP4_GTPU:
236  ipv4_gtpu_flow_convert (&f->flow.ip4_gtpu, &flow.ip4_gtpu);
237  break;
238  case VNET_FLOW_TYPE_IP4_GTPC:
239  ipv4_gtpc_flow_convert (&f->flow.ip4_gtpc, &flow.ip4_gtpc);
240  break;
241  default:
242  rv = VNET_FLOW_ERROR_NOT_SUPPORTED;
243  goto out;
244  break;
245  }
246 
247  rv = vnet_flow_add (vnm, &flow, &flow_index);
248 
249 out:
250  /* *INDENT-OFF* */
251  REPLY_MACRO2(VL_API_FLOW_ADD_REPLY,
252  ({
253  rmp->flow_index = ntohl (flow_index);
254  }));
255  /* *INDENT-ON* */
256 }
257 
258 static void
260 {
262  int rv = 0;
263 
264  vnet_main_t *vnm = vnet_get_main ();
265  rv = vnet_flow_del (vnm, ntohl (mp->flow_index));
266 
267  REPLY_MACRO (VL_API_FLOW_DEL_REPLY);
268 }
269 
270 static void
272 {
274  int rv = 0;
275 
276  vnet_main_t *vnm = vnet_get_main ();
277  rv =
278  vnet_flow_enable (vnm, ntohl (mp->flow_index), ntohl (mp->hw_if_index));
279 
280  REPLY_MACRO (VL_API_FLOW_ENABLE_REPLY);
281 }
282 
283 static void
285 {
287  int rv = 0;
288 
289  vnet_main_t *vnm = vnet_get_main ();
290  rv =
291  vnet_flow_disable (vnm, ntohl (mp->flow_index), ntohl (mp->hw_if_index));
292 
293  REPLY_MACRO (VL_API_FLOW_DISABLE_REPLY);
294 }
295 
296 #define vl_msg_name_crc_list
297 #include <vnet/flow/flow.api.h>
298 #undef vl_msg_name_crc_list
299 
300 /*
301  * flow_api_hookup
302  * Add vpe's API message handlers to the table.
303  * vlib has already mapped shared memory and
304  * added the client registration handlers.
305  * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
306  */
307 
308 
309 static void
311 {
312 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
313  foreach_vl_msg_name_crc_flow;
314 #undef _
315 }
316 
317 static clib_error_t *
319 {
320  api_main_t *am = vlibapi_get_main ();
321 
322 #define _(N,n) \
323  vl_msg_api_set_handlers(VL_API_##N, #n, \
324  vl_api_##n##_t_handler, \
325  vl_noop_handler, \
326  vl_api_##n##_t_endian, \
327  vl_api_##n##_t_print, \
328  sizeof(vl_api_##n##_t), 1);
330 #undef _
331 
332  /*
333  * Set up the (msg_name, crc, message-id) table
334  */
336 
337  return 0;
338 }
339 
341 
342 /*
343  * fd.io coding-style-patch-verification: ON
344  *
345  * Local Variables:
346  * eval: (c-set-style "gnu")
347  * End:
348  */
vl_api_flow_rule_t flow
Definition: flow.api:31
static void ipv6_addr_and_mask_convert(vl_api_ip6_address_and_mask_t *vl_api_addr, ip6_address_and_mask_t *vnet_addr)
Definition: flow_api.c:63
vnet_flow_type_t type
Definition: flow.h:220
#define ntohs(x)
Definition: af_xdp.bpf.c:29
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
static void vl_api_flow_del_t_handler(vl_api_flow_del_t *mp)
Definition: flow_api.c:259
reply for adding flow
Definition: flow.api:40
#define REPLY_MACRO2(t, body)
static void vl_api_flow_add_t_handler(vl_api_flow_add_t *mp)
Definition: flow_api.c:189
vlib_main_t * vm
Definition: in2out_ed.c:1580
static void ipv4_ipsec_ah_flow_convert(vl_api_flow_ip4_ipsec_ah_t *vl_api_flow, vnet_flow_ip4_ipsec_ah_t *f)
Definition: flow_api.c:150
int vnet_flow_disable(vnet_main_t *vnm, u32 flow_index, u32 hw_if_index)
Definition: flow.c:135
static void ipv4_addr_and_mask_convert(vl_api_ip4_address_and_mask_t *vl_api_addr, ip4_address_and_mask_t *vnet_addr)
Definition: flow_api.c:56
static void vl_api_flow_disable_t_handler(vl_api_flow_disable_t *mp)
Definition: flow_api.c:284
static void setup_message_id_table(api_main_t *am)
Definition: flow_api.c:310
u32 redirect_node_index
Definition: flow.h:232
static void ipv4_gtpc_flow_convert(vl_api_flow_ip4_gtpc_t *vl_api_flow, vnet_flow_ip4_gtpc_t *f)
Definition: flow_api.c:175
ip_protocol_t prot
Definition: flow.h:180
#define clib_memcpy(d, s, n)
Definition: string.h:180
static void vl_api_flow_enable_t_handler(vl_api_flow_enable_t *mp)
Definition: flow_api.c:271
flow del request
Definition: flow.api:52
u32 mark_flow_id
Definition: flow.h:229
unsigned int u32
Definition: types.h:88
int vnet_flow_del(vnet_main_t *vnm, u32 flow_index)
Definition: flow.c:67
static void ipv4_ipsec_esp_flow_convert(vl_api_flow_ip4_ipsec_esp_t *vl_api_flow, vnet_flow_ip4_ipsec_esp_t *f)
Definition: flow_api.c:139
enum ip_protocol ip_protocol_t
static void ipv4_l2tpv3oip_flow_convert(vl_api_flow_ip4_l2tpv3oip_t *vl_api_flow, vnet_flow_ip4_l2tpv3oip_t *f)
Definition: flow_api.c:128
u32 redirect_queue
Definition: flow.h:236
static void ipv4_n_tuple_tagged_flow_convert(vl_api_flow_ip4_n_tuple_tagged_t *vl_api_flow, vnet_flow_ip4_n_tuple_tagged_t *f)
Definition: flow_api.c:110
flow add request
Definition: flow.api:27
static void ipv4_n_tuple_flow_convert(vl_api_flow_ip4_n_tuple_t *vl_api_flow, vnet_flow_ip4_n_tuple_t *f)
Definition: flow_api.c:86
#define REPLY_MACRO(t)
static clib_error_t * hw_flow_api_hookup(vlib_main_t *vm)
Definition: flow_api.c:318
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:227
i32 buffer_advance
Definition: flow.h:239
u32 actions
Definition: flow.h:226
static void ipv6_n_tuple_tagged_flow_convert(vl_api_flow_ip6_n_tuple_tagged_t *vl_api_flow, vnet_flow_ip6_n_tuple_tagged_t *f)
Definition: flow_api.c:119
flow disable request
Definition: flow.api:81
static void port_and_mask_convert(vl_api_ip_port_and_mask_t *vl_api_port, ip_port_and_mask_t *vnet_port)
Definition: flow_api.c:78
int vnet_flow_add(vnet_main_t *vnm, vnet_flow_t *flow, u32 *flow_index)
Definition: flow.c:43
vl_api_flow_t flow
Definition: flow_types.api:240
static void ipv4_gtpu_flow_convert(vl_api_flow_ip4_gtpu_t *vl_api_flow, vnet_flow_ip4_gtpu_t *f)
Definition: flow_api.c:161
static void protocol_and_mask_convert(vl_api_ip_prot_and_mask_t *vl_api_protocol, ip_prot_and_mask_t *vnet_protocol)
Definition: flow_api.c:70
VLIB_API_INIT_FUNCTION(hw_flow_api_hookup)
static void ipv6_n_tuple_flow_convert(vl_api_flow_ip6_n_tuple_t *vl_api_flow, vnet_flow_ip6_n_tuple_t *f)
Definition: flow_api.c:98
int vnet_flow_enable(vnet_main_t *vnm, u32 flow_index, u32 hw_if_index)
Definition: flow.c:91
static api_main_t * vlibapi_get_main(void)
Definition: api_common.h:389
u32 redirect_device_input_next_index
Definition: flow.h:233
#define foreach_vpe_api_msg
Definition: flow_api.c:49
flow enable request
Definition: flow.api:66