Switch to JDT annotations for Nullable and NonNull
[netvirt.git] / sfc / translator / src / main / java / org / opendaylight / netvirt / sfc / translator / flowclassifier / FlowClassifierTranslator.java
1 /*
2  * Copyright (c) 2016, 2017 Brocade Communications 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.netvirt.sfc.translator.flowclassifier;
10
11 import java.util.ArrayList;
12 import org.eclipse.jdt.annotation.Nullable;
13 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.Ipv4Acl;
14 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.Ipv6Acl;
15 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.Acl;
16 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.AclBuilder;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.AclKey;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.AccessListEntriesBuilder;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.Ace;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.AceBuilder;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.AceKey;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.ActionsBuilder;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.MatchesBuilder;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpBuilder;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4Builder;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv6Builder;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160218.acl.transport.header.fields.DestinationPortRangeBuilder;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160218.acl.transport.header.fields.SourcePortRangeBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.sfc.acl.rev150105.NeutronPorts;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.sfc.acl.rev150105.NeutronPortsBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.sfc.acl.rev150105.RedirectToSfc;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.sfc.acl.rev150105.RedirectToSfcBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeV4;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeV6;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolTcp;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolUdp;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.sfc.flow.classifier.rev160511.sfc.flow.classifiers.attributes.sfc.flow.classifiers.SfcFlowClassifier;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 /**
44  * Class will convert OpenStack Flow Classifier API yang models to
45  * OpenDaylight ACL yang models.
46  */
47 public final class FlowClassifierTranslator {
48     private static final Logger LOG = LoggerFactory.getLogger(FlowClassifierTranslator.class);
49     private static final Short PROTO_TCP = 6;
50     private static final Short PROTO_UDP = 17;
51     private static final String RULE = "_rule";
52
53     private FlowClassifierTranslator() { }
54
55     public static Acl buildAcl(SfcFlowClassifier flowClassifier) {
56         return buildAcl(flowClassifier, null);
57     }
58
59     public static Acl buildAcl(SfcFlowClassifier flowClassifier, @Nullable String sfpName) {
60         LOG.info("OpenStack Networking SFC pushed Flow classifier : {}", flowClassifier);
61         AclBuilder aclBuilder = new AclBuilder();
62         AceBuilder aceBuilder = new AceBuilder();
63
64         ActionsBuilder actionsBuilder = new ActionsBuilder();
65         RedirectToSfcBuilder redirectToSfcBuilder = new RedirectToSfcBuilder();
66         NeutronPortsBuilder neutronPortsBuilder = new NeutronPortsBuilder();
67
68         AceIpBuilder aceIpBuilder = new AceIpBuilder();
69         DestinationPortRangeBuilder destinationPortRange = new DestinationPortRangeBuilder();
70         SourcePortRangeBuilder sourcePortRangeBuilder = new SourcePortRangeBuilder();
71
72         if (flowClassifier.getUuid() != null) {
73             if (flowClassifier.getName() != null) {
74                 aclBuilder.setAclName(flowClassifier.getUuid().getValue() + "_" + flowClassifier.getName());
75             } else {
76                 aclBuilder.setAclName(flowClassifier.getUuid().getValue());
77             }
78
79         }
80         if (flowClassifier.getEthertype() != null) {
81             IpPrefix sourceIp = null;
82             IpPrefix destinationIp = null;
83             if (flowClassifier.getSourceIpPrefix() != null) {
84                 sourceIp = flowClassifier.getSourceIpPrefix();
85             }
86             if (flowClassifier.getDestinationIpPrefix() != null) {
87                 destinationIp = flowClassifier.getDestinationIpPrefix();
88             }
89             if (flowClassifier.getEthertype() == EthertypeV4.class) {
90                 AceIpv4Builder aceIpv4Builder = new AceIpv4Builder();
91                 if (sourceIp != null && sourceIp.getIpv4Prefix() != null) {
92                     aceIpv4Builder.setSourceIpv4Network(sourceIp.getIpv4Prefix());
93                 }
94                 if (destinationIp != null && destinationIp.getIpv4Prefix() != null) {
95                     aceIpv4Builder.setDestinationIpv4Network(destinationIp.getIpv4Prefix());
96                 }
97                 aceIpBuilder.setAceIpVersion(aceIpv4Builder.build());
98                 aclBuilder.setAclType(Ipv4Acl.class);
99             }
100             if (flowClassifier.getEthertype() == EthertypeV6.class) {
101                 AceIpv6Builder aceIpv6Builder = new AceIpv6Builder();
102                 if (sourceIp != null && sourceIp.getIpv6Prefix() != null) {
103                     aceIpv6Builder.setSourceIpv6Network(sourceIp.getIpv6Prefix());
104                 }
105                 if (destinationIp != null && destinationIp.getIpv6Prefix() != null) {
106                     aceIpv6Builder.setDestinationIpv6Network(destinationIp.getIpv6Prefix());
107                 }
108                 aceIpBuilder.setAceIpVersion(aceIpv6Builder.build());
109                 aclBuilder.setAclType(Ipv6Acl.class);
110             }
111         }
112         if (flowClassifier.getProtocol() != null) {
113             if (flowClassifier.getProtocol() == ProtocolTcp.class) {
114                 aceIpBuilder.setProtocol(PROTO_TCP);
115             }
116             if (flowClassifier.getProtocol() == ProtocolUdp.class) {
117                 aceIpBuilder.setProtocol(PROTO_UDP);
118             }
119         }
120         if (flowClassifier.getSourcePortRangeMin() != null) {
121             sourcePortRangeBuilder.setLowerPort(new PortNumber(flowClassifier.getSourcePortRangeMin()));
122             // set source port range only if lower port is specified as it is a mandatory parameter in acl model
123             aceIpBuilder.setSourcePortRange(sourcePortRangeBuilder.build());
124         }
125         if (flowClassifier.getSourcePortRangeMax() != null) {
126             sourcePortRangeBuilder.setUpperPort(new PortNumber(flowClassifier.getSourcePortRangeMax()));
127             aceIpBuilder.setSourcePortRange(sourcePortRangeBuilder.build());
128         }
129         if (flowClassifier.getDestinationPortRangeMin() != null) {
130             destinationPortRange.setLowerPort(new PortNumber(flowClassifier.getDestinationPortRangeMin()));
131             // set destination port range only if lower port is specified as it is a mandatory parameter in acl model
132             aceIpBuilder.setDestinationPortRange(destinationPortRange.build());
133         }
134         if (flowClassifier.getDestinationPortRangeMax() != null) {
135             destinationPortRange.setUpperPort(new PortNumber(flowClassifier.getDestinationPortRangeMax()));
136             aceIpBuilder.setDestinationPortRange(destinationPortRange.build());
137         }
138         if (flowClassifier.getLogicalSourcePort() != null) {
139             neutronPortsBuilder.setSourcePortUuid(flowClassifier.getLogicalSourcePort().getValue());
140         }
141         if (flowClassifier.getLogicalDestinationPort() != null) {
142             neutronPortsBuilder.setDestinationPortUuid(flowClassifier.getLogicalDestinationPort().getValue());
143         }
144
145         // currently not supported.
146 //        if (flowClassifier.getL7Parameter() != null) {
147 //        }
148
149         MatchesBuilder matchesBuilder = new MatchesBuilder();
150         matchesBuilder.setAceType(aceIpBuilder.build());
151         matchesBuilder.addAugmentation(NeutronPorts.class, neutronPortsBuilder.build());
152
153         //Set redirect-to-rsp action if rsp name is provided
154         if (sfpName != null) {
155             redirectToSfcBuilder.setSfpName(sfpName);
156             actionsBuilder.addAugmentation(RedirectToSfc.class, redirectToSfcBuilder.build());
157             aceBuilder.setActions(actionsBuilder.build());
158         }
159         aceBuilder.setMatches(matchesBuilder.build());
160
161         //OpenStack networking-sfc don't pass action information
162         //with flow classifier. It need to be determined using the
163         //Port Chain data and then flow calssifier need to be updated
164         //with the actions.
165
166         aceBuilder.setRuleName(aclBuilder.getAclName() + RULE);
167         aceBuilder.withKey(new AceKey(aceBuilder.getRuleName()));
168
169         ArrayList<Ace> aceList = new ArrayList<>();
170         aceList.add(aceBuilder.build());
171         AccessListEntriesBuilder accessListEntriesBuilder = new AccessListEntriesBuilder();
172         accessListEntriesBuilder.setAce(aceList);
173
174         aclBuilder.setAccessListEntries(accessListEntriesBuilder.build());
175         aclBuilder.withKey(new AclKey(aclBuilder.getAclName(),aclBuilder.getAclType()));
176
177         LOG.info("Translated ACL Flow classfier : {}", aclBuilder.toString());
178
179         return aclBuilder.build();
180     }
181 }