<extensions>true</extensions>
<configuration>
<instructions>
- <Export-Package>org.opendaylight.l2switch.packethandler.decoders,org.opendaylight.yang.gen.v1.urn.opendaylight.packetdecoder.config.rev140528,</Export-Package>
+ <Export-Package>org.opendaylight.l2switch.packethandler.decoders,</Export-Package>
<Import-Package>*</Import-Package>
</instructions>
</configuration>
</plugin>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- <version>${yangtools.version}</version>
- <executions>
- <execution>
- <goals>
- <goal>generate-sources</goal>
- </goals>
- <configuration>
- <codeGenerators>
- <generator>
- <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
- </codeGeneratorClass>
- <outputBaseDir>${configCodeGeneratorPath}</outputBaseDir>
- <additionalConfiguration>
- <namespaceToPackage1>
- urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
- </namespaceToPackage1>
- </additionalConfiguration>
- </generator>
- </codeGenerators>
- <inspectDependencies>true</inspectDependencies>
- </configuration>
- </execution>
- </executions>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>yang-jmx-generator-plugin</artifactId>
- <version>${config.version}</version>
- </dependency>
- </dependencies>
- </plugin>
</plugins>
</build>
*/
package org.opendaylight.l2switch.packethandler;
+import com.google.common.collect.ImmutableSet;
import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
-import org.opendaylight.l2switch.packethandler.decoders.*;
-import org.opendaylight.yangtools.concepts.Registration;
-import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.opendaylight.l2switch.packethandler.decoders.AbstractPacketDecoder;
+import org.opendaylight.l2switch.packethandler.decoders.ArpDecoder;
+import org.opendaylight.l2switch.packethandler.decoders.EthernetDecoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private final static Logger _logger = LoggerFactory.getLogger(PacketHandlerProvider.class);
- private Registration<NotificationListener> rawPacketListenerRegistration;
+ ImmutableSet<AbstractPacketDecoder> decoders;
/**
*/
@Override
public void onSessionInitiated(BindingAwareBroker.ProviderContext providerContext) {
- DataBrokerService dataService = providerContext.<DataBrokerService>getSALService(DataBrokerService.class);
NotificationProviderService notificationProviderService =
providerContext.<NotificationProviderService>getSALService(NotificationProviderService.class);
- DecoderRegistry decoderRegistry = new DecoderRegistry();
+ initiateDecoders(notificationProviderService);
- PacketNotificationRegistry packetNotificationRegistry = new PacketNotificationRegistry();
- notificationProviderService.registerInterestListener(packetNotificationRegistry);
-
- PacketDecoderService packetDecoderService = new PacketDecoderServiceImpl(decoderRegistry, packetNotificationRegistry);
-
- RawPacketHandler rawPacketHandler = new RawPacketHandler();
- rawPacketHandler.setNotificationProviderService(notificationProviderService);
- rawPacketHandler.setDecoderRegistry(decoderRegistry);
- rawPacketHandler.setPacketNotificationRegistry(packetNotificationRegistry);
- this.rawPacketListenerRegistration = notificationProviderService.registerNotificationListener(rawPacketHandler);
}
/**
*/
@Override
public void close() throws Exception {
- if(rawPacketListenerRegistration != null)
- rawPacketListenerRegistration.close();
+ closeDecoders();
+ }
+
+ private void initiateDecoders(NotificationProviderService notificationProviderService) {
+ decoders = new ImmutableSet.Builder<AbstractPacketDecoder>()
+ .add(new EthernetDecoder(notificationProviderService))
+ .add(new ArpDecoder(notificationProviderService))
+ .build();
+ }
+
+ private void closeDecoders() throws Exception {
+ if(decoders != null && !decoders.isEmpty()) {
+ for(AbstractPacketDecoder decoder : decoders) {
+ decoder.close();
+ }
+ }
}
}
\ No newline at end of file
+++ /dev/null
-package org.opendaylight.l2switch.packethandler;
-
-import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.l2switch.packethandler.decoders.DecoderRegistry;
-import org.opendaylight.l2switch.packethandler.decoders.PacketDecoder;
-import org.opendaylight.l2switch.packethandler.decoders.PacketNotificationRegistry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.BasePacket;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.BasePacketBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.Packet;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.PacketType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.packet.PacketPayloadType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.packet.PacketPayloadTypeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.packet.RawPacket;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.packet.RawPacketBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingListener;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived;
-import org.opendaylight.yangtools.yang.binding.Notification;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * RawPacketHandler subscribes to RawPacket in event. Calls the Ethernet decoder to
- */
-public class RawPacketHandler implements PacketProcessingListener {
- private final static Logger _logger = LoggerFactory.getLogger(RawPacketHandler.class);
-
- private NotificationProviderService notificationProviderService;
- private PacketNotificationRegistry packetNotificationRegistry;
- private DecoderRegistry decoderRegistry;
-
- public void setDecoderRegistry(DecoderRegistry decoderRegistry) {
- this.decoderRegistry = decoderRegistry;
- }
-
- public void setPacketNotificationRegistry(PacketNotificationRegistry packetNotificationRegistry) {
- this.packetNotificationRegistry = packetNotificationRegistry;
- }
-
-
- public void setNotificationProviderService(NotificationProviderService notificationProviderService) {
- this.notificationProviderService = notificationProviderService;
- }
-
- @Override
- public void onPacketReceived(PacketReceived packetReceived) {
-
- if(packetReceived == null) return;
-
- PacketPayloadType packetPayloadType = getPacketPayloadType(packetReceived);
- PacketDecoder packetDecoder = decoderRegistry.getDecoder(packetPayloadType);
- Packet packet = getBasePacket(packetReceived);
-
- while(packetDecoder != null) {
-
- packet = packetDecoder.decode(packet);
-
- if(packet == null) {
- _logger.info("Could not decode packet : []", packet);
- break;
- }
-
- Notification packetInNotification = packetDecoder.buildPacketNotification(packet);
- if(packetInNotification != null && packetNotificationRegistry.isListenerSubscribed(packetInNotification.getClass()))
- notificationProviderService.publish(packetInNotification);
-
- packetPayloadType = packet.getPacketPayloadType();
- if(packetPayloadType == null) {
- _logger.info("No PacketPayloadType set in packet : []", packet);
- break;
- }
-
- packetDecoder = decoderRegistry.getDecoder(packetPayloadType);
- }
- }
-
- private BasePacket getBasePacket(PacketReceived packetReceived) {
-
- return new BasePacketBuilder()
- .setPacketPayloadType(getPacketPayloadType(packetReceived))
- .setRawPacket(getRawPacket(packetReceived)).build();
- }
-
- private PacketPayloadType getPacketPayloadType(PacketReceived packetReceived) {
-
- //currently doesn't make use of packet received as currently only ethernet packets are received so following is hard coded.
- return new PacketPayloadTypeBuilder().setPacketType(PacketType.Raw).setPayloadType(PacketType.Ethernet.getIntValue()).build();
- }
-
- private RawPacket getRawPacket(PacketReceived packetReceived) {
- return new RawPacketBuilder().setIngress(packetReceived.getIngress()).setPayload(packetReceived.getPayload()).build();
- }
-
-}
package org.opendaylight.l2switch.packethandler.decoders;
+import com.google.common.collect.ImmutableMap;
import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.Packet;
+import org.opendaylight.yangtools.concepts.Registration;
import org.opendaylight.yangtools.yang.binding.Notification;
+import org.opendaylight.yangtools.yang.binding.NotificationListener;
/**
* A base class for all decoders. Each extended decoder should also implement a notification listener
* that it can consume. And make use of
*/
-public abstract class AbstractPacketDecoder<N extends Notification> implements NotificationProviderService.NotificationInterestListener{
+public abstract class AbstractPacketDecoder<ConsumedPacketNotification, ProducedPacketNotification extends Notification>
+ implements NotificationProviderService.NotificationInterestListener , AutoCloseable {
- private Class<N> producedPacketNotificationType;
+ private Class<ProducedPacketNotification> producedPacketNotificationType;
private NotificationProviderService notificationProviderService;
- private int listenerCount=0;
+
+
+ protected Registration<NotificationListener> listenerRegistration;
/**
* Constructor to
* @param producedPacketNotificationType
* @param notificationProviderService
*/
- public AbstractPacketDecoder(Class<N> producedPacketNotificationType, NotificationProviderService notificationProviderService) {
+ public AbstractPacketDecoder(Class<ProducedPacketNotification> producedPacketNotificationType, NotificationProviderService notificationProviderService) {
this.producedPacketNotificationType = producedPacketNotificationType;
this.notificationProviderService = notificationProviderService;
notificationProviderService.registerInterestListener(this);
}
+
/**
* Keeps track of listeners registered for the notification that a decoder produces.
* @param aClass
*/
@Override
public void onNotificationSubscribtion(Class<? extends Notification> aClass) {
- if (aClass !=null && aClass.isAssignableFrom(producedPacketNotificationType)) {
- listenerCount++;
- }
- }
-
- /**
- * TODO: This method is not there today but planning to propose it in MD_SAL notification service,
- * TODO: as it would be useful to know un-subscriptions to a notification as well.
- *
- * Keeps track of listeners unregistered for the notification that a decoder produces.
- * @param aClass
- @Override
- public void onNotificationUnSubscription(Class<? extends Notification> aClass) {
- if (aClass !=null && aClass.isAssignableFrom(producedPacketNotificationType)) {
- listenerCount--;
+ if (aClass !=null && aClass.equals(producedPacketNotificationType)) {
+ if(listenerRegistration == null) {
+ NotificationListener notificationListener = getConsumedNotificationListener();
+ listenerRegistration = notificationProviderService.registerNotificationListener(notificationListener);
+ }
}
}
- */
/**
* Every extended decoder should call this method on a receipt of a input packet notification.
* This method would make sure it decodes only when necessary and publishes corresponding event
* on successful decoding.
- * @param packet
*/
- public void decodeAndPublish(Packet packet) {
- Packet decodedPacket = null;
- if(listenerCount>0) {
- decodedPacket = decode(packet);
- if(decodedPacket!=null) {
- N packetNotification = buildPacketNotification(decodedPacket);
- if(packetNotification != null) {
- notificationProviderService.publish(packetNotification);
- }
- }
+ public void decodeAndPublish(ConsumedPacketNotification consumedPacketNotification) {
+ ProducedPacketNotification packetNotification = decode(consumedPacketNotification);
+ if(packetNotification != null) {
+ notificationProviderService.publish(packetNotification);
}
}
/**
* Decodes the payload in given Packet further and returns a extension of Packet.
* e.g. ARP, IPV4, LLDP etc.
*
- * @param packet
* @return
*/
- public abstract Packet decode(Packet packet);
+ public abstract ProducedPacketNotification decode(ConsumedPacketNotification consumedPacketNotification);
- /**
- * This is utility method for converting the decoded packet to its corresponding notification.
- *
- * @param decodedPacket
- * @return
- */
- public abstract N buildPacketNotification(Packet decodedPacket);
+
+ public abstract NotificationListener getConsumedNotificationListener();
+
+
+ @Override
+ public void close() throws Exception {
+ if(listenerRegistration != null) {
+ listenerRegistration.close();
+ }
+ }
}
--- /dev/null
+package org.opendaylight.l2switch.packethandler.decoders;
+
+import com.google.common.collect.ImmutableSet;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.arp.rev140528.ArpPacketOverEthernetReceived;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.arp.rev140528.ArpPacketOverEthernetReceivedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.EthernetPacketListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.EthernetPacketOverRawReceived;
+import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * ARP (Address Resolution Protocol) Packet Decoder
+ */
+public class ArpDecoder extends AbstractPacketDecoder<EthernetPacketOverRawReceived, ArpPacketOverEthernetReceived>
+ implements EthernetPacketListener {
+
+ private static final Logger _logger = LoggerFactory.getLogger(ArpDecoder.class);
+
+ public ArpDecoder(NotificationProviderService notificationProviderService) {
+ super(ArpPacketOverEthernetReceived.class, notificationProviderService);
+ }
+
+ /**
+ * Decode an EthernetPacket into an ArpPacket
+ */
+ @Override
+ public ArpPacketOverEthernetReceived decode(EthernetPacketOverRawReceived ethernetPacketOverRawReceived) {
+ ArpPacketOverEthernetReceivedBuilder builder = new ArpPacketOverEthernetReceivedBuilder();
+
+ byte[] data = ethernetPacketOverRawReceived.getPayload();
+ int offset = ethernetPacketOverRawReceived.getEthernetPacket().getPayloadOffset();
+ //TODO: PLease note that the payload is original payload and to decode ethernet payload use payload offset from ethernet
+ /*
+ EthernetPacketGrp ethernetPacket = (EthernetPacketGrp) packet;
+ builder.fieldsFrom(ethernetPacket);
+
+ try {
+ // Decode the hardware-type (HTYPE) and protocol-type (PTYPE) fields
+ builder.setHardwareType(KnownHardwareType.forValue(BitBufferHelper.getInt(BitBufferHelper.getBits(data, 0, 16))));
+ builder.setProtocolType(KnownEtherType.forValue(BitBufferHelper.getInt(BitBufferHelper.getBits(data, 16, 16))));
+
+ // Decode the hardware-length and protocol-length fields
+ builder.setHardwareLength(BitBufferHelper.getShort(BitBufferHelper.getBits(data, 32, 8)));
+ builder.setProtocolLength(BitBufferHelper.getShort(BitBufferHelper.getBits(data, 40, 8)));
+
+ // Decode the operation field
+ builder.setOperation(KnownOperation.forValue(BitBufferHelper.getInt(BitBufferHelper.getBits(data, 48, 16))));
+
+ // Decode the address fields
+ int indexSrcProtAdd = 64 + 8 * builder.getHardwareLength();
+ int indexDstHardAdd = indexSrcProtAdd + 8 * builder.getProtocolLength();
+ int indexDstProtAdd = indexDstHardAdd + 8 * builder.getHardwareLength();
+ if(builder.getHardwareType().equals(KnownHardwareType.Ethernet)) {
+ builder.setSourceHardwareAddress(HexEncode.bytesToHexStringFormat(BitBufferHelper.getBits(data, 64, 8 * builder.getHardwareLength())));
+ builder.setDestinationHardwareAddress(HexEncode.bytesToHexStringFormat(BitBufferHelper.getBits(data, indexDstHardAdd, 8 * builder.getHardwareLength())));
+ } else {
+ _logger.debug("Unknown HardwareType -- sourceHardwareAddress and destinationHardwareAddress are not decoded");
+ }
+
+ if(builder.getProtocolType().equals(KnownEtherType.Ipv4) || builder.getProtocolType().equals(KnownEtherType.Ipv6)) {
+ builder.setSourceProtocolAddress(InetAddress.getByAddress(BitBufferHelper.getBits(data, indexSrcProtAdd, 8 * builder.getProtocolLength())).getHostAddress());
+ builder.setDestinationProtocolAddress(InetAddress.getByAddress(BitBufferHelper.getBits(data, indexDstProtAdd, 8 * builder.getProtocolLength())).getHostAddress());
+ } else {
+ _logger.debug("Unknown ProtocolType -- sourceProtocolAddress and destinationProtocolAddress are not decoded");
+ }
+ } catch(BufferException | UnknownHostException e) {
+ _logger.debug("Exception while decoding APR packet", e.getMessage());
+ }
+*/
+ return builder.build();
+ }
+
+ @Override
+ public NotificationListener getConsumedNotificationListener() {
+ return this;
+ }
+
+ @Override
+ public void onEthernetPacketOverRawReceived(EthernetPacketOverRawReceived notification) {
+ decodeAndPublish(notification);
+ }
+}
+++ /dev/null
-package org.opendaylight.l2switch.packethandler.decoders;
-
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.packet.PacketPayloadType;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * DecoderRegistry maintains mapping of decoders to PacketPayloadType
- */
-public class DecoderRegistry {
- private Map<PacketPayloadType, PacketDecoder> packetPayloadTypeToDecoderMap = new HashMap<PacketPayloadType, PacketDecoder>();
-
- public void addDecoder(PacketPayloadType packetPayloadType, PacketDecoder decoder) {
- if(packetPayloadType == null || decoder == null) return;
-
- synchronized(this) {
- packetPayloadTypeToDecoderMap.put(packetPayloadType, decoder);
- }
-
- }
-
- public synchronized PacketDecoder getDecoder(PacketPayloadType packetPayloadType) {
- return packetPayloadTypeToDecoderMap.get(packetPayloadType);
- }
-}
--- /dev/null
+package org.opendaylight.l2switch.packethandler.decoders;
+
+import com.google.common.collect.ImmutableSet;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.EthernetPacketOverRawReceived;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.EthernetPacketOverRawReceivedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived;
+import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Ethernet Packet Decoder
+ */
+public class EthernetDecoder extends AbstractPacketDecoder<PacketReceived, EthernetPacketOverRawReceived> implements PacketProcessingListener {
+ private static final Logger _logger = LoggerFactory.getLogger(EthernetDecoder.class);
+ public static final Integer LENGTH_MAX = 1500;
+ public static final Integer ETHERTYPE_MIN = 1536;
+ public static final Integer ETHERTYPE_8021Q = 0x8100;
+ public static final Integer ETHERTYPE_QINQ = 0x9100;
+
+ public EthernetDecoder(NotificationProviderService notificationProviderService) {
+ super(EthernetPacketOverRawReceived.class, notificationProviderService);
+ }
+
+ @Override
+ public void onPacketReceived(PacketReceived packetReceived) {
+ decodeAndPublish(packetReceived);
+ }
+
+ /**
+ * Decode a RawPacket into an EthernetPacket
+ *
+ * @param packetReceived -- data from wire to deserialize
+ * @return
+ * @throws org.opendaylight.controller.sal.packet.BufferException
+ */
+ @Override
+ public EthernetPacketOverRawReceived decode(PacketReceived packetReceived) {
+ byte[] data = packetReceived.getPayload();
+ EthernetPacketOverRawReceivedBuilder builder = new EthernetPacketOverRawReceivedBuilder();
+ /*
+ try {
+ // Save original rawPacket
+ builder.setRawPacket(new RawPacketBuilder().setIngress(packetReceived.getIngress()).setPayload(data).build());
+
+ // Deserialize the destination & source fields
+ builder.setDestinationMac(new MacAddress(HexEncode.bytesToHexStringFormat(BitBufferHelper.getBits(data, 0, 48))));
+ builder.setSourceMac(new MacAddress(HexEncode.bytesToHexStringFormat(BitBufferHelper.getBits(data, 48, 48))));
+
+ // Deserialize the optional field 802.1Q headers
+ Integer nextField = BitBufferHelper.getInt(BitBufferHelper.getBits(data, 96, 16));
+ int extraHeaderBits = 0;
+ ArrayList<Header8021q> headerList = new ArrayList<Header8021q>();
+ while(nextField.equals(ETHERTYPE_8021Q) || nextField.equals(ETHERTYPE_QINQ)) {
+ Header8021qBuilder hBuilder = new Header8021qBuilder();
+ hBuilder.setType(Header8021qType.forValue(nextField));
+
+ // Read 2 more bytes for priority (3bits), drop eligible (1bit), vlan-id (12bits)
+ byte[] vlanBytes = BitBufferHelper.getBits(data, 112 + extraHeaderBits, 16);
+
+ // Remove the sign & right-shift to get the priority code
+ hBuilder.setPriorityCode((short) ((vlanBytes[0] & 0xff) >> 5));
+
+ // Remove the sign & remove priority code bits & right-shift to get drop-eligible bit
+ hBuilder.setDropEligible(1 == (((vlanBytes[0] & 0xff) & 0x10) >> 4));
+
+ // Remove priority code & drop-eligible bits, to get the VLAN-id
+ vlanBytes[0] = (byte) (vlanBytes[0] & 0x0F);
+ hBuilder.setVlan(BitBufferHelper.getInt(vlanBytes));
+
+ // Add 802.1Q header to the growing collection
+ headerList.add(hBuilder.build());
+
+ // Reset value of "nextField" to correspond to following 2 bytes for next 802.1Q header or EtherType/Length
+ nextField = BitBufferHelper.getInt(BitBufferHelper.getBits(data, 128 + extraHeaderBits, 16));
+
+ // 802.1Q header means payload starts at a later position
+ extraHeaderBits += 32;
+ }
+ // Set 802.1Q headers
+ if(!headerList.isEmpty()) {
+ builder.setHeader8021q(headerList);
+ }
+
+ // Deserialize the EtherType or Length field
+ if(nextField >= ETHERTYPE_MIN) {
+ builder.setEthertype(KnownEtherType.forValue(nextField));
+ } else if(nextField <= LENGTH_MAX) {
+ builder.setEthernetLength(nextField);
+ } else {
+ _logger.debug("Undefined header, value is not valid EtherType or length. Value is " + nextField);
+ }
+
+ // Deserialize the payload now
+ int payloadStart = 96 + 16 + extraHeaderBits;
+ int payloadSize = data.length * NetUtils.NumBitsInAByte - payloadStart;
+ int start = payloadStart / NetUtils.NumBitsInAByte;
+ int stop = start + payloadSize / NetUtils.NumBitsInAByte;
+ builder.setEthernetPayload(Arrays.copyOfRange(data, start, stop));
+
+ if(null != builder.getEthertype()) {
+ builder.setPacketPayloadType(new PacketPayloadTypeBuilder()
+ .setPacketType(PacketType.Ethernet)
+ .setPayloadType(builder.getEthertype().getIntValue())
+ .build());
+ }
+
+ } catch(BufferException be) {
+ _logger.info("Exception during decoding raw packet to ethernet.");
+ }
+
+*/
+ //ToDo: Possibly log these values
+ /*if (_logger.isTraceEnabled()) {
+ _logger.trace("{}: {}: {} (offset {} bitsize {})",
+ new Object[] { this.getClass().getSimpleName(), hdrField,
+ HexEncode.bytesToHexString(hdrFieldBytes),
+ startOffset, numBits });
+ }*/
+ return builder.build();
+ }
+
+
+ @Override
+ public NotificationListener getConsumedNotificationListener() {
+ return this;
+ }
+}
--- /dev/null
+package org.opendaylight.l2switch.packethandler.decoders;
+
+import com.google.common.collect.ImmutableSet;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.EthernetPacketListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.EthernetPacketOverRawReceived;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ipv4.rev140528.Ipv4PacketOverEthernetReceived;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ipv4.rev140528.Ipv4PacketOverEthernetReceivedBuilder;
+import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * IPv4 Packet Decoder
+ */
+public class Ipv4Decoder extends AbstractPacketDecoder<EthernetPacketOverRawReceived, Ipv4PacketOverEthernetReceived>
+ implements EthernetPacketListener {
+
+ private static final Logger _logger = LoggerFactory.getLogger(Ipv4Decoder.class);
+
+ public Ipv4Decoder(NotificationProviderService notificationProviderService) {
+ super(Ipv4PacketOverEthernetReceived.class, notificationProviderService);
+ }
+
+ /**
+ * Decode an EthernetPacket into an Ipv4Packet
+ */
+ @Override
+ public Ipv4PacketOverEthernetReceived decode(EthernetPacketOverRawReceived ethernetPacketOverRawReceived) {
+
+ Ipv4PacketOverEthernetReceivedBuilder builder = new Ipv4PacketOverEthernetReceivedBuilder();
+ byte[] data = ethernetPacketOverRawReceived.getPayload();
+ int offset = ethernetPacketOverRawReceived.getEthernetPacket().getPayloadOffset();
+ //TODO: PLease note that the payload is original payload and to decode ethernet payload use payload offset from ethernet
+ /*
+ EthernetPacketGrp ethernetPacket = (EthernetPacketGrp) packet;
+ builder.fieldsFrom(ethernetPacket);
+ try {
+ builder.setVersion(BitBufferHelper.getShort(BitBufferHelper.getBits(data, 0, 4)));
+ if (builder.getVersion().intValue() != 4) {
+ _logger.debug("Version should be 4, but is " + builder.getVersion());
+ }
+
+ builder.setIhl(BitBufferHelper.getShort(BitBufferHelper.getBits(data, 4, 4)));
+ builder.setDscp(BitBufferHelper.getShort(BitBufferHelper.getBits(data, 8, 6)));
+ builder.setEcn(BitBufferHelper.getShort(BitBufferHelper.getBits(data, 14, 2)));
+ builder.setIpv4Length(BitBufferHelper.getInt(BitBufferHelper.getBits(data, 16, 16)));
+ builder.setId(BitBufferHelper.getInt(BitBufferHelper.getBits(data, 32, 16)));
+
+ // Decode the flags -- Reserved, DF (Don't Fragment), MF (More Fragments)
+ builder.setReservedFlag(1 == (BitBufferHelper.getBits(data, 48, 1)[0] & 0xff));
+ if (builder.isReservedFlag()) {
+ _logger.debug("Reserved flag should be 0, but is 1.");
+ }
+ // "& 0xff" removes the sign of the Java byte
+ builder.setDfFlag(1 == (BitBufferHelper.getBits(data, 49, 1)[0] & 0xff));
+ builder.setMfFlag(1 == (BitBufferHelper.getBits(data, 50, 1)[0] & 0xff));
+
+ builder.setFragmentOffset(BitBufferHelper.getInt(BitBufferHelper.getBits(data, 51, 13)));
+ builder.setTtl(BitBufferHelper.getShort(BitBufferHelper.getBits(data, 64, 8)));
+ builder.setProtocol(KnownIpProtocols.forValue(BitBufferHelper.getShort(BitBufferHelper.getBits(data, 72, 8))));
+ builder.setChecksum(BitBufferHelper.getInt(BitBufferHelper.getBits(data, 80, 16)));
+ builder.setSourceIpv4(InetAddress.getByAddress(BitBufferHelper.getBits(data, 96, 32)).getHostAddress());
+ builder.setDestinationIpv4(InetAddress.getByAddress(BitBufferHelper.getBits(data, 128, 32)).getHostAddress());
+
+ // Decode the optional "options" parameter
+ int optionsSize = (builder.getIhl()-5)*32;
+ if (optionsSize > 0) {
+ builder.setIpv4Options(BitBufferHelper.getBits(data, 160, optionsSize));
+ }
+
+ // Decode the IPv4 Payload
+ int payloadStartInBits = 160+optionsSize;
+ int payloadEndInBits = data.length*NetUtils.NumBitsInAByte - payloadStartInBits;
+ int start = payloadStartInBits/NetUtils.NumBitsInAByte;
+ int end = start + payloadEndInBits/NetUtils.NumBitsInAByte;
+ builder.setIpv4Payload(Arrays.copyOfRange(data, start, end));
+
+ // Set packet payload type
+ if (builder.getProtocol() != null) {
+ builder.setPacketPayloadType(new PacketPayloadTypeBuilder()
+ .setPacketType(PacketType.Ipv4)
+ .setPayloadType(builder.getProtocol().getIntValue())
+ .build());
+ }
+ }
+ catch (BufferException | UnknownHostException e) {
+ _logger.debug("Exception while decoding IPv4 packet", e.getMessage());
+ }
+ */
+ return builder.build();
+ }
+
+
+ @Override
+ public NotificationListener getConsumedNotificationListener() {
+ return this;
+ }
+
+ @Override
+ public void onEthernetPacketOverRawReceived(EthernetPacketOverRawReceived notification) {
+ decodeAndPublish(notification);
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.l2switch.packethandler.decoders;
-
-
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.Packet;
-import org.opendaylight.yangtools.yang.binding.Notification;
-
-/**
- * PacketDecoder should be implemented by all the decoders that are going to decode any Packet.
- * E.g. LLDPDecoder, ARPDecoder etc.
- */
-public interface PacketDecoder {
-
- /**
- * Decodes the payload in given Packet further and returns a extension of Packet.
- * e.g. ARP, IPV4, LLDP etc.
- *
- * @param packet
- * @return
- */
- public Packet decode(Packet packet);
-
- /**
- * This is utility method for converting the decoded packet to its corresponding notification.
- *
- * @param decodedPacket
- * @return
- */
- public Notification buildPacketNotification(Packet decodedPacket);
-}
+++ /dev/null
-package org.opendaylight.l2switch.packethandler.decoders;
-
-import org.opendaylight.controller.sal.binding.api.BindingAwareService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.packet.PacketPayloadType;
-import org.opendaylight.yangtools.yang.binding.Notification;
-
-/**
- * Created by amitmandke on 6/4/14.
- */
-public interface PacketDecoderService extends BindingAwareService {
- public <C extends Notification> void registerDecoder(PacketPayloadType packetPayloadType, PacketDecoder packetDecoder, Class<C> packetReceivedNotificationType);
-}
+++ /dev/null
-package org.opendaylight.l2switch.packethandler.decoders;
-
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.packet.PacketPayloadType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packetdecoder.config.impl.rev140528.PacketDecoderImplRuntimeMXBean;
-import org.opendaylight.yangtools.yang.binding.Notification;
-
-/**
- * Created by amitmandke on 6/5/14.
- */
-public class PacketDecoderServiceImpl implements PacketDecoderService, PacketDecoderImplRuntimeMXBean {
- private DecoderRegistry decoderRegistry;
- private PacketNotificationRegistry packetNotificationRegistry;
-
- public PacketDecoderServiceImpl(DecoderRegistry decoderRegistry, PacketNotificationRegistry packetNotificationRegistry) {
- this.decoderRegistry = decoderRegistry;
- this.packetNotificationRegistry = packetNotificationRegistry;
- }
-
- @Override
- public <C extends Notification> void registerDecoder(PacketPayloadType packetPayloadType, PacketDecoder packetDecoder, Class<C> packetReceivedNotificationType) {
- decoderRegistry.addDecoder(packetPayloadType, packetDecoder);
- packetNotificationRegistry.trackPacketNotificationListener(packetPayloadType, packetReceivedNotificationType);
- }
-}
+++ /dev/null
-package org.opendaylight.l2switch.packethandler.decoders;
-
-import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.packet.PacketPayloadType;
-import org.opendaylight.yangtools.yang.binding.Notification;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * PacketNotificationRegistry maintains mapping of NotificationType to PacketPayloadType. It also maintains
- * the count of Listener that are subscribed to a particular notification. This way it can specify if there
- * is any active listener subscription for any particular EtherType notification.
- */
-public class PacketNotificationRegistry implements NotificationProviderService.NotificationInterestListener {
- private Map<PacketPayloadType, Class<? extends Notification>> packetPayloadTypeToPacketNotificationTypeMap = new HashMap<PacketPayloadType, Class<? extends Notification>>();
-
- private Map<Class<? extends Notification>, Integer> packetNotificationTypeToListenerCountMap = new HashMap<Class<? extends Notification>, Integer>();
-
- /**
- * Increments the listener count for given notification type.
- *
- * @param aClass
- */
- @Override
- public void onNotificationSubscribtion(Class<? extends Notification> aClass) {
- if(aClass == null) return;
-
- synchronized(this) {
- Integer listenerCount = packetNotificationTypeToListenerCountMap.get(aClass);
- if(listenerCount == null)
- listenerCount = 0;
- packetNotificationTypeToListenerCountMap.put(aClass, ++listenerCount);
- }
- }
-
- /**
- * Maintains map of EtherType to notificationType
- *
- * @param notificationType
- * @param <N>
- */
- public <N extends Notification> void trackPacketNotificationListener(PacketPayloadType packetPayloadType, Class<N> notificationType) {
- if(packetPayloadType == null || notificationType == null) return;
-
- synchronized(this) {
- packetPayloadTypeToPacketNotificationTypeMap.put(packetPayloadType, notificationType);
- }
-
- }
-
- /**
- * Checks if a listener is subscribed to notification that is associated with given EtherType.
- *
- * @param packetPayloadType
- * @return
- */
- public boolean isListenerSubscribed(PacketPayloadType packetPayloadType) {
- if(packetPayloadType == null) return false;
-
- Class<?> packetNotification = packetPayloadTypeToPacketNotificationTypeMap.get(packetPayloadType);
- if(packetNotification == null) return false;
-
- return isListenerSubscribed((Class<? extends Notification>) packetNotification);
- }
-
- /**
- * Checks if a listener is subscribed to give the notification type .
- *
- * @param packetNotificationType
- * @return
- */
- public boolean isListenerSubscribed(Class<? extends Notification> packetNotificationType) {
- if(packetNotificationType == null) return false;
-
- Integer listenerCount = packetNotificationTypeToListenerCountMap.get(packetNotificationType);
-
- if(listenerCount == null) return false;
-
- return listenerCount > 0;
- }
-}
+++ /dev/null
-package org.opendaylight.yang.gen.v1.urn.opendaylight.packetdecoder.config.impl.rev140528;
-
-import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.l2switch.packethandler.RawPacketHandler;
-import org.opendaylight.l2switch.packethandler.decoders.DecoderRegistry;
-import org.opendaylight.l2switch.packethandler.decoders.PacketDecoderServiceImpl;
-import org.opendaylight.l2switch.packethandler.decoders.PacketNotificationRegistry;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class PacketDecoderImplModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.packetdecoder.config.impl.rev140528.AbstractPacketDecoderImplModule {
- private static final Logger _logger = LoggerFactory.getLogger(PacketDecoderImplModule.class);
-
- public PacketDecoderImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
- super(identifier, dependencyResolver);
- }
-
- public PacketDecoderImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.urn.opendaylight.packetdecoder.config.impl.rev140528.PacketDecoderImplModule oldModule, java.lang.AutoCloseable oldInstance) {
- super(identifier, dependencyResolver, oldModule, oldInstance);
- }
-
- @Override
- public void customValidation() {
- // add custom validation form module attributes here.
- }
-
- @Override
- public java.lang.AutoCloseable createInstance() {
- NotificationProviderService notificationProviderService = getNotificationServiceDependency();
- DecoderRegistry decoderRegistry = new DecoderRegistry();
-
- PacketNotificationRegistry packetNotificationRegistry = new PacketNotificationRegistry();
- notificationProviderService.registerInterestListener(packetNotificationRegistry);
-
-
- RawPacketHandler rawPacketHandler = new RawPacketHandler();
- rawPacketHandler.setNotificationProviderService(notificationProviderService);
- rawPacketHandler.setDecoderRegistry(decoderRegistry);
- rawPacketHandler.setPacketNotificationRegistry(packetNotificationRegistry);
- notificationProviderService.registerNotificationListener(rawPacketHandler);
- _logger.info("About to return packet decoder instance.");
- PacketDecoderServiceImpl packetDecoderService = new PacketDecoderServiceImpl(decoderRegistry, packetNotificationRegistry);
-
- final PacketDecoderImplRuntimeRegistration runtimeRegistration = getRootRuntimeBeanRegistratorWrapper().register(packetDecoderService);
- AutoCloseable autoCloseable = new AutoCloseable() {
- @Override
- public void close() throws Exception {
- runtimeRegistration.close();
- }
- };
- return autoCloseable;
-
- }
-
-}
+++ /dev/null
-/*
-* Generated file
-*
-* Generated from: yang module name: packet-decoder-impl-config yang module local name: packet-deocoder-impl
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Wed Jun 18 15:46:00 PDT 2014
-*
-* Do not modify this file unless it is present under src/main directory
-*/
-package org.opendaylight.yang.gen.v1.urn.opendaylight.packetdecoder.config.impl.rev140528;
-public class PacketDecoderImplModuleFactory extends org.opendaylight.yang.gen.v1.urn.opendaylight.packetdecoder.config.impl.rev140528.AbstractPacketDecoderImplModuleFactory {
-
-}
+++ /dev/null
-module packet-decoder-config {
- yang-version 1;
- namespace "urn:opendaylight:packetdecoder:config";
- prefix pconfig;
-
- import config { prefix config; revision-date 2013-04-05; }
-
- description
- "Service definition for packet decoder service";
-
- revision "2014-05-28" {
- description
- "Initial revision";
- }
-
- // Service definition for packet decoder service
- identity packet-decoder-service {
- description
- "packet decoder service definition";
-
- base "config:service-type";
- config:java-class "org.opendaylight.l2switch.packethandler.decoders.PacketDecoderService";
- }
-}
+++ /dev/null
-module packet-decoder-impl-config {
-
- yang-version 1;
- namespace "urn:opendaylight:packetdecoder:config:impl";
- prefix "pconfig-impl";
-
- // Dependency on service definition for config-demo
- /* Service definitions could be also located in this yang file or even
- * in a separate maven project that is marked as maven dependency
- */
- import packet-decoder-config { prefix pconfig; revision-date 2014-05-28;}
-
- // Dependencies on config subsystem definition
- import config { prefix config; revision-date 2013-04-05; }
- import rpc-context { prefix rpcx; revision-date 2013-06-17; }
- import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; }
-
-
- description
- "Service implementation for packet decoder";
-
- revision "2014-05-28" {
- description
- "Initial revision";
- }
- // identity for implementing module
- identity packet-decoder-impl {
- base config:module-type;
- config:provided-service pconfig:packet-decoder-service;
- config:java-name-prefix PacketDecoderImpl;
- }
-
- // Configuration for module
- augment "/config:modules/config:module/config:configuration" {
- case packet-decoder-impl {
- when "/config:modules/config:module/config:type = 'packet-decoder-impl'";
-
-
- // Dependency on bar service instance
- container notification-service {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity mdsal:binding-notification-service;
- }
- }
- }
- }
- }
-
- // Runtime state definition for module
- augment "/config:modules/config:module/config:state" {
- case packet-decoder-impl {
- when "/config:modules/config:module/config:type = 'packet-decoder-impl'";
- }
- }
-}
\ No newline at end of file
--- /dev/null
+package org.opendaylight.l2switch.packethandler.decoders;
+
+public class ArpDecoderTest {
+ /* ArpDecoder arpDecoder = new ArpDecoder();
+
+ @Test
+ public void testDecode_RequestIPv4() throws Exception {
+ byte[] payload = {
+ 0x00, 0x01, // Hardware Type -- Ethernet
+ 0x08, 0x00, // Protocol Type -- Ipv4
+ 0x06, // Hardware Length -- 6
+ 0x04, // Protcool Length -- 4
+ 0x00, 0x01, // Operator -- Request
+ 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xab, // Src Hardware Address
+ (byte)0xc0, (byte)0xa8, 0x00, 0x01, // Src Protocol Address
+ (byte) 0xcd, (byte) 0xef, 0x01, 0x23, 0x45, 0x67, // Dest Hardware Address
+ 0x01, 0x02, 0x03, 0x04 // Dest Protocol Address
+ };
+ ArpPacket arp = (ArpPacket)arpDecoder.decode(new EthernetPacketBuilder().setEthernetPayload(payload).build());
+ assertEquals(KnownHardwareType.Ethernet, arp.getHardwareType());
+ assertEquals(KnownEtherType.Ipv4, arp.getProtocolType());
+ assertEquals(6, arp.getHardwareLength().intValue());
+ assertEquals(4, arp.getProtocolLength().intValue());
+ assertEquals(KnownOperation.Request, arp.getOperation());
+ assertEquals("01:23:45:67:89:ab", arp.getSourceHardwareAddress());
+ assertEquals("192.168.0.1", arp.getSourceProtocolAddress());
+ assertEquals("cd:ef:01:23:45:67", arp.getDestinationHardwareAddress());
+ assertEquals("1.2.3.4", arp.getDestinationProtocolAddress());
+ }
+
+ @Test
+ public void testDecode_ReplyIPv4() throws Exception {
+ byte[] payload = {
+ 0x00, 0x01, // Hardware Type -- Ethernet
+ 0x08, 0x00, // Protocol Type -- Ipv4
+ 0x06, // Hardware Length -- 6
+ 0x04, // Protcool Length -- 4
+ 0x00, 0x02, // Operator -- Reply
+ 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xab, // Src Hardware Address
+ (byte)0xc0, (byte)0xa8, 0x00, 0x01, // Src Protocol Address
+ (byte) 0xcd, (byte) 0xef, 0x01, 0x23, 0x45, 0x67, // Dest Hardware Address
+ 0x01, 0x02, 0x03, 0x04 // Dest Protocol Address
+ };
+ ArpPacket arp = (ArpPacket)arpDecoder.decode(new EthernetPacketBuilder().setEthernetPayload(payload).build());
+ assertEquals(KnownHardwareType.Ethernet, arp.getHardwareType());
+ assertEquals(KnownEtherType.Ipv4, arp.getProtocolType());
+ assertEquals(6, arp.getHardwareLength().intValue());
+ assertEquals(4, arp.getProtocolLength().intValue());
+ assertEquals(KnownOperation.Reply, arp.getOperation());
+ assertEquals("01:23:45:67:89:ab", arp.getSourceHardwareAddress());
+ assertEquals("192.168.0.1", arp.getSourceProtocolAddress());
+ assertEquals("cd:ef:01:23:45:67", arp.getDestinationHardwareAddress());
+ assertEquals("1.2.3.4", arp.getDestinationProtocolAddress());
+ }
+ */
+}
+++ /dev/null
-package org.opendaylight.l2switch.packethandler.decoders;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.PacketType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.packet.PacketPayloadType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.packet.PacketPayloadTypeBuilder;
-
-import static junit.framework.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
-
-
-/**
- * Created by amitmandke on 6/5/14.
- */
-public class DecoderRegistryTest {
- private DecoderRegistry decoderRegistry = null;
- private PacketDecoder packetDecoder;
- private PacketPayloadType packetPayloadType;
-
- @Before
- public void init() {
- decoderRegistry = new DecoderRegistry();
- packetDecoder = mock(PacketDecoder.class);
- packetPayloadType = new PacketPayloadTypeBuilder().setPacketType(PacketType.Raw).setPayloadType(1).build();
- }
-
- @Test
- public void testAddDecoderSunnyDay() {
- decoderRegistry.addDecoder(packetPayloadType, packetDecoder);
- assertEquals(packetDecoder, decoderRegistry.getDecoder(packetPayloadType));
- }
-
- public void testGetDecoderWithoutAdding() {
- PacketDecoder decoder = decoderRegistry.getDecoder(packetPayloadType);
- assertEquals(null, decoder);
- }
-}
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.l2switch.packethandler.decoders;
+
+public class EthernetDecoderTest {
+
+ /* @Test
+ public void testDecode_IPv4EtherType() throws Exception {
+ byte[] packet = {
+ 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xab,
+ (byte) 0xcd, (byte) 0xef, 0x01, 0x23, 0x45, 0x67,
+ 0x08, 0x00,
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11
+ };
+ EthernetPacketGrp e = (EthernetPacketGrp) new EthernetDecoder().decode(getBasePacket(new RawPacketBuilder().setPayload(packet).build()));
+ assertEquals(e.getEthertype(), KnownEtherType.Ipv4);
+ assertNull(e.getEthernetLength());
+ assertNull(e.getHeader8021q());
+ assertEquals(e.getDestinationMac().getValue(), "01:23:45:67:89:ab");
+ assertEquals(e.getSourceMac().getValue(), "cd:ef:01:23:45:67");
+ assertTrue(Arrays.equals(e.getEthernetPayload(), Arrays.copyOfRange(packet, 14, packet.length)));
+ }
+
+ @Test
+ public void testDecode_Length() throws Exception {
+ byte[] packet = {
+ 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xab,
+ (byte) 0xcd, (byte) 0xef, 0x01, 0x23, 0x45, 0x67,
+ 0x00, 0x0e,
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11
+ };
+ EthernetPacketGrp e = (EthernetPacketGrp) new EthernetDecoder().decode(getBasePacket(new RawPacketBuilder().setPayload(packet).build()));
+ assertNull(e.getEthertype());
+ assertEquals(e.getEthernetLength().intValue(), 14);
+ assertNull(e.getHeader8021q());
+ assertEquals(e.getDestinationMac().getValue(), "01:23:45:67:89:ab");
+ assertEquals(e.getSourceMac().getValue(), "cd:ef:01:23:45:67");
+ assertTrue(Arrays.equals(e.getEthernetPayload(), Arrays.copyOfRange(packet, 14, packet.length)));
+ }
+
+ @Test
+ public void testDecode_IPv6EtherTypeWith8021qHeader() throws Exception {
+ byte[] packet = {
+ 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xab,
+ (byte) 0xcd, (byte) 0xef, 0x01, 0x23, 0x45, 0x67,
+ (byte) 0x81, 0x00,
+ (byte) 0xff, (byte) 0xff,
+ (byte) 0x86, (byte) 0xdd,
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11
+ };
+ EthernetPacketGrp e = (EthernetPacketGrp) new EthernetDecoder().decode(getBasePacket(new RawPacketBuilder().setPayload(packet).build()));
+ assertEquals(e.getEthertype(), KnownEtherType.Ipv6);
+ assertNull(e.getEthernetLength());
+ assertEquals(e.getHeader8021q().size(), 1);
+ assertEquals(e.getHeader8021q().get(0).getType(), Header8021qType.VlanTagged);
+ assertEquals(e.getHeader8021q().get(0).getPriorityCode().intValue(), 7);
+ assertTrue(e.getHeader8021q().get(0).isDropEligible());
+ assertEquals(e.getHeader8021q().get(0).getVlan().intValue(), 4095);
+ assertEquals(e.getDestinationMac().getValue(), "01:23:45:67:89:ab");
+ assertEquals(e.getSourceMac().getValue(), "cd:ef:01:23:45:67");
+ assertTrue(Arrays.equals(e.getEthernetPayload(), Arrays.copyOfRange(packet, 18, packet.length)));
+ }
+
+ @Test
+ public void testDecode_IPv6EtherTypeWithQinQ() throws Exception {
+ byte[] packet = {
+ 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xab,
+ (byte) 0xcd, (byte) 0xef, 0x01, 0x23, 0x45, 0x67,
+ (byte) 0x91, 0x00,
+ (byte) 0xff, (byte) 0xff,
+ (byte) 0x81, 0x00,
+ (byte) 0xa0, (byte) 0x0a,
+ (byte) 0x86, (byte) 0xdd,
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11
+ };
+ EthernetPacketGrp e = (EthernetPacketGrp) new EthernetDecoder().decode(getBasePacket(new RawPacketBuilder().setPayload(packet).build()));
+ assertEquals(e.getEthertype(), KnownEtherType.Ipv6);
+ assertNull(e.getEthernetLength());
+ assertEquals(e.getHeader8021q().size(), 2);
+ assertEquals(e.getHeader8021q().get(0).getType(), Header8021qType.QInQ);
+ assertEquals(e.getHeader8021q().get(0).getPriorityCode().intValue(), 7);
+ assertTrue(e.getHeader8021q().get(0).isDropEligible());
+ assertEquals(e.getHeader8021q().get(0).getVlan().intValue(), 4095);
+ assertEquals(e.getHeader8021q().get(1).getType(), Header8021qType.VlanTagged);
+ assertEquals(e.getHeader8021q().get(1).getPriorityCode().intValue(), 5);
+ assertFalse(e.getHeader8021q().get(1).isDropEligible());
+ assertEquals(e.getHeader8021q().get(1).getVlan().intValue(), 10);
+ assertEquals(e.getDestinationMac().getValue(), "01:23:45:67:89:ab");
+ assertEquals(e.getSourceMac().getValue(), "cd:ef:01:23:45:67");
+ assertTrue(Arrays.equals(e.getEthernetPayload(), Arrays.copyOfRange(packet, 22, packet.length)));
+ }
+
+ private BasePacket getBasePacket(RawPacket rawPacket) {
+
+ return new BasePacketBuilder()
+ .setPacketPayloadType(getRawEthernetPacketPayloadType())
+ .setRawPacket(rawPacket).build();
+ }
+
+ private PacketPayloadType getRawEthernetPacketPayloadType() {
+
+ //currently doesn't make use of packet received as currently only ethernet packets are received so following is hard coded.
+ return new PacketPayloadTypeBuilder().setPacketType(PacketType.Raw).setPayloadType(PacketType.Ethernet.getIntValue()).build();
+ }*/
+
+}
--- /dev/null
+package org.opendaylight.l2switch.packethandler.decoders;
+
+public class Ipv4DecoderTest {
+ /*Ipv4Decoder ipv4Decoder = new Ipv4Decoder();
+
+ @Test
+ public void testDecode() throws Exception {
+ byte[] payload = {
+ 0x45, // Version = 4, IHL = 5
+ 0x00, // DSCP =0, ECN = 0
+ 0x00, 0x1E, // Total Length -- 30
+ 0x01, 0x1E, // Identification -- 286
+ 0x00, 0x00, // Flags = all off & Fragment offset = 0
+ 0x12, 0x11, // TTL = 18, Protocol = UDP
+ 0x00, 0x00, // Checksum = 0
+ (byte)0xc0, (byte)0xa8, 0x00, 0x01, // Src IP Address
+ 0x01, 0x02, 0x03, 0x04, // Dest IP Address
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10 // Data
+ };
+ Ipv4Packet ipv4packet = (Ipv4Packet)ipv4Decoder.decode(new EthernetPacketBuilder().setEthernetPayload(payload).build());
+ assertEquals(4, ipv4packet.getVersion().intValue());
+ assertEquals(5, ipv4packet.getIhl().intValue());
+ assertEquals(30, ipv4packet.getIpv4Length().intValue());
+ assertEquals(0, ipv4packet.getDscp().intValue());
+ assertEquals(0, ipv4packet.getEcn().intValue());
+ assertEquals(30, ipv4packet.getIpv4Length().intValue());
+ assertEquals(286, ipv4packet.getId().intValue());
+ assertFalse(ipv4packet.isReservedFlag());
+ assertFalse(ipv4packet.isDfFlag());
+ assertFalse(ipv4packet.isMfFlag());
+ assertEquals(0, ipv4packet.getFragmentOffset().intValue());
+ assertEquals(18, ipv4packet.getTtl().intValue());
+ assertEquals(KnownIpProtocols.Udp, ipv4packet.getProtocol());
+ assertEquals(0, ipv4packet.getChecksum().intValue());
+ assertEquals("192.168.0.1", ipv4packet.getSourceIpv4());
+ assertEquals("1.2.3.4", ipv4packet.getDestinationIpv4());
+ assertTrue(Arrays.equals(ipv4packet.getIpv4Payload(), Arrays.copyOfRange(payload, 20, payload.length)));
+ }
+
+ @Test
+ public void testDecode_WithDiffServAndFlagsAndOffset() throws Exception {
+ byte[] payload = {
+ 0x45, // Version = 4, IHL = 5
+ (byte)0xff, // DSCP =63, ECN = 3
+ 0x00, 0x1E, // Total Length -- 30
+ 0x01, 0x1E, // Identification -- 286
+ (byte)0xf0, 0x00, // Flags = all on & Fragment offset = 0
+ 0x12, 0x06, // TTL = 18, Protocol = TCP
+ (byte)0x00, 0x00, // Checksum = 0
+ (byte)0xc0, (byte)0xa8, 0x00, 0x01, // Src IP Address
+ 0x01, 0x02, 0x03, 0x04, // Dest IP Address
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10 // Data
+ };
+ Ipv4Packet ipv4packet = (Ipv4Packet)ipv4Decoder.decode(new EthernetPacketBuilder().setEthernetPayload(payload).build());
+ assertEquals(4, ipv4packet.getVersion().intValue());
+ assertEquals(5, ipv4packet.getIhl().intValue());
+ assertEquals(30, ipv4packet.getIpv4Length().intValue());
+ assertEquals(63, ipv4packet.getDscp().intValue());
+ assertEquals(3, ipv4packet.getEcn().intValue());
+ assertEquals(30, ipv4packet.getIpv4Length().intValue());
+ assertEquals(286, ipv4packet.getId().intValue());
+ assertTrue(ipv4packet.isReservedFlag());
+ assertTrue(ipv4packet.isDfFlag());
+ assertTrue(ipv4packet.isMfFlag());
+ assertEquals(4096, ipv4packet.getFragmentOffset().intValue());
+ assertEquals(18, ipv4packet.getTtl().intValue());
+ assertEquals(KnownIpProtocols.Tcp, ipv4packet.getProtocol());
+ assertEquals(0, ipv4packet.getChecksum().intValue());
+ assertEquals("192.168.0.1", ipv4packet.getSourceIpv4());
+ assertEquals("1.2.3.4", ipv4packet.getDestinationIpv4());
+ assertTrue(Arrays.equals(ipv4packet.getIpv4Payload(), Arrays.copyOfRange(payload, 20, payload.length)));
+ }
+
+ @Test
+ public void testDecode_AlternatingBits() throws Exception {
+ byte[] payload = {
+ (byte)0xf5, // Version = 15, IHL = 5
+ (byte)0x0f, // DSCP =3, ECN = 3
+ 0x00, 0x00, // Total Length -- 30
+ (byte)0xff, (byte)0xff, // Identification -- 65535
+ (byte)0x1f, (byte)0xff, // Flags = all off & Fragment offset = 8191
+ 0x00, 0x06, // TTL = 00, Protocol = TCP
+ (byte)0xff, (byte)0xff, // Checksum = 65535
+ (byte)0x00, (byte)0x00, 0x00, 0x00, // Src IP Address
+ (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, // Dest IP Address
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10 // Data
+ };
+ Ipv4Packet ipv4packet = (Ipv4Packet)ipv4Decoder.decode(new EthernetPacketBuilder().setEthernetPayload(payload).build());
+ assertEquals(15, ipv4packet.getVersion().intValue());
+ assertEquals(5, ipv4packet.getIhl().intValue());
+ assertEquals(0, ipv4packet.getIpv4Length().intValue());
+ assertEquals(3, ipv4packet.getDscp().intValue());
+ assertEquals(3, ipv4packet.getEcn().intValue());
+ assertEquals(0, ipv4packet.getIpv4Length().intValue());
+ assertEquals(65535, ipv4packet.getId().intValue());
+ assertFalse(ipv4packet.isReservedFlag());
+ assertFalse(ipv4packet.isDfFlag());
+ assertFalse(ipv4packet.isMfFlag());
+ assertEquals(8191, ipv4packet.getFragmentOffset().intValue());
+ assertEquals(0, ipv4packet.getTtl().intValue());
+ assertEquals(KnownIpProtocols.Tcp, ipv4packet.getProtocol());
+ assertEquals(65535, ipv4packet.getChecksum().intValue());
+ assertEquals("0.0.0.0", ipv4packet.getSourceIpv4());
+ assertEquals("255.255.255.255", ipv4packet.getDestinationIpv4());
+ assertTrue(Arrays.equals(ipv4packet.getIpv4Payload(), Arrays.copyOfRange(payload, 20, payload.length)));
+ }
+ */
+}
+++ /dev/null
-package org.opendaylight.l2switch.packethandler.decoders;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.PacketType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.packet.PacketPayloadType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.packet.PacketPayloadTypeBuilder;
-import org.opendaylight.yangtools.yang.binding.Notification;
-
-import static junit.framework.Assert.assertEquals;
-
-
-/**
- * Created by amitmandke on 6/5/14.
- */
-public class PacketNotificationRegistryTest {
- PacketNotificationRegistry packetNotificationRegistry = null;
- private PacketPayloadType packetPayloadType;
-
- @Before
- public void init() {
- packetNotificationRegistry = new PacketNotificationRegistry();
- packetPayloadType = new PacketPayloadTypeBuilder().setPacketType(PacketType.Raw).setPayloadType(1).build();
- }
-
- @Test
- public void testIsListenerSubscribedByNotificationTypeWithoutAddingAnyListener() {
- assertEquals(false, packetNotificationRegistry.isListenerSubscribed(Notification.class));
- }
-
- @Test
- public void testIsListenerSubscribedByEtherTypeWithoutAddingAnyListener() {
- assertEquals(false, packetNotificationRegistry.isListenerSubscribed(packetPayloadType));
- }
-
- @Test
- public void testIsListenerSubscribedByNotificationTypeSunnyDay() {
- addNotification();
- assertEquals(true, packetNotificationRegistry.isListenerSubscribed(Notification.class));
- }
-
- @Test
- public void testIsListenerSubscribedByEtherTypeWithoutAddingEtherType() {
- addNotification();
- assertEquals(false, packetNotificationRegistry.isListenerSubscribed(packetPayloadType));
- }
-
- @Test
- public void testIsListenerSubscribedByEtherTypeSunnyDay() {
- addNotification();
- addEtherTypeNotification();
- assertEquals(true, packetNotificationRegistry.isListenerSubscribed(packetPayloadType));
- }
-
- private void addNotification() {
- packetNotificationRegistry.onNotificationSubscribtion(Notification.class);
-
- }
-
- private void addEtherTypeNotification() {
- packetNotificationRegistry.trackPacketNotificationListener(packetPayloadType, Notification.class);
- }
-}
--- /dev/null
+module arp-packet {
+ yang-version 1;
+ namespace "urn:opendaylight:packet:arp";
+ prefix arp;
+
+ import ietf-inet-types {
+ prefix inet;
+ revision-date 2010-09-24;
+ }
+ import base-packet {
+ prefix bpacket;
+ revision-date 2014-05-28;
+ }
+ import ethernet-packet {
+ prefix ethernet;
+ revision-date 2014-05-28;
+ }
+
+ revision 2014-05-28 {
+ description
+ "ARP packet module draft.";
+ }
+
+ typedef known-hardware-type {
+ type enumeration {
+ enum "reserved" {
+ value 0;
+ }
+ enum "ethernet" {
+ value 1;
+ }
+ }
+ }
+
+ typedef known-operation {
+ type enumeration {
+ enum "reserved" {
+ value 0;
+ }
+ enum "request" {
+ value 1;
+ }
+ enum "reply" {
+ value 2;
+ }
+ enum "request reverse" {
+ value 3;
+ }
+ enum "reply reverse" {
+ value 4;
+ }
+ }
+ }
+
+
+ grouping arp-packet-fields {
+ leaf hardware-type {
+ type known-hardware-type;
+ description "Network protocol type";
+ }
+
+ leaf protocol-type {
+ type ethernet:known-ether-type;
+ description "Higher layer protocol for which the ARP request is intended. This corresponds to EtherType.";
+ }
+
+ leaf hardware-length {
+ type uint8;
+ description "Length (in octets) of a hardware address. Ethernet address size is 6.";
+ }
+
+ leaf protocol-length {
+ type uint8;
+ description "Length (in octets) of addresses used in the higher layer protocol. IPv4 address size is 4.";
+ }
+
+ leaf operation {
+ type known-operation;
+ description "Specifies the operation that the sender is performing: 1 for request, 2 for reply.";
+ }
+
+ leaf source-hardware-address {
+ type string;
+ description "Media address of the sender.";
+ }
+
+ leaf source-protocol-address {
+ type string;
+ description "Internet address of the sender.";
+ }
+
+ leaf destination-hardware-address {
+ type string;
+ description "Media address of the destination/target.";
+ }
+
+ leaf destination-protocol-address {
+ type string;
+ description "Internet address of the destination/target.";
+ }
+
+ uses bpacket:packet-fields;
+ }
+
+ grouping arp-packet-over-ethernet-fields {
+ container arp-packet {
+ uses arp-packet-fields;
+ }
+ container ethernet-over-raw-packet {
+ uses ethernet:ethernet-packet-over-raw-fields;
+ }
+ }
+
+ notification arp-packet-over-ethernet-received {
+ uses bpacket:packet-payload;
+ uses arp-packet-over-ethernet-fields;
+ }
+}
\ No newline at end of file
--- /dev/null
+module ethernet-packet {
+ yang-version 1;
+ namespace "urn:opendaylight:packet:ethernet";
+ prefix ethernet;
+
+ import ietf-yang-types {
+ prefix yang;
+ revision-date 2010-09-24;
+ }
+ import packet-processing {
+ prefix pprocessing;
+ revision-date 2013-07-09;
+ }
+ import base-packet {
+ prefix bpacket;
+ revision-date 2014-05-28;
+ }
+
+ revision 2014-05-28 {
+ description
+ "Ethernet packet module draft.";
+ }
+
+ /* Taken from opendaylight-l2-types.yang, but it is commented out there -- will import once uncommented */
+ typedef known-ether-type {
+ type enumeration {
+ enum "ipv4" {
+ value 2048; // 0x0800
+ description "Internet Protocol version 4 (IPv4)";
+ }
+ enum "arp" {
+ value 2054; // 0x0806
+ description "Address Resolution Protocol (ARP)";
+ }
+ enum "wake-on-lan" {
+ value 2114; // 0x0842
+ description "Wake-on-LAN[3]";
+ }
+ enum "ietf-trill" {
+ value 8947; // 0x22F3
+ description "IETF TRILL Protocol";
+ }
+ enum "decnet-phase-iv" {
+ value 24579; // 0x6003
+ description "DECnet Phase IV";
+ }
+ enum "reverse-arp" {
+ value 32821; // 0x8035
+ description "Reverse Address Resolution Protocol";
+ }
+ enum "apple-talk" {
+ value 32923; // 0x809B
+ description "AppleTalk (Ethertalk)";
+ }
+ enum "apple-talk-arp" {
+ value 33011; // 0x80F3
+ description "AppleTalk Address Resolution Protocol (AARP)";
+ }
+ enum "vlan-tagged" {
+ value 33024; // 0x8100
+ description "VLAN-tagged frame (IEEE 802.1Q) & Shortest Path Bridging IEEE 802.1aq[4]";
+ }
+ enum "ipx" {
+ value 33079; // 0x8137
+ description "IPX";
+ }
+ enum "ipx2" {
+ value 33080; // 0x8138
+ description "IPX";
+ }
+ enum "qnx-qnet" {
+ value 33284; // 0x8204
+ description "QNX Qnet";
+ }
+ enum "ipv6" {
+ value 34525; // 0x86DD
+ description "Internet Protocol Version 6 (IPv6)";
+ }
+ enum "ethernet-flow-control" {
+ value 34824; // 0x8808
+ description "Ethernet flow control";
+ }
+ enum "slow-protocols" {
+ value 34825; // 0x8809
+ description "Slow Protocols (IEEE 802.3)";
+ }
+ enum "cobra-net" {
+ value 34841; // 0x8819
+ description "CobraNet";
+ }
+ enum "mpls-unicast" {
+ value 34887; // 0x8847
+ description "MPLS unicast";
+ }
+ enum "mpls-multicast" {
+ value 34888; // 0x8848
+ description "MPLS multicast";
+ }
+ enum "PPP-over-ethernet-discovery" {
+ value 34915; // 0x8863
+ description "PPPoE Discovery Stage";
+ }
+ enum "PPP-over-ethernet-session" {
+ value 34916; // 0x8864
+ description "PPPoE Session Stage";
+ }
+ enum "jumbo" {
+ value 34928; // 0x8870
+ description "Jumbo Frames[2]";
+ }
+ enum "homeplug" {
+ value 34939; // 0x887B
+ description "HomePlug 1.0 MME";
+ }
+ enum "eap-over-lan" {
+ value 34958; // 0x888E
+ description "EAP over LAN (IEEE 802.1X)";
+ }
+ enum "profinet" {
+ value 34962; // 0x8892
+ description "PROFINET Protocol";
+ }
+ enum "hyper-scsi" {
+ value 34970; // 0x889A
+ description "HyperSCSI (SCSI over Ethernet)";
+ }
+ enum "ata-over-ethernet" {
+ value 34978; // 0x88A2
+ description "ATA over Ethernet";
+ }
+ enum "ethercat" {
+ value 34980; // 0x88A4
+ description "EtherCAT Protocol";
+ }
+ enum "provider-bridging" {
+ value 34984; // 0x88A8
+ description "Provider Bridging (IEEE 802.1ad) & Shortest Path Bridging IEEE 802.1aq[5]";
+ }
+ enum "ethernet-powerlink" {
+ value 34987; // 0x88AB
+ description "Ethernet Powerlink[citation needed]";
+ }
+ enum "lldp" {
+ value 35020; // 0x88CC
+ description "Link Layer Discovery Protocol (LLDP)";
+ }
+ enum "sercos-3" {
+ value 35021; // 0x88CD
+ description "SERCOS III";
+ }
+ enum "homeplug-av-mme" {
+ value 35041; // 0x88E1
+ description "HomePlug AV MME[citation needed]";
+ }
+ enum "media-redudancy-protocol" {
+ value 35043; // 0x88E3
+ description "Media Redundancy Protocol (IEC62439-2)";
+ }
+ enum "mac-security" {
+ value 35045; // 0x88E5
+ description "MAC security (IEEE 802.1AE)";
+ }
+ enum "precision-time-protocol" {
+ value 35063; // 0x88F7
+ description "Precision Time Protocol (IEEE 1588)";
+ }
+ enum "connectivity-fault-management" {
+ value 35074; // 0x8902
+ description "IEEE 802.1ag Connectivity Fault Management (CFM) Protocol / ITU-T Recommendation Y.1731 (OAM)";
+ }
+ enum "fibre-channel-over-ethernet" {
+ value 35078; // 0x8906
+ description "Fibre Channel over Ethernet (FCoE)";
+ }
+ enum "fibre-channel-over-ethernet-initialization" {
+ value 35092; // 0x8914
+ description "FCoE Initialization Protocol";
+ }
+ enum "rmda-over-converged-ethernet" {
+ value 35093; // 0x8915
+ description "RDMA over Converged Ethernet (RoCE)";
+ }
+ enum "high-availability-seamless-redudancy" {
+ value 35119; // 0x892F
+ description "High-availability Seamless Redundancy (HSR)";
+ }
+ enum "ethernet-configuration-testing-protocol" {
+ value 36864; // 0x9000
+ description "Ethernet Configuration Testing Protocol[6]";
+ }
+ enum "q-in-q" {
+ value 37120; // 0x9100
+ description "Q-in-Q";
+ }
+ enum "veritas-low-latency" {
+ value 51966; // 0xCAFE
+ description "Veritas Low Latency Transport (LLT)[7] for Veritas Cluster Server";
+ }
+ }
+ }
+
+ typedef header8021q-type {
+ type enumeration {
+ enum "vlan-tagged" {
+ value 33024; // 0x8100
+ description "VLAN-tagged frame (IEEE 802.1Q) & Shortest Path Bridging IEEE 802.1aq[4]";
+ }
+ enum "q-in-q" {
+ value 37120; // 0x9100
+ description "Q-in-Q";
+ }
+ }
+ }
+
+ grouping header8021q {
+ leaf type {
+ type header8021q-type;
+ }
+
+ leaf priority-code {
+ type int16;
+ }
+
+ leaf drop-eligible {
+ type boolean;
+ }
+
+ leaf vlan {
+ type int32;
+ }
+ }
+
+ grouping ethernet-packet-fields {
+ leaf source-mac {
+ type yang:mac-address;
+ }
+
+ leaf destination-mac {
+ type yang:mac-address;
+ }
+
+ list header8021q {
+ uses header8021q;
+ }
+
+ leaf ethertype {
+ type known-ether-type;
+ }
+
+ leaf ethernet-length {
+ type int32;
+ }
+ uses bpacket:packet-fields;
+ }
+
+ grouping ethernet-packet-over-raw-fields {
+ container ethernet-packet {
+ uses ethernet-packet-fields;
+ }
+ container raw-packet {
+ uses bpacket:raw-packet-fields;
+ }
+ }
+
+ notification ethernet-packet-over-raw-received {
+ uses bpacket:packet-payload;
+ uses ethernet-packet-over-raw-fields;
+ }
+}
\ No newline at end of file
--- /dev/null
+module ipv4-packet {
+ yang-version 1;
+ namespace "urn:opendaylight:packet:ipv4";
+ prefix ipv4;
+
+ import base-packet {
+ prefix bpacket;
+ revision-date 2014-05-28;
+ }
+
+ import ethernet-packet {
+ prefix ethernet;
+ revision-date 2014-05-28;
+ }
+
+ revision 2014-05-28 {
+ description
+ "IPv4 packet module draft.";
+ }
+
+ typedef known-ip-protocols {
+ type enumeration {
+ enum "hopopt" {
+ value 0;
+ description "IPv6 Hop-by-Hop Option";
+ }
+ enum "icmp" {
+ value 1;
+ description "Internet Control Message Protocol";
+ }
+ enum "igmp" {
+ value 2;
+ description "Internet Group Management Protocol";
+ }
+ enum "ggp" {
+ value 3;
+ description "Gateway-to-Gateway Protocol";
+ }
+ enum "ip-in-ip" {
+ value 4;
+ description "IP-in-IP Encapsulation";
+ }
+ enum "st" {
+ value 5;
+ description "Internet Stream Protocol";
+ }
+ enum "tcp" {
+ value 6;
+ description "Transmisson Control Protocol";
+ }
+ enum "cbt" {
+ value 7;
+ description "Core-based trees";
+ }
+ enum "egp" {
+ value 8;
+ description "Exterior Gateway Protocol";
+ }
+ enum "igp" {
+ value 9;
+ description "Interior Gateway Protocol";
+ }
+ enum "nvp" {
+ value 11;
+ description "Network Voice Protocol";
+ }
+ enum "udp" {
+ value 17;
+ description "User Datagram Protocol";
+ }
+ enum "hmp" {
+ value 20;
+ description "Host Monitoring Protocol";
+ }
+ enum "rdp" {
+ value 27;
+ description "Reliable Datagram Protocol";
+ }
+ enum "dccp" {
+ value 33;
+ description "Datagram Congestion Control Protocol";
+ }
+ enum "encap" {
+ value 41;
+ description "IPv6 Encapsulation";
+ }
+ enum "ipv6-route" {
+ value 43;
+ description "IPv6 Routing Header";
+ }
+ enum "ipv6-frag" {
+ value 44;
+ description "IPv6 Fragment Header";
+ }
+ enum "rsvp" {
+ value 46;
+ description "Resource Reservation Protocol";
+ }
+ enum "gre" {
+ value 47;
+ description "Generic Routing Encapsulation";
+ }
+ enum "esp" {
+ value 50;
+ description "Encapsulating Security Payload";
+ }
+ enum "ah" {
+ value 51;
+ description "Authentication Header";
+ }
+ enum "ipv6-icmp" {
+ value 58;
+ description "IPv6 ICMP";
+ }
+ enum "ipv6-no-next" {
+ value 59;
+ description "IPv6 No Next Header";
+ }
+ enum "ipv6-opts" {
+ value 60;
+ description "IPv6 Destination Options";
+ }
+ enum "ospf" {
+ value 89;
+ description "Open Shortest Path First";
+ }
+ enum "sctp" {
+ value 132;
+ description "Stream Control Transmission Protocol";
+ }
+ }
+ }
+
+ grouping ipv4-packet-fields {
+ leaf version {
+ type uint8;
+ }
+
+ leaf ihl {
+ type uint8;
+ description "Internal Header Length";
+ }
+
+ leaf dscp {
+ type uint8;
+ description "Differentiated Code Services Point";
+ }
+
+ leaf ecn {
+ type uint8;
+ description "Explicit Congestion Notification";
+ }
+
+ leaf ipv4-length {
+ type uint16;
+ description "Packet size, including header and data, in bytes";
+ }
+
+ leaf id {
+ type uint16;
+ description "Identification";
+ }
+
+ leaf reserved-flag {
+ type boolean;
+ description "First bit in the flags, must be 0";
+ }
+
+ leaf df-flag {
+ type boolean;
+ description "Second bit in the flags, Don't Fragment Flag";
+ }
+
+ leaf mf-flag {
+ type boolean;
+ description "Third bit in the flags, More Fragments Flag";
+ }
+
+ leaf fragment-offset {
+ type uint16;
+ description "Specifies the offset of a particular fragment relative to the beginning of the original unfragmented IP datagram";
+ }
+
+ leaf ttl {
+ type uint8;
+ description "Time to live";
+ }
+
+ leaf protocol {
+ type known-ip-protocols;
+ description "Protocol for the data";
+ }
+
+ leaf checksum {
+ type uint16;
+ description "Header Checksum";
+ }
+
+ leaf source-ipv4 {
+ type string;
+ }
+
+ leaf destination-ipv4 {
+ type string;
+ }
+
+ leaf ipv4-options {
+ type binary;
+ }
+
+
+ uses bpacket:packet-fields;
+ }
+
+ grouping ipv4-packet-over-ethernet-fields {
+ container ipv4-packet {
+ uses ipv4-packet-fields;
+ }
+ container ethernet-over-raw-packet {
+ uses ethernet:ethernet-packet-over-raw-fields;
+ }
+ }
+
+ notification ipv4-packet-over-ethernet-received {
+ uses bpacket:packet-payload;
+ uses ipv4-packet-over-ethernet-fields;
+ }
+}
namespace "urn:opendaylight:packet:basepacket";
prefix bpacket;
- import ietf-yang-types {
- prefix yang;
- revision-date 2010-09-24;
- }
- import packet-processing {
- prefix pprocessing;
- revision-date 2013-07-09;
- }
+ import ietf-yang-types {prefix yang; revision-date 2010-09-24;}
+ import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
+ import packet-processing {prefix pprocessing; revision-date 2013-07-09;}
+ import opendaylight-match-types {prefix match-type;revision-date "2013-10-26";}
+ import opendaylight-table-types {prefix table-type;revision-date "2013-10-26";}
+ import opendaylight-flow-types {prefix flow-type;revision-date "2013-10-26";}
+
revision 2014-05-28 {
description
"Base packet module draft.";
}
- /* packet type for the packets that have payload in them to decode */
- typedef packet-type {
- type enumeration {
- enum "raw" {
- value 0;
- description "Default raw packet";
- }
- enum "ethernet" {
- value 1;
- description "Ethernet protocol";
- }
- enum "ipv4" {
- value 2;
- description "Address Resolution Protocol (ARP)";
- }
-
+ grouping packet-payload {
+ leaf payload {
+ type binary;
}
}
- grouping packet-payload-type-grp {
- leaf packet-type {
- type packet-type;
+ grouping packet-fields {
+ leaf payload-offset {
+ type int32;
}
- leaf payload-type {
+ leaf payload-length {
type int32;
}
- }
+ }
- grouping packet {
- container packet-payload-type {
- uses packet-payload-type-grp;
+ grouping raw-packet-fields {
+ leaf ingress {
+ type inv:node-connector-ref;
+ }
+ leaf connection-cookie {
+ type pprocessing:connection-cookie;
}
- container raw-packet {
- uses pprocessing:raw-packet;
+ leaf flow-cookie {
+ type flow-type:flow-cookie;
}
+ leaf table-id {
+ type table-type:table-id;
+ }
+ leaf packet-in-reason {
+ type identityref {
+ base pprocessing:packet-in-reason;
+ }
+ }
+ container match {
+ uses match-type:match;
+ }
+ uses packet-fields;
}
- container base-packet {
- uses packet;
- }
}
\ No newline at end of file
<modules>
<module>parent</module>
<module>packethandler</module>
- <module>ethernetdecoder</module>
+ <!--module>ethernetdecoder</module>
<module>arpdecoder</module>
<module>ipv4decoder</module>
<module>ipv6decoder</module>
- <module>addresstracker</module>
+ <module>addresstracker</module-->
<module>l2switch-controller-config</module>
</modules>
<scm>