Update OF header lenght
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / core / OFVersionDetector.java
index d5b31e261651088f868119c68713856a961298e5..8e23566af1fef8bf5fda007668787aff26c58f97 100644 (file)
@@ -1,58 +1,73 @@
-/* Copyright (C)2013 Pantheon Technologies, s.r.o. All rights reserved. */
+/*
+ * Copyright (c) 2013 Pantheon Technologies s.r.o. 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.openflowjava.protocol.impl.core;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.handler.codec.ByteToMessageDecoder;
-
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
-
+import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
+import org.opendaylight.openflowjava.statistics.CounterEventTypes;
+import org.opendaylight.openflowjava.statistics.StatisticsCounters;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Class that detects version of used OpenFlow Protocol and engages right OFCodec into
- * pipeline.
- *
+ * Detects version of used OpenFlow Protocol and discards unsupported version messages.
  * @author michal.polkorab
  */
 public class OFVersionDetector extends ByteToMessageDecoder {
 
-    /** Version number of OpenFlow 1.0 protocol */
-    public static final byte OF10_VERSION_ID = 0x01;
-    /** Version number of OpenFlow 1.3 protocol */
-    public static final byte OF13_VERSION_ID = 0x04;
-    private static final Logger LOGGER = LoggerFactory.getLogger(OFVersionDetector.class);
+    private static final Logger LOG = LoggerFactory.getLogger(OFVersionDetector.class);
+    /** IDs of accepted OpenFlow protocol versions */
+    private static final List<Byte> OF_VERSIONS = new ArrayList<>(Arrays.asList(
+            EncodeConstants.OF10_VERSION_ID,
+            EncodeConstants.OF13_VERSION_ID
+    ));
+    private final StatisticsCounters statisticsCounters;
+    private volatile boolean filterPacketIns;
 
-    /**
-     * Constructor of class.
-     */
     public OFVersionDetector() {
-        LOGGER.debug("Creating OFVersionDetector");
+        LOG.trace("Creating OFVersionDetector");
+        statisticsCounters = StatisticsCounters.getInstance();
+    }
+
+    public void setFilterPacketIns(final boolean enabled) {
+        filterPacketIns = enabled;
     }
 
     @Override
-    protected void decode(ChannelHandlerContext chc, ByteBuf bb, List<Object> list) throws Exception {
-        if (bb.readableBytes() == 0) {
-            LOGGER.debug("not enough data");
-            bb.release();
+    protected void decode(final ChannelHandlerContext ctx, final ByteBuf in, final List<Object> out) {
+        if (!in.isReadable()) {
+            LOG.debug("not enough data");
+            in.release();
             return;
         }
-        LOGGER.debug("RI: " + bb.readerIndex());
-        byte version = bb.readByte();
 
-        if ((version == OF13_VERSION_ID) || (version == OF10_VERSION_ID)) {
-            LOGGER.debug("detected version: " + version);
+        final byte version = in.readByte();
+        final short messageType = in.getUnsignedByte(in.readerIndex());
+        if (messageType == EncodeConstants.OF_HELLO_MESSAGE_TYPE_VALUE || OF_VERSIONS.contains(version)) {
+            LOG.debug("detected version: {}", version);
+            if (!filterPacketIns || EncodeConstants.OF_PACKETIN_MESSAGE_TYPE_VALUE != messageType) {
+                ByteBuf messageBuffer = in.slice();
+                out.add(new VersionMessageWrapper(version, messageBuffer));
+                messageBuffer.retain();
+            } else {
+                LOG.debug("dropped packetin");
+                statisticsCounters.incrementCounter(CounterEventTypes.US_DROPPED_PACKET_IN);
+            }
         } else {
-            LOGGER.warn("detected version: " + version + " - currently not supported");
-            bb.skipBytes(bb.readableBytes());
-            return;
+            LOG.warn("detected version: {} - currently not supported", version);
         }
-
-        ByteBuf messageBuffer = bb.slice();
-        list.add(new VersionMessageWrapper(version, messageBuffer));
-        messageBuffer.retain();
-        bb.skipBytes(bb.readableBytes());
+        in.skipBytes(in.readableBytes());
     }
 
 }