FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
ip6_punt_drop.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 #include <vnet/ip/ip.h>
17 #include <vnet/ip/ip_punt_drop.h>
18 #include <vnet/policer/policer.h>
20 
21 /* *INDENT-OFF* */
22 VNET_FEATURE_ARC_INIT (ip6_punt) =
23 {
24  .arc_name = "ip6-punt",
25  .start_nodes = VNET_FEATURES ("ip6-punt"),
26 };
27 
28 VNET_FEATURE_ARC_INIT (ip6_drop) =
29 {
30  .arc_name = "ip6-drop",
31  .start_nodes = VNET_FEATURES ("ip6-drop", "ip6-not-enabled"),
32 };
33 /* *INDENT-ON* */
34 
36 
37 #ifndef CLIB_MARCH_VARIANT
39 #endif /* CLIB_MARCH_VARIANT */
40 
41 static char *ip6_punt_policer_handoff_error_strings[] = { "congestion drop" };
42 
45 {
48 }
49 
51  .name = "ip6-punt-policer-handoff",
52  .vector_size = sizeof (u32),
53  .format_trace = format_policer_handoff_trace,
57 
58  .n_next_nodes = 1,
59  .next_nodes = {
60  [0] = "error-drop",
61  },
62 };
63 
65 #define _(sym,string) string,
67 #undef _
68 };
69 
73 {
74  return (ip_punt_policer (vm, node, frame,
75  vnet_feat_arc_ip6_punt.feature_arc_index,
77 }
78 
79 
80 /* *INDENT-OFF* */
81 
83  .name = "ip6-punt-policer",
84  .vector_size = sizeof (u32),
85  .n_next_nodes = IP_PUNT_POLICER_N_NEXT,
86  .format_trace = format_ip_punt_policer_trace,
88  .error_strings = ip6_punt_policer_error_strings,
89 
90  /* edit / add dispositions here */
91  .next_nodes = {
92  [IP_PUNT_POLICER_NEXT_DROP] = "ip6-drop",
93  [IP_PUNT_POLICER_NEXT_HANDOFF] = "ip6-punt-policer-handoff",
94  },
95 };
96 
98  .arc_name = "ip6-punt",
99  .node_name = "ip6-punt-policer",
100  .runs_before = VNET_FEATURES("ip6-punt-redirect")
101 };
102 /* *INDENT-ON* */
103 
106 {
107  if (node->flags & VLIB_NODE_FLAG_TRACE)
109 
110  return ip_drop_or_punt (vm, node, frame,
111  vnet_feat_arc_ip6_drop.feature_arc_index);
112 
113 }
114 
118 {
119  if (node->flags & VLIB_NODE_FLAG_TRACE)
121 
122  return ip_drop_or_punt (vm, node, frame,
123  vnet_feat_arc_ip6_drop.feature_arc_index);
124 
125 }
126 
129 {
130  if (node->flags & VLIB_NODE_FLAG_TRACE)
132 
133  return ip_drop_or_punt (vm, node, frame,
134  vnet_feat_arc_ip6_punt.feature_arc_index);
135 }
136 
137 /* *INDENT-OFF* */
139 {
140  .name = "ip6-drop",
141  .vector_size = sizeof (u32),
142  .format_trace = format_ip6_forward_next_trace,
143  .n_next_nodes = 1,
144  .next_nodes = {
145  [0] = "error-drop",
146  },
147 };
148 
150 {
151  .name = "ip6-not-enabled",
152  .vector_size = sizeof (u32),
153  .format_trace = format_ip6_forward_next_trace,
154  .n_next_nodes = 1,
155  .next_nodes = {
156  [0] = "error-drop",
157  },
158 };
159 
161 {
162  .name = "ip6-punt",
163  .vector_size = sizeof (u32),
164  .format_trace = format_ip6_forward_next_trace,
165  .n_next_nodes = 1,
166  .next_nodes = {
167  [0] = "error-punt",
168  },
169 };
170 
171 VNET_FEATURE_INIT (ip6_punt_end_of_arc, static) = {
172  .arc_name = "ip6-punt",
173  .node_name = "error-punt",
174  .runs_before = 0, /* not before any other features */
175 };
176 
177 VNET_FEATURE_INIT (ip6_drop_end_of_arc, static) = {
178  .arc_name = "ip6-drop",
179  .node_name = "error-drop",
180  .runs_before = 0, /* not before any other features */
181 };
182 /* *INDENT-ON */
183 
184 #ifndef CLIB_MARCH_VARIANT
185 void
186 ip6_punt_policer_add_del (u8 is_add, u32 policer_index)
187 {
188  ip6_punt_policer_cfg.policer_index = policer_index;
189 
190  vnet_feature_enable_disable ("ip6-punt", "ip6-punt-policer",
191  0, is_add, 0, 0);
192 }
193 #endif /* CLIB_MARCH_VARIANT */
194 
195 static clib_error_t *
197  unformat_input_t * main_input,
198  vlib_cli_command_t * cmd)
199 {
200  unformat_input_t _line_input, *line_input = &_line_input;
201  clib_error_t *error = 0;
202  u32 policer_index;
203  u8 is_add = 1;
204 
205  policer_index = ~0;
206 
207  if (!unformat_user (main_input, unformat_line_input, line_input))
208  return 0;
209 
210  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
211  {
212  if (unformat (line_input, "%d", &policer_index))
213  ;
214  else if (unformat (line_input, "del"))
215  is_add = 0;
216  else if (unformat (line_input, "add"))
217  is_add = 1;
218  else
219  {
220  error = unformat_parse_error (line_input);
221  goto done;
222  }
223  }
224 
225  if (is_add && ~0 == policer_index)
226  {
227  error = clib_error_return (0, "expected policer index `%U'",
228  format_unformat_error, line_input);
229  goto done;
230  }
231  if (!is_add)
232  policer_index = ~0;
233 
234  ip6_punt_policer_add_del(is_add, policer_index);
235 
236 done:
237  unformat_free (line_input);
238  return (error);
239 }
240 
241 /*?
242  *
243  * @cliexpar
244  * @cliexcmd{set ip punt policer <INDEX>}
245  ?*/
246 /* *INDENT-OFF* */
248 {
249  .path = "ip6 punt policer",
250  .function = ip6_punt_police_cmd,
251  .short_help = "ip6 punt policer [add|del] <index>",
252 };
253 
254 /* *INDENT-ON* */
255 
256 #define foreach_ip6_punt_redirect_error \
257 _(DROP, "ip6 punt redirect drop")
258 
259 typedef enum
260 {
261 #define _(sym,str) IP6_PUNT_REDIRECT_ERROR_##sym,
263 #undef _
266 
268 #define _(sym,string) string,
270 #undef _
271 };
272 
276 {
277  return (ip_punt_redirect (vm, node, frame,
278  vnet_feat_arc_ip6_punt.feature_arc_index,
280 }
281 
282 /* *INDENT-OFF* */
284  .name = "ip6-punt-redirect",
285  .vector_size = sizeof (u32),
286  .n_next_nodes = IP_PUNT_REDIRECT_N_NEXT,
287  .format_trace = format_ip_punt_redirect_trace,
289  .error_strings = ip6_punt_redirect_error_strings,
290 
291  /* edit / add dispositions here */
292  .next_nodes = {
293  [IP_PUNT_REDIRECT_NEXT_DROP] = "ip6-drop",
294  [IP_PUNT_REDIRECT_NEXT_TX] = "ip6-rewrite",
295  [IP_PUNT_REDIRECT_NEXT_ARP] = "ip6-discover-neighbor",
296  },
297 };
298 
300  .arc_name = "ip6-punt",
301  .node_name = "ip6-punt-redirect",
302  .runs_before = VNET_FEATURES("error-punt")
303 };
304 /* *INDENT-ON* */
305 
306 #ifndef CLIB_MARCH_VARIANT
307 
308 void
310  const fib_route_path_t *rpaths)
311 {
313  rx_sw_if_index,
315 
316  vnet_feature_enable_disable ("ip6-punt", "ip6-punt-redirect", 0, 1, 0, 0);
317 }
318 
319 void
320 ip6_punt_redirect_del (u32 rx_sw_if_index)
321 {
322  vnet_feature_enable_disable ("ip6-punt", "ip6-punt-redirect", 0, 0, 0, 0);
323 
324  ip_punt_redirect_del (FIB_PROTOCOL_IP6, rx_sw_if_index);
325 }
326 #endif /* CLIB_MARCH_VARIANT */
327 
328 static clib_error_t *
330  unformat_input_t * main_input,
331  vlib_cli_command_t * cmd)
332 {
333  unformat_input_t _line_input, *line_input = &_line_input;
334  fib_route_path_t *rpaths = NULL, rpath;
335  dpo_proto_t payload_proto = DPO_PROTO_IP6;
336  clib_error_t *error = 0;
337  u32 rx_sw_if_index = ~0;
338  vnet_main_t *vnm;
339  u8 is_add;
340 
341  is_add = 1;
342  vnm = vnet_get_main ();
343 
344  if (!unformat_user (main_input, unformat_line_input, line_input))
345  return 0;
346 
347  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
348  {
349  if (unformat (line_input, "del"))
350  is_add = 0;
351  else if (unformat (line_input, "add"))
352  is_add = 1;
353  else if (unformat (line_input, "rx all"))
354  rx_sw_if_index = 0;
355  else if (unformat (line_input, "rx %U",
356  unformat_vnet_sw_interface, vnm, &rx_sw_if_index))
357  ;
358  else if (unformat (line_input, "via %U",
359  unformat_fib_route_path, &rpath, &payload_proto))
360  vec_add1 (rpaths, rpath);
361  else
362  {
363  error = unformat_parse_error (line_input);
364  goto done;
365  }
366  }
367 
368  if (~0 == rx_sw_if_index)
369  {
370  error = unformat_parse_error (line_input);
371  goto done;
372  }
373 
374  if (is_add)
375  {
376  if (vec_len (rpaths))
377  ip6_punt_redirect_add_paths (rx_sw_if_index, rpaths);
378  }
379  else
380  {
381  ip6_punt_redirect_del (rx_sw_if_index);
382  }
383 
384 done:
385  vec_free (rpaths);
386  unformat_free (line_input);
387  return (error);
388 }
389 
390 /*?
391  *
392  * @cliexpar
393  * @cliexcmd{set ip punt policer <INDEX>}
394  ?*/
395 /* *INDENT-OFF* */
397 {
398  .path = "ip6 punt redirect",
399  .function = ip6_punt_redirect_cmd,
400  .short_help = "ip6 punt redirect [add|del] rx [<interface>|all] via [<nh>] <tx_interface>",
401 };
402 /* *INDENT-ON* */
403 
404 #ifndef CLIB_MARCH_VARIANT
405 
406 #endif /* CLIB_MARCH_VARIANT */
407 
408 static clib_error_t *
410  unformat_input_t * main_input,
411  vlib_cli_command_t * cmd)
412 {
414 
415  return (NULL);
416 }
417 
418 /*?
419  *
420  * @cliexpar
421  * @cliexcmd{set ip punt policer <INDEX>}
422  ?*/
423 /* *INDENT-OFF* */
425 {
426  .path = "show ip6 punt redirect",
427  .function = ip6_punt_redirect_show_cmd,
428  .short_help = "show ip6 punt redirect",
429  .is_mp_safe = 1,
430 };
431 /* *INDENT-ON* */
432 
433 /*
434  * fd.io coding-style-patch-verification: ON
435  *
436  * Local Variables:
437  * eval: (c-set-style "gnu")
438  * End:
439  */
unformat_user
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
show_ip6_punt_redirect_command
static vlib_cli_command_t show_ip6_punt_redirect_command
(constructor) VLIB_CLI_COMMAND (show_ip6_punt_redirect_command)
Definition: ip6_punt_drop.c:424
ip6_punt_redirect_show_cmd
static clib_error_t * ip6_punt_redirect_show_cmd(vlib_main_t *vm, unformat_input_t *main_input, vlib_cli_command_t *cmd)
Definition: ip6_punt_drop.c:409
ip6_punt_policer_add_del
void ip6_punt_policer_add_del(u8 is_add, u32 policer_index)
Definition: ip6_punt_drop.c:186
ip6_punt_redirect_node
vlib_node_registration_t ip6_punt_redirect_node
(constructor) VLIB_REGISTER_NODE (ip6_punt_redirect_node)
Definition: ip6_punt_drop.c:283
dpo_proto_t
enum dpo_proto_t_ dpo_proto_t
Data path protocol.
ip6_punt_policer_error_strings
static char * ip6_punt_policer_error_strings[]
Definition: ip6_punt_drop.c:64
VNET_FEATURE_INIT
VNET_FEATURE_INIT(ip6_punt_policer_node, static)
unformat_line_input
unformat_function_t unformat_line_input
Definition: format.h:275
IP_PUNT_REDIRECT_NEXT_TX
@ IP_PUNT_REDIRECT_NEXT_TX
Definition: ip_punt_drop.h:253
IP_PUNT_POLICER_NEXT_DROP
@ IP_PUNT_POLICER_NEXT_DROP
Definition: ip_punt_drop.h:35
frame
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: ip6_punt_drop.c:45
VLIB_NODE_TYPE_INTERNAL
@ VLIB_NODE_TYPE_INTERNAL
Definition: node.h:72
clib_error_return
#define clib_error_return(e, args...)
Definition: error.h:99
ip6_punt_policer_node
vlib_node_registration_t ip6_punt_policer_node
(constructor) VLIB_REGISTER_NODE (ip6_punt_policer_node)
Definition: ip6_punt_drop.c:82
vlib_cli_command_t::path
char * path
Definition: cli.h:96
ip_punt_redirect_add
void ip_punt_redirect_add(fib_protocol_t fproto, u32 rx_sw_if_index, fib_forward_chain_type_t ct, const fib_route_path_t *rpaths)
Add a punt redirect entry.
Definition: ip_punt_drop.c:72
foreach_ip_punt_policer_error
#define foreach_ip_punt_policer_error
Definition: ip_punt_drop.h:46
ip6_punt_policer_handoff_error_strings
static char * ip6_punt_policer_handoff_error_strings[]
Definition: ip6_punt_drop.c:41
unformat_parse_error
#define unformat_parse_error(input)
Definition: format.h:261
policer.h
ip_punt_policer_t_::policer_index
u32 policer_index
Definition: ip_punt_drop.h:29
ip_punt_redirect_del
void ip_punt_redirect_del(fib_protocol_t fproto, u32 rx_sw_if_index)
Definition: ip_punt_drop.c:105
unformat_input_t
struct _unformat_input_t unformat_input_t
ip_punt_drop.h
vlib_frame_t
Definition: node.h:372
ip6_punt_redirect_error_t
ip6_punt_redirect_error_t
Definition: ip6_punt_drop.c:259
policer_handoff
static_always_inline uword policer_handoff(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u32 fq_index, u32 policer_index)
Definition: police_inlines.h:118
error
Definition: cJSON.c:88
ip_punt_policer_t_::fq_index
u32 fq_index
Definition: ip_punt_drop.h:30
ip_punt_policer_t_
IP4 punt policer configuration we police the punt rate to prevent overloading the host.
Definition: ip_punt_drop.h:27
ip6_punt_redirect_command
static vlib_cli_command_t ip6_punt_redirect_command
(constructor) VLIB_CLI_COMMAND (ip6_punt_redirect_command)
Definition: ip6_punt_drop.c:396
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
ip6_not_enabled_node
vlib_node_registration_t ip6_not_enabled_node
(constructor) VLIB_REGISTER_NODE (ip6_not_enabled_node)
Definition: ip6_punt_drop.c:149
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
unformat_free
static void unformat_free(unformat_input_t *i)
Definition: format.h:155
VLIB_NODE_FN
#define VLIB_NODE_FN(node)
Definition: node.h:202
vec_add1
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:606
vm
vlib_main_t * vm
Definition: ip6_punt_drop.c:44
ip6_punt_policer_cfg
ip_punt_policer_t ip6_punt_policer_cfg
Definition: ip6_punt_drop.c:38
ip6_punt_redirect_add_paths
void ip6_punt_redirect_add_paths(u32 rx_sw_if_index, const fib_route_path_t *rpaths)
Definition: ip6_punt_drop.c:309
IP_PUNT_POLICER_N_NEXT
@ IP_PUNT_POLICER_N_NEXT
Definition: ip_punt_drop.h:37
format_policer_handoff_trace
u8 * format_policer_handoff_trace(u8 *s, va_list *args)
Definition: policer.c:25
vnet_get_main
vnet_main_t * vnet_get_main(void)
Definition: pnat_test_stubs.h:56
VLIB_NODE_FLAG_TRACE
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:291
ip_punt_redirect
static uword ip_punt_redirect(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u8 arc_index, fib_protocol_t fproto)
Definition: ip_punt_drop.h:294
ARRAY_LEN
#define ARRAY_LEN(x)
Definition: clib.h:70
unformat_check_input
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
IP6_PUNT_REDIRECT_N_ERROR
@ IP6_PUNT_REDIRECT_N_ERROR
Definition: ip6_punt_drop.c:264
format_unformat_error
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
ip_punt_policer
static uword ip_punt_policer(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u8 arc_index, u32 policer_index)
IP punt policing node function.
Definition: ip_punt_drop.h:67
VLIB_CLI_COMMAND
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
police_inlines.h
IP_PUNT_POLICER_NEXT_HANDOFF
@ IP_PUNT_POLICER_NEXT_HANDOFF
Definition: ip_punt_drop.h:36
vlib_node_registration_t
struct _vlib_node_registration vlib_node_registration_t
ip6_punt_police_cmd
static clib_error_t * ip6_punt_police_cmd(vlib_main_t *vm, unformat_input_t *main_input, vlib_cli_command_t *cmd)
Definition: ip6_punt_drop.c:196
vlib_cli_output
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
ip6_punt_redirect_error_strings
static char * ip6_punt_redirect_error_strings[]
Definition: ip6_punt_drop.c:267
vnet_main_t
Definition: vnet.h:76
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
format_ip_punt_redirect
u8 * format_ip_punt_redirect(u8 *s, va_list *args)
Definition: ip_punt_drop.c:129
node
vlib_main_t vlib_node_runtime_t * node
Definition: ip6_punt_drop.c:44
format_ip_punt_redirect_trace
u8 * format_ip_punt_redirect_trace(u8 *s, va_list *args)
Definition: ip_punt_drop.c:23
ip6_punt_redirect_del
void ip6_punt_redirect_del(u32 rx_sw_if_index)
Definition: ip6_punt_drop.c:320
unformat_vnet_sw_interface
unformat_function_t unformat_vnet_sw_interface
Definition: interface_funcs.h:462
ip6_drop_node
vlib_node_registration_t ip6_drop_node
(constructor) VLIB_REGISTER_NODE (ip6_drop_node)
Definition: ip6_punt_drop.c:138
ip6_punt_policer_command
static vlib_cli_command_t ip6_punt_policer_command
(constructor) VLIB_CLI_COMMAND (ip6_punt_policer_command)
Definition: ip6_punt_drop.c:247
DPO_PROTO_IP6
@ DPO_PROTO_IP6
Definition: dpo.h:65
ip.h
u32
unsigned int u32
Definition: types.h:88
FIB_PROTOCOL_IP6
@ FIB_PROTOCOL_IP6
Definition: fib_types.h:37
fib_route_path_t_
A representation of a path as described by a route producer.
Definition: fib_types.h:500
foreach_ip6_punt_redirect_error
#define foreach_ip6_punt_redirect_error
Definition: ip6_punt_drop.c:256
vnet_feature_enable_disable
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
Definition: pnat_test_stubs.h:50
IP_PUNT_REDIRECT_NEXT_ARP
@ IP_PUNT_REDIRECT_NEXT_ARP
Definition: ip_punt_drop.h:254
ip6_punt_policer_handoff_node
vlib_node_registration_t ip6_punt_policer_handoff_node
(constructor) VLIB_REGISTER_NODE (ip6_punt_policer_handoff_node)
Definition: ip6_punt_drop.c:50
vlib_main_t
Definition: main.h:102
VNET_FEATURES
#define VNET_FEATURES(...)
Definition: feature.h:470
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
IP_PUNT_REDIRECT_N_NEXT
@ IP_PUNT_REDIRECT_N_NEXT
Definition: ip_punt_drop.h:255
VNET_FEATURE_ARC_INIT
VNET_FEATURE_ARC_INIT(ip6_punt)
IP_PUNT_REDIRECT_NEXT_DROP
@ IP_PUNT_REDIRECT_NEXT_DROP
Definition: ip_punt_drop.h:252
FIB_FORW_CHAIN_TYPE_UNICAST_IP6
@ FIB_FORW_CHAIN_TYPE_UNICAST_IP6
Contribute an object that is to be used to forward IP6 packets.
Definition: fib_types.h:112
ip6_punt_redirect_cmd
static clib_error_t * ip6_punt_redirect_cmd(vlib_main_t *vm, unformat_input_t *main_input, vlib_cli_command_t *cmd)
Definition: ip6_punt_drop.c:329
ip6_punt_node
vlib_node_registration_t ip6_punt_node
(constructor) VLIB_REGISTER_NODE (ip6_punt_node)
Definition: ip6_punt_drop.c:160
vlib_node_runtime_t
Definition: node.h:454
vlib_cli_command_t
Definition: cli.h:92
ip_drop_or_punt
static uword ip_drop_or_punt(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u8 arc_index)
Definition: ip_punt_drop.h:377
VLIB_TX
@ VLIB_TX
Definition: defs.h:47
ip6_forward_next_trace
void ip6_forward_next_trace(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, vlib_rx_or_tx_t which_adj_index)
Definition: ip6_forward.c:1004
format_ip6_forward_next_trace
u8 * format_ip6_forward_next_trace(u8 *s, va_list *args)
Definition: ip6_forward.c:949
unformat_fib_route_path
uword unformat_fib_route_path(unformat_input_t *input, va_list *args)
Unformat a fib_route_path_t from CLI input.
Definition: fib_types.c:540
type
vl_api_fib_path_type_t type
Definition: fib_types.api:123
format_ip_punt_policer_trace
u8 * format_ip_punt_policer_trace(u8 *s, va_list *args)
Definition: ip4_punt_drop.c:39
UNFORMAT_END_OF_INPUT
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
VLIB_REGISTER_NODE
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169