FD.io VPP  v18.10-34-gcce845e
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 (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 
85  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 (!vnet_hw_interface_is_valid (vnm, hw_if_index))
100  return VNET_FLOW_ERROR_NO_SUCH_INTERFACE;
101 
102  /* don't enable flow twice */
103  if (hash_get (f->private_data, hw_if_index) != 0)
104  return VNET_FLOW_ERROR_ALREADY_DONE;
105 
106  hi = vnet_get_hw_interface (vnm, hw_if_index);
107  dev_class = vnet_get_device_class (vnm, hi->dev_class_index);
108 
109  if (dev_class->flow_ops_function == 0)
110  return VNET_FLOW_ERROR_NOT_SUPPORTED;
111 
112  if (f->actions & VNET_FLOW_ACTION_REDIRECT_TO_NODE)
113  {
114  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
118  }
119 
120  rv = dev_class->flow_ops_function (vnm, VNET_FLOW_DEV_OP_ADD_FLOW,
121  hi->dev_instance, flow_index,
122  &private_data);
123 
124  if (rv)
125  return rv;
126 
127  hash_set (f->private_data, hw_if_index, private_data);
128  return 0;
129 }
130 
131 int
132 vnet_flow_disable (vnet_main_t * vnm, u32 flow_index, u32 hw_if_index)
133 {
134  vnet_flow_t *f = vnet_get_flow (flow_index);
136  vnet_device_class_t *dev_class;
137  uword *p;
138  int rv;
139 
140  if (!vnet_hw_interface_is_valid (vnm, hw_if_index))
141  return VNET_FLOW_ERROR_NO_SUCH_INTERFACE;
142 
143  /* don't disable if not enabled */
144  if ((p = hash_get (f->private_data, hw_if_index)) == 0)
145  return VNET_FLOW_ERROR_ALREADY_DONE;
146 
147  hi = vnet_get_hw_interface (vnm, hw_if_index);
148  dev_class = vnet_get_device_class (vnm, hi->dev_class_index);
149 
150  rv = dev_class->flow_ops_function (vnm, VNET_FLOW_DEV_OP_DEL_FLOW,
151  hi->dev_instance, flow_index, p);
152 
153  if (rv)
154  return rv;
155 
156  hash_unset (f->private_data, hw_if_index);
157  return 0;
158 }
159 
160 /*
161  * fd.io coding-style-patch-verification: ON
162  *
163  * Local Variables:
164  * eval: (c-set-style "gnu")
165  * End:
166  */
vmrglw vmrglh hi
#define hash_set(h, key, value)
Definition: hash.h:255
int vnet_flow_get_range(vnet_main_t *vnm, char *owner, u32 count, u32 *start)
Definition: flow.c:24
#define hash_unset(h, key)
Definition: hash.h:261
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:562
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
vnet_flow_t * global_flow_pool
Definition: flow.h:171
struct _vnet_device_class vnet_device_class_t
int vnet_flow_disable(vnet_main_t *vnm, u32 flow_index, u32 hw_if_index)
Definition: flow.c:132
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:228
u32 redirect_node_index
Definition: flow.h:133
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:1118
#define fm
memset(h->entries, 0, sizeof(h->entries[0])*entries)
static vnet_device_class_t * vnet_get_device_class(vnet_main_t *vnm, u32 dev_class_index)
#define hash_foreach(key_var, value_var, h, body)
Definition: hash.h:442
vnet_flow_main_t flow_main
Definition: flow.c:21
unsigned int u32
Definition: types.h:88
vnet_flow_range_t * ranges
Definition: flow.h:177
int vnet_flow_del(vnet_main_t *vnm, u32 flow_index)
Definition: flow.c:67
#define hash_get(h, key)
Definition: hash.h:249
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:464
vlib_main_t * vlib_main
Definition: vnet.h:80
#define hash_free(h)
Definition: hash.h:310
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:274
vnet_flow_t * vnet_get_flow(u32 flow_index)
Definition: flow.c:57
u32 index
Definition: flow.h:124
u32 actions
Definition: flow.h:127
uword * private_data
Definition: flow.h:150
#define clib_memcpy(a, b, c)
Definition: string.h:75
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:271
static uword vnet_hw_interface_is_valid(vnet_main_t *vnm, u32 hw_if_index)
size_t count
Definition: vapi.c:46
int vnet_flow_add(vnet_main_t *vnm, vnet_flow_t *flow, u32 *flow_index)
Definition: flow.c:43
u32 flows_used
Definition: flow.h:174
u64 uword
Definition: types.h:112
int vnet_flow_enable(vnet_main_t *vnm, u32 flow_index, u32 hw_if_index)
Definition: flow.c:91
u32 redirect_device_input_next_index
Definition: flow.h:134
icmpr_flow_t * flow
Definition: main.c:123