diff options
author | Romain Lenglet <rlenglet@vmware.com> | 2013-04-22 10:01:14 -0700 |
---|---|---|
committer | Ben Pfaff <blp@nicira.com> | 2013-04-22 14:33:58 -0700 |
commit | 29089a540cfa30a834e3ee19a8b4c52ff2e331b2 (patch) | |
tree | 7fd0c5d666c5f18fbd7ad463edc8d908636999f3 /ofproto/ipfix-gen-entities | |
parent | d8558b4ae86f0f64afe520c4c1d99f55a94063d8 (diff) | |
download | openvswitch-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-x | ofproto/ipfix-gen-entities | 140 |
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: |