Code ReOrganization and Re-Architecture changes
[ovsdb.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.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           * Table(1) Rule #2
318           * ----------------
319           * Match: Match Tunnel ID and L2 ::::FF:FF Flooding
320           * Action: Flood to selected destination TEPs
321           * -------------------------------------------
322           * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
323           * actions=output:10,output:11,goto_table:2
324           */
325
326          writeTunnelFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort);
327
328     }
329
330     private void programRemoteEgressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
331         /*
332          * Table(1) Rule #1
333          * ----------------
334          * Match: Drop any remaining Ingress Local VM Packets
335          * Action: Drop w/ a low priority
336          * -------------------------------------------
337          * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
338          * actions=output:11,goto_table:2
339          */
340
341         writeTunnelOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, attachedMac);
342     }
343
344     private Long getIntegrationBridgeOFDPID (Node node) {
345         try {
346             String bridgeName = AdminConfigManager.getManager().getIntegrationBridgeName();
347             String brIntId = this.getInternalBridgeUUID(node, bridgeName);
348             if (brIntId == null) {
349                 logger.error("Unable to spot Bridge Identifier for {} in {}", bridgeName, node);
350                 return 0L;
351             }
352
353             OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
354             Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brIntId);
355             Set<String> dpids = bridge.getDatapath_id();
356             if (dpids == null || dpids.size() == 0) return 0L;
357             return Long.valueOf(HexEncode.stringToLong((String) dpids.toArray()[0]));
358         } catch (Exception e) {
359             logger.error("Error finding Integration Bridge's OF DPID", e);
360             return 0L;
361         }
362     }
363     private void programLocalRules (String tunnelType, String segmentationId, Node node, Interface intf) {
364         try {
365             Long dpid = this.getIntegrationBridgeOFDPID(node);
366             if (dpid == 0L) {
367                 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
368                 return;
369             }
370
371             Set<BigInteger> of_ports = intf.getOfport();
372             if (of_ports == null || of_ports.size() <= 0) {
373                 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
374                 return;
375             }
376             long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
377
378             Map<String, String> externalIds = intf.getExternal_ids();
379             if (externalIds == null) {
380                 logger.error("No external_ids seen in {}", intf);
381                 return;
382             }
383
384             String attachedMac = externalIds.get(TenantNetworkManager.EXTERNAL_ID_VM_MAC);
385             if (attachedMac == null) {
386                 logger.error("No AttachedMac seen in {}", intf);
387                 return;
388             }
389
390             programLocalBridgeRules(node, dpid, segmentationId, attachedMac, localPort);
391         } catch (Exception e) {
392             logger.error("Exception in programming Local Rules for "+intf+" on "+node, e);
393         }
394     }
395
396     private void programTunnelRules (String tunnelType, String segmentationId, InetAddress dst, Node node,
397             Interface intf, boolean local) {
398         try {
399
400             Long dpid = this.getIntegrationBridgeOFDPID(node);
401             if (dpid == 0L) {
402                 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
403                 return;
404             }
405             OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
406
407             Set<BigInteger> of_ports = intf.getOfport();
408             if (of_ports == null || of_ports.size() <= 0) {
409                 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
410                 return;
411             }
412             long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
413
414             Map<String, String> externalIds = intf.getExternal_ids();
415             if (externalIds == null) {
416                 logger.error("No external_ids seen in {}", intf);
417                 return;
418             }
419
420             String attachedMac = externalIds.get(TenantNetworkManager.EXTERNAL_ID_VM_MAC);
421             if (attachedMac == null) {
422                 logger.error("No AttachedMac seen in {}", intf);
423                 return;
424             }
425
426             Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
427             if (intfs != null) {
428                 for (org.opendaylight.ovsdb.lib.table.Table<?> row : intfs.values()) {
429                     Interface tunIntf = (Interface)row;
430                     if (tunIntf.getName().equals(this.getTunnelName(tunnelType, dst))) {
431                         of_ports = tunIntf.getOfport();
432                         if (of_ports == null || of_ports.size() <= 0) {
433                             logger.error("Could NOT Identify Tunnel port {} on {}", tunIntf.getName(), node);
434                             continue;
435                         }
436                         long tunnelOFPort = ((BigInteger)of_ports.toArray()[0]).longValue();
437
438                         if (tunnelOFPort == -1) {
439                             logger.error("Could NOT Identify Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
440                             return;
441                         }
442                         logger.debug("Identified Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
443
444                         if (!local) {
445                             programRemoteEgressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
446                         }
447                         programLocalIngressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
448                         return;
449                     }
450                 }
451             }
452         } catch (Exception e) {
453             logger.error("", e);
454         }
455     }
456
457     @Override
458     public Status handleInterfaceUpdate(String tunnelType, String tunnelKey, Node srcNode, Interface intf) {
459         ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, "default", this);
460         if (switchManager == null) {
461             logger.error("Unable to identify SwitchManager");
462         } else {
463             Long dpid = this.getIntegrationBridgeOFDPID(srcNode);
464             if (dpid == 0L) {
465                 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", srcNode);
466                 return new Status(StatusCode.NOTFOUND);
467             }
468             Set<Node> ofNodes = switchManager.getNodes();
469             boolean ofNodeFound = false;
470             if (ofNodes != null) {
471                 for (Node ofNode : ofNodes) {
472                     if (ofNode.toString().contains(dpid+"")) {
473                         logger.debug("Identified the Openflow node via toString {}", ofNode);
474                         ofNodeFound = true;
475                         break;
476                     }
477                 }
478             } else {
479                 logger.error("Unable to find any Node from SwitchManager");
480             }
481             if (!ofNodeFound) {
482                 logger.error("Unable to find OF Node for {} with update {} on node {}", dpid, intf, srcNode);
483                 return new Status(StatusCode.NOTFOUND);
484             }
485         }
486
487         IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
488         List<Node> nodes = connectionService.getNodes();
489         nodes.remove(srcNode);
490         this.programLocalRules(tunnelType, tunnelKey, srcNode, intf);
491
492         for (Node dstNode : nodes) {
493             InetAddress src = AdminConfigManager.getManager().getTunnelEndPoint(srcNode);
494             InetAddress dst = AdminConfigManager.getManager().getTunnelEndPoint(dstNode);
495             Status status = addTunnelPort(srcNode, tunnelType, src, dst);
496             if (status.isSuccess()) {
497                 this.programTunnelRules(tunnelType, tunnelKey, dst, srcNode, intf, true);
498             }
499             addTunnelPort(dstNode, tunnelType, dst, src);
500             if (status.isSuccess()) {
501                 this.programTunnelRules(tunnelType, tunnelKey, src, dstNode, intf, false);
502             }
503         }
504
505         return new Status(StatusCode.SUCCESS);
506     }
507
508     private Status triggerInterfaceUpdates(Node node) {
509         try {
510             OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
511             Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
512             if (intfs != null) {
513                 for (org.opendaylight.ovsdb.lib.table.Table<?> row : intfs.values()) {
514                     Interface intf = (Interface)row;
515                     NeutronNetwork network = TenantNetworkManager.getManager().getTenantNetworkForInterface(intf);
516                     logger.debug("Trigger Interface update for {}", intf);
517                     if (network != null) {
518                         this.handleInterfaceUpdate(network.getProviderNetworkType(), network.getProviderSegmentationID(), node, intf);
519                     }
520                 }
521             }
522         } catch (Exception e) {
523             logger.error("Error Triggering the lost interface updates for "+ node, e);
524             return new Status(StatusCode.INTERNALERROR, e.getLocalizedMessage());
525         }
526         return new Status(StatusCode.SUCCESS);
527     }
528     @Override
529     public Status handleInterfaceUpdate(String tunnelType, String tunnelKey) {
530         // TODO Auto-generated method stub
531         return null;
532     }
533
534     @Override
535     public Status handleInterfaceDelete(String tunnelType, String tunnelKey, Node source, Interface intf,
536             boolean isLastInstanceOnNode) {
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         ib.setOrder(0);
598         ib.setKey(new InstructionKey(0));
599         instructions.add(ib.build());
600
601         // Add InstructionBuilder to the Instruction(s)Builder List
602         isb.setInstruction(instructions);
603
604         // Add InstructionsBuilder to FlowBuilder
605         flowBuilder.setInstructions(isb.build());
606
607         String flowId = "LLDP";
608         flowBuilder.setId(new FlowId(flowId));
609         FlowKey key = new FlowKey(new FlowId(flowId));
610         flowBuilder.setBarrier(true);
611         flowBuilder.setTableId((short) 0);
612         flowBuilder.setKey(key);
613         flowBuilder.setFlowName(flowId);
614         flowBuilder.setHardTimeout(0);
615         flowBuilder.setIdleTimeout(0);
616         writeFlow(flowBuilder, nodeBuilder);
617     }
618
619     /*
620      * (Table:0) Ingress Tunnel Traffic
621      * Match: OpenFlow InPort and Tunnel ID
622      * Action: GOTO Local Table (10)
623      * table=0,tun_id=0x5,in_port=10, actions=goto_table:2
624      */
625
626     private void writeTunnelIn(Long dpidLong, Short writeTable, Short goToTableId, String segmentationId,  Long ofPort) {
627
628         String nodeName = "openflow:" + dpidLong;
629
630         BigInteger tunnelId = new BigInteger(segmentationId);
631         MatchBuilder matchBuilder = new MatchBuilder();
632         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
633         FlowBuilder flowBuilder = new FlowBuilder();
634
635         // Create Match(es) and Set them in the FlowBuilder Object
636         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, tunnelId).build());
637         flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, ofPort).build());
638
639         // Create the OF Actions and Instructions
640         InstructionBuilder ib = new InstructionBuilder();
641         InstructionsBuilder isb = new InstructionsBuilder();
642
643         // Instructions List Stores Individual Instructions
644         List<Instruction> instructions = new ArrayList<Instruction>();
645
646         // Call the InstructionBuilder Methods Containing Actions
647         createGotoTableInstructions(ib, goToTableId);
648         ib.setOrder(0);
649         ib.setKey(new InstructionKey(0));
650         instructions.add(ib.build());
651
652         // Add InstructionBuilder to the Instruction(s)Builder List
653         isb.setInstruction(instructions);
654
655         // Add InstructionsBuilder to FlowBuilder
656         flowBuilder.setInstructions(isb.build());
657
658         String flowId = "TunnelIn_"+segmentationId+"_"+ofPort;
659         // Add Flow Attributes
660         flowBuilder.setId(new FlowId(flowId));
661         FlowKey key = new FlowKey(new FlowId(flowId));
662         flowBuilder.setStrict(true);
663         flowBuilder.setBarrier(false);
664         flowBuilder.setTableId(writeTable);
665         flowBuilder.setKey(key);
666         flowBuilder.setFlowName(flowId);
667         flowBuilder.setHardTimeout(0);
668         flowBuilder.setIdleTimeout(0);
669         writeFlow(flowBuilder, nodeBuilder);
670     }
671
672    /*
673     * (Table:0) Egress VM Traffic Towards TEP
674     * Match: Destination Ethernet Addr and OpenFlow InPort
675     * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
676     * table=0,in_port=2,dl_src=00:00:00:00:00:01 \
677     * actions=set_field:5->tun_id,goto_table=1"
678     */
679
680     private void writeLocalInPort(Long dpidLong, Short writeTable, Short goToTableId, String segmentationId, Long inPort, String attachedMac) {
681
682         String nodeName = "openflow:" + dpidLong;
683
684         MatchBuilder matchBuilder = new MatchBuilder();
685         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
686         FlowBuilder flowBuilder = new FlowBuilder();
687
688         // Create the OF Match using MatchBuilder
689         flowBuilder.setMatch(createEthSrcMatch(matchBuilder, new MacAddress(attachedMac)).build());
690         // TODO Broken In_Port Match
691         flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
692
693         String flowId = "LocalMac_"+segmentationId+"_"+inPort+"_"+attachedMac;
694         // Add Flow Attributes
695         flowBuilder.setId(new FlowId(flowId));
696         FlowKey key = new FlowKey(new FlowId(flowId));
697         flowBuilder.setStrict(true);
698         flowBuilder.setBarrier(false);
699         flowBuilder.setTableId(writeTable);
700         flowBuilder.setKey(key);
701         flowBuilder.setFlowName(flowId);
702         flowBuilder.setHardTimeout(0);
703         flowBuilder.setIdleTimeout(0);
704
705         // Instantiate the Builders for the OF Actions and Instructions
706         InstructionBuilder ib = new InstructionBuilder();
707         InstructionsBuilder isb = new InstructionsBuilder();
708
709         // Instructions List Stores Individual Instructions
710         List<Instruction> instructions = new ArrayList<Instruction>();
711
712         // GOTO Instuctions Need to be added first to the List
713         createGotoTableInstructions(ib, goToTableId);
714         ib.setOrder(0);
715         ib.setKey(new InstructionKey(0));
716         instructions.add(ib.build());
717         // TODO Broken SetTunID
718         createSetTunnelIdInstructions(ib, new BigInteger(segmentationId));
719         ib.setOrder(1);
720         ib.setKey(new InstructionKey(1));
721         instructions.add(ib.build());
722
723         // Add InstructionBuilder to the Instruction(s)Builder List
724         isb.setInstruction(instructions);
725
726         // Add InstructionsBuilder to FlowBuilder
727         flowBuilder.setInstructions(isb.build());
728
729         writeFlow(flowBuilder, nodeBuilder);
730     }
731
732     /*
733      * (Table:0) Drop frames sourced from a VM that do not
734      * match the associated MAC address of the local VM.
735      * Match: Low priority anything not matching the VM SMAC
736      * Instruction: Drop
737      * table=0,priority=16384,in_port=1 actions=drop"
738      */
739
740     private void writeDropSrcIface(Long dpidLong, Long inPort) {
741
742         String nodeName = "openflow:" + dpidLong;
743
744         MatchBuilder matchBuilder = new MatchBuilder();
745         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
746         FlowBuilder flowBuilder = new FlowBuilder();
747
748         // Create the OF Match using MatchBuilder
749         flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
750
751         // Instantiate the Builders for the OF Actions and Instructions
752         InstructionBuilder ib = new InstructionBuilder();
753         InstructionsBuilder isb = new InstructionsBuilder();
754
755         // Instructions List Stores Individual Instructions
756         List<Instruction> instructions = new ArrayList<Instruction>();
757
758         // Call the InstructionBuilder Methods Containing Actions
759         createDropInstructions(ib);
760         ib.setOrder(0);
761         ib.setKey(new InstructionKey(0));
762         instructions.add(ib.build());
763
764         // Add InstructionBuilder to the Instruction(s)Builder List
765         isb.setInstruction(instructions);
766
767         // Add InstructionsBuilder to FlowBuilder
768         flowBuilder.setInstructions(isb.build());
769
770         String flowId = "DropFilter_"+inPort;
771         // Add Flow Attributes
772         flowBuilder.setId(new FlowId(flowId));
773         FlowKey key = new FlowKey(new FlowId(flowId));
774         flowBuilder.setStrict(true);
775         flowBuilder.setBarrier(false);
776         flowBuilder.setTableId((short) 0);
777         flowBuilder.setKey(key);
778         flowBuilder.setFlowName(flowId);
779         flowBuilder.setPriority(8192);
780         flowBuilder.setHardTimeout(0);
781         flowBuilder.setIdleTimeout(0);
782         writeFlow(flowBuilder, nodeBuilder);
783     }
784
785    /*
786     * (Table:1) Egress Tunnel Traffic
787     * Match: Destination Ethernet Addr and Local InPort
788     * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
789     * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
790     * actions=output:10,goto_table:2"
791     */
792
793     private void writeTunnelOut(Long dpidLong, Short writeTable, Short goToTableId, String segmentationId , Long OFPortOut, String attachedMac) {
794
795         String nodeName = "openflow:" + dpidLong;
796
797         MatchBuilder matchBuilder = new MatchBuilder();
798         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
799         FlowBuilder flowBuilder = new FlowBuilder();
800
801         // Create the OF Match using MatchBuilder
802         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
803         flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
804
805         String flowId = "TunnelOut_"+segmentationId+"_"+OFPortOut+"_"+attachedMac;
806         // Add Flow Attributes
807         flowBuilder.setId(new FlowId(flowId));
808         FlowKey key = new FlowKey(new FlowId(flowId));
809         flowBuilder.setStrict(true);
810         flowBuilder.setBarrier(false);
811         flowBuilder.setTableId(writeTable);
812         flowBuilder.setKey(key);
813         flowBuilder.setFlowName(flowId);
814         flowBuilder.setHardTimeout(0);
815         flowBuilder.setIdleTimeout(0);
816         // Instantiate the Builders for the OF Actions and Instructions
817         InstructionBuilder ib = new InstructionBuilder();
818         InstructionsBuilder isb = new InstructionsBuilder();
819
820         // Instructions List Stores Individual Instructions
821         List<Instruction> instructions = new ArrayList<Instruction>();
822
823         // GOTO Instuctions
824         createGotoTableInstructions(ib, goToTableId);
825         ib.setOrder(0);
826         ib.setKey(new InstructionKey(0));
827         instructions.add(ib.build());
828         // Set the Output Port/Iface
829         createOutputPortInstructions(ib, dpidLong, OFPortOut);
830         ib.setOrder(1);
831         ib.setKey(new InstructionKey(1));
832         instructions.add(ib.build());
833
834         // Add InstructionBuilder to the Instruction(s)Builder List
835         isb.setInstruction(instructions);
836
837         // Add InstructionsBuilder to FlowBuilder
838         flowBuilder.setInstructions(isb.build());
839
840         writeFlow(flowBuilder, nodeBuilder);
841     }
842
843        /*
844     * (Table:1) Egress Tunnel Traffic
845     * Match: Destination Ethernet Addr and Local InPort
846     * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
847     * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
848     * actions=output:10,output:11,goto_table:2
849     */
850
851     private void writeTunnelFloodOut(Long dpidLong, Short writeTable, Short localTable, String segmentationId,  Long OFPortOut) {
852
853         String nodeName = "openflow:" + dpidLong;
854
855         MatchBuilder matchBuilder = new MatchBuilder();
856         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
857         FlowBuilder flowBuilder = new FlowBuilder();
858
859         // Create the OF Match using MatchBuilder
860         // Match TunnelID
861         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
862         // Match DMAC
863
864         flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
865
866         String flowId = "TunnelFloodOut_"+segmentationId;
867         // Add Flow Attributes
868         flowBuilder.setId(new FlowId(flowId));
869         FlowKey key = new FlowKey(new FlowId(flowId));
870         flowBuilder.setBarrier(true);
871         flowBuilder.setTableId(writeTable);
872         flowBuilder.setKey(key);
873         flowBuilder.setPriority(16384);
874         flowBuilder.setFlowName(flowId);
875         flowBuilder.setHardTimeout(0);
876         flowBuilder.setIdleTimeout(0);
877
878         Flow flow = this.getFlow(flowBuilder, nodeBuilder);
879         // Instantiate the Builders for the OF Actions and Instructions
880         InstructionBuilder ib = new InstructionBuilder();
881         InstructionsBuilder isb = new InstructionsBuilder();
882         List<Instruction> instructions = new ArrayList<Instruction>();
883         List<Instruction> existingInstructions = null;
884         if (flow != null) {
885             Instructions ins = flow.getInstructions();
886             if (ins != null) {
887                 existingInstructions = ins.getInstruction();
888             }
889         }
890         // GOTO Instuction
891         createGotoTableInstructions(ib, localTable);
892         ib.setOrder(0);
893         ib.setKey(new InstructionKey(0));
894         instructions.add(ib.build());
895         // Set the Output Port/Iface
896         createOutputPortInstructions(ib, dpidLong, OFPortOut, existingInstructions);
897         ib.setOrder(1);
898         ib.setKey(new InstructionKey(1));
899         instructions.add(ib.build());
900
901         // Add InstructionBuilder to the Instruction(s)Builder List
902         isb.setInstruction(instructions);
903
904         // Add InstructionsBuilder to FlowBuilder
905         flowBuilder.setInstructions(isb.build());
906
907         writeFlow(flowBuilder, nodeBuilder);
908     }
909
910    /*
911     * (Table:1) Table Drain w/ Catch All
912     * Match: Tunnel ID
913     * Action: GOTO Local Table (10)
914     * table=2,priority=8192,tun_id=0x5 actions=drop
915     */
916
917     private void writeTunnelMiss(Long dpidLong, Short writeTable, Short goToTableId, String segmentationId) {
918
919         String nodeName = "openflow:" + dpidLong;
920
921         MatchBuilder matchBuilder = new MatchBuilder();
922         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
923         FlowBuilder flowBuilder = new FlowBuilder();
924
925         // Create Match(es) and Set them in the FlowBuilder Object
926         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
927
928         // Create the OF Actions and Instructions
929         InstructionBuilder ib = new InstructionBuilder();
930         InstructionsBuilder isb = new InstructionsBuilder();
931
932         // Instructions List Stores Individual Instructions
933         List<Instruction> instructions = new ArrayList<Instruction>();
934
935         // Call the InstructionBuilder Methods Containing Actions
936         createGotoTableInstructions(ib, goToTableId);
937         ib.setOrder(0);
938         ib.setKey(new InstructionKey(0));
939         instructions.add(ib.build());
940
941         // Add InstructionBuilder to the Instruction(s)Builder List
942         isb.setInstruction(instructions);
943
944         // Add InstructionsBuilder to FlowBuilder
945         flowBuilder.setInstructions(isb.build());
946
947         String flowId = "TunnelMiss_"+segmentationId;
948         // Add Flow Attributes
949         flowBuilder.setId(new FlowId(flowId));
950         FlowKey key = new FlowKey(new FlowId(flowId));
951         flowBuilder.setStrict(true);
952         flowBuilder.setBarrier(false);
953         flowBuilder.setTableId(writeTable);
954         flowBuilder.setKey(key);
955         flowBuilder.setPriority(8192);
956         flowBuilder.setFlowName(flowId);
957         flowBuilder.setHardTimeout(0);
958         flowBuilder.setIdleTimeout(0);
959         writeFlow(flowBuilder, nodeBuilder);
960     }
961
962     /*
963      * (Table:1) Local Broadcast Flood
964      * Match: Tunnel ID and dMAC
965      * Action: Output Port
966      * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
967      */
968
969     private void writeLocalUcastOut(Long dpidLong, Short writeTable, String segmentationId, Long localPort, String attachedMac) {
970
971         String nodeName = "openflow:" + dpidLong;
972
973         MatchBuilder matchBuilder = new MatchBuilder();
974         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
975         FlowBuilder flowBuilder = new FlowBuilder();
976
977         // Create the OF Match using MatchBuilder
978         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
979         flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
980
981         String flowId = "UcastOut_"+segmentationId+"_"+localPort+"_"+attachedMac;
982         // Add Flow Attributes
983         flowBuilder.setId(new FlowId(flowId));
984         FlowKey key = new FlowKey(new FlowId(flowId));
985         flowBuilder.setStrict(true);
986         flowBuilder.setBarrier(false);
987         flowBuilder.setTableId(writeTable);
988         flowBuilder.setKey(key);
989         flowBuilder.setFlowName(flowId);
990         flowBuilder.setHardTimeout(0);
991         flowBuilder.setIdleTimeout(0);
992
993         // Instantiate the Builders for the OF Actions and Instructions
994         InstructionBuilder ib = new InstructionBuilder();
995         InstructionsBuilder isb = new InstructionsBuilder();
996
997         // Instructions List Stores Individual Instructions
998         List<Instruction> instructions = new ArrayList<Instruction>();
999
1000         // Set the Output Port/Iface
1001         createOutputPortInstructions(ib, dpidLong, localPort);
1002         ib.setOrder(0);
1003         ib.setKey(new InstructionKey(0));
1004         instructions.add(ib.build());
1005
1006         // Add InstructionBuilder to the Instruction(s)Builder List
1007         isb.setInstruction(instructions);
1008
1009         // Add InstructionsBuilder to FlowBuilder
1010         flowBuilder.setInstructions(isb.build());
1011         writeFlow(flowBuilder, nodeBuilder);
1012     }
1013
1014     /*
1015      * (Table:1) Local Broadcast Flood
1016      * Match: Tunnel ID and dMAC (::::FF:FF)
1017      * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
1018      * actions=output:2,3,4,5
1019      */
1020
1021     private void writeLocalBcastOut(Long dpidLong, Short writeTable, String segmentationId, Long localPort) {
1022
1023         String nodeName = "openflow:" + dpidLong;
1024
1025         MatchBuilder matchBuilder = new MatchBuilder();
1026         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1027         FlowBuilder flowBuilder = new FlowBuilder();
1028
1029         // Create the OF Match using MatchBuilder
1030         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
1031         flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
1032
1033         String flowId = "BcastOut_"+segmentationId;
1034         // Add Flow Attributes
1035         flowBuilder.setId(new FlowId(flowId));
1036         FlowKey key = new FlowKey(new FlowId(flowId));
1037         flowBuilder.setStrict(true);
1038         flowBuilder.setBarrier(false);
1039         flowBuilder.setTableId(writeTable);
1040         flowBuilder.setKey(key);
1041         flowBuilder.setPriority(16384);
1042         flowBuilder.setFlowName(flowId);
1043         flowBuilder.setHardTimeout(0);
1044         flowBuilder.setIdleTimeout(0);
1045         Flow flow = this.getFlow(flowBuilder, nodeBuilder);
1046         // Instantiate the Builders for the OF Actions and Instructions
1047         InstructionBuilder ib = new InstructionBuilder();
1048         InstructionsBuilder isb = new InstructionsBuilder();
1049         List<Instruction> instructions = new ArrayList<Instruction>();
1050         List<Instruction> existingInstructions = null;
1051         if (flow != null) {
1052             Instructions ins = flow.getInstructions();
1053             if (ins != null) {
1054                 existingInstructions = ins.getInstruction();
1055             }
1056         }
1057
1058         // Broken OutPort TODO: localPort needs to be a list of Ports)
1059         createOutputPortInstructions(ib, dpidLong, localPort, existingInstructions);
1060         ib.setOrder(0);
1061         ib.setKey(new InstructionKey(0));
1062         instructions.add(ib.build());
1063
1064         // Add InstructionBuilder to the Instruction(s)Builder List
1065         isb.setInstruction(instructions);
1066
1067         // Add InstructionsBuilder to FlowBuilder
1068         flowBuilder.setInstructions(isb.build());
1069
1070         writeFlow(flowBuilder, nodeBuilder);
1071     }
1072
1073     /*
1074      * (Table:1) Local Table Miss
1075      * Match: Any Remaining Flows w/a TunID
1076      * Action: Drop w/ a low priority
1077      * table=2,priority=8192,tun_id=0x5 actions=drop
1078      */
1079
1080     private void writeLocalTableMiss(Long dpidLong, Short writeTable, String segmentationId) {
1081
1082         String nodeName = "openflow:" + dpidLong;
1083
1084         MatchBuilder matchBuilder = new MatchBuilder();
1085         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1086         FlowBuilder flowBuilder = new FlowBuilder();
1087
1088         // Create Match(es) and Set them in the FlowBuilder Object
1089         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
1090
1091         // Create the OF Actions and Instructions
1092         InstructionBuilder ib = new InstructionBuilder();
1093         InstructionsBuilder isb = new InstructionsBuilder();
1094
1095         // Instructions List Stores Individual Instructions
1096         List<Instruction> instructions = new ArrayList<Instruction>();
1097
1098         // Call the InstructionBuilder Methods Containing Actions
1099         createDropInstructions(ib);
1100         ib.setOrder(0);
1101         ib.setKey(new InstructionKey(0));
1102         instructions.add(ib.build());
1103
1104         // Add InstructionBuilder to the Instruction(s)Builder List
1105         isb.setInstruction(instructions);
1106
1107         // Add InstructionsBuilder to FlowBuilder
1108         flowBuilder.setInstructions(isb.build());
1109
1110         String flowId = "LocalTableMiss_"+segmentationId;
1111         // Add Flow Attributes
1112         flowBuilder.setId(new FlowId(flowId));
1113         FlowKey key = new FlowKey(new FlowId(flowId));
1114         flowBuilder.setStrict(true);
1115         flowBuilder.setBarrier(false);
1116         flowBuilder.setTableId(writeTable);
1117         flowBuilder.setKey(key);
1118         flowBuilder.setPriority(8192);
1119         flowBuilder.setFlowName(flowId);
1120         flowBuilder.setHardTimeout(0);
1121         flowBuilder.setIdleTimeout(0);
1122         writeFlow(flowBuilder, nodeBuilder);
1123     }
1124
1125     private Flow getFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
1126         IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
1127         if (mdsalConsumer == null) {
1128             logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
1129             return null;
1130         }
1131
1132         dataBrokerService = mdsalConsumer.getDataBrokerService();
1133
1134         if (dataBrokerService == null) {
1135             logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
1136             return null;
1137         }
1138
1139         InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
1140                 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class,
1141                 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
1142         return (Flow)dataBrokerService.readConfigurationData(path1);
1143     }
1144
1145     private void writeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
1146         IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
1147         if (mdsalConsumer == null) {
1148             logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
1149             return;
1150         }
1151
1152         dataBrokerService = mdsalConsumer.getDataBrokerService();
1153
1154         if (dataBrokerService == null) {
1155             logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
1156             return;
1157         }
1158         DataModification<InstanceIdentifier<?>, DataObject> modification = dataBrokerService.beginTransaction();
1159         InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
1160                 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class,
1161                 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
1162         modification.putOperationalData(nodeBuilderToInstanceId(nodeBuilder), nodeBuilder.build());
1163         modification.putOperationalData(path1, flowBuilder.build());
1164         modification.putConfigurationData(nodeBuilderToInstanceId(nodeBuilder), nodeBuilder.build());
1165         modification.putConfigurationData(path1, flowBuilder.build());
1166         Future<RpcResult<TransactionStatus>> commitFuture = modification.commit();
1167         try {
1168             RpcResult<TransactionStatus> result = commitFuture.get();
1169             TransactionStatus status = result.getResult();
1170             logger.debug("Transaction Status "+status.toString()+" for Flow "+flowBuilder.getFlowName());
1171         } catch (InterruptedException e) {
1172             logger.error(e.getMessage(), e);
1173         } catch (ExecutionException e) {
1174             logger.error(e.getMessage(), e);
1175         }
1176     }
1177
1178     /**
1179      * Create Ingress Port Match dpidLong, inPort
1180      *
1181      * @param matchBuilder  Map matchBuilder MatchBuilder Object without a match
1182      * @param dpidLong      Long the datapath ID of a switch/node
1183      * @param inPort        Long ingress port on a switch
1184      * @return matchBuilder Map MatchBuilder Object with a match
1185      */
1186     protected static MatchBuilder createInPortMatch(MatchBuilder matchBuilder, Long dpidLong, Long inPort) {
1187
1188         NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + inPort);
1189         logger.debug("createInPortMatch() Node Connector ID is - Type=openflow: DPID={} inPort={} ", dpidLong, inPort);
1190         matchBuilder.setInPort(NodeConnectorId.getDefaultInstance(ncid.getValue()));
1191         matchBuilder.setInPort(ncid);
1192
1193         return matchBuilder;
1194     }
1195
1196     /**
1197      * Create EtherType Match
1198      *
1199      * @param matchBuilder  Map matchBuilder MatchBuilder Object without a match
1200      * @param etherType     Long EtherType
1201      * @return matchBuilder Map MatchBuilder Object with a match
1202      */
1203     protected static MatchBuilder createEtherTypeMatch(MatchBuilder matchBuilder, EtherType etherType) {
1204
1205         EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
1206         EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
1207         ethTypeBuilder.setType(new EtherType(etherType));
1208         ethernetMatch.setEthernetType(ethTypeBuilder.build());
1209         matchBuilder.setEthernetMatch(ethernetMatch.build());
1210
1211         return matchBuilder;
1212     }
1213
1214     /**
1215      * Create Ethernet Source Match
1216      *
1217      * @param matchBuilder  MatchBuilder Object without a match yet
1218      * @param sMacAddr      String representing a source MAC
1219      * @return matchBuilder Map MatchBuilder Object with a match
1220      */
1221     protected static MatchBuilder createEthSrcMatch(MatchBuilder matchBuilder, MacAddress sMacAddr) {
1222
1223         EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
1224         EthernetSourceBuilder ethSourceBuilder = new EthernetSourceBuilder();
1225         ethSourceBuilder.setAddress(new MacAddress(sMacAddr));
1226         ethernetMatch.setEthernetSource(ethSourceBuilder.build());
1227         matchBuilder.setEthernetMatch(ethernetMatch.build());
1228
1229         return matchBuilder;
1230     }
1231
1232     /**
1233      * Create Ethernet Destination Match
1234      *
1235      * @param matchBuilder MatchBuilder Object without a match yet
1236      * @param vlanId       Integer representing a VLAN ID Integer representing a VLAN ID
1237      * @return matchBuilder Map MatchBuilder Object with a match
1238      */
1239
1240     protected static MatchBuilder createVlanIdMatch(MatchBuilder matchBuilder, VlanId vlanId) {
1241
1242         VlanMatchBuilder vlanMatchBuilder = new VlanMatchBuilder();
1243         VlanIdBuilder vlanIdBuilder = new VlanIdBuilder();
1244         vlanIdBuilder.setVlanId(new VlanId(vlanId));
1245         vlanMatchBuilder.setVlanId(vlanIdBuilder.build());
1246         matchBuilder.setVlanMatch(vlanMatchBuilder.build());
1247
1248         return matchBuilder;
1249     }
1250
1251     /**
1252      * Create Ethernet Destination Match
1253      *
1254      * @param matchBuilder  MatchBuilder Object without a match yet
1255      * @param dMacAddr      String representing a destination MAC
1256      * @return matchBuilder Map MatchBuilder Object with a match
1257      */
1258
1259     protected static MatchBuilder createDestEthMatch(MatchBuilder matchBuilder, MacAddress dMacAddr, MacAddress mask) {
1260
1261         EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
1262         EthernetDestinationBuilder ethDestinationBuilder = new EthernetDestinationBuilder();
1263         ethDestinationBuilder.setAddress(new MacAddress(dMacAddr));
1264         if (mask != null) {
1265             ethDestinationBuilder.setMask(mask);
1266         }
1267         ethernetMatch.setEthernetDestination(ethDestinationBuilder.build());
1268         matchBuilder.setEthernetMatch(ethernetMatch.build());
1269
1270         return matchBuilder;
1271     }
1272
1273     /**
1274      * Tunnel ID Match Builder
1275      *
1276      * @param matchBuilder  MatchBuilder Object without a match yet
1277      * @param tunnelId      BigInteger representing a tunnel ID
1278      * @return matchBuilder Map MatchBuilder Object with a match
1279      */
1280     protected static MatchBuilder createTunnelIDMatch(MatchBuilder matchBuilder, BigInteger tunnelId) {
1281
1282         TunnelBuilder tunnelBuilder = new TunnelBuilder();
1283         tunnelBuilder.setTunnelId(tunnelId);
1284         matchBuilder.setTunnel(tunnelBuilder.build());
1285
1286         return matchBuilder;
1287     }
1288
1289     /**
1290      * Match ICMP code and type
1291      *
1292      * @param matchBuilder  MatchBuilder Object without a match yet
1293      * @param type          short representing an ICMP type
1294      * @param code          short representing an ICMP code
1295      * @return matchBuilder Map MatchBuilder Object with a match
1296      */
1297     protected static MatchBuilder createICMPv4Match(MatchBuilder matchBuilder, short type, short code) {
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         // Build the IPv4 Match requied per OVS Syntax
1306         IpMatchBuilder ipmatch = new IpMatchBuilder();
1307         ipmatch.setIpProtocol((short) 1);
1308         matchBuilder.setIpMatch(ipmatch.build());
1309
1310         // Build the ICMPv4 Match
1311         Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
1312         icmpv4match.setIcmpv4Type(type);
1313         icmpv4match.setIcmpv4Code(code);
1314         matchBuilder.setIcmpv4Match(icmpv4match.build());
1315
1316         return matchBuilder;
1317     }
1318
1319     /**
1320      * @param matchBuilder MatchBuilder Object without a match yet
1321      * @param dstip        String containing an IPv4 prefix
1322      * @return matchBuilder Map Object with a match
1323      */
1324     private static MatchBuilder createDstL3IPv4Match(MatchBuilder matchBuilder, Ipv4Prefix dstip) {
1325
1326         EthernetMatchBuilder eth = new EthernetMatchBuilder();
1327         EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
1328         ethTypeBuilder.setType(new EtherType(0x0800L));
1329         eth.setEthernetType(ethTypeBuilder.build());
1330         matchBuilder.setEthernetMatch(eth.build());
1331
1332         Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder();
1333         ipv4match.setIpv4Destination(dstip);
1334
1335         matchBuilder.setLayer3Match(ipv4match.build());
1336
1337         return matchBuilder;
1338
1339     }
1340
1341     /**
1342      * @param matchBuilder MatchBuilder Object without a match yet
1343      * @param srcip        String containing an IPv4 prefix
1344      * @return             matchBuilder Map Object with a match
1345      */
1346     private static MatchBuilder createSrcL3IPv4Match(MatchBuilder matchBuilder, Ipv4Prefix srcip) {
1347
1348         EthernetMatchBuilder eth = new EthernetMatchBuilder();
1349         EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
1350         ethTypeBuilder.setType(new EtherType(0x0800L));
1351         eth.setEthernetType(ethTypeBuilder.build());
1352         matchBuilder.setEthernetMatch(eth.build());
1353
1354         Ipv4MatchBuilder ipv4Match = new Ipv4MatchBuilder();
1355         Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder();
1356         ipv4match.setIpv4Source(srcip);
1357         matchBuilder.setLayer3Match(ipv4match.build());
1358
1359         return matchBuilder;
1360
1361     }
1362
1363     /**
1364      * Create Source TCP Port Match
1365      *
1366      * @param matchBuilder @param matchbuilder MatchBuilder Object without a match yet
1367      * @param tcpport      Integer representing a source TCP port
1368      * @return             matchBuilder Map MatchBuilder Object with a match
1369      */
1370     protected static MatchBuilder createSetSrcTcpMatch(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         TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
1383         tcpmatch.setTcpSourcePort(tcpport);
1384         matchBuilder.setLayer4Match(tcpmatch.build());
1385
1386         return matchBuilder;
1387
1388     }
1389
1390     /**
1391      * Create Destination TCP Port Match
1392      *
1393      * @param matchBuilder MatchBuilder Object without a match yet
1394      * @param tcpport      Integer representing a destination TCP port
1395      * @return             matchBuilder Map MatchBuilder Object with a match
1396      */
1397     protected static MatchBuilder createSetDstTcpMatch(MatchBuilder matchBuilder, PortNumber tcpport) {
1398
1399         EthernetMatchBuilder ethType = new EthernetMatchBuilder();
1400         EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
1401         ethTypeBuilder.setType(new EtherType(0x0800L));
1402         ethType.setEthernetType(ethTypeBuilder.build());
1403         matchBuilder.setEthernetMatch(ethType.build());
1404
1405         IpMatchBuilder ipmatch = new IpMatchBuilder();
1406         ipmatch.setIpProtocol((short) 6);
1407         matchBuilder.setIpMatch(ipmatch.build());
1408
1409         PortNumber dstport = new PortNumber(tcpport);
1410         TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
1411
1412         tcpmatch.setTcpDestinationPort(tcpport);
1413         matchBuilder.setLayer4Match(tcpmatch.build());
1414
1415         return matchBuilder;
1416     }
1417
1418     /**
1419      * Create Send to Controller Reserved Port Instruction (packet_in)
1420      *
1421      * @param ib Map InstructionBuilder without any instructions
1422      * @return ib Map InstructionBuilder with instructions
1423      */
1424
1425     protected static InstructionBuilder createSendToControllerInstructions(InstructionBuilder ib) {
1426
1427         List<Action> actionList = new ArrayList<Action>();
1428         ActionBuilder ab = new ActionBuilder();
1429
1430         OutputActionBuilder output = new OutputActionBuilder();
1431         output.setMaxLength(56);
1432         Uri value = new Uri("CONTROLLER");
1433         output.setOutputNodeConnector(value);
1434         ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
1435         ab.setOrder(0);
1436         ab.setKey(new ActionKey(0));
1437         actionList.add(ab.build());
1438
1439         // Create an Apply Action
1440         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1441         aab.setAction(actionList);
1442
1443         // Wrap our Apply Action in an Instruction
1444         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1445
1446         return ib;
1447     }
1448
1449     /**
1450      * Create Output Port Instruction
1451      *
1452      * @param ib       Map InstructionBuilder without any instructions
1453      * @param dpidLong Long the datapath ID of a switch/node
1454      * @param port     Long representing a port on a switch/node
1455      * @return ib InstructionBuilder Map with instructions
1456      */
1457     protected static InstructionBuilder createOutputPortInstructions(InstructionBuilder ib, Long dpidLong, Long port) {
1458
1459         NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
1460         logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} inPort={} ", dpidLong, port);
1461
1462         List<Action> actionList = new ArrayList<Action>();
1463         ActionBuilder ab = new ActionBuilder();
1464         OutputActionBuilder oab = new OutputActionBuilder();
1465         oab.setOutputNodeConnector(ncid);
1466
1467         ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
1468         ab.setOrder(0);
1469         ab.setKey(new ActionKey(0));
1470         actionList.add(ab.build());
1471
1472         // Create an Apply Action
1473         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1474         aab.setAction(actionList);
1475         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1476
1477         return ib;
1478     }
1479
1480     /**
1481      * Create Output Port Instruction
1482      *
1483      * @param ib       Map InstructionBuilder without any instructions
1484      * @param dpidLong Long the datapath ID of a switch/node
1485      * @param port     Long representing a port on a switch/node
1486      * @return ib InstructionBuilder Map with instructions
1487      */
1488     protected static InstructionBuilder createOutputPortInstructions(InstructionBuilder ib, Long dpidLong, Long port , List<Instruction> instructions) {
1489
1490         NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
1491         logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
1492
1493         List<Action> actionList = new ArrayList<Action>();
1494         ActionBuilder ab = new ActionBuilder();
1495
1496         List<Action> existingActions = null;
1497         if (instructions != null) {
1498             for (Instruction in : instructions) {
1499                 if (in.getInstruction() instanceof ApplyActionsCase) {
1500                     existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
1501                     actionList.addAll(existingActions);
1502                 }
1503             }
1504         }
1505
1506         OutputActionBuilder oab = new OutputActionBuilder();
1507         oab.setOutputNodeConnector(ncid);
1508         ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
1509         ab.setOrder(0);
1510         ab.setKey(new ActionKey(0));
1511         Action newAction = ab.build();
1512         boolean addNew = true;
1513         for (Action action : actionList) {
1514             if (action.getAction() instanceof OutputActionCase) {
1515                 OutputActionCase opAction = (OutputActionCase)action.getAction();
1516                 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
1517                     addNew = false;
1518                     break;
1519                 }
1520             }
1521         }
1522         if (addNew) actionList.add(newAction);
1523
1524         // Create an Apply Action
1525         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1526         aab.setAction(actionList);
1527         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1528
1529         return ib;
1530     }
1531
1532     /**
1533      * Create Set Vlan ID Instruction
1534      *
1535      * @param ib     Map InstructionBuilder without any instructions
1536      * @param vlanId Integer representing a VLAN ID Integer representing a VLAN ID
1537      * @return ib Map InstructionBuilder with instructions
1538      */
1539     protected static InstructionBuilder createSetVlanInstructions(InstructionBuilder ib, VlanId vlanId) {
1540
1541         List<Action> actionList = new ArrayList<Action>();
1542         ActionBuilder ab = new ActionBuilder();
1543
1544         SetVlanIdActionBuilder vl = new SetVlanIdActionBuilder();
1545         vl.setVlanId(vlanId);
1546         ab.setAction(new SetVlanIdActionCaseBuilder().setSetVlanIdAction(vl.build()).build());
1547         actionList.add(ab.build());
1548         // Create an Apply Action
1549         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1550         aab.setAction(actionList);
1551
1552         // Wrap our Apply Action in an Instruction
1553         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1554
1555         return ib;
1556     }
1557
1558     /**
1559      * Create Set IPv4 Destination Instruction
1560      *
1561      * @param ib Map InstructionBuilder without any instructions
1562      * @return ib Map InstructionBuilder with instructions
1563      */
1564     protected static InstructionBuilder createStripVlanInstructions(InstructionBuilder ib) {
1565
1566         StripVlanActionBuilder stripVlanActionBuilder = new StripVlanActionBuilder();
1567         StripVlanAction vlanAction = stripVlanActionBuilder.build();
1568         ActionBuilder ab = new ActionBuilder();
1569         ab.setAction(new StripVlanActionCaseBuilder().setStripVlanAction(vlanAction).build());
1570
1571         // Add our drop action to a list
1572         List<Action> actionList = new ArrayList<Action>();
1573         actionList.add(ab.build());
1574
1575         // Create an Apply Action
1576         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1577         aab.setAction(actionList);
1578
1579         // Wrap our Apply Action in an Instruction
1580         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1581
1582         return ib;
1583     }
1584
1585     /**
1586      * Create Set IPv4 Source Instruction
1587      *
1588      * @param ib        Map InstructionBuilder without any instructions
1589      * @param prefixsrc String containing an IPv4 prefix
1590      * @return ib Map InstructionBuilder with instructions
1591      */
1592     protected static InstructionBuilder createNwSrcInstructions(InstructionBuilder ib, Ipv4Prefix prefixsrc) {
1593
1594         List<Action> actionList = new ArrayList<Action>();
1595         ActionBuilder ab = new ActionBuilder();
1596
1597         SetNwSrcActionBuilder setNwsrcActionBuilder = new SetNwSrcActionBuilder();
1598         Ipv4Builder ipsrc = new Ipv4Builder();
1599         ipsrc.setIpv4Address(prefixsrc);
1600         setNwsrcActionBuilder.setAddress(ipsrc.build());
1601         ab.setAction(new SetNwSrcActionCaseBuilder().setSetNwSrcAction(setNwsrcActionBuilder.build()).build());
1602         actionList.add(ab.build());
1603
1604         // Create an Apply Action
1605         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1606         aab.setAction(actionList);
1607
1608         // Wrap our Apply Action in an Instruction
1609         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1610
1611         return ib;
1612     }
1613
1614     /**
1615      * Create Set IPv4 Destination Instruction
1616      *
1617      * @param ib           Map InstructionBuilder without any instructions
1618      * @param prefixdst    String containing an IPv4 prefix
1619      * @return ib Map InstructionBuilder with instructions
1620      */
1621     protected static InstructionBuilder createNwDstInstructions(InstructionBuilder ib, Ipv4Prefix prefixdst) {
1622
1623         List<Action> actionList = new ArrayList<Action>();
1624         ActionBuilder ab = new ActionBuilder();
1625
1626         SetNwDstActionBuilder setNwDstActionBuilder = new SetNwDstActionBuilder();
1627         Ipv4Builder ipdst = new Ipv4Builder();
1628         ipdst.setIpv4Address(prefixdst);
1629         setNwDstActionBuilder.setAddress(ipdst.build());
1630         ab.setAction(new SetNwDstActionCaseBuilder().setSetNwDstAction(setNwDstActionBuilder.build()).build());
1631         actionList.add(ab.build());
1632
1633         // Create an Apply Action
1634         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1635         aab.setAction(actionList);
1636
1637         // Wrap our Apply Action in an Instruction
1638         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1639
1640         return ib;
1641     }
1642
1643     /**
1644      * Create Drop Instruction
1645      *
1646      * @param ib Map InstructionBuilder without any instructions
1647      * @return ib Map InstructionBuilder with instructions
1648      */
1649     protected static InstructionBuilder createDropInstructions(InstructionBuilder ib) {
1650
1651         DropActionBuilder dab = new DropActionBuilder();
1652         DropAction dropAction = dab.build();
1653         ActionBuilder ab = new ActionBuilder();
1654         ab.setAction(new DropActionCaseBuilder().setDropAction(dropAction).build());
1655
1656         // Add our drop action to a list
1657         List<Action> actionList = new ArrayList<Action>();
1658         actionList.add(ab.build());
1659
1660         // Create an Apply Action
1661         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1662         aab.setAction(actionList);
1663
1664         // Wrap our Apply Action in an Instruction
1665         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1666
1667         return ib;
1668     }
1669
1670     /**
1671      * Create GOTO Table Instruction Builder
1672      *
1673      * @param ib      Map InstructionBuilder without any instructions
1674      * @param tableId short representing a flow table ID short representing a flow table ID
1675      * @return ib Map InstructionBuilder with instructions
1676      */
1677     protected static InstructionBuilder createGotoTableInstructions(InstructionBuilder ib, short tableId) {
1678
1679         GoToTableBuilder gttb = new GoToTableBuilder();
1680         gttb.setTableId(tableId);
1681
1682         // Wrap our Apply Action in an InstructionBuilder
1683         ib.setInstruction(new GoToTableCaseBuilder().setGoToTable(gttb.build()).build());
1684
1685         return ib;
1686     }
1687
1688     /**
1689      * Create Set Tunnel ID Instruction Builder
1690      *
1691      * @param ib       Map InstructionBuilder without any instructions
1692      * @param tunnelId BigInteger representing a tunnel ID
1693      * @return ib Map InstructionBuilder with instructions
1694      */
1695     protected static InstructionBuilder createSetTunnelIdInstructions(InstructionBuilder ib, BigInteger tunnelId) {
1696
1697         List<Action> actionList = new ArrayList<Action>();
1698         ActionBuilder ab = new ActionBuilder();
1699         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1700
1701         // Build the Set Tunnel Field Action
1702         TunnelBuilder tunnel = new TunnelBuilder();
1703         tunnel.setTunnelId(tunnelId);
1704         setFieldBuilder.setTunnel(tunnel.build());
1705         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1706         actionList.add(ab.build());
1707
1708         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1709         aab.setAction(actionList);
1710
1711         // Wrap the Apply Action in an InstructionBuilder and return
1712         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1713
1714         return ib;
1715     }
1716
1717     /**
1718      * Create Set Source TCP Port Instruction
1719      *
1720      * @param ib      Map InstructionBuilder without any instructions
1721      * @param tcpport Integer representing a source TCP port
1722      * @return ib Map InstructionBuilder with instructions
1723      */
1724     protected static InstructionBuilder createSetSrcTCPPort(InstructionBuilder ib, PortNumber tcpport) {
1725
1726         List<Action> actionList = new ArrayList<Action>();
1727         ActionBuilder ab = new ActionBuilder();
1728         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1729
1730         // Build the Destination TCP Port
1731         PortNumber tcpsrcport = new PortNumber(tcpport);
1732         TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
1733         tcpmatch.setTcpSourcePort(tcpsrcport);
1734
1735         setFieldBuilder.setLayer4Match(tcpmatch.build());
1736         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1737         ab.setKey(new ActionKey(1));
1738         actionList.add(ab.build());
1739
1740         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1741         aab.setAction(actionList);
1742         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1743
1744         return ib;
1745     }
1746
1747     /**
1748      * Create Set Destination TCP Port Instruction
1749      *
1750      * @param ib      Map InstructionBuilder without any instructions
1751      * @param tcpport Integer representing a source TCP port
1752      * @return ib Map InstructionBuilder with instructions
1753      */
1754     protected static InstructionBuilder createSetDstTCPPort(InstructionBuilder ib, PortNumber tcpport) {
1755
1756         List<Action> actionList = new ArrayList<Action>();
1757         ActionBuilder ab = new ActionBuilder();
1758         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1759
1760         // Build the Destination TCP Port
1761         PortNumber tcpdstport = new PortNumber(tcpport);
1762         TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
1763         tcpmatch.setTcpDestinationPort(tcpdstport);
1764
1765         setFieldBuilder.setLayer4Match(tcpmatch.build());
1766         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1767         ab.setKey(new ActionKey(1));
1768         actionList.add(ab.build());
1769
1770         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1771         aab.setAction(actionList);
1772         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1773
1774         return ib;
1775     }
1776
1777     /**
1778      * Create Set Source UDP Port Instruction
1779      *
1780      * @param ib      Map InstructionBuilder without any instructions
1781      * @param udpport Integer representing a source UDP port
1782      * @return ib Map InstructionBuilder with instructions
1783      */
1784     protected static InstructionBuilder createSetSrcUDPPort(InstructionBuilder ib, PortNumber udpport) {
1785
1786         List<Action> actionList = new ArrayList<Action>();
1787         ActionBuilder ab = new ActionBuilder();
1788         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1789
1790         // Build the Destination TCP Port
1791         PortNumber udpsrcport = new PortNumber(udpport);
1792         UdpMatchBuilder udpmatch = new UdpMatchBuilder();
1793         udpmatch.setUdpSourcePort(udpsrcport);
1794
1795         setFieldBuilder.setLayer4Match(udpmatch.build());
1796         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1797         ab.setKey(new ActionKey(1));
1798         actionList.add(ab.build());
1799
1800         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1801         aab.setAction(actionList);
1802         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1803
1804         return ib;
1805     }
1806
1807     /**
1808      * Create Set Destination UDP Port Instruction
1809      *
1810      * @param ib      Map InstructionBuilder without any instructions
1811      * @param udpport Integer representing a destination UDP port
1812      * @return ib Map InstructionBuilder with instructions
1813      */
1814     protected static InstructionBuilder createSetDstUDPPort(InstructionBuilder ib, PortNumber udpport) {
1815
1816         List<Action> actionList = new ArrayList<Action>();
1817         ActionBuilder ab = new ActionBuilder();
1818         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1819
1820         // Build the Destination TCP Port
1821         PortNumber udpdstport = new PortNumber(udpport);
1822         UdpMatchBuilder udpmatch = new UdpMatchBuilder();
1823         udpmatch.setUdpDestinationPort(udpdstport);
1824
1825         setFieldBuilder.setLayer4Match(udpmatch.build());
1826         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1827         ab.setKey(new ActionKey(1));
1828         actionList.add(ab.build());
1829
1830         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1831         aab.setAction(actionList);
1832         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1833
1834         return ib;
1835     }
1836
1837     /**
1838      * Create Set ICMP Code Instruction
1839      *
1840      * @param ib   Map InstructionBuilder without any instructions
1841      * @param code short repesenting an ICMP code
1842      * @return ib Map InstructionBuilder with instructions
1843      */
1844
1845     private static InstructionBuilder createSetIcmpCodeInstruction(InstructionBuilder ib, short code) {
1846
1847         List<Action> actionList = new ArrayList<Action>();
1848         ActionBuilder ab = new ActionBuilder();
1849         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1850         Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
1851
1852         // Build the ICMPv4 Code Match
1853         icmpv4match.setIcmpv4Code(code);
1854         setFieldBuilder.setIcmpv4Match(icmpv4match.build());
1855
1856         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1857         ab.setKey(new ActionKey(0));
1858         actionList.add(ab.build());
1859         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1860         aab.setAction(actionList);
1861
1862         // Wrap our Apply Action in an Instruction
1863         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1864
1865         return ib;
1866     }
1867
1868     /**
1869      * Create Set ICMP Code Instruction
1870      *
1871      * @param ib Map InstructionBuilder without any instructions
1872      * @return ib Map InstructionBuilder with instructions
1873      */
1874     private static InstructionBuilder createSetIcmpTypeInstruction(InstructionBuilder ib, short type) {
1875
1876         List<Action> actionList = new ArrayList<Action>();
1877         ActionBuilder ab = new ActionBuilder();
1878         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1879         Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
1880
1881         // Build the ICMPv4 Code Match
1882         icmpv4match.setIcmpv4Code(type);
1883         setFieldBuilder.setIcmpv4Match(icmpv4match.build());
1884
1885         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1886         ab.setKey(new ActionKey(1));
1887         actionList.add(ab.build());
1888         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1889         aab.setAction(actionList);
1890
1891         // Wrap our Apply Action in an Instruction
1892         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1893
1894         return ib;
1895     }
1896
1897     /**
1898      * Create Decrement TTL Instruction
1899      *
1900      * @param ib Map InstructionBuilder without any instructions
1901      * @return ib Map InstructionBuilder with instructions
1902      */
1903     private static InstructionBuilder createDecNwTtlInstructions(InstructionBuilder ib) {
1904         DecNwTtlBuilder decNwTtlBuilder = new DecNwTtlBuilder();
1905         DecNwTtl decNwTtl = decNwTtlBuilder.build();
1906         ActionBuilder ab = new ActionBuilder();
1907         ab.setAction(new DecNwTtlCaseBuilder().setDecNwTtl(decNwTtl).build());
1908
1909         // Add our drop action to a list
1910         List<Action> actionList = new ArrayList<Action>();
1911         actionList.add(ab.build());
1912
1913         // Create an Apply Action
1914         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1915         aab.setAction(actionList);
1916
1917         // Wrap our Apply Action in an Instruction
1918         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1919
1920         return ib;
1921     }
1922
1923     /**
1924      * Set Src Arp MAC
1925      */
1926     private static InstructionBuilder createSrcArpMacInstructions(InstructionBuilder ib, MacAddress macsrc) {
1927
1928         List<Action> actionList = new ArrayList<Action>();
1929         ActionBuilder ab = new ActionBuilder();
1930
1931         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1932         ArpMatchBuilder arpmatch = new ArpMatchBuilder();
1933         ArpSourceHardwareAddressBuilder arpsrc = new ArpSourceHardwareAddressBuilder();
1934         arpsrc.setAddress(macsrc);
1935         arpmatch.setArpSourceHardwareAddress(arpsrc.build());
1936         setFieldBuilder.setLayer3Match(arpmatch.build());
1937         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1938         ab.setKey(new ActionKey(0));
1939         actionList.add(ab.build());
1940
1941         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1942         aab.setAction(actionList);
1943
1944         return ib;
1945     }
1946
1947     /**
1948      * Set Dst Arp MAC
1949      */
1950     private static InstructionBuilder createDstArpMacInstructions(InstructionBuilder ib, MacAddress macdst) {
1951
1952         List<Action> actionList = new ArrayList<Action>();
1953         ActionBuilder ab = new ActionBuilder();
1954         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1955
1956         ArpMatchBuilder arpmatch = new ArpMatchBuilder();
1957         ArpTargetHardwareAddressBuilder arpdst = new ArpTargetHardwareAddressBuilder();
1958         arpdst.setAddress(macdst);
1959         setFieldBuilder.setLayer3Match(arpmatch.build());
1960         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1961         ab.setKey(new ActionKey(0));
1962         actionList.add(ab.build());
1963
1964         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1965         aab.setAction(actionList);
1966
1967         return ib;
1968     }
1969
1970     /**
1971      * Set Dst Arp IP
1972      */
1973     private static InstructionBuilder createDstArpIpInstructions(InstructionBuilder ib, Ipv4Prefix dstiparp) {
1974
1975         List<Action> actionList = new ArrayList<Action>();
1976         ActionBuilder ab = new ActionBuilder();
1977         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1978
1979         ArpMatchBuilder arpmatch = new ArpMatchBuilder();
1980         arpmatch.setArpTargetTransportAddress(dstiparp);
1981         setFieldBuilder.setLayer3Match(arpmatch.build());
1982         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1983         ab.setKey(new ActionKey(0));
1984         actionList.add(ab.build());
1985
1986         ApplyActionsBuilder aab = new ApplyActionsBuilder();
1987         aab.setAction(actionList);
1988
1989         return ib;
1990     }
1991
1992     /**
1993      * Set Src Arp IP
1994      */
1995     private static InstructionBuilder createSrcArpIpInstructions(InstructionBuilder ib, Ipv4Prefix srciparp) {
1996
1997         List<Action> actionList = new ArrayList<Action>();
1998         ActionBuilder ab = new ActionBuilder();
1999         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
2000
2001         ArpMatchBuilder arpmatch = new ArpMatchBuilder();
2002         arpmatch.setArpSourceTransportAddress(srciparp);
2003         setFieldBuilder.setLayer3Match(arpmatch.build());
2004         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
2005         ab.setKey(new ActionKey(0));
2006         actionList.add(ab.build());
2007
2008         ApplyActionsBuilder aab = new ApplyActionsBuilder();
2009         aab.setAction(actionList);
2010
2011         return ib;
2012     }
2013
2014     @Override
2015     public void initializeOFFlowRules(Node openflowNode) {
2016         IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
2017         List<Node> ovsNodes = connectionService.getNodes();
2018         if (ovsNodes == null) return;
2019         for (Node ovsNode : ovsNodes) {
2020             Long dpid = this.getIntegrationBridgeOFDPID(ovsNode);
2021             logger.debug("Compare openflowNode to OVS br-int node {} vs {}", openflowNode.getID(), dpid);
2022             String openflowID = ""+openflowNode.getID();
2023             if (openflowID.contains(""+dpid)) {
2024                 this.initializeFlowRules(ovsNode, AdminConfigManager.getManager().getIntegrationBridgeName());
2025                 this.triggerInterfaceUpdates(ovsNode);
2026             }
2027         }
2028     }
2029
2030     private NodeBuilder createNodeBuilder(String nodeId) {
2031         NodeBuilder builder = new NodeBuilder();
2032         builder.setId(new NodeId(nodeId));
2033         builder.setKey(new NodeKey(builder.getId()));
2034         return builder;
2035     }
2036
2037     private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeBuilderToInstanceId(NodeBuilder
2038                                                                                                                                              node) {
2039         return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
2040                 node.getKey()).toInstance();
2041     }
2042 }