Sflow packet header
Ref: https://datatracker.ietf.org/doc/html/rfc3176
Change-Id: Ie101eb956fd2cf0e0f213565263fc563ae0545d1
diff --git a/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/SflowSample.java b/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/SflowSample.java
new file mode 100644
index 0000000..041e994
--- /dev/null
+++ b/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/SflowSample.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2024-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.sflow;
+
+/**
+ * The sFlow Agent uses two forms of sampling.
+ * statistical packet-based sampling of switched flows,
+ * and time-based sampling of network interface statistics.
+ * Ref : https://datatracker.ietf.org/doc/html/rfc3176
+ */
+public interface SflowSample {
+
+ /**
+ * Get sflow sampling type.
+ * Sflow packet sampling type.
+ *
+ *
+ * @return sampling type number.
+ */
+ int getSampleType();
+}
diff --git a/apps/ipflow-monitor/sflow/app/src/main/java/org/onosproject/sflow/impl/SflowPacket.java b/apps/ipflow-monitor/sflow/app/src/main/java/org/onosproject/sflow/impl/SflowPacket.java
new file mode 100644
index 0000000..d8a1372
--- /dev/null
+++ b/apps/ipflow-monitor/sflow/app/src/main/java/org/onosproject/sflow/impl/SflowPacket.java
@@ -0,0 +1,308 @@
+/*
+ * Copyright 2023-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.sflow.impl;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.onosproject.sflow.SflowSample;
+import org.onlab.packet.Deserializer;
+import org.onlab.packet.BasePacket;
+
+import static com.google.common.base.Preconditions.checkState;
+
+/**
+ * The sFlow Datagram structure permits multiple samples to be included in each
+ * datagram, the sFlow Agent must not wait for a buffer to fill with samples
+ * before sending the sFlow Datagram. sFlow is intended to provide timely
+ * information on traffic
+ * Ref: (A) https://www.ietf.org/rfc/rfc3176.txt
+ * (B) https://sflow.org/sflow_version_5.txt
+ * The Packet Header format is specified as:
+ * <p>
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | sFlow Version Number |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Agent IP Version |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Agent IP Address |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | SubAgent ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Sequence Number |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | System Up Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Number of Samples |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Sample Data Headers |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+public final class SflowPacket extends BasePacket {
+
+ private int version; //current supported version is 5
+ private int agentIpVersion; // current supported version 1=v4, 2=v6
+ private String agentAddress; // sflow agent IP address
+ private int subAgentID; //sflow implemented on distributed device
+ private int seqNumber; // To overcome spoofed attacks of spoofed sflow dgrams
+ private int sysUptime; // Milliseconds since device last booted
+ private int numberOfSamples; // number of samplings
+ private List<SflowSample> sFlowsample; // List of sampling data headers
+
+ private SflowPacket(Builder builder) {
+ this.version = builder.version;
+ this.agentIpVersion = builder.agentIpVersion;
+ this.agentAddress = builder.agentAddress;
+ this.subAgentID = builder.subAgentID;
+ this.seqNumber = builder.seqNumber;
+ this.sysUptime = builder.sysUptime;
+ this.numberOfSamples = builder.numberOfSamples;
+ this.sFlowsample = builder.sflowSample;
+ }
+
+
+ /**
+ * Returns Version of Flow entry ; Supported Version 2,4,5.
+ *
+ * @return version number
+ */
+ public int getVersion() {
+ return version;
+ }
+
+ /**
+ * Returns The address type of the address associated with this agent.
+ * Supported Version IPv4
+ *
+ * @return version number
+ */
+ public int getAgentIpVersion() {
+ return agentIpVersion;
+ }
+
+ /**
+ * Returns The IP address associated with this agent ; Supported Version IPv4.
+ * The IP address associated with this agent. In the case of a multi-homed
+ * agent, this should be the loopback address of the agent. The sFlowAgent
+ * address must provide SNMP connectivity to the agent. The address should be an
+ * invariant that does not change as interfaces are reconfigured, enabled,
+ * disabled, added or removed. A manager should be able to use the
+ * sFlowAgentAddress as a unique key that will identify this agent over extended
+ * periods of time so that a history can be maintained.
+ *
+ * @return IP Address
+ */
+ public String getAgentAddress() {
+ return agentAddress;
+ }
+
+ /**
+ * Returns : 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.
+ *
+ * @return IP Address of subAgent
+ */
+ public int getSubAgentID() {
+ return subAgentID;
+ }
+
+ /**
+ * Returns Sequence number of flow entry . Incremented with each flow sample.
+ * generated by this source_id
+ *
+ * @return sequence number
+ */
+ public int getSeqNumber() {
+ return seqNumber;
+ }
+
+ /**
+ * Returns time in milliseconds since this device was first booted.
+ *
+ * @return system up time
+ **/
+ public int getSysUptime() {
+ return sysUptime;
+ }
+
+ /**
+ * Returns number of samplings generated in sFlow datagram.
+ *
+ * @return Number of samplings
+ **/
+
+ public int getNumberSample() {
+ return numberOfSamples;
+ }
+
+ /**
+ * Returns number of samplings generated in sFlow datagram. An sFlow Datagram.
+ * contains lists of Packet Flow Records and counter records. The format of each
+ * Packet Flow Record is identified by a data_format value. The data_format name
+ * space is extensible, allowing for the addition of standard record types as
+ * well as vendor specific extensions.
+ *
+ * @return List of Sample data Headers
+ **/
+ public List<SflowSample> getSampleDataHeaders() {
+ return sFlowsample;
+ }
+
+ /**
+ * Deserializer function for sFlow packets.
+ *
+ * @return deserializer function
+ */
+ public static Deserializer<SflowPacket> deserializer() {
+ return (data, offset, length) -> null;
+ }
+
+ @Override
+ public byte[] serialize() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ /**
+ * Builder for sFlow packet.
+ */
+ private static class Builder {
+ private int version;
+ private int agentIpVersion;
+ private String agentAddress;
+ private int subAgentID;
+ private int seqNumber;
+ private int sysUptime;
+ private int numberOfSamples;
+ private List<SflowSample> sflowSample = new LinkedList<>();
+
+ /**
+ * Setter sFlow Version of Flow entry ; Supported Version 2,4,5.
+ *
+ * @param version number.
+ * @return this class builder.
+ */
+ public Builder version(int version) {
+ this.version = version;
+ return this;
+ }
+
+ /**
+ * Setter for The address type of the address associated with this agent.
+ *
+ * @param agent ip version.
+ * @return this class builder.
+ */
+ public Builder agentIpVersion(int agentIpVersion) {
+ this.agentIpVersion = agentIpVersion;
+ return this;
+ }
+
+ /**
+ * Setter The IP address associated with this agent.
+ *
+ * @param IP Address.
+ * @return this class builder.
+ */
+ public Builder agentAddress(String agentAddress) {
+ this.agentAddress = agentAddress;
+ return this;
+ }
+
+ /**
+ * Setter for time in milliseconds since this device was first booted.
+ *
+ * @param agent id.
+ * @return this class builder.
+ */
+ public Builder subAgentID(int subAgentID) {
+ this.subAgentID = subAgentID;
+ return this;
+ }
+
+ /**
+ * Setter for number of samplings generated in sFlow datagram.
+ *
+ * @param Number of samplings.
+ * @return this class builder.
+ */
+ public Builder numberOfSamples(int numberOfSamples) {
+ this.numberOfSamples = numberOfSamples;
+ return this;
+ }
+
+ /**
+ * Setter for time in milliseconds since this device was first booted.
+ *
+ * @param sysUptime system up time.
+ * @return this class builder.
+ */
+ public Builder sysUptime(int sysUptime) {
+ this.sysUptime = sysUptime;
+ return this;
+ }
+
+ /**
+ * Returns Sequence number of flow entry . Incremented with each flow sampling.
+ * generated by this source_id
+ *
+ * @param sequence number.
+ * @return this class builder.
+ */
+ public Builder seqNumber(int seqNumber) {
+ this.seqNumber = seqNumber;
+ return this;
+ }
+
+ /**
+ * Setter for list of samplings.
+ *
+ * @param sflowSample list of samplings.
+ * @return this class builder.
+ */
+ public Builder sflowSample(SflowSample sflowSample) {
+ this.sflowSample.add(sflowSample);
+ return this;
+ }
+
+
+ /**
+ * Checks arguments for sFlow packet.
+ */
+ private void checkArguments() {
+ checkState(version != 0, "Invalid Version.");
+ checkState(agentIpVersion != 0, "Invalid ipVersionAgent.");
+ checkState(subAgentID != 0, "Invalid subAgentID.");
+ checkState(seqNumber != 0, "Invalid SeqNumber.");
+ checkState(sysUptime != 0, "Invalid sysUptime.");
+ }
+
+ /**
+ * Builds sFlow packet.
+ *
+ * @return sflowpacket.
+ */
+ public SflowPacket build() {
+ checkArguments();
+ return new SflowPacket(this);
+ }
+
+ }
+}