FD.io VPP  v16.06
Vector Packet Processing
ip4_input.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 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  * ip/ip4_input.c: IP v4 input node
17  *
18  * Copyright (c) 2008 Eliot Dresselhaus
19  *
20  * Permission is hereby granted, free of charge, to any person obtaining
21  * a copy of this software and associated documentation files (the
22  * "Software"), to deal in the Software without restriction, including
23  * without limitation the rights to use, copy, modify, merge, publish,
24  * distribute, sublicense, and/or sell copies of the Software, and to
25  * permit persons to whom the Software is furnished to do so, subject to
26  * the following conditions:
27  *
28  * The above copyright notice and this permission notice shall be
29  * included in all copies or substantial portions of the Software.
30  *
31  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38  */
39 
40 #include <vnet/ip/ip.h>
41 #include <vnet/ethernet/ethernet.h>
42 #include <vnet/ppp/ppp.h>
43 #include <vnet/hdlc/hdlc.h>
44 
45 typedef struct {
46  u8 packet_data[64];
48 
49 static u8 * format_ip4_input_trace (u8 * s, va_list * va)
50 {
51  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
52  CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
53  ip4_input_trace_t * t = va_arg (*va, ip4_input_trace_t *);
54 
55  s = format (s, "%U",
57  t->packet_data, sizeof (t->packet_data));
58 
59  return s;
60 }
61 
62 typedef enum {
70 
71 /* Validate IP v4 packets and pass them either to forwarding code
72  or drop/punt exception packets. */
75  vlib_node_runtime_t * node,
76  vlib_frame_t * frame,
77  int verify_checksum)
78 {
79  ip4_main_t * im = &ip4_main;
80  vnet_main_t * vnm = vnet_get_main();
81  ip_lookup_main_t * lm = &im->lookup_main;
82  u32 n_left_from, * from, * to_next;
83  ip4_input_next_t next_index;
84  vlib_node_runtime_t * error_node = vlib_node_get_runtime (vm, ip4_input_node.index);
86  u32 cpu_index = os_get_cpu_number();
87 
88  from = vlib_frame_vector_args (frame);
89  n_left_from = frame->n_vectors;
90  next_index = node->cached_next_index;
91 
92  if (node->flags & VLIB_NODE_FLAG_TRACE)
93  vlib_trace_frame_buffers_only (vm, node, from, frame->n_vectors,
94  /* stride */ 1,
95  sizeof (ip4_input_trace_t));
96 
99 
100  while (n_left_from > 0)
101  {
102  u32 n_left_to_next;
103 
104  vlib_get_next_frame (vm, node, next_index,
105  to_next, n_left_to_next);
106 
107  while (n_left_from >= 4 && n_left_to_next >= 2)
108  {
109  vlib_buffer_t * p0, * p1;
110  ip4_header_t * ip0, * ip1;
111  ip_config_main_t * cm0, * cm1;
112  u32 sw_if_index0, pi0, ip_len0, cur_len0, next0;
113  u32 sw_if_index1, pi1, ip_len1, cur_len1, next1;
114  i32 len_diff0, len_diff1;
115  u8 error0, error1, cast0, cast1;
116 
117  /* Prefetch next iteration. */
118  {
119  vlib_buffer_t * p2, * p3;
120 
121  p2 = vlib_get_buffer (vm, from[2]);
122  p3 = vlib_get_buffer (vm, from[3]);
123 
124  vlib_prefetch_buffer_header (p2, LOAD);
125  vlib_prefetch_buffer_header (p3, LOAD);
126 
127  CLIB_PREFETCH (p2->data, sizeof (ip0[0]), LOAD);
128  CLIB_PREFETCH (p3->data, sizeof (ip1[0]), LOAD);
129  }
130 
131  to_next[0] = pi0 = from[0];
132  to_next[1] = pi1 = from[1];
133  from += 2;
134  to_next += 2;
135  n_left_from -= 2;
136  n_left_to_next -= 2;
137 
138  p0 = vlib_get_buffer (vm, pi0);
139  p1 = vlib_get_buffer (vm, pi1);
140 
141  ip0 = vlib_buffer_get_current (p0);
142  ip1 = vlib_buffer_get_current (p1);
143 
144  sw_if_index0 = vnet_buffer (p0)->sw_if_index[VLIB_RX];
145  sw_if_index1 = vnet_buffer (p1)->sw_if_index[VLIB_RX];
146 
149 
150  cm0 = lm->rx_config_mains + cast0;
151  cm1 = lm->rx_config_mains + cast1;
152 
153  vnet_buffer (p0)->ip.current_config_index = vec_elt (cm0->config_index_by_sw_if_index, sw_if_index0);
154  vnet_buffer (p1)->ip.current_config_index = vec_elt (cm1->config_index_by_sw_if_index, sw_if_index1);
155 
156  vnet_buffer (p0)->ip.adj_index[VLIB_RX] = ~0;
157  vnet_buffer (p1)->ip.adj_index[VLIB_RX] = ~0;
158 
160  &vnet_buffer (p0)->ip.current_config_index,
161  &next0,
162  /* # bytes of config data */ 0);
164  &vnet_buffer (p1)->ip.current_config_index,
165  &next1,
166  /* # bytes of config data */ 0);
167 
168  vlib_increment_simple_counter (cm, cpu_index, sw_if_index0, 1);
169  vlib_increment_simple_counter (cm, cpu_index, sw_if_index1, 1);
170 
171  error0 = error1 = IP4_ERROR_NONE;
172 
173  /* Punt packets with options. */
174  error0 = (ip0->ip_version_and_header_length & 0xf) != 5 ? IP4_ERROR_OPTIONS : error0;
175  error1 = (ip1->ip_version_and_header_length & 0xf) != 5 ? IP4_ERROR_OPTIONS : error1;
176 
177  /* Version != 4? Drop it. */
178  error0 = (ip0->ip_version_and_header_length >> 4) != 4 ? IP4_ERROR_VERSION : error0;
179  error1 = (ip1->ip_version_and_header_length >> 4) != 4 ? IP4_ERROR_VERSION : error1;
180 
181  /* Verify header checksum. */
182  if (verify_checksum)
183  {
184  ip_csum_t sum0, sum1;
185 
186  ip4_partial_header_checksum_x1 (ip0, sum0);
187  ip4_partial_header_checksum_x1 (ip1, sum1);
188 
189  error0 = 0xffff != ip_csum_fold (sum0) ? IP4_ERROR_BAD_CHECKSUM : error0;
190  error1 = 0xffff != ip_csum_fold (sum1) ? IP4_ERROR_BAD_CHECKSUM : error1;
191  }
192 
193  /* Drop fragmentation offset 1 packets. */
194  error0 = ip4_get_fragment_offset (ip0) == 1 ? IP4_ERROR_FRAGMENT_OFFSET_ONE : error0;
195  error1 = ip4_get_fragment_offset (ip1) == 1 ? IP4_ERROR_FRAGMENT_OFFSET_ONE : error1;
196 
197  /* TTL <= 1? Drop it. */
198  error0 = (ip0->ttl <= 1 && cast0 == VNET_UNICAST) ? IP4_ERROR_TIME_EXPIRED : error0;
199  error1 = (ip1->ttl <= 1 && cast1 == VNET_UNICAST) ? IP4_ERROR_TIME_EXPIRED : error1;
200 
201  /* Verify lengths. */
202  ip_len0 = clib_net_to_host_u16 (ip0->length);
203  ip_len1 = clib_net_to_host_u16 (ip1->length);
204 
205  /* IP length must be at least minimal IP header. */
206  error0 = ip_len0 < sizeof (ip0[0]) ? IP4_ERROR_TOO_SHORT : error0;
207  error1 = ip_len1 < sizeof (ip1[0]) ? IP4_ERROR_TOO_SHORT : error1;
208 
209  cur_len0 = vlib_buffer_length_in_chain (vm, p0);
210  cur_len1 = vlib_buffer_length_in_chain (vm, p1);
211 
212  len_diff0 = cur_len0 - ip_len0;
213  len_diff1 = cur_len1 - ip_len1;
214 
215  error0 = len_diff0 < 0 ? IP4_ERROR_BAD_LENGTH : error0;
216  error1 = len_diff1 < 0 ? IP4_ERROR_BAD_LENGTH : error1;
217 
218  p0->error = error_node->errors[error0];
219  p1->error = error_node->errors[error1];
220 
221  if (PREDICT_FALSE(error0 != IP4_ERROR_NONE))
222  {
223  if (error0 == IP4_ERROR_TIME_EXPIRED) {
224  icmp4_error_set_vnet_buffer(p0, ICMP4_time_exceeded,
225  ICMP4_time_exceeded_ttl_exceeded_in_transit, 0);
227  } else
228  next0 = error0 != IP4_ERROR_OPTIONS ? IP4_INPUT_NEXT_DROP : IP4_INPUT_NEXT_PUNT;
229  }
230  if (PREDICT_FALSE(error1 != IP4_ERROR_NONE))
231  {
232  if (error1 == IP4_ERROR_TIME_EXPIRED) {
233  icmp4_error_set_vnet_buffer(p1, ICMP4_time_exceeded,
234  ICMP4_time_exceeded_ttl_exceeded_in_transit, 0);
236  } else
237  next1 = error1 != IP4_ERROR_OPTIONS ? IP4_INPUT_NEXT_DROP : IP4_INPUT_NEXT_PUNT;
238  }
239 
240  vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
241  to_next, n_left_to_next,
242  pi0, pi1, next0, next1);
243  }
244  while (n_left_from > 0 && n_left_to_next > 0)
245  {
246  vlib_buffer_t * p0;
247  ip4_header_t * ip0;
248  ip_config_main_t * cm0;
249  u32 sw_if_index0, pi0, ip_len0, cur_len0, next0;
250  i32 len_diff0;
251  u8 error0, cast0;
252 
253  pi0 = from[0];
254  to_next[0] = pi0;
255  from += 1;
256  to_next += 1;
257  n_left_from -= 1;
258  n_left_to_next -= 1;
259 
260  p0 = vlib_get_buffer (vm, pi0);
261  ip0 = vlib_buffer_get_current (p0);
262 
263  sw_if_index0 = vnet_buffer (p0)->sw_if_index[VLIB_RX];
264 
266  cm0 = lm->rx_config_mains + cast0;
267  vnet_buffer (p0)->ip.current_config_index = vec_elt (cm0->config_index_by_sw_if_index, sw_if_index0);
268  vnet_buffer (p0)->ip.adj_index[VLIB_RX] = ~0;
270  &vnet_buffer (p0)->ip.current_config_index,
271  &next0,
272  /* # bytes of config data */ 0);
273 
274  vlib_increment_simple_counter (cm, cpu_index, sw_if_index0, 1);
275 
276  error0 = IP4_ERROR_NONE;
277 
278  /* Punt packets with options. */
279  error0 = (ip0->ip_version_and_header_length & 0xf) != 5 ? IP4_ERROR_OPTIONS : error0;
280 
281  /* Version != 4? Drop it. */
282  error0 = (ip0->ip_version_and_header_length >> 4) != 4 ? IP4_ERROR_VERSION : error0;
283 
284  /* Verify header checksum. */
285  if (verify_checksum)
286  {
287  ip_csum_t sum0;
288 
289  ip4_partial_header_checksum_x1 (ip0, sum0);
290  error0 = 0xffff != ip_csum_fold (sum0) ? IP4_ERROR_BAD_CHECKSUM : error0;
291  }
292 
293  /* Drop fragmentation offset 1 packets. */
294  error0 = ip4_get_fragment_offset (ip0) == 1 ? IP4_ERROR_FRAGMENT_OFFSET_ONE : error0;
295 
296  /* TTL <= 1? Drop it. */
297  error0 = (ip0->ttl <= 1 && cast0 == VNET_UNICAST) ? IP4_ERROR_TIME_EXPIRED : error0;
298 
299  /* Verify lengths. */
300  ip_len0 = clib_net_to_host_u16 (ip0->length);
301 
302  /* IP length must be at least minimal IP header. */
303  error0 = ip_len0 < sizeof (ip0[0]) ? IP4_ERROR_TOO_SHORT : error0;
304 
305  cur_len0 = vlib_buffer_length_in_chain (vm, p0);
306  len_diff0 = cur_len0 - ip_len0;
307  error0 = len_diff0 < 0 ? IP4_ERROR_BAD_LENGTH : error0;
308 
309  p0->error = error_node->errors[error0];
310  if (PREDICT_FALSE(error0 != IP4_ERROR_NONE))
311  {
312  if (error0 == IP4_ERROR_TIME_EXPIRED) {
313  icmp4_error_set_vnet_buffer(p0, ICMP4_time_exceeded,
314  ICMP4_time_exceeded_ttl_exceeded_in_transit, 0);
316  } else
317  next0 = error0 != IP4_ERROR_OPTIONS ? IP4_INPUT_NEXT_DROP : IP4_INPUT_NEXT_PUNT;
318  }
319 
320  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
321  to_next, n_left_to_next,
322  pi0, next0);
323  }
324 
325  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
326  }
327 
328  return frame->n_vectors;
329 }
330 
331 static uword
333  vlib_node_runtime_t * node,
334  vlib_frame_t * frame)
335 {
336  return ip4_input_inline (vm, node, frame, /* verify_checksum */ 1);
337 }
338 
339 static uword
341  vlib_node_runtime_t * node,
342  vlib_frame_t * frame)
343 {
344  return ip4_input_inline (vm, node, frame, /* verify_checksum */ 0);
345 }
346 
347 static char * ip4_error_strings[] = {
348 #define _(sym,string) string,
350 #undef _
351 };
352 
354  .function = ip4_input,
355  .name = "ip4-input",
356  .vector_size = sizeof (u32),
357 
358  .n_errors = IP4_N_ERROR,
359  .error_strings = ip4_error_strings,
360 
361  .n_next_nodes = IP4_INPUT_N_NEXT,
362  .next_nodes = {
363  [IP4_INPUT_NEXT_DROP] = "error-drop",
364  [IP4_INPUT_NEXT_PUNT] = "error-punt",
365  [IP4_INPUT_NEXT_LOOKUP] = "ip4-lookup",
366  [IP4_INPUT_NEXT_LOOKUP_MULTICAST] = "ip4-lookup-multicast",
367  [IP4_INPUT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
368  },
369 
370  .format_buffer = format_ip4_header,
371  .format_trace = format_ip4_input_trace,
372 };
373 
375  .function = ip4_input_no_checksum,
376  .name = "ip4-input-no-checksum",
377  .vector_size = sizeof (u32),
378 
379  .n_next_nodes = IP4_INPUT_N_NEXT,
380  .next_nodes = {
381  [IP4_INPUT_NEXT_DROP] = "error-drop",
382  [IP4_INPUT_NEXT_PUNT] = "error-punt",
383  [IP4_INPUT_NEXT_LOOKUP] = "ip4-lookup",
384  [IP4_INPUT_NEXT_LOOKUP_MULTICAST] = "ip4-lookup-multicast",
385  [IP4_INPUT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
386  },
387 
388  .format_buffer = format_ip4_header,
389  .format_trace = format_ip4_input_trace,
390 };
391 
393 {
394  clib_error_t * error;
395 
396  ethernet_register_input_type (vm, ETHERNET_TYPE_IP4,
397  ip4_input_node.index);
398  ppp_register_input_protocol (vm, PPP_PROTOCOL_ip4,
399  ip4_input_node.index);
400  hdlc_register_input_protocol (vm, HDLC_PROTOCOL_ip4,
401  ip4_input_node.index);
402 
403  {
404  pg_node_t * pn;
405  pn = pg_get_node (ip4_input_node.index);
409  }
410 
411  if ((error = vlib_call_init_function (vm, ip4_cli_init)))
412  return error;
413 
415  return error;
416 
417  /* Set flow hash to something non-zero. */
418  ip4_main.flow_hash_seed = 0xdeadbeef;
419 
420  /* Default TTL for packets we generate. */
421  ip4_main.host_config.ttl = 64;
422 
423  return error;
424 }
425 
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Definition: main.c:459
always_inline uword ip4_address_is_multicast(ip4_address_t *a)
Definition: ip4_packet.h:263
#define CLIB_UNUSED(x)
Definition: clib.h:79
u32 * config_index_by_sw_if_index
Definition: lookup.h:345
static uword ip4_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: ip4_input.c:332
always_inline pg_node_t * pg_get_node(uword node_index)
Definition: pg.h:335
vnet_interface_main_t interface_main
Definition: vnet.h:62
always_inline int ip4_get_fragment_offset(ip4_header_t *i)
Definition: ip4_packet.h:162
unformat_function_t unformat_pg_ip4_header
Definition: format.h:83
ip_config_main_t rx_config_mains[VNET_N_CAST]
Definition: lookup.h:401
ip_lookup_main_t lookup_main
Definition: ip4.h:129
uword ip_csum_t
Definition: ip_packet.h:86
vlib_error_t * errors
Definition: node.h:378
static clib_error_t * ip4_cli_init(vlib_main_t *vm)
Definition: ip46_cli.c:155
always_inline void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:184
vnet_main_t * vnet_get_main(void)
Definition: misc.c:45
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:109
static clib_error_t * ip4_init(vlib_main_t *vm)
Definition: ip4_input.c:392
#define always_inline
Definition: clib.h:84
ip4_address_t dst_address
Definition: ip4_packet.h:138
int i32
Definition: types.h:81
static char * ip4_error_strings[]
Definition: ip4_input.c:347
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
always_inline 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:112
#define vlib_call_init_function(vm, x)
Definition: init.h:159
always_inline void * vlib_frame_vector_args(vlib_frame_t *f)
Definition: node_funcs.h:202
void ppp_register_input_protocol(vlib_main_t *vm, ppp_protocol_t protocol, u32 node_index)
Definition: node.c:305
vlib_node_registration_t ip4_input_no_checksum_node
(constructor) VLIB_REGISTER_NODE (ip4_input_no_checksum_node)
Definition: ip4_input.c:374
always_inline u16 ip_csum_fold(ip_csum_t c)
Definition: ip_packet.h:138
static u8 * format_ip4_input_trace(u8 *s, va_list *va)
Definition: ip4_input.c:49
always_inline void vlib_increment_simple_counter(vlib_simple_counter_main_t *cm, u32 cpu_index, u32 index, u32 increment)
Definition: counter.h:70
uword os_get_cpu_number(void)
Definition: unix-misc.c:206
#define PREDICT_FALSE(x)
Definition: clib.h:97
vlib_simple_counter_main_t * sw_if_counters
Definition: interface.h:457
#define vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next, n_left_to_next, bi0, bi1, next0, next1)
Definition: buffer_node.h:43
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Definition: buffer_node.h:83
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Definition: node_funcs.h:265
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:129
u8 packet_data[64]
Definition: ip4_input.c:46
#define foreach_ip4_error
Definition: ip4_error.h:43
static uword ip4_input_no_checksum(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: ip4_input.c:340
u16 n_vectors
Definition: node.h:307
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:82
clib_error_t * ip4_source_check_init(vlib_main_t *vm)
void icmp4_error_set_vnet_buffer(vlib_buffer_t *b, u8 type, u8 code, u32 data)
Definition: icmp4.c:416
unformat_function_t * unformat_edit
Definition: pg.h:290
void hdlc_register_input_protocol(vlib_main_t *vm, hdlc_protocol_t protocol, u32 node_index)
Definition: node.c:319
always_inline uword ip4_input_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, int verify_checksum)
Definition: ip4_input.c:74
u16 cached_next_index
Definition: node.h:422
ip4_input_next_t
Definition: ip4_input.c:62
format_function_t format_ip4_header
Definition: format.h:78
unsigned int u32
Definition: types.h:88
struct ip4_main_t::@97 host_config
#define vnet_buffer(b)
Definition: buffer.h:300
u8 * format(u8 *s, char *fmt,...)
Definition: format.c:405
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:225
void ethernet_register_input_type(vlib_main_t *vm, ethernet_type_t type, u32 node_index)
Definition: node.c:1078
u64 uword
Definition: types.h:112
#define vec_elt(v, i)
Get vector value at index i.
void vlib_trace_frame_buffers_only(vlib_main_t *vm, vlib_node_runtime_t *node, u32 *buffers, uword n_buffers, uword next_buffer_stride, uword n_buffer_data_bytes_in_trace)
Definition: trace.c:45
unsigned char u8
Definition: types.h:56
#define ip4_partial_header_checksum_x1(ip0, sum0)
Definition: ip4_packet.h:218
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:162
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:140
ip4_main_t ip4_main
Definition: ip4_forward.c:1394
always_inline vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Definition: node_funcs.h:61
u8 data[0]
Packet data.
Definition: buffer.h:150
vlib_node_registration_t ip4_input_node
(constructor) VLIB_REGISTER_NODE (ip4_input_node)
Definition: ip4_input.c:353
u32 flow_hash_seed
Definition: ip4.h:156
u8 ip_version_and_header_length
Definition: ip4_packet.h:108
always_inline void * vnet_get_config_data(vnet_config_main_t *cm, u32 *config_index, u32 *next_index, u32 n_data_bytes)
Definition: config.h:115
u8 ttl
Definition: ip4.h:160
always_inline vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:69
Definition: pg.h:288
vnet_config_main_t config_main
Definition: lookup.h:343
Definition: defs.h:45