2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
\r
4 * This program and the accompanying materials are made available under the
\r
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
\r
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
\r
9 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
\r
11 import com.google.common.collect.ImmutableList;
\r
12 import com.google.common.collect.ImmutableMap;
\r
13 import org.junit.Before;
\r
14 import org.junit.Test;
\r
15 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
\r
16 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;
\r
17 import org.opendaylight.groupbasedpolicy.resolver.ConditionGroup;
\r
18 import org.opendaylight.groupbasedpolicy.resolver.EgKey;
\r
19 import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
\r
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
\r
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
\r
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
\r
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
\r
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
\r
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
\r
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
\r
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName;
\r
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClauseName;
\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionMatcherName;
\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayNodeConfigBuilder;
\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.nodes.node.TunnelBuilder;
\r
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
\r
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Matcher.MatchType;
\r
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.action.refs.ActionRefBuilder;
\r
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;
\r
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.condition.matchers.ConditionMatcherBuilder;
\r
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.conditions.Condition;
\r
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.conditions.ConditionBuilder;
\r
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantBuilder;
\r
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Contract;
\r
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ContractBuilder;
\r
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.ClauseBuilder;
\r
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Subject;
\r
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ConsumerMatchersBuilder;
\r
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ProviderMatchersBuilder;
\r
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.Rule;
\r
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.RuleBuilder;
\r
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
\r
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;
\r
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
\r
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;
\r
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg2;
\r
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg3;
\r
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7;
\r
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.ExtensionKey;
\r
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
\r
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.Extension;
\r
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
\r
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlow;
\r
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg0Key;
\r
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg2Key;
\r
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan;
\r
66 import org.slf4j.Logger;
\r
67 import org.slf4j.LoggerFactory;
\r
69 import java.util.Collections;
\r
70 import java.util.HashMap;
\r
71 import java.util.List;
\r
72 import java.util.Objects;
\r
74 import static org.junit.Assert.assertEquals;
\r
75 import static org.junit.Assert.assertNotEquals;
\r
76 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.applyActionIns;
\r
77 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.instructions;
\r
78 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxOutputRegAction;
\r
80 public class PolicyEnforcerTest extends FlowTableTest {
\r
81 protected static final Logger LOG =
\r
82 LoggerFactory.getLogger(PolicyEnforcerTest.class);
\r
86 public void setup() throws Exception {
\r
88 table = new PolicyEnforcer(ctx,ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER());
\r
91 switchManager.addSwitch(
\r
94 Collections.<NodeConnectorId>emptySet(),
\r
95 new OfOverlayNodeConfigBuilder().setTunnel(
\r
96 ImmutableList.of(new TunnelBuilder().setIp(new IpAddress(new Ipv4Address("1.2.3.4")))
\r
97 .setTunnelType(TunnelTypeVxlan.class)
\r
98 .setNodeConnectorId(tunnelId)
\r
99 .build())).build());
\r
103 public void testNoEps() throws Exception {
\r
104 FlowMap fm = dosync(null);
\r
105 assertEquals(2, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow().size());
\r
109 public void testSameEg() throws Exception {
\r
110 Endpoint ep1 = localEP().build();
\r
111 endpointManager.addEndpoint(ep1);
\r
112 Endpoint ep2 = localEP()
\r
113 .setMacAddress(new MacAddress("00:00:00:00:00:02"))
\r
115 endpointManager.addEndpoint(ep2);
\r
116 policyResolver.addTenant(baseTenant().setContract(
\r
117 ImmutableList.<Contract>of(baseContract(null).build())).build());
\r
119 FlowMap fm = dosync(null);
\r
120 assertNotEquals(0, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow().size());
\r
122 HashMap<String, Flow> flowMap = new HashMap<>();
\r
123 for (Flow f : fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow()) {
\r
124 flowMap.put(f.getId().getValue(), f);
\r
125 if (isAllowSameEpg(f)) {
\r
129 assertEquals(1, count);
\r
130 assertEquals(3, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow().size());
\r
131 fm = dosync(flowMap);
\r
132 assertEquals(3, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow().size());
\r
136 public void testDifferentEg() throws Exception {
\r
137 assertEquals(7, doTestDifferentEg(ImmutableList.<Subject>of(baseSubject(null).build())));
\r
138 assertEquals(7, doTestDifferentEg(ImmutableList.<Subject>of(baseSubject(Direction.Bidirectional).build())));
\r
139 assertEquals(5, doTestDifferentEg(ImmutableList.<Subject>of(baseSubject(Direction.In).build())));
\r
140 assertEquals(5, doTestDifferentEg(ImmutableList.<Subject>of(baseSubject(Direction.Out).build())));
\r
144 public void doTestRule() throws Exception {
\r
145 Rule rule1 = new RuleBuilder().setActionRef(
\r
146 ImmutableList.of(new ActionRefBuilder().setName(new ActionName("allow")).build()))
\r
148 createClassifierRefs(ImmutableMap.<String, Direction>of("tcp_dst_80", Direction.In,
\r
149 "tcp_src_80", Direction.In)))
\r
151 Rule rule2 = new RuleBuilder().setActionRef(
\r
152 ImmutableList.of(new ActionRefBuilder().setName(new ActionName("allow")).build()))
\r
154 createClassifierRefs(ImmutableMap.<String, Direction>of("tcp_dst_80", Direction.In,
\r
155 "tcp_src_80", Direction.Out)))
\r
157 Rule rule3 = new RuleBuilder().setActionRef(
\r
158 ImmutableList.of(new ActionRefBuilder().setName(new ActionName("allow")).build()))
\r
160 createClassifierRefs(ImmutableMap.<String, Direction>of("tcp_dst_80", Direction.In,
\r
161 "tcp_src_80", Direction.Out,
\r
162 "ether_type", Direction.In)))
\r
164 Rule rule4 = new RuleBuilder().setActionRef(
\r
165 ImmutableList.of(new ActionRefBuilder().setName(new ActionName("allow")).build()))
\r
167 createClassifierRefs(ImmutableMap.<String, Direction>of("tcp_dst_80", Direction.In,
\r
168 "tcp_dst_90", Direction.In)))
\r
172 doTestDifferentEg(ImmutableList.<Subject>of(createSubject("s1", ImmutableList.<Rule>of(rule1)))));
\r
174 doTestDifferentEg(ImmutableList.<Subject>of(createSubject("s2", ImmutableList.<Rule>of(rule2)))));
\r
176 doTestDifferentEg(ImmutableList.<Subject>of(createSubject("s3", ImmutableList.<Rule>of(rule3)))));
\r
178 doTestDifferentEg(ImmutableList.<Subject>of(createSubject("s4", ImmutableList.<Rule>of(rule4)))));
\r
181 private int doTestDifferentEg(List<Subject> subjects) throws Exception {
\r
182 Endpoint ep1 = localEP().build();
\r
183 endpointManager.addEndpoint(ep1);
\r
184 Endpoint ep2 = localEP()
\r
185 .setMacAddress(new MacAddress("00:00:00:00:00:02"))
\r
186 .setEndpointGroup(eg2)
\r
188 endpointManager.addEndpoint(ep2);
\r
189 policyResolver.addTenant(baseTenant().setContract(
\r
190 ImmutableList.<Contract>of(baseContract(subjects).build())).build());
\r
192 FlowMap fm = dosync(null);
\r
193 assertNotEquals(0, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow().size());
\r
195 HashMap<String, Flow> flowMap = new HashMap<>();
\r
196 for (Flow f : fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow()) {
\r
197 flowMap.put(f.getId().getValue(), f);
\r
198 if (isAllowSameEpg(f)) {
\r
200 } else if (f.getMatch() != null &&
\r
201 Objects.equals(tunnelId, f.getMatch().getInPort())) {
\r
202 assertEquals(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))),
\r
203 f.getInstructions());
\r
205 } else if (f.getMatch() != null &&
\r
206 f.getMatch().getEthernetMatch() != null &&
\r
207 Objects.equals(FlowUtils.IPv4,
\r
208 f.getMatch().getEthernetMatch()
\r
209 .getEthernetType().getType().getValue()) &&
\r
210 f.getMatch().getIpMatch() != null &&
\r
211 Objects.equals(Short.valueOf((short)6),
\r
212 f.getMatch().getIpMatch().getIpProtocol()) &&
\r
213 f.getMatch().getLayer4Match() != null &&
\r
215 Objects.equals(new PortNumber(Integer.valueOf(80)),
\r
216 ((TcpMatch)f.getMatch().getLayer4Match())
\r
217 .getTcpSourcePort())
\r
219 Objects.equals(new PortNumber(Integer.valueOf(80)),
\r
220 ((TcpMatch)f.getMatch().getLayer4Match())
\r
221 .getTcpDestinationPort())
\r
224 } else if (f.getMatch() != null &&
\r
225 f.getMatch().getEthernetMatch() != null &&
\r
226 Objects.equals(FlowUtils.IPv6,
\r
227 f.getMatch().getEthernetMatch()
\r
228 .getEthernetType().getType().getValue()) &&
\r
229 f.getMatch().getIpMatch() != null &&
\r
230 Objects.equals(Short.valueOf((short)6),
\r
231 f.getMatch().getIpMatch().getIpProtocol()) &&
\r
232 f.getMatch().getLayer4Match() != null &&
\r
234 Objects.equals(new PortNumber(Integer.valueOf(80)),
\r
235 ((TcpMatch)f.getMatch().getLayer4Match())
\r
236 .getTcpSourcePort())
\r
238 Objects.equals(new PortNumber(Integer.valueOf(80)),
\r
239 ((TcpMatch)f.getMatch().getLayer4Match())
\r
240 .getTcpDestinationPort())
\r
249 public void testConditions() throws Exception {
\r
250 Condition cond1 = new ConditionBuilder()
\r
251 .setName(new ConditionName("cond1"))
\r
253 Condition cond2 = new ConditionBuilder()
\r
254 .setName(new ConditionName("cond2"))
\r
257 Endpoint ep1 = localEP()
\r
258 .setCondition(ImmutableList.of(cond1.getName()))
\r
260 endpointManager.addEndpoint(ep1);
\r
261 Endpoint ep2 = localEP()
\r
262 .setMacAddress(new MacAddress("00:00:00:00:00:02"))
\r
263 .setCondition(ImmutableList.of(cond1.getName(), cond2.getName()))
\r
264 .setEndpointGroup(eg2)
\r
266 endpointManager.addEndpoint(ep2);
\r
268 TenantBuilder tb = baseTenant()
\r
269 .setContract(ImmutableList.of(new ContractBuilder()
\r
271 .setSubject(ImmutableList.of(baseSubject(Direction.Out).build()))
\r
272 .setClause(ImmutableList.of(new ClauseBuilder()
\r
273 .setName(new ClauseName("test"))
\r
274 .setSubjectRefs(ImmutableList.of(new SubjectName("s1")))
\r
275 .setConsumerMatchers(new ConsumerMatchersBuilder()
\r
276 .setConditionMatcher(ImmutableList.of(new ConditionMatcherBuilder()
\r
277 .setName(new ConditionMatcherName("m1"))
\r
278 .setCondition(ImmutableList.of(cond1, cond2))
\r
279 .setMatchType(MatchType.Any)
\r
282 .setProviderMatchers(new ProviderMatchersBuilder()
\r
283 .setConditionMatcher(ImmutableList.of(new ConditionMatcherBuilder()
\r
284 .setName(new ConditionMatcherName("m2"))
\r
285 .setCondition(ImmutableList.of(cond1, cond2))
\r
286 .setMatchType(MatchType.All)
\r
291 policyResolver.addTenant(tb.build());
\r
293 PolicyInfo policy = policyResolver.getCurrentPolicy();
\r
294 List<ConditionName> ep1c = endpointManager.getCondsForEndpoint(ep1);
\r
295 ConditionGroup cg1 =
\r
296 policy.getEgCondGroup(new EgKey(tb.getId(),
\r
297 ep1.getEndpointGroup()),
\r
299 List<ConditionName> ep2c = endpointManager.getCondsForEndpoint(ep2);
\r
300 ConditionGroup cg2 =
\r
301 policy.getEgCondGroup(new EgKey(tb.getId(),
\r
302 ep2.getEndpointGroup()),
\r
304 int cg1Id = OrdinalFactory.getCondGroupOrdinal(cg1);
\r
305 int cg2Id = OrdinalFactory.getCondGroupOrdinal(cg2);
\r
306 int eg1Id = OrdinalFactory.getContextOrdinal(ep1.getTenant(),
\r
307 ep1.getEndpointGroup());
\r
308 int eg2Id = OrdinalFactory.getContextOrdinal(ep1.getTenant(),
\r
309 ep2.getEndpointGroup());
\r
311 assertNotEquals(cg1Id, cg2Id);
\r
313 MatchBuilder mb = new MatchBuilder();
\r
314 FlowUtils.addNxRegMatch(mb,
\r
315 RegMatch.of(NxmNxReg0.class, Long.valueOf(eg1Id)),
\r
316 RegMatch.of(NxmNxReg1.class, Long.valueOf(cg1Id)),
\r
317 RegMatch.of(NxmNxReg2.class, Long.valueOf(eg2Id)),
\r
318 RegMatch.of(NxmNxReg3.class, Long.valueOf(cg2Id)));
\r
319 GeneralAugMatchNodesNodeTableFlow m1 =
\r
320 mb.getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);
\r
321 FlowUtils.addNxRegMatch(mb,
\r
322 RegMatch.of(NxmNxReg0.class, Long.valueOf(eg2Id)),
\r
323 RegMatch.of(NxmNxReg1.class, Long.valueOf(cg2Id)),
\r
324 RegMatch.of(NxmNxReg2.class, Long.valueOf(eg1Id)),
\r
325 RegMatch.of(NxmNxReg3.class, Long.valueOf(cg1Id)));
\r
326 GeneralAugMatchNodesNodeTableFlow m2 =
\r
327 mb.getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);
\r
329 FlowMap fm = dosync(null);
\r
330 assertEquals(7, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow().size());
\r
331 HashMap<String, Flow> flowMap = new HashMap<>();
\r
332 for (Flow f : fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow()) {
\r
333 flowMap.put(f.getId().getValue(), f);
\r
334 if (f.getMatch() != null &&
\r
335 f.getMatch().getEthernetMatch() != null) {
\r
339 assertEquals(3, count);
\r
340 fm = dosync(flowMap);
\r
341 int numberOfFlows = fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow().size();
\r
342 fm = dosync(flowMap);
\r
343 assertEquals(numberOfFlows, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow().size());
\r
346 private boolean isAllowSameEpg(Flow flow) {
\r
347 // flow has to have exactly 2 registers set, namely NxmNxReg0 and NxmNxReg2
\r
348 // (these register values don't have to be equal)
\r
349 boolean res = false;
\r
350 if (flow != null && flow.getMatch() != null) {
\r
351 GeneralAugMatchNodesNodeTableFlow genAug =
\r
352 flow.getMatch().getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);
\r
353 if (genAug != null) {
\r
354 List<ExtensionList> extensions = genAug.getExtensionList();
\r
355 if (extensions != null && extensions.size() == 2) {
\r
358 for (ExtensionList extensionList : extensions) {
\r
359 Class<? extends ExtensionKey> extensionKey = extensionList.getExtensionKey();
\r
360 Extension extension = extensionList.getExtension();
\r
361 if (extensionKey != null && extension != null) {
\r
362 NxAugMatchNodesNodeTableFlow nxAugMatch =
\r
363 extension.getAugmentation(NxAugMatchNodesNodeTableFlow.class);
\r
364 if (nxAugMatch != null && nxAugMatch.getNxmNxReg() != null) {
\r
365 if (extensionKey.equals(NxmNxReg0Key.class)) {
\r
366 reg0 = nxAugMatch.getNxmNxReg().getValue();
\r
367 } else if (extensionKey.equals(NxmNxReg2Key.class)) {
\r
368 reg2 = nxAugMatch.getNxmNxReg().getValue();
\r
373 if (reg0 != null && reg2 != null) {
\r