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