Bug 7730: Traffic drop in ACL during port update for AAP
[netvirt.git] / vpnservice / 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.util.Arrays;
14 import java.util.Collections;
15 import java.util.List;
16 import java.util.stream.Collectors;
17 import javax.inject.Inject;
18 import org.junit.Before;
19 import org.junit.Ignore;
20 import org.junit.Rule;
21 import org.junit.Test;
22 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
23 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
24 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
25 import org.opendaylight.genius.datastoreutils.testutils.AsyncEventsWaiter;
26 import org.opendaylight.genius.datastoreutils.testutils.JobCoordinatorEventsWaiter;
27 import org.opendaylight.genius.mdsalutil.FlowEntity;
28 import org.opendaylight.genius.mdsalutil.NwConstants;
29 import org.opendaylight.genius.mdsalutil.interfaces.testutils.TestIMdsalApiManager;
30 import org.opendaylight.infrautils.testutils.LogRule;
31 import org.opendaylight.netvirt.aclservice.tests.infra.DataBrokerPairsUtil;
32 import org.opendaylight.netvirt.aclservice.utils.AclConstants;
33 import org.opendaylight.netvirt.aclservice.utils.AclServiceTestUtils;
34 import org.opendaylight.netvirt.aclservice.utils.AclServiceUtils;
35 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;
36 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;
37 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;
38 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;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160218.acl.transport.header.fields.DestinationPortRangeBuilder;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionEgress;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionIngress;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairsBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceBuilder;
54 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
57
58 public abstract class AclServiceTestBase {
59     private static final Logger LOG = LoggerFactory.getLogger(AclServiceTestBase.class);
60
61     public @Rule LogRule logRule = new LogRule();
62
63     // public static @ClassRule RunUntilFailureClassRule classRepeater = new RunUntilFailureClassRule();
64     // public @Rule RunUntilFailureRule repeater = new RunUntilFailureRule(classRepeater);
65
66     static final String PORT_MAC_1 = "0D:AA:D8:42:30:F3";
67     static final String PORT_MAC_2 = "0D:AA:D8:42:30:F4";
68     static final String PORT_MAC_3 = "0D:AA:D8:42:30:F5";
69     static final String PORT_MAC_4 = "0D:AA:D8:42:30:F6";
70     static final String PORT_1 = "port1";
71     static final String PORT_2 = "port2";
72     static final String PORT_3 = "port3";
73     static final String PORT_4 = "port4";
74     static String SG_UUID = "85cc3048-abc3-43cc-89b3-377341426ac5";
75     static String SR_UUID_1 = "85cc3048-abc3-43cc-89b3-377341426ac6";
76     static String SR_UUID_2 = "85cc3048-abc3-43cc-89b3-377341426ac7";
77     static String SG_UUID_1 = "85cc3048-abc3-43cc-89b3-377341426ac5";
78     static String SG_UUID_2 = "85cc3048-abc3-43cc-89b3-377341426ac8";
79     static String SR_UUID_1_1 = "85cc3048-abc3-43cc-89b3-377341426ac6";
80     static String SR_UUID_1_2 = "85cc3048-abc3-43cc-89b3-377341426ac7";
81     static String SR_UUID_2_1 = "85cc3048-abc3-43cc-89b3-377341426a21";
82     static String SR_UUID_2_2 = "85cc3048-abc3-43cc-89b3-377341426a22";
83     static String ELAN = "elan1";
84     static String IP_PREFIX_1 = "10.0.0.1/32";
85     static String IP_PREFIX_2 = "10.0.0.2/32";
86     static String IP_PREFIX_3 = "10.0.0.3/32";
87     static String IP_PREFIX_4 = "10.0.0.4/32";
88     static long ELAN_TAG = 5000L;
89
90     static final AllowedAddressPairs AAP_PORT_1 = buildAap(IP_PREFIX_1, PORT_MAC_1);
91     static final AllowedAddressPairs AAP_PORT_2 = buildAap(IP_PREFIX_2, PORT_MAC_2);
92     static final AllowedAddressPairs AAP_PORT_3 = buildAap(IP_PREFIX_3, PORT_MAC_3);
93     static final AllowedAddressPairs AAP_PORT_4 = buildAap(IP_PREFIX_4, PORT_MAC_4);
94
95     @Inject DataBroker dataBroker;
96     @Inject DataBrokerPairsUtil dataBrokerUtil;
97     SingleTransactionDataBroker singleTransactionDataBroker;
98     @Inject TestIMdsalApiManager mdsalApiManager;
99     @Inject AsyncEventsWaiter asyncEventsWaiter;
100     @Inject JobCoordinatorEventsWaiter coordinatorEventsWaiter;
101
102     @Before
103     public void beforeEachTest() throws Exception {
104         singleTransactionDataBroker = new SingleTransactionDataBroker(dataBroker);
105         setUpData();
106     }
107
108     @Test
109     public void newInterface() throws Exception {
110         LOG.info("newInterface - start");
111
112         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1));
113         // Given
114         // putNewInterface(dataBroker, "port1", true, Collections.emptyList(), Collections.emptyList());
115         dataBrokerUtil.put(
116                 ImmutableIdentifiedInterfaceWithAclBuilder.builder().interfaceName("port1").portSecurity(true).build());
117
118         // When
119         putNewStateInterface(dataBroker, "port1", PORT_MAC_1);
120
121         AclServiceTestUtils.waitABit(asyncEventsWaiter);
122
123         // Then
124         newInterfaceCheck();
125         LOG.info("newInterface - end");
126     }
127
128     abstract void newInterfaceCheck();
129
130     @Test
131     public void newInterfaceWithEtherTypeAcl() throws Exception {
132         LOG.info("newInterfaceWithEtherTypeAcl - start");
133
134         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1));
135         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_2));
136
137         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
138                 AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, AclConstants.DEST_LOWER_PORT_UNSPECIFIED,
139                 AclConstants.DEST_UPPER_PORT_UNSPECIFIED, AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED,
140                 AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED, (short) -1);
141         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_1)
142                 .newMatches(matches).newDirection(DirectionEgress.class).build());
143         matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED, AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED,
144                 AclConstants.DEST_LOWER_PORT_UNSPECIFIED, AclConstants.DEST_UPPER_PORT_UNSPECIFIED,
145                 AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED, AclConstants.DEST_REMOTE_IP_PREFIX_UNSPECIFIED,
146                 (short) -1);
147         dataBrokerUtil.put(
148                 ImmutableIdentifiedAceBuilder.builder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_2).newMatches(matches)
149                         .newDirection(DirectionIngress.class).newRemoteGroupId(new Uuid(SG_UUID_1)).build());
150         // When
151         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
152         putNewStateInterface(dataBroker, PORT_2, PORT_MAC_2);
153
154         AclServiceTestUtils.waitABit(asyncEventsWaiter);
155
156         // Then
157         newInterfaceWithEtherTypeAclCheck();
158         LOG.info("newInterfaceWithEtherTypeAcl - end");
159     }
160
161     abstract void newInterfaceWithEtherTypeAclCheck();
162
163     @Test
164     public void newInterfaceWithTcpDstAcl() throws Exception {
165         LOG.info("newInterfaceWithTcpDstAcl - start");
166
167         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1));
168         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_2));
169
170         // Given
171         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
172                 AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, AclConstants.DEST_LOWER_PORT_HTTP,
173                 AclConstants.DEST_UPPER_PORT_HTTP, AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED,
174                 AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED, (short) NwConstants.IP_PROT_TCP);
175         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_1)
176                 .newMatches(matches).newDirection(DirectionEgress.class).newRemoteGroupId(new Uuid(SG_UUID_1)).build());
177         matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED, AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED,
178                 AclConstants.DEST_LOWER_PORT_HTTP, AclConstants.DEST_UPPER_PORT_HTTP,
179                 AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED, AclConstants.DEST_REMOTE_IP_PREFIX_UNSPECIFIED,
180                 (short) NwConstants.IP_PROT_TCP);
181
182         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_2)
183                 .newMatches(matches).newDirection(DirectionIngress.class).build());
184
185         // When
186         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
187         putNewStateInterface(dataBroker, PORT_2, PORT_MAC_2);
188
189         AclServiceTestUtils.waitABit(asyncEventsWaiter);
190
191         // Then
192         newInterfaceWithTcpDstAclCheck();
193         LOG.info("newInterfaceWithTcpDstAcl - end");
194     }
195
196     abstract void newInterfaceWithTcpDstAclCheck();
197
198     @Ignore
199     @Test
200     public void newInterfaceWithUdpDstAcl() throws Exception {
201         LOG.info("newInterfaceWithUdpDstAcl - start");
202
203         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1));
204         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_2));
205         // Given
206         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
207                 AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, AclConstants.DEST_LOWER_PORT_HTTP,
208                 AclConstants.DEST_UPPER_PORT_HTTP, AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED,
209                 AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED, (short) NwConstants.IP_PROT_UDP);
210         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_1)
211                 .newMatches(matches).newDirection(DirectionEgress.class).build());
212
213         matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED, AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED,
214                 AclConstants.DEST_LOWER_PORT_HTTP, AclConstants.DEST_UPPER_PORT_HTTP,
215                 AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED, AclConstants.DEST_REMOTE_IP_PREFIX_UNSPECIFIED,
216                 (short) NwConstants.IP_PROT_UDP);
217         dataBrokerUtil.put(
218                 ImmutableIdentifiedAceBuilder.builder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_2).newMatches(matches)
219                         .newDirection(DirectionIngress.class).newRemoteGroupId(new Uuid(SG_UUID_1)).build());
220
221         // When
222         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
223         putNewStateInterface(dataBroker, PORT_2, PORT_MAC_2);
224
225         AclServiceTestUtils.waitABit(asyncEventsWaiter);
226
227         // Then
228         newInterfaceWithUdpDstAclCheck();
229         LOG.info("newInterfaceWithUdpDstAcl - end");
230     }
231
232     abstract void newInterfaceWithUdpDstAclCheck();
233
234     @Test
235     public void newInterfaceWithIcmpAcl() throws Exception {
236         LOG.info("newInterfaceWithIcmpAcl - start");
237
238         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1));
239         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_2));
240         // Given
241         prepareInterfaceWithIcmpAcl();
242
243         // When
244         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
245         putNewStateInterface(dataBroker, PORT_2, PORT_MAC_2);
246
247         AclServiceTestUtils.waitABit(asyncEventsWaiter);
248
249         // Then
250         newInterfaceWithIcmpAclCheck();
251         LOG.info("newInterfaceWithIcmpAcl - end");
252     }
253
254     abstract void newInterfaceWithIcmpAclCheck();
255
256     @Test
257     public void newInterfaceWithDstPortRange() throws Exception {
258         LOG.info("newInterfaceWithDstPortRange - start");
259
260         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1));
261         // Given
262         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
263                 AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, 333, 777, AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED,
264                 AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED, (short) NwConstants.IP_PROT_TCP);
265         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_1)
266                 .newMatches(matches).newDirection(DirectionEgress.class).build());
267         matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED, AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, 2000,
268                 2003, AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED, AclConstants.DEST_REMOTE_IP_PREFIX_UNSPECIFIED,
269                 (short) NwConstants.IP_PROT_UDP);
270
271         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_2)
272                 .newMatches(matches).newDirection(DirectionIngress.class).build());
273
274         // When
275         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
276
277         AclServiceTestUtils.waitABit(asyncEventsWaiter);
278
279         // Then
280         newInterfaceWithDstPortRangeCheck();
281         LOG.info("newInterfaceWithDstPortRange - end");
282     }
283
284     abstract void newInterfaceWithDstPortRangeCheck();
285
286     @Test
287     public void newInterfaceWithDstAllPorts() throws Exception {
288         LOG.info("newInterfaceWithDstAllPorts - start");
289
290         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1));
291         // Given
292         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
293                 AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, 1, 65535, AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED,
294                 AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED, (short) NwConstants.IP_PROT_TCP);
295         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_1)
296                 .newMatches(matches).newDirection(DirectionEgress.class).build());
297         matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED, AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, 1,
298                 65535, AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED, AclConstants.DEST_REMOTE_IP_PREFIX_UNSPECIFIED,
299                 (short) NwConstants.IP_PROT_UDP);
300
301         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_2)
302                 .newMatches(matches).newDirection(DirectionIngress.class).build());
303
304         // When
305         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
306
307         AclServiceTestUtils.waitABit(asyncEventsWaiter);
308
309         // Then
310         newInterfaceWithDstAllPortsCheck();
311         LOG.info("newInterfaceWithDstAllPorts - end");
312     }
313
314     abstract void newInterfaceWithDstAllPortsCheck();
315
316     @Test
317     public void newInterfaceWithTwoAclsHavingSameRules() throws Exception {
318         LOG.info("newInterfaceWithTwoAclsHavingSameRules - start");
319
320         newAllowedAddressPair(PORT_3, Arrays.asList(SG_UUID_1, SG_UUID_2), Collections.singletonList(AAP_PORT_3));
321         // Given
322         Matches icmpEgressMatches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
323                 AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, AclConstants.DEST_LOWER_PORT_2,
324                 AclConstants.DEST_UPPER_PORT_3, AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED,
325                 AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED, (short) NwConstants.IP_PROT_ICMP);
326         Matches icmpIngressMatches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
327                 AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, AclConstants.DEST_LOWER_PORT_2,
328                 AclConstants.DEST_UPPER_PORT_3, AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED,
329                 AclConstants.DEST_REMOTE_IP_PREFIX_UNSPECIFIED, (short) NwConstants.IP_PROT_ICMP);
330
331         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_1)
332                 .newMatches(icmpEgressMatches).newDirection(DirectionEgress.class).build());
333
334         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_2)
335                 .newMatches(icmpIngressMatches).newDirection(DirectionIngress.class).build());
336
337         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder().sgUuid(SG_UUID_2).newRuleName(SR_UUID_2_1)
338                 .newMatches(icmpEgressMatches).newDirection(DirectionEgress.class).build());
339
340         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder().sgUuid(SG_UUID_2).newRuleName(SR_UUID_2_2)
341                 .newMatches(icmpIngressMatches).newDirection(DirectionIngress.class).build());
342
343         // When
344         putNewStateInterface(dataBroker, PORT_3, PORT_MAC_3);
345
346         AclServiceTestUtils.waitABit(asyncEventsWaiter);
347
348         // Then
349         newInterfaceWithTwoAclsHavingSameRulesCheck();
350         LOG.info("newInterfaceWithTwoAclsHavingSameRules - end");
351     }
352
353     abstract void newInterfaceWithTwoAclsHavingSameRulesCheck();
354
355     @Test
356     public void newInterfaceWithIcmpAclHavingOverlappingMac() throws Exception {
357         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1));
358         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_2));
359         // Given
360         prepareInterfaceWithIcmpAcl();
361
362         // When
363         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
364         putNewStateInterface(dataBroker, PORT_2, PORT_MAC_1);
365
366         AclServiceTestUtils.waitABit(asyncEventsWaiter);
367
368         // Then
369         newInterfaceWithIcmpAclCheck();
370     }
371
372     /**
373      * Test new interface with allowed-address-pair (AAP) having IP prefix 0.0.0.0/0.
374      * <p>
375      * FIXME: This TC works locally but is failing in Jenkins, hence disabling TC for now. This is related to ordering
376      * issue (with FlowEntity objects) with test infra (AssertDataObjects.assertEqualBeans) which needs to be fixed.
377      * </p>
378      *
379      * @throws Exception
380      *             the exception
381      */
382     @Test
383     @Ignore
384     public void newInterfaceWithAapIpv4All() throws Exception {
385         LOG.info("newInterfaceWithAapIpv4All test - start");
386
387         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1));
388         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1),
389                 Arrays.asList(AAP_PORT_2, buildAap(AclConstants.IPV4_ALL_NETWORK, PORT_MAC_2)));
390
391         prepareInterfaceWithIcmpAcl();
392         // When
393         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
394         putNewStateInterface(dataBroker, PORT_2, PORT_MAC_2);
395
396         AclServiceTestUtils.waitABit(asyncEventsWaiter);
397
398         // Then
399         newInterfaceWithAapIpv4AllCheck();
400         LOG.info("newInterfaceWithAapIpv4All test - end");
401     }
402
403     abstract void newInterfaceWithAapIpv4AllCheck();
404
405     @Test
406     public void newInterfaceWithAap() throws Exception {
407         LOG.info("newInterfaceWithAap test - start");
408
409         // AAP with same MAC and different IP
410         AllowedAddressPairs aapWithSameMac = buildAap("10.0.0.100/32", PORT_MAC_2);
411         // AAP with different MAC and different IP
412         AllowedAddressPairs aapWithDifferentMac = buildAap("10.0.0.101/32", "0D:AA:D8:42:30:A4");
413
414         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1));
415         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1),
416                 Arrays.asList(AAP_PORT_2, aapWithSameMac, aapWithDifferentMac));
417
418         prepareInterfaceWithIcmpAcl();
419         // When
420         putNewStateInterface(dataBroker, PORT_1, PORT_MAC_1);
421         putNewStateInterface(dataBroker, PORT_2, PORT_MAC_2);
422
423         asyncEventsWaiter.awaitEventsConsumption();
424
425         // Then
426         newInterfaceWithAapCheck();
427         LOG.info("newInterfaceWithAap test - end");
428     }
429
430     abstract void newInterfaceWithAapCheck();
431
432     protected void assertFlowsInAnyOrder(Iterable<FlowEntity> expectedFlows) {
433         asyncEventsWaiter.awaitEventsConsumption();
434         coordinatorEventsWaiter.awaitEventsConsumption();
435         mdsalApiManager.assertFlowsInAnyOrder(expectedFlows);
436     }
437
438     protected void prepareInterfaceWithIcmpAcl() throws TransactionCommitFailedException {
439         // Given
440         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
441                 AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, AclConstants.DEST_LOWER_PORT_2,
442                 AclConstants.DEST_UPPER_PORT_3, AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED,
443                 AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED, (short) NwConstants.IP_PROT_ICMP);
444         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_1)
445                 .newMatches(matches).newDirection(DirectionEgress.class).newRemoteGroupId(new Uuid(SG_UUID_1)).build());
446
447         matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED, AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED,
448                 AclConstants.DEST_LOWER_PORT_2, AclConstants.DEST_UPPER_PORT_3,
449                 AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED, AclConstants.DEST_REMOTE_IP_PREFIX_UNSPECIFIED,
450                 (short) NwConstants.IP_PROT_ICMP);
451         dataBrokerUtil.put(ImmutableIdentifiedAceBuilder.builder().sgUuid(SG_UUID_1).newRuleName(SR_UUID_1_2)
452                 .newMatches(matches).newDirection(DirectionIngress.class).build());
453     }
454
455     protected void newAllowedAddressPair(String portName, List<String> sgUuidList, List<AllowedAddressPairs> aapList)
456             throws TransactionCommitFailedException {
457         List<Uuid> sgList = sgUuidList.stream().map(Uuid::new).collect(Collectors.toList());
458
459         dataBrokerUtil.put(ImmutableIdentifiedInterfaceWithAclBuilder.builder().interfaceName(portName)
460                 .portSecurity(true).addAllNewSecurityGroups(sgList).addAllIfAllowedAddressPairs(aapList).build());
461     }
462
463     protected void newElan(String elanName, long elanId) throws TransactionCommitFailedException {
464         ElanInstance elan = new ElanInstanceBuilder().setElanInstanceName(elanName).setElanTag(5000L).build();
465         singleTransactionDataBroker.syncWrite(CONFIGURATION,
466                 AclServiceUtils.getElanInstanceConfigurationDataPath(elanName), elan);
467     }
468
469     protected void newElanInterface(String elanName, String portName, boolean isWrite)
470             throws TransactionCommitFailedException {
471         ElanInterface elanInterface =
472                 new ElanInterfaceBuilder().setName(portName).setElanInstanceName(elanName).build();
473         InstanceIdentifier<ElanInterface> id = AclServiceUtils.getElanInterfaceConfigurationDataPathId(portName);
474         if (isWrite) {
475             singleTransactionDataBroker.syncWrite(CONFIGURATION, id, elanInterface);
476         } else {
477             singleTransactionDataBroker.syncDelete(CONFIGURATION, id);
478         }
479     }
480
481     // TODO refactor this instead of stealing it from org.opendaylight.netvirt.neutronvpn.NeutronSecurityRuleListener
482     protected Matches newMatch(int srcLowerPort, int srcUpperPort, int destLowerPort, int destupperPort,
483             int srcRemoteIpPrefix, int dstRemoteIpPrefix, short protocol) {
484
485         AceIpBuilder aceIpBuilder = new AceIpBuilder();
486         if (destLowerPort != -1) {
487             DestinationPortRangeBuilder destinationPortRangeBuilder = new DestinationPortRangeBuilder();
488             destinationPortRangeBuilder.setLowerPort(new PortNumber(destLowerPort));
489             destinationPortRangeBuilder.setUpperPort(new PortNumber(destupperPort));
490             aceIpBuilder.setDestinationPortRange(destinationPortRangeBuilder.build());
491         }
492         AceIpv4Builder aceIpv4Builder = new AceIpv4Builder();
493         if (srcRemoteIpPrefix == AclConstants.SOURCE_REMOTE_IP_PREFIX_SPECIFIED) {
494             aceIpv4Builder.setSourceIpv4Network(new Ipv4Prefix(AclConstants.IPV4_ALL_NETWORK));
495         }
496         if (dstRemoteIpPrefix == AclConstants.DEST_REMOTE_IP_PREFIX_SPECIFIED) {
497             aceIpv4Builder.setSourceIpv4Network(new Ipv4Prefix(AclConstants.IPV4_ALL_NETWORK));
498         }
499         if (protocol != -1) {
500             aceIpBuilder.setProtocol(protocol);
501         }
502         aceIpBuilder.setAceIpVersion(aceIpv4Builder.build());
503
504         MatchesBuilder matchesBuilder = new MatchesBuilder();
505         matchesBuilder.setAceType(aceIpBuilder.build());
506         return matchesBuilder.build();
507     }
508
509     protected static AllowedAddressPairs buildAap(String ipAddress, String macAddress) {
510         return new AllowedAddressPairsBuilder()
511                 .setIpAddress(new IpPrefixOrAddress(new IpPrefix(ipAddress.toCharArray())))
512                 .setMacAddress(new MacAddress(macAddress)).build();
513     }
514
515     protected void setUpData() throws Exception {
516         newElan(ELAN, ELAN_TAG);
517         newElanInterface(ELAN, PORT_1, true);
518         newElanInterface(ELAN, PORT_2, true);
519         newElanInterface(ELAN, PORT_3, true);
520         newElanInterface(ELAN, PORT_4, true);
521     }
522
523 }