FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
flow.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 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 <vnet/ip/ip.h>
18 #include <vnet/ethernet/ethernet.h>
19 #include <vnet/flow/flow.h>
20 
22 
23 int
24 vnet_flow_get_range (vnet_main_t * vnm, char *owner, u32 count, u32 * start)
25 {
28 
29  /* skip 0 */
30  if (fm->flows_used == 0)
31  fm->flows_used = 1;
32 
33  *start = fm->flows_used;
34  fm->flows_used += count;
35  vec_add2 (fm->ranges, r, 1);
36  r->start = *start;
37  r->count = count;
38  r->owner = format (0, "%s%c", owner, 0);
39  return 0;
40 }
41 
42 int
43 vnet_flow_add (vnet_main_t * vnm, vnet_flow_t * flow, u32 * flow_index)
44 {
46  vnet_flow_t *f;
47 
48  pool_get (fm->global_flow_pool, f);
49  *flow_index = f - fm->global_flow_pool;
50  clib_memcpy_fast (f, flow, sizeof (vnet_flow_t));
51  f->private_data = 0;
52  f->index = *flow_index;
53  return 0;
54 }
55 
57 vnet_get_flow (u32 flow_index)
58 {
60  if (pool_is_free_index (fm->global_flow_pool, flow_index))
61  return 0;
62 
63  return pool_elt_at_index (fm->global_flow_pool, flow_index);
64 }
65 
66 int
67 vnet_flow_del (vnet_main_t * vnm, u32 flow_index)
68 {
70  vnet_flow_t *f = vnet_get_flow (flow_index);
71  uword hw_if_index;
72  uword private_data;
73 
74  if (f == 0)
75  return VNET_FLOW_ERROR_NO_SUCH_ENTRY;
76 
77  /* *INDENT-OFF* */
78  hash_foreach (hw_if_index, private_data, f->private_data,
79  ({
80  vnet_flow_disable (vnm, flow_index, hw_if_index);
81  }));
82  /* *INDENT-ON* */
83 
84  hash_free (f->private_data);
85  clib_memset (f, 0, sizeof (*f));
86  pool_put (fm->global_flow_pool, f);
87  return 0;
88 }
89 
90 int
91 vnet_flow_enable (vnet_main_t * vnm, u32 flow_index, u32 hw_if_index)
92 {
93  vnet_flow_t *f = vnet_get_flow (flow_index);
95  vnet_device_class_t *dev_class;
96  uword private_data;
97  int rv;
98 
99  if (f == 0)
100  return VNET_FLOW_ERROR_NO_SUCH_ENTRY;
101 
102  if (!vnet_hw_interface_is_valid (vnm, hw_if_index))
103  return VNET_FLOW_ERROR_NO_SUCH_INTERFACE;
104 
105  /* don't enable flow twice */
106  if (hash_get (f->private_data, hw_if_index) != 0)
107  return VNET_FLOW_ERROR_ALREADY_DONE;
108 
109  hi = vnet_get_hw_interface (vnm, hw_if_index);
110  dev_class = vnet_get_device_class (vnm, hi->dev_class_index);
111 
112  if (dev_class->flow_ops_function == 0)
113  return VNET_FLOW_ERROR_NOT_SUPPORTED;
114 
115  if (f->actions & VNET_FLOW_ACTION_REDIRECT_TO_NODE)
116  {
117  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
118  f->redirect_device_input_next_index =
120  f->redirect_node_index);
121  }
122 
123  rv = dev_class->flow_ops_function (vnm, VNET_FLOW_DEV_OP_ADD_FLOW,
124  hi->dev_instance, flow_index,
125  &private_data);
126 
127  if (rv)
128  return rv;
129 
130  hash_set (f->private_data, hw_if_index, private_data);
131  return 0;
132 }
133 
134 int
135 vnet_flow_disable (vnet_main_t * vnm, u32 flow_index, u32 hw_if_index)
136 {
137  vnet_flow_t *f = vnet_get_flow (flow_index);
139  vnet_device_class_t *dev_class;
140  uword *p;
141  int rv;
142 
143  if (f == 0)
144  return VNET_FLOW_ERROR_NO_SUCH_ENTRY;
145 
146  if (!vnet_hw_interface_is_valid (vnm, hw_if_index))
147  return VNET_FLOW_ERROR_NO_SUCH_INTERFACE;
148 
149  /* don't disable if not enabled */
150  if ((p = hash_get (f->private_data, hw_if_index)) == 0)
151  return VNET_FLOW_ERROR_ALREADY_DONE;
152 
153  hi = vnet_get_hw_interface (vnm, hw_if_index);
154  dev_class = vnet_get_device_class (vnm, hi->dev_class_index);
155 
156  rv = dev_class->flow_ops_function (vnm, VNET_FLOW_DEV_OP_DEL_FLOW,
157  hi->dev_instance, flow_index, p);
158 
159  if (rv)
160  return rv;
161 
162  hash_unset (f->private_data, hw_if_index);
163  return 0;
164 }
165 
166 /*
167  * fd.io coding-style-patch-verification: ON
168  *
169  * Local Variables:
170  * eval: (c-set-style "gnu")
171  * End:
172  */
vnet_flow_enable
int vnet_flow_enable(vnet_main_t *vnm, u32 flow_index, u32 hw_if_index)
Definition: flow.c:91
vnet_flow_del
int vnet_flow_del(vnet_main_t *vnm, u32 flow_index)
Definition: flow.c:67
vnet_device_class_t
struct _vnet_device_class vnet_device_class_t
vlib_node_add_next
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:1177
flow_main
vnet_flow_main_t flow_main
Definition: flow.c:21
vnet_get_flow
vnet_flow_t * vnet_get_flow(u32 flow_index)
Definition: flow.c:57
f
vlib_frame_t * f
Definition: interface_output.c:1080
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:553
pool_put
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:305
vnet_flow_range_t
Definition: flow.h:264
fm
vnet_feature_main_t * fm
Definition: nat44_ei_hairpinning.c:589
flow
Definition: flow_types.api:196
hi
vl_api_ip4_address_t hi
Definition: arp.api:37
vnet_get_device_class
static vnet_device_class_t * vnet_get_device_class(vnet_main_t *vnm, u32 dev_class_index)
Definition: interface_funcs.h:124
r
vnet_hw_if_output_node_runtime_t * r
Definition: interface_output.c:1071
clib_memcpy_fast
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
Definition: string.h:92
ethernet.h
pool_is_free_index
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:302
hash_set
#define hash_set(h, key, value)
Definition: hash.h:255
count
u8 count
Definition: dhcp.api:208
vec_add2
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:644
hash_free
#define hash_free(h)
Definition: hash.h:310
vnet_get_hw_interface
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface_funcs.h:44
uword
u64 uword
Definition: types.h:112
hash_get
#define hash_get(h, key)
Definition: hash.h:249
vnet_hw_interface_is_valid
static uword vnet_hw_interface_is_valid(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface_funcs.h:258
hash_foreach
#define hash_foreach(key_var, value_var, h, body)
Definition: hash.h:441
vnet_flow_disable
int vnet_flow_disable(vnet_main_t *vnm, u32 flow_index, u32 hw_if_index)
Definition: flow.c:135
pool_get
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:255
vnet_main_t::vlib_main
vlib_main_t * vlib_main
Definition: vnet.h:111
VNET_FLOW_DEV_OP_DEL_FLOW
@ VNET_FLOW_DEV_OP_DEL_FLOW
Definition: interface.h:99
vnet_flow_t
Definition: flow.h:215
VNET_FLOW_DEV_OP_ADD_FLOW
@ VNET_FLOW_DEV_OP_ADD_FLOW
Definition: interface.h:98
vnet_hw_interface_t
Definition: interface.h:638
vnet_main_t
Definition: vnet.h:76
format
description fragment has unexpected format
Definition: map.api:433
vnet_flow_get_range
int vnet_flow_get_range(vnet_main_t *vnm, char *owner, u32 count, u32 *start)
Definition: flow.c:24
ip.h
u32
unsigned int u32
Definition: types.h:88
hash_unset
#define hash_unset(h, key)
Definition: hash.h:261
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
vnet_flow_main_t
Definition: flow.h:271
rv
int __clib_unused rv
Definition: application.c:491
vnet_hw_interface_t::input_node_index
u32 input_node_index
Definition: interface.h:718
vnet.h
vnet_flow_add
int vnet_flow_add(vnet_main_t *vnm, vnet_flow_t *flow, u32 *flow_index)
Definition: flow.c:43
flow.h