summaryrefslogtreecommitdiffstats
path: root/src/vnet
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet')
-rw-r--r--src/vnet/ipfix-export/flow_report.c95
-rw-r--r--src/vnet/ipfix-export/flow_report.h34
-rw-r--r--src/vnet/ipfix-export/flow_report_classify.c4
-rw-r--r--src/vnet/ipfix-export/flow_report_classify.h4
4 files changed, 127 insertions, 10 deletions
diff --git a/src/vnet/ipfix-export/flow_report.c b/src/vnet/ipfix-export/flow_report.c
index 793eedaeb38..78ad1f5023c 100644
--- a/src/vnet/ipfix-export/flow_report.c
+++ b/src/vnet/ipfix-export/flow_report.c
@@ -107,7 +107,10 @@ send_template_packet (flow_report_main_t * frm,
fr->rewrite = fr->rewrite_callback (frm, fr,
&frm->ipfix_collector,
&frm->src_address,
- frm->collector_port);
+ frm->collector_port,
+ fr->report_elements,
+ fr->n_report_elements,
+ fr->stream_indexp);
fr->update_rewrite = 0;
}
@@ -164,6 +167,92 @@ send_template_packet (flow_report_main_t * frm,
return 0;
}
+u8 *
+vnet_flow_rewrite_generic_callback (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 * report_elts,
+ u32 n_elts, u32 * stream_indexp)
+{
+ ip4_header_t *ip;
+ udp_header_t *udp;
+ ipfix_message_header_t *h;
+ ipfix_set_header_t *s;
+ ipfix_template_header_t *t;
+ ipfix_field_specifier_t *f;
+ ipfix_field_specifier_t *first_field;
+ u8 *rewrite = 0;
+ ip4_ipfix_template_packet_t *tp;
+ flow_report_stream_t *stream;
+ int i;
+ ipfix_report_element_t *ep;
+
+ ASSERT (stream_indexp);
+ ASSERT (n_elts);
+ ASSERT (report_elts);
+
+ stream = &frm->streams[fr->stream_index];
+ *stream_indexp = fr->stream_index;
+
+ /* allocate rewrite space */
+ vec_validate_aligned (rewrite,
+ sizeof (ip4_ipfix_template_packet_t)
+ + n_elts * sizeof (ipfix_field_specifier_t) - 1,
+ CLIB_CACHE_LINE_BYTES);
+
+ /* create the packet rewrite string */
+ tp = (ip4_ipfix_template_packet_t *) rewrite;
+ ip = (ip4_header_t *) & tp->ip4;
+ udp = (udp_header_t *) (ip + 1);
+ h = (ipfix_message_header_t *) (udp + 1);
+ s = (ipfix_set_header_t *) (h + 1);
+ t = (ipfix_template_header_t *) (s + 1);
+ first_field = f = (ipfix_field_specifier_t *) (t + 1);
+
+ ip->ip_version_and_header_length = 0x45;
+ ip->ttl = 254;
+ ip->protocol = IP_PROTOCOL_UDP;
+ 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 (stream->src_port);
+ udp->dst_port = clib_host_to_net_u16 (collector_port);
+ udp->length = clib_host_to_net_u16 (vec_len (rewrite) - sizeof (*ip));
+
+ /* FIXUP LATER: message header export_time */
+ h->domain_id = clib_host_to_net_u32 (stream->domain_id);
+
+ ep = report_elts;
+
+ for (i = 0; i < n_elts; i++)
+ {
+ f->e_id_length = ipfix_e_id_length (0, ep->info_element, ep->size);
+ f++;
+ ep++;
+ }
+
+ /* Back to the template packet... */
+ ip = (ip4_header_t *) & tp->ip4;
+ udp = (udp_header_t *) (ip + 1);
+
+ ASSERT (f - first_field);
+ /* Field count in this template */
+ t->id_count = ipfix_id_count (fr->template_id, f - first_field);
+
+ /* set length in octets */
+ s->set_id_length =
+ ipfix_set_id_length (2 /* set_id */ , (u8 *) f - (u8 *) s);
+
+ /* message length in octets */
+ h->version_length = version_length ((u8 *) f - (u8 *) h);
+
+ ip->length = clib_host_to_net_u16 ((u8 *) f - (u8 *) ip);
+ ip->checksum = ip4_header_checksum (ip);
+
+ return rewrite;
+}
+
static uword
flow_report_process (vlib_main_t * vm,
vlib_node_runtime_t * rt, vlib_frame_t * f)
@@ -315,7 +404,9 @@ vnet_flow_report_add_del (flow_report_main_t * frm,
fr->opaque = a->opaque;
fr->rewrite_callback = a->rewrite_callback;
fr->flow_data_callback = a->flow_data_callback;
-
+ fr->report_elements = a->report_elements;
+ fr->n_report_elements = a->n_report_elements;
+ fr->stream_indexp = a->stream_indexp;
if (template_id)
*template_id = fr->template_id;
diff --git a/src/vnet/ipfix-export/flow_report.h b/src/vnet/ipfix-export/flow_report.h
index b45ce06a880..a26232d5919 100644
--- a/src/vnet/ipfix-export/flow_report.h
+++ b/src/vnet/ipfix-export/flow_report.h
@@ -31,6 +31,13 @@
#include <vnet/ipfix-export/ipfix_packet.h>
+/* ipfix field definitions for a particular report */
+typedef struct
+{
+ u32 info_element;
+ u32 size;
+} ipfix_report_element_t;
+
/* Used to build the rewrite */
typedef struct
{
@@ -42,16 +49,25 @@ typedef struct
struct flow_report_main;
struct flow_report;
-typedef u8 *(vnet_flow_rewrite_callback_t) (struct flow_report_main *,
- struct flow_report *,
- ip4_address_t *,
- ip4_address_t *, u16);
-
typedef vlib_frame_t *(vnet_flow_data_callback_t) (struct flow_report_main *,
struct flow_report *,
vlib_frame_t *, u32 *,
u32);
+typedef u8 *(vnet_flow_rewrite_callback_t) (struct flow_report_main *,
+ struct flow_report *,
+ ip4_address_t *,
+ ip4_address_t *, u16,
+ ipfix_report_element_t * elts,
+ u32 n_elts, u32 * stream_index);
+
+u8 *vnet_flow_rewrite_generic_callback (struct flow_report_main *,
+ struct flow_report *,
+ ip4_address_t *,
+ ip4_address_t *, u16,
+ ipfix_report_element_t * elts,
+ u32 n_elts, u32 * stream_index);
+
typedef union
{
void *as_ptr;
@@ -82,8 +98,11 @@ typedef struct flow_report
/* Opaque data */
opaque_t opaque;
- /* build-the-rewrite callback */
+ /* build-the-template-packet rewrite callback */
vnet_flow_rewrite_callback_t *rewrite_callback;
+ ipfix_report_element_t *report_elements;
+ u32 n_report_elements;
+ u32 *stream_indexp;
/* Send-flow-data callback */
vnet_flow_data_callback_t *flow_data_callback;
@@ -128,10 +147,13 @@ typedef struct
{
vnet_flow_data_callback_t *flow_data_callback;
vnet_flow_rewrite_callback_t *rewrite_callback;
+ ipfix_report_element_t *report_elements;
+ u32 n_report_elements;
opaque_t opaque;
int is_add;
u32 domain_id;
u16 src_port;
+ u32 *stream_indexp;
} vnet_flow_report_add_del_args_t;
int vnet_flow_report_add_del (flow_report_main_t * frm,
diff --git a/src/vnet/ipfix-export/flow_report_classify.c b/src/vnet/ipfix-export/flow_report_classify.c
index 46813ee6e1b..8fb73fc0867 100644
--- a/src/vnet/ipfix-export/flow_report_classify.c
+++ b/src/vnet/ipfix-export/flow_report_classify.c
@@ -30,7 +30,9 @@ ipfix_classify_template_rewrite (flow_report_main_t * frm,
flow_report_t * fr,
ip4_address_t * collector_address,
ip4_address_t * src_address,
- u16 collector_port)
+ u16 collector_port,
+ ipfix_report_element_t * elts,
+ u32 n_elts, u32 * stream_index)
{
flow_report_classify_main_t *fcm = &flow_report_classify_main;
vnet_classify_table_t *tblp;
diff --git a/src/vnet/ipfix-export/flow_report_classify.h b/src/vnet/ipfix-export/flow_report_classify.h
index 0533b450122..a923f36714a 100644
--- a/src/vnet/ipfix-export/flow_report_classify.h
+++ b/src/vnet/ipfix-export/flow_report_classify.h
@@ -116,7 +116,9 @@ u8 *ipfix_classify_template_rewrite (flow_report_main_t * frm,
flow_report_t * fr,
ip4_address_t * collector_address,
ip4_address_t * src_address,
- u16 collector_port);
+ u16 collector_port,
+ ipfix_report_element_t * elts,
+ u32 n_elts, u32 * stream_index);
vlib_frame_t *ipfix_classify_send_flows (flow_report_main_t * frm,
flow_report_t * fr,