60747e5513f9a21f3698b8ce4ab058ed1188ed14
[groupbasedpolicy.git] / renderers / ofoverlay / src / test / java / org / opendaylight / groupbasedpolicy / renderer / ofoverlay / flow / PortSecurityTest.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, 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
9 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
10
11 import java.util.Collections;
12 import java.util.HashMap;
13 import java.util.List;
14 import java.util.Objects;
15 import java.util.Set;
16
17 import org.junit.Before;
18 import org.junit.Test;
19 import org.mockito.ArgumentCaptor;
20 import org.mockito.Matchers;
21 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowTable.FlowCtx;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatch;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6Match;
37 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 import com.google.common.collect.ImmutableList;
42 import com.google.common.collect.ImmutableSet;
43
44 import static org.junit.Assert.*;
45
46 import static org.mockito.Matchers.*;
47
48 import static org.mockito.Mockito.*;
49
50 public class PortSecurityTest extends FlowTableTest {
51     protected static final Logger LOG =
52             LoggerFactory.getLogger(PortSecurityTest.class);
53
54     @Override
55     @Before
56     public void setup() throws Exception {
57         initCtx();
58         table = new PortSecurity(ctx);
59         super.setup();
60     }
61
62     @Test
63     public void testDefaultDeny() throws Exception {
64         ReadWriteTransaction t = dosync(null);
65         ArgumentCaptor<Flow> ac = ArgumentCaptor.forClass(Flow.class);
66         verify(t, times(4)).put(eq(LogicalDatastoreType.CONFIGURATION),
67                                 Matchers.<InstanceIdentifier<Flow>>any(),
68                                 ac.capture(), anyBoolean());
69         int count = 0;
70
71         HashMap<String, FlowCtx> flowMap = new HashMap<>();
72         for (Flow f : ac.getAllValues()) {
73             flowMap.put(f.getId().getValue(), new FlowCtx(f));
74             Long etherType = null;
75             if (f.getMatch() != null) {
76                 etherType = f.getMatch().getEthernetMatch()
77                         .getEthernetType().getType().getValue();
78             }
79             if (f.getMatch() == null ||
80                 FlowUtils.ARP.equals(etherType) ||
81                 FlowUtils.IPv4.equals(etherType) ||
82                 FlowUtils.IPv6.equals(etherType)) {
83                 count += 1;
84                 assertEquals(FlowUtils.dropInstructions(),
85                              f.getInstructions());
86             }
87         }
88         assertEquals(4, count);
89         t = dosync(flowMap);
90         verify(t, never()).put(any(LogicalDatastoreType.class),
91                                Matchers.<InstanceIdentifier<Flow>>any(),
92                                any(Flow.class), anyBoolean());
93     }
94
95     @Test
96     public void testNonLocalAllow() throws Exception {
97         switchManager
98             .addSwitch(new NodeId("openflow:1"),
99                        new NodeConnectorId("openflow:1:1"),
100                        ImmutableSet.of(new NodeConnectorId("openflow:1:2")),
101                        null);
102
103         ReadWriteTransaction t = dosync(null);
104         ArgumentCaptor<Flow> ac = ArgumentCaptor.forClass(Flow.class);
105         verify(t, atLeastOnce()).put(eq(LogicalDatastoreType.CONFIGURATION),
106                                      Matchers.<InstanceIdentifier<Flow>>any(),
107                                      ac.capture(), anyBoolean());
108
109         int count = 0;
110         HashMap<String, FlowCtx> flowMap = new HashMap<>();
111         Set<String> ncs = ImmutableSet.of("openflow:1:1", "openflow:1:2");
112         for (Flow f : ac.getAllValues()) {
113             flowMap.put(f.getId().getValue(), new FlowCtx(f));
114             if (f.getMatch() != null && f.getMatch().getInPort() != null &&
115                 ncs.contains(f.getMatch().getInPort().getValue())) {
116                 assertEquals(f.getInstructions(),
117                              FlowUtils.gotoTableInstructions((short)(table.getTableId()+1)));
118                 count += 1;
119             }
120         }
121         assertEquals(2, count);
122
123         t = dosync(flowMap);
124         verify(t, never()).put(any(LogicalDatastoreType.class),
125                                Matchers.<InstanceIdentifier<Flow>>any(),
126                                any(Flow.class), anyBoolean());
127     }
128
129     @Test
130     public void testL2() throws Exception {
131         List<L3Address> l3 = Collections.emptyList();
132         Endpoint ep = localEP()
133             .setL3Address(l3)
134             .build();
135
136         endpointManager.addEndpoint(ep);
137
138         ReadWriteTransaction t = dosync(null);
139         ArgumentCaptor<Flow> ac = ArgumentCaptor.forClass(Flow.class);
140         verify(t, atLeastOnce()).put(eq(LogicalDatastoreType.CONFIGURATION),
141                                      Matchers.<InstanceIdentifier<Flow>>any(),
142                                      ac.capture(), anyBoolean());
143
144         int count = 0;
145         HashMap<String, FlowCtx> flowMap = new HashMap<>();
146         for (Flow f : ac.getAllValues()) {
147             flowMap.put(f.getId().getValue(), new FlowCtx(f));
148             if (f.getMatch() != null &&
149                 f.getMatch().getEthernetMatch() != null &&
150                 f.getMatch().getEthernetMatch().getEthernetSource() != null &&
151                 Objects.equals(ep.getMacAddress(),
152                                f.getMatch().getEthernetMatch()
153                                    .getEthernetSource().getAddress()) &&
154                 Objects.equals(ep.getAugmentation(OfOverlayContext.class).getNodeConnectorId(),
155                                f.getMatch().getInPort())) {
156                 count += 1;
157                 assertEquals(FlowUtils.gotoTableInstructions((short)(table.getTableId()+1)),
158                              f.getInstructions());
159             }
160         }
161         assertEquals(2, count);
162         t = dosync(flowMap);
163         verify(t, never()).put(any(LogicalDatastoreType.class),
164                                Matchers.<InstanceIdentifier<Flow>>any(),
165                                any(Flow.class), anyBoolean());
166     }
167
168     @Test
169     public void testL3() throws Exception {
170         Endpoint ep = localEP()
171             .setL3Address(ImmutableList.of(new L3AddressBuilder()
172                 .setIpAddress(new IpAddress(new Ipv4Address("10.10.10.10")))
173                 .build(),
174                 new L3AddressBuilder()
175                 .setIpAddress(new IpAddress(new Ipv6Address("2001:db8:85a3::8a2e:370:7334")))
176                 .build()))
177             .build();
178
179         endpointManager.addEndpoint(ep);
180
181         ReadWriteTransaction t = dosync(null);
182         ArgumentCaptor<Flow> ac = ArgumentCaptor.forClass(Flow.class);
183         verify(t, atLeastOnce()).put(eq(LogicalDatastoreType.CONFIGURATION),
184                                      Matchers.<InstanceIdentifier<Flow>>any(),
185                                      ac.capture(), anyBoolean());
186
187         int count = 0;
188         HashMap<String, FlowCtx> flowMap = new HashMap<>();
189         for (Flow f : ac.getAllValues()) {
190             flowMap.put(f.getId().getValue(), new FlowCtx(f));
191             if (f.getMatch() != null &&
192                 Objects.equals(ep.getAugmentation(OfOverlayContext.class).getNodeConnectorId(),
193                                f.getMatch().getInPort()) &&
194                 ((f.getMatch().getLayer3Match() != null &&
195                   f.getMatch().getLayer3Match() instanceof Ipv4Match &&
196                   ((Ipv4Match)f.getMatch().getLayer3Match()).getIpv4Source() != null &&
197                   Objects.equals(ep.getL3Address().get(0).getIpAddress().getIpv4Address().getValue(),
198                           ((Ipv4Match)f.getMatch().getLayer3Match()).getIpv4Source().getValue().split("/")[0])) ||
199                  (f.getMatch().getLayer3Match() != null &&
200                          f.getMatch().getLayer3Match() instanceof Ipv4Match &&
201                          ((Ipv4Match)f.getMatch().getLayer3Match()).getIpv4Destination() != null &&
202                   Objects.equals("255.255.255.255",
203                           ((Ipv4Match)f.getMatch().getLayer3Match()).getIpv4Destination().getValue().split("/")[0]))     ||
204                  (f.getMatch().getLayer3Match() != null &&
205                   f.getMatch().getLayer3Match() instanceof ArpMatch &&
206                   Objects.equals(ep.getL3Address().get(0).getIpAddress().getIpv4Address().getValue(),
207                                  ((ArpMatch)f.getMatch().getLayer3Match()).getArpSourceTransportAddress().getValue().split("/")[0])) ||
208                  (f.getMatch().getLayer3Match() != null &&
209                   f.getMatch().getLayer3Match() instanceof Ipv6Match &&
210                   Objects.equals(ep.getL3Address().get(1).getIpAddress().getIpv6Address().getValue(),
211                                  ((Ipv6Match)f.getMatch().getLayer3Match()).getIpv6Source().getValue().split("/")[0])))) {
212                 count += 1;
213                 assertEquals(FlowUtils.gotoTableInstructions((short)(table.getTableId()+1)),
214                              f.getInstructions());
215             }
216         }
217         assertEquals(4, count);
218         t = dosync(flowMap);
219         verify(t, never()).put(any(LogicalDatastoreType.class),
220                                Matchers.<InstanceIdentifier<Flow>>any(),
221                                any(Flow.class), anyBoolean());
222     }
223 }