2 * Copyright (c) 2016, 2017 Brocade Communications Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.netvirt.sfc.translator.flowclassifier;
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;
44 * Class will convert OpenStack Flow Classifier API yang models to
45 * OpenDaylight ACL yang models.
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";
53 private FlowClassifierTranslator() { }
55 public static Acl buildAcl(SfcFlowClassifier flowClassifier) {
56 return buildAcl(flowClassifier, null);
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();
64 ActionsBuilder actionsBuilder = new ActionsBuilder();
65 RedirectToSfcBuilder redirectToSfcBuilder = new RedirectToSfcBuilder();
66 NeutronPortsBuilder neutronPortsBuilder = new NeutronPortsBuilder();
68 AceIpBuilder aceIpBuilder = new AceIpBuilder();
69 DestinationPortRangeBuilder destinationPortRange = new DestinationPortRangeBuilder();
70 SourcePortRangeBuilder sourcePortRangeBuilder = new SourcePortRangeBuilder();
72 if (flowClassifier.getUuid() != null) {
73 if (flowClassifier.getName() != null) {
74 aclBuilder.setAclName(flowClassifier.getUuid().getValue() + "_" + flowClassifier.getName());
76 aclBuilder.setAclName(flowClassifier.getUuid().getValue());
80 if (flowClassifier.getEthertype() != null) {
81 IpPrefix sourceIp = null;
82 IpPrefix destinationIp = null;
83 if (flowClassifier.getSourceIpPrefix() != null) {
84 sourceIp = flowClassifier.getSourceIpPrefix();
86 if (flowClassifier.getDestinationIpPrefix() != null) {
87 destinationIp = flowClassifier.getDestinationIpPrefix();
89 if (flowClassifier.getEthertype() == EthertypeV4.class) {
90 AceIpv4Builder aceIpv4Builder = new AceIpv4Builder();
91 if (sourceIp != null && sourceIp.getIpv4Prefix() != null) {
92 aceIpv4Builder.setSourceIpv4Network(sourceIp.getIpv4Prefix());
94 if (destinationIp != null && destinationIp.getIpv4Prefix() != null) {
95 aceIpv4Builder.setDestinationIpv4Network(destinationIp.getIpv4Prefix());
97 aceIpBuilder.setAceIpVersion(aceIpv4Builder.build());
98 aclBuilder.setAclType(Ipv4Acl.class);
100 if (flowClassifier.getEthertype() == EthertypeV6.class) {
101 AceIpv6Builder aceIpv6Builder = new AceIpv6Builder();
102 if (sourceIp != null && sourceIp.getIpv6Prefix() != null) {
103 aceIpv6Builder.setSourceIpv6Network(sourceIp.getIpv6Prefix());
105 if (destinationIp != null && destinationIp.getIpv6Prefix() != null) {
106 aceIpv6Builder.setDestinationIpv6Network(destinationIp.getIpv6Prefix());
108 aceIpBuilder.setAceIpVersion(aceIpv6Builder.build());
109 aclBuilder.setAclType(Ipv6Acl.class);
112 if (flowClassifier.getProtocol() != null) {
113 if (flowClassifier.getProtocol() == ProtocolTcp.class) {
114 aceIpBuilder.setProtocol(PROTO_TCP);
116 if (flowClassifier.getProtocol() == ProtocolUdp.class) {
117 aceIpBuilder.setProtocol(PROTO_UDP);
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());
125 if (flowClassifier.getSourcePortRangeMax() != null) {
126 sourcePortRangeBuilder.setUpperPort(new PortNumber(flowClassifier.getSourcePortRangeMax()));
127 aceIpBuilder.setSourcePortRange(sourcePortRangeBuilder.build());
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());
134 if (flowClassifier.getDestinationPortRangeMax() != null) {
135 destinationPortRange.setUpperPort(new PortNumber(flowClassifier.getDestinationPortRangeMax()));
136 aceIpBuilder.setDestinationPortRange(destinationPortRange.build());
138 if (flowClassifier.getLogicalSourcePort() != null) {
139 neutronPortsBuilder.setSourcePortUuid(flowClassifier.getLogicalSourcePort().getValue());
141 if (flowClassifier.getLogicalDestinationPort() != null) {
142 neutronPortsBuilder.setDestinationPortUuid(flowClassifier.getLogicalDestinationPort().getValue());
145 // currently not supported.
146 // if (flowClassifier.getL7Parameter() != null) {
149 MatchesBuilder matchesBuilder = new MatchesBuilder();
150 matchesBuilder.setAceType(aceIpBuilder.build());
151 matchesBuilder.addAugmentation(NeutronPorts.class, neutronPortsBuilder.build());
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());
159 aceBuilder.setMatches(matchesBuilder.build());
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
166 aceBuilder.setRuleName(aclBuilder.getAclName() + RULE);
167 aceBuilder.withKey(new AceKey(aceBuilder.getRuleName()));
169 ArrayList<Ace> aceList = new ArrayList<>();
170 aceList.add(aceBuilder.build());
171 AccessListEntriesBuilder accessListEntriesBuilder = new AccessListEntriesBuilder();
172 accessListEntriesBuilder.setAce(aceList);
174 aclBuilder.setAccessListEntries(accessListEntriesBuilder.build());
175 aclBuilder.withKey(new AclKey(aclBuilder.getAclName(),aclBuilder.getAclType()));
177 LOG.info("Translated ACL Flow classfier : {}", aclBuilder.toString());
179 return aclBuilder.build();