Add configuration options for IPFIX 97/1897/2
authorJuraj Sloboda <jsloboda@cisco.com>
Thu, 7 Jul 2016 10:23:15 +0000 (03:23 -0700)
committerDamjan Marion <dmarion.lists@gmail.com>
Thu, 7 Jul 2016 20:29:18 +0000 (20:29 +0000)
Make Path MTU configurable
Make template resend interval configurable
Make collector port configurable

Change-Id: Ia557916137995ea565f0ede12e169efe81eb0a5d
Signed-off-by: Juraj Sloboda <jsloboda@cisco.com>
vnet/vnet/flow/flow_report.c
vnet/vnet/flow/flow_report.h
vnet/vnet/flow/flow_report_sample.c

index 97ff277..b78df60 100644 (file)
@@ -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,
 };
 
index 518e7b0..8b08e47 100644 (file)
@@ -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;
index 122bd9d..761e47c 100644 (file)
@@ -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 -