2 * Copyright (c) 2016 Pantheon Technologies s.r.o. and others. All rights reserved.
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
8 package org.opendaylight.openflowplugin.impl.protocol.deserialization.match;
10 import io.netty.buffer.ByteBuf;
11 import java.util.HashMap;
13 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry;
14 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector;
15 import org.opendaylight.openflowjava.protocol.api.extensibility.HeaderDeserializer;
16 import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
17 import org.opendaylight.openflowjava.protocol.api.keys.MatchEntryDeserializerKey;
18 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
19 import org.opendaylight.openflowplugin.api.openflow.protocol.deserialization.MatchEntryDeserializer;
20 import org.opendaylight.openflowplugin.api.openflow.protocol.deserialization.MatchEntryDeserializerRegistry;
21 import org.opendaylight.openflowplugin.extension.api.path.MatchPath;
22 import org.opendaylight.openflowplugin.openflow.md.core.extension.MatchExtensionHelper;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
29 public class MatchDeserializer implements OFDeserializer<Match>, HeaderDeserializer<Match>,
30 MatchEntryDeserializerRegistry, MatchEntryDeserializer, DeserializerRegistryInjector {
32 private static final Logger LOG = LoggerFactory.getLogger(MatchDeserializer.class);
33 private final Map<MatchEntryDeserializerKey, MatchEntryDeserializer> entryRegistry = new HashMap<>();
34 private final MatchPath matchPath;
35 private DeserializerRegistry registry;
37 public MatchDeserializer(final MatchPath matchPath) {
38 this.matchPath = matchPath;
42 public Match deserialize(ByteBuf inBuffer) {
43 if (inBuffer.readableBytes() <= 0) {
47 final MatchBuilder builder = new MatchBuilder();
49 // OFP do not have any method to differentiate between OXM and standard match, so we do not care about type
50 inBuffer.readUnsignedShort();
51 final int length = inBuffer.readUnsignedShort();
53 final int startIndex = inBuffer.readerIndex();
54 final int entriesLength = length - 2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES;
56 while (inBuffer.readerIndex() - startIndex < entriesLength) {
57 deserializeEntry(inBuffer, builder);
60 int paddingRemainder = length % EncodeConstants.PADDING;
62 if (paddingRemainder != 0) {
63 inBuffer.skipBytes(EncodeConstants.PADDING - paddingRemainder);
66 return builder.build();
70 public Match deserializeHeader(ByteBuf inBuffer) {
71 final MatchBuilder builder = new MatchBuilder();
72 deserializeEntry(inBuffer, builder);
73 return builder.build();
77 public void deserializeEntry(ByteBuf inBuffer, MatchBuilder builder) {
78 if (inBuffer.readableBytes() <= 0) {
81 int oxmClass = inBuffer.getUnsignedShort(inBuffer.readerIndex());
82 int oxmField = inBuffer.getUnsignedByte(inBuffer.readerIndex()
83 + EncodeConstants.SIZE_OF_SHORT_IN_BYTES) >>> 1;
85 final MatchEntryDeserializerKey key = new MatchEntryDeserializerKey(
86 EncodeConstants.OF13_VERSION_ID, oxmClass, oxmField);
88 if (oxmClass == EncodeConstants.EXPERIMENTER_VALUE) {
89 long expId = inBuffer.getUnsignedInt(inBuffer.readerIndex()
90 + EncodeConstants.SIZE_OF_SHORT_IN_BYTES
91 + 2 * EncodeConstants.SIZE_OF_BYTE_IN_BYTES);
93 key.setExperimenterId(expId);
96 final MatchEntryDeserializer entryDeserializer = entryRegistry.get(key);
98 if (entryDeserializer != null) {
99 entryDeserializer.deserializeEntry(inBuffer, builder);
101 final OFDeserializer<MatchEntry> deserializer = registry.getDeserializer(key);
102 MatchExtensionHelper.injectExtension(EncodeConstants.OF13_VERSION_ID,
103 deserializer.deserialize(inBuffer), builder, matchPath);
108 public void registerEntryDeserializer(MatchEntryDeserializerKey key, MatchEntryDeserializer deserializer) {
109 if (key == null || deserializer == null) {
110 throw new IllegalArgumentException("MatchEntryDeserializerKey or Deserializer is null");
113 final MatchEntryDeserializer desInRegistry = entryRegistry.put(key, deserializer);
115 if (desInRegistry != null) {
116 LOG.debug("Deserializer for key {} overwritten. Old deserializer: {}, new deserializer: {}", key,
117 desInRegistry.getClass().getName(), deserializer.getClass().getName());
122 public boolean unregisterEntryDeserializer(MatchEntryDeserializerKey key) {
124 throw new IllegalArgumentException("MatchEntryDeserializerKey is null");
127 return entryRegistry.remove(key) != null;
131 public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) {
132 registry = deserializerRegistry;