Hybrid ICN (hICN) plugin  v21.06-rc0-4-g18fa668
data_fwd.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2020 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 #ifndef __HICN_DATA_FWD_H__
17 #define __HICN_DATA_FWD_H__
18 
19 #include <vlib/buffer.h>
20 
21 #include "pcs.h"
22 
46 /* Trace context struct */
47 typedef struct
48 {
49  u32 next_index;
50  u32 sw_if_index;
51  u8 pkt_type;
52  u8 packet_data[64];
54 
55 typedef enum
56 {
57  HICN_DATA_FWD_NEXT_V4_LOOKUP,
58  HICN_DATA_FWD_NEXT_V6_LOOKUP,
59  HICN_DATA_FWD_NEXT_IFACE4_OUT,
60  HICN_DATA_FWD_NEXT_IFACE6_OUT,
61  HICN_DATA_FWD_NEXT_ERROR_DROP,
62  HICN_DATA_FWD_N_NEXT,
63 } hicn_data_fwd_next_t;
64 
80 always_inline u16
81 vlib_buffer_clone_256_2 (vlib_main_t *vm, u32 src_buffer, u32 *buffers,
82  u16 n_buffers, u16 head_end_offset)
83 {
84  u16 i;
85  vlib_buffer_t *s = vlib_get_buffer (vm, src_buffer);
86 
87  ASSERT (n_buffers);
88  ASSERT (n_buffers <= 256);
89 
90  if (s->current_length <= head_end_offset + CLIB_CACHE_LINE_BYTES * 2)
91  {
92  for (i = 0; i < n_buffers; i++)
93  {
94  vlib_buffer_t *d;
95  d = vlib_buffer_copy (vm, s);
96  if (d == 0)
97  return i;
98  buffers[i] = vlib_get_buffer_index (vm, d);
99  }
100  return n_buffers;
101  }
102  n_buffers =
103  vlib_buffer_alloc_from_pool (vm, buffers, n_buffers, s->buffer_pool_index);
104 
105  for (i = 0; i < n_buffers; i++)
106  {
107  vlib_buffer_t *d = vlib_get_buffer (vm, buffers[i]);
108  d->current_data = s->current_data;
109  d->current_length = head_end_offset;
110  d->trace_handle = s->trace_handle;
111 
112  d->total_length_not_including_first_buffer =
113  s->current_length - head_end_offset;
114  if (PREDICT_FALSE (s->flags & VLIB_BUFFER_NEXT_PRESENT))
115  {
116  d->total_length_not_including_first_buffer +=
117  s->total_length_not_including_first_buffer;
118  }
119  d->flags = s->flags | VLIB_BUFFER_NEXT_PRESENT;
120  d->flags &= ~VLIB_BUFFER_EXT_HDR_VALID;
121  d->trace_handle = s->trace_handle;
122  clib_memcpy_fast (d->opaque, s->opaque, sizeof (s->opaque));
123  clib_memcpy_fast (d->opaque2, s->opaque2, sizeof (s->opaque2));
124  clib_memcpy_fast (vlib_buffer_get_current (d),
125  vlib_buffer_get_current (s), head_end_offset);
126  d->next_buffer = src_buffer;
127  }
128  vlib_buffer_advance (s, head_end_offset);
129  s->ref_count = n_buffers;
130  while (s->flags & VLIB_BUFFER_NEXT_PRESENT)
131  {
132  s = vlib_get_buffer (vm, s->next_buffer);
133  s->ref_count = n_buffers;
134  }
135 
136  return n_buffers;
137 }
138 
153 always_inline u16
154 vlib_buffer_clone2 (vlib_main_t *vm, u32 src_buffer, u32 *buffers,
155  u16 n_buffers, u16 head_end_offset)
156 {
157  vlib_buffer_t *s = vlib_get_buffer (vm, src_buffer);
158 
159  /*
160  * total_length_not_including_first_buffer is not initialized to 0
161  * when a buffer is used.
162  */
163  if (PREDICT_TRUE (s->next_buffer == 0))
164  s->total_length_not_including_first_buffer = 0;
165 
166  u16 n_cloned = 0;
167  u8 n_clone_src = 255 - s->ref_count;
168 
169  /*
170  * We need to copy src for all the clones that cannot be chained in
171  * the src_buffer
172  */
173  /* MAX(ref_count) = 256 */
174  if (n_buffers > n_clone_src)
175  {
176  vlib_buffer_t *copy;
177  /* Ok to call the original vlib_buffer_copy. */
178  copy = vlib_buffer_copy (vm, s);
179  n_cloned +=
180  vlib_buffer_clone (vm, vlib_get_buffer_index (vm, copy), buffers,
181  n_buffers - n_clone_src, head_end_offset);
182  n_buffers -= n_cloned;
183  }
184  /*
185  * vlib_buffer_clone_256 check if ref_count is 0. We force it to be
186  * 0 before calling the function and we retore it to the right value
187  * after the function has been called
188  */
189  u8 tmp_ref_count = s->ref_count;
190 
191  s->ref_count = 1;
192  /*
193  * The regular vlib_buffer_clone_256 does copy if we need to clone
194  * only one packet. While this is not a problem per se, it adds
195  * complexity to the code, especially because we need to add 1 to
196  * ref_count when the packet is cloned.
197  */
198  n_cloned += vlib_buffer_clone_256_2 (vm, src_buffer, (buffers + n_cloned),
199  n_buffers, head_end_offset);
200 
201  s->ref_count += (tmp_ref_count - 1);
202 
203  return n_cloned;
204 }
205 
206 #endif /* //__HICN_DATA_FWD_H__ */
207 
208 /*
209  * fd.io coding-style-patch-verification: ON
210  *
211  * Local Variables: eval: (c-set-style "gnu") End:
212  */
hicn_data_fwd_trace_t
Definition: data_fwd.h:47
vlib_buffer_clone_256_2
always_inline u16 vlib_buffer_clone_256_2(vlib_main_t *vm, u32 src_buffer, u32 *buffers, u16 n_buffers, u16 head_end_offset)
Create a maximum of 256 clones of buffer and store them in the supplied array. Unlike the original fu...
Definition: data_fwd.h:81
vlib_buffer_clone2
always_inline u16 vlib_buffer_clone2(vlib_main_t *vm, u32 src_buffer, u32 *buffers, u16 n_buffers, u16 head_end_offset)
Create multiple clones of buffer and store them in the supplied array. Unlike the function in the vli...
Definition: data_fwd.h:154
pcs.h