DROP and FLOOD/Broadcast Support
[netvirt.git] / neutron / src / main / java / org / opendaylight / ovsdb / neutron / provider / OF13ProviderManager.java
1 /**
2  * Copyright (C) 2013 Red Hat, Inc.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Authors : Madhu Venugopal, Brent Salisbury
9  */
10 package org.opendaylight.ovsdb.neutron.provider;
11
12 import java.math.BigInteger;
13 import java.net.InetAddress;
14 import java.util.ArrayList;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Set;
18 import java.util.concurrent.ExecutionException;
19 import java.util.concurrent.Future;
20
21 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
22 import org.opendaylight.controller.md.sal.common.api.data.DataModification;
23 import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
24 import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
25 import org.opendaylight.controller.sal.core.Node;
26 import org.opendaylight.controller.sal.utils.HexEncode;
27 import org.opendaylight.controller.sal.utils.ServiceHelper;
28 import org.opendaylight.controller.sal.utils.Status;
29 import org.opendaylight.controller.sal.utils.StatusCode;
30 import org.opendaylight.controller.switchmanager.ISwitchManager;
31 import org.opendaylight.ovsdb.lib.notation.OvsDBMap;
32 import org.opendaylight.ovsdb.lib.notation.OvsDBSet;
33 import org.opendaylight.ovsdb.lib.notation.UUID;
34 import org.opendaylight.ovsdb.lib.table.Bridge;
35 import org.opendaylight.ovsdb.lib.table.Interface;
36 import org.opendaylight.ovsdb.lib.table.Port;
37 import org.opendaylight.ovsdb.neutron.AdminConfigManager;
38 import org.opendaylight.ovsdb.neutron.IMDSALConsumer;
39 import org.opendaylight.ovsdb.neutron.InternalNetworkManager;
40 import org.opendaylight.ovsdb.neutron.TenantNetworkManager;
41 import org.opendaylight.ovsdb.plugin.IConnectionServiceInternal;
42 import org.opendaylight.ovsdb.plugin.OVSDBConfigService;
43 import org.opendaylight.ovsdb.plugin.StatusWithUuid;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DecNwTtlCaseBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCaseBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionCaseBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwSrcActionCaseBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCaseBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.StripVlanActionCaseBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtl;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtlBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropAction;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropActionBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.dst.action._case.SetNwDstActionBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.src.action._case.SetNwSrcActionBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.vlan.id.action._case.SetVlanIdActionBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.strip.vlan.action._case.StripVlanAction;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.strip.vlan.action._case.StripVlanActionBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCaseBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTableBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpSourceHardwareAddressBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpTargetHardwareAddressBuilder;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv4MatchBuilder;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
112 import org.opendaylight.yangtools.yang.binding.DataObject;
113 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
114 import org.opendaylight.yangtools.yang.common.RpcResult;
115 import org.slf4j.Logger;
116 import org.slf4j.LoggerFactory;
117
118
119 /**
120  *
121  */
122 class OF13ProviderManager extends ProviderNetworkManager {
123     private static final Logger logger = LoggerFactory.getLogger(OF13ProviderManager.class);
124     private DataBrokerService dataBrokerService;
125     private static final short TABLE_0_DEFAULT_INGRESS = 0;
126     private static final short TABLE_1_ISOLATE_TENANT = 10;
127     private static final short TABLE_2_LOCAL_FORWARD = 20;
128
129     @Override
130     public boolean hasPerTenantTunneling() {
131         return false;
132     }
133
134     private Status getTunnelReadinessStatus (Node node, String tunnelKey) {
135         InetAddress srcTunnelEndPoint = AdminConfigManager.getManager().getTunnelEndPoint(node);
136         if (srcTunnelEndPoint == null) {
137             logger.error("Tunnel Endpoint not configured for Node {}", node);
138             return new Status(StatusCode.NOTFOUND, "Tunnel Endpoint not configured for "+ node);
139         }
140
141         if (!InternalNetworkManager.getManager().isInternalNetworkNeutronReady(node)) {
142             logger.error(node+" is not Overlay ready");
143             return new Status(StatusCode.NOTACCEPTABLE, node+" is not Overlay ready");
144         }
145
146         if (!TenantNetworkManager.getManager().isTenantNetworkPresentInNode(node, tunnelKey)) {
147             logger.debug(node+" has no VM corresponding to segment "+ tunnelKey);
148             return new Status(StatusCode.NOTACCEPTABLE, node+" has no VM corresponding to segment "+ tunnelKey);
149         }
150         return new Status(StatusCode.SUCCESS);
151     }
152
153     private String getTunnelName(String tunnelType, InetAddress dst) {
154         return tunnelType+"-"+dst.getHostAddress();
155     }
156
157     private boolean isTunnelPresent(Node node, String tunnelName, String bridgeUUID) throws Exception {
158         OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
159         Bridge bridge = (Bridge)ovsdbTable.getRow(node, Bridge.NAME.getName(), bridgeUUID);
160         if (bridge != null) {
161             Set<UUID> ports = bridge.getPorts();
162             for (UUID portUUID : ports) {
163                 Port port = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), portUUID.toString());
164                 if (port != null && port.getName().equalsIgnoreCase(tunnelName)) return true;
165             }
166         }
167         return false;
168     }
169
170     private Status addTunnelPort (Node node, String tunnelType, InetAddress src, InetAddress dst) {
171         try {
172             String bridgeUUID = null;
173             String tunnelBridgeName = AdminConfigManager.getManager().getIntegrationBridgeName();
174             OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
175             Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
176             if (bridgeTable != null) {
177                 for (String uuid : bridgeTable.keySet()) {
178                     Bridge bridge = (Bridge)bridgeTable.get(uuid);
179                     if (bridge.getName().equals(tunnelBridgeName)) {
180                         bridgeUUID = uuid;
181                         break;
182                     }
183                 }
184             }
185             if (bridgeUUID == null) {
186                 logger.error("Could not find Bridge {} in {}", tunnelBridgeName, node);
187                 return new Status(StatusCode.NOTFOUND, "Could not find "+tunnelBridgeName+" in "+node);
188             }
189             String portName = getTunnelName(tunnelType, dst);
190
191             if (this.isTunnelPresent(node, portName, bridgeUUID)) {
192                 logger.trace("Tunnel {} is present in {} of {}", portName, tunnelBridgeName, node);
193                 return new Status(StatusCode.SUCCESS);
194             }
195
196             Port tunnelPort = new Port();
197             tunnelPort.setName(portName);
198             StatusWithUuid statusWithUuid = ovsdbTable.insertRow(node, Port.NAME.getName(), bridgeUUID, tunnelPort);
199             if (!statusWithUuid.isSuccess()) {
200                 logger.error("Failed to insert Tunnel port {} in {}", portName, bridgeUUID);
201                 return statusWithUuid;
202             }
203
204             String tunnelPortUUID = statusWithUuid.getUuid().toString();
205             String interfaceUUID = null;
206             int timeout = 6;
207             while ((interfaceUUID == null) && (timeout > 0)) {
208                 tunnelPort = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), tunnelPortUUID);
209                 OvsDBSet<UUID> interfaces = tunnelPort.getInterfaces();
210                 if (interfaces == null || interfaces.size() == 0) {
211                     // Wait for the OVSDB update to sync up the Local cache.
212                     Thread.sleep(500);
213                     timeout--;
214                     continue;
215                 }
216                 interfaceUUID = interfaces.toArray()[0].toString();
217                 Interface intf = (Interface)ovsdbTable.getRow(node, Interface.NAME.getName(), interfaceUUID);
218                 if (intf == null) interfaceUUID = null;
219             }
220
221             if (interfaceUUID == null) {
222                 logger.error("Cannot identify Tunnel Interface for port {}/{}", portName, tunnelPortUUID);
223                 return new Status(StatusCode.INTERNALERROR);
224             }
225
226             Interface tunInterface = new Interface();
227             tunInterface.setType(tunnelType);
228             OvsDBMap<String, String> options = new OvsDBMap<String, String>();
229             options.put("key", "flow");
230             options.put("local_ip", src.getHostAddress());
231             options.put("remote_ip", dst.getHostAddress());
232             tunInterface.setOptions(options);
233             Status status = ovsdbTable.updateRow(node, Interface.NAME.getName(), tunnelPortUUID, interfaceUUID, tunInterface);
234             logger.debug("Tunnel {} add status : {}", tunInterface, status);
235             return status;
236         } catch (Exception e) {
237             logger.error("Exception in addTunnelPort", e);
238             return new Status(StatusCode.INTERNALERROR);
239         }
240     }
241
242     private void programLocalBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long localPort) {
243          /*
244          * Table(0) Rule #3
245          * ----------------
246          * Match: VM sMac and Local Ingress Port
247          * Action:Action: Set Tunnel ID and GOTO Local Table (5)
248          */
249
250          writeLocalInPort(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_1_ISOLATE_TENANT, segmentationId, localPort, attachedMac);
251
252         /*
253          * Table(0) Rule #4
254          * ----------------
255          * Match: Drop any remaining Ingress Local VM Packets
256          * Action: Drop w/ a low priority
257          */
258
259          writeDropSrcIface(dpid, localPort);
260
261          /*
262           * Table(2) Rule #1
263           * ----------------
264           * Match: Match TunID and Destination DL/dMAC Addr
265           * Action: Output Port
266           * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
267           */
268
269           writeLocalUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, attachedMac);
270
271          /*
272           * Table(2) Rule #2
273           * ----------------
274           * Match: Tunnel ID and dMAC (::::FF:FF)
275           * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
276           * actions=output:2,3,4,5
277           */
278
279           writeLocalBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort);
280
281           /*
282            * TODO : Optimize the following 2 writes to be restricted only for the very first port known in a segment.
283            */
284           /*
285            * Table(1) Rule #3
286            * ----------------
287            * Match:  Any remaining Ingress Local VM Packets
288            * Action: Drop w/ a low priority
289            * -------------------------------------------
290            * table=1,priority=8192,tun_id=0x5 actions=goto_table:2
291            */
292
293            writeTunnelMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId);
294
295           /*
296            * Table(2) Rule #3
297            * ----------------
298            * Match: Any Remaining Flows w/a TunID
299            * Action: Drop w/ a low priority
300            * table=2,priority=8192,tun_id=0x5 actions=drop
301            */
302
303            writeLocalTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId);
304     }
305
306     private void programLocalIngressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
307         /*
308          * Table(0) Rule #2
309          * ----------------
310          * Match: Ingress Port, Tunnel ID
311          * Action: GOTO Local Table (10)
312          */
313
314          writeTunnelIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort);
315     }
316
317     private void programRemoteEgressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
318         /*
319          * Table(1) Rule #1
320          * ----------------
321          * Match: Drop any remaining Ingress Local VM Packets
322          * Action: Drop w/ a low priority
323          * -------------------------------------------
324          * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
325          * actions=output:11,goto_table:2
326          */
327
328         writeTunnelOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, attachedMac);
329
330         /*
331          * Table(1) Rule #2
332          * ----------------
333          * Match: Match Tunnel ID and L2 ::::FF:FF Flooding
334          * Action: Flood to selected destination TEPs
335          * -------------------------------------------
336          * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
337          * actions=output:10,output:11,goto_table:2
338          */
339
340         writeTunnelFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort);
341     }
342
343     private Long getIntegrationBridgeOFDPID (Node node) {
344         try {
345             String bridgeName = AdminConfigManager.getManager().getIntegrationBridgeName();
346             String brIntId = this.getInternalBridgeUUID(node, bridgeName);
347             if (brIntId == null) {
348                 logger.error("Unable to spot Bridge Identifier for {} in {}", bridgeName, node);
349                 return 0L;
350             }
351
352             OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
353             Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brIntId);
354             Set<String> dpids = bridge.getDatapath_id();
355             if (dpids == null || dpids.size() == 0) return 0L;
356             return Long.valueOf(HexEncode.stringToLong((String) dpids.toArray()[0]));
357         } catch (Exception e) {
358             logger.error("Error finding Integration Bridge's OF DPID", e);
359             return 0L;
360         }
361     }
362     private void programLocalRules (String tunnelType, String segmentationId, Node node, Interface intf) {
363         try {
364             Long dpid = this.getIntegrationBridgeOFDPID(node);
365             if (dpid == 0L) {
366                 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
367                 return;
368             }
369
370             Set<BigInteger> of_ports = intf.getOfport();
371             if (of_ports == null || of_ports.size() <= 0) {
372                 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
373                 return;
374             }
375             long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
376
377             Map<String, String> externalIds = intf.getExternal_ids();
378             if (externalIds == null) {
379                 logger.error("No external_ids seen in {}", intf);
380                 return;
381             }
382
383             String attachedMac = externalIds.get(TenantNetworkManager.EXTERNAL_ID_VM_MAC);
384             if (attachedMac == null) {
385                 logger.error("No AttachedMac seen in {}", intf);
386                 return;
387             }
388
389             programLocalBridgeRules(node, dpid, segmentationId, attachedMac, localPort);
390         } catch (Exception e) {
391             logger.error("Exception in programming Local Rules for "+intf+" on "+node, e);
392         }
393     }
394
395     private void programTunnelRules (String tunnelType, String segmentationId, InetAddress dst, Node node,
396             Interface intf, boolean local) {
397         try {
398
399             Long dpid = this.getIntegrationBridgeOFDPID(node);
400             if (dpid == 0L) {
401                 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
402                 return;
403             }
404             OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
405
406             Set<BigInteger> of_ports = intf.getOfport();
407             if (of_ports == null || of_ports.size() <= 0) {
408                 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
409                 return;
410             }
411             long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
412
413             Map<String, String> externalIds = intf.getExternal_ids();
414             if (externalIds == null) {
415                 logger.error("No external_ids seen in {}", intf);
416                 return;
417             }
418
419             String attachedMac = externalIds.get(TenantNetworkManager.EXTERNAL_ID_VM_MAC);
420             if (attachedMac == null) {
421                 logger.error("No AttachedMac seen in {}", intf);
422                 return;
423             }
424
425             Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
426             if (intfs != null) {
427                 for (org.opendaylight.ovsdb.lib.table.internal.Table<?> row : intfs.values()) {
428                     Interface tunIntf = (Interface)row;
429                     if (tunIntf.getName().equals(this.getTunnelName(tunnelType, dst))) {
430                         of_ports = tunIntf.getOfport();
431                         if (of_ports == null || of_ports.size() <= 0) {
432                             logger.error("Could NOT Identify Tunnel port {} on {}", tunIntf.getName(), node);
433                             continue;
434                         }
435                         long tunnelOFPort = ((BigInteger)of_ports.toArray()[0]).longValue();
436
437                         if (tunnelOFPort == -1) {
438                             logger.error("Could NOT Identify Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
439                             return;
440                         }
441                         logger.debug("Identified Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
442
443                         if (!local) {
444                             programRemoteEgressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
445                         }
446                         programLocalIngressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
447                         return;
448                     }
449                 }
450             }
451         } catch (Exception e) {
452             logger.error("", e);
453         }
454     }
455
456     @Override
457     public Status handleInterfaceUpdate(String tunnelType, String tunnelKey, Node srcNode, Interface intf) {
458         ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, "default", this);
459         if (switchManager == null) {
460             logger.error("Unable to identify SwitchManager");
461         } else {
462             Long dpid = this.getIntegrationBridgeOFDPID(srcNode);
463             if (dpid == 0L) {
464                 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", srcNode);
465                 return new Status(StatusCode.NOTFOUND);
466             }
467             Set<Node> ofNodes = switchManager.getNodes();
468             boolean ofNodeFound = false;
469             if (ofNodes != null) {
470                 for (Node ofNode : ofNodes) {
471                     if (ofNode.toString().contains(dpid+"")) {
472                         logger.info("Identified the Openflow node via toString {}", ofNode);
473                         ofNodeFound = true;
474                         break;
475                     }
476                 }
477             } else {
478                 logger.error("Unable to find any Node from SwitchManager");
479             }
480             if (!ofNodeFound) {
481                 logger.error("Unable to find OF Node for {} with update {} on node {}", dpid, intf, srcNode);
482                 return new Status(StatusCode.NOTFOUND);
483             }
484         }
485
486         IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
487         List<Node> nodes = connectionService.getNodes();
488         nodes.remove(srcNode);
489         this.programLocalRules(tunnelType, tunnelKey, srcNode, intf);
490
491         for (Node dstNode : nodes) {
492             Status status = getTunnelReadinessStatus(dstNode, tunnelKey);
493             if (!status.isSuccess()) continue;
494             InetAddress src = AdminConfigManager.getManager().getTunnelEndPoint(srcNode);
495             InetAddress dst = AdminConfigManager.getManager().getTunnelEndPoint(dstNode);
496             status = addTunnelPort(srcNode, tunnelType, src, dst);
497             if (status.isSuccess()) {
498                 this.programTunnelRules(tunnelType, tunnelKey, dst, srcNode, intf, true);
499             }
500             addTunnelPort(dstNode, tunnelType, dst, src);
501             if (status.isSuccess()) {
502                 this.programTunnelRules(tunnelType, tunnelKey, src, dstNode, intf, false);
503             }
504         }
505
506         return new Status(StatusCode.SUCCESS);
507     }
508
509     private Status triggerInterfaceUpdates(Node node) {
510         try {
511             OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
512             Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
513             if (intfs != null) {
514                 for (org.opendaylight.ovsdb.lib.table.internal.Table<?> row : intfs.values()) {
515                     Interface intf = (Interface)row;
516                     NeutronNetwork network = TenantNetworkManager.getManager().getTenantNetworkForInterface(intf);
517                     logger.debug("Trigger Interface update for {}", intf);
518                     if (network != null) {
519                         this.handleInterfaceUpdate(network.getProviderNetworkType(), network.getProviderSegmentationID(), node, intf);
520                     }
521                 }
522             }
523         } catch (Exception e) {
524             logger.error("Error Triggering the lost interface updates for "+ node, e);
525             return new Status(StatusCode.INTERNALERROR, e.getLocalizedMessage());
526         }
527         return new Status(StatusCode.SUCCESS);
528     }
529     @Override
530     public Status handleInterfaceUpdate(String tunnelType, String tunnelKey) {
531         // TODO Auto-generated method stub
532         return null;
533     }
534
535     @Override
536     public Status deleteTunnels(String tunnelType, String tunnelKey, Node source, Interface intf) {
537         // TODO Auto-generated method stub
538         return null;
539     }
540
541     @Override
542     public void initializeFlowRules(Node node) {
543         this.initializeFlowRules(node, AdminConfigManager.getManager().getIntegrationBridgeName());
544         this.triggerInterfaceUpdates(node);
545     }
546
547     /**
548      * @param node
549      * @param bridgeName
550      */
551     private void initializeFlowRules(Node node, String bridgeName) {
552         Long dpid = this.getIntegrationBridgeOFDPID(node);
553         if (dpid == 0L) {
554             logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
555             return;
556         }
557
558         /*
559          * Table(0) Rule #1
560          * ----------------
561          * Match: LLDP (0x88CCL)
562          * Action: Packet_In to Controller Reserved Port
563          */
564
565          writeLLDPRule(dpid);
566     }
567
568     /*
569     * Create an LLDP Flow Rule to encapsulate into
570     * a packet_in that is sent to the controller
571     * for topology handling.
572     * Match: Ethertype 0x88CCL
573     * Action: Punt to Controller in a Packet_In msg
574     */
575
576     private void writeLLDPRule(Long dpidLong) {
577
578         String nodeName = "openflow:" + dpidLong;
579         EtherType etherType = new EtherType(0x88CCL);
580
581         MatchBuilder matchBuilder = new MatchBuilder();
582         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
583         FlowBuilder flowBuilder = new FlowBuilder();
584
585         // Create Match(es) and Set them in the FlowBuilder Object
586         flowBuilder.setMatch(createEtherTypeMatch(matchBuilder, etherType).build());
587
588         // Create the OF Actions and Instructions
589         InstructionBuilder ib = new InstructionBuilder();
590         InstructionsBuilder isb = new InstructionsBuilder();
591
592         // Instructions List Stores Individual Instructions
593         List<Instruction> instructions = new ArrayList<Instruction>();
594
595         // Call the InstructionBuilder Methods Containing Actions
596         createSendToControllerInstructions(ib);
597         instructions.add(ib.build());
598
599         // Add InstructionBuilder to the Instruction(s)Builder List
600         isb.setInstruction(instructions);
601
602         // Add InstructionsBuilder to FlowBuilder
603         flowBuilder.setInstructions(isb.build());
604
605         String flowId = "LLDP";
606         flowBuilder.setId(new FlowId(flowId));
607         FlowKey key = new FlowKey(new FlowId(flowId));
608         flowBuilder.setBarrier(true);
609         flowBuilder.setTableId((short) 0);
610         flowBuilder.setKey(key);
611         flowBuilder.setFlowName(flowId);
612         flowBuilder.setHardTimeout(0);
613         flowBuilder.setIdleTimeout(0);
614         writeFlow(flowBuilder, nodeBuilder);
615     }
616
617     /*
618      * (Table:0) Ingress Tunnel Traffic
619      * Match: OpenFlow InPort and Tunnel ID
620      * Action: GOTO Local Table (10)
621      * table=0,tun_id=0x5,in_port=10, actions=goto_table:2
622      */
623
624     private void writeTunnelIn(Long dpidLong, Short writeTable, Short goToTableId, String segmentationId,  Long ofPort) {
625
626         String nodeName = "openflow:" + dpidLong;
627
628         BigInteger tunnelId = new BigInteger(segmentationId);
629         MatchBuilder matchBuilder = new MatchBuilder();
630         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
631         FlowBuilder flowBuilder = new FlowBuilder();
632
633         // Create Match(es) and Set them in the FlowBuilder Object
634         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, tunnelId).build());
635         flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, ofPort).build());
636
637         // Create the OF Actions and Instructions
638         InstructionBuilder ib = new InstructionBuilder();
639         InstructionsBuilder isb = new InstructionsBuilder();
640
641         // Instructions List Stores Individual Instructions
642         List<Instruction> instructions = new ArrayList<Instruction>();
643
644         // Call the InstructionBuilder Methods Containing Actions
645         createGotoTableInstructions(ib, goToTableId);
646         instructions.add(ib.build());
647
648         // Add InstructionBuilder to the Instruction(s)Builder List
649         isb.setInstruction(instructions);
650
651         // Add InstructionsBuilder to FlowBuilder
652         flowBuilder.setInstructions(isb.build());
653
654         String flowId = "TunnelIn_"+segmentationId+"_"+ofPort;
655         // Add Flow Attributes
656         flowBuilder.setId(new FlowId(flowId));
657         FlowKey key = new FlowKey(new FlowId(flowId));
658         flowBuilder.setBarrier(false);
659         flowBuilder.setTableId(writeTable);
660         flowBuilder.setKey(key);
661         flowBuilder.setFlowName(flowId);
662         flowBuilder.setHardTimeout(0);
663         flowBuilder.setIdleTimeout(0);
664         writeFlow(flowBuilder, nodeBuilder);
665     }
666
667    /*
668     * (Table:0) Egress VM Traffic Towards TEP
669     * Match: Destination Ethernet Addr and OpenFlow InPort
670     * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
671     * table=0,in_port=2,dl_src=00:00:00:00:00:01 \
672     * actions=set_field:5->tun_id,goto_table=1"
673     */
674
675     private void writeLocalInPort(Long dpidLong, Short writeTable, Short goToTableId, String segmentationId, Long inPort, String attachedMac) {
676
677         String nodeName = "openflow:" + dpidLong;
678
679         MatchBuilder matchBuilder = new MatchBuilder();
680         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
681         FlowBuilder flowBuilder = new FlowBuilder();
682
683         // Create the OF Match using MatchBuilder
684         flowBuilder.setMatch(createEthSrcMatch(matchBuilder, new MacAddress(attachedMac)).build());
685         // TODO Broken In_Port Match
686         flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
687
688         // Instantiate the Builders for the OF Actions and Instructions
689         InstructionBuilder ib = new InstructionBuilder();
690         InstructionsBuilder isb = new InstructionsBuilder();
691
692         // Instructions List Stores Individual Instructions
693         List<Instruction> instructions = new ArrayList<Instruction>();
694
695         // GOTO Instuctions Need to be added first to the List
696         createGotoTableInstructions(ib, goToTableId);
697         instructions.add(ib.build());
698         // TODO Broken SetTunID
699         createSetTunnelIdInstructions(ib, new BigInteger(segmentationId));
700         instructions.add(ib.build());
701
702         // Add InstructionBuilder to the Instruction(s)Builder List
703         isb.setInstruction(instructions);
704
705         // Add InstructionsBuilder to FlowBuilder
706         flowBuilder.setInstructions(isb.build());
707
708         String flowId = "LocalMac_"+segmentationId+"_"+inPort+"_"+attachedMac;
709         // Add Flow Attributes
710         flowBuilder.setId(new FlowId(flowId));
711         FlowKey key = new FlowKey(new FlowId(flowId));
712         flowBuilder.setBarrier(false);
713         flowBuilder.setTableId(writeTable);
714         flowBuilder.setKey(key);
715         flowBuilder.setFlowName(flowId);
716         flowBuilder.setHardTimeout(0);
717         flowBuilder.setIdleTimeout(0);
718         writeFlow(flowBuilder, nodeBuilder);
719     }
720
721     /*
722      * (Table:0) Drop frames sourced from a VM that do not
723      * match the associated MAC address of the local VM.
724      * Match: Low priority anything not matching the VM SMAC
725      * Instruction: Drop
726      * table=0,priority=16384,in_port=1 actions=drop"
727      */
728
729     private void writeDropSrcIface(Long dpidLong, Long inPort) {
730
731         String nodeName = "openflow:" + dpidLong;
732
733         MatchBuilder matchBuilder = new MatchBuilder();
734         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
735         FlowBuilder flowBuilder = new FlowBuilder();
736
737         // Create the OF Match using MatchBuilder
738         flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
739
740         // Instantiate the Builders for the OF Actions and Instructions
741         InstructionBuilder ib = new InstructionBuilder();
742         InstructionsBuilder isb = new InstructionsBuilder();
743
744         // Instructions List Stores Individual Instructions
745         List<Instruction> instructions = new ArrayList<Instruction>();
746
747         // Call the InstructionBuilder Methods Containing Actions
748         createDropInstructions(ib);
749         instructions.add(ib.build());
750
751         // Add InstructionBuilder to the Instruction(s)Builder List
752         isb.setInstruction(instructions);
753
754         // Add InstructionsBuilder to FlowBuilder
755         flowBuilder.setInstructions(isb.build());
756
757         String flowId = "DropFilter_"+inPort;
758         // Add Flow Attributes
759         flowBuilder.setId(new FlowId(flowId));
760         FlowKey key = new FlowKey(new FlowId(flowId));
761         flowBuilder.setBarrier(false);
762         flowBuilder.setStrict(true);
763         flowBuilder.setTableId((short) 0);
764         flowBuilder.setKey(key);
765         flowBuilder.setFlowName(flowId);
766         flowBuilder.setPriority(8192);
767         flowBuilder.setHardTimeout(0);
768         flowBuilder.setIdleTimeout(0);
769         writeFlow(flowBuilder, nodeBuilder);
770     }
771
772    /*
773     * (Table:1) Egress Tunnel Traffic
774     * Match: Destination Ethernet Addr and Local InPort
775     * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
776     * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
777     * actions=output:10,goto_table:2"
778     */
779
780     private void writeTunnelOut(Long dpidLong, Short writeTable, Short goToTableId, String segmentationId , Long OFPortOut, String attachedMac) {
781
782         String nodeName = "openflow:" + dpidLong;
783
784         MatchBuilder matchBuilder = new MatchBuilder();
785         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
786         FlowBuilder flowBuilder = new FlowBuilder();
787
788         // Create the OF Match using MatchBuilder
789         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
790         flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
791
792         // Instantiate the Builders for the OF Actions and Instructions
793         InstructionBuilder ib = new InstructionBuilder();
794         InstructionsBuilder isb = new InstructionsBuilder();
795
796         // Instructions List Stores Individual Instructions
797         List<Instruction> instructions = new ArrayList<Instruction>();
798
799         // GOTO Instuctions
800         createGotoTableInstructions(ib, goToTableId);
801         instructions.add(ib.build());
802         // Set the Output Port/Iface
803         createOutputPortInstructions(ib, dpidLong, OFPortOut);
804         instructions.add(ib.build());
805
806         // Add InstructionBuilder to the Instruction(s)Builder List
807         isb.setInstruction(instructions);
808
809         // Add InstructionsBuilder to FlowBuilder
810         flowBuilder.setInstructions(isb.build());
811
812         String flowId = "TunnelOut_"+segmentationId+"_"+OFPortOut+"_"+attachedMac;
813         // Add Flow Attributes
814         flowBuilder.setId(new FlowId(flowId));
815         FlowKey key = new FlowKey(new FlowId(flowId));
816         flowBuilder.setBarrier(false);
817         flowBuilder.setTableId(writeTable);
818         flowBuilder.setKey(key);
819         flowBuilder.setFlowName(flowId);
820         flowBuilder.setHardTimeout(0);
821         flowBuilder.setIdleTimeout(0);
822         writeFlow(flowBuilder, nodeBuilder);
823     }
824
825        /*
826     * (Table:1) Egress Tunnel Traffic
827     * Match: Destination Ethernet Addr and Local InPort
828     * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
829     * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
830     * actions=output:10,output:11,goto_table:2
831     */
832
833     private void writeTunnelFloodOut(Long dpidLong, Short writeTable, Short localTable, String segmentationId,  Long OFPortOut) {
834
835         String nodeName = "openflow:" + dpidLong;
836
837         MatchBuilder matchBuilder = new MatchBuilder();
838         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
839         FlowBuilder flowBuilder = new FlowBuilder();
840
841         // Create the OF Match using MatchBuilder
842         // Match TunnelID
843         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
844         // Match DMAC
845
846         flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
847
848         String flowId = "TunnelFloodOut_"+segmentationId;
849         // Add Flow Attributes
850         flowBuilder.setId(new FlowId(flowId));
851         FlowKey key = new FlowKey(new FlowId(flowId));
852         flowBuilder.setBarrier(true);
853         flowBuilder.setTableId(writeTable);
854         flowBuilder.setKey(key);
855         flowBuilder.setPriority(16384);
856         flowBuilder.setFlowName(flowId);
857         flowBuilder.setHardTimeout(0);
858         flowBuilder.setIdleTimeout(0);
859
860         Flow flow = this.getFlow(flowBuilder, nodeBuilder);
861         // Instantiate the Builders for the OF Actions and Instructions
862         InstructionBuilder ib = new InstructionBuilder();
863         InstructionsBuilder isb = new InstructionsBuilder();
864         List<Instruction> instructions = new ArrayList<Instruction>();
865         List<Instruction> existingInstructions = null;
866         if (flow != null) {
867             Instructions ins = flow.getInstructions();
868             if (ins != null) {
869                 existingInstructions = ins.getInstruction();
870             }
871         }
872         // GOTO Instuction
873         createGotoTableInstructions(ib, localTable);
874         ib.setOrder(0);
875         ib.setKey(new InstructionKey(0));
876         instructions.add(ib.build());
877         // Set the Output Port/Iface
878         createOutputPortInstructions(ib, dpidLong, OFPortOut, existingInstructions);
879         ib.setOrder(1);
880         ib.setKey(new InstructionKey(1));
881         instructions.add(ib.build());
882
883         // Add InstructionBuilder to the Instruction(s)Builder List
884         isb.setInstruction(instructions);
885
886         // Add InstructionsBuilder to FlowBuilder
887         flowBuilder.setInstructions(isb.build());
888
889         writeFlow(flowBuilder, nodeBuilder);
890     }
891
892    /*
893     * (Table:1) Table Drain w/ Catch All
894     * Match: Tunnel ID
895     * Action: GOTO Local Table (10)
896     * table=2,priority=8192,tun_id=0x5 actions=drop
897     */
898
899     private void writeTunnelMiss(Long dpidLong, Short writeTable, Short goToTableId, String segmentationId) {
900
901         String nodeName = "openflow:" + dpidLong;
902
903         MatchBuilder matchBuilder = new MatchBuilder();
904         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
905         FlowBuilder flowBuilder = new FlowBuilder();
906
907         // Create Match(es) and Set them in the FlowBuilder Object
908         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
909
910         // Create the OF Actions and Instructions
911         InstructionBuilder ib = new InstructionBuilder();
912         InstructionsBuilder isb = new InstructionsBuilder();
913
914         // Instructions List Stores Individual Instructions
915         List<Instruction> instructions = new ArrayList<Instruction>();
916
917         // Call the InstructionBuilder Methods Containing Actions
918         createGotoTableInstructions(ib, goToTableId);
919         instructions.add(ib.build());
920
921         // Add InstructionBuilder to the Instruction(s)Builder List
922         isb.setInstruction(instructions);
923
924         // Add InstructionsBuilder to FlowBuilder
925         flowBuilder.setInstructions(isb.build());
926
927         String flowId = "TunnelMiss_"+segmentationId;
928         // Add Flow Attributes
929         flowBuilder.setId(new FlowId(flowId));
930         FlowKey key = new FlowKey(new FlowId(flowId));
931         flowBuilder.setBarrier(false);
932         flowBuilder.setTableId(writeTable);
933         flowBuilder.setKey(key);
934         flowBuilder.setPriority(8192);
935         flowBuilder.setFlowName(flowId);
936         flowBuilder.setHardTimeout(0);
937         flowBuilder.setIdleTimeout(0);
938         writeFlow(flowBuilder, nodeBuilder);
939     }
940
941     /*
942      * (Table:1) Local Broadcast Flood
943      * Match: Tunnel ID and dMAC
944      * Action: Output Port
945      * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
946      */
947
948     private void writeLocalUcastOut(Long dpidLong, Short writeTable, String segmentationId, Long localPort, String attachedMac) {
949
950         String nodeName = "openflow:" + dpidLong;
951
952         MatchBuilder matchBuilder = new MatchBuilder();
953         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
954         FlowBuilder flowBuilder = new FlowBuilder();
955
956         // Create the OF Match using MatchBuilder
957         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
958         flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
959
960         // Instantiate the Builders for the OF Actions and Instructions
961         InstructionBuilder ib = new InstructionBuilder();
962         InstructionsBuilder isb = new InstructionsBuilder();
963
964         // Instructions List Stores Individual Instructions
965         List<Instruction> instructions = new ArrayList<Instruction>();
966
967         // Set the Output Port/Iface
968         createOutputPortInstructions(ib, dpidLong, localPort);
969         instructions.add(ib.build());
970
971         // Add InstructionBuilder to the Instruction(s)Builder List
972         isb.setInstruction(instructions);
973
974         // Add InstructionsBuilder to FlowBuilder
975         flowBuilder.setInstructions(isb.build());
976
977         String flowId = "UcastOut_"+segmentationId+"_"+localPort+"_"+attachedMac;
978         // Add Flow Attributes
979         flowBuilder.setId(new FlowId(flowId));
980         FlowKey key = new FlowKey(new FlowId(flowId));
981         flowBuilder.setBarrier(false);
982         flowBuilder.setTableId(writeTable);
983         flowBuilder.setKey(key);
984         flowBuilder.setFlowName(flowId);
985         flowBuilder.setHardTimeout(0);
986         flowBuilder.setIdleTimeout(0);
987         writeFlow(flowBuilder, nodeBuilder);
988     }
989
990     /*
991      * (Table:1) Local Broadcast Flood
992      * Match: Tunnel ID and dMAC (::::FF:FF)
993      * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
994      * actions=output:2,3,4,5
995      */
996
997     private void writeLocalBcastOut(Long dpidLong, Short writeTable, String segmentationId, Long localPort) {
998
999         String nodeName = "openflow:" + dpidLong;
1000
1001         MatchBuilder matchBuilder = new MatchBuilder();
1002         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1003         FlowBuilder flowBuilder = new FlowBuilder();
1004
1005         // Create the OF Match using MatchBuilder
1006         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
1007         flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
1008
1009         String flowId = "BcastOut_"+segmentationId;
1010         // Add Flow Attributes
1011         flowBuilder.setId(new FlowId(flowId));
1012         FlowKey key = new FlowKey(new FlowId(flowId));
1013         flowBuilder.setBarrier(false);
1014         flowBuilder.setTableId(writeTable);
1015         flowBuilder.setKey(key);
1016         flowBuilder.setPriority(16384);
1017         flowBuilder.setFlowName(flowId);
1018         flowBuilder.setHardTimeout(0);
1019         flowBuilder.setIdleTimeout(0);
1020         Flow flow = this.getFlow(flowBuilder, nodeBuilder);
1021         // Instantiate the Builders for the OF Actions and Instructions
1022         InstructionBuilder ib = new InstructionBuilder();
1023         InstructionsBuilder isb = new InstructionsBuilder();
1024         List<Instruction> instructions = new ArrayList<Instruction>();
1025         List<Instruction> existingInstructions = null;
1026         if (flow != null) {
1027             Instructions ins = flow.getInstructions();
1028             if (ins != null) {
1029                 existingInstructions = ins.getInstruction();
1030             }
1031         }
1032
1033         // Broken OutPort TODO: localPort needs to be a list of Ports)
1034         createOutputPortInstructions(ib, dpidLong, localPort, existingInstructions);
1035         ib.setOrder(0);
1036         ib.setKey(new InstructionKey(0));
1037         instructions.add(ib.build());
1038
1039         // Add InstructionBuilder to the Instruction(s)Builder List
1040         isb.setInstruction(instructions);
1041
1042         // Add InstructionsBuilder to FlowBuilder
1043         flowBuilder.setInstructions(isb.build());
1044
1045         writeFlow(flowBuilder, nodeBuilder);
1046     }
1047
1048     /*
1049      * (Table:1) Local Table Miss
1050      * Match: Any Remaining Flows w/a TunID
1051      * Action: Drop w/ a low priority
1052      * table=2,priority=8192,tun_id=0x5 actions=drop
1053      */
1054
1055     private void writeLocalTableMiss(Long dpidLong, Short writeTable, String segmentationId) {
1056
1057         String nodeName = "openflow:" + dpidLong;
1058
1059         MatchBuilder matchBuilder = new MatchBuilder();
1060         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1061         FlowBuilder flowBuilder = new FlowBuilder();
1062
1063         // Create Match(es) and Set them in the FlowBuilder Object
1064         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
1065
1066         // Create the OF Actions and Instructions
1067         InstructionBuilder ib = new InstructionBuilder();
1068         InstructionsBuilder isb = new InstructionsBuilder();
1069
1070         // Instructions List Stores Individual Instructions
1071         List<Instruction> instructions = new ArrayList<Instruction>();
1072
1073         // Call the InstructionBuilder Methods Containing Actions
1074         createDropInstructions(ib);
1075         instructions.add(ib.build());
1076
1077         // Add InstructionBuilder to the Instruction(s)Builder List
1078         isb.setInstruction(instructions);
1079
1080         // Add InstructionsBuilder to FlowBuilder
1081         flowBuilder.setInstructions(isb.build());
1082
1083         String flowId = "LocalTableMiss_"+segmentationId;
1084         // Add Flow Attributes
1085         flowBuilder.setId(new FlowId(flowId));
1086         FlowKey key = new FlowKey(new FlowId(flowId));
1087         flowBuilder.setBarrier(false);
1088         flowBuilder.setStrict(true);
1089         flowBuilder.setTableId(writeTable);
1090         flowBuilder.setKey(key);
1091         flowBuilder.setPriority(8192);
1092         flowBuilder.setFlowName(flowId);
1093         flowBuilder.setHardTimeout(0);
1094         flowBuilder.setIdleTimeout(0);
1095         writeFlow(flowBuilder, nodeBuilder);
1096     }
1097
1098     private Flow getFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
1099         IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
1100         if (mdsalConsumer == null) {
1101             logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
1102             return null;
1103         }
1104
1105         dataBrokerService = mdsalConsumer.getDataBrokerService();
1106
1107         if (dataBrokerService == null) {
1108             logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
1109             return null;
1110         }
1111
1112         InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
1113                 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class,
1114                 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
1115         return (Flow)dataBrokerService.readConfigurationData(path1);
1116     }
1117
1118     private void writeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
1119         IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
1120         if (mdsalConsumer == null) {
1121             logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
1122             return;
1123         }
1124
1125         dataBrokerService = mdsalConsumer.getDataBrokerService();
1126
1127         if (dataBrokerService == null) {
1128             logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
1129             return;
1130         }
1131         DataModification<InstanceIdentifier<?>, DataObject> modification = dataBrokerService.beginTransaction();
1132         InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
1133                 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class,
1134                 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
1135         modification.putOperationalData(nodeBuilderToInstanceId(nodeBuilder), nodeBuilder.build());
1136         modification.putOperationalData(path1, flowBuilder.build());
1137         modification.putConfigurationData(nodeBuilderToInstanceId(nodeBuilder), nodeBuilder.build());
1138         modification.putConfigurationData(path1, flowBuilder.build());
1139         Future<RpcResult<TransactionStatus>> commitFuture = modification.commit();
1140         try {
1141             RpcResult<TransactionStatus> result = commitFuture.get();
1142             TransactionStatus status = result.getResult();
1143             logger.debug("Transaction Status "+status.toString()+" for Flow "+flowBuilder.getFlowName());
1144         } catch (InterruptedException e) {
1145             logger.error(e.getMessage(), e);
1146         } catch (ExecutionException e) {
1147             logger.error(e.getMessage(), e);
1148         }
1149     }
1150
1151     /**
1152      * Create Ingress Port Match dpidLong, inPort
1153      *
1154      * @param matchBuilder  Map matchBuilder MatchBuilder Object without a match
1155      * @param dpidLong      Long the datapath ID of a switch/node
1156      * @param inPort        Long ingress port on a switch
1157      * @return matchBuilder Map MatchBuilder Object with a match
1158      */
1159     protected static MatchBuilder createInPortMatch(MatchBuilder matchBuilder, Long dpidLong, Long inPort) {
1160
1161         NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + inPort);
1162         logger.debug("createInPortMatch() Node Connector ID is - Type=openflow: DPID={} inPort={} ", dpidLong, inPort);
1163         matchBuilder.setInPort(NodeConnectorId.getDefaultInstance(ncid.getValue()));
1164         matchBuilder.setInPort(ncid);
1165
1166         return matchBuilder;
1167     }
1168
1169     /**
1170      * Create EtherType Match
1171      *
1172      * @param matchBuilder  Map matchBuilder MatchBuilder Object without a match
1173      * @param etherType     Long EtherType
1174      * @return matchBuilder Map MatchBuilder Object with a match
1175      */
1176     protected static MatchBuilder createEtherTypeMatch(MatchBuilder matchBuilder, EtherType etherType) {
1177
1178         EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
1179         EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
1180         ethTypeBuilder.setType(new EtherType(etherType));
1181         ethernetMatch.setEthernetType(ethTypeBuilder.build());
1182         matchBuilder.setEthernetMatch(ethernetMatch.build());
1183
1184         return matchBuilder;
1185     }
1186
1187     /**
1188      * Create Ethernet Source Match
1189      *
1190      * @param matchBuilder  MatchBuilder Object without a match yet
1191      * @param sMacAddr      String representing a source MAC
1192      * @return matchBuilder Map MatchBuilder Object with a match
1193      */
1194     protected static MatchBuilder createEthSrcMatch(MatchBuilder matchBuilder, MacAddress sMacAddr) {
1195
1196         EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
1197         EthernetSourceBuilder ethSourceBuilder = new EthernetSourceBuilder();
1198         ethSourceBuilder.setAddress(new MacAddress(sMacAddr));
1199         ethernetMatch.setEthernetSource(ethSourceBuilder.build());
1200         matchBuilder.setEthernetMatch(ethernetMatch.build());
1201
1202         return matchBuilder;
1203     }
1204
1205     /**
1206      * Create Ethernet Destination Match
1207      *
1208      * @param matchBuilder MatchBuilder Object without a match yet
1209      * @param vlanId       Integer representing a VLAN ID Integer representing a VLAN ID
1210      * @return matchBuilder Map MatchBuilder Object with a match
1211      */
1212
1213     protected static MatchBuilder createVlanIdMatch(MatchBuilder matchBuilder, VlanId vlanId) {
1214
1215         VlanMatchBuilder vlanMatchBuilder = new VlanMatchBuilder();
1216         VlanIdBuilder vlanIdBuilder = new VlanIdBuilder();
1217         vlanIdBuilder.setVlanId(new VlanId(vlanId));
1218         vlanMatchBuilder.setVlanId(vlanIdBuilder.build());
1219         matchBuilder.setVlanMatch(vlanMatchBuilder.build());
1220
1221         return matchBuilder;
1222     }
1223
1224     /**
1225      * Create Ethernet Destination Match
1226      *
1227      * @param matchBuilder  MatchBuilder Object without a match yet
1228      * @param dMacAddr      String representing a destination MAC
1229      * @return matchBuilder Map MatchBuilder Object with a match
1230      */
1231
1232     protected static MatchBuilder createDestEthMatch(MatchBuilder matchBuilder, MacAddress dMacAddr, MacAddress mask) {
1233
1234         EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
1235         EthernetDestinationBuilder ethDestinationBuilder = new EthernetDestinationBuilder();
1236         ethDestinationBuilder.setAddress(new MacAddress(dMacAddr));
1237         if (mask != null) {
1238             ethDestinationBuilder.setMask(mask);
1239         }
1240         ethernetMatch.setEthernetDestination(ethDestinationBuilder.build());
1241         matchBuilder.setEthernetMatch(ethernetMatch.build());
1242
1243         return matchBuilder;
1244     }
1245
1246     /**
1247      * Tunnel ID Match Builder
1248      *
1249      * @param matchBuilder  MatchBuilder Object without a match yet
1250      * @param tunnelId      BigInteger representing a tunnel ID
1251      * @return matchBuilder Map MatchBuilder Object with a match
1252      */
1253     protected static MatchBuilder createTunnelIDMatch(MatchBuilder matchBuilder, BigInteger tunnelId) {
1254
1255         TunnelBuilder tunnelBuilder = new TunnelBuilder();
1256         tunnelBuilder.setTunnelId(tunnelId);
1257         matchBuilder.setTunnel(tunnelBuilder.build());
1258
1259         return matchBuilder;
1260     }
1261
1262     /**
1263      * Match ICMP code and type
1264      *
1265      * @param matchBuilder  MatchBuilder Object without a match yet
1266      * @param type          short representing an ICMP type
1267      * @param code          short representing an ICMP code
1268      * @return matchBuilder Map MatchBuilder Object with a match
1269      */
1270     protected static MatchBuilder createICMPv4Match(MatchBuilder matchBuilder, short type, short code) {
1271
1272         EthernetMatchBuilder eth = new EthernetMatchBuilder();
1273         EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
1274         ethTypeBuilder.setType(new EtherType(0x0800L));
1275         eth.setEthernetType(ethTypeBuilder.build());
1276         matchBuilder.setEthernetMatch(eth.build());
1277
1278         // Build the IPv4 Match requied per OVS Syntax
1279         IpMatchBuilder ipmatch = new IpMatchBuilder();
1280         ipmatch.setIpProtocol((short) 1);
1281         matchBuilder.setIpMatch(ipmatch.build());
1282
1283         // Build the ICMPv4 Match
1284         Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
1285         icmpv4match.setIcmpv4Type(type);
1286         icmpv4match.setIcmpv4Code(code);
1287         matchBuilder.setIcmpv4Match(icmpv4match.build());
1288
1289         return matchBuilder;
1290     }
1291
1292     /**
1293      * @param matchBuilder MatchBuilder Object without a match yet
1294      * @param dstip        String containing an IPv4 prefix
1295      * @return matchBuilder Map Object with a match
1296      */
1297     private static MatchBuilder createDstL3IPv4Match(MatchBuilder matchBuilder, Ipv4Prefix dstip) {
1298
1299         EthernetMatchBuilder eth = new EthernetMatchBuilder();
1300         EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
1301         ethTypeBuilder.setType(new EtherType(0x0800L));
1302         eth.setEthernetType(ethTypeBuilder.build());
1303         matchBuilder.setEthernetMatch(eth.build());
1304
1305         Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder();
1306         ipv4match.setIpv4Destination(dstip);
1307
1308         matchBuilder.setLayer3Match(ipv4match.build());
1309
1310         return matchBuilder;
1311
1312     }
1313
1314     /**
1315      * @param matchBuilder MatchBuilder Object without a match yet
1316      * @param srcip        String containing an IPv4 prefix
1317      * @return             matchBuilder Map Object with a match
1318      */
1319     private static MatchBuilder createSrcL3IPv4Match(MatchBuilder matchBuilder, Ipv4Prefix srcip) {
1320
1321         EthernetMatchBuilder eth = new EthernetMatchBuilder();
1322         EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
1323         ethTypeBuilder.setType(new EtherType(0x0800L));
1324         eth.setEthernetType(ethTypeBuilder.build());
1325         matchBuilder.setEthernetMatch(eth.build());
1326
1327         Ipv4MatchBuilder ipv4Match = new Ipv4MatchBuilder();
1328         Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder();
1329         ipv4match.setIpv4Source(srcip);
1330         matchBuilder.setLayer3Match(ipv4match.build());
1331
1332         return matchBuilder;
1333
1334     }
1335
1336     /**
1337      * Create Source TCP Port Match
1338      *
1339      * @param matchBuilder @param matchbuilder MatchBuilder Object without a match yet
1340      * @param tcpport      Integer representing a source TCP port
1341      * @return             matchBuilder Map MatchBuilder Object with a match
1342      */
1343     protected static MatchBuilder createSetSrcTcpMatch(MatchBuilder matchBuilder, PortNumber tcpport) {
1344
1345         EthernetMatchBuilder ethType = new EthernetMatchBuilder();
1346         EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
1347         ethTypeBuilder.setType(new EtherType(0x0800L));
1348         ethType.setEthernetType(ethTypeBuilder.build());
1349         matchBuilder.setEthernetMatch(ethType.build());
1350
1351         IpMatchBuilder ipmatch = new IpMatchBuilder();
1352         ipmatch.setIpProtocol((short) 6);
1353         matchBuilder.setIpMatch(ipmatch.build());
1354
1355         TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
1356         tcpmatch.setTcpSourcePort(tcpport);
1357         matchBuilder.setLayer4Match(tcpmatch.build());
1358
1359         return matchBuilder;
1360
1361     }
1362
1363     /**
1364      * Create Destination TCP Port Match
1365      *
1366      * @param matchBuilder MatchBuilder Object without a match yet
1367      * @param tcpport      Integer representing a destination TCP port
1368      * @return             matchBuilder Map MatchBuilder Object with a match
1369      */
1370     protected static MatchBuilder createSetDstTcpMatch(MatchBuilder matchBuilder, PortNumber tcpport) {
1371
1372         EthernetMatchBuilder ethType = new EthernetMatchBuilder();
1373         EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
1374         ethTypeBuilder.setType(new EtherType(0x0800L));
1375         ethType.setEthernetType(ethTypeBuilder.build());
1376         matchBuilder.setEthernetMatch(ethType.build());
1377
1378         IpMatchBuilder ipmatch = new IpMatchBuilder();
1379         ipmatch.setIpProtocol((short) 6);
1380         matchBuilder.setIpMatch(ipmatch.build());
1381
1382         PortNumber dstport = new PortNumber(tcpport);
1383         TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
1384
1385         tcpmatch.setTcpDestinationPort(tcpport);
1386         matchBuilder.setLayer4Match(tcpmatch.build());
1387
1388         return matchBuilder;
1389     }
1390
1391     /**
1392      * Create Send to Controller Reserved Port Instruction (packet_in)
1393      *
1394      * @param ib Map InstructionBuilder without any instructions
1395      * @return ib Map InstructionBuilder with instructions
1396      */
1397
1398     protected static InstructionBuilder createSendToControllerInstructions(InstructionBuilder ib) {
1399
1400         List<Action> actionList = new ArrayList<Action>();
1401         ActionBuilder ab = new ActionBuilder();
1402
1403         OutputActionBuilder output = new OutputActionBuilder();
1404         output.setMaxLength(56);
1405         Uri value = new Uri("CONTROLLER");
1406         output.setOutputNodeConnector(value);
1407         ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
1408         ab.setOrder(0);
1409         ab.setKey(new ActionKey(0));
1410         actionList.add(ab.build());
1411
1412         // Create an Apply Action
1413         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1414         aab.setAction(actionList);
1415
1416         // Wrap our Apply Action in an Instruction
1417         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1418         ib.setOrder(0);
1419         ib.setKey(new InstructionKey(0));
1420
1421         return ib;
1422     }
1423
1424     /**
1425      * Create Output Port Instruction
1426      *
1427      * @param ib       Map InstructionBuilder without any instructions
1428      * @param dpidLong Long the datapath ID of a switch/node
1429      * @param port     Long representing a port on a switch/node
1430      * @return ib InstructionBuilder Map with instructions
1431      */
1432     protected static InstructionBuilder createOutputPortInstructions(InstructionBuilder ib, Long dpidLong, Long port) {
1433
1434         NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
1435         logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} inPort={} ", dpidLong, port);
1436
1437         List<Action> actionList = new ArrayList<Action>();
1438         ActionBuilder ab = new ActionBuilder();
1439         OutputActionBuilder oab = new OutputActionBuilder();
1440         oab.setOutputNodeConnector(ncid);
1441
1442         ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
1443         ab.setOrder(5);
1444         ab.setKey(new ActionKey(5));
1445         actionList.add(ab.build());
1446
1447         // Create an Apply Action
1448         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1449         aab.setAction(actionList);
1450         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1451
1452         return ib;
1453     }
1454
1455     /**
1456      * Create Output Port Instruction
1457      *
1458      * @param ib       Map InstructionBuilder without any instructions
1459      * @param dpidLong Long the datapath ID of a switch/node
1460      * @param port     Long representing a port on a switch/node
1461      * @return ib InstructionBuilder Map with instructions
1462      */
1463     protected static InstructionBuilder createOutputPortInstructions(InstructionBuilder ib, Long dpidLong, Long port , List<Instruction> instructions) {
1464
1465         NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
1466         logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
1467
1468         List<Action> actionList = new ArrayList<Action>();
1469         ActionBuilder ab = new ActionBuilder();
1470
1471         List<Action> existingActions = null;
1472         if (instructions != null) {
1473             for (Instruction in : instructions) {
1474                 if (in.getInstruction() instanceof ApplyActionsCase) {
1475                     existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
1476                     actionList.addAll(existingActions);
1477                 }
1478             }
1479         }
1480
1481         OutputActionBuilder oab = new OutputActionBuilder();
1482         oab.setOutputNodeConnector(ncid);
1483         ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
1484         ab.setOrder(0);
1485         ab.setKey(new ActionKey(0));
1486         Action newAction = ab.build();
1487         boolean addNew = true;
1488         for (Action action : actionList) {
1489             if (action.getAction() instanceof OutputActionCase) {
1490                 OutputActionCase opAction = (OutputActionCase)action.getAction();
1491                 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
1492                     addNew = false;
1493                     break;
1494                 }
1495             }
1496         }
1497         if (addNew) actionList.add(newAction);
1498
1499         // Create an Apply Action
1500         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1501         aab.setAction(actionList);
1502         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1503
1504         return ib;
1505     }
1506
1507     /**
1508      * Create Set Vlan ID Instruction
1509      *
1510      * @param ib     Map InstructionBuilder without any instructions
1511      * @param vlanId Integer representing a VLAN ID Integer representing a VLAN ID
1512      * @return ib Map InstructionBuilder with instructions
1513      */
1514     protected static InstructionBuilder createSetVlanInstructions(InstructionBuilder ib, VlanId vlanId) {
1515
1516         List<Action> actionList = new ArrayList<Action>();
1517         ActionBuilder ab = new ActionBuilder();
1518
1519         SetVlanIdActionBuilder vl = new SetVlanIdActionBuilder();
1520         vl.setVlanId(vlanId);
1521         ab.setAction(new SetVlanIdActionCaseBuilder().setSetVlanIdAction(vl.build()).build());
1522         actionList.add(ab.build());
1523         // Create an Apply Action
1524         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1525         aab.setAction(actionList);
1526
1527         // Wrap our Apply Action in an Instruction
1528         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1529
1530         return ib;
1531     }
1532
1533     /**
1534      * Create Set IPv4 Destination Instruction
1535      *
1536      * @param ib Map InstructionBuilder without any instructions
1537      * @return ib Map InstructionBuilder with instructions
1538      */
1539     protected static InstructionBuilder createStripVlanInstructions(InstructionBuilder ib) {
1540
1541         StripVlanActionBuilder stripVlanActionBuilder = new StripVlanActionBuilder();
1542         StripVlanAction vlanAction = stripVlanActionBuilder.build();
1543         ActionBuilder ab = new ActionBuilder();
1544         ab.setAction(new StripVlanActionCaseBuilder().setStripVlanAction(vlanAction).build());
1545
1546         // Add our drop action to a list
1547         List<Action> actionList = new ArrayList<Action>();
1548         actionList.add(ab.build());
1549
1550         // Create an Apply Action
1551         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1552         aab.setAction(actionList);
1553
1554         // Wrap our Apply Action in an Instruction
1555         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1556         ib.setOrder(0);
1557         ib.setKey(new InstructionKey(0));
1558
1559         return ib;
1560     }
1561
1562     /**
1563      * Create Set IPv4 Source Instruction
1564      *
1565      * @param ib        Map InstructionBuilder without any instructions
1566      * @param prefixsrc String containing an IPv4 prefix
1567      * @return ib Map InstructionBuilder with instructions
1568      */
1569     protected static InstructionBuilder createNwSrcInstructions(InstructionBuilder ib, Ipv4Prefix prefixsrc) {
1570
1571         List<Action> actionList = new ArrayList<Action>();
1572         ActionBuilder ab = new ActionBuilder();
1573
1574         SetNwSrcActionBuilder setNwsrcActionBuilder = new SetNwSrcActionBuilder();
1575         Ipv4Builder ipsrc = new Ipv4Builder();
1576         ipsrc.setIpv4Address(prefixsrc);
1577         setNwsrcActionBuilder.setAddress(ipsrc.build());
1578         ab.setAction(new SetNwSrcActionCaseBuilder().setSetNwSrcAction(setNwsrcActionBuilder.build()).build());
1579         actionList.add(ab.build());
1580
1581         // Create an Apply Action
1582         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1583         aab.setAction(actionList);
1584
1585         // Wrap our Apply Action in an Instruction
1586         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1587
1588         return ib;
1589     }
1590
1591     /**
1592      * Create Set IPv4 Destination Instruction
1593      *
1594      * @param ib           Map InstructionBuilder without any instructions
1595      * @param prefixdst    String containing an IPv4 prefix
1596      * @return ib Map InstructionBuilder with instructions
1597      */
1598     protected static InstructionBuilder createNwDstInstructions(InstructionBuilder ib, Ipv4Prefix prefixdst) {
1599
1600         List<Action> actionList = new ArrayList<Action>();
1601         ActionBuilder ab = new ActionBuilder();
1602
1603         SetNwDstActionBuilder setNwDstActionBuilder = new SetNwDstActionBuilder();
1604         Ipv4Builder ipdst = new Ipv4Builder();
1605         ipdst.setIpv4Address(prefixdst);
1606         setNwDstActionBuilder.setAddress(ipdst.build());
1607         ab.setAction(new SetNwDstActionCaseBuilder().setSetNwDstAction(setNwDstActionBuilder.build()).build());
1608         actionList.add(ab.build());
1609
1610         // Create an Apply Action
1611         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1612         aab.setAction(actionList);
1613
1614         // Wrap our Apply Action in an Instruction
1615         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1616
1617         return ib;
1618     }
1619
1620     /**
1621      * Create Drop Instruction
1622      *
1623      * @param ib Map InstructionBuilder without any instructions
1624      * @return ib Map InstructionBuilder with instructions
1625      */
1626     protected static InstructionBuilder createDropInstructions(InstructionBuilder ib) {
1627
1628         DropActionBuilder dab = new DropActionBuilder();
1629         DropAction dropAction = dab.build();
1630         ActionBuilder ab = new ActionBuilder();
1631         ab.setAction(new DropActionCaseBuilder().setDropAction(dropAction).build());
1632
1633         // Add our drop action to a list
1634         List<Action> actionList = new ArrayList<Action>();
1635         actionList.add(ab.build());
1636
1637         // Create an Apply Action
1638         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1639         aab.setAction(actionList);
1640
1641         // Wrap our Apply Action in an Instruction
1642         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1643         ib.setOrder(0);
1644         ib.setKey(new InstructionKey(0));
1645
1646         return ib;
1647     }
1648
1649     /**
1650      * Create GOTO Table Instruction Builder
1651      *
1652      * @param ib      Map InstructionBuilder without any instructions
1653      * @param tableId short representing a flow table ID short representing a flow table ID
1654      * @return ib Map InstructionBuilder with instructions
1655      */
1656     protected static InstructionBuilder createGotoTableInstructions(InstructionBuilder ib, short tableId) {
1657
1658         GoToTableBuilder gttb = new GoToTableBuilder();
1659         gttb.setTableId(tableId);
1660
1661         // Wrap our Apply Action in an InstructionBuilder
1662         ib.setInstruction(new GoToTableCaseBuilder().setGoToTable(gttb.build()).build());
1663         ib.setOrder(0);
1664         ib.setKey(new InstructionKey(0));
1665
1666         return ib;
1667     }
1668
1669     /**
1670      * Create Set Tunnel ID Instruction Builder
1671      *
1672      * @param ib       Map InstructionBuilder without any instructions
1673      * @param tunnelId BigInteger representing a tunnel ID
1674      * @return ib Map InstructionBuilder with instructions
1675      */
1676     protected static InstructionBuilder createSetTunnelIdInstructions(InstructionBuilder ib, BigInteger tunnelId) {
1677
1678         List<Action> actionList = new ArrayList<Action>();
1679         ActionBuilder ab = new ActionBuilder();
1680         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1681
1682         // Build the Set Tunnel Field Action
1683         TunnelBuilder tunnel = new TunnelBuilder();
1684         tunnel.setTunnelId(tunnelId);
1685         setFieldBuilder.setTunnel(tunnel.build());
1686         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1687         actionList.add(ab.build());
1688
1689         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1690         aab.setAction(actionList);
1691
1692         // Wrap the Apply Action in an InstructionBuilder and return
1693         ib.setOrder(0);
1694         ib.setKey(new InstructionKey(0));
1695         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1696
1697         return ib;
1698     }
1699
1700     /**
1701      * Create Set Source TCP Port Instruction
1702      *
1703      * @param ib      Map InstructionBuilder without any instructions
1704      * @param tcpport Integer representing a source TCP port
1705      * @return ib Map InstructionBuilder with instructions
1706      */
1707     protected static InstructionBuilder createSetSrcTCPPort(InstructionBuilder ib, PortNumber tcpport) {
1708
1709         List<Action> actionList = new ArrayList<Action>();
1710         ActionBuilder ab = new ActionBuilder();
1711         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1712
1713         // Build the Destination TCP Port
1714         PortNumber tcpsrcport = new PortNumber(tcpport);
1715         TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
1716         tcpmatch.setTcpSourcePort(tcpsrcport);
1717
1718         setFieldBuilder.setLayer4Match(tcpmatch.build());
1719         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1720         ab.setKey(new ActionKey(1));
1721         actionList.add(ab.build());
1722
1723         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1724         aab.setAction(actionList);
1725         ib.setKey(new InstructionKey(1));
1726         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1727
1728         return ib;
1729     }
1730
1731     /**
1732      * Create Set Destination TCP Port Instruction
1733      *
1734      * @param ib      Map InstructionBuilder without any instructions
1735      * @param tcpport Integer representing a source TCP port
1736      * @return ib Map InstructionBuilder with instructions
1737      */
1738     protected static InstructionBuilder createSetDstTCPPort(InstructionBuilder ib, PortNumber tcpport) {
1739
1740         List<Action> actionList = new ArrayList<Action>();
1741         ActionBuilder ab = new ActionBuilder();
1742         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1743
1744         // Build the Destination TCP Port
1745         PortNumber tcpdstport = new PortNumber(tcpport);
1746         TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
1747         tcpmatch.setTcpDestinationPort(tcpdstport);
1748
1749         setFieldBuilder.setLayer4Match(tcpmatch.build());
1750         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1751         ab.setKey(new ActionKey(1));
1752         actionList.add(ab.build());
1753
1754         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1755         aab.setAction(actionList);
1756         ib.setKey(new InstructionKey(1));
1757         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1758
1759         return ib;
1760     }
1761
1762     /**
1763      * Create Set Source UDP Port Instruction
1764      *
1765      * @param ib      Map InstructionBuilder without any instructions
1766      * @param udpport Integer representing a source UDP port
1767      * @return ib Map InstructionBuilder with instructions
1768      */
1769     protected static InstructionBuilder createSetSrcUDPPort(InstructionBuilder ib, PortNumber udpport) {
1770
1771         List<Action> actionList = new ArrayList<Action>();
1772         ActionBuilder ab = new ActionBuilder();
1773         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1774
1775         // Build the Destination TCP Port
1776         PortNumber udpsrcport = new PortNumber(udpport);
1777         UdpMatchBuilder udpmatch = new UdpMatchBuilder();
1778         udpmatch.setUdpSourcePort(udpsrcport);
1779
1780         setFieldBuilder.setLayer4Match(udpmatch.build());
1781         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1782         ab.setKey(new ActionKey(1));
1783         actionList.add(ab.build());
1784
1785         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1786         aab.setAction(actionList);
1787         ib.setKey(new InstructionKey(1));
1788         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1789
1790         return ib;
1791     }
1792
1793     /**
1794      * Create Set Destination UDP Port Instruction
1795      *
1796      * @param ib      Map InstructionBuilder without any instructions
1797      * @param udpport Integer representing a destination UDP port
1798      * @return ib Map InstructionBuilder with instructions
1799      */
1800     protected static InstructionBuilder createSetDstUDPPort(InstructionBuilder ib, PortNumber udpport) {
1801
1802         List<Action> actionList = new ArrayList<Action>();
1803         ActionBuilder ab = new ActionBuilder();
1804         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1805
1806         // Build the Destination TCP Port
1807         PortNumber udpdstport = new PortNumber(udpport);
1808         UdpMatchBuilder udpmatch = new UdpMatchBuilder();
1809         udpmatch.setUdpDestinationPort(udpdstport);
1810
1811         setFieldBuilder.setLayer4Match(udpmatch.build());
1812         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1813         ab.setKey(new ActionKey(1));
1814         actionList.add(ab.build());
1815
1816         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1817         aab.setAction(actionList);
1818         ib.setKey(new InstructionKey(1));
1819         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1820
1821         return ib;
1822     }
1823
1824     /**
1825      * Create Set ICMP Code Instruction
1826      *
1827      * @param ib   Map InstructionBuilder without any instructions
1828      * @param code short repesenting an ICMP code
1829      * @return ib Map InstructionBuilder with instructions
1830      */
1831
1832     private static InstructionBuilder createSetIcmpCodeInstruction(InstructionBuilder ib, short code) {
1833
1834         List<Action> actionList = new ArrayList<Action>();
1835         ActionBuilder ab = new ActionBuilder();
1836         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1837         Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
1838
1839         // Build the ICMPv4 Code Match
1840         icmpv4match.setIcmpv4Code(code);
1841         setFieldBuilder.setIcmpv4Match(icmpv4match.build());
1842
1843         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1844         ab.setKey(new ActionKey(0));
1845         actionList.add(ab.build());
1846         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1847         aab.setAction(actionList);
1848
1849         // Wrap our Apply Action in an Instruction
1850         ib.setKey(new InstructionKey(0));
1851         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1852
1853         return ib;
1854     }
1855
1856     /**
1857      * Create Set ICMP Code Instruction
1858      *
1859      * @param ib Map InstructionBuilder without any instructions
1860      * @return ib Map InstructionBuilder with instructions
1861      */
1862     private static InstructionBuilder createSetIcmpTypeInstruction(InstructionBuilder ib, short type) {
1863
1864         List<Action> actionList = new ArrayList<Action>();
1865         ActionBuilder ab = new ActionBuilder();
1866         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1867         Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
1868
1869         // Build the ICMPv4 Code Match
1870         icmpv4match.setIcmpv4Code(type);
1871         setFieldBuilder.setIcmpv4Match(icmpv4match.build());
1872
1873         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1874         ab.setKey(new ActionKey(1));
1875         actionList.add(ab.build());
1876         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1877         aab.setAction(actionList);
1878
1879         // Wrap our Apply Action in an Instruction
1880         ib.setKey(new InstructionKey(1));
1881         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1882
1883         return ib;
1884     }
1885
1886     /**
1887      * Create Decrement TTL Instruction
1888      *
1889      * @param ib Map InstructionBuilder without any instructions
1890      * @return ib Map InstructionBuilder with instructions
1891      */
1892     private static InstructionBuilder createDecNwTtlInstructions(InstructionBuilder ib) {
1893         DecNwTtlBuilder decNwTtlBuilder = new DecNwTtlBuilder();
1894         DecNwTtl decNwTtl = decNwTtlBuilder.build();
1895         ActionBuilder ab = new ActionBuilder();
1896         ab.setAction(new DecNwTtlCaseBuilder().setDecNwTtl(decNwTtl).build());
1897
1898         // Add our drop action to a list
1899         List<Action> actionList = new ArrayList<Action>();
1900         actionList.add(ab.build());
1901
1902         // Create an Apply Action
1903         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1904         aab.setAction(actionList);
1905
1906         // Wrap our Apply Action in an Instruction
1907         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1908         ib.setKey(new InstructionKey(0));
1909         ib.setOrder(0);
1910
1911         return ib;
1912     }
1913
1914     /**
1915      * Set Src Arp MAC
1916      */
1917     private static InstructionBuilder createSrcArpMacInstructions(InstructionBuilder ib, MacAddress macsrc) {
1918
1919         List<Action> actionList = new ArrayList<Action>();
1920         ActionBuilder ab = new ActionBuilder();
1921
1922         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1923         ArpMatchBuilder arpmatch = new ArpMatchBuilder();
1924         ArpSourceHardwareAddressBuilder arpsrc = new ArpSourceHardwareAddressBuilder();
1925         arpsrc.setAddress(macsrc);
1926         arpmatch.setArpSourceHardwareAddress(arpsrc.build());
1927         setFieldBuilder.setLayer3Match(arpmatch.build());
1928         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1929         ab.setKey(new ActionKey(0));
1930         actionList.add(ab.build());
1931
1932         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1933         aab.setAction(actionList);
1934
1935         return ib;
1936     }
1937
1938     /**
1939      * Set Dst Arp MAC
1940      */
1941     private static InstructionBuilder createDstArpMacInstructions(InstructionBuilder ib, MacAddress macdst) {
1942
1943         List<Action> actionList = new ArrayList<Action>();
1944         ActionBuilder ab = new ActionBuilder();
1945         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1946
1947         ArpMatchBuilder arpmatch = new ArpMatchBuilder();
1948         ArpTargetHardwareAddressBuilder arpdst = new ArpTargetHardwareAddressBuilder();
1949         arpdst.setAddress(macdst);
1950         setFieldBuilder.setLayer3Match(arpmatch.build());
1951         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1952         ab.setKey(new ActionKey(0));
1953         actionList.add(ab.build());
1954
1955         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1956         aab.setAction(actionList);
1957
1958         return ib;
1959     }
1960
1961     /**
1962      * Set Dst Arp IP
1963      */
1964     private static InstructionBuilder createDstArpIpInstructions(InstructionBuilder ib, Ipv4Prefix dstiparp) {
1965
1966         List<Action> actionList = new ArrayList<Action>();
1967         ActionBuilder ab = new ActionBuilder();
1968         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1969
1970         ArpMatchBuilder arpmatch = new ArpMatchBuilder();
1971         arpmatch.setArpTargetTransportAddress(dstiparp);
1972         setFieldBuilder.setLayer3Match(arpmatch.build());
1973         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1974         ab.setKey(new ActionKey(0));
1975         actionList.add(ab.build());
1976
1977         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1978         aab.setAction(actionList);
1979
1980         return ib;
1981     }
1982
1983     /**
1984      * Set Src Arp IP
1985      */
1986     private static InstructionBuilder createSrcArpIpInstructions(InstructionBuilder ib, Ipv4Prefix srciparp) {
1987
1988         List<Action> actionList = new ArrayList<Action>();
1989         ActionBuilder ab = new ActionBuilder();
1990         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1991
1992         ArpMatchBuilder arpmatch = new ArpMatchBuilder();
1993         arpmatch.setArpSourceTransportAddress(srciparp);
1994         setFieldBuilder.setLayer3Match(arpmatch.build());
1995         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1996         ab.setKey(new ActionKey(0));
1997         actionList.add(ab.build());
1998
1999         ApplyActionsBuilder aab = new ApplyActionsBuilder();
2000         aab.setAction(actionList);
2001
2002         return ib;
2003     }
2004
2005     @Override
2006     public void initializeOFFlowRules(Node openflowNode) {
2007         IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
2008         List<Node> ovsNodes = connectionService.getNodes();
2009         if (ovsNodes == null) return;
2010         for (Node ovsNode : ovsNodes) {
2011             Long dpid = this.getIntegrationBridgeOFDPID(ovsNode);
2012             logger.debug("Compare openflowNode to OVS br-int node {} vs {}", openflowNode.getID(), dpid);
2013             String openflowID = (String)openflowNode.getID();
2014             if (openflowID.contains(""+dpid)) {
2015                 this.initializeFlowRules(ovsNode, AdminConfigManager.getManager().getIntegrationBridgeName());
2016                 this.triggerInterfaceUpdates(ovsNode);
2017             }
2018         }
2019     }
2020
2021     private NodeBuilder createNodeBuilder(String nodeId) {
2022         NodeBuilder builder = new NodeBuilder();
2023         builder.setId(new NodeId(nodeId));
2024         builder.setKey(new NodeKey(builder.getId()));
2025         return builder;
2026     }
2027
2028     private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeBuilderToInstanceId(NodeBuilder
2029                                                                                                                                              node) {
2030         return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
2031                 node.getKey()).toInstance();
2032     }
2033 }