FD.io VPP  v18.07.1-13-g909ba93
Vector Packet Processing
reply_node.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 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/dns/dns.h>
17 
18 #include <vlib/vlib.h>
19 #include <vnet/vnet.h>
20 
22 
23 typedef struct
24 {
28 
29 /* packet trace format function */
30 static u8 *
31 format_dns46_reply_trace (u8 * s, va_list * args)
32 {
33  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
34  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
35  dns46_reply_trace_t *t = va_arg (*args, dns46_reply_trace_t *);
36 
37  s = format (s, "DNS46_REPLY: pool index %d, disposition %d",
38  t->pool_index, t->disposition);
39  return s;
40 }
41 
43 
44 static char *dns46_reply_error_strings[] = {
45 #define _(sym,string) string,
47 #undef _
48 };
49 
50 typedef enum
51 {
56 
57 static uword
59  vlib_node_runtime_t * node, vlib_frame_t * frame)
60 {
61  u32 n_left_from, *from, *to_next;
62  dns46_reply_next_t next_index;
63  dns_main_t *dm = &dns_main;
64 
65  from = vlib_frame_vector_args (frame);
66  n_left_from = frame->n_vectors;
67  next_index = node->cached_next_index;
68 
69  while (n_left_from > 0)
70  {
71  u32 n_left_to_next;
72 
73  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
74 
75 #if 0
76  while (n_left_from >= 4 && n_left_to_next >= 2)
77  {
78  u32 next0 = DNS46_REPLY_NEXT_INTERFACE_OUTPUT;
79  u32 next1 = DNS46_REPLY_NEXT_INTERFACE_OUTPUT;
80  u32 sw_if_index0, sw_if_index1;
81  u8 tmp0[6], tmp1[6];
82  ethernet_header_t *en0, *en1;
83  u32 bi0, bi1;
84  vlib_buffer_t *b0, *b1;
85 
86  /* Prefetch next iteration. */
87  {
88  vlib_buffer_t *p2, *p3;
89 
90  p2 = vlib_get_buffer (vm, from[2]);
91  p3 = vlib_get_buffer (vm, from[3]);
92 
93  vlib_prefetch_buffer_header (p2, LOAD);
94  vlib_prefetch_buffer_header (p3, LOAD);
95 
98  }
99 
100  /* speculatively enqueue b0 and b1 to the current next frame */
101  to_next[0] = bi0 = from[0];
102  to_next[1] = bi1 = from[1];
103  from += 2;
104  to_next += 2;
105  n_left_from -= 2;
106  n_left_to_next -= 2;
107 
108  b0 = vlib_get_buffer (vm, bi0);
109  b1 = vlib_get_buffer (vm, bi1);
110 
111  /* $$$$$ End of processing 2 x packets $$$$$ */
112 
113  if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
114  {
115  if (b0->flags & VLIB_BUFFER_IS_TRACED)
116  {
118  vlib_add_trace (vm, node, b0, sizeof (*t));
119  t->sw_if_index = sw_if_index0;
120  t->next_index = next0;
121  }
122  if (b1->flags & VLIB_BUFFER_IS_TRACED)
123  {
125  vlib_add_trace (vm, node, b1, sizeof (*t));
126  t->sw_if_index = sw_if_index1;
127  t->next_index = next1;
128  }
129  }
130 
131  /* verify speculative enqueues, maybe switch current next frame */
132  vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
133  to_next, n_left_to_next,
134  bi0, bi1, next0, next1);
135  }
136 #endif
137 
138  while (n_left_from > 0 && n_left_to_next > 0)
139  {
140  u32 bi0;
141  vlib_buffer_t *b0;
142  u32 next0 = DNS46_REPLY_NEXT_DROP;
143  dns_header_t *d0;
144  u32 pool_index0 = ~0;
145  u32 error0 = 0;
146  u8 *resp0 = 0;
147 
148  /* speculatively enqueue b0 to the current next frame */
149  bi0 = from[0];
150  to_next[0] = bi0;
151  from += 1;
152  to_next += 1;
153  n_left_from -= 1;
154  n_left_to_next -= 1;
155 
156  b0 = vlib_get_buffer (vm, bi0);
157  d0 = vlib_buffer_get_current (b0);
158  if (PREDICT_FALSE (dm->is_enabled == 0))
159  {
160  next0 = DNS46_REPLY_NEXT_PUNT;
161  error0 = DNS46_REPLY_ERROR_DISABLED;
162  goto done0;
163  }
164 
165  pool_index0 = clib_host_to_net_u16 (d0->id);
166 
167  /* Save the reply */
168  vec_validate (resp0, vlib_buffer_length_in_chain (vm, b0) - 1);
169  clib_memcpy (resp0, d0, vlib_buffer_length_in_chain (vm, b0));
170 
171  /*
172  * Deal with everything in process ctx on the main thread
173  */
176  (uword) resp0);
177  error0 = DNS46_REPLY_ERROR_PROCESSED;
178 
179  done0:
180  b0->error = node->errors[error0];
181 
183  && (b0->flags & VLIB_BUFFER_IS_TRACED)))
184  {
186  vlib_add_trace (vm, node, b0, sizeof (*t));
187  t->disposition = error0;
188  t->pool_index = pool_index0;
189  }
190 
191  /* verify speculative enqueue, maybe switch current next frame */
192  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
193  to_next, n_left_to_next,
194  bi0, next0);
195  }
196 
197  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
198  }
199 
200  return frame->n_vectors;
201 }
202 
203 /* *INDENT-OFF* */
205 {
206  .function = dns46_reply_node_fn,
207  .name = "dns46_reply",
208  .vector_size = sizeof (u32),
209  .format_trace = format_dns46_reply_trace,
210  .type = VLIB_NODE_TYPE_INTERNAL,
211  .n_errors = ARRAY_LEN (dns46_reply_error_strings),
212  .error_strings = dns46_reply_error_strings,
213  .n_next_nodes = DNS46_REPLY_N_NEXT,
214  .next_nodes = {
215  [DNS46_REPLY_NEXT_DROP] = "error-drop",
216  [DNS46_REPLY_NEXT_PUNT] = "error-punt",
217  },
218 };
219 /* *INDENT-ON* */
220 
221 /*
222  * fd.io coding-style-patch-verification: ON
223  *
224  * Local Variables:
225  * eval: (c-set-style "gnu")
226  * End:
227  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:437
#define CLIB_UNUSED(x)
Definition: clib.h:79
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
vlib_error_t * errors
Vector of errors for this node.
Definition: node.h:451
static uword vlib_buffer_length_in_chain(vlib_main_t *vm, vlib_buffer_t *b)
Get length in bytes of the buffer chain.
Definition: buffer_funcs.h:250
unsigned char u8
Definition: types.h:56
dns_main_t dns_main
Definition: dns.c:42
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:184
static uword dns46_reply_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: reply_node.c:58
unsigned int u32
Definition: types.h:88
static u8 * format_dns46_reply_trace(u8 *s, va_list *args)
Definition: reply_node.c:31
#define foreach_dns46_reply_error
Definition: dns.h:142
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:202
#define PREDICT_FALSE(x)
Definition: clib.h:105
#define vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next, n_left_to_next, bi0, bi1, next0, next1)
Finish enqueueing two buffers forward in the graph.
Definition: buffer_node.h:70
static char * dns46_reply_error_strings[]
Definition: reply_node.c:44
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
Definition: buffer_node.h:218
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
Definition: node_funcs.h:364
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:135
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:153
u16 n_vectors
Definition: node.h:380
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:77
vlib_main_t * vm
Definition: buffer.c:294
static void vlib_process_signal_event_mt(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
Signal event to process from any thread.
Definition: node_funcs.h:976
#define clib_memcpy(a, b, c)
Definition: string.h:75
#define ARRAY_LEN(x)
Definition: clib.h:59
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
Definition: main.c:454
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:492
#define DNS_RESOLVER_EVENT_RESOLVED
Definition: dns.h:85
vlib_node_registration_t dns_resolver_node
(constructor) VLIB_REGISTER_NODE (dns_resolver_node)
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace_funcs.h:55
struct _vlib_node_registration vlib_node_registration_t
u64 uword
Definition: types.h:112
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:267
Definition: dns.h:89
vlib_node_registration_t dns46_reply_node
(constructor) VLIB_REGISTER_NODE (dns46_reply_node)
Definition: reply_node.c:21
u8 data[0]
Packet data.
Definition: buffer.h:172
u16 flags
Copy of main node flags.
Definition: node.h:486
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:295
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:62
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:111
dns46_reply_next_t
Definition: reply_node.c:50
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:57
int is_enabled
enable / disable flag
Definition: dns.h:102