Revert "Bug 7775: Updated to use DataStoreJobCoordinator for flow programming"
[netvirt.git] / vpnservice / aclservice / impl / src / test / java / org / opendaylight / netvirt / aclservice / StatelessEgressAclServiceImplTest.java
1 /*
2  * Copyright © 2016, 2017 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 package org.opendaylight.netvirt.aclservice;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertTrue;
12 import static org.mockito.Matchers.any;
13 import static org.mockito.Mockito.doAnswer;
14 import static org.mockito.Mockito.doReturn;
15 import static org.mockito.Mockito.when;
16
17 import com.google.common.base.Optional;
18 import com.google.common.util.concurrent.Futures;
19 import java.math.BigInteger;
20 import java.util.Collections;
21 import org.junit.Before;
22 import org.junit.Test;
23 import org.junit.runner.RunWith;
24 import org.mockito.Mock;
25 import org.mockito.runners.MockitoJUnitRunner;
26 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
27 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
28 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
29 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
30 import org.opendaylight.genius.mdsalutil.FlowEntity;
31 import org.opendaylight.genius.mdsalutil.NwConstants;
32 import org.opendaylight.genius.mdsalutil.NxMatchFieldType;
33 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
34 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
35 import org.opendaylight.genius.mdsalutil.matches.MatchTcpFlags;
36 import org.opendaylight.netvirt.aclservice.api.utils.AclInterface;
37 import org.opendaylight.netvirt.aclservice.utils.AclDataUtil;
38 import org.opendaylight.netvirt.aclservice.utils.AclServiceTestUtils;
39 import org.opendaylight.netvirt.aclservice.utils.AclServiceUtils;
40 import org.opendaylight.netvirt.aclservice.utils.MethodInvocationParamSaver;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.Ipv4Acl;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.Acl;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.AclBuilder;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.AclKey;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.AccessListEntriesBuilder;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.AceBuilder;
47 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;
48 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;
49 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;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160218.acl.transport.header.fields.DestinationPortRangeBuilder;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.config.rev160806.AclserviceConfig;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionEgress;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.SecurityRuleAttr;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.SecurityRuleAttrBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairsBuilder;
62 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
63
64 @RunWith(MockitoJUnitRunner.class)
65 public class StatelessEgressAclServiceImplTest {
66
67     StatelessEgressAclServiceImpl testedService;
68
69     @Mock DataBroker dataBroker;
70     @Mock IMdsalApiManager mdsalManager;
71     @Mock WriteTransaction mockWriteTx;
72     @Mock ReadOnlyTransaction mockReadTx;
73     @Mock AclserviceConfig config;
74     @Mock IdManagerService idManager;
75
76     MethodInvocationParamSaver<Void> installFlowValueSaver = null;
77     MethodInvocationParamSaver<Void> removeFlowValueSaver = null;
78
79     @Before
80     public void setUp() {
81         AclDataUtil aclDataUtil = new AclDataUtil();
82         AclServiceUtils aclServiceUtils = new AclServiceUtils(aclDataUtil, config, idManager);
83         testedService = new StatelessEgressAclServiceImpl(dataBroker, mdsalManager, aclDataUtil, aclServiceUtils);
84         doReturn(Futures.immediateCheckedFuture(null)).when(mockWriteTx).submit();
85         doReturn(mockReadTx).when(dataBroker).newReadOnlyTransaction();
86         doReturn(mockWriteTx).when(dataBroker).newWriteOnlyTransaction();
87         installFlowValueSaver = new MethodInvocationParamSaver<>(null);
88         doAnswer(installFlowValueSaver).when(mdsalManager).installFlow(any(FlowEntity.class));
89         removeFlowValueSaver = new MethodInvocationParamSaver<>(null);
90         doAnswer(removeFlowValueSaver).when(mdsalManager).removeFlow(any(FlowEntity.class));
91     }
92
93     @Test
94     public void addAcl__NullInterface() {
95         assertEquals(false, testedService.applyAcl(null));
96     }
97
98     @Test
99     public void addAcl__MissingInterfaceStateShouldFail() throws Exception {
100         AclInterface ai = new AclInterface();
101         ai.setPortSecurityEnabled(true);
102         ai.setDpId(BigInteger.ONE);
103         assertEquals(false, testedService.applyAcl(ai));
104     }
105
106     @Test
107     public void addAcl__SinglePort() throws Exception {
108         Uuid sgUuid = new Uuid("12345678-1234-1234-1234-123456789012");
109         AclInterface ai = stubTcpAclInterface(sgUuid, "if_name", "1.1.1.1/32", 80, 80);
110         assertEquals(true, testedService.applyAcl(ai));
111         assertEquals(10, installFlowValueSaver.getNumOfInvocations());
112
113         FlowEntity firstRangeFlow = (FlowEntity) installFlowValueSaver.getInvocationParams(9).get(0);
114         AclServiceTestUtils.verifyMatchInfo(firstRangeFlow.getMatchInfoList(),
115                 NxMatchFieldType.nx_tcp_dst_with_mask, "80", "65535");
116         assertTrue(firstRangeFlow.getMatchInfoList().contains(new MatchTcpFlags(2)));
117         AclServiceTestUtils.verifyActionInfo(firstRangeFlow.getInstructionInfoList().get(0),
118                 new ActionNxResubmit(NwConstants.LPORT_DISPATCHER_TABLE));
119
120     }
121
122     @Test
123     public void addAcl__AllowAll() throws Exception {
124         Uuid sgUuid = new Uuid("12345678-1234-1234-1234-123456789012");
125         AclInterface ai = stubAllowAllInterface(sgUuid, "if_name");
126         assertEquals(true, testedService.applyAcl(ai));
127         assertEquals(10, installFlowValueSaver.getNumOfInvocations());
128
129         FlowEntity firstRangeFlow = (FlowEntity) installFlowValueSaver.getInvocationParams(9).get(0);
130         AclServiceTestUtils.verifyActionInfo(firstRangeFlow.getInstructionInfoList().get(0),
131                 new ActionNxResubmit(NwConstants.LPORT_DISPATCHER_TABLE));
132     }
133
134     @Test
135     public void addAcl__MultipleRanges() throws Exception {
136         Uuid sgUuid = new Uuid("12345678-1234-1234-1234-123456789012");
137         AclInterface ai = stubTcpAclInterface(sgUuid, "if_name", "1.1.1.1/32", 80, 84);
138         assertEquals(true, testedService.applyAcl(ai));
139         assertEquals(11, installFlowValueSaver.getNumOfInvocations());
140         FlowEntity firstRangeFlow = (FlowEntity) installFlowValueSaver.getInvocationParams(9).get(0);
141         AclServiceTestUtils.verifyMatchInfo(firstRangeFlow.getMatchInfoList(),
142                 NxMatchFieldType.nx_tcp_dst_with_mask, "80", "65532");
143         assertTrue(firstRangeFlow.getMatchInfoList().contains(new MatchTcpFlags(2)));
144
145         FlowEntity secondRangeFlow = (FlowEntity) installFlowValueSaver.getInvocationParams(10).get(0);
146         AclServiceTestUtils.verifyMatchInfo(secondRangeFlow.getMatchInfoList(),
147                 NxMatchFieldType.nx_tcp_dst_with_mask, "84", "65535");
148         assertTrue(secondRangeFlow.getMatchInfoList().contains(new MatchTcpFlags(2)));
149     }
150
151     @Test
152     public void addAcl__UdpSinglePortShouldNotCreateSynRule() throws Exception {
153         Uuid sgUuid = new Uuid("12345678-1234-1234-1234-123456789012");
154         AclInterface ai = stubUdpAclInterface(sgUuid, "if_name", "1.1.1.1/32", 80, 80);
155         assertEquals(true, testedService.applyAcl(ai));
156         assertEquals(9, installFlowValueSaver.getNumOfInvocations());
157     }
158
159     @Test
160     public void removeAcl__SinglePort() throws Exception {
161         Uuid sgUuid = new Uuid("12345678-1234-1234-1234-123456789012");
162         AclInterface ai = stubTcpAclInterface(sgUuid, "if_name", "1.1.1.1/32", 80, 80);
163         assertEquals(true, testedService.removeAcl(ai));
164         assertEquals(10, removeFlowValueSaver.getNumOfInvocations());
165         FlowEntity firstRangeFlow = (FlowEntity) removeFlowValueSaver.getInvocationParams(9).get(0);
166         assertTrue(firstRangeFlow.getMatchInfoList().contains(new MatchTcpFlags(2)));
167         AclServiceTestUtils.verifyMatchInfo(firstRangeFlow.getMatchInfoList(),
168                 NxMatchFieldType.nx_tcp_dst_with_mask, "80", "65535");
169
170     }
171
172     private AclInterface stubUdpAclInterface(Uuid sgUuid, String ifName, String ipv4PrefixStr,
173             int tcpPortLower, int tcpPortUpper) {
174         AclInterface ai = new AclInterface();
175         ai.setPortSecurityEnabled(true);
176         ai.setSecurityGroups(Collections.singletonList(sgUuid));
177         ai.setDpId(BigInteger.ONE);
178         ai.setLPortTag(2);
179         stubInterfaceAcl(ifName, ai);
180
181         stubAccessList(sgUuid, ipv4PrefixStr, tcpPortLower, tcpPortUpper, (short)NwConstants.IP_PROT_UDP);
182         return ai;
183     }
184
185     private AclInterface stubTcpAclInterface(Uuid sgUuid, String ifName, String ipv4PrefixStr,
186             int tcpPortLower, int tcpPortUpper) {
187         AclInterface ai = new AclInterface();
188         ai.setPortSecurityEnabled(true);
189         ai.setDpId(BigInteger.ONE);
190         ai.setLPortTag(2);
191         ai.setSecurityGroups(Collections.singletonList(sgUuid));
192         stubInterfaceAcl(ifName, ai);
193
194         stubAccessList(sgUuid, ipv4PrefixStr, tcpPortLower, tcpPortUpper, (short)NwConstants.IP_PROT_TCP);
195         return ai;
196     }
197
198     private AclInterface stubAllowAllInterface(Uuid sgUuid, String ifName) {
199         AclInterface ai = new AclInterface();
200         ai.setPortSecurityEnabled(true);
201         ai.setSecurityGroups(Collections.singletonList(sgUuid));
202         ai.setDpId(BigInteger.ONE);
203         ai.setLPortTag(2);
204         stubInterfaceAcl(ifName, ai);
205
206         stubAccessList(sgUuid, "0.0.0.0/0", -1, -1, (short)-1);
207         return ai;
208     }
209
210     private void stubInterfaceAcl(String ifName, AclInterface ai) {
211         AllowedAddressPairsBuilder aapb = new AllowedAddressPairsBuilder();
212         aapb.setIpAddress(new IpPrefixOrAddress("1.1.1.1/32".toCharArray()));
213         aapb.setMacAddress(new MacAddress("AA:BB:CC:DD:EE:FF"));
214         ai.setAllowedAddressPairs(Collections.singletonList(aapb.build()));
215     }
216
217     private void stubAccessList(Uuid sgUuid, String ipv4PrefixStr, int portLower, int portUpper, short protocol) {
218         AclBuilder ab = new AclBuilder();
219         ab.setAclName("AAA");
220         ab.setKey(new AclKey(sgUuid.getValue(),Ipv4Acl.class));
221
222         AceIpBuilder aceIpBuilder = new AceIpBuilder();
223         if (portLower != -1 && portUpper != -1) {
224             DestinationPortRangeBuilder dprb = new DestinationPortRangeBuilder();
225             dprb.setLowerPort(new PortNumber(portLower));
226             dprb.setUpperPort(new PortNumber(portUpper));
227             aceIpBuilder.setDestinationPortRange(dprb.build());
228         }
229         if (ipv4PrefixStr != null) {
230             AceIpv4Builder aceIpv4Builder = new AceIpv4Builder();
231             Ipv4Prefix ipv4Prefix = new Ipv4Prefix(ipv4PrefixStr);
232             aceIpv4Builder.setSourceIpv4Network(ipv4Prefix);
233             aceIpBuilder.setAceIpVersion(aceIpv4Builder.build());
234         }
235         if (protocol != -1) {
236             aceIpBuilder.setProtocol(protocol);
237         }
238         MatchesBuilder matches = new MatchesBuilder();
239         matches.setAceType(aceIpBuilder.build());
240         AceBuilder aceBuilder = new AceBuilder();
241         aceBuilder.setMatches(matches.build());
242         SecurityRuleAttrBuilder securityRuleAttrBuilder = new SecurityRuleAttrBuilder();
243         securityRuleAttrBuilder.setDirection(DirectionEgress.class);
244         aceBuilder.addAugmentation(SecurityRuleAttr.class, securityRuleAttrBuilder.build());
245         AccessListEntriesBuilder aleb = new AccessListEntriesBuilder();
246         aleb.setAce(Collections.singletonList(aceBuilder.build()));
247         ab.setAccessListEntries(aleb.build());
248
249         InstanceIdentifier<Acl> aclKey = AclServiceUtils.getAclInstanceIdentifier(sgUuid.getValue());
250         when(mockReadTx.read(LogicalDatastoreType.CONFIGURATION, aclKey))
251             .thenReturn(Futures.immediateCheckedFuture(Optional.of(ab.build())));
252     }
253 }