Merge "Migrate most of openflowplugin to use Uint types"
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / sal / convertor / match / cases / OfToSalIpv4DstCase.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. 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.openflowplugin.openflow.md.core.sal.convertor.match.cases;
10
11 import java.util.Optional;
12 import org.eclipse.jdt.annotation.NonNull;
13 import org.opendaylight.openflowplugin.api.OFConstants;
14 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
15 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.ConvertorCase;
16 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.IpConversionUtil;
17 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.data.MatchResponseConvertorData;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchArbitraryBitMaskBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv4DstCase;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv4.dst._case.Ipv4Dst;
26
27 public class OfToSalIpv4DstCase extends ConvertorCase<Ipv4DstCase, MatchBuilder, MatchResponseConvertorData> {
28     public OfToSalIpv4DstCase() {
29         super(Ipv4DstCase.class, true, OFConstants.OFP_VERSION_1_0, OFConstants.OFP_VERSION_1_3);
30     }
31
32     private static void setIpv4MatchBuilderFields(final Ipv4MatchBuilder ipv4MatchBuilder, final byte[] mask,
33             final Ipv4Address address) {
34         final Ipv4Prefix ipv4Prefix;
35         if (mask != null) {
36             ipv4Prefix = IpConversionUtil.createPrefix(address, mask);
37         } else {
38             //Openflow Spec : 1.3.2
39             //An all-one-bits oxm_mask is equivalent to specifying 0 for oxm_hasmask and omitting oxm_mask.
40             // So when user specify 32 as a mast, switch omit that mast and we get null as a mask in flow
41             // statistics response.
42             ipv4Prefix = IpConversionUtil.createPrefix(address);
43         }
44
45         ipv4MatchBuilder.setIpv4Destination(ipv4Prefix);
46     }
47
48     private static void setSrcIpv4MatchArbitraryBitMaskBuilderFields(
49             final Ipv4MatchArbitraryBitMaskBuilder ipv4MatchArbitraryBitMaskBuilder,
50             final DottedQuad mask, final String ipv4AddressStr) {
51         if (mask != null) {
52             ipv4MatchArbitraryBitMaskBuilder.setIpv4SourceArbitraryBitmask(mask);
53         }
54
55         ipv4MatchArbitraryBitMaskBuilder.setIpv4SourceAddressNoMask(new Ipv4Address(ipv4AddressStr));
56     }
57
58     private static void setDstIpv4MatchArbitraryBitMaskBuilderFields(
59             final Ipv4MatchArbitraryBitMaskBuilder ipv4MatchArbitraryBitMaskBuilder,
60             final DottedQuad mask, final Ipv4Address ipv4Address) {
61         if (mask != null) {
62             ipv4MatchArbitraryBitMaskBuilder.setIpv4DestinationArbitraryBitmask(mask);
63         }
64
65         ipv4MatchArbitraryBitMaskBuilder.setIpv4DestinationAddressNoMask(ipv4Address);
66     }
67
68     @Override
69     public Optional<MatchBuilder> process(@NonNull final Ipv4DstCase source, final MatchResponseConvertorData data,
70             final ConvertorExecutor convertorExecutor) {
71         final MatchBuilder matchBuilder = data.getMatchBuilder();
72         final Ipv4MatchBuilder ipv4MatchBuilder = data.getIpv4MatchBuilder();
73         final Ipv4MatchArbitraryBitMaskBuilder ipv4MatchArbitraryBitMaskBuilder =
74                 data.getIpv4MatchArbitraryBitMaskBuilder();
75
76         Ipv4Dst ipv4Address = source.getIpv4Dst();
77
78         if (ipv4Address != null) {
79             byte[] mask = ipv4Address.getMask();
80
81             if (mask != null && IpConversionUtil.isArbitraryBitMask(mask)) {
82                 // case where ipv4src is of type ipv4MatchBuilder and ipv4dst is of type ipv4MatchArbitrary.
83                 // Needs to convert ipv4src to ipv4MatchArbitrary.
84                 if (ipv4MatchBuilder.getIpv4Source() != null) {
85                     Ipv4Prefix ipv4PrefixSourceAddress = ipv4MatchBuilder.getIpv4Source();
86                     Ipv4Address ipv4SourceAddress = IpConversionUtil.extractIpv4Address(ipv4PrefixSourceAddress);
87                     DottedQuad srcDottedQuad = IpConversionUtil.extractIpv4AddressMask(ipv4PrefixSourceAddress);
88                     setSrcIpv4MatchArbitraryBitMaskBuilderFields(ipv4MatchArbitraryBitMaskBuilder,
89                             srcDottedQuad, ipv4SourceAddress.getValue());
90                 }
91
92                 DottedQuad dstDottedQuadMask = IpConversionUtil.createArbitraryBitMask(mask);
93                 setDstIpv4MatchArbitraryBitMaskBuilderFields(ipv4MatchArbitraryBitMaskBuilder,
94                         dstDottedQuadMask, ipv4Address.getIpv4Address());
95                 matchBuilder.setLayer3Match(ipv4MatchArbitraryBitMaskBuilder.build());
96             } else if (ipv4MatchArbitraryBitMaskBuilder.getIpv4SourceAddressNoMask() != null) {
97                         /*
98                         Case where source is of type ipv4MatchArbitraryBitMask already exists in Layer3Match,
99                         destination which of type ipv4Match needs to be converted to ipv4MatchArbitraryBitMask.
100                         We convert 36.36.36.0/24 to 36.36.0/255.255.255.0
101                         expected output example:-
102                         <ipv4-source>36.36.36.0/24</ipv4-source>
103                         <ipv4-destination-address-no-mask>36.36.36.0</ipv4-destination-address-no-mask>
104                         <ipv4-destination-arbitrary-bitmask>255.0.255.0</ipv4-destination-arbitrary-bitmask>
105                         after conversion output example:-
106                         <ipv4-source-address-no-mask>36.36.36.0</ipv4-source-address-no-mask>
107                         <ipv4-source-arbitrary-bitmask>255.255.255.0</ipv4-source-arbitrary-bitmask>
108                         <ipv4-destination-address-no-mask>36.36.36.0</ipv4-destination-address-no-mask>
109                         <ipv4-destination-arbitrary-bitmask>255.0.255.0</ipv4-destination-arbitrary-bitmask>
110                         */
111                 DottedQuad dstDottedQuadMask = IpConversionUtil.createArbitraryBitMask(mask);
112                 setDstIpv4MatchArbitraryBitMaskBuilderFields(ipv4MatchArbitraryBitMaskBuilder,
113                         dstDottedQuadMask, ipv4Address.getIpv4Address());
114                 matchBuilder.setLayer3Match(ipv4MatchArbitraryBitMaskBuilder.build());
115             } else {
116                 setIpv4MatchBuilderFields(ipv4MatchBuilder, mask, ipv4Address.getIpv4Address());
117                 matchBuilder.setLayer3Match(ipv4MatchBuilder.build());
118             }
119         }
120
121         return Optional.of(matchBuilder);
122     }
123 }