Java tutorial
/* * Copyright 2015 Open Networking Laboratory * * 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.ipfix; import java.util.ArrayList; import java.util.List; import org.onlab.packet.Ethernet; import org.onlab.packet.IPv4; import org.onlab.packet.IPv6; import org.onlab.packet.Ip6Address; import org.onlab.packet.IpAddress; import org.onlab.packet.MacAddress; import org.onosproject.ipfix.packet.DataRecord; import org.onosproject.net.flow.FlowEntry; import org.onosproject.net.flow.FlowRule; import org.onosproject.net.flow.FlowRuleEvent; import org.onosproject.net.flow.FlowRuleListener; import org.onosproject.net.flow.criteria.EthCriterion; import org.onosproject.net.flow.criteria.EthTypeCriterion; import org.onosproject.net.flow.criteria.IPCriterion; import org.onosproject.net.flow.criteria.IPDscpCriterion; import org.onosproject.net.flow.criteria.IPEcnCriterion; import org.onosproject.net.flow.criteria.IPProtocolCriterion; import org.onosproject.net.flow.criteria.IPv6FlowLabelCriterion; import org.onosproject.net.flow.criteria.IcmpCodeCriterion; import org.onosproject.net.flow.criteria.IcmpTypeCriterion; import org.onosproject.net.flow.criteria.Icmpv6CodeCriterion; import org.onosproject.net.flow.criteria.Icmpv6TypeCriterion; import org.onosproject.net.flow.criteria.PortCriterion; import org.onosproject.net.flow.criteria.TcpPortCriterion; import org.onosproject.net.flow.criteria.UdpPortCriterion; import org.onosproject.net.flow.criteria.VlanIdCriterion; import org.onosproject.net.flow.criteria.Criterion.Type; import org.onosproject.net.flow.instructions.Instruction; import org.onosproject.net.flow.instructions.Instructions.OutputInstruction; import org.onosproject.openflow.controller.Dpid; import com.google.common.primitives.Longs; /** * Flow Rule Listener for detecting flow removal or flow statistics update by ONOS. */ public class FlowRemovedListener implements FlowRuleListener { private IpfixManager ipfixManager; /** * Flow Event listerner for Flow removed events of Reactive Forwarding application. * * @param ipfixManager ipfix manager instance */ public FlowRemovedListener(IpfixManager ipfixManager) { this.ipfixManager = ipfixManager; } @Override public void event(FlowRuleEvent event) { switch (event.type()) { case RULE_REMOVED: FlowRule rule = event.subject(); FlowEntry entry = (FlowEntry) rule; if (entry.appId() == ipfixManager.coreService.getAppId("org.onosproject.fwd").id()) { flowRemovedRfwd(entry); } break; default: break; } } /** * Handle ONOS Reactive forwarding application flow removal. * When flow is removed, generate and send IPFIX record. * * @param entry flow entry removed from ONOS */ private void flowRemovedRfwd(FlowEntry entry) { //Log ipfixManager.log.trace("Flow Removed from Reactive Forwarding, id={}, device={}, selector={}, treatment={}", entry.id(), entry.deviceId(), entry.selector(), entry.treatment()); // Exporters IpAddress exporterIpv4 = IpAddress.valueOf( ipfixManager.deviceService.getDevice(entry.deviceId()).annotations().toString().split("=")[2] .split(":")[0]); long dpid = Dpid.dpid(entry.deviceId().uri()).value(); byte[] byteExporterIpv6 = new byte[16]; System.arraycopy(Longs.toByteArray(0), 0, byteExporterIpv6, 0, 8); System.arraycopy(Longs.toByteArray(dpid), 0, byteExporterIpv6, 8, 8); Ip6Address exporterIpv6 = Ip6Address.valueOf(byteExporterIpv6); // Timestamps, octets, packets long start = System.currentTimeMillis() - (1000 * entry.life()); long end = System.currentTimeMillis(); long octets = entry.bytes(); long packets = entry.packets(); // Input and Output ports PortCriterion portCrit = (PortCriterion) entry.selector().getCriterion(Type.IN_PORT); int intfIn = (portCrit == null) ? 0 : (int) portCrit.port().toLong(); List<Instruction> instructions = entry.treatment().allInstructions(); int intfOut = 0; for (Instruction instruction : instructions) { if (instruction.type() == Instruction.Type.OUTPUT) { OutputInstruction outputInstruction = (OutputInstruction) instruction; intfOut = (outputInstruction == null) ? 0 : (int) outputInstruction.port().toLong(); } } // Ethernet MACs, Ethertype and VLAN EthCriterion ethCrit; ethCrit = (EthCriterion) entry.selector().getCriterion(Type.ETH_SRC); MacAddress srcMac = (ethCrit == null) ? MacAddress.valueOf("00:00:00:00:00:00") : ethCrit.mac(); ethCrit = (EthCriterion) entry.selector().getCriterion(Type.ETH_DST); MacAddress dstMac = (ethCrit == null) ? MacAddress.valueOf("00:00:00:00:00:00") : ethCrit.mac(); EthTypeCriterion ethTypeCrit = (EthTypeCriterion) entry.selector().getCriterion(Type.ETH_TYPE); Short ethType = (ethTypeCrit == null) ? 0x0000 : ethTypeCrit.ethType().toShort(); VlanIdCriterion vlanCrit = (VlanIdCriterion) entry.selector().getCriterion(Type.VLAN_VID); Short vlan = (vlanCrit == null) ? 0x0000 : vlanCrit.vlanId().toShort(); // IP Criterion check IPCriterion srcIpCrit = (IPCriterion) entry.selector().getCriterion(Type.IPV4_SRC); IPCriterion dstIpCrit = (IPCriterion) entry.selector().getCriterion(Type.IPV4_DST); IPCriterion srcIp6Crit = (IPCriterion) entry.selector().getCriterion(Type.IPV6_SRC); IPCriterion dstIp6Crit = (IPCriterion) entry.selector().getCriterion(Type.IPV6_DST); // If IP criterions are null send MAC Data Record, else send IPv4 or IPv6 Data Record if (srcIpCrit == null && dstIpCrit == null && srcIp6Crit == null && dstIp6Crit == null) { DataRecordRfwdMac record = new DataRecordRfwdMac(exporterIpv4, exporterIpv6, start, end, octets, packets, intfIn, intfOut, srcMac, dstMac, ethType, vlan); List<DataRecord> recordList = new ArrayList<DataRecord>(); recordList.add(record); ipfixManager.ipfixSender.sendRecords(DataRecordRfwdMac.getTemplateRecord(), recordList, dpid, IpfixManager.collectorIp, IpfixManager.collectorPort); } else { // Checking IPv4 and IPv6 criterions IPProtocolCriterion protocolCrit = (IPProtocolCriterion) entry.selector().getCriterion(Type.IP_PROTO); byte ipProtocol = (protocolCrit == null) ? (byte) 0xff : (byte) protocolCrit.protocol(); IPDscpCriterion dscpCrit = (IPDscpCriterion) entry.selector().getCriterion(Type.IP_DSCP); byte dscp = (dscpCrit == null) ? 0x00 : dscpCrit.ipDscp(); IPEcnCriterion ecnCrit = (IPEcnCriterion) entry.selector().getCriterion(Type.IP_ECN); byte ecn = (ecnCrit == null) ? 0x00 : ecnCrit.ipEcn(); byte tos = (byte) ((byte) (dscp << 2) | ecn); IPv6FlowLabelCriterion flowLabelCrit = (IPv6FlowLabelCriterion) entry.selector() .getCriterion(Type.IPV6_FLABEL); int flowLabelIpv6 = (flowLabelCrit == null) ? 0 : flowLabelCrit.flowLabel(); int srcPort = 0; int dstPort = 0; if (ipProtocol == IPv4.PROTOCOL_TCP) { TcpPortCriterion tcpCrit; tcpCrit = (TcpPortCriterion) entry.selector().getCriterion(Type.TCP_SRC); srcPort = (tcpCrit == null) ? 0 : tcpCrit.tcpPort().toInt(); tcpCrit = (TcpPortCriterion) entry.selector().getCriterion(Type.TCP_DST); dstPort = (tcpCrit == null) ? 0 : tcpCrit.tcpPort().toInt(); } else if (ipProtocol == IPv4.PROTOCOL_UDP) { UdpPortCriterion udpCrit; udpCrit = (UdpPortCriterion) entry.selector().getCriterion(Type.UDP_SRC); srcPort = (udpCrit == null) ? 0 : udpCrit.udpPort().toInt(); udpCrit = (UdpPortCriterion) entry.selector().getCriterion(Type.UDP_DST); dstPort = (udpCrit == null) ? 0 : udpCrit.udpPort().toInt(); } else if (ipProtocol == IPv4.PROTOCOL_ICMP) { IcmpTypeCriterion icmpTypeCrit = (IcmpTypeCriterion) entry.selector() .getCriterion(Type.ICMPV4_TYPE); Short icmpType = (icmpTypeCrit == null) ? 0 : icmpTypeCrit.icmpType(); IcmpCodeCriterion icmpCodeCrit = (IcmpCodeCriterion) entry.selector() .getCriterion(Type.ICMPV4_CODE); Short icmpCode = (icmpCodeCrit == null) ? 0 : icmpCodeCrit.icmpCode(); dstPort = 256 * icmpType + icmpCode; } else if (ipProtocol == IPv6.PROTOCOL_ICMP6) { Icmpv6TypeCriterion icmpv6TypeCrit = (Icmpv6TypeCriterion) entry.selector() .getCriterion(Type.ICMPV6_TYPE); Short icmpType = (icmpv6TypeCrit == null) ? 0 : icmpv6TypeCrit.icmpv6Type(); Icmpv6CodeCriterion icmpv6CodeCrit = (Icmpv6CodeCriterion) entry.selector() .getCriterion(Type.ICMPV6_CODE); Short icmpCode = (icmpv6CodeCrit == null) ? 0 : icmpv6CodeCrit.icmpv6Code(); dstPort = 256 * icmpType + icmpCode; } // If IPv4 than send IPv4 Data record if ((srcIpCrit != null || dstIpCrit != null) && ethType == Ethernet.TYPE_IPV4) { IpAddress srcIp = (srcIpCrit == null) ? IpAddress.valueOf(0) : srcIpCrit.ip().address(); IpAddress dstIp = (dstIpCrit == null) ? IpAddress.valueOf(0) : dstIpCrit.ip().address(); DataRecordRfwdIpv4 record = new DataRecordRfwdIpv4(exporterIpv4, exporterIpv6, start, end, octets, packets, intfIn, intfOut, srcMac, dstMac, ethType, vlan, srcIp, dstIp, ipProtocol, tos, (short) srcPort, (short) dstPort); List<DataRecord> recordList = new ArrayList<DataRecord>(); recordList.add(record); ipfixManager.ipfixSender.sendRecords(DataRecordRfwdIpv4.getTemplateRecord(), recordList, dpid, IpfixManager.collectorIp, IpfixManager.collectorPort); } // If IPv6 than send IPv6 Data record if ((srcIp6Crit != null || dstIp6Crit != null) && ethType == Ethernet.TYPE_IPV6) { Ip6Address srcIp6 = (srcIp6Crit == null) ? Ip6Address.valueOf("0:0:0:0:0:0:0:0") : srcIp6Crit.ip().address().getIp6Address(); Ip6Address dstIp6 = (dstIp6Crit == null) ? Ip6Address.valueOf("0:0:0:0:0:0:0:0") : dstIp6Crit.ip().address().getIp6Address(); DataRecordRfwdIpv6 record = new DataRecordRfwdIpv6(exporterIpv4, exporterIpv6, start, end, octets, packets, intfIn, intfOut, srcMac, dstMac, ethType, vlan, srcIp6, dstIp6, flowLabelIpv6, ipProtocol, tos, (short) srcPort, (short) dstPort); List<DataRecord> recordList = new ArrayList<DataRecord>(); recordList.add(record); ipfixManager.ipfixSender.sendRecords(DataRecordRfwdIpv6.getTemplateRecord(), recordList, dpid, IpfixManager.collectorIp, IpfixManager.collectorPort); } } } }