Fixes for DestinationMapperFlowsTest
[groupbasedpolicy.git] / renderers / ofoverlay / src / test / java / org / opendaylight / groupbasedpolicy / renderer / ofoverlay / mapper / destination / DestinationMapperFlowsTest.java
1 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.destination;
2
3 import static org.mockito.Mockito.any;
4 import static org.mockito.Mockito.anyShort;
5 import static org.mockito.Mockito.eq;
6 import static org.mockito.Mockito.mock;
7 import static org.mockito.Mockito.times;
8 import static org.mockito.Mockito.verify;
9 import static org.mockito.Mockito.verifyZeroInteractions;
10 import static org.mockito.Mockito.when;
11 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.ARP;
12 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.IPv4;
13 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.IPv6;
14 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;
15 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.addNxRegMatch;
16 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.applyActionIns;
17 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.bytesFromHexString;
18 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.decNwTtlAction;
19 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.ethernetMatch;
20 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.gotoTableIns;
21 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.groupAction;
22 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadArpOpAction;
23 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadArpShaAction;
24 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadArpSpaAction;
25 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadRegAction;
26 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadTunIPv4Action;
27 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadTunIdAction;
28 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveArpShaToArpThaAction;
29 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveArpSpaToArpTpaAction;
30 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveEthSrcToEthDstAction;
31 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.outputAction;
32 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.setDlDstAction;
33 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.setDlSrcAction;
34
35 import java.math.BigInteger;
36 import java.util.ArrayList;
37 import java.util.HashSet;
38 import java.util.List;
39 import java.util.Set;
40
41 import org.junit.Before;
42 import org.junit.Test;
43 import org.opendaylight.groupbasedpolicy.dto.IndexedTenant;
44 import org.opendaylight.groupbasedpolicy.dto.PolicyInfo;
45 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
46 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
47 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager;
48 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.EndpointManager;
49 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowIdUtils;
50 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils;
51 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory;
52 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.MapperUtilsTest;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubnetId;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Prefix;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3PrefixBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContextBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.PolicyBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.SubnetBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ExternalImplicitGroup;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ExternalImplicitGroupBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg2;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg3;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg4;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7;
96
97 public class DestinationMapperFlowsTest extends MapperUtilsTest {
98
99     private DestinationMapperFlows flows;
100     private DestinationMapperUtils utils;
101     private Tenant tenant;
102     private IndexedTenant indexedTenant;
103
104     @Before
105     public void init() throws Exception {
106         endpointManager = mock(EndpointManager.class);
107         policyManager = mock(PolicyManager.class);
108         policyInfo = mock(PolicyInfo.class);
109         ctx = mock(OfContext.class);
110         ofWriter = mock(OfWriter.class);
111
112         tableId = 3;
113
114         tenant = buildTenant().build();
115         indexedTenant = new IndexedTenant(tenant);
116
117         when(ctx.getTenant(TENANT_ID)).thenReturn(indexedTenant);
118         when(ctx.getEndpointManager()).thenReturn(endpointManager);
119         when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
120
121         utils = new DestinationMapperUtils(ctx);
122         flows = new DestinationMapperFlows(utils, NODE_ID, tableId);
123         OrdinalFactory.resetPolicyOrdinalValue();
124     }
125
126     @Test
127     public void testDropFlow_noEthertype() {
128         Flow testFlow = buildFlow(new FlowId(DROP_ALL), tableId, 100, null, FlowUtils.dropInstructions()).build();
129
130         flows.dropFlow(100, null, ofWriter);
131         verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow);
132     }
133
134     @Test
135     public void testDropFlow_ipV4Ethertype() {
136         MatchBuilder matchBuilder = new MatchBuilder();
137         matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv4));
138         Match match = matchBuilder.build();
139         Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match,
140                 FlowUtils.dropInstructions()).build();
141
142         flows.dropFlow(100, FlowUtils.IPv4, ofWriter);
143         verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow);
144     }
145
146     @Test
147     public void testDropFlow_ipV6Ethertype() {
148         MatchBuilder matchBuilder = new MatchBuilder();
149         matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv6));
150         Match match = matchBuilder.build();
151         Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match,
152                 FlowUtils.dropInstructions()).build();
153
154         flows.dropFlow(100, FlowUtils.IPv6, ofWriter);
155         verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow);
156     }
157
158     @Test
159     public void testDropFlow_arpEthertype() {
160         MatchBuilder matchBuilder = new MatchBuilder();
161         matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.ARP));
162         Match match = matchBuilder.build();
163         Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match,
164                 FlowUtils.dropInstructions()).build();
165
166         flows.dropFlow(100, FlowUtils.ARP, ofWriter);
167         verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow);
168     }
169
170     @Test
171     public void createExternalL2Flow_exceptionCaught() {
172         EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0);
173         Set<NodeConnectorId> externalConnectors = new HashSet<>();
174         externalConnectors.add(new NodeConnectorId(CONNECTOR_0));
175         externalConnectors.add(new NodeConnectorId(CONNECTOR_1));
176
177         flows.createExternalL2Flow(tableId, 100, endpointBuilder.build(), externalConnectors, ofWriter);
178
179         verifyZeroInteractions(ofWriter);
180     }
181
182     @Test
183     public void createExternalL2Flow() {
184         EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0);
185         Set<NodeConnectorId> externalConnectors = new HashSet<>();
186         externalConnectors.add(new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue()));
187         externalConnectors.add(new NodeConnectorId(OPENFLOW + CONNECTOR_1.getValue()));
188         Endpoint endpoint = endpointBuilder.setTenant(tenant.getId()).build();
189
190         MatchBuilder matchBuilder =
191                 new MatchBuilder().setEthernetMatch(ethernetMatch(null, endpoint.getMacAddress(), null));
192         OrdinalFactory.EndpointFwdCtxOrdinals ord = utils.getEndpointOrdinals(endpoint);
193         addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg4.class, (long) ord.getBdId()));
194         Match match = matchBuilder.build();
195
196         List<Action> applyActions = new ArrayList<>();
197         applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1)));
198         applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0)));
199         applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0)));
200
201         int order = 0;
202         Instruction applyActionsIns = new InstructionBuilder().setOrder(order++)
203             .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
204             .build();
205         Instruction gotoTable = new InstructionBuilder().setOrder(order).setInstruction(gotoTableIns(tableId)).build();
206
207         ArrayList<Instruction> instructions = new ArrayList<>();
208         instructions.add(applyActionsIns);
209         instructions.add(gotoTable);
210         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
211         instructionsBuilder.setInstruction(instructions);
212
213         FlowId flowId = FlowIdUtils.newFlowId(tableId, "externalL2", match);
214         Flow flow = buildFlow(flowId, tableId, 100, match, instructionsBuilder.build()).build();
215
216         flows.createExternalL2Flow(tableId, 100, endpointBuilder.build(), externalConnectors, ofWriter);
217
218         verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow));
219     }
220
221     @Test
222     public void createExternalL3RoutedFlow_nullIpAddress() {
223         EndpointBuilder gatewayBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0);
224         EndpointBuilder endpointBuilder = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1);
225         Endpoint gateway = gatewayBuilder.build();
226         Endpoint endpoint = endpointBuilder.build();
227         L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();
228         l3AddressBuilder.setIpAddress(null);
229         Set<NodeConnectorId> externalConnectors = new HashSet<>();
230         externalConnectors.add(new NodeConnectorId(CONNECTOR_0));
231         externalConnectors.add(new NodeConnectorId(CONNECTOR_1));
232
233         flows.createExternalL3RoutedFlow(tableId, 90, endpoint, gateway, l3AddressBuilder.build(), externalConnectors,
234                 ofWriter);
235
236         verifyZeroInteractions(ofWriter);
237     }
238
239     @Test
240     public void createExternalL3RoutedFlow_exceptionCaught() {
241         EndpointBuilder gatewayBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0);
242         EndpointBuilder endpointBuilder = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1);
243         Endpoint gateway = gatewayBuilder.build();
244         Endpoint endpoint = endpointBuilder.build();
245         L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();
246         l3AddressBuilder.setIpAddress(new IpAddress(IPV4_0));
247         Set<NodeConnectorId> externalConnectors = new HashSet<>();
248         externalConnectors.add(new NodeConnectorId(CONNECTOR_0));
249         externalConnectors.add(new NodeConnectorId(CONNECTOR_1));
250
251         flows.createExternalL3RoutedFlow(tableId, 90, endpoint, gateway, l3AddressBuilder.build(), externalConnectors,
252                 ofWriter);
253
254         verifyZeroInteractions(ofWriter);
255     }
256
257     @Test
258     public void createExternalL3RoutedFlow_ipV4() {
259         EndpointBuilder gatewayBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0);
260         EndpointBuilder endpointBuilder = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1);
261         Endpoint gateway = gatewayBuilder.build();
262         Endpoint endpoint = endpointBuilder.build();
263         L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();
264         l3AddressBuilder.setIpAddress(new IpAddress(IPV4_0));
265         Set<NodeConnectorId> externalConnectors = new HashSet<>();
266         externalConnectors.add(new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue()));
267         externalConnectors.add(new NodeConnectorId(OPENFLOW + CONNECTOR_1.getValue()));
268
269         List<Action> l3ApplyActions = new ArrayList<>();
270         l3ApplyActions.add(setDlSrcAction(MAC_0));
271         l3ApplyActions.add(setDlDstAction(MAC_0));
272         List<Action> applyActions = new ArrayList<>();
273         applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1)));
274         applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0)));
275         applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0)));
276         applyActions.addAll(l3ApplyActions);
277
278         MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, MAC_1, IPv4))
279             .setLayer3Match(new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(IPV4_0.getValue() + IP_PREFIX_32))
280                 .build());
281         addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 5));
282         Match match = matchBuilder.build();
283
284         int order = 0;
285         Instruction applyActionsIns = new InstructionBuilder().setOrder(order++)
286             .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
287             .build();
288         Instruction gotoTable = new InstructionBuilder().setOrder(order).setInstruction(gotoTableIns(tableId)).build();
289         ArrayList<Instruction> l3instructions = new ArrayList<>();
290         l3instructions.add(applyActionsIns);
291         l3instructions.add(gotoTable);
292         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
293         instructionsBuilder.setInstruction(l3instructions);
294
295         FlowId flowid = FlowIdUtils.newFlowId(tableId, "externalL3", match);
296         Flow flow = buildFlow(flowid, tableId, 90, match, instructionsBuilder.build()).build();
297
298         flows.createExternalL3RoutedFlow(tableId, 90, endpoint, gateway, l3AddressBuilder.build(), externalConnectors,
299                 ofWriter);
300
301         verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow));
302     }
303
304     @Test
305     public void createExternalL3RoutedFlow_ipV6() {
306         EndpointBuilder gatewayBuilder = buildEndpoint(IPV4_1, MAC_0, CONNECTOR_0);
307         EndpointBuilder endpointBuilder = buildEndpoint(IPV4_2, MAC_1, CONNECTOR_1);
308         Endpoint gateway = gatewayBuilder.build();
309         Endpoint endpoint = endpointBuilder.build();
310         L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();
311         l3AddressBuilder.setIpAddress(new IpAddress(new Ipv6Address(IPV6_1)));
312         Set<NodeConnectorId> externalConnectors = new HashSet<>();
313         externalConnectors.add(new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue()));
314         externalConnectors.add(new NodeConnectorId(OPENFLOW + CONNECTOR_1.getValue()));
315
316         List<Action> l3ApplyActions = new ArrayList<>();
317         l3ApplyActions.add(setDlSrcAction(MAC_0));
318         l3ApplyActions.add(setDlDstAction(MAC_0));
319         List<Action> applyActions = new ArrayList<>();
320         applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1)));
321         applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0)));
322         applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0)));
323         applyActions.addAll(l3ApplyActions);
324
325         MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, MAC_1, IPv6))
326             .setLayer3Match(new Ipv6MatchBuilder().setIpv6Destination(new Ipv6Prefix(IPV6_1.getValue() + IP_PREFIX_128))
327                 .build());
328         addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 0));
329         Match match = matchBuilder.build();
330
331         int order = 0;
332         Instruction applyActionsIns = new InstructionBuilder().setOrder(order++)
333             .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
334             .build();
335         Instruction gotoTable = new InstructionBuilder().setOrder(order).setInstruction(gotoTableIns(tableId)).build();
336         ArrayList<Instruction> l3instructions = new ArrayList<>();
337         l3instructions.add(applyActionsIns);
338         l3instructions.add(gotoTable);
339         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
340         instructionsBuilder.setInstruction(l3instructions);
341
342         FlowId flowid = FlowIdUtils.newFlowId(tableId, "externalL3", match);
343         Flow flow = buildFlow(flowid, tableId, 90, match, instructionsBuilder.build()).build();
344
345         flows.createExternalL3RoutedFlow(tableId, 90, endpoint, gateway, l3AddressBuilder.build(), externalConnectors,
346                 ofWriter);
347
348         verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow));
349     }
350
351     @Test
352     public void createLocalL2Flow_exceptionCaught() {
353         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_0, CONNECTOR_0);
354         Endpoint endpoint = endpointBuilder.build();
355
356         flows.createLocalL2Flow(tableId, 80, endpoint, ofWriter);
357
358         verifyZeroInteractions(ofWriter);
359     }
360
361     @Test
362     public void createLocalL2Flow() {
363         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue());
364         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_0, connectorId);
365         endpointBuilder.setNetworkContainment(SUBNET_0);
366         Endpoint endpoint = endpointBuilder.setTenant(tenant.getId()).build();
367
368         List<Action> applyActions = new ArrayList<>();
369         applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1)));
370         applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0)));
371         applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0)));
372
373         int order = 0;
374         Instruction applyActionsIns = new InstructionBuilder().setOrder(order++)
375             .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
376             .build();
377         Instruction gotoTable = new InstructionBuilder().setOrder(order).setInstruction(gotoTableIns(tableId)).build();
378
379         ArrayList<Instruction> instructions = new ArrayList<>();
380         instructions.add(applyActionsIns);
381         instructions.add(gotoTable);
382         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
383         instructionsBuilder.setInstruction(instructions);
384
385         MatchBuilder matchBuilder =
386                 new MatchBuilder().setEthernetMatch(ethernetMatch(null, endpoint.getMacAddress(), null));
387         OrdinalFactory.EndpointFwdCtxOrdinals ord = utils.getEndpointOrdinals(endpoint);
388         addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg4.class, (long) ord.getBdId()));
389         Match match = matchBuilder.build();
390
391         Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "localL2", match), tableId, 80, match,
392                 instructionsBuilder.build()).build();
393
394         flows.createLocalL2Flow(tableId, 80, endpoint, ofWriter);
395
396         verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow));
397     }
398
399     @Test
400     public void createLocalL3RoutedFlow_nullL3Context() {
401         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue());
402         OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
403         ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(CONNECTOR_1));
404         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_0, connectorId);
405         endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
406         Endpoint endpoint = endpointBuilder.build();
407         flows.createLocalL3RoutedFlow(tableId, 80, endpoint, null, null, null, ofWriter);
408         verifyZeroInteractions(ofWriter);
409     }
410
411     @Test
412     public void createLocalL3RoutedFlow_noMac() {
413         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue());
414         OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
415         ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(CONNECTOR_1));
416         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, connectorId);
417         endpointBuilder.setNetworkContainment(SUBNET_0);
418         endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
419         endpointBuilder.setTenant(getTestIndexedTenant().getTenant().getId());
420         endpointBuilder.setMacAddress(null);
421         Endpoint endpoint = endpointBuilder.build();
422
423         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
424         localSubnetBuilder.setId(SUBNET_0);
425         localSubnetBuilder.setParent(L2FD_ID);
426         Subnet localSubnet = localSubnetBuilder.build();
427
428         SubnetBuilder destSubnetBuilder = new SubnetBuilder();
429         destSubnetBuilder.setId(SUBNET_1);
430         Subnet destSubnet = destSubnetBuilder.build();
431
432         flows.createLocalL3RoutedFlow(tableId, 80, endpoint, null, localSubnet, destSubnet, ofWriter);
433
434         verifyZeroInteractions(ofWriter);
435     }
436
437     @Test
438     public void createLocalL3RoutedFlow_sameSubnetIdAndExceptionCaught() {
439         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue());
440         OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
441         ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(CONNECTOR_1));
442         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, connectorId);
443         endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
444         endpointBuilder.setNetworkContainment(SUBNET_0);
445         endpointBuilder.setTenant(getTestIndexedTenant().getTenant().getId());
446         Endpoint endpoint = endpointBuilder.build();
447
448         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
449         localSubnetBuilder.setId(SUBNET_0);
450         localSubnetBuilder.setParent(L2FD_ID);
451         Subnet localSubnet = localSubnetBuilder.build();
452
453         SubnetBuilder destSubnetBuilder = new SubnetBuilder();
454         destSubnetBuilder.setId(SUBNET_1);
455         destSubnetBuilder.setParent(L2FD_ID);
456         Subnet destSubnet = destSubnetBuilder.build();
457
458         flows.createLocalL3RoutedFlow(tableId, 80, endpoint, null, localSubnet, destSubnet, ofWriter);
459
460         verifyZeroInteractions(ofWriter);
461     }
462
463     @Test
464     public void createLocalL3RoutedFlow_noIp() {
465         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue());
466         OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
467         ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(OPENFLOW + CONNECTOR_1));
468         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, connectorId);
469         endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
470         endpointBuilder.setTenant(getTestIndexedTenant().getTenant().getId());
471         Endpoint endpoint = endpointBuilder.build();
472
473         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
474         localSubnetBuilder.setId(SUBNET_0).setParent(L2FD_ID);
475         Subnet localSubnet = localSubnetBuilder.build();
476
477         SubnetBuilder destSubnetBuilder = new SubnetBuilder();
478         destSubnetBuilder.setId(SUBNET_1);
479         Subnet destSubnet = destSubnetBuilder.build();
480
481         L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();
482         l3AddressBuilder.setIpAddress(null);
483         L3Address l3Address = l3AddressBuilder.build();
484
485         flows.createLocalL3RoutedFlow(tableId, 80, endpoint, l3Address, localSubnet, destSubnet, ofWriter);
486
487         verifyZeroInteractions(ofWriter);
488     }
489
490     @Test
491     public void createLocalL3RoutedFlow_ipV4() {
492         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue());
493         MacAddress destMac = DestinationMapper.ROUTER_MAC;
494         OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
495         ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(connectorId));
496         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, connectorId);
497         endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
498         endpointBuilder.setTenant(getTestIndexedTenant().getTenant().getId());
499         endpointBuilder.setNetworkContainment(SUBNET_0);
500         Endpoint endpoint = endpointBuilder.build();
501
502         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
503         localSubnetBuilder.setId(SUBNET_0);
504         localSubnetBuilder.setParent(L2FD_ID);
505         Subnet localSubnet = localSubnetBuilder.build();
506
507         SubnetBuilder destSubnetBuilder = new SubnetBuilder();
508         destSubnetBuilder.setId(SUBNET_1);
509         destSubnetBuilder.setParent(L2FD_ID);
510         Subnet destSubnet = destSubnetBuilder.build();
511
512         L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();
513         l3AddressBuilder.setIpAddress(new IpAddress((IPV4_0)));
514         L3Address l3Address = l3AddressBuilder.build();
515
516         List<Action> l3ApplyActions = new ArrayList<>();
517         l3ApplyActions.add(setDlDstAction((MAC_1)));
518         l3ApplyActions.add(decNwTtlAction());
519         l3ApplyActions.add(setDlSrcAction(destMac));
520
521         List<Action> applyActions = new ArrayList<>();
522         applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1)));
523         applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0)));
524         applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0)));
525         applyActions.addAll(l3ApplyActions);
526
527         int order = 0;
528         Instruction applyActionsIns = new InstructionBuilder().setOrder(order++)
529             .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
530             .build();
531         Instruction gotoTable = new InstructionBuilder().setOrder(order).setInstruction(gotoTableIns(tableId)).build();
532         ArrayList<Instruction> l3instructions = new ArrayList<>();
533         l3instructions.add(applyActionsIns);
534         l3instructions.add(gotoTable);
535
536         MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, destMac, IPv4))
537             .setLayer3Match(new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(IPV4_0.getValue() + IP_PREFIX_32))
538                 .build());
539         addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 5));
540         Match match = matchBuilder.build();
541         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
542         instructionsBuilder.setInstruction(l3instructions);
543
544         Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "localL3", match), tableId, 80, match,
545                 instructionsBuilder.build()).build();
546
547         flows.createLocalL3RoutedFlow(tableId, 80, endpoint, l3Address, localSubnet, destSubnet, ofWriter);
548
549         verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow));
550     }
551
552     @Test
553     public void createLocalL3RoutedFlow_ipV6() {
554         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue());
555         MacAddress destMac = DestinationMapper.ROUTER_MAC;
556         OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
557         ofOverlayContextBuilder.setNodeConnectorId(connectorId);
558         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, connectorId);
559         endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
560         endpointBuilder.setTenant(getTestIndexedTenant().getTenant().getId());
561         endpointBuilder.setNetworkContainment(SUBNET_0);
562         Endpoint endpoint = endpointBuilder.build();
563
564         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
565         localSubnetBuilder.setId(SUBNET_0);
566         localSubnetBuilder.setParent(L2FD_ID);
567         Subnet localSubnet = localSubnetBuilder.build();
568
569         SubnetBuilder destSubnetBuilder = new SubnetBuilder();
570         destSubnetBuilder.setId(SUBNET_1);
571         destSubnetBuilder.setParent(L2FD_ID);
572         Subnet destSubnet = destSubnetBuilder.build();
573
574         L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();
575         l3AddressBuilder.setIpAddress(new IpAddress((IPV6_1)));
576         L3Address l3Address = l3AddressBuilder.build();
577
578         List<Action> l3ApplyActions = new ArrayList<>();
579         l3ApplyActions.add(setDlDstAction(MAC_1));
580         l3ApplyActions.add(decNwTtlAction());
581         l3ApplyActions.add(setDlSrcAction(destMac));
582
583         List<Action> applyActions = new ArrayList<>();
584         applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1)));
585         applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0)));
586         applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0)));
587         applyActions.addAll(l3ApplyActions);
588
589         int order = 0;
590         Instruction applyActionsIns = new InstructionBuilder().setOrder(order++)
591             .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
592             .build();
593         Instruction gotoTable = new InstructionBuilder().setOrder(order).setInstruction(gotoTableIns(tableId)).build();
594         ArrayList<Instruction> l3instructions = new ArrayList<>();
595         l3instructions.add(applyActionsIns);
596         l3instructions.add(gotoTable);
597
598         MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, destMac, IPv6))
599             .setLayer3Match(new Ipv6MatchBuilder().setIpv6Destination(new Ipv6Prefix(IPV6_1.getValue() + IP_PREFIX_128))
600                 .build());
601         addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 5));
602         Match match = matchBuilder.build();
603         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
604         instructionsBuilder.setInstruction(l3instructions);
605
606         Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "localL3", match), tableId, 80, match,
607                 instructionsBuilder.build()).build();
608
609         flows.createLocalL3RoutedFlow(tableId, 80, endpoint, l3Address, localSubnet, destSubnet, ofWriter);
610
611         verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow));
612     }
613
614     @Test
615     public void createRemoteL2Flow_exceptionCaught() {
616         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, CONNECTOR_0);
617
618         flows.createRemoteL2Flow(tableId, 70, endpointBuilder.build(), null, null, new NodeConnectorId(CONNECTOR_1),
619                 ofWriter);
620
621         verifyZeroInteractions(ofWriter);
622     }
623
624     @Test
625     public void createRemoteL2Flow_ipV4() {
626         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_1.getValue());
627         IpAddress ipAddress = new IpAddress(IPV4_0);
628         Endpoint endpoint = buildEndpoint(IPV4_0, MAC_1, CONNECTOR_0).setTenant(tenant.getId()).build();
629         Endpoint peerEndpoint = buildEndpoint(IPV4_1, MAC_0, CONNECTOR_1).build();
630
631         List<Action> applyActions = new ArrayList<>();
632         applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1)));
633         applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0)));
634         applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(1)));
635         applyActions.add(nxLoadTunIPv4Action(ipAddress.getIpv4Address().getValue(), false));
636
637         int order = 0;
638         Instruction applyActionsIns = new InstructionBuilder().setOrder(order++)
639             .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
640             .build();
641         Instruction gotoTable = new InstructionBuilder().setOrder(order).setInstruction(gotoTableIns(tableId)).build();
642
643         ArrayList<Instruction> instructions = new ArrayList<>();
644         instructions.add(applyActionsIns);
645         instructions.add(gotoTable);
646         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
647         instructionsBuilder.setInstruction(instructions);
648
649         MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, MAC_0, null));
650         OrdinalFactory.EndpointFwdCtxOrdinals ord = utils.getEndpointOrdinals(endpoint);
651         addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg4.class, (long) ord.getBdId()));
652         Match match = matchBuilder.build();
653
654         Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "remoteL2", match), tableId, 70, match,
655                 instructionsBuilder.build()).build();
656
657         flows.createRemoteL2Flow(tableId, 70, endpoint, peerEndpoint, ipAddress, connectorId, ofWriter);
658
659         verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow));
660     }
661
662     @Test
663     public void createRemoteL2Flow_ipV6() {
664         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_1);
665         IpAddress ipAddress = new IpAddress(new Ipv6Address(IPV6_1));
666         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, CONNECTOR_0);
667         EndpointBuilder peerEndpointBuilder = buildEndpoint(IPV6_2, MAC_0, CONNECTOR_0);
668
669         flows.createRemoteL2Flow(tableId, 70, endpointBuilder.build(), peerEndpointBuilder.build(), ipAddress,
670                 connectorId, ofWriter);
671
672         verifyZeroInteractions(ofWriter);
673     }
674
675     @Test
676     public void createRemoteL3RoutedFlow_noL3Context() {
677         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, CONNECTOR_0);
678         Endpoint endpoint = endpointBuilder.build();
679         flows.createRemoteL3RoutedFlow(tableId, 60, endpoint, null, null, null, null, null, ofWriter);
680         verifyZeroInteractions(ofWriter);
681     }
682
683     @Test
684     public void createRemoteL3RoutedFlow_noMac() {
685         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, CONNECTOR_0);
686         endpointBuilder.setMacAddress(null);
687         Endpoint endpoint = endpointBuilder.build();
688
689         SubnetBuilder destSubnetBuilder = new SubnetBuilder();
690         destSubnetBuilder.setId(SUBNET_0);
691         destSubnetBuilder.setParent(L2FD_ID);
692         Subnet destSubnet = destSubnetBuilder.build();
693
694         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
695         localSubnetBuilder.setId(SUBNET_1);
696         localSubnetBuilder.setVirtualRouterIp(new IpAddress(IPV4_1));
697         localSubnetBuilder.setParent(L2FD_ID);
698         Subnet localSubnet = localSubnetBuilder.build();
699
700         flows.createRemoteL3RoutedFlow(tableId, 60, endpoint, null, destSubnet, null, null, localSubnet, ofWriter);
701
702         verifyZeroInteractions(ofWriter);
703     }
704
705     @Test
706     public void createRemoteL3RoutedFlow_noIp() {
707         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, CONNECTOR_0);
708         endpointBuilder.setNetworkContainment(SUBNET_0);
709         Endpoint endpoint = endpointBuilder.build();
710
711         SubnetBuilder destSubnetBuilder = new SubnetBuilder();
712         destSubnetBuilder.setId(SUBNET_1);
713         destSubnetBuilder.setParent(L2FD_ID);
714         Subnet destSubnet = destSubnetBuilder.build();
715
716         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
717         localSubnetBuilder.setId(SUBNET_0);
718         localSubnetBuilder.setVirtualRouterIp(new IpAddress(IPV4_1));
719         localSubnetBuilder.setParent(L2FD_ID);
720         Subnet localSubnet = localSubnetBuilder.build();
721
722         flows.createRemoteL3RoutedFlow(tableId, 60, endpoint, null, destSubnet, null, null, localSubnet, ofWriter);
723
724         verifyZeroInteractions(ofWriter);
725     }
726
727     @Test
728     public void createRemoteL3RoutedFlow_incorrectPortId() {
729         IpAddress ipAddress = new IpAddress(IPV4_0);
730         NodeConnectorId connectorId = new NodeConnectorId(CONNECTOR_0);
731         EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, CONNECTOR_0);
732         endpointBuilder.setNetworkContainment(SUBNET_0);
733         Endpoint endpoint = endpointBuilder.build();
734
735         SubnetBuilder destSubnetBuilder = new SubnetBuilder();
736         destSubnetBuilder.setId(SUBNET_1);
737         destSubnetBuilder.setParent(L2FD_ID);
738         Subnet destSubnet = destSubnetBuilder.build();
739
740         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
741         localSubnetBuilder.setId(SUBNET_0);
742         localSubnetBuilder.setVirtualRouterIp(new IpAddress(IPV4_1));
743         Subnet localSubnet = localSubnetBuilder.build();
744
745         flows.createRemoteL3RoutedFlow(tableId, 60, endpoint, null, destSubnet, ipAddress, connectorId, localSubnet,
746                 ofWriter);
747
748         verifyZeroInteractions(ofWriter);
749     }
750
751     @Test
752     public void createRemoteL3RoutedFlow_ipV4() {
753         MacAddress routerMac = DestinationMapper.ROUTER_MAC;
754         IpAddress ipAddress = new IpAddress(IPV4_1);
755         L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();
756         l3AddressBuilder.setIpAddress(new IpAddress(IPV4_1));
757         L3Address l3Address = l3AddressBuilder.build();
758         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue());
759         EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_1, CONNECTOR_0);
760         Endpoint endpoint = endpointBuilder.build();
761
762         SubnetBuilder destSubnetBuilder = new SubnetBuilder();
763         destSubnetBuilder.setId(SUBNET_1);
764         destSubnetBuilder.setParent(L2FD_ID);
765         Subnet destSubnet = destSubnetBuilder.build();
766
767         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
768         localSubnetBuilder.setId(SUBNET_0);
769         localSubnetBuilder.setVirtualRouterIp(new IpAddress(IPV4_1));
770         localSubnetBuilder.setParent(L2FD_ID);
771         Subnet localSubnet = localSubnetBuilder.build();
772
773         List<Action> l3ApplyActions = new ArrayList<>();
774         l3ApplyActions.add(setDlSrcAction(routerMac));
775         l3ApplyActions.add(setDlDstAction(MAC_1));
776         l3ApplyActions.add(decNwTtlAction());
777         List<Action> applyActions = new ArrayList<>();
778         applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1)));
779         applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0)));
780         applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0)));
781         applyActions.add(nxLoadTunIPv4Action(IPV4_1.getValue(), false));
782         applyActions.addAll(l3ApplyActions);
783         Instruction applyActionsIns = new InstructionBuilder().setOrder(0)
784             .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
785             .build();
786         Instruction gotoTable = new InstructionBuilder().setOrder(1).setInstruction(gotoTableIns(tableId)).build();
787         ArrayList<Instruction> l3instructions = new ArrayList<>();
788         l3instructions.add(applyActionsIns);
789         l3instructions.add(gotoTable);
790         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
791         instructionsBuilder.setInstruction(l3instructions);
792
793         MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, routerMac, IPv4))
794             .setLayer3Match(new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(IPV4_1.getValue() + IP_PREFIX_32))
795                 .build());
796         addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 5));
797         Match match = matchBuilder.build();
798
799         Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "remoteL3", match), tableId, 60, match,
800                 instructionsBuilder.build()).build();
801
802         flows.createRemoteL3RoutedFlow(tableId, 60, endpoint, l3Address, destSubnet, ipAddress, connectorId,
803                 localSubnet, ofWriter);
804
805         verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow));
806     }
807
808     @Test
809     public void createRemoteL3RoutedFlow_ipV6() {
810         IpAddress ipAddress = new IpAddress(new Ipv6Address(IPV6_1));
811         L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();
812         l3AddressBuilder.setIpAddress(new IpAddress(IPV4_1));
813         L3Address l3Address = l3AddressBuilder.build();
814         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0);
815         EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_1, CONNECTOR_0);
816         Endpoint endpoint = endpointBuilder.build();
817
818         SubnetBuilder destSubnetBuilder = new SubnetBuilder();
819         destSubnetBuilder.setId(SUBNET_1);
820         destSubnetBuilder.setParent(L2FD_ID);
821         Subnet destSubnet = destSubnetBuilder.build();
822
823         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
824         localSubnetBuilder.setId(SUBNET_0);
825         localSubnetBuilder.setParent(L2FD_ID);
826         localSubnetBuilder.setVirtualRouterIp(new IpAddress(IPV4_1));
827         Subnet localSubnet = localSubnetBuilder.build();
828
829         flows.createRemoteL3RoutedFlow(tableId, 60, endpoint, l3Address, destSubnet, ipAddress, connectorId,
830                 localSubnet, ofWriter);
831
832         verifyZeroInteractions(ofWriter);
833     }
834
835     @Test
836     public void createRouterArpFlow_nullL3SubnetContext() throws Exception {
837         IndexedTenant tenant = getTestIndexedTenant();
838         SubnetBuilder subnetBuilder = new SubnetBuilder();
839         subnetBuilder.setId(new SubnetId("otherSubnet"));
840         flows.createRouterArpFlow(50, tenant, subnetBuilder.build(), ofWriter);
841         verifyZeroInteractions(ofWriter);
842     }
843
844     @Test
845     public void createRouterArpFlow_ipV4() throws Exception {
846         IndexedTenant tenant = getTestIndexedTenant();
847         SubnetBuilder subnetBuilder = new SubnetBuilder();
848         subnetBuilder.setId(SUBNET_0);
849         subnetBuilder.setParent(L2FD_ID);
850         subnetBuilder.setVirtualRouterIp(new IpAddress(IPV4_0));
851
852         MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, null, ARP))
853             .setLayer3Match(new ArpMatchBuilder().setArpOp(1)
854                 .setArpTargetTransportAddress(new Ipv4Prefix(IPV4_0.getValue() + IP_PREFIX_32))
855                 .build());
856         addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 5));
857         Match match = matchBuilder.build();
858
859         List<Action> actions = new ArrayList<>();
860         actions.add(nxMoveEthSrcToEthDstAction());
861         actions.add(setDlSrcAction(DestinationMapper.ROUTER_MAC));
862         actions.add(nxLoadArpOpAction(BigInteger.valueOf(2L)));
863         actions.add(nxMoveArpShaToArpThaAction());
864         actions.add(nxLoadArpShaAction(new BigInteger(1, bytesFromHexString(DestinationMapper.ROUTER_MAC.getValue()))));
865         actions.add(nxMoveArpSpaToArpTpaAction());
866         actions.add(nxLoadArpSpaAction(IPV4_0.getValue()));
867         actions.add(outputAction(new NodeConnectorId(NODE_ID.getValue() + ":INPORT")));
868         List<Instruction> instructions = new ArrayList<>();
869         InstructionBuilder instructionBuilder = new InstructionBuilder();
870         instructionBuilder.setInstruction(applyActionIns(actions.toArray(new Action[actions.size()]))).setOrder(0);
871         instructions.add(instructionBuilder.build());
872         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
873         instructionsBuilder.setInstruction(instructions);
874
875         Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "routerarp", match), tableId, 50, match,
876                 instructionsBuilder.build()).build();
877
878         flows.createRouterArpFlow(50, tenant, subnetBuilder.build(), ofWriter);
879
880         verify(ofWriter, times(1)).writeFlow(any(NodeId.class), anyShort(), eq(flow));
881     }
882
883     @Test
884     public void createRouterArpFlow_ipV6() throws Exception {
885         IndexedTenant tenant = getTestIndexedTenant();
886         SubnetBuilder subnetBuilder = new SubnetBuilder();
887         subnetBuilder.setId(SUBNET_1);
888         subnetBuilder.setParent(L2FD_ID);
889         subnetBuilder.setVirtualRouterIp(new IpAddress(IPV6_1));
890
891         flows.createRouterArpFlow(50, tenant, subnetBuilder.build(), ofWriter);
892
893         verifyZeroInteractions(ofWriter);
894     }
895
896     @Test
897     public void createBroadcastFlow() {
898         DestinationMapperUtils utils = new DestinationMapperUtils(ctx);
899         EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_1, CONNECTOR_1);
900         endpointBuilder.setTenant(buildTenant().getId());
901
902         OrdinalFactory.EndpointFwdCtxOrdinals ordinals = utils.getEndpointOrdinals(endpointBuilder.build());
903
904         MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(new EthernetMatchBuilder()
905             .setEthernetDestination(new EthernetDestinationBuilder().setAddress(MAC_0).setMask(MAC_0).build()).build());
906         addNxRegMatch(matchBuilder, FlowUtils.RegMatch.of(NxmNxReg5.class, (long) ordinals.getFdId()));
907         Match match = matchBuilder.build();
908         List<Action> actions = new ArrayList<>();
909         actions.add(nxLoadTunIdAction(BigInteger.valueOf(ordinals.getFdId()), false));
910         actions.add(groupAction((long) ordinals.getFdId()));
911         List<Instruction> instructions = new ArrayList<>();
912         InstructionBuilder instructionBuilder = new InstructionBuilder();
913         instructionBuilder.setInstruction(applyActionIns(actions.toArray(new Action[actions.size()]))).setOrder(0);
914         instructions.add(instructionBuilder.build());
915         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
916         instructionsBuilder.setInstruction(instructions);
917
918         Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "broadcast", match), tableId, 40, match,
919                 instructionsBuilder.build()).build();
920
921         flows.createBroadcastFlow(40, ordinals, MAC_0, ofWriter);
922
923         verify(ofWriter, times(1)).writeFlow(any(NodeId.class), anyShort(), eq(flow));
924     }
925
926     @Test
927     public void createL3PrefixFlow_internalExceptionCaught() {
928         EndpointBuilder gatewayEp = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0);
929         OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
930         ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(CONNECTOR_1));
931         gatewayEp.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
932
933         IndexedTenant tenant = getTestIndexedTenant();
934         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
935         localSubnetBuilder.setId(SUBNET_1);
936         localSubnetBuilder.setVirtualRouterIp(new IpAddress((IPV4_0)));
937         localSubnetBuilder.setParent(L2FD_ID);
938         Subnet localSubnet = localSubnetBuilder.build();
939
940         flows.createL3PrefixFlow(tableId, 30, gatewayEp.build(), null, tenant, localSubnet, null, ofWriter);
941
942         verifyZeroInteractions(ofWriter);
943     }
944
945     @Test
946     public void createL3PrefixFlow_externalExceptionCaught() {
947         EndpointBuilder gatewayEpBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0);
948         OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
949         ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(CONNECTOR_1));
950         gatewayEpBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
951         gatewayEpBuilder.setEndpointGroup(ENDPOINT_GROUP_0);
952
953         TenantBuilder tenantBuilder = new TenantBuilder(getTestIndexedTenant().getTenant());
954         List<ExternalImplicitGroup> externalImplicitGroups = new ArrayList<>();
955         ExternalImplicitGroupBuilder externalImplicitGroupBuilder = new ExternalImplicitGroupBuilder();
956         externalImplicitGroupBuilder.setId(ENDPOINT_GROUP_0);
957         externalImplicitGroups.add(externalImplicitGroupBuilder.build());
958         tenantBuilder.setPolicy(new PolicyBuilder().setExternalImplicitGroup(externalImplicitGroups).build());
959         IndexedTenant tenant = new IndexedTenant(tenantBuilder.build());
960
961         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
962         localSubnetBuilder.setId(SUBNET_1);
963         localSubnetBuilder.setVirtualRouterIp(new IpAddress(IPV4_0));
964         localSubnetBuilder.setParent(L2FD_ID);
965         Subnet localSubnet = localSubnetBuilder.build();
966
967         Set<NodeConnectorId> externalPorts = new HashSet<>();
968         externalPorts.add(new NodeConnectorId(CONNECTOR_0));
969         externalPorts.add(new NodeConnectorId(CONNECTOR_1));
970
971         flows.createL3PrefixFlow(tableId, 30, gatewayEpBuilder.build(), null, tenant, localSubnet, externalPorts,
972                 ofWriter);
973
974         verifyZeroInteractions(ofWriter);
975     }
976
977     @Test
978     public void createL3PrefixFlow_internalIpV4() {
979         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue());
980         EndpointBuilder gatewayEp = buildEndpoint(IPV4_0, MAC_0, connectorId);
981         OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
982         ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(OPENFLOW + CONNECTOR_1.getValue()));
983         gatewayEp.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
984
985         EndpointL3PrefixBuilder l3PrefixBuilder = new EndpointL3PrefixBuilder();
986         l3PrefixBuilder.setIpPrefix(new IpPrefix(new Ipv4Prefix(IPV4_0.getValue() + IP_PREFIX_32)));
987         EndpointL3Prefix l3Prefix = l3PrefixBuilder.build();
988
989         IndexedTenant tenant = getTestIndexedTenant();
990         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
991         localSubnetBuilder.setId(SUBNET_0);
992         localSubnetBuilder.setParent(L2FD_ID);
993         localSubnetBuilder.setVirtualRouterIp(new IpAddress(IPV4_0));
994         Subnet localSubnet = localSubnetBuilder.build();
995
996         List<Action> l3ApplyActions = new ArrayList<>();
997         l3ApplyActions.add(setDlDstAction(MAC_0));
998         l3ApplyActions.add(decNwTtlAction());
999         List<Action> applyActions = new ArrayList<>();
1000         applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1)));
1001         applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0)));
1002         applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(1)));
1003         applyActions.addAll(l3ApplyActions);
1004         Instruction applyActionsIns = new InstructionBuilder().setOrder(0)
1005             .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
1006             .build();
1007         Instruction gotoTable = new InstructionBuilder().setOrder(1).setInstruction(gotoTableIns(tableId)).build();
1008         ArrayList<Instruction> l3instructions = new ArrayList<>();
1009         l3instructions.add(applyActionsIns);
1010         l3instructions.add(gotoTable);
1011         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
1012         instructionsBuilder.setInstruction(l3instructions);
1013
1014         MatchBuilder matchBuilder =
1015                 new MatchBuilder().setEthernetMatch(ethernetMatch(null, DestinationMapper.ROUTER_MAC, IPv4));
1016         addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 5));
1017         Match match = matchBuilder.build();
1018
1019         Integer prefixLength = Integer.valueOf(l3Prefix.getIpPrefix().getIpv4Prefix().getValue().split("/")[1]);
1020         Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "L3prefix", match), tableId, 30 + prefixLength, match,
1021                 instructionsBuilder.build()).build();
1022
1023         flows.createL3PrefixFlow(tableId, 30, gatewayEp.build(), l3Prefix, tenant, localSubnet, null, ofWriter);
1024
1025         verify(ofWriter, times(1)).writeFlow(any(NodeId.class), anyShort(), eq(flow));
1026     }
1027
1028     @Test
1029     public void createL3PrefixFlow_externalIpv6() throws Exception {
1030         NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue());
1031         EndpointBuilder gatewayEpBuilder = buildEndpoint(IPV6_1, MAC_0, connectorId);
1032         gatewayEpBuilder.setNetworkContainment(SUBNET_0);
1033
1034         OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
1035         ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(OPENFLOW + CONNECTOR_1));
1036         gatewayEpBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
1037         gatewayEpBuilder.setEndpointGroup(ENDPOINT_GROUP_0);
1038
1039         TenantBuilder tenantBuilder = new TenantBuilder(getTestIndexedTenant().getTenant());
1040         List<ExternalImplicitGroup> externalImplicitGroups = new ArrayList<>();
1041         ExternalImplicitGroupBuilder externalImplicitGroupBuilder = new ExternalImplicitGroupBuilder();
1042         externalImplicitGroupBuilder.setId(ENDPOINT_GROUP_0);
1043         externalImplicitGroups.add(externalImplicitGroupBuilder.build());
1044         tenantBuilder.setPolicy(new PolicyBuilder().setExternalImplicitGroup(externalImplicitGroups).build());
1045         IndexedTenant tenant = new IndexedTenant(tenantBuilder.build());
1046
1047         SubnetBuilder localSubnetBuilder = new SubnetBuilder();
1048         localSubnetBuilder.setId(SUBNET_0);
1049         localSubnetBuilder.setVirtualRouterIp(new IpAddress(IPV6_2));
1050         localSubnetBuilder.setParent(L2FD_ID);
1051         Subnet localSubnet = localSubnetBuilder.build();
1052
1053         Set<NodeConnectorId> externalPorts = new HashSet<>();
1054         externalPorts.add(new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue()));
1055         externalPorts.add(new NodeConnectorId(OPENFLOW + CONNECTOR_1.getValue()));
1056
1057         EndpointL3PrefixBuilder l3PrefixBuilder = new EndpointL3PrefixBuilder();
1058         l3PrefixBuilder.setIpPrefix(new IpPrefix(new Ipv6Prefix(IPV6_1.getValue() + IP_PREFIX_128)));
1059         EndpointL3Prefix l3Prefix = l3PrefixBuilder.build();
1060
1061         List<Action> l3ApplyActions = new ArrayList<>();
1062         l3ApplyActions.add(setDlDstAction(MAC_0));
1063         l3ApplyActions.add(decNwTtlAction());
1064         List<Action> applyActions = new ArrayList<>();
1065         applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1)));
1066         applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0)));
1067         applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0)));
1068         applyActions.addAll(l3ApplyActions);
1069         Instruction applyActionsIns = new InstructionBuilder().setOrder(0)
1070             .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()])))
1071             .build();
1072         Instruction gotoTable = new InstructionBuilder().setOrder(1).setInstruction(gotoTableIns(tableId)).build();
1073         ArrayList<Instruction> l3instructions = new ArrayList<>();
1074         l3instructions.add(applyActionsIns);
1075         l3instructions.add(gotoTable);
1076         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
1077         instructionsBuilder.setInstruction(l3instructions);
1078
1079         MatchBuilder matchBuilder =
1080                 new MatchBuilder().setEthernetMatch(ethernetMatch(null, DestinationMapper.ROUTER_MAC, IPv6));
1081         addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 5));
1082         Match match = matchBuilder.build();
1083
1084         Integer prefixLength = Integer.valueOf(l3Prefix.getIpPrefix().getIpv6Prefix().getValue().split("/")[1]);
1085         Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "L3prefix", match), tableId, 30 + prefixLength, match,
1086                 instructionsBuilder.build()).build();
1087
1088         flows.createL3PrefixFlow(tableId, 30, gatewayEpBuilder.build(), l3Prefix, tenant, localSubnet, externalPorts,
1089                 ofWriter);
1090
1091         verify(ofWriter, times(1)).writeFlow(any(NodeId.class), anyShort(), eq(flow));
1092     }
1093
1094 }