/* Proposed sFlow Datagram Version 5 (draft 7) */ /* Revision History - version 5 adds support for: Adds sub-agent support. Adds Packet discard information. Adds support for vendor specific extensions. Adds length information to data fields. Adds length information to sample types. Define reset semantics for flow_sample,counter_sample sequence no. Splits sFlow datagram definition from flow/counter data definitions. Note: Revision history for sFlow data definitions is now part of data definition document. */ /* Address types */ typedef opaque ip_v4[4]; typedef opaque ip_v6[16]; enum address_type { IP_V4 = 1, IP_V6 = 2 } union address (address_type type) { case IP_V4: ip_v4; case IP_V6: ip_v6; } /* Data Format The data_format uniquely identifies the format of an opaque structure in the sFlow specification. A data_format is contructed as follows: - The most significant 20 bits correspond to the SMI Private Enterprise Code of the entity responsible for the structure definition. A value of zero is used to denote standard structures defined by sflow.org. - The least significant 12 bits are a structure format number assigned by the enterprise that should uniquely identify the the format of the structure. There are currently three opaque structures where which data_formats are used: 1. sample_data 2. counter_data 3. flow_data Structure format numbers may be re-used within each of these contexts. For example, an (inmon,1) data_format could identify a particular set of counters when used to describe counter_data, but refer to a set of flow attributes when used to describe flow_data. An sFlow implementor should use the standard structures where possible, even if they can only be partially populated. Vendor specific structures are allowed, but should only be used to supplement the existing structures, or to carry information that hasn't yet been standardized. Enterprises are encouraged to publish structure definitions in XDR format to www.sflow.org. A structure description document should contain an XDR structure definition immediately preceded by a comment listing the structure to which it applies, the enterprise number, and the structure number. See the definitions of counter_sample and flow_sample for examples. Note: An enterprise which has defined sFlow structures is permitted to extend those structure definitions at the end without changing structure numbers. Any changes that would alter or invalidate fields in published structure definitions must be implemented using a new structure number. This policy allows additional data to be added to structures while still maintaining backward compatibility. Applications receiving sFlow data must always use the opaque length information when decoding opaque<> structures so that encountering extended structures will not cause decoding errors. Note that these rules apply to the standard structures as well. */ typedef unsigned int data_format; /* sFlowDataSource encoded as follows: The most significant byte of the source_id is used to indicate the type of sFlowDataSource: 0 = ifIndex 1 = smonVlanDataSource 2 = entPhysicalEntry The lower three bytes contain the relevant index value. */ typedef unsigned int sflow_data_source; struct flow_record { data_format flow_format; /* The format of sflow_data */ opaque flow_data<>; /* Flow data uniquely defined by the flow_format. */ } /* Input/output port information Encoding of interface(s) involved in the packet's path through the device. 0 if interface is not known. The most significant 2 bits are used to indicate the format of the 30 bit value. - format = 0 single interface value is ifIndex of the interface. A value of 0x3FFFFFFF indicates that there is no input or output interface (according to which field it appears in). This is used in describing traffic which is not bridged, routed, or otherwise sent through the device being monitored by the agent, but which rather originates or terminates in the device itself. In the input field, this value is used to indicate packets for which the origin was the device itself (e.g. a RIP request packet sent by the device, if it is acting as an IP router). In the output field, this value is used to indicate packets for which the destination was the device itself (e.g. a RIP response packet (whether unicast or not) received by the device, if it is acting as an IP router). - format = 1 packet discarded value is a reason code. Currently the following codes are defined: 0 - 255 use ICMP Destination Unreachable codes See www.iana.org for authoritative list. RFC 1812, section 5.2.7.1 describes the current codes. Note that the use of these codes does not imply that the packet to which they refer is an IP packet, or if it is, that an ICMP message of any kind was generated for it. Current value are: 0 Net Unreachable 1 Host Unreachable 2 Protocol Unreachable 3 Port Unreachable 4 Fragmentation Needed and Don't Fragment was Set 5 Source Route Failed 6 Destination Network Unknown 7 Destination Host Unknown 8 Source Host Isolated 9 Communication with Destination Network is Administratively Prohibited 10 Communication with Destination Host is Administratively Prohibited 11 Destination Network Unreachable for Type of Service 12 Destination Host Unreachable for Type of Service 13 Communication Administratively Prohibited 14 Host Precedence Violation 15 Precedence cutoff in effect 256 = unknown 257 = ttl exceeded 258 = ACL 259 = no buffer space 260 = RED 261 = traffic shaping/rate limiting 262 = packet too big (for protocols that don't support fragmentation) Note: Additional reason codes may be published over time. An application receiving sFlow must be prepared to accept additional reason codes. The authoritative list of reason codes will be maintained at www.sflow.org - format = 2 multiple destination interfaces value is the number of interfaces. A value of 0 indicates an unknown number greater than 1. Note: Formats 1 & 2 apply only to an output interface and never to an input interface. A packet is always received on a single (possibly unknown) interface. Examples: 0x00000002 indicates ifIndex = 2 0x00000000 ifIndex unknown. 0x40000001 packet discarded because of ACL. 0x80000007 indicates a packet sent to 7 interfaces. 0x80000000 indicates a packet sent to an unknown number of interfaces greater than 1. */ typedef unsigned int interface; /* Format of a single flow sample */ /* opaque = sample_data; enterprise = 0; format = 1 */ struct flow_sample { unsigned int sequence_number; /* Incremented with each flow sample generated by this source_id. Note: If a source_id reset affects the sample_pool then the sequence_number must also be reset. */ sflow_data_source source_id; /* sFlowDataSource */ unsigned int sampling_rate; /* sFlowPacketSamplingRate */ unsigned int sample_pool; /* Total number of packets that could have been sampled (i.e. packets skipped by sampling process + total number of samples) */ unsigned int drops; /* Number of times that the sFlow agent detected that a packet marked to be sampled was dropped due to lack of resources. The drops counter reports the total number of drops detected since the agent was last reset. A high drop rate indicates that the management agent is unable to process samples as fast as they are being generated by hardware. Increasing sampling_rate will reduce the drop rate. Note: An agent that cannot detect drops will always report zero. */ interface input; /* Interface packet was received on. */ interface output; /* Interface packet was sent on. */ flow_record flow_records<>; /* Information about a sampled packet */ } struct counter_record { data_format counter_format; /* The format of counter_data */ opaque counter_data<>; /* A block of counters uniquely defined by the counter_format. */ } /* Format of a single counter sample */ /* opaque = sample_data; enterprise = 0; format = 2 */ struct counters_sample { unsigned int sequence_number; /* Incremented with each counter sample generated by this source_id Note: If a source_id reset affects any of the counters being reported then the sequence_number must be reset. */ sflow_data_source source_id; /* sFlowDataSource */ unsigned int last_change; /* The value of uptime when this source_id was last reset. A reset is any change to the value of a counter that would make the delta's between counter values in successive counter_samples invalid. If no resets have occured since the agent was last booted then last_change will be zero. */ counter_record counters<>; /* Counters polled for this source */ } /* Format of a sample datagram */ struct sample_record { data_format sample_type; /* Specifies the type of sample data */ opaque sample_data<>; /* A structure corresponding to the sample_type */ } /* Header information for sFlow version 5 datagrams The sub-agent field is used when an sFlow agent is implemented on a distributed architecture and where it is impractical to bring the samples to a single point for transmission. However, it is strongly recommended that wherever possible the sub-agent mechanism not be used. If multiple processors are available within a device the various tasks associated with creating flow and counter samples can be distributed among the processors. However, the agent should be architected so that all the samples are marshalled into a single datagram stream. The final marshalling task involved very little processing, but has important benefits in making the overall sFlow system scalable. By reducing the number of UDP packets and packet streams, the protocol overheads associated with sFlow are significantly reduced at the receiver. Each sFlowDataSource must be associated with only one sub-agent. The association between sFlowDataSource and sub-agent must remain constant for the entire duration of an sFlow session. */ struct sample_datagram_v5 { address agent_address /* IP address of sampling agent, sFlowAgentAddress. */ unsigned int sub_agent_id; /* Used to distinguishing between datagram streams from separate agent sub entities within an device. */ unsigned int sequence_number; /* Incremented with each sample datagram generated by a sub-agent within an agent. */ unsigned int uptime; /* Current time (in milliseconds since device last booted). Should be set as close to datagram transmission time as possible. Note: While a sub-agents should try and track the global sysUptime value a receiver of sFlow packets must not assume that values are synchronised between sub-agents. */ sample_record samples<>; /* An array of sample records */ } enum datagram_version { VERSION5 = 5 } union sample_datagram_type (datagram_version version) { case VERSION5: sample_datagram_v5 datagram; } struct sample_datagram { sample_datagram_type version; }