a84bc3506212362a67e4e177a7a0625aa8b2edc0
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / sal / convertor / match / NxmExtensionsConvertor.java
1 /*
2  * Copyright (C) 2014 Red Hat, Inc.
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;
10
11 import com.google.common.base.Splitter;
12 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
13 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv4AddressMatchEntry;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv4AddressMatchEntryBuilder;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaskMatchEntry;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaskMatchEntryBuilder;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TcpFlagMatchEntry;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TcpFlagMatchEntryBuilder;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.MatchField;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Nxm1Class;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.TcpFlag;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntries;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntriesBuilder;
25
26 import java.util.Iterator;
27
28 /**
29  * Temporary extension conversions until extension are supported in MD_SAL OpenFlow v1.3 implementations
30  */
31 public class NxmExtensionsConvertor {
32     static final Splitter PREFIX_SPLITTER = Splitter.on('/');
33
34     static MatchEntries toNxmTcpFlag(Integer tcpFlag) {
35         MatchEntriesBuilder matchBuilder = new MatchEntriesBuilder();
36         matchBuilder.setOxmClass(Nxm1Class.class);
37         matchBuilder.setHasMask(false);
38         matchBuilder.setOxmMatchField(TcpFlag.class);
39         TcpFlagMatchEntryBuilder tcpFlagBuilder = new TcpFlagMatchEntryBuilder();
40         tcpFlagBuilder.setTcpFlag(tcpFlag);
41         matchBuilder.addAugmentation(TcpFlagMatchEntry.class, tcpFlagBuilder.build());
42         return matchBuilder.build();
43     }
44
45     public static MatchEntries toNxmIpv4Tunnel(Class<? extends MatchField> field, Ipv4Prefix ipv4Prefix) {
46         MatchEntriesBuilder matchEntriesBuilder = new MatchEntriesBuilder();
47         matchEntriesBuilder.setOxmClass(Nxm1Class.class);
48         matchEntriesBuilder.setOxmMatchField(field);
49         boolean hasMask = addNxmIpv4PrefixAugmentation(matchEntriesBuilder, ipv4Prefix);
50         matchEntriesBuilder.setHasMask(hasMask);
51         return matchEntriesBuilder.build();
52     }
53
54     static void addNxmMaskAugmentation(final MatchEntriesBuilder builder, final byte[] mask) {
55         MaskMatchEntryBuilder maskBuilder = new MaskMatchEntryBuilder();
56         maskBuilder.setMask(mask);
57         builder.addAugmentation(MaskMatchEntry.class, maskBuilder.build());
58     }
59
60     /**
61      * @return true if Ipv4Prefix contains prefix (and it is used in mask),
62      *         false otherwise
63      */
64     static boolean addNxmIpv4PrefixAugmentation(final MatchEntriesBuilder builder, final Ipv4Prefix address) {
65         boolean hasMask = false;
66         Iterator<String> addressParts = PREFIX_SPLITTER.split(address.getValue()).iterator();
67         Ipv4Address ipv4Address = new Ipv4Address(addressParts.next());
68
69         final int prefix;
70         if (addressParts.hasNext()) {
71             prefix = Integer.parseInt(addressParts.next());
72         } else {
73             prefix = 0;
74         }
75
76         Ipv4AddressMatchEntryBuilder ipv4AddressBuilder = new Ipv4AddressMatchEntryBuilder();
77         ipv4AddressBuilder.setIpv4Address(ipv4Address);
78         builder.addAugmentation(Ipv4AddressMatchEntry.class, ipv4AddressBuilder.build());
79         if (prefix != 0) {
80             int mask = 0xffffffff << (32 - prefix);
81             byte[] maskBytes = new byte[] { (byte) (mask >>> 24), (byte) (mask >>> 16), (byte) (mask >>> 8),
82                     (byte) mask };
83             addNxmMaskAugmentation(builder, maskBytes);
84             hasMask = true;
85         }
86         return hasMask;
87     }
88 }