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