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 static org.junit.Assert.assertEquals;
\r
12 import static org.junit.Assert.assertNotEquals;
\r
13 import static org.junit.Assert.assertTrue;
\r
14 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.ARP;
\r
15 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.decNwTtlAction;
\r
16 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.dropInstructions;
\r
17 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.ethernetMatch;
\r
18 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.getOfPortNum;
\r
19 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.gotoTableIns;
\r
20 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.groupAction;
\r
21 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadArpOpAction;
\r
22 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadArpShaAction;
\r
23 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadArpSpaAction;
\r
24 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadRegAction;
\r
25 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveArpShaToArpThaAction;
\r
26 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveArpSpaToArpTpaAction;
\r
27 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveEthSrcToEthDstAction;
\r
28 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveRegTunIdAction;
\r
29 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.setDlSrcAction;
\r
31 import java.math.BigInteger;
\r
32 import java.util.Collections;
\r
33 import java.util.HashMap;
\r
34 import java.util.List;
\r
35 import java.util.Objects;
\r
37 import org.junit.Before;
\r
38 import org.junit.Test;
\r
39 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
\r
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
\r
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
\r
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
\r
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
\r
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
\r
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
\r
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCase;
\r
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
\r
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder;
\r
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
\r
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder;
\r
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayNodeConfigBuilder;
\r
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.nodes.node.TunnelBuilder;
\r
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Contract;
\r
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
\r
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
\r
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
\r
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6Match;
\r
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
\r
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7;
\r
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan;
\r
61 import org.slf4j.Logger;
\r
62 import org.slf4j.LoggerFactory;
\r
64 import com.google.common.collect.ImmutableList;
\r
66 public class DestinationMapperTest extends FlowTableTest {
\r
67 protected static final Logger LOG =
\r
68 LoggerFactory.getLogger(DestinationMapperTest.class);
\r
70 NodeConnectorId remoteTunnelId =
\r
71 new NodeConnectorId(remoteNodeId.getValue() + ":101");
\r
75 public void setup() throws Exception {
\r
77 table = new DestinationMapper(ctx,ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER());
\r
82 public void testNoEps() throws Exception {
\r
83 OfWriter fm = dosync(null);
\r
84 assertEquals(1, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER()).getFlow().size());
\r
87 private void verifyDMap(Endpoint remoteEp,
\r
88 Endpoint localEp) throws Exception {
\r
90 OfWriter fm = dosync(null);
\r
91 assertNotEquals(0, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER()).getFlow().size());
\r
93 // presumably counts flows that have correct matches set up
\r
95 HashMap<String, Flow> flowMap = new HashMap<>();
\r
96 for (Flow f : fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER()).getFlow()) {
\r
97 flowMap.put(f.getId().getValue(), f);
\r
98 if (f.getMatch() == null) {
\r
99 assertEquals(dropInstructions(),
\r
100 f.getInstructions());
\r
102 } else if (Objects.equals(ethernetMatch(null, null, ARP),
\r
103 f.getMatch().getEthernetMatch())) {
\r
104 // router ARP reply
\r
105 Instruction ins = f.getInstructions().getInstruction().get(0);
\r
106 ins = f.getInstructions().getInstruction().get(0);
\r
107 assertTrue(ins.getInstruction() instanceof ApplyActionsCase);
\r
108 List<Action> actions = ((ApplyActionsCase) ins.getInstruction()).getApplyActions().getAction();
\r
109 assertEquals(nxMoveEthSrcToEthDstAction(),
\r
110 actions.get(0).getAction());
\r
111 assertEquals(Integer.valueOf(0), actions.get(0).getOrder());
\r
112 assertEquals(setDlSrcAction(DestinationMapper.ROUTER_MAC),
\r
113 actions.get(1).getAction());
\r
114 assertEquals(Integer.valueOf(1), actions.get(1).getOrder());
\r
115 assertEquals(nxLoadArpOpAction(BigInteger.valueOf(2L)),
\r
116 actions.get(2).getAction());
\r
117 assertEquals(Integer.valueOf(2), actions.get(2).getOrder());
\r
118 assertEquals(nxMoveArpShaToArpThaAction(),
\r
119 actions.get(3).getAction());
\r
120 assertEquals(Integer.valueOf(3), actions.get(3).getOrder());
\r
121 assertEquals(nxLoadArpShaAction(new BigInteger(1, DestinationMapper
\r
122 .bytesFromHexString(DestinationMapper.ROUTER_MAC
\r
124 actions.get(4).getAction());
\r
125 assertEquals(Integer.valueOf(4), actions.get(4).getOrder());
\r
126 assertEquals(nxMoveArpSpaToArpTpaAction(),
\r
127 actions.get(5).getAction());
\r
128 assertEquals(Integer.valueOf(5), actions.get(5).getOrder());
\r
129 assertTrue(nxLoadArpSpaAction("10.0.0.1").equals(actions.get(6).getAction()) ||
\r
130 nxLoadArpSpaAction("10.0.1.1").equals(actions.get(6).getAction()) ||
\r
131 nxLoadArpSpaAction("10.0.2.1").equals(actions.get(6).getAction()));
\r
132 assertEquals(Integer.valueOf(6), actions.get(6).getOrder());
\r
134 } else if (Objects.equals(localEp.getMacAddress(),
\r
135 f.getMatch().getEthernetMatch()
\r
136 .getEthernetDestination().getAddress())) {
\r
138 for (Instruction ins : f.getInstructions().getInstruction()) {
\r
139 if (ins.getInstruction() instanceof ApplyActionsCase) {
\r
140 long p = getOfPortNum(nodeConnectorId);
\r
141 List<Action> actions = ((ApplyActionsCase) ins.getInstruction()).getApplyActions().getAction();
\r
142 assertEquals(nxLoadRegAction(NxmNxReg7.class,
\r
143 BigInteger.valueOf(p)),
\r
144 actions.get(2).getAction());
\r
146 } else if (ins.getInstruction() instanceof GoToTableCase) {
\r
147 assertEquals(gotoTableIns(ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()),
\r
148 ins.getInstruction());
\r
152 assertEquals(2, icount);
\r
155 } else if (Objects.equals(remoteEp.getMacAddress(),
\r
156 f.getMatch().getEthernetMatch()
\r
157 .getEthernetDestination().getAddress())) {
\r
159 for (Instruction ins : f.getInstructions().getInstruction()) {
\r
160 if (ins.getInstruction() instanceof ApplyActionsCase) {
\r
161 long p = getOfPortNum(tunnelId);
\r
162 List<Action> actions = ((ApplyActionsCase) ins.getInstruction()).getApplyActions().getAction();
\r
163 assertEquals(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(p)),
\r
164 actions.get(actions.size() - 1).getAction());
\r
166 } else if (ins.getInstruction() instanceof GoToTableCase) {
\r
167 assertEquals(gotoTableIns((short) (table.getTableId() + 1)),
\r
168 ins.getInstruction());
\r
172 assertEquals(2, icount);
\r
175 } else if (Objects.equals(DestinationMapper.ROUTER_MAC,
\r
176 f.getMatch().getEthernetMatch()
\r
177 .getEthernetDestination()
\r
179 if (f.getMatch().getLayer3Match() instanceof Ipv4Match) {
\r
180 // should be local port with rewrite dlsrc and dldst plus
\r
182 Instruction ins = f.getInstructions().getInstruction().get(0);
\r
183 assertTrue(ins.getInstruction() instanceof ApplyActionsCase);
\r
184 List<Action> actions = ((ApplyActionsCase) ins.getInstruction()).getApplyActions().getAction();
\r
185 long p = getOfPortNum(nodeConnectorId);
\r
186 assertEquals(nxLoadRegAction(NxmNxReg7.class,
\r
187 BigInteger.valueOf(p)),
\r
188 actions.get(2).getAction());
\r
189 assertEquals(Integer.valueOf(2), actions.get(2).getOrder());
\r
190 assertEquals(Integer.valueOf(3), actions.get(3).getOrder());
\r
191 assertEquals(Integer.valueOf(4), actions.get(4).getOrder());
\r
192 assertEquals(decNwTtlAction(),
\r
193 actions.get(5).getAction());
\r
194 assertEquals(Integer.valueOf(5), actions.get(5).getOrder());
\r
196 } else if (f.getMatch().getLayer3Match() instanceof Ipv6Match) {
\r
197 // should be remote port with rewrite dlsrc plus
\r
199 Instruction ins = f.getInstructions().getInstruction().get(0);
\r
200 assertTrue(ins.getInstruction() instanceof ApplyActionsCase);
\r
201 List<Action> actions = ((ApplyActionsCase) ins.getInstruction()).getApplyActions().getAction();
\r
202 long p = getOfPortNum(tunnelId);
\r
203 assertEquals(nxLoadRegAction(NxmNxReg7.class,
\r
204 BigInteger.valueOf(p)),
\r
205 actions.get(4).getAction());
\r
206 assertEquals(Integer.valueOf(4), actions.get(4).getOrder());
\r
207 assertEquals(setDlSrcAction(DestinationMapper.ROUTER_MAC),
\r
208 actions.get(5).getAction());
\r
209 assertEquals(Integer.valueOf(5), actions.get(5).getOrder());
\r
210 assertEquals(decNwTtlAction(),
\r
211 actions.get(6).getAction());
\r
212 assertEquals(Integer.valueOf(6), actions.get(6).getOrder());
\r
215 } else if (Objects.equals(DestinationMapper.MULTICAST_MAC,
\r
216 f.getMatch().getEthernetMatch()
\r
217 .getEthernetDestination()
\r
219 // broadcast/multicast flow should output to group table
\r
220 Instruction ins = f.getInstructions().getInstruction().get(0);
\r
221 ins = f.getInstructions().getInstruction().get(0);
\r
222 assertTrue(ins.getInstruction() instanceof ApplyActionsCase);
\r
223 List<Action> actions = ((ApplyActionsCase) ins.getInstruction()).getApplyActions().getAction();
\r
224 assertEquals(nxMoveRegTunIdAction(NxmNxReg0.class, false),
\r
225 actions.get(0).getAction());
\r
226 assertEquals(Integer.valueOf(0), actions.get(0).getOrder());
\r
228 Long v = Long.valueOf(OrdinalFactory.getContextOrdinal(tid, fd));
\r
229 assertEquals(groupAction(v), actions.get(1).getAction());
\r
230 assertEquals(Integer.valueOf(1), actions.get(1).getOrder());
\r
235 // TODO Li alagalah: Due to subnet checking this test is no longer setup
\r
236 // correct. Must address before Li.
\r
237 // assertEquals(8, count);
\r
238 assertEquals(fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER()).getFlow().size(), count);
\r
239 int numberOfFlows = fm.getTableForNode(nodeId, (short) 2).getFlow().size();
\r
240 fm = dosync(flowMap);
\r
241 assertEquals(numberOfFlows, fm.getTableForNode(nodeId, (short) 2).getFlow().size());
\r
245 protected EndpointBuilder localEP() {
\r
246 return super.localEP()
\r
247 .setL3Address(ImmutableList.of(new L3AddressBuilder()
\r
249 .setIpAddress(new IpAddress(new Ipv4Address("10.0.0.1")))
\r
254 protected EndpointBuilder remoteEP(NodeId remoteNodeId) {
\r
255 return super.remoteEP(remoteNodeId)
\r
256 .setL3Address(ImmutableList.of(new L3AddressBuilder()
\r
258 .setIpAddress(new IpAddress(new Ipv6Address("::ffff:0:0:0:10.0.0.2")))
\r
262 private void addSwitches() {
\r
263 switchManager.addSwitch(
\r
266 Collections.<NodeConnectorId>emptySet(),
\r
267 new OfOverlayNodeConfigBuilder().setTunnel(
\r
268 ImmutableList.of(new TunnelBuilder().setIp(new IpAddress(new Ipv4Address("1.2.3.4")))
\r
269 .setTunnelType(TunnelTypeVxlan.class)
\r
270 .setNodeConnectorId(tunnelId)
\r
271 .build())).build());
\r
272 switchManager.addSwitch(
\r
275 Collections.<NodeConnectorId>emptySet(),
\r
276 new OfOverlayNodeConfigBuilder().setTunnel(
\r
277 ImmutableList.of(new TunnelBuilder().setIp(new IpAddress(new Ipv4Address("1.2.3.5")))
\r
278 .setTunnelType(TunnelTypeVxlan.class)
\r
279 .setNodeConnectorId(tunnelId)
\r
280 .build())).build());
\r
284 public void testSame() throws Exception {
\r
286 Endpoint localEp = localEP().build();
\r
287 endpointManager.addEndpoint(localEp);
\r
288 Endpoint remoteEp = remoteEP(remoteNodeId).build();
\r
289 endpointManager.addEndpoint(remoteEp);
\r
292 ctx.addTenant(baseTenant().setContract(
\r
293 ImmutableList.<Contract> of(baseContract(null).build())).build());
\r
294 verifyDMap(remoteEp, localEp);
\r
298 public void testDiff() throws Exception {
\r
300 Endpoint localEp = localEP().build();
\r
301 endpointManager.addEndpoint(localEp);
\r
302 Endpoint remoteEp = remoteEP(remoteNodeId)
\r
303 .setEndpointGroup(eg2)
\r
305 endpointManager.addEndpoint(remoteEp);
\r
307 ctx.addTenant(baseTenant().setContract(
\r
308 ImmutableList.<Contract> of(baseContract(null).build())).build());
\r
309 verifyDMap(remoteEp, localEp);
\r