25a2607cc58ca46cc84d93ae7dd1ff6bb2722738
[netvirt.git] / aclservice / impl / src / test / java / org / opendaylight / netvirt / aclservice / tests / AclServiceTestBase.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.tests;
9
10 import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
11 import static org.opendaylight.netvirt.aclservice.tests.StateInterfaceBuilderHelper.putNewStateInterface;
12
13 import java.math.BigInteger;
14 import java.util.ArrayList;
15 import java.util.Arrays;
16 import java.util.Collections;
17 import java.util.List;
18 import java.util.stream.Collectors;
19 import javax.inject.Inject;
20 import org.eclipse.xtext.xbase.lib.Pair;
21 import org.junit.Before;
22 import org.junit.Rule;
23 import org.junit.Test;
24 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
25 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
26 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
27 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
28 import org.opendaylight.genius.datastoreutils.testutils.AsyncEventsWaiter;
29 import org.opendaylight.genius.datastoreutils.testutils.JobCoordinatorEventsWaiter;
30 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
31 import org.opendaylight.genius.mdsalutil.FlowEntity;
32 import org.opendaylight.genius.mdsalutil.NwConstants;
33 import org.opendaylight.genius.mdsalutil.interfaces.testutils.TestIMdsalApiManager;
34 import org.opendaylight.genius.testutils.TestInterfaceManager;
35 import org.opendaylight.infrautils.testutils.LogCaptureRule;
36 import org.opendaylight.infrautils.testutils.LogRule;
37 import org.opendaylight.netvirt.aclservice.tests.infra.DataBrokerPairsUtil;
38 import org.opendaylight.netvirt.aclservice.utils.AclConstants;
39 import org.opendaylight.netvirt.aclservice.utils.AclServiceUtils;
40 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;
41 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;
42 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;
43 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;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160218.acl.transport.header.fields.DestinationPortRangeBuilder;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionEgress;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionIngress;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddressBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpVersionBase;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpVersionV4;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairsBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.SubnetInfo;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.SubnetInfoBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.SubnetInfoKey;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceBuilder;
67 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
68 import org.opendaylight.yangtools.yang.common.Uint64;
69 import org.slf4j.Logger;
70 import org.slf4j.LoggerFactory;
71
72 public abstract class AclServiceTestBase {
73     private static final Logger LOG = LoggerFactory.getLogger(AclServiceTestBase.class);
74
75     public @Rule LogRule logRule = new LogRule();
76     public @Rule LogCaptureRule logCaptureRule = new LogCaptureRule();
77
78     // public static @ClassRule RunUntilFailureClassRule classRepeater = new RunUntilFailureClassRule();
79     // public @Rule RunUntilFailureRule repeater = new RunUntilFailureRule(classRepeater);
80
81     static final String PORT_MAC_1 = "0D:AA:D8:42:30:F3";
82     static final String PORT_MAC_2 = "0D:AA:D8:42:30:F4";
83     static final String PORT_MAC_3 = "0D:AA:D8:42:30:F5";
84     static final String PORT_MAC_4 = "0D:AA:D8:42:30:F6";
85     static final String PORT_1 = "port1";
86     static final String PORT_2 = "port2";
87     static final String PORT_3 = "port3";
88     static final String PORT_4 = "port4";
89     static String SG_UUID = "85cc3048-abc3-43cc-89b3-377341426ac5";
90     static String SR_UUID_1 = "85cc3048-abc3-43cc-89b3-377341426ac6";
91     static String SR_UUID_2 = "85cc3048-abc3-43cc-89b3-377341426ac7";
92     static String SG_UUID_1 = "85cc3048-abc3-43cc-89b3-377341426ac5";
93     static String SG_UUID_2 = "85cc3048-abc3-43cc-89b3-377341426ac8";
94     static String SR_UUID_1_1 = "85cc3048-abc3-43cc-89b3-377341426ac6";
95     static String SR_UUID_1_2 = "85cc3048-abc3-43cc-89b3-377341426ac7";
96     static String SR_UUID_2_1 = "85cc3048-abc3-43cc-89b3-377341426a21";
97     static String SR_UUID_2_2 = "85cc3048-abc3-43cc-89b3-377341426a22";
98     static String ELAN = "elan1";
99     static String IP_PREFIX_1 = "10.0.0.1/32";
100     static String IP_PREFIX_2 = "10.0.0.2/32";
101     static String IP_PREFIX_3 = "10.0.0.3/32";
102     static String IP_PREFIX_4 = "10.0.0.4/32";
103     static String IP_100_PREFIX = "10.0.0.100/32";
104     static String IP_101_PREFIX = "10.0.0.101/32";
105     static long ELAN_TAG = 5000L;
106
107     static String SUBNET_IP_PREFIX_1 = "10.0.0.0/24";
108     static Uuid SUBNET_ID_1 = new Uuid("39add98b-63b7-42e6-8368-ff807eee165e");
109     static SubnetInfo SUBNET_INFO_1 = buildSubnetInfo(SUBNET_ID_1, SUBNET_IP_PREFIX_1, IpVersionV4.class, "10.0.0.1");
110
111     static AllowedAddressPairs AAP_PORT_1;
112     static AllowedAddressPairs AAP_PORT_2;
113     static AllowedAddressPairs AAP_PORT_3;
114     static AllowedAddressPairs AAP_PORT_4;
115     static AllowedAddressPairs AAP_PORT_100;
116     static AllowedAddressPairs AAP_PORT_101;
117
118     @Inject DataBroker dataBroker;
119     @Inject DataBrokerPairsUtil dataBrokerUtil;
120     SingleTransactionDataBroker singleTransactionDataBroker;
121     @Inject TestIMdsalApiManager mdsalApiManager;
122     @Inject AsyncEventsWaiter asyncEventsWaiter;
123     @Inject JobCoordinatorEventsWaiter coordinatorEventsWaiter;
124     @Inject TestInterfaceManager testInterfaceManager;
125
126     @Before
127     public void beforeEachTest() throws Exception {
128         singleTransactionDataBroker = new SingleTransactionDataBroker(dataBroker);
129         setUpData();
130     }
131
132     private InterfaceInfo newInterfaceInfo(String testInterfaceName) {
133         InterfaceInfo interfaceInfo = new InterfaceInfo(Uint64.valueOf(BigInteger.valueOf(789)), "port1");
134         interfaceInfo.setInterfaceName(testInterfaceName);
135         return interfaceInfo;
136     }
137
138     @Test
139     public void newInterface() throws Exception {
140         LOG.info("newInterface - start");
141
142         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1),
143                 Collections.singletonList(SUBNET_INFO_1));
144         testInterfaceManager.addInterfaceInfo(newInterfaceInfo("port1"));
145
146         // When
147         putNewStateInterface(dataBroker, "port1", PORT_MAC_1);
148
149         asyncEventsWaiter.awaitEventsConsumption();
150
151         // Then
152         newInterfaceCheck();
153         LOG.info("newInterface - end");
154     }
155
156     abstract void newInterfaceCheck();
157
158     @Test
159     public void newInterfaceWithEtherTypeAcl() throws Exception {
160         LOG.info("newInterfaceWithEtherTypeAcl - start");
161
162         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1),
163                 Collections.singletonList(SUBNET_INFO_1));
164         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_2),
165                 Collections.singletonList(SUBNET_INFO_1));
166
167         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
168                 AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, AclConstants.DEST_LOWER_PORT_UNSPECIFIED,
169                 AclConstants.DEST_UPPER_PORT_UNSPECIFIED, AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED,
170                 AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED, (short) -1);
171         dataBrokerUtil.put(new IdentifiedAceBuilder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_1)
172                 .newMatches(matches).newDirection(DirectionEgress.class).build());
173         matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED, AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED,
174                 AclConstants.DEST_LOWER_PORT_UNSPECIFIED, AclConstants.DEST_UPPER_PORT_UNSPECIFIED,
175                 AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED, AclConstants.DEST_REMOTE_IP_PREFIX_UNSPECIFIED,
176                 (short) -1);
177         dataBrokerUtil.put(
178                 new IdentifiedAceBuilder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_2).newMatches(matches)
179                         .newDirection(DirectionIngress.class).newRemoteGroupId(new Uuid(SG_UUID_1)).build());
180         // When
181         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
182         putNewStateInterface(dataBroker, PORT_2, PORT_MAC_2);
183
184         asyncEventsWaiter.awaitEventsConsumption();
185
186         // Then
187         newInterfaceWithEtherTypeAclCheck();
188         LOG.info("newInterfaceWithEtherTypeAcl - end");
189     }
190
191     abstract void newInterfaceWithEtherTypeAclCheck();
192
193     @Test
194     public void newInterfaceWithMultipleAcl() throws Exception {
195         LOG.info("newInterfaceWithEtherTypeAcl - start");
196
197         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1),
198                 Collections.singletonList(SUBNET_INFO_1));
199         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_2),
200                 Collections.singletonList(SUBNET_INFO_1));
201
202         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
203                 AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, AclConstants.DEST_LOWER_PORT_UNSPECIFIED,
204                 AclConstants.DEST_UPPER_PORT_UNSPECIFIED, AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED,
205                 AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED, (short) -1);
206         dataBrokerUtil.put(new IdentifiedAceBuilder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_1)
207                 .newMatches(matches).newDirection(DirectionEgress.class).build());
208         matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED, AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED,
209                 AclConstants.DEST_LOWER_PORT_UNSPECIFIED, AclConstants.DEST_UPPER_PORT_UNSPECIFIED,
210                 AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED, AclConstants.DEST_REMOTE_IP_PREFIX_UNSPECIFIED,
211                 (short) -1);
212         dataBrokerUtil.put(
213                 new IdentifiedAceBuilder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_2).newMatches(matches)
214                         .newDirection(DirectionIngress.class).newRemoteGroupId(new Uuid(SG_UUID_1)).build());
215         // When
216         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
217         putNewStateInterface(dataBroker, PORT_2, PORT_MAC_2);
218
219         asyncEventsWaiter.awaitEventsConsumption();
220
221         // Then
222         newInterfaceWithEtherTypeAclCheck();
223
224         LOG.info("newInterfaceWithEtherTypeAcl - end");
225
226         // Given
227         matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
228                 AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, AclConstants.DEST_LOWER_PORT_HTTP,
229                 AclConstants.DEST_UPPER_PORT_HTTP, AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED,
230                 AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED, (short) NwConstants.IP_PROT_TCP);
231         dataBrokerUtil.put(new IdentifiedAceBuilder().sgUuid(SG_UUID_2).newRuleName(SR_UUID_2_1)
232                 .newMatches(matches).newDirection(DirectionEgress.class).newRemoteGroupId(new Uuid(SG_UUID_2)).build());
233         matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED, AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED,
234                 AclConstants.DEST_LOWER_PORT_HTTP, AclConstants.DEST_UPPER_PORT_HTTP,
235                 AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED, AclConstants.DEST_REMOTE_IP_PREFIX_UNSPECIFIED,
236                 (short) NwConstants.IP_PROT_TCP);
237
238         dataBrokerUtil.put(new IdentifiedAceBuilder().sgUuid(SG_UUID_2).newRuleName(SR_UUID_2_2)
239                 .newMatches(matches).newDirection(DirectionIngress.class).build());
240         List<String> sgList = new ArrayList<>();
241         sgList.add(SG_UUID_1);
242         sgList.add(SG_UUID_2);
243         newAllowedAddressPair(PORT_1, sgList, Collections.singletonList(AAP_PORT_1),
244                 Collections.singletonList(SUBNET_INFO_1));
245         newAllowedAddressPair(PORT_2, sgList, Collections.singletonList(AAP_PORT_2),
246                 Collections.singletonList(SUBNET_INFO_1));
247
248         asyncEventsWaiter.awaitEventsConsumption();
249         newInterfaceWithMultipleAclCheck();
250     }
251
252     abstract void newInterfaceWithMultipleAclCheck();
253
254     @Test
255     public void newInterfaceWithTcpDstAcl() throws Exception {
256         LOG.info("newInterfaceWithTcpDstAcl - start");
257
258         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1),
259                 Collections.singletonList(SUBNET_INFO_1));
260         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_2),
261                 Collections.singletonList(SUBNET_INFO_1));
262
263         // Given
264         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
265                 AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, AclConstants.DEST_LOWER_PORT_HTTP,
266                 AclConstants.DEST_UPPER_PORT_HTTP, AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED,
267                 AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED, (short) NwConstants.IP_PROT_TCP);
268         dataBrokerUtil.put(new IdentifiedAceBuilder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_1)
269                 .newMatches(matches).newDirection(DirectionEgress.class).newRemoteGroupId(new Uuid(SG_UUID_1)).build());
270         matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED, AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED,
271                 AclConstants.DEST_LOWER_PORT_HTTP, AclConstants.DEST_UPPER_PORT_HTTP,
272                 AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED, AclConstants.DEST_REMOTE_IP_PREFIX_UNSPECIFIED,
273                 (short) NwConstants.IP_PROT_TCP);
274
275         dataBrokerUtil.put(new IdentifiedAceBuilder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_2)
276                 .newMatches(matches).newDirection(DirectionIngress.class).build());
277
278         // When
279         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
280         putNewStateInterface(dataBroker, PORT_2, PORT_MAC_2);
281
282         asyncEventsWaiter.awaitEventsConsumption();
283
284         // Then
285         newInterfaceWithTcpDstAclCheck();
286         LOG.info("newInterfaceWithTcpDstAcl - end");
287     }
288
289     abstract void newInterfaceWithTcpDstAclCheck();
290
291     @Test
292     public void newInterfaceWithUdpDstAcl() throws Exception {
293         LOG.info("newInterfaceWithUdpDstAcl - start");
294
295         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1),
296                 Collections.singletonList(SUBNET_INFO_1));
297         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_2),
298                 Collections.singletonList(SUBNET_INFO_1));
299
300         // Given
301         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
302                 AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, AclConstants.DEST_LOWER_PORT_HTTP,
303                 AclConstants.DEST_UPPER_PORT_HTTP, AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED,
304                 AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED, (short) NwConstants.IP_PROT_UDP);
305         dataBrokerUtil.put(new IdentifiedAceBuilder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_1)
306                 .newMatches(matches).newDirection(DirectionEgress.class).build());
307
308         matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED, AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED,
309                 AclConstants.DEST_LOWER_PORT_HTTP, AclConstants.DEST_UPPER_PORT_HTTP,
310                 AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED, AclConstants.DEST_REMOTE_IP_PREFIX_UNSPECIFIED,
311                 (short) NwConstants.IP_PROT_UDP);
312         dataBrokerUtil.put(
313                 new IdentifiedAceBuilder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_2).newMatches(matches)
314                         .newDirection(DirectionIngress.class).newRemoteGroupId(new Uuid(SG_UUID_1)).build());
315
316         // When
317         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
318         putNewStateInterface(dataBroker, PORT_2, PORT_MAC_2);
319
320         asyncEventsWaiter.awaitEventsConsumption();
321
322         // Then
323         newInterfaceWithUdpDstAclCheck();
324         LOG.info("newInterfaceWithUdpDstAcl - end");
325     }
326
327     abstract void newInterfaceWithUdpDstAclCheck();
328
329     @Test
330     public void newInterfaceWithIcmpAcl() throws Exception {
331         LOG.info("newInterfaceWithIcmpAcl - start");
332
333         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1),
334                 Collections.singletonList(SUBNET_INFO_1));
335         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_2),
336                 Collections.singletonList(SUBNET_INFO_1));
337         // Given
338         prepareInterfaceWithIcmpAcl();
339
340         // When
341         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
342         putNewStateInterface(dataBroker, PORT_2, PORT_MAC_2);
343
344         asyncEventsWaiter.awaitEventsConsumption();
345
346         // Then
347         newInterfaceWithIcmpAclCheck();
348         LOG.info("newInterfaceWithIcmpAcl - end");
349     }
350
351     abstract void newInterfaceWithIcmpAclCheck();
352
353     @Test
354     public void newInterfaceWithDstPortRange() throws Exception {
355         LOG.info("newInterfaceWithDstPortRange - start");
356
357         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1),
358                 Collections.singletonList(SUBNET_INFO_1));
359         // Given
360         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
361                 AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, 333, 777, AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED,
362                 AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED, (short) NwConstants.IP_PROT_TCP);
363         dataBrokerUtil.put(new IdentifiedAceBuilder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_1)
364                 .newMatches(matches).newDirection(DirectionEgress.class).build());
365         matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED, AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, 2000,
366                 2003, AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED, AclConstants.DEST_REMOTE_IP_PREFIX_UNSPECIFIED,
367                 (short) NwConstants.IP_PROT_UDP);
368
369         dataBrokerUtil.put(new IdentifiedAceBuilder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_2)
370                 .newMatches(matches).newDirection(DirectionIngress.class).build());
371
372         // When
373         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
374
375         asyncEventsWaiter.awaitEventsConsumption();
376
377         // Then
378         newInterfaceWithDstPortRangeCheck();
379         LOG.info("newInterfaceWithDstPortRange - end");
380     }
381
382     abstract void newInterfaceWithDstPortRangeCheck();
383
384     @Test
385     public void newInterfaceWithDstAllPorts() throws Exception {
386         LOG.info("newInterfaceWithDstAllPorts - start");
387
388         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1),
389                 Collections.singletonList(SUBNET_INFO_1));
390         // Given
391         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
392                 AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, 1, 65535, AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED,
393                 AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED, (short) NwConstants.IP_PROT_TCP);
394         dataBrokerUtil.put(new IdentifiedAceBuilder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_1)
395                 .newMatches(matches).newDirection(DirectionEgress.class).build());
396         matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED, AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, 1,
397                 65535, AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED, AclConstants.DEST_REMOTE_IP_PREFIX_UNSPECIFIED,
398                 (short) NwConstants.IP_PROT_UDP);
399
400         dataBrokerUtil.put(new IdentifiedAceBuilder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_2)
401                 .newMatches(matches).newDirection(DirectionIngress.class).build());
402
403         // When
404         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
405
406         asyncEventsWaiter.awaitEventsConsumption();
407
408         // Then
409         newInterfaceWithDstAllPortsCheck();
410         LOG.info("newInterfaceWithDstAllPorts - end");
411     }
412
413     abstract void newInterfaceWithDstAllPortsCheck();
414
415     @Test
416     public void newInterfaceWithTwoAclsHavingSameRules() throws Exception {
417         LOG.info("newInterfaceWithTwoAclsHavingSameRules - start");
418
419         newAllowedAddressPair(PORT_3, Arrays.asList(SG_UUID_1, SG_UUID_2), Collections.singletonList(AAP_PORT_3),
420                 Collections.singletonList(SUBNET_INFO_1));
421         // Given
422         Matches icmpEgressMatches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
423                 AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, AclConstants.DEST_LOWER_PORT_2,
424                 AclConstants.DEST_UPPER_PORT_3, AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED,
425                 AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED, (short) NwConstants.IP_PROT_ICMP);
426         Matches icmpIngressMatches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
427                 AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, AclConstants.DEST_LOWER_PORT_2,
428                 AclConstants.DEST_UPPER_PORT_3, AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED,
429                 AclConstants.DEST_REMOTE_IP_PREFIX_UNSPECIFIED, (short) NwConstants.IP_PROT_ICMP);
430
431         dataBrokerUtil.put(new IdentifiedAceBuilder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_1)
432                 .newMatches(icmpEgressMatches).newDirection(DirectionEgress.class).build());
433
434         dataBrokerUtil.put(new IdentifiedAceBuilder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_2)
435                 .newMatches(icmpIngressMatches).newDirection(DirectionIngress.class).build());
436
437         dataBrokerUtil.put(new IdentifiedAceBuilder().sgUuid(SG_UUID_2).newRuleName(SR_UUID_2_1)
438                 .newMatches(icmpEgressMatches).newDirection(DirectionEgress.class).build());
439
440         dataBrokerUtil.put(new IdentifiedAceBuilder().sgUuid(SG_UUID_2).newRuleName(SR_UUID_2_2)
441                 .newMatches(icmpIngressMatches).newDirection(DirectionIngress.class).build());
442
443         // When
444         putNewStateInterface(dataBroker, PORT_3, PORT_MAC_3);
445
446         asyncEventsWaiter.awaitEventsConsumption();
447
448         // Then
449         newInterfaceWithTwoAclsHavingSameRulesCheck();
450         LOG.info("newInterfaceWithTwoAclsHavingSameRules - end");
451     }
452
453     abstract void newInterfaceWithTwoAclsHavingSameRulesCheck();
454
455     @Test
456     public void newInterfaceWithIcmpAclHavingOverlappingMac() throws Exception {
457         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1),
458                 Collections.singletonList(SUBNET_INFO_1));
459         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_2),
460                 Collections.singletonList(SUBNET_INFO_1));
461         // Given
462         prepareInterfaceWithIcmpAcl();
463
464         // When
465         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
466         putNewStateInterface(dataBroker, PORT_2, PORT_MAC_1);
467
468         asyncEventsWaiter.awaitEventsConsumption();
469
470         // Then
471         newInterfaceWithIcmpAclCheck();
472     }
473
474     @Test
475     public void newInterfaceWithAapIpv4All() throws Exception {
476         LOG.info("newInterfaceWithAapIpv4All test - start");
477         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1),
478                 Collections.singletonList(SUBNET_INFO_1));
479         List<AllowedAddressPairs> aapList = new ArrayList<>();
480         aapList.add(AAP_PORT_2);
481         aapList.add(buildAap("0.0.0.0/0", PORT_MAC_2));
482         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1), aapList,
483                 Collections.singletonList(SUBNET_INFO_1));
484
485         prepareInterfaceWithIcmpAcl();
486         // When
487         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
488         putNewStateInterface(dataBroker, PORT_2, PORT_MAC_2);
489
490         asyncEventsWaiter.awaitEventsConsumption();
491
492         // Then
493         newInterfaceWithAapIpv4AllCheck();
494         LOG.info("newInterfaceWithAapIpv4All test - end");
495     }
496
497     abstract void newInterfaceWithAapIpv4AllCheck();
498
499     @Test
500     public void newInterfaceWithAap() throws Exception {
501         LOG.info("newInterfaceWithAap test - start");
502
503         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1),
504                 Collections.singletonList(SUBNET_INFO_1));
505         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1),
506                 Arrays.asList(AAP_PORT_2, AAP_PORT_100, AAP_PORT_101), Collections.singletonList(SUBNET_INFO_1));
507
508         prepareInterfaceWithIcmpAcl();
509         // When
510         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
511         putNewStateInterface(dataBroker, PORT_2, PORT_MAC_2);
512
513         asyncEventsWaiter.awaitEventsConsumption();
514
515         // Then
516         newInterfaceWithAapCheck();
517         LOG.info("newInterfaceWithAap test - end");
518     }
519
520     abstract void newInterfaceWithAapCheck();
521
522     protected void assertFlowsInAnyOrder(Iterable<FlowEntity> expectedFlows) {
523         coordinatorEventsWaiter.awaitEventsConsumption();
524         asyncEventsWaiter.awaitEventsConsumption();
525         mdsalApiManager.assertFlowsInAnyOrder(expectedFlows);
526     }
527
528     protected void prepareInterfaceWithIcmpAcl() throws TransactionCommitFailedException {
529         // Given
530         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
531                 AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, AclConstants.DEST_LOWER_PORT_2,
532                 AclConstants.DEST_UPPER_PORT_3, AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED,
533                 AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED, (short) NwConstants.IP_PROT_ICMP);
534         dataBrokerUtil.put(new IdentifiedAceBuilder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_1)
535                 .newMatches(matches).newDirection(DirectionEgress.class).newRemoteGroupId(new Uuid(SG_UUID_1)).build());
536
537         matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED, AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED,
538                 AclConstants.DEST_LOWER_PORT_2, AclConstants.DEST_UPPER_PORT_3,
539                 AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED, AclConstants.DEST_REMOTE_IP_PREFIX_UNSPECIFIED,
540                 (short) NwConstants.IP_PROT_ICMP);
541         dataBrokerUtil.put(new IdentifiedAceBuilder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_2)
542                 .newMatches(matches).newDirection(DirectionIngress.class).build());
543     }
544
545     protected void newAllowedAddressPair(String portName, List<String> sgUuidList, List<AllowedAddressPairs> aapList,
546             List<SubnetInfo> subnetInfo)
547             throws TransactionCommitFailedException {
548         List<Uuid> sgList = sgUuidList.stream().map(Uuid::new).collect(Collectors.toList());
549         Pair<DataTreeIdentifier<Interface>, Interface> port = new IdentifiedInterfaceWithAclBuilder()
550                 .interfaceName(portName)
551                 .portSecurity(true)
552                 .addAllNewSecurityGroups(sgList)
553                 .addAllIfAllowedAddressPairs(aapList)
554                 .addAllIfSubnetInfo(subnetInfo).build();
555         dataBrokerUtil.put(port);
556         testInterfaceManager.addInterface(port.getValue());
557     }
558
559     protected void newElan(String elanName, long elanId) throws TransactionCommitFailedException {
560         ElanInstance elan = new ElanInstanceBuilder().setElanInstanceName(elanName).setElanTag(5000L).build();
561         singleTransactionDataBroker.syncWrite(CONFIGURATION,
562                 AclServiceUtils.getElanInstanceConfigurationDataPath(elanName), elan);
563     }
564
565     protected void newElanInterface(String elanName, String portName, boolean isWrite)
566             throws TransactionCommitFailedException {
567         ElanInterface elanInterface =
568                 new ElanInterfaceBuilder().setName(portName).setElanInstanceName(elanName).build();
569         InstanceIdentifier<ElanInterface> id = AclServiceUtils.getElanInterfaceConfigurationDataPathId(portName);
570         if (isWrite) {
571             singleTransactionDataBroker.syncWrite(CONFIGURATION, id, elanInterface);
572         } else {
573             singleTransactionDataBroker.syncDelete(CONFIGURATION, id);
574         }
575     }
576
577     // TODO refactor this instead of stealing it from org.opendaylight.netvirt.neutronvpn.NeutronSecurityRuleListener
578     protected Matches newMatch(int srcLowerPort, int srcUpperPort, int destLowerPort, int destupperPort,
579             int srcRemoteIpPrefix, int dstRemoteIpPrefix, short protocol) {
580
581         AceIpBuilder aceIpBuilder = new AceIpBuilder();
582         if (destLowerPort != -1) {
583             DestinationPortRangeBuilder destinationPortRangeBuilder = new DestinationPortRangeBuilder();
584             destinationPortRangeBuilder.setLowerPort(new PortNumber(destLowerPort));
585             destinationPortRangeBuilder.setUpperPort(new PortNumber(destupperPort));
586             aceIpBuilder.setDestinationPortRange(destinationPortRangeBuilder.build());
587         }
588         AceIpv4Builder aceIpv4Builder = new AceIpv4Builder();
589         if (srcRemoteIpPrefix == AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED) {
590             aceIpv4Builder.setSourceIpv4Network(new Ipv4Prefix(AclConstants.IPV4_ALL_NETWORK));
591         }
592         if (dstRemoteIpPrefix == AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED) {
593             aceIpv4Builder.setSourceIpv4Network(new Ipv4Prefix(AclConstants.IPV4_ALL_NETWORK));
594         }
595         if (protocol != -1) {
596             aceIpBuilder.setProtocol(protocol);
597         }
598         aceIpBuilder.setAceIpVersion(aceIpv4Builder.build());
599
600         MatchesBuilder matchesBuilder = new MatchesBuilder();
601         matchesBuilder.setAceType(aceIpBuilder.build());
602         return matchesBuilder.build();
603     }
604
605     protected static AllowedAddressPairs buildAap(String ipAddress, String macAddress) {
606         return new AllowedAddressPairsBuilder()
607                 .setIpAddress(new IpPrefixOrAddress(IpPrefixBuilder.getDefaultInstance(ipAddress)))
608                 .setMacAddress(new MacAddress(macAddress)).build();
609     }
610
611     protected static SubnetInfo buildSubnetInfo(Uuid subnetId, String ipPrefix,
612             Class<? extends IpVersionBase> ipVersion, String gwIp) {
613         return new SubnetInfoBuilder().withKey(new SubnetInfoKey(subnetId)).setIpVersion(ipVersion)
614                 .setIpPrefix(IpPrefixOrAddressBuilder.getDefaultInstance(ipPrefix))
615                 .setGatewayIp(IpAddressBuilder.getDefaultInstance(gwIp)).build();
616     }
617
618     protected void setUpData() throws Exception {
619         newElan(ELAN, ELAN_TAG);
620         newElanInterface(ELAN, PORT_1, true);
621         newElanInterface(ELAN, PORT_2, true);
622         newElanInterface(ELAN, PORT_3, true);
623         newElanInterface(ELAN, PORT_4, true);
624
625         AAP_PORT_1 = buildAap(IP_PREFIX_1, PORT_MAC_1);
626         AAP_PORT_2 = buildAap(IP_PREFIX_2, PORT_MAC_2);
627         AAP_PORT_3 = buildAap(IP_PREFIX_3, PORT_MAC_3);
628         AAP_PORT_4 = buildAap(IP_PREFIX_4, PORT_MAC_4);
629         AAP_PORT_100 = buildAap(IP_100_PREFIX, PORT_MAC_2);
630         AAP_PORT_101 = buildAap(IP_101_PREFIX, "0D:AA:D8:42:30:A4");
631     }
632
633 }