Merge "Minimize flow-programming."
[groupbasedpolicy.git] / renderers / ofoverlay / src / test / java / org / opendaylight / groupbasedpolicy / renderer / ofoverlay / flow / PolicyEnforcerTest.java
1 /*\r
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.\r
3  *\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
7  */\r
8 \r
9 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;\r
10 \r
11 import java.util.Collections;\r
12 import java.util.HashMap;\r
13 import java.util.List;\r
14 import java.util.Objects;\r
15 \r
16 import org.junit.Before;\r
17 import org.junit.Test;\r
18 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;\r
19 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;\r
20 import org.opendaylight.groupbasedpolicy.resolver.ConditionGroup;\r
21 import org.opendaylight.groupbasedpolicy.resolver.EgKey;\r
22 import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;\r
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;\r
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;\r
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;\r
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;\r
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;\r
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName;\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClauseName;\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionMatcherName;\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayNodeConfigBuilder;\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.condition.matchers.ConditionMatcherBuilder;\r
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.conditions.Condition;\r
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.conditions.ConditionBuilder;\r
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantBuilder;\r
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Contract;\r
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ContractBuilder;\r
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.ClauseBuilder;\r
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Subject;\r
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ConsumerMatchersBuilder;\r
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ProviderMatchersBuilder;\r
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.Rule;\r
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.RuleBuilder;\r
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;\r
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;\r
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;\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.GeneralAugMatchNodesNodeTableFlow;\r
59 import org.slf4j.Logger;\r
60 import org.slf4j.LoggerFactory;\r
61 \r
62 import com.google.common.collect.ImmutableList;\r
63 import com.google.common.collect.ImmutableMap;\r
64 \r
65 import static org.junit.Assert.*;\r
66 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.*;\r
67 \r
68 public class PolicyEnforcerTest extends FlowTableTest {\r
69     protected static final Logger LOG = \r
70             LoggerFactory.getLogger(PolicyEnforcerTest.class);\r
71 \r
72     @Before\r
73     public void setup() throws Exception {\r
74         initCtx();\r
75         table = new PolicyEnforcer(ctx);\r
76         super.setup();\r
77         \r
78         switchManager.addSwitch(nodeId, tunnelId, \r
79                                 Collections.<NodeConnectorId>emptySet(),\r
80                                 new OfOverlayNodeConfigBuilder()\r
81                                     .setTunnelIp(new IpAddress(new Ipv4Address("1.2.3.4")))\r
82                                     .build());\r
83     }\r
84 \r
85     @Test\r
86     public void testNoEps() throws Exception {\r
87         FlowMap fm = dosync(null);\r
88         assertEquals(2, fm.getTableForNode(nodeId, (short) 3).getFlow().size());\r
89     }\r
90 \r
91     @Test\r
92     public void testSameEg() throws Exception {\r
93         Endpoint ep1 = localEP().build();\r
94         endpointManager.addEndpoint(ep1);\r
95         Endpoint ep2 = localEP()\r
96             .setMacAddress(new MacAddress("00:00:00:00:00:02"))\r
97             .build();\r
98         endpointManager.addEndpoint(ep2);\r
99         policyResolver.addTenant(baseTenant().setContract(\r
100                 ImmutableList.<Contract>of(baseContract(null).build())).build());\r
101 \r
102         FlowMap fm = dosync(null);\r
103         assertNotEquals(0, fm.getTableForNode(nodeId, (short) 3).getFlow().size());\r
104         int count = 0;\r
105         HashMap<String, Flow> flowMap = new HashMap<>();\r
106         for (Flow f : fm.getTableForNode(nodeId, (short) 3).getFlow()) {\r
107             flowMap.put(f.getId().getValue(), f);\r
108             if (f.getId().getValue().indexOf("intraallow") == 0)\r
109                 count += 1;\r
110         }\r
111         assertEquals(1, count);\r
112         assertEquals(3, fm.getTableForNode(nodeId, (short) 3).getFlow().size());\r
113         fm = dosync(flowMap);\r
114         assertEquals(3, fm.getTableForNode(nodeId, (short) 3).getFlow().size());\r
115     }\r
116 \r
117     @Test\r
118     public void testDifferentEg() throws Exception {\r
119         assertEquals(7, doTestDifferentEg(ImmutableList.<Subject>of(baseSubject(null).build())));\r
120         assertEquals(7, doTestDifferentEg(ImmutableList.<Subject>of(baseSubject(Direction.Bidirectional).build())));\r
121         assertEquals(5, doTestDifferentEg(ImmutableList.<Subject>of(baseSubject(Direction.In).build())));\r
122         assertEquals(5, doTestDifferentEg(ImmutableList.<Subject>of(baseSubject(Direction.Out).build())));\r
123     }\r
124 \r
125     @Test\r
126     public void doTestRule() throws Exception {\r
127         Rule rule1 = new RuleBuilder().setActionRef(\r
128                 ImmutableList.of(new ActionRefBuilder().setName(new ActionName("allow")).build()))\r
129             .setClassifierRef(\r
130                     createClassifierRefs(ImmutableMap.<String, Direction>of("tcp_dst_80", Direction.In, "tcp_src_80",\r
131                             Direction.In)))\r
132             .build();\r
133         Rule rule2 = new RuleBuilder().setActionRef(\r
134                 ImmutableList.of(new ActionRefBuilder().setName(new ActionName("allow")).build()))\r
135             .setClassifierRef(\r
136                     createClassifierRefs(ImmutableMap.<String, Direction>of("tcp_dst_80", Direction.In, "tcp_src_80",\r
137                             Direction.Out)))\r
138             .build();\r
139         Rule rule3 = new RuleBuilder().setActionRef(\r
140                 ImmutableList.of(new ActionRefBuilder().setName(new ActionName("allow")).build()))\r
141             .setClassifierRef(\r
142                     createClassifierRefs(ImmutableMap.<String, Direction>of("tcp_dst_80", Direction.In, "tcp_src_80",\r
143                             Direction.Out, "ether_type", Direction.In)))\r
144             .build();\r
145         assertEquals(5,\r
146                 doTestDifferentEg(ImmutableList.<Subject>of(createSubject("s1", ImmutableList.<Rule>of(rule1)))));\r
147         assertEquals(7,\r
148                 doTestDifferentEg(ImmutableList.<Subject>of(createSubject("s2", ImmutableList.<Rule>of(rule2)))));\r
149         assertEquals(6,\r
150                 doTestDifferentEg(ImmutableList.<Subject>of(createSubject("s3", ImmutableList.<Rule>of(rule3)))));\r
151     }\r
152 \r
153     private int doTestDifferentEg(List<Subject> subjects) throws Exception {\r
154         Endpoint ep1 = localEP().build();\r
155         endpointManager.addEndpoint(ep1);\r
156         Endpoint ep2 = localEP()\r
157             .setMacAddress(new MacAddress("00:00:00:00:00:02"))\r
158             .setEndpointGroup(eg2)\r
159             .build();\r
160         endpointManager.addEndpoint(ep2);\r
161         policyResolver.addTenant(baseTenant().setContract(\r
162                 ImmutableList.<Contract>of(baseContract(subjects).build())).build());\r
163 \r
164         FlowMap fm = dosync(null);\r
165         assertNotEquals(0, fm.getTableForNode(nodeId, (short) 3).getFlow().size());\r
166         int count = 0;\r
167         HashMap<String, Flow> flowMap = new HashMap<>();\r
168         for (Flow f : fm.getTableForNode(nodeId, (short) 3).getFlow()) {\r
169             flowMap.put(f.getId().getValue(), f);\r
170             if (f.getId().getValue().indexOf("intraallow") == 0) {\r
171                 count += 1;\r
172             } else if (f.getMatch() != null &&\r
173                        Objects.equals(tunnelId, f.getMatch().getInPort())) {\r
174                 assertEquals(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))),\r
175                              f.getInstructions());\r
176                 count += 1;\r
177             } else if (f.getMatch() != null &&\r
178                        f.getMatch().getEthernetMatch() != null &&\r
179                        Objects.equals(FlowUtils.IPv4,\r
180                                       f.getMatch().getEthernetMatch()\r
181                                           .getEthernetType().getType().getValue()) &&\r
182                        f.getMatch().getIpMatch() != null &&\r
183                        Objects.equals(Short.valueOf((short)6),\r
184                                       f.getMatch().getIpMatch().getIpProtocol()) &&\r
185                        f.getMatch().getLayer4Match() != null &&\r
186                        (\r
187                         Objects.equals(new PortNumber(Integer.valueOf(80)),\r
188                                ((TcpMatch)f.getMatch().getLayer4Match())\r
189                                 .getTcpSourcePort())\r
190                                 ||\r
191                         Objects.equals(new PortNumber(Integer.valueOf(80)),\r
192                                ((TcpMatch)f.getMatch().getLayer4Match())\r
193                                 .getTcpDestinationPort())\r
194                         )) {\r
195                 count += 1;\r
196             } else if (f.getMatch() != null &&\r
197                        f.getMatch().getEthernetMatch() != null &&\r
198                        Objects.equals(FlowUtils.IPv6,\r
199                                       f.getMatch().getEthernetMatch()\r
200                                           .getEthernetType().getType().getValue()) &&\r
201                        f.getMatch().getIpMatch() != null &&\r
202                        Objects.equals(Short.valueOf((short)6),\r
203                                       f.getMatch().getIpMatch().getIpProtocol()) &&\r
204                        f.getMatch().getLayer4Match() != null &&\r
205                         (\r
206                         Objects.equals(new PortNumber(Integer.valueOf(80)),\r
207                                 ((TcpMatch)f.getMatch().getLayer4Match())\r
208                                 .getTcpSourcePort())\r
209                                 ||\r
210                         Objects.equals(new PortNumber(Integer.valueOf(80)),\r
211                                 ((TcpMatch)f.getMatch().getLayer4Match())\r
212                                 .getTcpDestinationPort())\r
213                         )) {\r
214                 count += 1;\r
215             } \r
216         }\r
217         return count;\r
218     }\r
219 \r
220     @Test\r
221     public void testConditions() throws Exception {\r
222         Condition cond1 = new ConditionBuilder()\r
223             .setName(new ConditionName("cond1"))\r
224             .build();\r
225         Condition cond2 = new ConditionBuilder()\r
226             .setName(new ConditionName("cond2"))\r
227             .build();\r
228 \r
229         Endpoint ep1 = localEP()\r
230             .setCondition(ImmutableList.of(cond1.getName()))\r
231             .build();\r
232         endpointManager.addEndpoint(ep1);\r
233         Endpoint ep2 = localEP()\r
234             .setMacAddress(new MacAddress("00:00:00:00:00:02"))\r
235             .setCondition(ImmutableList.of(cond1.getName(), cond2.getName()))\r
236             .setEndpointGroup(eg2)\r
237             .build();\r
238         endpointManager.addEndpoint(ep2);        \r
239 \r
240         TenantBuilder tb = baseTenant()\r
241             .setContract(ImmutableList.of(new ContractBuilder()\r
242                 .setId(cid)\r
243                 .setSubject(ImmutableList.of(baseSubject(Direction.Out).build()))\r
244                 .setClause(ImmutableList.of(new ClauseBuilder()\r
245                     .setName(new ClauseName("test"))\r
246                     .setSubjectRefs(ImmutableList.of(new SubjectName("s1")))\r
247                     .setConsumerMatchers(new ConsumerMatchersBuilder()\r
248                         .setConditionMatcher(ImmutableList.of(new ConditionMatcherBuilder()\r
249                             .setName(new ConditionMatcherName("m1"))\r
250                             .setCondition(ImmutableList.of(cond1, cond2))\r
251                             .setMatchType(MatchType.Any)\r
252                             .build()))\r
253                         .build())\r
254                     .setProviderMatchers(new ProviderMatchersBuilder()\r
255                         .setConditionMatcher(ImmutableList.of(new ConditionMatcherBuilder()\r
256                             .setName(new ConditionMatcherName("m2"))\r
257                             .setCondition(ImmutableList.of(cond1, cond2))\r
258                             .setMatchType(MatchType.All)\r
259                             .build()))\r
260                         .build())\r
261                     .build()))\r
262                 .build()));\r
263         policyResolver.addTenant(tb.build());\r
264 \r
265         PolicyInfo policy = policyResolver.getCurrentPolicy();\r
266         List<ConditionName> ep1c = endpointManager.getCondsForEndpoint(ep1);\r
267         ConditionGroup cg1 = \r
268                 policy.getEgCondGroup(new EgKey(tb.getId(), \r
269                                                 ep1.getEndpointGroup()),\r
270                                       ep1c);\r
271         List<ConditionName> ep2c = endpointManager.getCondsForEndpoint(ep2);\r
272         ConditionGroup cg2 = \r
273                 policy.getEgCondGroup(new EgKey(tb.getId(), \r
274                                                 ep2.getEndpointGroup()),\r
275                                       ep2c);\r
276         int cg1Id = OrdinalFactory.getCondGroupOrdinal(cg1);\r
277         int cg2Id = OrdinalFactory.getCondGroupOrdinal(cg2);\r
278         int eg1Id = OrdinalFactory.getContextOrdinal(ep1.getTenant(),\r
279                                                     ep1.getEndpointGroup());\r
280         int eg2Id = OrdinalFactory.getContextOrdinal(ep1.getTenant(),\r
281                                                     ep2.getEndpointGroup());\r
282 \r
283         assertNotEquals(cg1Id, cg2Id);\r
284 \r
285         MatchBuilder mb = new MatchBuilder();\r
286         FlowUtils.addNxRegMatch(mb, \r
287                                 RegMatch.of(NxmNxReg0.class, Long.valueOf(eg1Id)),\r
288                                 RegMatch.of(NxmNxReg1.class, Long.valueOf(cg1Id)),\r
289                                 RegMatch.of(NxmNxReg2.class, Long.valueOf(eg2Id)),\r
290                                 RegMatch.of(NxmNxReg3.class, Long.valueOf(cg2Id)));\r
291         GeneralAugMatchNodesNodeTableFlow m1 =\r
292                 mb.getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);\r
293         FlowUtils.addNxRegMatch(mb, \r
294                                 RegMatch.of(NxmNxReg0.class, Long.valueOf(eg2Id)),\r
295                                 RegMatch.of(NxmNxReg1.class, Long.valueOf(cg2Id)),\r
296                                 RegMatch.of(NxmNxReg2.class, Long.valueOf(eg1Id)),\r
297                                 RegMatch.of(NxmNxReg3.class, Long.valueOf(cg1Id)));\r
298         GeneralAugMatchNodesNodeTableFlow m2 =\r
299                 mb.getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);\r
300         int count = 0;\r
301         FlowMap fm = dosync(null);\r
302         assertEquals(6, fm.getTableForNode(nodeId, (short) 3).getFlow().size());\r
303         HashMap<String, Flow> flowMap = new HashMap<>();\r
304         for (Flow f : fm.getTableForNode(nodeId, (short) 3).getFlow()) {\r
305             flowMap.put(f.getId().getValue(), f);\r
306             if (f.getMatch() != null &&\r
307                 f.getMatch().getEthernetMatch() != null) {\r
308                 count++;\r
309             }\r
310         }\r
311         assertEquals(2, count);\r
312         fm = dosync(flowMap);\r
313         int numberOfFlows = fm.getTableForNode(nodeId, (short) 3).getFlow().size();\r
314         fm = dosync(flowMap);\r
315         assertEquals(numberOfFlows, fm.getTableForNode(nodeId, (short) 3).getFlow().size());\r
316     }\r
317 }\r