Use ByteBuf.readRetainedSlice()
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / protocol / deserialization / MatchDeserializerInjector.java
1 /*
2  * Copyright (c) 2016 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 package org.opendaylight.openflowplugin.impl.protocol.deserialization;
9
10 import com.google.common.annotations.VisibleForTesting;
11 import java.util.function.Consumer;
12 import java.util.function.Function;
13 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerExtensionProvider;
14 import org.opendaylight.openflowjava.protocol.api.keys.MatchEntryDeserializerKey;
15 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
16 import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants;
17 import org.opendaylight.openflowplugin.api.openflow.protocol.deserialization.MatchEntryDeserializer;
18 import org.opendaylight.openflowplugin.api.openflow.protocol.deserialization.MatchEntryDeserializerRegistry;
19 import org.opendaylight.openflowplugin.extension.api.path.MatchPath;
20 import org.opendaylight.openflowplugin.impl.protocol.deserialization.key.MessageCodeMatchKey;
21 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.ArpOpEntryDeserializer;
22 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.ArpSourceHardwareAddressEntryDeserializer;
23 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.ArpSourceTransportAddressEntryDeserializer;
24 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.ArpTargetHardwareAddressEntryDeserializer;
25 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.ArpTargetTransportAddressEntryDeserializer;
26 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.EthernetDestinationEntryDeserializer;
27 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.EthernetSourceEntryDeserializer;
28 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.EthernetTypeEntryDeserializer;
29 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.Icmpv4CodeEntryDeserializer;
30 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.Icmpv4TypeEntryDeserializer;
31 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.Icmpv6CodeEntryDeserializer;
32 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.Icmpv6TypeEntryDeserializer;
33 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.InPhyPortEntryDeserializer;
34 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.InPortEntryDeserializer;
35 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.IpDscpEntryDeserializer;
36 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.IpEcnEntryDeserializer;
37 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.IpProtoEntryDeserializer;
38 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.Ipv4DestinationEntryDeserializer;
39 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.Ipv4SourceEntryDeserializer;
40 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.Ipv6DestinationEntryDeserializer;
41 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.Ipv6ExtHeaderEntryDeserializer;
42 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.Ipv6FlabelEntryDeserializer;
43 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.Ipv6NdSllEntryDeserializer;
44 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.Ipv6NdTargetEntryDeserializer;
45 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.Ipv6NdTllEntryDeserializer;
46 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.Ipv6SourceEntryDeserializer;
47 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.MatchDeserializer;
48 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.MetadataEntryDeserializer;
49 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.MplsBosEntryDeserializer;
50 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.MplsLabelEntryDeserializer;
51 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.MplsTcEntryDeserializer;
52 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.PacketTypeEntryDeserializer;
53 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.PbbEntryDeserializer;
54 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.SctpDestinationPortEntryDeserializer;
55 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.SctpSourcePortEntryDeserializer;
56 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.TcpDestinationPortEntryDeserializer;
57 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.TcpFlagsEntryDeserializer;
58 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.TcpSourcePortEntryDeserializer;
59 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.TunnelIdEntryDeserializer;
60 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.UdpDestinationPortEntryDeserializer;
61 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.UdpSourcePortEntryDeserializer;
62 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.VlanPcpEntryDeserializer;
63 import org.opendaylight.openflowplugin.impl.protocol.deserialization.match.VlanVidEntryDeserializer;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match;
65 import org.opendaylight.yangtools.yang.common.Uint32;
66 import org.opendaylight.yangtools.yang.common.Uint8;
67
68 /**
69  * Util class for injecting new match entry deserializers into OpenflowJava.
70  */
71 public final class MatchDeserializerInjector {
72
73     private MatchDeserializerInjector() {
74     }
75
76     /**
77      * Injects deserializers into provided
78      * {@link org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerExtensionProvider}.
79      *
80      * @param provider OpenflowJava deserializer extension provider
81      */
82     static void injectDeserializers(final DeserializerExtensionProvider provider) {
83         for (MatchPath path : MatchPath.values()) {
84             final MatchDeserializer deserializer = new MatchDeserializer(path);
85             provider.registerDeserializer(
86                     new MessageCodeMatchKey(
87                             EncodeConstants.OF_VERSION_1_3,
88                             EncodeConstants.EMPTY_LENGTH,
89                             Match.class,
90                             path),
91                     deserializer);
92
93             // Inject new match entry serializers here using injector created by createInjector method
94             final Function<Integer, Function<Uint32, Function<Integer, Consumer<MatchEntryDeserializer>>>> injector =
95                     createInjector(deserializer, EncodeConstants.OF_VERSION_1_3);
96
97             // Wrapped injector that uses OPENFLOW_BASIC_CLASS
98             final Function<Integer, Consumer<MatchEntryDeserializer>> basicInjector =
99                     injector.apply(OxmMatchConstants.OPENFLOW_BASIC_CLASS).apply(null);
100
101             // Wrapped injector that uses EXPERIMENTER_CLASS
102             final Function<Uint32, Function<Integer, Consumer<MatchEntryDeserializer>>> experInjector =
103                     injector.apply(OxmMatchConstants.EXPERIMENTER_CLASS);
104
105             basicInjector.apply(OxmMatchConstants.ARP_OP).accept(new ArpOpEntryDeserializer());
106             basicInjector.apply(OxmMatchConstants.ARP_SHA).accept(new ArpSourceHardwareAddressEntryDeserializer());
107             basicInjector.apply(OxmMatchConstants.ARP_THA).accept(new ArpTargetHardwareAddressEntryDeserializer());
108             basicInjector.apply(OxmMatchConstants.ARP_SPA).accept(new ArpSourceTransportAddressEntryDeserializer());
109             basicInjector.apply(OxmMatchConstants.ARP_TPA).accept(new ArpTargetTransportAddressEntryDeserializer());
110             basicInjector.apply(OxmMatchConstants.IN_PORT).accept(new InPortEntryDeserializer());
111             basicInjector.apply(OxmMatchConstants.IN_PHY_PORT).accept(new InPhyPortEntryDeserializer());
112             basicInjector.apply(OxmMatchConstants.METADATA).accept(new MetadataEntryDeserializer());
113             basicInjector.apply(OxmMatchConstants.PACKET_TYPE).accept(new PacketTypeEntryDeserializer());
114             basicInjector.apply(OxmMatchConstants.ETH_DST).accept(new EthernetDestinationEntryDeserializer());
115             basicInjector.apply(OxmMatchConstants.ETH_SRC).accept(new EthernetSourceEntryDeserializer());
116             basicInjector.apply(OxmMatchConstants.ETH_TYPE).accept(new EthernetTypeEntryDeserializer());
117             basicInjector.apply(OxmMatchConstants.VLAN_PCP).accept(new VlanPcpEntryDeserializer());
118             basicInjector.apply(OxmMatchConstants.VLAN_VID).accept(new VlanVidEntryDeserializer());
119             basicInjector.apply(OxmMatchConstants.IP_DSCP).accept(new IpDscpEntryDeserializer());
120             basicInjector.apply(OxmMatchConstants.IP_ECN).accept(new IpEcnEntryDeserializer());
121             basicInjector.apply(OxmMatchConstants.IP_PROTO).accept(new IpProtoEntryDeserializer());
122             basicInjector.apply(OxmMatchConstants.TCP_SRC).accept(new TcpSourcePortEntryDeserializer());
123             basicInjector.apply(OxmMatchConstants.TCP_DST).accept(new TcpDestinationPortEntryDeserializer());
124             basicInjector.apply(OxmMatchConstants.UDP_SRC).accept(new UdpSourcePortEntryDeserializer());
125             basicInjector.apply(OxmMatchConstants.UDP_DST).accept(new UdpDestinationPortEntryDeserializer());
126             basicInjector.apply(OxmMatchConstants.SCTP_SRC).accept(new SctpSourcePortEntryDeserializer());
127             basicInjector.apply(OxmMatchConstants.SCTP_DST).accept(new SctpDestinationPortEntryDeserializer());
128             basicInjector.apply(OxmMatchConstants.ICMPV4_CODE).accept(new Icmpv4CodeEntryDeserializer());
129             basicInjector.apply(OxmMatchConstants.ICMPV4_TYPE).accept(new Icmpv4TypeEntryDeserializer());
130             basicInjector.apply(OxmMatchConstants.ICMPV6_CODE).accept(new Icmpv6CodeEntryDeserializer());
131             basicInjector.apply(OxmMatchConstants.ICMPV6_TYPE).accept(new Icmpv6TypeEntryDeserializer());
132             // TODO: How to differentiate between Ipv4 and Tunnel when both are serialized to same format?
133             basicInjector.apply(OxmMatchConstants.IPV4_SRC).accept(new Ipv4SourceEntryDeserializer());
134             basicInjector.apply(OxmMatchConstants.IPV4_DST).accept(new Ipv4DestinationEntryDeserializer());
135             basicInjector.apply(OxmMatchConstants.IPV6_SRC).accept(new Ipv6SourceEntryDeserializer());
136             basicInjector.apply(OxmMatchConstants.IPV6_DST).accept(new Ipv6DestinationEntryDeserializer());
137             basicInjector.apply(OxmMatchConstants.IPV6_EXTHDR).accept(new Ipv6ExtHeaderEntryDeserializer());
138             basicInjector.apply(OxmMatchConstants.IPV6_FLABEL).accept(new Ipv6FlabelEntryDeserializer());
139             basicInjector.apply(OxmMatchConstants.IPV6_ND_SLL).accept(new Ipv6NdSllEntryDeserializer());
140             basicInjector.apply(OxmMatchConstants.IPV6_ND_TLL).accept(new Ipv6NdTllEntryDeserializer());
141             basicInjector.apply(OxmMatchConstants.IPV6_ND_TARGET).accept(new Ipv6NdTargetEntryDeserializer());
142             basicInjector.apply(OxmMatchConstants.MPLS_LABEL).accept(new MplsLabelEntryDeserializer());
143             basicInjector.apply(OxmMatchConstants.MPLS_BOS).accept(new MplsBosEntryDeserializer());
144             basicInjector.apply(OxmMatchConstants.MPLS_TC).accept(new MplsTcEntryDeserializer());
145             basicInjector.apply(OxmMatchConstants.PBB_ISID).accept(new PbbEntryDeserializer());
146             basicInjector.apply(OxmMatchConstants.TUNNEL_ID).accept(new TunnelIdEntryDeserializer());
147             experInjector.apply(EncodeConstants.ONF_EXPERIMENTER_ID).apply(EncodeConstants.ONFOXM_ET_TCP_FLAGS)
148                     .accept(new TcpFlagsEntryDeserializer());
149         }
150     }
151
152     /**
153      * Create injector that will inject new serializers into
154      * {@link org.opendaylight.openflowplugin.api.openflow.protocol.deserialization.MatchEntryDeserializerRegistry}.
155      *
156      * @param registry Match entry deserializer registry
157      * @param version  Openflow version
158      * @return injector
159      */
160     @VisibleForTesting
161     static Function<Integer, Function<Uint32, Function<Integer, Consumer<MatchEntryDeserializer>>>> createInjector(
162             final MatchEntryDeserializerRegistry registry, final Uint8 version) {
163         return oxmClass -> expId -> oxmField -> deserializer -> {
164             final MatchEntryDeserializerKey key = new MatchEntryDeserializerKey(version, oxmClass, oxmField);
165             key.setExperimenterId(expId);
166             registry.registerEntryDeserializer(key, deserializer);
167         };
168     }
169
170 }