diff options
Diffstat (limited to 'vnet')
-rw-r--r-- | vnet/vnet/flow/flow_report.c | 38 | ||||
-rw-r--r-- | vnet/vnet/flow/flow_report.h | 12 | ||||
-rw-r--r-- | vnet/vnet/flow/flow_report_sample.c | 13 |
3 files changed, 52 insertions, 11 deletions
diff --git a/vnet/vnet/flow/flow_report.c b/vnet/vnet/flow/flow_report.c index 97ff2779d37..b78df60a3c6 100644 --- a/vnet/vnet/flow/flow_report.c +++ b/vnet/vnet/flow/flow_report.c @@ -50,7 +50,8 @@ int send_template_packet (flow_report_main_t *frm, { fr->rewrite = fr->rewrite_callback (frm, fr, &frm->ipfix_collector, - &frm->src_address); + &frm->src_address, + frm->collector_port); fr->update_rewrite = 0; } @@ -130,7 +131,8 @@ flow_report_process (vlib_main_t * vm, now = vlib_time_now (vm); /* Need to send a template packet? */ - send_template = now > (fr->last_template_sent + 20.0); + send_template = + now > (fr->last_template_sent + frm->template_interval); send_template += fr->last_template_sent == 0; template_bi = ~0; rv = 0; @@ -216,15 +218,20 @@ set_ipfix_command_fn (vlib_main_t * vm, { flow_report_main_t * frm = &flow_report_main; ip4_address_t collector, src; + u16 collector_port = UDP_DST_PORT_ipfix; u32 fib_id; u32 fib_index = ~0; collector.as_u32 = 0; src.as_u32 = 0; + u32 path_mtu = 512; // RFC 7011 section 10.3.3. + u32 template_interval = 20; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "collector %U", unformat_ip4_address, &collector)) ; + else if (unformat (input, "port %u", &collector_port)) + ; else if (unformat (input, "src %U", unformat_ip4_address, &src)) ; else if (unformat (input, "fib-id %u", &fib_id)) @@ -236,6 +243,10 @@ set_ipfix_command_fn (vlib_main_t * vm, fib_id); fib_index = p[0]; } + else if (unformat (input, "path-mtu %u", &path_mtu)) + ; + else if (unformat (input, "template-interval %u", &template_interval)) + ; else break; } @@ -246,14 +257,26 @@ set_ipfix_command_fn (vlib_main_t * vm, if (src.as_u32 == 0) return clib_error_return (0, "src address required"); + if (path_mtu > 1450 /* vpp does not support fragmentation */) + return clib_error_return (0, "too big path-mtu value, maximum is 1450"); + + if (path_mtu < 68) + return clib_error_return (0, "too small path-mtu value, minimum is 68"); + frm->ipfix_collector.as_u32 = collector.as_u32; + frm->collector_port = collector_port; frm->src_address.as_u32 = src.as_u32; frm->fib_index = fib_index; + frm->path_mtu = path_mtu; + frm->template_interval = template_interval; - vlib_cli_output (vm, "Collector %U, src address %U, fib index %d", + vlib_cli_output (vm, "Collector %U, src address %U, " + "fib index %d, path MTU %u, " + "template resend interval %us", format_ip4_address, &frm->ipfix_collector, - format_ip4_address, &frm->src_address, fib_index); - + format_ip4_address, &frm->src_address, + fib_index, path_mtu, template_interval); + /* Turn on the flow reporting process */ vlib_process_signal_event (vm, flow_report_process_node.index, 1, 0); @@ -263,7 +286,10 @@ set_ipfix_command_fn (vlib_main_t * vm, VLIB_CLI_COMMAND (set_ipfix_command, static) = { .path = "set ipfix", .short_help = "set ipfix collector <ip4-address> " - "src <ip4-address> [fib-id <fib-id>]", + "[port <port>] " + "src <ip4-address> [fib-id <fib-id>] " + "[path-mtu <path-mtu>] " + "[template-interval <template-interval>]", .function = set_ipfix_command_fn, }; diff --git a/vnet/vnet/flow/flow_report.h b/vnet/vnet/flow/flow_report.h index 518e7b0f705..8b08e47e22b 100644 --- a/vnet/vnet/flow/flow_report.h +++ b/vnet/vnet/flow/flow_report.h @@ -44,7 +44,8 @@ struct flow_report; typedef u8 * (vnet_flow_rewrite_callback_t)(struct flow_report_main *, struct flow_report *, ip4_address_t *, - ip4_address_t *); + ip4_address_t *, + u16); typedef vlib_frame_t * (vnet_flow_data_callback_t) (struct flow_report_main *, struct flow_report *, @@ -74,11 +75,18 @@ typedef struct flow_report { typedef struct flow_report_main { flow_report_t * reports; - /* ipfix collector, our ip address, fib index */ + /* ipfix collector ip address, port, our ip address, fib index */ ip4_address_t ipfix_collector; + u16 collector_port; ip4_address_t src_address; u32 fib_index; + /* Path MTU */ + u32 path_mtu; + + /* time interval in seconds after which to resend templates */ + u32 template_interval; + /* time scale transform. Joy. */ u32 unix_time_0; f64 vlib_time_0; diff --git a/vnet/vnet/flow/flow_report_sample.c b/vnet/vnet/flow/flow_report_sample.c index 122bd9d8aea..761e47caa15 100644 --- a/vnet/vnet/flow/flow_report_sample.c +++ b/vnet/vnet/flow/flow_report_sample.c @@ -25,7 +25,8 @@ flow_report_sample_main_t flow_report_sample_main; static u8 * template_rewrite (flow_report_main_t * frm, flow_report_t * fr, ip4_address_t * collector_address, - ip4_address_t * src_address) + ip4_address_t * src_address, + u16 collector_port) { vnet_classify_table_t * tblp; vnet_classify_main_t * vcm = &vnet_classify_main; @@ -92,7 +93,7 @@ static u8 * template_rewrite (flow_report_main_t * frm, ip->src_address.as_u32 = src_address->as_u32; ip->dst_address.as_u32 = collector_address->as_u32; udp->src_port = clib_host_to_net_u16 (4739 /* $$FIXME */); - udp->dst_port = clib_host_to_net_u16 (UDP_DST_PORT_ipfix); + udp->dst_port = clib_host_to_net_u16 (collector_port); udp->length = clib_host_to_net_u16 (vec_len(rewrite) - sizeof (*ip)); /* FIXUP: message header export_time */ @@ -150,6 +151,7 @@ static vlib_frame_t * send_flows (flow_report_main_t * frm, vnet_classify_entry_t * v, * save_v; vlib_buffer_t *b0 = 0; u32 next_offset = 0; + u32 record_offset = 0; u32 bi0 = ~0; int i, j, k; ip4_ipfix_template_packet_t * tp; @@ -218,6 +220,7 @@ static vlib_frame_t * send_flows (flow_report_main_t * frm, h->sequence_number = clib_host_to_net_u32 (h->sequence_number); next_offset = (u32) (((u8 *)(s+1)) - (u8 *)tp); + record_offset = next_offset; records_this_buffer = 0; } @@ -246,7 +249,11 @@ static vlib_frame_t * send_flows (flow_report_main_t * frm, records_this_buffer++; fr->sequence_number++; - if (next_offset > 1450) + /* Next record will have the same size as this record */ + u32 next_record_size = next_offset - record_offset; + record_offset = next_offset; + + if (next_offset + next_record_size > frm->path_mtu) { s->set_id_length = ipfix_set_id_length (256 /* template ID*/, next_offset - |