FD.io VPP  v19.08.3-2-gbabecb413
Vector Packet Processing
flowprobe.c File Reference

Per-packet IPFIX flow record generator plugin. More...

+ Include dependency graph for flowprobe.c:

Go to the source code of this file.

Macros

#define vl_typedefs
 
#define vl_endianfun
 
#define vl_print(handle, ...)   vlib_cli_output (handle, __VA_ARGS__)
 
#define vl_printfun
 
#define vl_api_version(n, v)   static u32 api_version=(v);
 
#define REPLY_MSG_ID_BASE   fm->msg_id_base
 
#define FINISH
 
#define flowprobe_template_ip4_field_count()   4
 
#define flowprobe_template_ip6_field_count()   4
 
#define flowprobe_template_l2_field_count()   3
 
#define flowprobe_template_common_field_count()   5
 
#define flowprobe_template_l4_field_count()   3
 
#define vec_neg_search(v, E)
 
#define foreach_flowprobe_plugin_api_msg
 
#define vl_msg_name_crc_list
 

Functions

uword flowprobe_walker_process (vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
 
 VNET_FEATURE_INIT (flow_perpacket_ip4, static)
 
 VNET_FEATURE_INIT (flow_perpacket_ip6, static)
 
 VNET_FEATURE_INIT (flow_perpacket_l2, static)
 
static ipfix_field_specifier_tflowprobe_template_ip4_fields (ipfix_field_specifier_t *f)
 
static ipfix_field_specifier_tflowprobe_template_ip6_fields (ipfix_field_specifier_t *f)
 
static ipfix_field_specifier_tflowprobe_template_l2_fields (ipfix_field_specifier_t *f)
 
static ipfix_field_specifier_tflowprobe_template_common_fields (ipfix_field_specifier_t *f)
 
static ipfix_field_specifier_tflowprobe_template_l4_fields (ipfix_field_specifier_t *f)
 
static u8flowprobe_template_rewrite_inline (flow_report_main_t *frm, flow_report_t *fr, ip4_address_t *collector_address, ip4_address_t *src_address, u16 collector_port, flowprobe_variant_t which)
 Create an IPFIX template packet rewrite string. More...
 
static u8flowprobe_template_rewrite_ip6 (flow_report_main_t *frm, flow_report_t *fr, ip4_address_t *collector_address, ip4_address_t *src_address, u16 collector_port, ipfix_report_element_t *elts, u32 n_elts, u32 *stream_index)
 
static u8flowprobe_template_rewrite_ip4 (flow_report_main_t *frm, flow_report_t *fr, ip4_address_t *collector_address, ip4_address_t *src_address, u16 collector_port, ipfix_report_element_t *elts, u32 n_elts, u32 *stream_index)
 
static u8flowprobe_template_rewrite_l2 (flow_report_main_t *frm, flow_report_t *fr, ip4_address_t *collector_address, ip4_address_t *src_address, u16 collector_port, ipfix_report_element_t *elts, u32 n_elts, u32 *stream_index)
 
static u8flowprobe_template_rewrite_l2_ip4 (flow_report_main_t *frm, flow_report_t *fr, ip4_address_t *collector_address, ip4_address_t *src_address, u16 collector_port, ipfix_report_element_t *elts, u32 n_elts, u32 *stream_index)
 
static u8flowprobe_template_rewrite_l2_ip6 (flow_report_main_t *frm, flow_report_t *fr, ip4_address_t *collector_address, ip4_address_t *src_address, u16 collector_port, ipfix_report_element_t *elts, u32 n_elts, u32 *stream_index)
 
vlib_frame_tflowprobe_data_callback_ip4 (flow_report_main_t *frm, flow_report_t *fr, vlib_frame_t *f, u32 *to_next, u32 node_index)
 Flush accumulated data. More...
 
vlib_frame_tflowprobe_data_callback_ip6 (flow_report_main_t *frm, flow_report_t *fr, vlib_frame_t *f, u32 *to_next, u32 node_index)
 
vlib_frame_tflowprobe_data_callback_l2 (flow_report_main_t *frm, flow_report_t *fr, vlib_frame_t *f, u32 *to_next, u32 node_index)
 
static int flowprobe_template_add_del (u32 domain_id, u16 src_port, flowprobe_record_t flags, vnet_flow_data_callback_t *flow_data_callback, vnet_flow_rewrite_callback_t *rewrite_callback, bool is_add, u16 *template_id)
 
static void flowprobe_expired_timer_callback (u32 *expired_timers)
 
static clib_error_tflowprobe_create_state_tables (u32 active_timer)
 
static int validate_feature_on_interface (flowprobe_main_t *fm, u32 sw_if_index, u8 which)
 
static int flowprobe_tx_interface_add_del_feature (flowprobe_main_t *fm, u32 sw_if_index, u8 which, int is_add)
 configure / deconfigure the IPFIX flow-per-packet More...
 
void vl_api_flowprobe_tx_interface_add_del_t_handler (vl_api_flowprobe_tx_interface_add_del_t *mp)
 API message handler. More...
 
static void * vl_api_flowprobe_tx_interface_add_del_t_print (vl_api_flowprobe_tx_interface_add_del_t *mp, void *handle)
 API message custom-dump function. More...
 
static int flowprobe_params (flowprobe_main_t *fm, u8 record_l2, u8 record_l3, u8 record_l4, u32 active_timer, u32 passive_timer)
 
void vl_api_flowprobe_params_t_handler (vl_api_flowprobe_params_t *mp)
 
 VLIB_PLUGIN_REGISTER ()
 
u8format_flowprobe_entry (u8 *s, va_list *args)
 
static clib_error_tflowprobe_show_table_fn (vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cm)
 
static clib_error_tflowprobe_show_stats_fn (vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cm)
 
static clib_error_tflowprobe_tx_interface_add_del_feature_command_fn (vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
 
static clib_error_tflowprobe_params_command_fn (vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
 
static clib_error_tflowprobe_plugin_api_hookup (vlib_main_t *vm)
 Set up the API message handling tables. More...
 
static void setup_message_id_table (flowprobe_main_t *fm, api_main_t *am)
 
static uword timer_process (vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
 
static clib_error_tflowprobe_init (vlib_main_t *vm)
 Set up the API message handling tables. More...
 

Variables

flowprobe_main_t flowprobe_main
 
static vlib_node_registration_t flowprobe_timer_node
 (constructor) VLIB_REGISTER_NODE (flowprobe_timer_node) More...
 
static vlib_cli_command_t flowprobe_enable_disable_command
 (constructor) VLIB_CLI_COMMAND (flowprobe_enable_disable_command) More...
 
static vlib_cli_command_t flowprobe_params_command
 (constructor) VLIB_CLI_COMMAND (flowprobe_params_command) More...
 
static vlib_cli_command_t flowprobe_show_table_command
 (constructor) VLIB_CLI_COMMAND (flowprobe_show_table_command) More...
 
static vlib_cli_command_t flowprobe_show_stats_command
 (constructor) VLIB_CLI_COMMAND (flowprobe_show_stats_command) More...
 

Detailed Description

Per-packet IPFIX flow record generator plugin.

This file implements vpp plugin registration mechanics, debug CLI, and binary API handling.

Definition in file flowprobe.c.

Macro Definition Documentation

◆ FINISH

#define FINISH
Value:
vec_add1 (s, 0); \
vl_print (handle, (char *)s); \
vec_free (s); \
return handle;
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:522

Definition at line 91 of file flowprobe.c.

◆ flowprobe_template_common_field_count

#define flowprobe_template_common_field_count ( )    5

◆ flowprobe_template_ip4_field_count

#define flowprobe_template_ip4_field_count ( )    4

◆ flowprobe_template_ip6_field_count

#define flowprobe_template_ip6_field_count ( )    4

◆ flowprobe_template_l2_field_count

#define flowprobe_template_l2_field_count ( )    3

◆ flowprobe_template_l4_field_count

#define flowprobe_template_l4_field_count ( )    3

◆ foreach_flowprobe_plugin_api_msg

#define foreach_flowprobe_plugin_api_msg
Value:
_(FLOWPROBE_TX_INTERFACE_ADD_DEL, flowprobe_tx_interface_add_del) \
_(FLOWPROBE_PARAMS, flowprobe_params)
static int flowprobe_params(flowprobe_main_t *fm, u8 record_l2, u8 record_l3, u8 record_l4, u32 active_timer, u32 passive_timer)
Definition: flowprobe.c:715

Definition at line 760 of file flowprobe.c.

◆ REPLY_MSG_ID_BASE

#define REPLY_MSG_ID_BASE   fm->msg_id_base

Definition at line 63 of file flowprobe.c.

◆ vec_neg_search

#define vec_neg_search (   v,
 
)
Value:
({ \
word _v(i) = 0; \
while (_v(i) < vec_len(v) && v[_v(i)] == E) \
{ \
_v(i)++; \
} \
if (_v(i) == vec_len(v)) \
_v(i) = ~0; \
_v(i); \
})
int i
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)

Definition at line 702 of file flowprobe.c.

◆ vl_api_version

#define vl_api_version (   n,
 
)    static u32 api_version=(v);

Definition at line 59 of file flowprobe.c.

◆ vl_endianfun

#define vl_endianfun

Definition at line 43 of file flowprobe.c.

◆ vl_msg_name_crc_list

#define vl_msg_name_crc_list

Definition at line 1006 of file flowprobe.c.

◆ vl_print

#define vl_print (   handle,
  ... 
)    vlib_cli_output (handle, __VA_ARGS__)

Definition at line 48 of file flowprobe.c.

◆ vl_printfun

#define vl_printfun

Definition at line 49 of file flowprobe.c.

◆ vl_typedefs

#define vl_typedefs

Definition at line 38 of file flowprobe.c.

Function Documentation

◆ flowprobe_create_state_tables()

static clib_error_t* flowprobe_create_state_tables ( u32  active_timer)
static

Definition at line 473 of file flowprobe.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flowprobe_data_callback_ip4()

vlib_frame_t* flowprobe_data_callback_ip4 ( flow_report_main_t frm,
flow_report_t fr,
vlib_frame_t f,
u32 to_next,
u32  node_index 
)

Flush accumulated data.

Parameters
frmflow_report_main_t *
frflow_report_t *
fvlib_frame_t *

Notes: This function must simply return the incoming frame, or no template packets will be sent.

Definition at line 411 of file flowprobe.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flowprobe_data_callback_ip6()

vlib_frame_t* flowprobe_data_callback_ip6 ( flow_report_main_t frm,
flow_report_t fr,
vlib_frame_t f,
u32 to_next,
u32  node_index 
)

Definition at line 420 of file flowprobe.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flowprobe_data_callback_l2()

vlib_frame_t* flowprobe_data_callback_l2 ( flow_report_main_t frm,
flow_report_t fr,
vlib_frame_t f,
u32 to_next,
u32  node_index 
)

Definition at line 429 of file flowprobe.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flowprobe_expired_timer_callback()

static void flowprobe_expired_timer_callback ( u32 expired_timers)
static

Definition at line 457 of file flowprobe.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flowprobe_init()

static clib_error_t* flowprobe_init ( vlib_main_t vm)
static

Set up the API message handling tables.

Parameters
vmvlib_main_t * vlib main data structure pointer
Returns
0 to indicate all is well, or a clib_error_t

Definition at line 1085 of file flowprobe.c.

+ Here is the call graph for this function:

◆ flowprobe_params()

static int flowprobe_params ( flowprobe_main_t fm,
u8  record_l2,
u8  record_l3,
u8  record_l4,
u32  active_timer,
u32  passive_timer 
)
static

Definition at line 715 of file flowprobe.c.

+ Here is the caller graph for this function:

◆ flowprobe_params_command_fn()

static clib_error_t* flowprobe_params_command_fn ( vlib_main_t vm,
unformat_input_t input,
vlib_cli_command_t cmd 
)
static

Definition at line 902 of file flowprobe.c.

+ Here is the call graph for this function:

◆ flowprobe_plugin_api_hookup()

static clib_error_t* flowprobe_plugin_api_hookup ( vlib_main_t vm)
static

Set up the API message handling tables.

Parameters
vmvlib_main_t * vlib main data structure pointer
Returns
0 to indicate all is well

Definition at line 989 of file flowprobe.c.

+ Here is the caller graph for this function:

◆ flowprobe_show_stats_fn()

static clib_error_t* flowprobe_show_stats_fn ( vlib_main_t vm,
unformat_input_t input,
vlib_cli_command_t cm 
)
static

Definition at line 815 of file flowprobe.c.

+ Here is the call graph for this function:

◆ flowprobe_show_table_fn()

static clib_error_t* flowprobe_show_table_fn ( vlib_main_t vm,
unformat_input_t input,
vlib_cli_command_t cm 
)
static

Definition at line 790 of file flowprobe.c.

+ Here is the call graph for this function:

◆ flowprobe_template_add_del()

static int flowprobe_template_add_del ( u32  domain_id,
u16  src_port,
flowprobe_record_t  flags,
vnet_flow_data_callback_t flow_data_callback,
vnet_flow_rewrite_callback_t rewrite_callback,
bool  is_add,
u16 template_id 
)
static

Definition at line 438 of file flowprobe.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flowprobe_template_common_fields()

static ipfix_field_specifier_t* flowprobe_template_common_fields ( ipfix_field_specifier_t f)
inlinestatic

Definition at line 163 of file flowprobe.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flowprobe_template_ip4_fields()

static ipfix_field_specifier_t* flowprobe_template_ip4_fields ( ipfix_field_specifier_t f)
inlinestatic

Definition at line 98 of file flowprobe.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flowprobe_template_ip6_fields()

static ipfix_field_specifier_t* flowprobe_template_ip6_fields ( ipfix_field_specifier_t f)
inlinestatic

Definition at line 121 of file flowprobe.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flowprobe_template_l2_fields()

static ipfix_field_specifier_t* flowprobe_template_l2_fields ( ipfix_field_specifier_t f)
inlinestatic

Definition at line 144 of file flowprobe.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flowprobe_template_l4_fields()

static ipfix_field_specifier_t* flowprobe_template_l4_fields ( ipfix_field_specifier_t f)
inlinestatic

Definition at line 195 of file flowprobe.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flowprobe_template_rewrite_inline()

static u8* flowprobe_template_rewrite_inline ( flow_report_main_t frm,
flow_report_t fr,
ip4_address_t collector_address,
ip4_address_t src_address,
u16  collector_port,
flowprobe_variant_t  which 
)
inlinestatic

Create an IPFIX template packet rewrite string.

Parameters
frmflow_report_main_t *
frflow_report_t *
collector_addressip4_address_t * the IPFIX collector address
src_addressip4_address_t * the source address we should use
collector_portu16 the collector port we should use, host byte order
Returns
u8 * vector containing the indicated IPFIX template packet

Definition at line 224 of file flowprobe.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flowprobe_template_rewrite_ip4()

static u8* flowprobe_template_rewrite_ip4 ( flow_report_main_t frm,
flow_report_t fr,
ip4_address_t collector_address,
ip4_address_t src_address,
u16  collector_port,
ipfix_report_element_t elts,
u32  n_elts,
u32 stream_index 
)
static

Definition at line 345 of file flowprobe.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flowprobe_template_rewrite_ip6()

static u8* flowprobe_template_rewrite_ip6 ( flow_report_main_t frm,
flow_report_t fr,
ip4_address_t collector_address,
ip4_address_t src_address,
u16  collector_port,
ipfix_report_element_t elts,
u32  n_elts,
u32 stream_index 
)
static

Definition at line 331 of file flowprobe.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flowprobe_template_rewrite_l2()

static u8* flowprobe_template_rewrite_l2 ( flow_report_main_t frm,
flow_report_t fr,
ip4_address_t collector_address,
ip4_address_t src_address,
u16  collector_port,
ipfix_report_element_t elts,
u32  n_elts,
u32 stream_index 
)
static

Definition at line 359 of file flowprobe.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flowprobe_template_rewrite_l2_ip4()

static u8* flowprobe_template_rewrite_l2_ip4 ( flow_report_main_t frm,
flow_report_t fr,
ip4_address_t collector_address,
ip4_address_t src_address,
u16  collector_port,
ipfix_report_element_t elts,
u32  n_elts,
u32 stream_index 
)
static

Definition at line 373 of file flowprobe.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flowprobe_template_rewrite_l2_ip6()

static u8* flowprobe_template_rewrite_l2_ip6 ( flow_report_main_t frm,
flow_report_t fr,
ip4_address_t collector_address,
ip4_address_t src_address,
u16  collector_port,
ipfix_report_element_t elts,
u32  n_elts,
u32 stream_index 
)
static

Definition at line 387 of file flowprobe.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flowprobe_tx_interface_add_del_feature()

static int flowprobe_tx_interface_add_del_feature ( flowprobe_main_t fm,
u32  sw_if_index,
u8  which,
int  is_add 
)
static

configure / deconfigure the IPFIX flow-per-packet

Parameters
fmflowprobe_main_t * fm
sw_if_indexu32 the desired interface
is_addint 1 to enable the feature, 0 to disable it
Returns
0 if successful, non-zero otherwise

Definition at line 546 of file flowprobe.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flowprobe_tx_interface_add_del_feature_command_fn()

static clib_error_t* flowprobe_tx_interface_add_del_feature_command_fn ( vlib_main_t vm,
unformat_input_t input,
vlib_cli_command_t cmd 
)
static

Definition at line 834 of file flowprobe.c.

+ Here is the call graph for this function:

◆ flowprobe_walker_process()

uword flowprobe_walker_process ( vlib_main_t vm,
vlib_node_runtime_t rt,
vlib_frame_t f 
)

◆ format_flowprobe_entry()

u8* format_flowprobe_entry ( u8 s,
va_list *  args 
)

Definition at line 772 of file flowprobe.c.

+ Here is the call graph for this function:

◆ setup_message_id_table()

static void setup_message_id_table ( flowprobe_main_t fm,
api_main_t am 
)
static

Definition at line 1011 of file flowprobe.c.

+ Here is the caller graph for this function:

◆ timer_process()

static uword timer_process ( vlib_main_t vm,
vlib_node_runtime_t rt,
vlib_frame_t f 
)
static

Definition at line 1024 of file flowprobe.c.

+ Here is the call graph for this function:

◆ validate_feature_on_interface()

static int validate_feature_on_interface ( flowprobe_main_t fm,
u32  sw_if_index,
u8  which 
)
static

Definition at line 524 of file flowprobe.c.

+ Here is the caller graph for this function:

◆ vl_api_flowprobe_params_t_handler()

void vl_api_flowprobe_params_t_handler ( vl_api_flowprobe_params_t mp)

Definition at line 745 of file flowprobe.c.

+ Here is the call graph for this function:

◆ vl_api_flowprobe_tx_interface_add_del_t_handler()

void vl_api_flowprobe_tx_interface_add_del_t_handler ( vl_api_flowprobe_tx_interface_add_del_t mp)

API message handler.

Parameters
mpvl_api_flowprobe_tx_interface_add_del_t * mp the api message

Definition at line 645 of file flowprobe.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ vl_api_flowprobe_tx_interface_add_del_t_print()

static void* vl_api_flowprobe_tx_interface_add_del_t_print ( vl_api_flowprobe_tx_interface_add_del_t mp,
void *  handle 
)
static

API message custom-dump function.

Parameters
mpvl_api_flowprobe_tx_interface_add_del_t * mp the api message
handlevoid * print function handle
Returns
u8 * output string

Definition at line 691 of file flowprobe.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ VLIB_PLUGIN_REGISTER()

VLIB_PLUGIN_REGISTER ( )

◆ VNET_FEATURE_INIT() [1/3]

VNET_FEATURE_INIT ( flow_perpacket_ip4  ,
static   
)

◆ VNET_FEATURE_INIT() [2/3]

VNET_FEATURE_INIT ( flow_perpacket_ip6  ,
static   
)

◆ VNET_FEATURE_INIT() [3/3]

VNET_FEATURE_INIT ( flow_perpacket_l2  ,
static   
)

Variable Documentation

◆ flowprobe_enable_disable_command

vlib_cli_command_t flowprobe_enable_disable_command
static
Initial value:
= {
.path = "flowprobe feature add-del",
.short_help =
"flowprobe feature add-del <interface-name> <l2|ip4|ip6> disable",
}
static clib_error_t * flowprobe_tx_interface_add_del_feature_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: flowprobe.c:834

(constructor) VLIB_CLI_COMMAND (flowprobe_enable_disable_command)

Definition at line 959 of file flowprobe.c.

◆ flowprobe_main

flowprobe_main_t flowprobe_main

Definition at line 53 of file flowprobe.c.

◆ flowprobe_params_command

vlib_cli_command_t flowprobe_params_command
static
Initial value:
= {
.path = "flowprobe params",
.short_help =
"flowprobe params record <[l2] [l3] [l4]> [active <timer> passive <timer>]",
}
static clib_error_t * flowprobe_params_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: flowprobe.c:902

(constructor) VLIB_CLI_COMMAND (flowprobe_params_command)

Definition at line 965 of file flowprobe.c.

◆ flowprobe_show_stats_command

vlib_cli_command_t flowprobe_show_stats_command
static
Initial value:
= {
.path = "show flowprobe statistics",
.short_help = "show flowprobe statistics",
}
static clib_error_t * flowprobe_show_stats_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cm)
Definition: flowprobe.c:815

(constructor) VLIB_CLI_COMMAND (flowprobe_show_stats_command)

Definition at line 976 of file flowprobe.c.

◆ flowprobe_show_table_command

vlib_cli_command_t flowprobe_show_table_command
static
Initial value:
= {
.path = "show flowprobe table",
.short_help = "show flowprobe table",
}
static clib_error_t * flowprobe_show_table_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cm)
Definition: flowprobe.c:790

(constructor) VLIB_CLI_COMMAND (flowprobe_show_table_command)

Definition at line 971 of file flowprobe.c.

◆ flowprobe_timer_node

static vlib_node_registration_t flowprobe_timer_node
static
Initial value:
= {
.function = timer_process,
.name = "flowprobe-timer-process",
}
static uword timer_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: flowprobe.c:1024

(constructor) VLIB_REGISTER_NODE (flowprobe_timer_node)

Definition at line 54 of file flowprobe.c.