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.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;
43 * Class will convert OpenStack Flow Classifier API yang models to
44 * OpenDaylight ACL yang models.
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";
52 private FlowClassifierTranslator() { }
54 public static Acl buildAcl(SfcFlowClassifier flowClassifier) {
55 return buildAcl(flowClassifier, null);
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();
63 ActionsBuilder actionsBuilder = new ActionsBuilder();
64 RedirectToSfcBuilder redirectToSfcBuilder = new RedirectToSfcBuilder();
65 NeutronPortsBuilder neutronPortsBuilder = new NeutronPortsBuilder();
67 AceIpBuilder aceIpBuilder = new AceIpBuilder();
68 DestinationPortRangeBuilder destinationPortRange = new DestinationPortRangeBuilder();
69 SourcePortRangeBuilder sourcePortRangeBuilder = new SourcePortRangeBuilder();
71 if (flowClassifier.getUuid() != null) {
72 if (flowClassifier.getName() != null) {
73 aclBuilder.setAclName(flowClassifier.getUuid().getValue() + "_" + flowClassifier.getName());
75 aclBuilder.setAclName(flowClassifier.getUuid().getValue());
79 if (flowClassifier.getEthertype() != null) {
80 IpPrefix sourceIp = null;
81 IpPrefix destinationIp = null;
82 if (flowClassifier.getSourceIpPrefix() != null) {
83 sourceIp = flowClassifier.getSourceIpPrefix();
85 if (flowClassifier.getDestinationIpPrefix() != null) {
86 destinationIp = flowClassifier.getDestinationIpPrefix();
88 if (flowClassifier.getEthertype() == EthertypeV4.class) {
89 AceIpv4Builder aceIpv4Builder = new AceIpv4Builder();
90 if (sourceIp != null && sourceIp.getIpv4Prefix() != null) {
91 aceIpv4Builder.setSourceIpv4Network(sourceIp.getIpv4Prefix());
93 if (destinationIp != null && destinationIp.getIpv4Prefix() != null) {
94 aceIpv4Builder.setDestinationIpv4Network(destinationIp.getIpv4Prefix());
96 aceIpBuilder.setAceIpVersion(aceIpv4Builder.build());
97 aclBuilder.setAclType(Ipv4Acl.class);
99 if (flowClassifier.getEthertype() == EthertypeV6.class) {
100 AceIpv6Builder aceIpv6Builder = new AceIpv6Builder();
101 if (sourceIp != null && sourceIp.getIpv6Prefix() != null) {
102 aceIpv6Builder.setSourceIpv6Network(sourceIp.getIpv6Prefix());
104 if (sourceIp != null && destinationIp.getIpv6Prefix() != null) {
105 aceIpv6Builder.setDestinationIpv6Network(destinationIp.getIpv6Prefix());
107 aceIpBuilder.setAceIpVersion(aceIpv6Builder.build());
108 aclBuilder.setAclType(Ipv6Acl.class);
111 if (flowClassifier.getProtocol() != null) {
112 if (flowClassifier.getProtocol() == ProtocolTcp.class) {
113 aceIpBuilder.setProtocol(PROTO_TCP);
115 if (flowClassifier.getProtocol() == ProtocolUdp.class) {
116 aceIpBuilder.setProtocol(PROTO_UDP);
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());
124 if (flowClassifier.getSourcePortRangeMax() != null) {
125 sourcePortRangeBuilder.setUpperPort(new PortNumber(flowClassifier.getSourcePortRangeMax()));
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());
132 if (flowClassifier.getDestinationPortRangeMax() != null) {
133 destinationPortRange.setUpperPort(new PortNumber(flowClassifier.getDestinationPortRangeMax()));
135 if (flowClassifier.getLogicalSourcePort() != null) {
136 neutronPortsBuilder.setSourcePortUuid(flowClassifier.getLogicalSourcePort().getValue());
138 if (flowClassifier.getLogicalDestinationPort() != null) {
139 neutronPortsBuilder.setDestinationPortUuid(flowClassifier.getLogicalDestinationPort().getValue());
142 // currently not supported.
143 // if (flowClassifier.getL7Parameter() != null) {
146 MatchesBuilder matchesBuilder = new MatchesBuilder();
147 matchesBuilder.setAceType(aceIpBuilder.build());
148 matchesBuilder.addAugmentation(NeutronPorts.class, neutronPortsBuilder.build());
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());
156 aceBuilder.setMatches(matchesBuilder.build());
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
163 aceBuilder.setRuleName(aclBuilder.getAclName() + RULE);
164 aceBuilder.setKey(new AceKey(aceBuilder.getRuleName()));
166 ArrayList<Ace> aceList = new ArrayList<>();
167 aceList.add(aceBuilder.build());
168 AccessListEntriesBuilder accessListEntriesBuilder = new AccessListEntriesBuilder();
169 accessListEntriesBuilder.setAce(aceList);
171 aclBuilder.setAccessListEntries(accessListEntriesBuilder.build());
172 aclBuilder.setKey(new AclKey(aclBuilder.getAclName(),aclBuilder.getAclType()));
174 LOG.info("Translated ACL Flow classfier : {}", aclBuilder.toString());
176 return aclBuilder.build();