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