summaryrefslogtreecommitdiff
path: root/ofproto/ipfix-gen-entities
diff options
context:
space:
mode:
authorRomain Lenglet <rlenglet@vmware.com>2013-04-22 10:01:14 -0700
committerBen Pfaff <blp@nicira.com>2013-04-22 14:33:58 -0700
commit29089a540cfa30a834e3ee19a8b4c52ff2e331b2 (patch)
tree7fd0c5d666c5f18fbd7ad463edc8d908636999f3 /ofproto/ipfix-gen-entities
parentd8558b4ae86f0f64afe520c4c1d99f55a94063d8 (diff)
downloadopenvswitch-29089a540cfa30a834e3ee19a8b4c52ff2e331b2.tar.gz
Implement IPFIX export
Define a new NXAST_SAMPLE OpenFlow vendor action and the corresponding OFPACT_SAMPLE OVS action, to do per-flow packet sampling, translated into a new SAMPLE "flow_sample" dp action. Make the userspace action's userdata size vary depending on the union member used. Add a new "flow_sample" upcall to do per-flow packet sampling. Add a new "ipfix" upcall to do per-bridge packet sampling to IPFIX collectors. Extend the OVSDB schema to support configuring IPFIX collector sets. Add support for configuring multiple IPFIX collectors for per-flow packet sampling. Add support for configuring per-bridge IPFIX sampling. Automatically generate standard IPFIX entity definitions from the IANA specs. Send one IPFIX data record message for every packet sampled by an OpenFlow sample action or received by a bridge configured with IPFIX sampling, and periodically send IPFIX template set messages. Signed-off-by: Romain Lenglet <rlenglet@vmware.com> Signed-off-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'ofproto/ipfix-gen-entities')
-rwxr-xr-xofproto/ipfix-gen-entities140
1 files changed, 140 insertions, 0 deletions
diff --git a/ofproto/ipfix-gen-entities b/ofproto/ipfix-gen-entities
new file mode 100755
index 000000000..4d4e0de6a
--- /dev/null
+++ b/ofproto/ipfix-gen-entities
@@ -0,0 +1,140 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2012 Nicira, Inc.
+#
+# Copying and distribution of this file, with or without modification,
+# are permitted in any medium without royalty provided the copyright
+# notice and this notice are preserved. This file is offered as-is,
+# without warranty of any kind.
+
+import getopt
+import re
+import sys
+import xml.sax
+import xml.sax.handler
+
+class IpfixEntityHandler(xml.sax.handler.ContentHandler):
+
+ RECORD_FIELDS = ['name', 'dataType', 'elementId', 'status']
+
+ # Cf. RFC 5101, Section 6.
+ DATA_TYPE_SIZE = {
+ 'unsigned8': 1,
+ 'unsigned16': 2,
+ 'unsigned32': 4,
+ 'unsigned64': 8,
+ 'signed8': 1,
+ 'signed16': 2,
+ 'signed32': 4,
+ 'signed64': 8,
+ 'float32': 4,
+ 'float64': 8,
+ 'boolean': 1, # Not clear.
+ 'macAddress': 6,
+ 'octetArray': 0, # Not clear.
+ 'string': 0, # Not clear.
+ 'dateTimeSeconds': 4,
+ 'dateTimeMilliseconds': 8,
+ 'dateTimeMicroseconds': 8,
+ 'dateTimeNanoseconds': 8,
+ 'ipv4Address': 4,
+ 'ipv6Address': 16,
+ }
+
+ def __init__(self):
+ self.current_field_name = None
+ self.current_field_value = []
+ self.current_record = dict()
+
+ def startDocument(self):
+ print """\
+/* IPFIX entities. */
+#ifndef IPFIX_ENTITY
+#define IPFIX_ENTITY(ENUM, ID, SIZE, NAME)
+#endif
+"""
+
+ def endDocument(self):
+ print """
+#undef IPFIX_ENTITY"""
+
+ def startElement(self, name, attrs):
+ if name in self.RECORD_FIELDS:
+ self.current_field_name = name
+ else:
+ self.current_field_name = None
+ self.current_field_value = []
+
+ @staticmethod
+ def camelcase_to_uppercase(s):
+ return re.sub('(.)([A-Z]+)', r'\1_\2', s).upper()
+
+ def endElement(self, name):
+ if self.current_field_name is not None:
+ self.current_record[self.current_field_name] = ''.join(
+ self.current_field_value).strip()
+ elif (name == 'record'
+ and self.current_record.get('status') == 'current'
+ and 'dataType' in self.current_record):
+
+ self.current_record['enumName'] = self.camelcase_to_uppercase(
+ self.current_record['name'])
+ self.current_record['dataTypeSize'] = self.DATA_TYPE_SIZE.get(
+ self.current_record['dataType'], 0)
+
+ print 'IPFIX_ENTITY(%(enumName)s, %(elementId)s, ' \
+ '%(dataTypeSize)i, %(name)s)' % self.current_record
+ self.current_record.clear()
+
+ def characters(self, content):
+ if self.current_field_name is not None:
+ self.current_field_value.append(content)
+
+def print_ipfix_entity_macros(xml_file):
+ xml.sax.parse(xml_file, IpfixEntityHandler())
+
+def usage(name):
+ print """\
+%(name)s: IPFIX entity definition generator
+Prints C macros defining IPFIX entities from the standard IANA file at
+<http://www.iana.org/assignments/ipfix/ipfix.xml>
+usage: %(name)s [OPTIONS] XML
+where XML is the standard IANA XML file defining IPFIX entities
+
+The following options are also available:
+ -h, --help display this help message
+ -V, --version display version information\
+""" % {'name': name}
+ sys.exit(0)
+
+if __name__ == '__main__':
+# try:
+ try:
+ options, args = getopt.gnu_getopt(sys.argv[1:], 'hV',
+ ['help', 'version'])
+ except getopt.GetoptError, geo:
+ sys.stderr.write('%s: %s\n' % (sys.argv[0], geo.msg))
+ sys.exit(1)
+
+ for key, value in options:
+ if key in ['-h', '--help']:
+ usage()
+ elif key in ['-V', '--version']:
+ print 'ipfix-gen-entities (Open vSwitch)'
+ else:
+ sys.exit(0)
+
+ if len(args) != 1:
+ sys.stderr.write('%s: exactly 1 non-option arguments required '
+ '(use --help for help)\n' % sys.argv[0])
+ sys.exit(1)
+
+ print_ipfix_entity_macros(args[0])
+
+# except Exception, e:
+# sys.stderr.write('%s: %s\n' % (sys.argv[0], e))
+# sys.exit(1)
+
+# Local variables:
+# mode: python
+# End: