/* * Copyright (c) 2017 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.openflowplugin.impl.protocol.deserialization.multipart; import com.google.common.collect.ImmutableMap; import io.netty.buffer.ByteBuf; import java.util.Map; import java.util.Optional; import org.opendaylight.openflowjava.protocol.api.keys.MatchEntryDeserializerKey; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.ArpOp; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.ArpSha; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.ArpSpa; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.ArpTha; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.ArpTpa; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.EthDst; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.EthSrc; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.Icmpv4Code; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.Icmpv4Type; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.Icmpv6Code; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.Icmpv6Type; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.InPhyPort; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.InPort; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.IpDscp; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.IpEcn; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.IpProto; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.Ipv4Dst; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.Ipv4Src; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.Ipv6Dst; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.Ipv6Exthdr; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.Ipv6Flabel; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.Ipv6NdSll; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.Ipv6NdTarget; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.Ipv6NdTll; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.Ipv6Src; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.MatchField; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.Metadata; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.MplsBos; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.MplsLabel; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.MplsTc; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.PbbIsid; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.SctpDst; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.SctpSrc; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TcpDst; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TcpFlags; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TcpSrc; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TunnelId; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.UdpDst; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.UdpSrc; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.VlanPcp; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.VlanVid; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.set.field.match.SetFieldMatch; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.set.field.match.SetFieldMatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.set.field.match.SetFieldMatchKey; public class TableFeaturesMatchFieldDeserializer { /** * Mapping of match entry code to match set field class */ private final Map<MatchEntryDeserializerKey, Class<? extends MatchField>> CODE_TO_FIELD = ImmutableMap .<MatchEntryDeserializerKey, Class<? extends MatchField>>builder() .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.ARP_OP), ArpOp.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.ARP_SHA), ArpSha.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.ARP_SPA), ArpSpa.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.ARP_THA), ArpTha.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.ARP_TPA), ArpTpa.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.ETH_DST), EthDst.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.ETH_SRC), EthSrc.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.ICMPV4_CODE), Icmpv4Code.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.ICMPV4_TYPE), Icmpv4Type.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.ICMPV6_CODE), Icmpv6Code.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.ICMPV6_TYPE), Icmpv6Type.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.IN_PHY_PORT), InPhyPort.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.IN_PORT), InPort.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.IP_DSCP), IpDscp.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.IP_ECN), IpEcn.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.IP_PROTO), IpProto.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.IPV4_DST), Ipv4Dst.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.IPV4_SRC), Ipv4Src.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.IPV6_DST), Ipv6Dst.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.IPV6_SRC), Ipv6Src.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.IPV6_EXTHDR), Ipv6Exthdr.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.IPV6_FLABEL), Ipv6Flabel.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.IPV6_ND_SLL), Ipv6NdSll.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.IPV6_ND_TLL), Ipv6NdTll.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.IPV6_ND_TARGET), Ipv6NdTarget.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.METADATA), Metadata.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.MPLS_BOS), MplsBos.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.MPLS_LABEL), MplsLabel.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.MPLS_TC), MplsTc.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.PBB_ISID), PbbIsid.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.SCTP_DST), SctpDst.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.SCTP_SRC), SctpSrc.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.TCP_SRC), TcpSrc.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.TCP_DST), TcpDst.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.TUNNEL_ID), TunnelId.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.UDP_SRC), UdpSrc.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.UDP_DST), UdpDst.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.VLAN_PCP), VlanPcp.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.VLAN_VID), VlanVid.class) .put(new MatchEntryDeserializerKey( EncodeConstants.OF13_VERSION_ID, OxmMatchConstants.EXPERIMENTER_CLASS, OxmMatchConstants.NXM_NX_TCP_FLAG), TcpFlags.class) .build(); /** * Processes match entry header and returns if it have mask, or not * @param in input buffer * @return SetFieldMatchBuilder with hasMask properly set */ protected static SetFieldMatchBuilder processHeader(ByteBuf in) { in.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES); // skip oxm_class boolean hasMask = (in.readUnsignedByte() & 1) != 0; in.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES); // skip match entry length return new SetFieldMatchBuilder() .setHasMask(hasMask); } /** * Deserialize match field if deserializer supports it, otherwise returns empty optional * @param message input buffer * @return set field match */ public Optional<SetFieldMatch> deserialize(ByteBuf message) { int oxmClass = message.getUnsignedShort(message.readerIndex()); int oxmField = message.getUnsignedByte(message.readerIndex() + EncodeConstants.SIZE_OF_SHORT_IN_BYTES) >>> 1; Long expId = null; if (oxmClass == EncodeConstants.EXPERIMENTER_VALUE) { expId = message.getUnsignedInt(message.readerIndex() + EncodeConstants.SIZE_OF_SHORT_IN_BYTES + 2 * EncodeConstants.SIZE_OF_BYTE_IN_BYTES); } final MatchEntryDeserializerKey key = new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, oxmClass, oxmField); key.setExperimenterId(expId); return Optional .ofNullable(CODE_TO_FIELD.get(key)) .map(clazz -> processHeader(message) .setKey(new SetFieldMatchKey(clazz)) .setMatchType(clazz) .build()); }}