BUG-3229: Add support for PacketIn filtering
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / core / OFVersionDetector.java
1 /*
2  * Copyright (c) 2013 Pantheon Technologies s.r.o. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.openflowjava.protocol.impl.core;
10
11 import io.netty.buffer.ByteBuf;
12 import io.netty.channel.ChannelHandlerContext;
13 import io.netty.handler.codec.ByteToMessageDecoder;
14 import java.util.List;
15 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
16 import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory;
18
19 /**
20  * Detects version of used OpenFlow Protocol and discards unsupported version messages
21  * @author michal.polkorab
22  */
23 public class OFVersionDetector extends ByteToMessageDecoder {
24
25     /** Version number of OpenFlow 1.0 protocol */
26     private static final byte OF10_VERSION_ID = EncodeConstants.OF10_VERSION_ID;
27     /** Version number of OpenFlow 1.3 protocol */
28     private static final byte OF13_VERSION_ID = EncodeConstants.OF13_VERSION_ID;
29     private static final short OF_PACKETIN = 10;
30     private static final Logger LOGGER = LoggerFactory.getLogger(OFVersionDetector.class);
31     private volatile boolean filterPacketIns;
32
33     /**
34      * Constructor of class.
35      */
36     public OFVersionDetector() {
37         LOGGER.trace("Creating OFVersionDetector");
38     }
39
40     public void setFilterPacketIns(final boolean enabled) {
41         filterPacketIns = enabled;
42     }
43
44     @Override
45     protected void decode(final ChannelHandlerContext ctx, final ByteBuf in, final List<Object> out) {
46         if (!in.isReadable()) {
47             LOGGER.debug("not enough data");
48             in.release();
49             return;
50         }
51
52         final byte version = in.readByte();
53         if (version == OF13_VERSION_ID || version == OF10_VERSION_ID) {
54             LOGGER.debug("detected version: {}", version);
55             if (!filterPacketIns || OF_PACKETIN != in.getUnsignedByte(in.readerIndex())) {
56                 ByteBuf messageBuffer = in.slice();
57                 out.add(new VersionMessageWrapper(version, messageBuffer));
58                 messageBuffer.retain();
59             } else {
60                 LOGGER.debug("dropped packetin");
61             }
62         } else {
63             LOGGER.warn("detected version: {} - currently not supported", version);
64         }
65         in.skipBytes(in.readableBytes());
66     }
67 }