Bug 4996 - Wrong flows when using SFC coexistence
[netvirt.git] / openstack / net-virt-sfc / impl / src / main / java / org / opendaylight / ovsdb / openstack / netvirt / sfc / workaround / services / AclMatches.java
1 /*
2  * Copyright © 2016 Red Hat, 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.ovsdb.openstack.netvirt.sfc.workaround.services;
10
11 import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
12 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.Matches;
13 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.AceEth;
14 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIp;
15 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4;
16 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv6;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21
22 public class AclMatches {
23     private static final Logger LOG = LoggerFactory.getLogger(AclMatches.class);
24     MatchBuilder matchBuilder;
25     Matches matches;
26
27     public AclMatches(Matches matches) {
28         matchBuilder = new MatchBuilder();
29         this.matches = matches;
30     }
31
32     /**
33      * Convert the ACL into an OpenFlow {@link MatchBuilder}
34      * @return {@link MatchBuilder}
35      */
36     //TODO: Matches will overwrite previous matches for ethernet and ip since these methods
37     // can be called successively for the same ACL.
38     // This requires fixing the MatchUtils to preserve previously set fields.
39     protected MatchBuilder buildMatch() {
40         if (matches.getAceType() instanceof AceEth) {
41             addEthMatch();
42         } else if (matches.getAceType() instanceof AceIp) {
43             addIpMatch();
44         }
45
46         LOG.info("buildMatch: {}", matchBuilder.build());
47         return matchBuilder;
48     }
49
50     private void addEthMatch() {
51         AceEth aceEth = (AceEth) matches.getAceType();
52         MatchUtils.createEthSrcDstMatch(matchBuilder, aceEth.getSourceMacAddress(),
53                 aceEth.getDestinationMacAddress());
54     }
55
56     private void addIpMatch() {
57         AceIp aceIp = (AceIp)matches.getAceType();
58
59         if (aceIp.getDscp() != null) {
60             MatchUtils.addDscp(matchBuilder, aceIp.getDscp().getValue());
61         }
62
63         if (aceIp.getProtocol() != null) {
64             addIpProtocolMatch(aceIp);
65         }
66
67         if (aceIp.getAceIpVersion() instanceof AceIpv4) {
68             addIpV4Match(aceIp);
69         }
70
71         if (aceIp.getAceIpVersion() instanceof AceIpv6) {
72             addIpV6Match(aceIp);
73         }
74     }
75
76     private void addIpProtocolMatch(AceIp aceIp) {
77         int srcPort = 0;
78         int dstPort = 0;
79
80         // TODO Ranges are not supported yet
81         if (aceIp.getSourcePortRange() != null && aceIp.getSourcePortRange().getLowerPort() != null) {
82             srcPort = aceIp.getSourcePortRange().getLowerPort().getValue();
83         }
84         if (aceIp.getDestinationPortRange() != null && aceIp.getDestinationPortRange().getLowerPort() != null) {
85             dstPort = aceIp.getDestinationPortRange().getLowerPort().getValue();
86         }
87         MatchUtils.createIpProtocolMatch(matchBuilder, aceIp.getProtocol());
88         MatchUtils.addLayer4Match(matchBuilder, aceIp.getProtocol().intValue(), srcPort, dstPort);
89     }
90
91     private void addIpV4Match(AceIp aceIp) {
92         AceIpv4 aceIpv4 = (AceIpv4)aceIp.getAceIpVersion();
93
94         MatchUtils.createEtherTypeMatch(matchBuilder, new EtherType(MatchUtils.ETHERTYPE_IPV4));
95         matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder, aceIpv4.getSourceIpv4Network(),
96                 aceIpv4.getDestinationIpv4Network());
97     }
98
99     private void addIpV6Match(AceIp aceIp) {
100         AceIpv6 aceIpv6 = (AceIpv6)aceIp.getAceIpVersion();
101
102         MatchUtils.createEtherTypeMatch(matchBuilder, new EtherType(MatchUtils.ETHERTYPE_IPV6));
103         matchBuilder = MatchUtils.addRemoteIpv6Prefix(matchBuilder, aceIpv6.getSourceIpv6Network(),
104                 aceIpv6.getDestinationIpv6Network());
105     }
106 }