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