Merge remote-tracking branch 'origin/master' into merge-branch
[ovsdb.git] / neutron / src / main / java / org / opendaylight / ovsdb / neutron / provider / OF13Provider.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, Dave Tucker
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.IAdminConfigManager;
38 import org.opendaylight.ovsdb.neutron.IInternalNetworkManager;
39 import org.opendaylight.ovsdb.neutron.IMDSALConsumer;
40 import org.opendaylight.ovsdb.neutron.NetworkHandler;
41 import org.opendaylight.ovsdb.neutron.ITenantNetworkManager;
42 import org.opendaylight.ovsdb.plugin.IConnectionServiceInternal;
43 import org.opendaylight.ovsdb.plugin.OVSDBConfigService;
44 import org.opendaylight.ovsdb.plugin.StatusWithUuid;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DecNwTtlCaseBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCase;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCaseBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCase;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCaseBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCaseBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionCaseBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwSrcActionCaseBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCaseBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCaseBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtl;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtlBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropAction;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropActionBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.group.action._case.GroupActionBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.vlan.action._case.PushVlanActionBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.dst.action._case.SetNwDstActionBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.src.action._case.SetNwSrcActionBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.vlan.id.action._case.SetVlanIdActionBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCaseBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTableBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.BucketId;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.BucketsBuilder;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.BucketBuilder;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.BucketKey;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.Buckets;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpSourceHardwareAddressBuilder;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpTargetHardwareAddressBuilder;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv4MatchBuilder;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
129 import org.opendaylight.yangtools.yang.binding.DataObject;
130 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
131 import org.opendaylight.yangtools.yang.common.RpcResult;
132 import org.slf4j.Logger;
133 import org.slf4j.LoggerFactory;
134
135
136 /**
137  *
138  */
139 public class OF13Provider implements NetworkProvider {
140     private static final Logger logger = LoggerFactory.getLogger(OF13Provider.class);
141     private DataBrokerService dataBrokerService;
142     private static final short TABLE_0_DEFAULT_INGRESS = 0;
143     private static final short TABLE_1_ISOLATE_TENANT = 10;
144     private static final short TABLE_2_LOCAL_FORWARD = 20;
145     private static Long groupId = 1L;
146
147     private IAdminConfigManager adminConfigManager;
148     private IInternalNetworkManager internalNetworkManager;
149     private ITenantNetworkManager tenantNetworkManager;
150
151     public OF13Provider(IAdminConfigManager adminConfigManager,
152                         IInternalNetworkManager internalNetworkManager,
153                         ITenantNetworkManager tenantNetworkManager) {
154         this.adminConfigManager = adminConfigManager;
155         this.internalNetworkManager = internalNetworkManager;
156         this.tenantNetworkManager = tenantNetworkManager;
157     }
158
159     @Override
160     public boolean hasPerTenantTunneling() {
161         return false;
162     }
163
164     private Status getTunnelReadinessStatus (Node node, String tunnelKey) {
165         InetAddress srcTunnelEndPoint = adminConfigManager.getTunnelEndPoint(node);
166         if (srcTunnelEndPoint == null) {
167             logger.error("Tunnel Endpoint not configured for Node {}", node);
168             return new Status(StatusCode.NOTFOUND, "Tunnel Endpoint not configured for "+ node);
169         }
170
171         if (!internalNetworkManager.isInternalNetworkNeutronReady(node)) {
172             logger.error(node+" is not Overlay ready");
173             return new Status(StatusCode.NOTACCEPTABLE, node+" is not Overlay ready");
174         }
175
176         if (!tenantNetworkManager.isTenantNetworkPresentInNode(node, tunnelKey)) {
177             logger.debug(node+" has no VM corresponding to segment "+ tunnelKey);
178             return new Status(StatusCode.NOTACCEPTABLE, node+" has no VM corresponding to segment "+ tunnelKey);
179         }
180         return new Status(StatusCode.SUCCESS);
181     }
182
183     private String getTunnelName(String tunnelType, InetAddress dst) {
184         return tunnelType+"-"+dst.getHostAddress();
185     }
186
187     private boolean isTunnelPresent(Node node, String tunnelName, String bridgeUUID) throws Exception {
188         OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
189         Bridge bridge = (Bridge)ovsdbTable.getRow(node, Bridge.NAME.getName(), bridgeUUID);
190         if (bridge != null) {
191             Set<UUID> ports = bridge.getPorts();
192             for (UUID portUUID : ports) {
193                 Port port = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), portUUID.toString());
194                 if (port != null && port.getName().equalsIgnoreCase(tunnelName)) return true;
195             }
196         }
197         return false;
198     }
199
200     private String getPortUuid(Node node, String name, String bridgeUUID) throws Exception {
201         OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
202         Bridge bridge = (Bridge)ovsdbTable.getRow(node, Bridge.NAME.getName(), bridgeUUID);
203         if (bridge != null) {
204             Set<UUID> ports = bridge.getPorts();
205             for (UUID portUUID : ports) {
206                 Port port = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), portUUID.toString());
207                 if (port != null && port.getName().equalsIgnoreCase(name)) return portUUID.toString();
208             }
209         }
210         return null;
211     }
212
213     private Status addTunnelPort (Node node, String tunnelType, InetAddress src, InetAddress dst) {
214         try {
215             String bridgeUUID = null;
216             String tunnelBridgeName = adminConfigManager.getIntegrationBridgeName();
217             OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
218             Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
219             if (bridgeTable != null) {
220                 for (String uuid : bridgeTable.keySet()) {
221                     Bridge bridge = (Bridge)bridgeTable.get(uuid);
222                     if (bridge.getName().equals(tunnelBridgeName)) {
223                         bridgeUUID = uuid;
224                         break;
225                     }
226                 }
227             }
228             if (bridgeUUID == null) {
229                 logger.error("Could not find Bridge {} in {}", tunnelBridgeName, node);
230                 return new Status(StatusCode.NOTFOUND, "Could not find "+tunnelBridgeName+" in "+node);
231             }
232             String portName = getTunnelName(tunnelType, dst);
233
234             if (this.isTunnelPresent(node, portName, bridgeUUID)) {
235                 logger.trace("Tunnel {} is present in {} of {}", portName, tunnelBridgeName, node);
236                 return new Status(StatusCode.SUCCESS);
237             }
238
239             Port tunnelPort = new Port();
240             tunnelPort.setName(portName);
241             StatusWithUuid statusWithUuid = ovsdbTable.insertRow(node, Port.NAME.getName(), bridgeUUID, tunnelPort);
242             if (!statusWithUuid.isSuccess()) {
243                 logger.error("Failed to insert Tunnel port {} in {}", portName, bridgeUUID);
244                 return statusWithUuid;
245             }
246
247             String tunnelPortUUID = statusWithUuid.getUuid().toString();
248             String interfaceUUID = null;
249             int timeout = 6;
250             while ((interfaceUUID == null) && (timeout > 0)) {
251                 tunnelPort = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), tunnelPortUUID);
252                 OvsDBSet<UUID> interfaces = tunnelPort.getInterfaces();
253                 if (interfaces == null || interfaces.size() == 0) {
254                     // Wait for the OVSDB update to sync up the Local cache.
255                     Thread.sleep(500);
256                     timeout--;
257                     continue;
258                 }
259                 interfaceUUID = interfaces.toArray()[0].toString();
260                 Interface intf = (Interface)ovsdbTable.getRow(node, Interface.NAME.getName(), interfaceUUID);
261                 if (intf == null) interfaceUUID = null;
262             }
263
264             if (interfaceUUID == null) {
265                 logger.error("Cannot identify Tunnel Interface for port {}/{}", portName, tunnelPortUUID);
266                 return new Status(StatusCode.INTERNALERROR);
267             }
268
269             Interface tunInterface = new Interface();
270             tunInterface.setType(tunnelType);
271             OvsDBMap<String, String> options = new OvsDBMap<String, String>();
272             options.put("key", "flow");
273             options.put("local_ip", src.getHostAddress());
274             options.put("remote_ip", dst.getHostAddress());
275             tunInterface.setOptions(options);
276             Status status = ovsdbTable.updateRow(node, Interface.NAME.getName(), tunnelPortUUID, interfaceUUID, tunInterface);
277             logger.debug("Tunnel {} add status : {}", tunInterface, status);
278             return status;
279         } catch (Exception e) {
280             logger.error("Exception in addTunnelPort", e);
281             return new Status(StatusCode.INTERNALERROR);
282         }
283     }
284
285     /* delete port from ovsdb port table */
286     private Status deletePort(Node node, String bridgeName, String portName) {
287         try {
288             String bridgeUUID = null;
289             OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
290             Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
291             if (bridgeTable != null) {
292                 for (String uuid : bridgeTable.keySet()) {
293                     Bridge bridge = (Bridge)bridgeTable.get(uuid);
294                     if (bridge.getName().equals(bridgeName)) {
295                         bridgeUUID = uuid;
296                         break;
297                     }
298                 }
299             }
300             if (bridgeUUID == null) {
301                 logger.debug("Could not find Bridge {} in {}", bridgeName, node);
302                 return new Status(StatusCode.SUCCESS);
303             }
304
305             String portUUID = this.getPortUuid(node, portName, bridgeUUID);
306             Status status = new Status(StatusCode.SUCCESS);
307             if (portUUID != null) {
308                status = ovsdbTable.deleteRow(node, Port.NAME.getName(), portUUID);
309                if (!status.isSuccess()) {
310                    logger.error("Failed to delete port {} in {} status : {}", portName, bridgeUUID,
311                                 status);
312                    return status;
313                }
314                logger.debug("Port {} delete status : {}", portName, status);
315             }
316             return status;
317         } catch (Exception e) {
318             logger.error("Exception in deletePort", e);
319             return new Status(StatusCode.INTERNALERROR);
320         }
321     }
322
323     private Status deleteTunnelPort(Node node, String tunnelType, InetAddress src, InetAddress dst) {
324         String tunnelBridgeName = adminConfigManager.getIntegrationBridgeName();
325         String portName = getTunnelName(tunnelType, dst);
326         Status status = deletePort(node, tunnelBridgeName, portName);
327         return status;
328     }
329
330     private Status deletePhysicalPort(Node node, String phyIntfName) {
331         String intBridgeName = adminConfigManager.getIntegrationBridgeName();
332         Status status = deletePort(node, intBridgeName, phyIntfName);
333         return status;
334     }
335
336     private void programLocalBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long localPort) {
337          /*
338          * Table(0) Rule #3
339          * ----------------
340          * Match: VM sMac and Local Ingress Port
341          * Action:Action: Set Tunnel ID and GOTO Local Table (5)
342          */
343
344          handleLocalInPort(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_1_ISOLATE_TENANT, segmentationId, localPort, attachedMac, true);
345
346         /*
347          * Table(0) Rule #4
348          * ----------------
349          * Match: Drop any remaining Ingress Local VM Packets
350          * Action: Drop w/ a low priority
351          */
352
353          handleDropSrcIface(dpid, localPort, true);
354
355          /*
356           * Table(2) Rule #1
357           * ----------------
358           * Match: Match TunID and Destination DL/dMAC Addr
359           * Action: Output Port
360           * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
361           */
362
363          handleLocalUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, attachedMac, true);
364
365          /*
366           * Table(2) Rule #2
367           * ----------------
368           * Match: Tunnel ID and dMAC (::::FF:FF)
369           * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
370           * actions=output:2,3,4,5
371           */
372
373           handleLocalBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, true);
374
375           /*
376            * TODO : Optimize the following 2 writes to be restricted only for the very first port known in a segment.
377            */
378           /*
379            * Table(1) Rule #3
380            * ----------------
381            * Match:  Any remaining Ingress Local VM Packets
382            * Action: Drop w/ a low priority
383            * -------------------------------------------
384            * table=1,priority=8192,tun_id=0x5 actions=goto_table:2
385            */
386
387            handleTunnelMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, true);
388
389           /*
390            * Table(2) Rule #3
391            * ----------------
392            * Match: Any Remaining Flows w/a TunID
393            * Action: Drop w/ a low priority
394            * table=2,priority=8192,tun_id=0x5 actions=drop
395            */
396
397            handleLocalTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, true);
398     }
399
400     private void removeLocalBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long localPort) {
401         /*
402          * Table(0) Rule #3
403          * ----------------
404          * Match: VM sMac and Local Ingress Port
405          * Action:Action: Set Tunnel ID and GOTO Local Table (5)
406          */
407
408          handleLocalInPort(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_1_ISOLATE_TENANT, segmentationId, localPort, attachedMac, false);
409
410         /*
411          * Table(0) Rule #4
412          * ----------------
413          * Match: Drop any remaining Ingress Local VM Packets
414          * Action: Drop w/ a low priority
415          */
416
417          handleDropSrcIface(dpid, localPort, false);
418
419          /*
420           * Table(2) Rule #1
421           * ----------------
422           * Match: Match TunID and Destination DL/dMAC Addr
423           * Action: Output Port
424           * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
425           */
426
427          handleLocalUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, attachedMac, false);
428
429          /*
430           * Table(2) Rule #2
431           * ----------------
432           * Match: Tunnel ID and dMAC (::::FF:FF)
433           * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
434           * actions=output:2,3,4,5
435           */
436
437           handleLocalBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, false);
438     }
439
440     private void programLocalIngressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
441         /*
442          * Table(0) Rule #2
443          * ----------------
444          * Match: Ingress Port, Tunnel ID
445          * Action: GOTO Local Table (20)
446          */
447
448          handleTunnelIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, true);
449
450          /*
451           * Table(1) Rule #2
452           * ----------------
453           * Match: Match Tunnel ID and L2 ::::FF:FF Flooding
454           * Action: Flood to selected destination TEPs
455           * -------------------------------------------
456           * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
457           * actions=output:10,output:11,goto_table:2
458           */
459
460          handleTunnelFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, true);
461
462     }
463
464     private void programRemoteEgressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
465         /*
466          * Table(1) Rule #1
467          * ----------------
468          * Match: Drop any remaining Ingress Local VM Packets
469          * Action: Drop w/ a low priority
470          * -------------------------------------------
471          * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
472          * actions=output:11,goto_table:2
473          */
474
475         handleTunnelOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, attachedMac, true);
476     }
477
478     private void removeRemoteEgressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
479         /*
480          * Table(1) Rule #1
481          * ----------------
482          * Match: Drop any remaining Ingress Local VM Packets
483          * Action: Drop w/ a low priority
484          * -------------------------------------------
485          * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
486          * actions=output:11,goto_table:2
487          */
488
489         handleTunnelOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, attachedMac, false);
490     }
491
492     /* Remove tunnel rules if last node in this tenant network */
493     private void removePerTunnelRules(Node node, Long dpid, String segmentationId, long tunnelOFPort) {
494         /*
495          * TODO : Optimize the following 2 writes to be restricted only for the very first port known in a segment.
496          */
497         /*
498          * Table(1) Rule #3
499          * ----------------
500          * Match:  Any remaining Ingress Local VM Packets
501          * Action: Drop w/ a low priority
502          * -------------------------------------------
503          * table=1,priority=8192,tun_id=0x5 actions=goto_table:2
504          */
505
506         handleTunnelMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, false);
507
508         /*
509          * Table(2) Rule #3
510          * ----------------
511          * Match: Any Remaining Flows w/a TunID
512          * Action: Drop w/ a low priority
513          * table=2,priority=8192,tun_id=0x5 actions=drop
514          */
515
516         handleLocalTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, false);
517
518         /*
519          * Table(0) Rule #2
520          * ----------------
521          * Match: Ingress Port, Tunnel ID
522          * Action: GOTO Local Table (10)
523          */
524
525         handleTunnelIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, false);
526
527          /*
528           * Table(1) Rule #2
529           * ----------------
530           * Match: Match Tunnel ID and L2 ::::FF:FF Flooding
531           * Action: Flood to selected destination TEPs
532           * -------------------------------------------
533           * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
534           * actions=output:10,output:11,goto_table:2
535           */
536
537         handleTunnelFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, false);
538     }
539
540     private void programLocalVlanRules(Node node, Long dpid, String segmentationId, String attachedMac, long localPort) {
541         /*
542          * Table(0) Rule #1
543          * ----------------
544          * Match: VM sMac and Local Ingress Port
545          * Action: Set VLAN ID and GOTO Local Table 1
546          */
547
548         handleLocalInPortSetVlan(dpid, TABLE_0_DEFAULT_INGRESS,
549                 TABLE_1_ISOLATE_TENANT, segmentationId, localPort,
550                 attachedMac, true);
551
552         /*
553          * Table(0) Rule #3
554          * ----------------
555          * Match: Drop any remaining Ingress Local VM Packets
556          * Action: Drop w/ a low priority
557          */
558
559         handleDropSrcIface(dpid, localPort, true);
560
561         /*
562          * Table(2) Rule #1
563          * ----------------
564          * Match: Match VLAN ID and Destination DL/dMAC Addr
565          * Action: strip vlan, output to local port
566          * Example: table=2,vlan_id=0x5,dl_dst=00:00:00:00:00:01 actions= strip vlan, output:2
567          */
568
569         handleLocalVlanUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
570                 localPort, attachedMac, true);
571
572         /*
573          * Table(2) Rule #2
574          * ----------------
575          * Match: VLAN ID and dMAC (::::FF:FF)
576          * Action: strip vlan, output to all local ports in this vlan
577          * Example: table=2,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
578          * actions= strip_vlan, output:2,3,4,5
579          */
580
581         handleLocalVlanBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
582                 localPort, true);
583
584          /*
585           * Table(2) Rule #3
586           * ----------------
587           * Match: Any Remaining Flows w/a VLAN ID
588           * Action: Drop w/ a low priority
589           * Example: table=2,priority=8192,vlan_id=0x5 actions=drop
590           */
591
592           handleLocalVlanTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
593                                    true);
594    }
595
596     private void removeLocalVlanRules(Node node, Long dpid,
597                                       String segmentationId, String attachedMac,
598                                       long localPort) {
599         /*
600          * Table(0) Rule #1
601          * ----------------
602          * Match: VM sMac and Local Ingress Port
603          * Action: Set VLAN ID and GOTO Local Table 1
604          */
605
606         handleLocalInPortSetVlan(dpid, TABLE_0_DEFAULT_INGRESS,
607                 TABLE_1_ISOLATE_TENANT, segmentationId, localPort,
608                 attachedMac, false);
609
610         /*
611          * Table(0) Rule #3
612          * ----------------
613          * Match: Drop any remaining Ingress Local VM Packets
614          * Action: Drop w/ a low priority
615          */
616
617         handleDropSrcIface(dpid, localPort, false);
618
619         /*
620          * Table(2) Rule #1
621          * ----------------
622          * Match: Match VLAN ID and Destination DL/dMAC Addr
623          * Action: strip vlan, output to local port
624          * Example: table=2,vlan_id=0x5,dl_dst=00:00:00:00:00:01 actions= strip vlan, output:2
625          */
626
627         handleLocalVlanUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
628                 localPort, attachedMac, false);
629
630         /*
631          * Table(2) Rule #2
632          * ----------------
633          * Match: VLAN ID and dMAC (::::FF:FF)
634          * Action: strip vlan, output to all local ports in this vlan
635          * Example: table=2,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
636          * actions= strip_vlan, output:2,3,4,5
637          */
638
639         handleLocalVlanBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
640                 localPort, false);
641    }
642
643    private void programLocalIngressVlanRules(Node node, Long dpid, String segmentationId, String attachedMac, long ethPort) {
644        /*
645         * Table(0) Rule #2
646         * ----------------
647         * Match: Ingress port = physical interface, Vlan ID
648         * Action: GOTO Local Table 2
649         */
650
651        handleVlanIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD,
652                     segmentationId, ethPort, true);
653
654         /*
655          * Table(1) Rule #2
656          * ----------------
657          * Match: Match VLAN ID and L2 ::::FF:FF Flooding
658          * Action: Flood to local and remote VLAN members
659          * -------------------------------------------
660          * Example: table=1,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
661          * actions=output:10 (eth port),goto_table:2
662          */
663
664         handleVlanFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
665                            segmentationId, ethPort, true);
666    }
667
668    private void programRemoteEgressVlanRules(Node node, Long dpid, String segmentationId, String attachedMac, long ethPort) {
669        /*
670         * Table(1) Rule #1
671         * ----------------
672         * Match: Destination MAC is local VM MAC and vlan id
673         * Action: go to table 2
674         * -------------------------------------------
675         * Example: table=1,vlan_id=0x5,dl_dst=00:00:00:00:00:08 \
676         * actions=goto_table:2
677         */
678
679        handleVlanOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
680                      segmentationId, ethPort, attachedMac, true);
681
682        /*
683         * Table(1) Rule #3
684         * ----------------
685         * Match:  VLAN ID
686         * Action: Go to table 2
687         * -------------------------------------------
688         * Example: table=1,priority=8192,vlan_id=0x5 actions=output:1,goto_table:2
689         */
690
691        handleVlanMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
692                       segmentationId, ethPort, true);
693    }
694
695    private void removeRemoteEgressVlanRules(Node node, Long dpid, String segmentationId, String attachedMac, long ethPort) {
696        /*
697         * Table(1) Rule #1
698         * ----------------
699         * Match: Destination MAC is local VM MAC and vlan id
700         * Action: go to table 2
701         * -------------------------------------------
702         * Example: table=1,vlan_id=0x5,dl_dst=00:00:00:00:00:08 \
703         * actions=goto_table:2
704         */
705
706        handleVlanOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
707                      segmentationId, ethPort, attachedMac, false);
708    }
709
710    private void removePerVlanRules(Node node, Long dpid, String segmentationId, long ethPort) {
711        /*
712         * Table(2) Rule #3
713         * ----------------
714         * Match: Any Remaining Flows w/a VLAN ID
715         * Action: Drop w/ a low priority
716         * Example: table=2,priority=8192,vlan_id=0x5 actions=drop
717         */
718
719         handleLocalVlanTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
720                                  false);
721
722         /*
723          * Table(0) Rule #2
724          * ----------------
725          * Match: Ingress port = physical interface, Vlan ID
726          * Action: GOTO Local Table 2
727          */
728
729         handleVlanIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD,
730                      segmentationId, ethPort, false);
731
732          /*
733           * Table(1) Rule #2
734           * ----------------
735           * Match: Match VLAN ID and L2 ::::FF:FF Flooding
736           * Action: Flood to local and remote VLAN members
737           * -------------------------------------------
738           * Example: table=1,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
739           * actions=output:10 (eth port),goto_table:2
740           */
741
742          handleVlanFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
743                             segmentationId, ethPort, false);
744
745          /*
746           * Table(1) Rule #3
747           * ----------------
748           * Match:  VLAN ID
749           * Action: Go to table 2
750           * -------------------------------------------
751           * Example: table=1,priority=8192,vlan_id=0x5 actions=output:1,goto_table:2
752           */
753
754          handleVlanMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
755                         segmentationId, ethPort, false);
756    }
757     private Long getDpid (Node node, String bridgeUuid) {
758         try {
759             OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
760             Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), bridgeUuid);
761             Set<String> dpids = bridge.getDatapath_id();
762             if (dpids == null || dpids.size() == 0) return 0L;
763             return Long.valueOf(HexEncode.stringToLong((String) dpids.toArray()[0]));
764         } catch (Exception e) {
765             logger.error("Error finding Bridge's OF DPID", e);
766             return 0L;
767         }
768     }
769
770     private Long getIntegrationBridgeOFDPID (Node node) {
771         try {
772             String bridgeName = adminConfigManager.getIntegrationBridgeName();
773             String brIntId = this.getInternalBridgeUUID(node, bridgeName);
774             if (brIntId == null) {
775                 logger.error("Unable to spot Bridge Identifier for {} in {}", bridgeName, node);
776                 return 0L;
777             }
778
779             return getDpid(node, brIntId);
780         } catch (Exception e) {
781             logger.error("Error finding Integration Bridge's OF DPID", e);
782             return 0L;
783         }
784     }
785
786     private Long getExternalBridgeDpid (Node node) {
787         try {
788             String bridgeName = adminConfigManager.getExternalBridgeName();
789             String brUuid = this.getInternalBridgeUUID(node, bridgeName);
790             if (brUuid == null) {
791                 logger.error("Unable to spot Bridge Identifier for {} in {}", bridgeName, node);
792                 return 0L;
793             }
794
795             return getDpid(node, brUuid);
796         } catch (Exception e) {
797             logger.error("Error finding External Bridge's OF DPID", e);
798             return 0L;
799         }
800     }
801
802     private void programLocalRules (String networkType, String segmentationId, Node node, Interface intf) {
803         try {
804             Long dpid = this.getIntegrationBridgeOFDPID(node);
805             if (dpid == 0L) {
806                 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
807                 return;
808             }
809
810             Set<BigInteger> of_ports = intf.getOfport();
811             if (of_ports == null || of_ports.size() <= 0) {
812                 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
813                 return;
814             }
815             long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
816
817             Map<String, String> externalIds = intf.getExternal_ids();
818             if (externalIds == null) {
819                 logger.error("No external_ids seen in {}", intf);
820                 return;
821             }
822
823             String attachedMac = externalIds.get(ITenantNetworkManager.EXTERNAL_ID_VM_MAC);
824             if (attachedMac == null) {
825                 logger.error("No AttachedMac seen in {}", intf);
826                 return;
827             }
828
829             /* Program local rules based on network type */
830             if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
831                 logger.debug("Program local vlan rules for interface {}", intf.getName());
832                 programLocalVlanRules(node, dpid, segmentationId, attachedMac, localPort);
833             } else if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) ||
834                        networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) {
835                 logger.debug("Program local bridge rules for interface {}", intf.getName());
836                 programLocalBridgeRules(node, dpid, segmentationId, attachedMac, localPort);
837             }
838         } catch (Exception e) {
839             logger.error("Exception in programming Local Rules for "+intf+" on "+node, e);
840         }
841     }
842
843     private void removeLocalRules (String networkType, String segmentationId, Node node, Interface intf) {
844         try {
845             Long dpid = this.getIntegrationBridgeOFDPID(node);
846             if (dpid == 0L) {
847                 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
848                 return;
849             }
850
851             Set<BigInteger> of_ports = intf.getOfport();
852             if (of_ports == null || of_ports.size() <= 0) {
853                 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
854                 return;
855             }
856             long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
857
858             Map<String, String> externalIds = intf.getExternal_ids();
859             if (externalIds == null) {
860                 logger.error("No external_ids seen in {}", intf);
861                 return;
862             }
863
864             String attachedMac = externalIds.get(ITenantNetworkManager.EXTERNAL_ID_VM_MAC);
865             if (attachedMac == null) {
866                 logger.error("No AttachedMac seen in {}", intf);
867                 return;
868             }
869
870             /* Program local rules based on network type */
871             if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
872                 logger.debug("Remove local vlan rules for interface {}", intf.getName());
873                 removeLocalVlanRules(node, dpid, segmentationId, attachedMac, localPort);
874             } else if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) ||
875                        networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) {
876                 logger.debug("Remove local bridge rules for interface {}", intf.getName());
877                 removeLocalBridgeRules(node, dpid, segmentationId, attachedMac, localPort);
878             }
879         } catch (Exception e) {
880             logger.error("Exception in removing Local Rules for "+intf+" on "+node, e);
881         }
882     }
883
884     private void programTunnelRules (String tunnelType, String segmentationId, InetAddress dst, Node node,
885             Interface intf, boolean local) {
886         try {
887
888             Long dpid = this.getIntegrationBridgeOFDPID(node);
889             if (dpid == 0L) {
890                 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
891                 return;
892             }
893             OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
894
895             Set<BigInteger> of_ports = intf.getOfport();
896             if (of_ports == null || of_ports.size() <= 0) {
897                 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
898                 return;
899             }
900             long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
901
902             Map<String, String> externalIds = intf.getExternal_ids();
903             if (externalIds == null) {
904                 logger.error("No external_ids seen in {}", intf);
905                 return;
906             }
907
908             String attachedMac = externalIds.get(ITenantNetworkManager.EXTERNAL_ID_VM_MAC);
909             if (attachedMac == null) {
910                 logger.error("No AttachedMac seen in {}", intf);
911                 return;
912             }
913
914             Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
915             if (intfs != null) {
916                 for (org.opendaylight.ovsdb.lib.table.Table<?> row : intfs.values()) {
917                     Interface tunIntf = (Interface)row;
918                     if (tunIntf.getName().equals(this.getTunnelName(tunnelType, dst))) {
919                         of_ports = tunIntf.getOfport();
920                         if (of_ports == null || of_ports.size() <= 0) {
921                             logger.error("Could NOT Identify Tunnel port {} on {}", tunIntf.getName(), node);
922                             continue;
923                         }
924                         long tunnelOFPort = ((BigInteger)of_ports.toArray()[0]).longValue();
925
926                         if (tunnelOFPort == -1) {
927                             logger.error("Could NOT Identify Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
928                             return;
929                         }
930                         logger.debug("Identified Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
931
932                         if (!local) {
933                             programRemoteEgressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
934                         }
935                         logger.trace("program local ingress tunnel rules: node" + node.getNodeIDString() + " intf " + intf.getName());
936                         if (local) {
937                             programLocalIngressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
938                         }
939                         return;
940                     }
941                 }
942             }
943         } catch (Exception e) {
944             logger.error("", e);
945         }
946     }
947
948     private void removeTunnelRules (String tunnelType, String segmentationId, InetAddress dst, Node node,
949             Interface intf, boolean local, boolean isLastInstanceOnNode) {
950         try {
951
952             Long dpid = this.getIntegrationBridgeOFDPID(node);
953             if (dpid == 0L) {
954                 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
955                 return;
956             }
957             OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
958
959             Set<BigInteger> of_ports = intf.getOfport();
960             if (of_ports == null || of_ports.size() <= 0) {
961                 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
962                 return;
963             }
964             long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
965
966             Map<String, String> externalIds = intf.getExternal_ids();
967             if (externalIds == null) {
968                 logger.error("No external_ids seen in {}", intf);
969                 return;
970             }
971
972             String attachedMac = externalIds.get(ITenantNetworkManager.EXTERNAL_ID_VM_MAC);
973             if (attachedMac == null) {
974                 logger.error("No AttachedMac seen in {}", intf);
975                 return;
976             }
977
978             Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
979             if (intfs != null) {
980                 for (org.opendaylight.ovsdb.lib.table.Table<?> row : intfs.values()) {
981                     Interface tunIntf = (Interface)row;
982                     if (tunIntf.getName().equals(this.getTunnelName(tunnelType, dst))) {
983                         of_ports = tunIntf.getOfport();
984                         if (of_ports == null || of_ports.size() <= 0) {
985                             logger.error("Could NOT Identify Tunnel port {} on {}", tunIntf.getName(), node);
986                             continue;
987                         }
988                         long tunnelOFPort = ((BigInteger)of_ports.toArray()[0]).longValue();
989
990                         if (tunnelOFPort == -1) {
991                             logger.error("Could NOT Identify Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
992                             return;
993                         }
994                         logger.debug("Identified Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
995
996                         if (!local) {
997                             removeRemoteEgressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
998                         }
999                         if (local && isLastInstanceOnNode) {
1000                             removePerTunnelRules(node, dpid, segmentationId, tunnelOFPort);
1001                         }
1002                         return;
1003                     }
1004                 }
1005             }
1006         } catch (Exception e) {
1007             logger.error("", e);
1008         }
1009     }
1010
1011     private void programVlanRules (NeutronNetwork network, Node node, Interface intf) {
1012         logger.debug("Program vlan rules for interface {}", intf.getName());
1013
1014         try {
1015
1016             Long dpid = this.getIntegrationBridgeOFDPID(node);
1017             if (dpid == 0L) {
1018                 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
1019                 return;
1020             }
1021             OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
1022
1023             Set<BigInteger> of_ports = intf.getOfport();
1024             int timeout = 6;
1025             while ((of_ports == null) && (timeout > 0)) {
1026                 of_ports = intf.getOfport();
1027                 if (of_ports == null || of_ports.size() <= 0) {
1028                     // Wait for the OVSDB update to sync up the Local cache.
1029                     Thread.sleep(500);
1030                     timeout--;
1031                     continue;
1032                 }
1033             }
1034             if (of_ports == null || of_ports.size() <= 0) {
1035                 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
1036                 return;
1037             }
1038
1039             Map<String, String> externalIds = intf.getExternal_ids();
1040             if (externalIds == null) {
1041                 logger.error("No external_ids seen in {}", intf);
1042                 return;
1043             }
1044
1045             String attachedMac = externalIds.get(tenantNetworkManager.EXTERNAL_ID_VM_MAC);
1046             if (attachedMac == null) {
1047                 logger.error("No AttachedMac seen in {}", intf);
1048                 return;
1049             }
1050
1051             Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
1052             if (intfs != null) {
1053                 for (org.opendaylight.ovsdb.lib.table.Table<?> row : intfs.values()) {
1054                     Interface ethIntf = (Interface)row;
1055                     if (ethIntf.getName().equalsIgnoreCase(adminConfigManager.getPhysicalInterfaceName(node, network.getProviderPhysicalNetwork()))) {
1056                         of_ports = ethIntf.getOfport();
1057                         timeout = 6;
1058                         while ((of_ports == null) && (timeout > 0)) {
1059                             of_ports = ethIntf.getOfport();
1060                             if (of_ports == null || of_ports.size() <= 0) {
1061                                 // Wait for the OVSDB update to sync up the Local cache.
1062                                 Thread.sleep(500);
1063                                 timeout--;
1064                                 continue;
1065                             }
1066                         }
1067
1068                         if (of_ports == null || of_ports.size() <= 0) {
1069                             logger.error("Could NOT Identify eth port {} on {}", ethIntf.getName(), node);
1070                             continue;
1071                         }
1072                         long ethOFPort = ((BigInteger)of_ports.toArray()[0]).longValue();
1073
1074                         if (ethOFPort == -1) {
1075                             logger.error("Could NOT Identify eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node);
1076                             throw new Exception("port number < 0");
1077                         }
1078                         logger.debug("Identified eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node);
1079
1080                         programRemoteEgressVlanRules(node, dpid, network.getProviderSegmentationID(), attachedMac, ethOFPort);
1081                         programLocalIngressVlanRules(node, dpid, network.getProviderSegmentationID(), attachedMac, ethOFPort);
1082                         return;
1083                     }
1084                 }
1085             }
1086         } catch (Exception e) {
1087             logger.error("", e);
1088         }
1089     }
1090
1091     private void removeVlanRules (NeutronNetwork network, Node node,
1092                       Interface intf, boolean isLastInstanceOnNode) {
1093         logger.debug("Remove vlan rules for interface {}", intf.getName());
1094
1095         try {
1096
1097             Long dpid = this.getIntegrationBridgeOFDPID(node);
1098             if (dpid == 0L) {
1099                 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
1100                 return;
1101             }
1102             OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
1103
1104             Set<BigInteger> of_ports = intf.getOfport();
1105             if (of_ports == null || of_ports.size() <= 0) {
1106                 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
1107                 return;
1108             }
1109
1110             Map<String, String> externalIds = intf.getExternal_ids();
1111             if (externalIds == null) {
1112                 logger.error("No external_ids seen in {}", intf);
1113                 return;
1114             }
1115
1116             String attachedMac = externalIds.get(tenantNetworkManager.EXTERNAL_ID_VM_MAC);
1117             if (attachedMac == null) {
1118                 logger.error("No AttachedMac seen in {}", intf);
1119                 return;
1120             }
1121
1122             Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
1123             if (intfs != null) {
1124                 for (org.opendaylight.ovsdb.lib.table.Table<?> row : intfs.values()) {
1125                     Interface ethIntf = (Interface)row;
1126                     if (ethIntf.getName().equalsIgnoreCase(adminConfigManager.getPhysicalInterfaceName(node,
1127                                                                    network.getProviderPhysicalNetwork()))) {
1128                         of_ports = ethIntf.getOfport();
1129                         if (of_ports == null || of_ports.size() <= 0) {
1130                             logger.error("Could NOT Identify eth port {} on {}", ethIntf.getName(), node);
1131                             continue;
1132                         }
1133                         long ethOFPort = ((BigInteger)of_ports.toArray()[0]).longValue();
1134
1135                         if (ethOFPort == -1) {
1136                             logger.error("Could NOT Identify eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node);
1137                             throw new Exception("port number < 0");
1138                         }
1139                         logger.debug("Identified eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node);
1140
1141                         removeRemoteEgressVlanRules(node, dpid, network.getProviderSegmentationID(), attachedMac, ethOFPort);
1142                         if (isLastInstanceOnNode) {
1143                             removePerVlanRules(node, dpid, network.getProviderSegmentationID(), ethOFPort);
1144                         }
1145                         return;
1146                     }
1147                 }
1148             }
1149         } catch (Exception e) {
1150             logger.error("", e);
1151         }
1152     }
1153
1154     @Override
1155     public Status handleInterfaceUpdate(NeutronNetwork network, Node srcNode, Interface intf) {
1156         ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, "default", this);
1157         if (switchManager == null) {
1158             logger.error("Unable to identify SwitchManager");
1159         } else {
1160             Long dpid = this.getIntegrationBridgeOFDPID(srcNode);
1161             if (dpid == 0L) {
1162                 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", srcNode);
1163                 return new Status(StatusCode.NOTFOUND);
1164             }
1165             Set<Node> ofNodes = switchManager.getNodes();
1166             boolean ofNodeFound = false;
1167             if (ofNodes != null) {
1168                 for (Node ofNode : ofNodes) {
1169                     if (ofNode.toString().contains(dpid+"")) {
1170                         logger.debug("Identified the Openflow node via toString {}", ofNode);
1171                         ofNodeFound = true;
1172                         break;
1173                     }
1174                 }
1175             } else {
1176                 logger.error("Unable to find any Node from SwitchManager");
1177             }
1178             if (!ofNodeFound) {
1179                 logger.error("Unable to find OF Node for {} with update {} on node {}", dpid, intf, srcNode);
1180                 return new Status(StatusCode.NOTFOUND);
1181             }
1182         }
1183
1184         IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
1185         List<Node> nodes = connectionService.getNodes();
1186         nodes.remove(srcNode);
1187         this.programLocalRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), srcNode, intf);
1188
1189         if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
1190             this.programVlanRules(network, srcNode, intf);
1191         } else if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)
1192                    || network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)){
1193             for (Node dstNode : nodes) {
1194                 InetAddress src = adminConfigManager.getTunnelEndPoint(srcNode);
1195                 InetAddress dst = adminConfigManager.getTunnelEndPoint(dstNode);
1196                 Status status = addTunnelPort(srcNode, network.getProviderNetworkType(), src, dst);
1197                 if (status.isSuccess()) {
1198                     this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), dst, srcNode, intf, true);
1199                 }
1200                 addTunnelPort(dstNode, network.getProviderNetworkType(), dst, src);
1201                 if (status.isSuccess()) {
1202                     this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), src, dstNode, intf, false);
1203                 }
1204             }
1205         }
1206
1207         return new Status(StatusCode.SUCCESS);
1208     }
1209
1210     private Status triggerInterfaceUpdates(Node node) {
1211         try {
1212             OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
1213             Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
1214             if (intfs != null) {
1215                 for (org.opendaylight.ovsdb.lib.table.Table<?> row : intfs.values()) {
1216                     Interface intf = (Interface)row;
1217                     NeutronNetwork network = tenantNetworkManager.getTenantNetworkForInterface(intf);
1218                     logger.debug("Trigger Interface update for {}", intf);
1219                     if (network != null) {
1220                         this.handleInterfaceUpdate(network, node, intf);
1221                     }
1222                 }
1223             }
1224         } catch (Exception e) {
1225             logger.error("Error Triggering the lost interface updates for "+ node, e);
1226             return new Status(StatusCode.INTERNALERROR, e.getLocalizedMessage());
1227         }
1228         return new Status(StatusCode.SUCCESS);
1229     }
1230     @Override
1231     public Status handleInterfaceUpdate(String tunnelType, String tunnelKey) {
1232         // TODO Auto-generated method stub
1233         return null;
1234     }
1235
1236     @Override
1237     public Status handleInterfaceDelete(String tunnelType, NeutronNetwork network, Node srcNode, Interface intf,
1238             boolean isLastInstanceOnNode) {
1239         Status status = new Status(StatusCode.SUCCESS);
1240         IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
1241         List<Node> nodes = connectionService.getNodes();
1242         nodes.remove(srcNode);
1243
1244         logger.info("Delete intf " + intf.getName() + " isLastInstanceOnNode " + isLastInstanceOnNode);
1245         List<String> phyIfName = adminConfigManager.getAllPhysicalInterfaceNames(srcNode);
1246         if (intf.getType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)
1247             || intf.getType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)) {
1248             /* Delete tunnel port */
1249             try {
1250                 OvsDBMap<String, String> options = intf.getOptions();
1251                 InetAddress src = InetAddress.getByName(options.get("local_ip"));
1252                 InetAddress dst = InetAddress.getByName(options.get("remote_ip"));
1253                 status = deleteTunnelPort(srcNode, intf.getType(), src, dst);
1254             } catch (Exception e) {
1255                 logger.error(e.getMessage(), e);
1256             }
1257         } else if (phyIfName.contains(intf.getName())) {
1258             deletePhysicalPort(srcNode, intf.getName());
1259         } else {
1260             /* delete all other interfaces */
1261             this.removeLocalRules(network.getProviderNetworkType(), network.getProviderSegmentationID(),
1262                     srcNode, intf);
1263
1264             if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
1265                 this.removeVlanRules(network, srcNode,
1266                                  intf, isLastInstanceOnNode);
1267             } else if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)
1268                    || network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) {
1269
1270                 for (Node dstNode : nodes) {
1271                     InetAddress src = adminConfigManager.getTunnelEndPoint(srcNode);
1272                     InetAddress dst = adminConfigManager.getTunnelEndPoint(dstNode);
1273                     logger.info("Remove tunnel rules for interface " + intf.getName() + " on srcNode" + srcNode.getNodeIDString());
1274                     this.removeTunnelRules(tunnelType, network.getProviderSegmentationID(),
1275                                            dst, srcNode, intf, true, isLastInstanceOnNode);
1276                     logger.info("Remove tunnel rules for interface " + intf.getName() + " on dstNode" + dstNode.getNodeIDString());
1277                     this.removeTunnelRules(tunnelType, network.getProviderSegmentationID(),
1278                                            src, dstNode, intf, false, isLastInstanceOnNode);
1279                 }
1280             }
1281         }
1282         return status;
1283     }
1284
1285     @Override
1286     public void initializeFlowRules(Node node) {
1287         this.initializeFlowRules(node, adminConfigManager.getIntegrationBridgeName());
1288         this.initializeFlowRules(node, adminConfigManager.getExternalBridgeName());
1289         this.triggerInterfaceUpdates(node);
1290     }
1291
1292     /**
1293      * @param node
1294      * @param bridgeName
1295      */
1296     private void initializeFlowRules(Node node, String bridgeName) {
1297         String bridgeUuid = this.getInternalBridgeUUID(node, bridgeName);
1298         if (bridgeUuid == null) {
1299             return;
1300         }
1301
1302         Long dpid = getDpid(node, bridgeUuid);
1303
1304         if (dpid == 0L) {
1305             logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
1306             return;
1307         }
1308
1309         /*
1310          * Table(0) Rule #1
1311          * ----------------
1312          * Match: LLDP (0x88CCL)
1313          * Action: Packet_In to Controller Reserved Port
1314          */
1315
1316          writeLLDPRule(dpid);
1317          if (bridgeName == adminConfigManager.getExternalBridgeName()) {
1318              writeNormalRule(dpid);
1319          }
1320     }
1321
1322     /*
1323     * Create an LLDP Flow Rule to encapsulate into
1324     * a packet_in that is sent to the controller
1325     * for topology handling.
1326     * Match: Ethertype 0x88CCL
1327     * Action: Punt to Controller in a Packet_In msg
1328     */
1329
1330     private void writeLLDPRule(Long dpidLong) {
1331
1332         String nodeName = "openflow:" + dpidLong;
1333         EtherType etherType = new EtherType(0x88CCL);
1334
1335         MatchBuilder matchBuilder = new MatchBuilder();
1336         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1337         FlowBuilder flowBuilder = new FlowBuilder();
1338
1339         // Create Match(es) and Set them in the FlowBuilder Object
1340         flowBuilder.setMatch(createEtherTypeMatch(matchBuilder, etherType).build());
1341
1342         // Create the OF Actions and Instructions
1343         InstructionBuilder ib = new InstructionBuilder();
1344         InstructionsBuilder isb = new InstructionsBuilder();
1345
1346         // Instructions List Stores Individual Instructions
1347         List<Instruction> instructions = new ArrayList<Instruction>();
1348
1349         // Call the InstructionBuilder Methods Containing Actions
1350         createSendToControllerInstructions(ib);
1351         ib.setOrder(0);
1352         ib.setKey(new InstructionKey(0));
1353         instructions.add(ib.build());
1354
1355         // Add InstructionBuilder to the Instruction(s)Builder List
1356         isb.setInstruction(instructions);
1357
1358         // Add InstructionsBuilder to FlowBuilder
1359         flowBuilder.setInstructions(isb.build());
1360
1361         String flowId = "LLDP";
1362         flowBuilder.setId(new FlowId(flowId));
1363         FlowKey key = new FlowKey(new FlowId(flowId));
1364         flowBuilder.setBarrier(true);
1365         flowBuilder.setTableId((short) 0);
1366         flowBuilder.setKey(key);
1367         flowBuilder.setFlowName(flowId);
1368         flowBuilder.setHardTimeout(0);
1369         flowBuilder.setIdleTimeout(0);
1370         writeFlow(flowBuilder, nodeBuilder);
1371     }
1372
1373     /*
1374     * Create a NORMAL Table Miss Flow Rule
1375     * Match: any
1376     * Action: forward to NORMAL pipeline
1377     */
1378
1379     private void writeNormalRule(Long dpidLong) {
1380
1381         String nodeName = "openflow:" + dpidLong;
1382
1383         MatchBuilder matchBuilder = new MatchBuilder();
1384         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1385         FlowBuilder flowBuilder = new FlowBuilder();
1386
1387         // Create the OF Actions and Instructions
1388         InstructionBuilder ib = new InstructionBuilder();
1389         InstructionsBuilder isb = new InstructionsBuilder();
1390
1391         // Instructions List Stores Individual Instructions
1392         List<Instruction> instructions = new ArrayList<Instruction>();
1393
1394         // Call the InstructionBuilder Methods Containing Actions
1395         createNormalInstructions(ib);
1396         ib.setOrder(0);
1397         ib.setKey(new InstructionKey(0));
1398         instructions.add(ib.build());
1399
1400         // Add InstructionBuilder to the Instruction(s)Builder List
1401         isb.setInstruction(instructions);
1402
1403         // Add InstructionsBuilder to FlowBuilder
1404         flowBuilder.setInstructions(isb.build());
1405
1406         String flowId = "NORMAL";
1407         flowBuilder.setId(new FlowId(flowId));
1408         FlowKey key = new FlowKey(new FlowId(flowId));
1409         flowBuilder.setMatch(matchBuilder.build());
1410         flowBuilder.setPriority(0);
1411         flowBuilder.setBarrier(true);
1412         flowBuilder.setTableId((short) 0);
1413         flowBuilder.setKey(key);
1414         flowBuilder.setFlowName(flowId);
1415         flowBuilder.setHardTimeout(0);
1416         flowBuilder.setIdleTimeout(0);
1417         writeFlow(flowBuilder, nodeBuilder);
1418     }
1419
1420     /*
1421      * (Table:0) Ingress Tunnel Traffic
1422      * Match: OpenFlow InPort and Tunnel ID
1423      * Action: GOTO Local Table (10)
1424      * table=0,tun_id=0x5,in_port=10, actions=goto_table:2
1425      */
1426
1427     private void handleTunnelIn(Long dpidLong, Short writeTable,
1428                                 Short goToTableId, String segmentationId,
1429                                 Long ofPort, boolean write) {
1430
1431         String nodeName = "openflow:" + dpidLong;
1432
1433         BigInteger tunnelId = new BigInteger(segmentationId);
1434         MatchBuilder matchBuilder = new MatchBuilder();
1435         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1436         FlowBuilder flowBuilder = new FlowBuilder();
1437
1438         // Create Match(es) and Set them in the FlowBuilder Object
1439         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, tunnelId).build());
1440         flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, ofPort).build());
1441
1442         if (write) {
1443             // Create the OF Actions and Instructions
1444             InstructionBuilder ib = new InstructionBuilder();
1445             InstructionsBuilder isb = new InstructionsBuilder();
1446
1447             // Instructions List Stores Individual Instructions
1448             List<Instruction> instructions = new ArrayList<Instruction>();
1449
1450             // Call the InstructionBuilder Methods Containing Actions
1451             createGotoTableInstructions(ib, goToTableId);
1452             ib.setOrder(0);
1453             ib.setKey(new InstructionKey(0));
1454             instructions.add(ib.build());
1455
1456             // Add InstructionBuilder to the Instruction(s)Builder List
1457             isb.setInstruction(instructions);
1458
1459             // Add InstructionsBuilder to FlowBuilder
1460             flowBuilder.setInstructions(isb.build());
1461         }
1462
1463         String flowId = "TunnelIn_"+segmentationId+"_"+ofPort;
1464         // Add Flow Attributes
1465         flowBuilder.setId(new FlowId(flowId));
1466         FlowKey key = new FlowKey(new FlowId(flowId));
1467         flowBuilder.setStrict(true);
1468         flowBuilder.setBarrier(false);
1469         flowBuilder.setTableId(writeTable);
1470         flowBuilder.setKey(key);
1471         flowBuilder.setFlowName(flowId);
1472         flowBuilder.setHardTimeout(0);
1473         flowBuilder.setIdleTimeout(0);
1474
1475         if (write) {
1476             writeFlow(flowBuilder, nodeBuilder);
1477         } else {
1478             removeFlow(flowBuilder, nodeBuilder);
1479         }
1480     }
1481
1482     /*
1483      * (Table:0) Ingress VLAN Traffic
1484      * Match: OpenFlow InPort and vlan ID
1485      * Action: GOTO Local Table (20)
1486      * table=0,vlan_id=0x5,in_port=10, actions=goto_table:2
1487      */
1488
1489     private void handleVlanIn(Long dpidLong, Short writeTable, Short goToTableId,
1490                       String segmentationId,  Long ethPort, boolean write) {
1491
1492         String nodeName = "openflow:" + dpidLong;
1493
1494         MatchBuilder matchBuilder = new MatchBuilder();
1495         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1496         FlowBuilder flowBuilder = new FlowBuilder();
1497
1498         // Create Match(es) and Set them in the FlowBuilder Object
1499         flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
1500         flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, ethPort).build());
1501
1502         if (write) {
1503             // Create the OF Actions and Instructions
1504             InstructionBuilder ib = new InstructionBuilder();
1505             InstructionsBuilder isb = new InstructionsBuilder();
1506
1507             // Instructions List Stores Individual Instructions
1508             List<Instruction> instructions = new ArrayList<Instruction>();
1509
1510             // Call the InstructionBuilder Methods Containing Actions
1511             createGotoTableInstructions(ib, goToTableId);
1512             ib.setOrder(0);
1513             ib.setKey(new InstructionKey(0));
1514             instructions.add(ib.build());
1515
1516             // Add InstructionBuilder to the Instruction(s)Builder List
1517             isb.setInstruction(instructions);
1518
1519             // Add InstructionsBuilder to FlowBuilder
1520             flowBuilder.setInstructions(isb.build());
1521         }
1522
1523         String flowId = "VlanIn_"+segmentationId+"_"+ethPort;
1524         // Add Flow Attributes
1525         flowBuilder.setId(new FlowId(flowId));
1526         FlowKey key = new FlowKey(new FlowId(flowId));
1527         flowBuilder.setStrict(true);
1528         flowBuilder.setBarrier(false);
1529         flowBuilder.setTableId(writeTable);
1530         flowBuilder.setKey(key);
1531         flowBuilder.setFlowName(flowId);
1532         flowBuilder.setHardTimeout(0);
1533         flowBuilder.setIdleTimeout(0);
1534         if (write) {
1535             writeFlow(flowBuilder, nodeBuilder);
1536         } else {
1537             removeFlow(flowBuilder, nodeBuilder);
1538         }
1539     }
1540
1541    /*
1542     * (Table:0) Egress VM Traffic Towards TEP
1543     * Match: Destination Ethernet Addr and OpenFlow InPort
1544     * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
1545     * table=0,in_port=2,dl_src=00:00:00:00:00:01 \
1546     * actions=set_field:5->tun_id,goto_table=1"
1547     */
1548
1549     private void handleLocalInPort(Long dpidLong, Short writeTable, Short goToTableId,
1550                            String segmentationId, Long inPort, String attachedMac,
1551                            boolean write) {
1552
1553         String nodeName = "openflow:" + dpidLong;
1554
1555         MatchBuilder matchBuilder = new MatchBuilder();
1556         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1557         FlowBuilder flowBuilder = new FlowBuilder();
1558
1559         // Create the OF Match using MatchBuilder
1560         flowBuilder.setMatch(createEthSrcMatch(matchBuilder, new MacAddress(attachedMac)).build());
1561         // TODO Broken In_Port Match
1562         flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
1563
1564         String flowId = "LocalMac_"+segmentationId+"_"+inPort+"_"+attachedMac;
1565         // Add Flow Attributes
1566         flowBuilder.setId(new FlowId(flowId));
1567         FlowKey key = new FlowKey(new FlowId(flowId));
1568         flowBuilder.setStrict(true);
1569         flowBuilder.setBarrier(false);
1570         flowBuilder.setTableId(writeTable);
1571         flowBuilder.setKey(key);
1572         flowBuilder.setFlowName(flowId);
1573         flowBuilder.setHardTimeout(0);
1574         flowBuilder.setIdleTimeout(0);
1575
1576         if (write) {
1577             // Instantiate the Builders for the OF Actions and Instructions
1578             InstructionBuilder ib = new InstructionBuilder();
1579             InstructionsBuilder isb = new InstructionsBuilder();
1580
1581             // Instructions List Stores Individual Instructions
1582             List<Instruction> instructions = new ArrayList<Instruction>();
1583
1584             // GOTO Instuctions Need to be added first to the List
1585             createGotoTableInstructions(ib, goToTableId);
1586             ib.setOrder(0);
1587             ib.setKey(new InstructionKey(0));
1588             instructions.add(ib.build());
1589             // TODO Broken SetTunID
1590             createSetTunnelIdInstructions(ib, new BigInteger(segmentationId));
1591             ib.setOrder(1);
1592             ib.setKey(new InstructionKey(1));
1593             instructions.add(ib.build());
1594
1595             // Add InstructionBuilder to the Instruction(s)Builder List
1596             isb.setInstruction(instructions);
1597
1598             // Add InstructionsBuilder to FlowBuilder
1599             flowBuilder.setInstructions(isb.build());
1600
1601             writeFlow(flowBuilder, nodeBuilder);
1602         } else {
1603             removeFlow(flowBuilder, nodeBuilder);
1604         }
1605     }
1606
1607     /*
1608      * (Table:0) Egress VM Traffic Towards TEP
1609      * Match: Source Ethernet Addr and OpenFlow InPort
1610      * Instruction: Set VLANID and GOTO Table Egress (n)
1611      * table=0,in_port=2,dl_src=00:00:00:00:00:01 \
1612      * actions=push_vlan, set_field:5->vlan_id,goto_table=1"
1613      */
1614
1615      private void handleLocalInPortSetVlan(Long dpidLong, Short writeTable,
1616                                   Short goToTableId, String segmentationId,
1617                                   Long inPort, String attachedMac,
1618                                   boolean write) {
1619
1620          String nodeName = "openflow:" + dpidLong;
1621
1622          MatchBuilder matchBuilder = new MatchBuilder();
1623          NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1624          FlowBuilder flowBuilder = new FlowBuilder();
1625
1626          // Create the OF Match using MatchBuilder
1627          flowBuilder.setMatch(createEthSrcMatch(matchBuilder, new MacAddress(attachedMac)).build());
1628          // TODO Broken In_Port Match
1629          flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
1630
1631          String flowId = "LocalMac_"+segmentationId+"_"+inPort+"_"+attachedMac;
1632          // Add Flow Attributes
1633          flowBuilder.setId(new FlowId(flowId));
1634          FlowKey key = new FlowKey(new FlowId(flowId));
1635          flowBuilder.setStrict(true);
1636          flowBuilder.setBarrier(false);
1637          flowBuilder.setTableId(writeTable);
1638          flowBuilder.setKey(key);
1639          flowBuilder.setFlowName(flowId);
1640          flowBuilder.setHardTimeout(0);
1641          flowBuilder.setIdleTimeout(0);
1642
1643          if (write) {
1644              // Instantiate the Builders for the OF Actions and Instructions
1645              InstructionBuilder ib = new InstructionBuilder();
1646              InstructionsBuilder isb = new InstructionsBuilder();
1647
1648              // Instructions List Stores Individual Instructions
1649              List<Instruction> instructions = new ArrayList<Instruction>();
1650
1651              // GOTO Instructions Need to be added first to the List
1652              createGotoTableInstructions(ib, goToTableId);
1653              ib.setOrder(0);
1654              ib.setKey(new InstructionKey(0));
1655              instructions.add(ib.build());
1656              // Set VLAN ID Instruction
1657              createSetVlanInstructions(ib, new VlanId(Integer.valueOf(segmentationId)));
1658              ib.setOrder(1);
1659              ib.setKey(new InstructionKey(1));
1660              instructions.add(ib.build());
1661
1662              // Add InstructionBuilder to the Instruction(s)Builder List
1663              isb.setInstruction(instructions);
1664
1665              // Add InstructionsBuilder to FlowBuilder
1666              flowBuilder.setInstructions(isb.build());
1667
1668              writeFlow(flowBuilder, nodeBuilder);
1669          } else {
1670              removeFlow(flowBuilder, nodeBuilder);
1671          }
1672      }
1673
1674     /*
1675      * (Table:0) Drop frames source from a VM that do not
1676      * match the associated MAC address of the local VM.
1677      * Match: Low priority anything not matching the VM SMAC
1678      * Instruction: Drop
1679      * table=0,priority=16384,in_port=1 actions=drop"
1680      */
1681
1682     private void handleDropSrcIface(Long dpidLong, Long inPort, boolean write) {
1683
1684         String nodeName = "openflow:" + dpidLong;
1685
1686         MatchBuilder matchBuilder = new MatchBuilder();
1687         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1688         FlowBuilder flowBuilder = new FlowBuilder();
1689
1690         // Create the OF Match using MatchBuilder
1691         flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
1692
1693         if (write) {
1694             // Instantiate the Builders for the OF Actions and Instructions
1695             InstructionBuilder ib = new InstructionBuilder();
1696             InstructionsBuilder isb = new InstructionsBuilder();
1697
1698             // Instructions List Stores Individual Instructions
1699             List<Instruction> instructions = new ArrayList<Instruction>();
1700
1701             // Call the InstructionBuilder Methods Containing Actions
1702             createDropInstructions(ib);
1703             ib.setOrder(0);
1704             ib.setKey(new InstructionKey(0));
1705             instructions.add(ib.build());
1706
1707             // Add InstructionBuilder to the Instruction(s)Builder List
1708             isb.setInstruction(instructions);
1709
1710             // Add InstructionsBuilder to FlowBuilder
1711             flowBuilder.setInstructions(isb.build());
1712         }
1713
1714         String flowId = "DropFilter_"+inPort;
1715         // Add Flow Attributes
1716         flowBuilder.setId(new FlowId(flowId));
1717         FlowKey key = new FlowKey(new FlowId(flowId));
1718         flowBuilder.setStrict(true);
1719         flowBuilder.setBarrier(false);
1720         flowBuilder.setTableId((short) 0);
1721         flowBuilder.setKey(key);
1722         flowBuilder.setFlowName(flowId);
1723         flowBuilder.setPriority(8192);
1724         flowBuilder.setHardTimeout(0);
1725         flowBuilder.setIdleTimeout(0);
1726         if (write) {
1727             writeFlow(flowBuilder, nodeBuilder);
1728         } else {
1729             removeFlow(flowBuilder, nodeBuilder);
1730         }
1731     }
1732
1733    /*
1734     * (Table:1) Egress Tunnel Traffic
1735     * Match: Destination Ethernet Addr and Local InPort
1736     * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
1737     * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
1738     * actions=output:10,goto_table:2"
1739     */
1740     private void handleTunnelOut(Long dpidLong, Short writeTable,
1741                          Short goToTableId, String segmentationId,
1742                          Long OFPortOut, String attachedMac,
1743                          boolean write) {
1744
1745         String nodeName = "openflow:" + dpidLong;
1746
1747         MatchBuilder matchBuilder = new MatchBuilder();
1748         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1749         FlowBuilder flowBuilder = new FlowBuilder();
1750
1751         // Create the OF Match using MatchBuilder
1752         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
1753         flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
1754
1755         String flowId = "TunnelOut_"+segmentationId+"_"+OFPortOut+"_"+attachedMac;
1756         // Add Flow Attributes
1757         flowBuilder.setId(new FlowId(flowId));
1758         FlowKey key = new FlowKey(new FlowId(flowId));
1759         flowBuilder.setStrict(true);
1760         flowBuilder.setBarrier(false);
1761         flowBuilder.setTableId(writeTable);
1762         flowBuilder.setKey(key);
1763         flowBuilder.setFlowName(flowId);
1764         flowBuilder.setHardTimeout(0);
1765         flowBuilder.setIdleTimeout(0);
1766
1767         if (write) {
1768             // Instantiate the Builders for the OF Actions and Instructions
1769             InstructionBuilder ib = new InstructionBuilder();
1770             InstructionsBuilder isb = new InstructionsBuilder();
1771
1772             // Instructions List Stores Individual Instructions
1773             List<Instruction> instructions = new ArrayList<Instruction>();
1774
1775             // GOTO Instuctions
1776             createGotoTableInstructions(ib, goToTableId);
1777             ib.setOrder(0);
1778             ib.setKey(new InstructionKey(0));
1779             instructions.add(ib.build());
1780             // Set the Output Port/Iface
1781             createOutputPortInstructions(ib, dpidLong, OFPortOut);
1782             ib.setOrder(1);
1783             ib.setKey(new InstructionKey(1));
1784             instructions.add(ib.build());
1785
1786             // Add InstructionBuilder to the Instruction(s)Builder List
1787             isb.setInstruction(instructions);
1788
1789             // Add InstructionsBuilder to FlowBuilder
1790             flowBuilder.setInstructions(isb.build());
1791
1792             writeFlow(flowBuilder, nodeBuilder);
1793         } else {
1794             removeFlow(flowBuilder, nodeBuilder);
1795         }
1796     }
1797
1798     /*
1799      * (Table:1) Egress VLAN Traffic
1800      * Match: Destination Ethernet Addr and VLAN id
1801      * Instruction: GOTO Table Table 2
1802      * table=1,vlan_id=0x5,dl_dst=00:00:00:00:00:08 \
1803      * actions= goto_table:2"
1804      */
1805
1806      private void handleVlanOut(Long dpidLong, Short writeTable,
1807                         Short goToTableId, String segmentationId,
1808                         Long ethPort, String attachedMac, boolean write) {
1809
1810          String nodeName = "openflow:" + dpidLong;
1811
1812          MatchBuilder matchBuilder = new MatchBuilder();
1813          NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1814          FlowBuilder flowBuilder = new FlowBuilder();
1815
1816          // Create the OF Match using MatchBuilder
1817          flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
1818          flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
1819
1820          String flowId = "VlanOut_"+segmentationId+"_"+ethPort+"_"+attachedMac;
1821          // Add Flow Attributes
1822          flowBuilder.setId(new FlowId(flowId));
1823          FlowKey key = new FlowKey(new FlowId(flowId));
1824          flowBuilder.setStrict(true);
1825          flowBuilder.setBarrier(false);
1826          flowBuilder.setTableId(writeTable);
1827          flowBuilder.setKey(key);
1828          flowBuilder.setFlowName(flowId);
1829          flowBuilder.setHardTimeout(0);
1830          flowBuilder.setIdleTimeout(0);
1831
1832          if (write) {
1833              // Instantiate the Builders for the OF Actions and Instructions
1834              InstructionBuilder ib = new InstructionBuilder();
1835              InstructionsBuilder isb = new InstructionsBuilder();
1836
1837              // Instructions List Stores Individual Instructions
1838              List<Instruction> instructions = new ArrayList<Instruction>();
1839
1840              // GOTO Instuctions
1841              createGotoTableInstructions(ib, goToTableId);
1842              ib.setOrder(0);
1843              ib.setKey(new InstructionKey(0));
1844              instructions.add(ib.build());
1845
1846              // Add InstructionBuilder to the Instruction(s)Builder List
1847              isb.setInstruction(instructions);
1848
1849              // Add InstructionsBuilder to FlowBuilder
1850              flowBuilder.setInstructions(isb.build());
1851
1852              writeFlow(flowBuilder, nodeBuilder);
1853          } else {
1854              removeFlow(flowBuilder, nodeBuilder);
1855          }
1856      }
1857
1858        /*
1859     * (Table:1) Egress Tunnel Traffic
1860     * Match: Destination Ethernet Addr and Local InPort
1861     * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
1862     * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
1863     * actions=output:10,output:11,goto_table:2
1864     */
1865
1866     private void handleTunnelFloodOut(Long dpidLong, Short writeTable,
1867                              Short localTable, String segmentationId,
1868                              Long OFPortOut, boolean write) {
1869
1870         String nodeName = "openflow:" + dpidLong;
1871
1872         MatchBuilder matchBuilder = new MatchBuilder();
1873         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1874         FlowBuilder flowBuilder = new FlowBuilder();
1875
1876         // Create the OF Match using MatchBuilder
1877         // Match TunnelID
1878         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
1879         // Match DMAC
1880
1881         flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
1882
1883         String flowId = "TunnelFloodOut_"+segmentationId;
1884         // Add Flow Attributes
1885         flowBuilder.setId(new FlowId(flowId));
1886         FlowKey key = new FlowKey(new FlowId(flowId));
1887         flowBuilder.setBarrier(true);
1888         flowBuilder.setTableId(writeTable);
1889         flowBuilder.setKey(key);
1890         flowBuilder.setPriority(16384);
1891         flowBuilder.setFlowName(flowId);
1892         flowBuilder.setHardTimeout(0);
1893         flowBuilder.setIdleTimeout(0);
1894
1895         Flow flow = this.getFlow(flowBuilder, nodeBuilder);
1896         // Instantiate the Builders for the OF Actions and Instructions
1897         InstructionBuilder ib = new InstructionBuilder();
1898         InstructionsBuilder isb = new InstructionsBuilder();
1899         List<Instruction> instructions = new ArrayList<Instruction>();
1900         List<Instruction> existingInstructions = null;
1901         if (flow != null) {
1902             Instructions ins = flow.getInstructions();
1903             if (ins != null) {
1904                 existingInstructions = ins.getInstruction();
1905             }
1906         }
1907
1908         if (write) {
1909             // GOTO Instruction
1910             createGotoTableInstructions(ib, localTable);
1911             ib.setOrder(0);
1912             ib.setKey(new InstructionKey(0));
1913             instructions.add(ib.build());
1914             // Set the Output Port/Iface
1915             //createOutputGroupInstructions(nodeBuilder, ib, dpidLong, OFPortOut, existingInstructions);
1916             createOutputPortInstructions(ib, dpidLong, OFPortOut, existingInstructions);
1917             ib.setOrder(1);
1918             ib.setKey(new InstructionKey(1));
1919             instructions.add(ib.build());
1920
1921             // Add InstructionBuilder to the Instruction(s)Builder List
1922             isb.setInstruction(instructions);
1923
1924             // Add InstructionsBuilder to FlowBuilder
1925             flowBuilder.setInstructions(isb.build());
1926
1927             writeFlow(flowBuilder, nodeBuilder);
1928         } else {
1929             /* remove port from action list */
1930             boolean flowRemove = removeOutputPortFromInstructions(ib, dpidLong,
1931                                    OFPortOut, existingInstructions);
1932             if (flowRemove) {
1933                 /* if all port are removed, remove the flow too. */
1934                 removeFlow(flowBuilder, nodeBuilder);
1935             } else {
1936                 /* Install instruction with new output port list*/
1937                 ib.setOrder(0);
1938                 ib.setKey(new InstructionKey(0));
1939                 instructions.add(ib.build());
1940
1941                 // Add InstructionBuilder to the Instruction(s)Builder List
1942                 isb.setInstruction(instructions);
1943
1944                 // Add InstructionsBuilder to FlowBuilder
1945                 flowBuilder.setInstructions(isb.build());
1946             }
1947         }
1948     }
1949
1950     /*
1951      * (Table:1) Egress VLAN Traffic
1952      * Match: Destination Ethernet Addr and VLAN id
1953      * Instruction: GOTO table 2 and Output port eth interface
1954      * Example: table=1,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
1955      * actions=output:eth1,goto_table:2
1956      */
1957
1958      private void handleVlanFloodOut(Long dpidLong, Short writeTable,
1959                            Short localTable, String segmentationId,
1960                            Long ethPort, boolean write) {
1961
1962          String nodeName = "openflow:" + dpidLong;
1963
1964          MatchBuilder matchBuilder = new MatchBuilder();
1965          NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1966          FlowBuilder flowBuilder = new FlowBuilder();
1967
1968          // Create the OF Match using MatchBuilder
1969          // Match Vlan ID
1970          flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
1971          // Match DMAC
1972          flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
1973
1974          String flowId = "VlanFloodOut_"+segmentationId;
1975          // Add Flow Attributes
1976          flowBuilder.setId(new FlowId(flowId));
1977          FlowKey key = new FlowKey(new FlowId(flowId));
1978          flowBuilder.setBarrier(true);
1979          flowBuilder.setTableId(writeTable);
1980          flowBuilder.setKey(key);
1981          flowBuilder.setPriority(16384);
1982          flowBuilder.setFlowName(flowId);
1983          flowBuilder.setHardTimeout(0);
1984          flowBuilder.setIdleTimeout(0);
1985
1986          Flow flow = this.getFlow(flowBuilder, nodeBuilder);
1987          // Instantiate the Builders for the OF Actions and Instructions
1988          InstructionBuilder ib = new InstructionBuilder();
1989          InstructionsBuilder isb = new InstructionsBuilder();
1990          List<Instruction> instructions = new ArrayList<Instruction>();
1991
1992          if (write) {
1993              // GOTO Instuction
1994              createGotoTableInstructions(ib, localTable);
1995              ib.setOrder(0);
1996              ib.setKey(new InstructionKey(0));
1997              instructions.add(ib.build());
1998              // Set the Output Port/Iface
1999              createOutputPortInstructions(ib, dpidLong, ethPort);
2000              ib.setOrder(1);
2001              ib.setKey(new InstructionKey(1));
2002              instructions.add(ib.build());
2003
2004              // Add InstructionBuilder to the Instruction(s)Builder List
2005              isb.setInstruction(instructions);
2006
2007              // Add InstructionsBuilder to FlowBuilder
2008              flowBuilder.setInstructions(isb.build());
2009
2010              writeFlow(flowBuilder, nodeBuilder);
2011          } else {
2012              removeFlow(flowBuilder, nodeBuilder);
2013          }
2014      }
2015
2016    /*
2017     * (Table:1) Table Drain w/ Catch All
2018     * Match: Tunnel ID
2019     * Action: GOTO Local Table (10)
2020     * table=2,priority=8192,tun_id=0x5 actions=drop
2021     */
2022
2023     private void handleTunnelMiss(Long dpidLong, Short writeTable,
2024                           Short goToTableId, String segmentationId,
2025                           boolean write) {
2026
2027         String nodeName = "openflow:" + dpidLong;
2028
2029         MatchBuilder matchBuilder = new MatchBuilder();
2030         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2031         FlowBuilder flowBuilder = new FlowBuilder();
2032
2033         // Create Match(es) and Set them in the FlowBuilder Object
2034         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
2035
2036         if (write) {
2037             // Create the OF Actions and Instructions
2038             InstructionBuilder ib = new InstructionBuilder();
2039             InstructionsBuilder isb = new InstructionsBuilder();
2040
2041             // Instructions List Stores Individual Instructions
2042             List<Instruction> instructions = new ArrayList<Instruction>();
2043
2044             // Call the InstructionBuilder Methods Containing Actions
2045             createGotoTableInstructions(ib, goToTableId);
2046             ib.setOrder(0);
2047             ib.setKey(new InstructionKey(0));
2048             instructions.add(ib.build());
2049
2050             // Add InstructionBuilder to the Instruction(s)Builder List
2051             isb.setInstruction(instructions);
2052
2053             // Add InstructionsBuilder to FlowBuilder
2054             flowBuilder.setInstructions(isb.build());
2055         }
2056
2057         String flowId = "TunnelMiss_"+segmentationId;
2058         // Add Flow Attributes
2059         flowBuilder.setId(new FlowId(flowId));
2060         FlowKey key = new FlowKey(new FlowId(flowId));
2061         flowBuilder.setStrict(true);
2062         flowBuilder.setBarrier(false);
2063         flowBuilder.setTableId(writeTable);
2064         flowBuilder.setKey(key);
2065         flowBuilder.setPriority(8192);
2066         flowBuilder.setFlowName(flowId);
2067         flowBuilder.setHardTimeout(0);
2068         flowBuilder.setIdleTimeout(0);
2069         if (write) {
2070             writeFlow(flowBuilder, nodeBuilder);
2071         } else {
2072             removeFlow(flowBuilder, nodeBuilder);
2073         }
2074     }
2075
2076
2077     /*
2078      * (Table:1) Table Drain w/ Catch All
2079      * Match: Vlan ID
2080      * Action: Output port eth interface
2081      * table=1,priority=8192,vlan_id=0x5 actions= output port:eth1
2082      */
2083
2084      private void handleVlanMiss(Long dpidLong, Short writeTable,
2085                          Short goToTableId, String segmentationId,
2086                          Long ethPort, boolean write) {
2087
2088          String nodeName = "openflow:" + dpidLong;
2089
2090          MatchBuilder matchBuilder = new MatchBuilder();
2091          NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2092          FlowBuilder flowBuilder = new FlowBuilder();
2093
2094          // Create Match(es) and Set them in the FlowBuilder Object
2095          flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
2096
2097          if (write) {
2098              // Create the OF Actions and Instructions
2099              InstructionBuilder ib = new InstructionBuilder();
2100              InstructionsBuilder isb = new InstructionsBuilder();
2101
2102              // Instructions List Stores Individual Instructions
2103              List<Instruction> instructions = new ArrayList<Instruction>();
2104
2105              // Call the InstructionBuilder Methods Containing Actions
2106              //createGotoTableInstructions(ib, goToTableId);
2107              //ib.setOrder(0);
2108              //ib.setKey(new InstructionKey(0));
2109              //instructions.add(ib.build());
2110              // Set the Output Port/Iface
2111              createOutputPortInstructions(ib, dpidLong, ethPort);
2112              ib.setOrder(0);
2113              ib.setKey(new InstructionKey(1));
2114              instructions.add(ib.build());
2115
2116              // Add InstructionBuilder to the Instruction(s)Builder List
2117              isb.setInstruction(instructions);
2118
2119              // Add InstructionsBuilder to FlowBuilder
2120              flowBuilder.setInstructions(isb.build());
2121          }
2122
2123          String flowId = "VlanMiss_"+segmentationId;
2124          // Add Flow Attributes
2125          flowBuilder.setId(new FlowId(flowId));
2126          FlowKey key = new FlowKey(new FlowId(flowId));
2127          flowBuilder.setStrict(true);
2128          flowBuilder.setBarrier(false);
2129          flowBuilder.setTableId(writeTable);
2130          flowBuilder.setKey(key);
2131          flowBuilder.setPriority(8192);
2132          flowBuilder.setFlowName(flowId);
2133          flowBuilder.setHardTimeout(0);
2134          flowBuilder.setIdleTimeout(0);
2135          if (write) {
2136              writeFlow(flowBuilder, nodeBuilder);
2137          } else {
2138              removeFlow(flowBuilder, nodeBuilder);
2139          }
2140      }
2141
2142     /*
2143      * (Table:1) Local Broadcast Flood
2144      * Match: Tunnel ID and dMAC
2145      * Action: Output Port
2146      * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
2147      */
2148
2149     private void handleLocalUcastOut(Long dpidLong, Short writeTable,
2150                              String segmentationId, Long localPort,
2151                              String attachedMac, boolean write) {
2152
2153         String nodeName = "openflow:" + dpidLong;
2154
2155         MatchBuilder matchBuilder = new MatchBuilder();
2156         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2157         FlowBuilder flowBuilder = new FlowBuilder();
2158
2159         // Create the OF Match using MatchBuilder
2160         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
2161         flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
2162
2163         String flowId = "UcastOut_"+segmentationId+"_"+localPort+"_"+attachedMac;
2164         // Add Flow Attributes
2165         flowBuilder.setId(new FlowId(flowId));
2166         FlowKey key = new FlowKey(new FlowId(flowId));
2167         flowBuilder.setStrict(true);
2168         flowBuilder.setBarrier(false);
2169         flowBuilder.setTableId(writeTable);
2170         flowBuilder.setKey(key);
2171         flowBuilder.setFlowName(flowId);
2172         flowBuilder.setHardTimeout(0);
2173         flowBuilder.setIdleTimeout(0);
2174
2175         if (write) {
2176             // Instantiate the Builders for the OF Actions and Instructions
2177             InstructionBuilder ib = new InstructionBuilder();
2178             InstructionsBuilder isb = new InstructionsBuilder();
2179
2180             // Instructions List Stores Individual Instructions
2181             List<Instruction> instructions = new ArrayList<Instruction>();
2182
2183             // Set the Output Port/Iface
2184             createOutputPortInstructions(ib, dpidLong, localPort);
2185             ib.setOrder(0);
2186             ib.setKey(new InstructionKey(0));
2187             instructions.add(ib.build());
2188
2189             // Add InstructionBuilder to the Instruction(s)Builder List
2190             isb.setInstruction(instructions);
2191
2192             // Add InstructionsBuilder to FlowBuilder
2193             flowBuilder.setInstructions(isb.build());
2194             writeFlow(flowBuilder, nodeBuilder);
2195         } else {
2196             removeFlow(flowBuilder, nodeBuilder);
2197         }
2198     }
2199
2200     /*
2201      * (Table:2) Local VLAN unicast
2202      * Match: VLAN ID and dMAC
2203      * Action: Output Port
2204      * table=2,vlan_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
2205      */
2206
2207     private void handleLocalVlanUcastOut(Long dpidLong, Short writeTable,
2208                                  String segmentationId, Long localPort,
2209                                  String attachedMac, boolean write) {
2210
2211         String nodeName = "openflow:" + dpidLong;
2212
2213         MatchBuilder matchBuilder = new MatchBuilder();
2214         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2215         FlowBuilder flowBuilder = new FlowBuilder();
2216
2217         // Create the OF Match using MatchBuilder
2218         flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
2219         flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
2220
2221         String flowId = "VlanUcastOut_"+segmentationId+"_"+localPort+"_"+attachedMac;
2222         // Add Flow Attributes
2223         flowBuilder.setId(new FlowId(flowId));
2224         FlowKey key = new FlowKey(new FlowId(flowId));
2225         flowBuilder.setStrict(true);
2226         flowBuilder.setBarrier(false);
2227         flowBuilder.setTableId(writeTable);
2228         flowBuilder.setKey(key);
2229         flowBuilder.setFlowName(flowId);
2230         flowBuilder.setHardTimeout(0);
2231         flowBuilder.setIdleTimeout(0);
2232
2233         if (write) {
2234             // Instantiate the Builders for the OF Actions and Instructions
2235             InstructionBuilder ib = new InstructionBuilder();
2236             InstructionsBuilder isb = new InstructionsBuilder();
2237
2238             // Instructions List Stores Individual Instructions
2239             List<Instruction> instructions = new ArrayList<Instruction>();
2240             List<Instruction> instructions_tmp = new ArrayList<Instruction>();
2241
2242             /* Strip vlan and store to tmp instruction space*/
2243             createPopVlanInstructions(ib);
2244             ib.setOrder(0);
2245             ib.setKey(new InstructionKey(0));
2246             instructions_tmp.add(ib.build());
2247
2248             // Set the Output Port/Iface
2249             ib = new InstructionBuilder();
2250             addOutputPortInstructions(ib, dpidLong, localPort, instructions_tmp);
2251             ib.setOrder(0);
2252             ib.setKey(new InstructionKey(0));
2253             instructions.add(ib.build());
2254
2255             // Add InstructionBuilder to the Instruction(s)Builder List
2256             isb.setInstruction(instructions);
2257
2258             // Add InstructionsBuilder to FlowBuilder
2259             flowBuilder.setInstructions(isb.build());
2260             writeFlow(flowBuilder, nodeBuilder);
2261         } else {
2262             removeFlow(flowBuilder, nodeBuilder);
2263         }
2264     }
2265
2266     /*
2267      * (Table:2) Local Broadcast Flood
2268      * Match: Tunnel ID and dMAC (::::FF:FF)
2269      * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
2270      * actions=output:2,3,4,5
2271      */
2272
2273     private void handleLocalBcastOut(Long dpidLong, Short writeTable,
2274                              String segmentationId, Long localPort,
2275                              boolean write) {
2276
2277         String nodeName = "openflow:" + dpidLong;
2278
2279         MatchBuilder matchBuilder = new MatchBuilder();
2280         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2281         FlowBuilder flowBuilder = new FlowBuilder();
2282
2283         // Create the OF Match using MatchBuilder
2284         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
2285         flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
2286
2287         String flowId = "BcastOut_"+segmentationId;
2288         // Add Flow Attributes
2289         flowBuilder.setId(new FlowId(flowId));
2290         FlowKey key = new FlowKey(new FlowId(flowId));
2291         flowBuilder.setStrict(true);
2292         flowBuilder.setBarrier(false);
2293         flowBuilder.setTableId(writeTable);
2294         flowBuilder.setKey(key);
2295         flowBuilder.setPriority(16384);
2296         flowBuilder.setFlowName(flowId);
2297         flowBuilder.setHardTimeout(0);
2298         flowBuilder.setIdleTimeout(0);
2299         Flow flow = this.getFlow(flowBuilder, nodeBuilder);
2300         // Instantiate the Builders for the OF Actions and Instructions
2301         InstructionBuilder ib = new InstructionBuilder();
2302         InstructionsBuilder isb = new InstructionsBuilder();
2303         List<Instruction> instructions = new ArrayList<Instruction>();
2304         List<Instruction> existingInstructions = null;
2305         if (flow != null) {
2306             Instructions ins = flow.getInstructions();
2307             if (ins != null) {
2308                 existingInstructions = ins.getInstruction();
2309             }
2310         }
2311
2312         if (write) {
2313             // Create output port list
2314             createOutputPortInstructions(ib, dpidLong, localPort, existingInstructions);
2315             ib.setOrder(0);
2316             ib.setKey(new InstructionKey(0));
2317             instructions.add(ib.build());
2318
2319             // Add InstructionBuilder to the Instruction(s)Builder List
2320             isb.setInstruction(instructions);
2321
2322             // Add InstructionsBuilder to FlowBuilder
2323             flowBuilder.setInstructions(isb.build());
2324
2325             writeFlow(flowBuilder, nodeBuilder);
2326         } else {
2327             boolean flowRemove = removeOutputPortFromInstructions(ib, dpidLong, localPort,
2328                                                                   existingInstructions);
2329             if (flowRemove) {
2330                 /* if all ports are removed, remove flow */
2331                 removeFlow(flowBuilder, nodeBuilder);
2332             } else {
2333                 /* Install instruction with new output port list*/
2334                 ib.setOrder(0);
2335                 ib.setKey(new InstructionKey(0));
2336                 instructions.add(ib.build());
2337
2338                 // Add InstructionBuilder to the Instruction(s)Builder List
2339                 isb.setInstruction(instructions);
2340
2341                 // Add InstructionsBuilder to FlowBuilder
2342                 flowBuilder.setInstructions(isb.build());
2343
2344                 writeFlow(flowBuilder, nodeBuilder);
2345             }
2346         }
2347     }
2348
2349     /*
2350      * (Table:2) Local VLAN Broadcast Flood
2351      * Match: vlan ID and dMAC (::::FF:FF)
2352      * table=2,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
2353      * actions=strip_vlan, output:2,3,4,5
2354      */
2355
2356     private void handleLocalVlanBcastOut(Long dpidLong, Short writeTable,
2357                                  String segmentationId, Long localPort,
2358                                  boolean write) {
2359
2360         String nodeName = "openflow:" + dpidLong;
2361
2362         MatchBuilder matchBuilder = new MatchBuilder();
2363         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2364         FlowBuilder flowBuilder = new FlowBuilder();
2365
2366         // Create the OF Match using MatchBuilder
2367         flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
2368         flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
2369
2370         String flowId = "VlanBcastOut_"+segmentationId;
2371         // Add Flow Attributes
2372         flowBuilder.setId(new FlowId(flowId));
2373         FlowKey key = new FlowKey(new FlowId(flowId));
2374         flowBuilder.setStrict(true);
2375         flowBuilder.setBarrier(false);
2376         flowBuilder.setTableId(writeTable);
2377         flowBuilder.setKey(key);
2378         flowBuilder.setPriority(16384);
2379         flowBuilder.setFlowName(flowId);
2380         flowBuilder.setHardTimeout(0);
2381         flowBuilder.setIdleTimeout(0);
2382         Flow flow = this.getFlow(flowBuilder, nodeBuilder);
2383         // Instantiate the Builders for the OF Actions and Instructions
2384         InstructionBuilder ib = new InstructionBuilder();
2385         InstructionsBuilder isb = new InstructionsBuilder();
2386         List<Instruction> instructions = new ArrayList<Instruction>();
2387         List<Instruction> existingInstructions = null;
2388         boolean add_pop_vlan = true;
2389         if (flow != null) {
2390             Instructions ins = flow.getInstructions();
2391             if (ins != null) {
2392                 existingInstructions = ins.getInstruction();
2393             }
2394         }
2395
2396         if (write) {
2397             if (existingInstructions != null) {
2398                 /* Check if pop vlan is already the first action in action list */
2399                 List<Action> existingActions = null;
2400                 for (Instruction in : existingInstructions) {
2401                     if (in.getInstruction() instanceof ApplyActionsCase) {
2402                         existingActions = (((ApplyActionsCase)
2403                                 in.getInstruction()).getApplyActions().getAction());
2404                         if (existingActions.get(0).getAction() instanceof PopVlanActionCase) {
2405                             add_pop_vlan = false;
2406                             break;
2407                         }
2408                     }
2409                 }
2410             } else {
2411                 existingInstructions = new ArrayList<Instruction>();
2412             }
2413
2414             if (add_pop_vlan) {
2415                 /* pop vlan */
2416                 createPopVlanInstructions(ib);
2417                 ib.setOrder(0);
2418                 ib.setKey(new InstructionKey(0));
2419                 existingInstructions.add(ib.build());
2420                 ib = new InstructionBuilder();
2421             }
2422
2423             // Create port list
2424             //createOutputGroupInstructions(nodeBuilder, ib, dpidLong, localPort, existingInstructions);
2425             createOutputPortInstructions(ib, dpidLong, localPort, existingInstructions);
2426             ib.setOrder(0);
2427             ib.setKey(new InstructionKey(0));
2428             instructions.add(ib.build());
2429
2430             // Add InstructionBuilder to the Instruction(s)Builder List
2431             isb.setInstruction(instructions);
2432
2433             // Add InstructionsBuilder to FlowBuilder
2434             flowBuilder.setInstructions(isb.build());
2435
2436             writeFlow(flowBuilder, nodeBuilder);
2437         } else {
2438             //boolean flowRemove = removeOutputPortFromGroup(nodeBuilder, ib, dpidLong,
2439             //                     localPort, existingInstructions);
2440             boolean flowRemove = removeOutputPortFromInstructions(ib, dpidLong,
2441                                                     localPort, existingInstructions);
2442             if (flowRemove) {
2443                 /* if all ports are removed, remove flow */
2444                 removeFlow(flowBuilder, nodeBuilder);
2445             } else {
2446                 /* Install instruction with new output port list*/
2447                 ib.setOrder(0);
2448                 ib.setKey(new InstructionKey(0));
2449                 instructions.add(ib.build());
2450
2451                 // Add InstructionBuilder to the Instruction(s)Builder List
2452                 isb.setInstruction(instructions);
2453
2454                 // Add InstructionsBuilder to FlowBuilder
2455                 flowBuilder.setInstructions(isb.build());
2456                 writeFlow(flowBuilder, nodeBuilder);
2457             }
2458         }
2459     }
2460
2461     /*
2462      * (Table:1) Local Table Miss
2463      * Match: Any Remaining Flows w/a TunID
2464      * Action: Drop w/ a low priority
2465      * table=2,priority=8192,tun_id=0x5 actions=drop
2466      */
2467
2468     private void handleLocalTableMiss(Long dpidLong, Short writeTable,
2469                              String segmentationId, boolean write) {
2470
2471         String nodeName = "openflow:" + dpidLong;
2472
2473         MatchBuilder matchBuilder = new MatchBuilder();
2474         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2475         FlowBuilder flowBuilder = new FlowBuilder();
2476
2477         // Create Match(es) and Set them in the FlowBuilder Object
2478         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
2479
2480         if (write) {
2481             // Create the OF Actions and Instructions
2482             InstructionBuilder ib = new InstructionBuilder();
2483             InstructionsBuilder isb = new InstructionsBuilder();
2484
2485             // Instructions List Stores Individual Instructions
2486             List<Instruction> instructions = new ArrayList<Instruction>();
2487
2488             // Call the InstructionBuilder Methods Containing Actions
2489             createDropInstructions(ib);
2490             ib.setOrder(0);
2491             ib.setKey(new InstructionKey(0));
2492             instructions.add(ib.build());
2493
2494             // Add InstructionBuilder to the Instruction(s)Builder List
2495             isb.setInstruction(instructions);
2496
2497             // Add InstructionsBuilder to FlowBuilder
2498             flowBuilder.setInstructions(isb.build());
2499         }
2500
2501         String flowId = "LocalTableMiss_"+segmentationId;
2502         // Add Flow Attributes
2503         flowBuilder.setId(new FlowId(flowId));
2504         FlowKey key = new FlowKey(new FlowId(flowId));
2505         flowBuilder.setStrict(true);
2506         flowBuilder.setBarrier(false);
2507         flowBuilder.setTableId(writeTable);
2508         flowBuilder.setKey(key);
2509         flowBuilder.setPriority(8192);
2510         flowBuilder.setFlowName(flowId);
2511         flowBuilder.setHardTimeout(0);
2512         flowBuilder.setIdleTimeout(0);
2513         if (write) {
2514             writeFlow(flowBuilder, nodeBuilder);
2515         } else {
2516             removeFlow(flowBuilder, nodeBuilder);
2517         }
2518     }
2519
2520     /*
2521      * (Table:1) Local Table Miss
2522      * Match: Any Remaining Flows w/a VLAN ID
2523      * Action: Drop w/ a low priority
2524      * table=2,priority=8192,vlan_id=0x5 actions=drop
2525      */
2526
2527     private void handleLocalVlanTableMiss(Long dpidLong, Short writeTable,
2528                                   String segmentationId, boolean write) {
2529
2530         String nodeName = "openflow:" + dpidLong;
2531
2532         MatchBuilder matchBuilder = new MatchBuilder();
2533         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2534         FlowBuilder flowBuilder = new FlowBuilder();
2535
2536         // Create Match(es) and Set them in the FlowBuilder Object
2537         flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
2538
2539         if (write) {
2540             // Create the OF Actions and Instructions
2541             InstructionBuilder ib = new InstructionBuilder();
2542             InstructionsBuilder isb = new InstructionsBuilder();
2543
2544             // Instructions List Stores Individual Instructions
2545             List<Instruction> instructions = new ArrayList<Instruction>();
2546
2547             // Call the InstructionBuilder Methods Containing Actions
2548             createDropInstructions(ib);
2549             ib.setOrder(0);
2550             ib.setKey(new InstructionKey(0));
2551             instructions.add(ib.build());
2552
2553             // Add InstructionBuilder to the Instruction(s)Builder List
2554             isb.setInstruction(instructions);
2555
2556             // Add InstructionsBuilder to FlowBuilder
2557             flowBuilder.setInstructions(isb.build());
2558         }
2559
2560         String flowId = "LocalTableMiss_"+segmentationId;
2561         // Add Flow Attributes
2562         flowBuilder.setId(new FlowId(flowId));
2563         FlowKey key = new FlowKey(new FlowId(flowId));
2564         flowBuilder.setStrict(true);
2565         flowBuilder.setBarrier(false);
2566         flowBuilder.setTableId(writeTable);
2567         flowBuilder.setKey(key);
2568         flowBuilder.setPriority(8192);
2569         flowBuilder.setFlowName(flowId);
2570         flowBuilder.setHardTimeout(0);
2571         flowBuilder.setIdleTimeout(0);
2572         if (write) {
2573             writeFlow(flowBuilder, nodeBuilder);
2574         } else {
2575             removeFlow(flowBuilder, nodeBuilder);
2576         }
2577     }
2578
2579     private Group getGroup(GroupBuilder groupBuilder, NodeBuilder nodeBuilder) {
2580         IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2581         if (mdsalConsumer == null) {
2582             logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2583             return null;
2584         }
2585
2586         dataBrokerService = mdsalConsumer.getDataBrokerService();
2587
2588         if (dataBrokerService == null) {
2589             logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2590             return null;
2591         }
2592
2593         InstanceIdentifier<Group> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2594                 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Group.class,
2595                 new GroupKey(groupBuilder.getGroupId())).build();
2596         return (Group)dataBrokerService.readConfigurationData(path1);
2597     }
2598
2599     private Group writeGroup(GroupBuilder groupBuilder, NodeBuilder nodeBuilder) {
2600         IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2601         if (mdsalConsumer == null) {
2602             logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2603             return null;
2604         }
2605
2606         dataBrokerService = mdsalConsumer.getDataBrokerService();
2607
2608         if (dataBrokerService == null) {
2609             logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2610             return null;
2611         }
2612         DataModification<InstanceIdentifier<?>, DataObject> modification = dataBrokerService.beginTransaction();
2613         InstanceIdentifier<Group> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2614                 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Group.class,
2615                 new GroupKey(groupBuilder.getGroupId())).build();
2616         modification.putConfigurationData(nodeBuilderToInstanceId(nodeBuilder), nodeBuilder.build());
2617         modification.putConfigurationData(path1, groupBuilder.build());
2618         Future<RpcResult<TransactionStatus>> commitFuture = modification.commit();
2619
2620         try {
2621             RpcResult<TransactionStatus> result = commitFuture.get();
2622             TransactionStatus status = result.getResult();
2623             logger.debug("Transaction Status "+status.toString()+" for Group "+groupBuilder.getGroupName());
2624         } catch (InterruptedException e) {
2625             logger.error(e.getMessage(), e);
2626         } catch (ExecutionException e) {
2627             logger.error(e.getMessage(), e);
2628         }
2629         return (Group)dataBrokerService.readConfigurationData(path1);
2630     }
2631
2632     private Group removeGroup(GroupBuilder groupBuilder, NodeBuilder nodeBuilder) {
2633         IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2634         if (mdsalConsumer == null) {
2635             logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2636             return null;
2637         }
2638
2639         dataBrokerService = mdsalConsumer.getDataBrokerService();
2640
2641         if (dataBrokerService == null) {
2642             logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2643             return null;
2644         }
2645         DataModification<InstanceIdentifier<?>, DataObject> modification = dataBrokerService.beginTransaction();
2646         InstanceIdentifier<Group> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2647                 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Group.class,
2648                 new GroupKey(groupBuilder.getGroupId())).build();
2649         modification.removeConfigurationData(path1);
2650         Future<RpcResult<TransactionStatus>> commitFuture = modification.commit();
2651
2652         try {
2653             RpcResult<TransactionStatus> result = commitFuture.get();
2654             TransactionStatus status = result.getResult();
2655             logger.debug("Transaction Status "+status.toString()+" for Group "+groupBuilder.getGroupName());
2656         } catch (InterruptedException e) {
2657             logger.error(e.getMessage(), e);
2658         } catch (ExecutionException e) {
2659             logger.error(e.getMessage(), e);
2660         }
2661         return (Group)dataBrokerService.readConfigurationData(path1);
2662     }
2663     private Flow getFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
2664         IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2665         if (mdsalConsumer == null) {
2666             logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2667             return null;
2668         }
2669
2670         dataBrokerService = mdsalConsumer.getDataBrokerService();
2671
2672         if (dataBrokerService == null) {
2673             logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2674             return null;
2675         }
2676
2677         InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2678                 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class,
2679                 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
2680         return (Flow)dataBrokerService.readConfigurationData(path1);
2681     }
2682
2683     private void writeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
2684         IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2685         if (mdsalConsumer == null) {
2686             logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2687             return;
2688         }
2689
2690         dataBrokerService = mdsalConsumer.getDataBrokerService();
2691
2692         if (dataBrokerService == null) {
2693             logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2694             return;
2695         }
2696         DataModification<InstanceIdentifier<?>, DataObject> modification = dataBrokerService.beginTransaction();
2697         InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2698                 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class,
2699                 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
2700         //modification.putOperationalData(nodeBuilderToInstanceId(nodeBuilder), nodeBuilder.build());
2701         //modification.putOperationalData(path1, flowBuilder.build());
2702         modification.putConfigurationData(nodeBuilderToInstanceId(nodeBuilder), nodeBuilder.build());
2703         modification.putConfigurationData(path1, flowBuilder.build());
2704         Future<RpcResult<TransactionStatus>> commitFuture = modification.commit();
2705         try {
2706             RpcResult<TransactionStatus> result = commitFuture.get();
2707             TransactionStatus status = result.getResult();
2708             logger.debug("Transaction Status "+status.toString()+" for Flow "+flowBuilder.getFlowName());
2709         } catch (InterruptedException e) {
2710             logger.error(e.getMessage(), e);
2711         } catch (ExecutionException e) {
2712             logger.error(e.getMessage(), e);
2713         }
2714     }
2715
2716     private void removeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
2717         IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2718         if (mdsalConsumer == null) {
2719             logger.error("ERROR finding MDSAL Service.");
2720             return;
2721         }
2722
2723         dataBrokerService = mdsalConsumer.getDataBrokerService();
2724
2725         if (dataBrokerService == null) {
2726             logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2727             return;
2728         }
2729         DataModification<InstanceIdentifier<?>, DataObject> modification = dataBrokerService.beginTransaction();
2730         InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class)
2731                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2732                 .rev130819.nodes.Node.class, nodeBuilder.getKey())
2733                 .augmentation(FlowCapableNode.class).child(Table.class,
2734                 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
2735         //modification.removeOperationalData(nodeBuilderToInstanceId(nodeBuilder));
2736         //modification.removeOperationalData(path1);
2737         //modification.removeConfigurationData(nodeBuilderToInstanceId(nodeBuilder));
2738         modification.removeConfigurationData(path1);
2739         Future<RpcResult<TransactionStatus>> commitFuture = modification.commit();
2740         try {
2741             RpcResult<TransactionStatus> result = commitFuture.get();
2742             TransactionStatus status = result.getResult();
2743             logger.debug("Transaction Status "+status.toString()+" for Flow "+flowBuilder.getFlowName());
2744         } catch (InterruptedException e) {
2745             logger.error(e.getMessage(), e);
2746         } catch (ExecutionException e) {
2747             logger.error(e.getMessage(), e);
2748         }
2749     }
2750
2751     /**
2752      * Create Ingress Port Match dpidLong, inPort
2753      *
2754      * @param matchBuilder  Map matchBuilder MatchBuilder Object without a match
2755      * @param dpidLong      Long the datapath ID of a switch/node
2756      * @param inPort        Long ingress port on a switch
2757      * @return matchBuilder Map MatchBuilder Object with a match
2758      */
2759     protected static MatchBuilder createInPortMatch(MatchBuilder matchBuilder, Long dpidLong, Long inPort) {
2760
2761         NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + inPort);
2762         logger.debug("createInPortMatch() Node Connector ID is - Type=openflow: DPID={} inPort={} ", dpidLong, inPort);
2763         matchBuilder.setInPort(NodeConnectorId.getDefaultInstance(ncid.getValue()));
2764         matchBuilder.setInPort(ncid);
2765
2766         return matchBuilder;
2767     }
2768
2769     /**
2770      * Create EtherType Match
2771      *
2772      * @param matchBuilder  Map matchBuilder MatchBuilder Object without a match
2773      * @param etherType     Long EtherType
2774      * @return matchBuilder Map MatchBuilder Object with a match
2775      */
2776     protected static MatchBuilder createEtherTypeMatch(MatchBuilder matchBuilder, EtherType etherType) {
2777
2778         EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
2779         EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2780         ethTypeBuilder.setType(new EtherType(etherType));
2781         ethernetMatch.setEthernetType(ethTypeBuilder.build());
2782         matchBuilder.setEthernetMatch(ethernetMatch.build());
2783
2784         return matchBuilder;
2785     }
2786
2787     /**
2788      * Create Ethernet Source Match
2789      *
2790      * @param matchBuilder  MatchBuilder Object without a match yet
2791      * @param sMacAddr      String representing a source MAC
2792      * @return matchBuilder Map MatchBuilder Object with a match
2793      */
2794     protected static MatchBuilder createEthSrcMatch(MatchBuilder matchBuilder, MacAddress sMacAddr) {
2795
2796         EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
2797         EthernetSourceBuilder ethSourceBuilder = new EthernetSourceBuilder();
2798         ethSourceBuilder.setAddress(new MacAddress(sMacAddr));
2799         ethernetMatch.setEthernetSource(ethSourceBuilder.build());
2800         matchBuilder.setEthernetMatch(ethernetMatch.build());
2801
2802         return matchBuilder;
2803     }
2804
2805     /**
2806      * Create Ethernet Destination Match
2807      *
2808      * @param matchBuilder MatchBuilder Object without a match yet
2809      * @param vlanId       Integer representing a VLAN ID Integer representing a VLAN ID
2810      * @return matchBuilder Map MatchBuilder Object with a match
2811      */
2812
2813     protected static MatchBuilder createVlanIdMatch(MatchBuilder matchBuilder, VlanId vlanId) {
2814         VlanMatchBuilder vlanMatchBuilder = new VlanMatchBuilder();
2815         VlanIdBuilder vlanIdBuilder = new VlanIdBuilder();
2816         vlanIdBuilder.setVlanId(new VlanId(vlanId));
2817         vlanIdBuilder.setVlanIdPresent(true);
2818         vlanMatchBuilder.setVlanId(vlanIdBuilder.build());
2819         matchBuilder.setVlanMatch(vlanMatchBuilder.build());
2820
2821         return matchBuilder;
2822     }
2823
2824     /**
2825      * Create Ethernet Destination Match
2826      *
2827      * @param matchBuilder  MatchBuilder Object without a match yet
2828      * @param dMacAddr      String representing a destination MAC
2829      * @return matchBuilder Map MatchBuilder Object with a match
2830      */
2831
2832     protected static MatchBuilder createDestEthMatch(MatchBuilder matchBuilder, MacAddress dMacAddr, MacAddress mask) {
2833
2834         EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
2835         EthernetDestinationBuilder ethDestinationBuilder = new EthernetDestinationBuilder();
2836         ethDestinationBuilder.setAddress(new MacAddress(dMacAddr));
2837         if (mask != null) {
2838             ethDestinationBuilder.setMask(mask);
2839         }
2840         ethernetMatch.setEthernetDestination(ethDestinationBuilder.build());
2841         matchBuilder.setEthernetMatch(ethernetMatch.build());
2842
2843         return matchBuilder;
2844     }
2845
2846     /**
2847      * Tunnel ID Match Builder
2848      *
2849      * @param matchBuilder  MatchBuilder Object without a match yet
2850      * @param tunnelId      BigInteger representing a tunnel ID
2851      * @return matchBuilder Map MatchBuilder Object with a match
2852      */
2853     protected static MatchBuilder createTunnelIDMatch(MatchBuilder matchBuilder, BigInteger tunnelId) {
2854
2855         TunnelBuilder tunnelBuilder = new TunnelBuilder();
2856         tunnelBuilder.setTunnelId(tunnelId);
2857         matchBuilder.setTunnel(tunnelBuilder.build());
2858
2859         return matchBuilder;
2860     }
2861
2862     /**
2863      * Match ICMP code and type
2864      *
2865      * @param matchBuilder  MatchBuilder Object without a match yet
2866      * @param type          short representing an ICMP type
2867      * @param code          short representing an ICMP code
2868      * @return matchBuilder Map MatchBuilder Object with a match
2869      */
2870     protected static MatchBuilder createICMPv4Match(MatchBuilder matchBuilder, short type, short code) {
2871
2872         EthernetMatchBuilder eth = new EthernetMatchBuilder();
2873         EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2874         ethTypeBuilder.setType(new EtherType(0x0800L));
2875         eth.setEthernetType(ethTypeBuilder.build());
2876         matchBuilder.setEthernetMatch(eth.build());
2877
2878         // Build the IPv4 Match requied per OVS Syntax
2879         IpMatchBuilder ipmatch = new IpMatchBuilder();
2880         ipmatch.setIpProtocol((short) 1);
2881         matchBuilder.setIpMatch(ipmatch.build());
2882
2883         // Build the ICMPv4 Match
2884         Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
2885         icmpv4match.setIcmpv4Type(type);
2886         icmpv4match.setIcmpv4Code(code);
2887         matchBuilder.setIcmpv4Match(icmpv4match.build());
2888
2889         return matchBuilder;
2890     }
2891
2892     /**
2893      * @param matchBuilder MatchBuilder Object without a match yet
2894      * @param dstip        String containing an IPv4 prefix
2895      * @return matchBuilder Map Object with a match
2896      */
2897     private static MatchBuilder createDstL3IPv4Match(MatchBuilder matchBuilder, Ipv4Prefix dstip) {
2898
2899         EthernetMatchBuilder eth = new EthernetMatchBuilder();
2900         EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2901         ethTypeBuilder.setType(new EtherType(0x0800L));
2902         eth.setEthernetType(ethTypeBuilder.build());
2903         matchBuilder.setEthernetMatch(eth.build());
2904
2905         Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder();
2906         ipv4match.setIpv4Destination(dstip);
2907
2908         matchBuilder.setLayer3Match(ipv4match.build());
2909
2910         return matchBuilder;
2911
2912     }
2913
2914     /**
2915      * @param matchBuilder MatchBuilder Object without a match yet
2916      * @param srcip        String containing an IPv4 prefix
2917      * @return             matchBuilder Map Object with a match
2918      */
2919     private static MatchBuilder createSrcL3IPv4Match(MatchBuilder matchBuilder, Ipv4Prefix srcip) {
2920
2921         EthernetMatchBuilder eth = new EthernetMatchBuilder();
2922         EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2923         ethTypeBuilder.setType(new EtherType(0x0800L));
2924         eth.setEthernetType(ethTypeBuilder.build());
2925         matchBuilder.setEthernetMatch(eth.build());
2926
2927         Ipv4MatchBuilder ipv4Match = new Ipv4MatchBuilder();
2928         Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder();
2929         ipv4match.setIpv4Source(srcip);
2930         matchBuilder.setLayer3Match(ipv4match.build());
2931
2932         return matchBuilder;
2933
2934     }
2935
2936     /**
2937      * Create Source TCP Port Match
2938      *
2939      * @param matchBuilder @param matchbuilder MatchBuilder Object without a match yet
2940      * @param tcpport      Integer representing a source TCP port
2941      * @return             matchBuilder Map MatchBuilder Object with a match
2942      */
2943     protected static MatchBuilder createSetSrcTcpMatch(MatchBuilder matchBuilder, PortNumber tcpport) {
2944
2945         EthernetMatchBuilder ethType = new EthernetMatchBuilder();
2946         EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2947         ethTypeBuilder.setType(new EtherType(0x0800L));
2948         ethType.setEthernetType(ethTypeBuilder.build());
2949         matchBuilder.setEthernetMatch(ethType.build());
2950
2951         IpMatchBuilder ipmatch = new IpMatchBuilder();
2952         ipmatch.setIpProtocol((short) 6);
2953         matchBuilder.setIpMatch(ipmatch.build());
2954
2955         TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
2956         tcpmatch.setTcpSourcePort(tcpport);
2957         matchBuilder.setLayer4Match(tcpmatch.build());
2958
2959         return matchBuilder;
2960
2961     }
2962
2963     /**
2964      * Create Destination TCP Port Match
2965      *
2966      * @param matchBuilder MatchBuilder Object without a match yet
2967      * @param tcpport      Integer representing a destination TCP port
2968      * @return             matchBuilder Map MatchBuilder Object with a match
2969      */
2970     protected static MatchBuilder createSetDstTcpMatch(MatchBuilder matchBuilder, PortNumber tcpport) {
2971
2972         EthernetMatchBuilder ethType = new EthernetMatchBuilder();
2973         EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2974         ethTypeBuilder.setType(new EtherType(0x0800L));
2975         ethType.setEthernetType(ethTypeBuilder.build());
2976         matchBuilder.setEthernetMatch(ethType.build());
2977
2978         IpMatchBuilder ipmatch = new IpMatchBuilder();
2979         ipmatch.setIpProtocol((short) 6);
2980         matchBuilder.setIpMatch(ipmatch.build());
2981
2982         PortNumber dstport = new PortNumber(tcpport);
2983         TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
2984
2985         tcpmatch.setTcpDestinationPort(tcpport);
2986         matchBuilder.setLayer4Match(tcpmatch.build());
2987
2988         return matchBuilder;
2989     }
2990
2991     /**
2992      * Create Send to Controller Reserved Port Instruction (packet_in)
2993      *
2994      * @param ib Map InstructionBuilder without any instructions
2995      * @return ib Map InstructionBuilder with instructions
2996      */
2997
2998     protected static InstructionBuilder createSendToControllerInstructions(InstructionBuilder ib) {
2999
3000         List<Action> actionList = new ArrayList<Action>();
3001         ActionBuilder ab = new ActionBuilder();
3002
3003         OutputActionBuilder output = new OutputActionBuilder();
3004         output.setMaxLength(0xffff);
3005         Uri value = new Uri("CONTROLLER");
3006         output.setOutputNodeConnector(value);
3007         ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
3008         ab.setOrder(0);
3009         ab.setKey(new ActionKey(0));
3010         actionList.add(ab.build());
3011
3012         // Create an Apply Action
3013         ApplyActionsBuilder aab = new ApplyActionsBuilder();
3014         aab.setAction(actionList);
3015
3016         // Wrap our Apply Action in an Instruction
3017         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3018
3019         return ib;
3020     }
3021
3022     /**
3023      * Create NORMAL Reserved Port Instruction (packet_in)
3024      *
3025      * @param ib Map InstructionBuilder without any instructions
3026      * @return ib Map InstructionBuilder with instructions
3027      */
3028
3029     protected static InstructionBuilder createNormalInstructions(InstructionBuilder ib) {
3030
3031         List<Action> actionList = new ArrayList<Action>();
3032         ActionBuilder ab = new ActionBuilder();
3033
3034         OutputActionBuilder output = new OutputActionBuilder();
3035         Uri value = new Uri("NORMAL");
3036         output.setOutputNodeConnector(value);
3037         ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
3038         ab.setOrder(0);
3039         ab.setKey(new ActionKey(0));
3040         actionList.add(ab.build());
3041
3042         // Create an Apply Action
3043         ApplyActionsBuilder aab = new ApplyActionsBuilder();
3044         aab.setAction(actionList);
3045
3046         // Wrap our Apply Action in an Instruction
3047         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3048
3049         return ib;
3050     }
3051
3052     /**
3053      * Create Output Port Instruction
3054      *
3055      * @param ib       Map InstructionBuilder without any instructions
3056      * @param dpidLong Long the datapath ID of a switch/node
3057      * @param port     Long representing a port on a switch/node
3058      * @return ib InstructionBuilder Map with instructions
3059      */
3060     protected static InstructionBuilder createOutputPortInstructions(InstructionBuilder ib, Long dpidLong, Long port) {
3061
3062         NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3063         logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} inPort={} ", dpidLong, port);
3064
3065         List<Action> actionList = new ArrayList<Action>();
3066         ActionBuilder ab = new ActionBuilder();
3067         OutputActionBuilder oab = new OutputActionBuilder();
3068         oab.setOutputNodeConnector(ncid);
3069
3070         ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
3071         ab.setOrder(0);
3072         ab.setKey(new ActionKey(0));
3073         actionList.add(ab.build());
3074
3075         // Create an Apply Action
3076         ApplyActionsBuilder aab = new ApplyActionsBuilder();
3077         aab.setAction(actionList);
3078         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3079
3080         return ib;
3081     }
3082
3083     /**
3084      * Create Output Port Group Instruction
3085      *
3086      * @param ib       Map InstructionBuilder without any instructions
3087      * @param dpidLong Long the datapath ID of a switch/node
3088      * @param port     Long representing a port on a switch/node
3089      * @return ib InstructionBuilder Map with instructions
3090      */
3091     protected InstructionBuilder createOutputPortInstructions(InstructionBuilder ib,
3092                                                               Long dpidLong, Long port ,
3093                                                               List<Instruction> instructions) {
3094         NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3095         logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3096
3097         List<Action> actionList = new ArrayList<Action>();
3098         ActionBuilder ab = new ActionBuilder();
3099
3100         List<Action> existingActions = null;
3101         if (instructions != null) {
3102             for (Instruction in : instructions) {
3103                 if (in.getInstruction() instanceof ApplyActionsCase) {
3104                     existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3105                     actionList.addAll(existingActions);
3106                 }
3107             }
3108         }
3109         /* Create output action for this port*/
3110         OutputActionBuilder oab = new OutputActionBuilder();
3111         oab.setOutputNodeConnector(ncid);
3112         ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
3113         boolean addNew = true;
3114
3115         /* Find the group action and get the group */
3116         for (Action action : actionList) {
3117             if (action.getAction() instanceof OutputActionCase) {
3118                 OutputActionCase opAction = (OutputActionCase)action.getAction();
3119                 /* If output port action already in the action list of one of the buckets, skip */
3120                 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
3121                     addNew = false;
3122                     break;
3123                 }
3124             }
3125         }
3126         if (addNew) {
3127             ab.setOrder(actionList.size());
3128             ab.setKey(new ActionKey(actionList.size()));
3129             actionList.add(ab.build());
3130         }
3131         // Create an Apply Action
3132         ApplyActionsBuilder aab = new ApplyActionsBuilder();
3133         aab.setAction(actionList);
3134         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3135         logger.debug("createOutputPortInstructions() : applyAction {}", aab.build());
3136         return ib;
3137     }
3138
3139     /**
3140      * Create Output Port Group Instruction
3141      *
3142      * @param ib       Map InstructionBuilder without any instructions
3143      * @param dpidLong Long the datapath ID of a switch/node
3144      * @param port     Long representing a port on a switch/node
3145      * @return ib InstructionBuilder Map with instructions
3146      */
3147     protected InstructionBuilder createOutputGroupInstructions(NodeBuilder nodeBuilder,
3148                                                                InstructionBuilder ib,
3149                                                                Long dpidLong, Long port ,
3150                                                                List<Instruction> instructions) {
3151         NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3152         logger.debug("createOutputGroupInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3153
3154         List<Action> actionList = new ArrayList<Action>();
3155         ActionBuilder ab = new ActionBuilder();
3156
3157         List<Action> existingActions = null;
3158         if (instructions != null) {
3159             for (Instruction in : instructions) {
3160                 if (in.getInstruction() instanceof ApplyActionsCase) {
3161                     existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3162                     actionList.addAll(existingActions);
3163                 }
3164             }
3165         }
3166
3167         GroupBuilder groupBuilder = new GroupBuilder();
3168         Group group = null;
3169
3170         /* Create output action for this port*/
3171         OutputActionBuilder oab = new OutputActionBuilder();
3172         oab.setOutputNodeConnector(ncid);
3173         ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
3174         logger.debug("createOutputGroupInstructions(): output action {}", ab.build());
3175         boolean addNew = true;
3176         boolean groupActionAdded = false;
3177
3178         /* Find the group action and get the group */
3179         for (Action action : actionList) {
3180             if (action.getAction() instanceof GroupActionCase) {
3181                 groupActionAdded = true;
3182                 GroupActionCase groupAction = (GroupActionCase) action.getAction();
3183                 Long id = groupAction.getGroupAction().getGroupId();
3184                 String groupName = groupAction.getGroupAction().getGroup();
3185                 GroupKey key = new GroupKey(new GroupId(id));
3186
3187                 groupBuilder.setGroupId(new GroupId(id));
3188                 groupBuilder.setGroupName(groupName);
3189                 groupBuilder.setGroupType(GroupTypes.GroupAll);
3190                 groupBuilder.setKey(key);
3191                 group = getGroup(groupBuilder, nodeBuilder);
3192                 logger.debug("createOutputGroupInstructions: group {}", group);
3193                 break;
3194             }
3195         }
3196
3197         logger.debug("createOutputGroupInstructions: groupActionAdded {}", groupActionAdded);
3198         if (groupActionAdded) {
3199             /* modify the action bucket in group */
3200             groupBuilder = new GroupBuilder(group);
3201             Buckets buckets = groupBuilder.getBuckets();
3202             for (Bucket bucket : buckets.getBucket()) {
3203                 List<Action> bucketActions = bucket.getAction();
3204                 logger.debug("createOutputGroupInstructions: bucketActions {}", bucketActions);
3205                 for (Action action : bucketActions) {
3206                     if (action.getAction() instanceof OutputActionCase) {
3207                         OutputActionCase opAction = (OutputActionCase)action.getAction();
3208                         /* If output port action already in the action list of one of the buckets, skip */
3209                         if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
3210                             addNew = false;
3211                             break;
3212                         }
3213                     }
3214                 }
3215             }
3216             logger.debug("createOutputGroupInstructions: addNew {}", addNew);
3217             if (addNew) {
3218                 /* the new output action is not in the bucket, add to bucket */
3219                 if (!buckets.getBucket().isEmpty()) {
3220                     Bucket bucket = buckets.getBucket().get(0);
3221                     List<Action> bucketActionList = new ArrayList<Action>();
3222                     bucketActionList.addAll(bucket.getAction());
3223                     /* set order for new action and add to action list */
3224                     ab.setOrder(bucketActionList.size());
3225                     ab.setKey(new ActionKey(bucketActionList.size()));
3226                     bucketActionList.add(ab.build());
3227
3228                     /* set bucket and buckets list. Reset groupBuilder with new buckets.*/
3229                     BucketsBuilder bucketsBuilder = new BucketsBuilder();
3230                     List<Bucket> bucketList = new ArrayList<Bucket>();
3231                     BucketBuilder bucketBuilder = new BucketBuilder();
3232                     bucketBuilder.setBucketId(new BucketId((long) 1));
3233                     bucketBuilder.setKey(new BucketKey(new BucketId((long) 1)));
3234                     bucketBuilder.setAction(bucketActionList);
3235                     bucketList.add(bucketBuilder.build());
3236                     bucketsBuilder.setBucket(bucketList);
3237                     groupBuilder.setBuckets(bucketsBuilder.build());
3238                     logger.debug("createOutputGroupInstructions: bucketList {}", bucketList);
3239                 }
3240             }
3241         } else {
3242             /* create group */
3243             groupBuilder = new GroupBuilder();
3244             groupBuilder.setGroupType(GroupTypes.GroupAll);
3245             groupBuilder.setGroupId(new GroupId(groupId));
3246             groupBuilder.setKey(new GroupKey(new GroupId(groupId)));
3247             groupBuilder.setGroupName("Output port group" + groupId);
3248             groupBuilder.setBarrier(false);
3249
3250             BucketsBuilder bucketBuilder = new BucketsBuilder();
3251             List<Bucket> bucketList = new ArrayList<Bucket>();
3252             BucketBuilder bucket = new BucketBuilder();
3253             bucket.setBucketId(new BucketId((long) 1));
3254             bucket.setKey(new BucketKey(new BucketId((long) 1)));
3255
3256             /* put output action to the bucket */
3257             List<Action> bucketActionList = new ArrayList<Action>();
3258             /* set order for new action and add to action list */
3259             ab.setOrder(bucketActionList.size());
3260             ab.setKey(new ActionKey(bucketActionList.size()));
3261             bucketActionList.add(ab.build());
3262
3263             bucket.setAction(bucketActionList);
3264             bucketList.add(bucket.build());
3265             bucketBuilder.setBucket(bucketList);
3266             groupBuilder.setBuckets(bucketBuilder.build());
3267
3268             /* Add new group action */
3269             GroupActionBuilder groupActionB = new GroupActionBuilder();
3270             groupActionB.setGroupId(groupId);
3271             groupActionB.setGroup("Output port group" + groupId);
3272             ab = new ActionBuilder();
3273             ab.setAction(new GroupActionCaseBuilder().setGroupAction(groupActionB.build()).build());
3274             ab.setOrder(actionList.size());
3275             ab.setKey(new ActionKey(actionList.size()));
3276             actionList.add(ab.build());
3277
3278             groupId++;
3279         }
3280         logger.debug("createOutputGroupInstructions: group {}", groupBuilder.build());
3281         logger.debug("createOutputGroupInstructions: actionList {}", actionList);
3282
3283         if (addNew) {
3284             /* rewrite the group to group table */
3285             writeGroup(groupBuilder, nodeBuilder);
3286         }
3287
3288         // Create an Apply Action
3289         ApplyActionsBuilder aab = new ApplyActionsBuilder();
3290         aab.setAction(actionList);
3291         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3292
3293         return ib;
3294     }
3295
3296     /**
3297      * add Output Port action to Instruction action list.
3298      * This is use for flow with single output port actions.
3299      * Flow with mutiple output port actions should use createOutputPortInstructions() method.
3300      *
3301      * @param ib       Map InstructionBuilder without any instructions
3302      * @param dpidLong Long the datapath ID of a switch/node
3303      * @param port     Long representing a port on a switch/node
3304      * @return ib InstructionBuilder Map with instructions
3305      */
3306     protected static InstructionBuilder addOutputPortInstructions(InstructionBuilder ib,
3307                                                                      Long dpidLong, Long port ,
3308                                                                      List<Instruction> instructions) {
3309         NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3310         logger.debug("addOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3311
3312         List<Action> actionList = new ArrayList<Action>();
3313         ActionBuilder ab = new ActionBuilder();
3314
3315         List<Action> existingActions = null;
3316         if (instructions != null) {
3317             for (Instruction in : instructions) {
3318                 if (in.getInstruction() instanceof ApplyActionsCase) {
3319                     existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3320                     actionList.addAll(existingActions);
3321                 }
3322             }
3323         }
3324
3325         /* Create output action for this port*/
3326         OutputActionBuilder oab = new OutputActionBuilder();
3327         oab.setOutputNodeConnector(ncid);
3328         ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
3329         ab.setOrder(actionList.size());
3330         ab.setKey(new ActionKey(actionList.size()));
3331         actionList.add(ab.build());
3332
3333         // Create an Apply Action
3334         ApplyActionsBuilder aab = new ApplyActionsBuilder();
3335         aab.setAction(actionList);
3336         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3337
3338         return ib;
3339     }
3340
3341     /**
3342      * Remove Output Port from action list in group bucket
3343      *
3344      * @param ib       Map InstructionBuilder without any instructions
3345      * @param dpidLong Long the datapath ID of a switch/node
3346      * @param port     Long representing a port on a switch/node
3347      * @return ib InstructionBuilder Map with instructions
3348      */
3349     protected boolean removeOutputPortFromGroup(NodeBuilder nodeBuilder, InstructionBuilder ib,
3350                                 Long dpidLong, Long port , List<Instruction> instructions) {
3351
3352         NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3353         logger.debug("removeOutputPortFromGroup() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3354
3355         List<Action> actionList = new ArrayList<Action>();
3356         ActionBuilder ab;
3357
3358         List<Action> existingActions = null;
3359         if (instructions != null) {
3360             for (Instruction in : instructions) {
3361                 if (in.getInstruction() instanceof ApplyActionsCase) {
3362                     existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3363                     actionList.addAll(existingActions);
3364                     break;
3365                 }
3366             }
3367         }
3368
3369         GroupBuilder groupBuilder = new GroupBuilder();
3370         Group group = null;
3371         boolean groupActionAdded = false;
3372         /* Find the group action and get the group */
3373         for (Action action : actionList) {
3374             if (action.getAction() instanceof GroupActionCase) {
3375                 groupActionAdded = true;
3376                 GroupActionCase groupAction = (GroupActionCase) action.getAction();
3377                 Long id = groupAction.getGroupAction().getGroupId();
3378                 String groupName = groupAction.getGroupAction().getGroup();
3379                 GroupKey key = new GroupKey(new GroupId(id));
3380
3381                 groupBuilder.setGroupId(new GroupId(id));
3382                 groupBuilder.setGroupName(groupName);
3383                 groupBuilder.setGroupType(GroupTypes.GroupAll);
3384                 groupBuilder.setKey(key);
3385                 group = getGroup(groupBuilder, nodeBuilder);
3386                 break;
3387             }
3388         }
3389
3390         if (groupActionAdded) {
3391             /* modify the action bucket in group */
3392             groupBuilder = new GroupBuilder(group);
3393             Buckets buckets = groupBuilder.getBuckets();
3394             List<Action> bucketActions = new ArrayList<Action>();
3395             for (Bucket bucket : buckets.getBucket()) {
3396                 int index = 0;
3397                 boolean isPortDeleted = false;
3398                 bucketActions = bucket.getAction();
3399                 for (Action action : bucketActions) {
3400                     if (action.getAction() instanceof OutputActionCase) {
3401                         OutputActionCase opAction = (OutputActionCase)action.getAction();
3402                         if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
3403                             /* Find the output port in action list and remove */
3404                             index = bucketActions.indexOf(action);
3405                             bucketActions.remove(action);
3406                             isPortDeleted = true;
3407                             break;
3408                         }
3409                     }
3410                 }
3411                 if (isPortDeleted && !bucketActions.isEmpty()) {
3412                     for (int i = index; i< bucketActions.size(); i++) {
3413                         Action action = bucketActions.get(i);
3414                         if (action.getOrder() != i) {
3415                             /* Shift the action order */
3416                             ab = new ActionBuilder();
3417                             ab.setAction(action.getAction());
3418                             ab.setOrder(i);
3419                             ab.setKey(new ActionKey(i));
3420                             Action actionNewOrder = ab.build();
3421                             bucketActions.remove(action);
3422                             bucketActions.add(i, actionNewOrder);
3423                         }
3424                     }
3425
3426                 } else if (bucketActions.isEmpty()) {
3427                     /* remove bucket with empty action list */
3428                     buckets.getBucket().remove(bucket);
3429                     break;
3430                 }
3431             }
3432             if (!buckets.getBucket().isEmpty()) {
3433                 /* rewrite the group to group table */
3434                 /* set bucket and buckets list. Reset groupBuilder with new buckets.*/
3435                 BucketsBuilder bucketsBuilder = new BucketsBuilder();
3436                 List<Bucket> bucketList = new ArrayList<Bucket>();
3437                 BucketBuilder bucketBuilder = new BucketBuilder();
3438                 bucketBuilder.setBucketId(new BucketId((long) 1));
3439                 bucketBuilder.setKey(new BucketKey(new BucketId((long) 1)));
3440                 bucketBuilder.setAction(bucketActions);
3441                 bucketList.add(bucketBuilder.build());
3442                 bucketsBuilder.setBucket(bucketList);
3443                 groupBuilder.setBuckets(bucketsBuilder.build());
3444                 logger.debug("removeOutputPortFromGroup: bucketList {}", bucketList);
3445
3446                 writeGroup(groupBuilder, nodeBuilder);
3447                 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3448                 aab.setAction(actionList);
3449                 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3450                 return false;
3451             } else {
3452                 /* remove group with empty bucket. return true to delete flow */
3453                 removeGroup(groupBuilder, nodeBuilder);
3454                 return true;
3455             }
3456         } else {
3457             /* no group for port list. flow can be removed */
3458             return true;
3459         }
3460     }
3461
3462     /**
3463      * Remove Output Port from Instruction
3464      *
3465      * @param ib       Map InstructionBuilder without any instructions
3466      * @param dpidLong Long the datapath ID of a switch/node
3467      * @param port     Long representing a port on a switch/node
3468      * @return ib InstructionBuilder Map with instructions
3469      */
3470     protected static boolean removeOutputPortFromInstructions(InstructionBuilder ib,
3471                                 Long dpidLong, Long port , List<Instruction> instructions) {
3472
3473         NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3474         logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3475
3476         List<Action> actionList = new ArrayList<Action>();
3477         ActionBuilder ab;
3478
3479         List<Action> existingActions = null;
3480         if (instructions != null) {
3481             for (Instruction in : instructions) {
3482                 if (in.getInstruction() instanceof ApplyActionsCase) {
3483                     existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3484                     actionList.addAll(existingActions);
3485                     break;
3486                 }
3487             }
3488         }
3489
3490         int numOutputPort = 0;
3491         int index = 0;
3492         boolean isPortDeleted = false;
3493         for (Action action : actionList) {
3494             if (action.getAction() instanceof OutputActionCase) {
3495                 numOutputPort++;
3496                 OutputActionCase opAction = (OutputActionCase)action.getAction();
3497                 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
3498                     /* Find the output port in action list and remove */
3499                     index = actionList.indexOf(action);
3500                     actionList.remove(action);
3501                     isPortDeleted = true;
3502                     numOutputPort--;
3503                     break;
3504                 }
3505             }
3506         }
3507
3508         if (isPortDeleted) {
3509             for (int i = index; i< actionList.size(); i++) {
3510                 Action action = actionList.get(i);
3511                 if (action.getOrder() != i) {
3512                     /* Shift the action order */
3513                     ab = new ActionBuilder();
3514                     ab.setAction(action.getAction());
3515                     ab.setOrder(i);
3516                     ab.setKey(new ActionKey(i));
3517                     Action actionNewOrder = ab.build();
3518                     actionList.remove(action);
3519                     actionList.add(i, actionNewOrder);
3520                 }
3521             }
3522         }
3523
3524         /* Put new action list in Apply Action instruction */
3525         if (numOutputPort > 0) {
3526             ApplyActionsBuilder aab = new ApplyActionsBuilder();
3527             aab.setAction(actionList);
3528             ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3529             logger.debug("createOutputPortInstructions() : applyAction {}", aab.build());
3530             return false;
3531         } else {
3532             /* if all output port are removed. Return true to indicate flow remove */
3533             return true;
3534         }
3535     }
3536
3537     /**
3538      * Create Set Vlan ID Instruction - This includes push vlan action, and set field -> vlan vid action
3539      *
3540      * @param ib     Map InstructionBuilder without any instructions
3541      * @param vlanId Integer representing a VLAN ID Integer representing a VLAN ID
3542      * @return ib Map InstructionBuilder with instructions
3543      */
3544     protected static InstructionBuilder createSetVlanInstructions(InstructionBuilder ib, VlanId vlanId) {
3545
3546         List<Action> actionList = new ArrayList<Action>();
3547         ActionBuilder ab = new ActionBuilder();
3548
3549         /* First we push vlan header */
3550         PushVlanActionBuilder vlan = new PushVlanActionBuilder();
3551         vlan.setEthernetType(new Integer(0x8100));
3552         ab.setAction(new PushVlanActionCaseBuilder().setPushVlanAction(vlan.build()).build());
3553         ab.setOrder(0);
3554         actionList.add(ab.build());
3555
3556         /* Then we set vlan id value as vlanId */
3557         SetVlanIdActionBuilder vl = new SetVlanIdActionBuilder();
3558         vl.setVlanId(vlanId);
3559         ab = new ActionBuilder();
3560         ab.setAction(new SetVlanIdActionCaseBuilder().setSetVlanIdAction(vl.build()).build());
3561         ab.setOrder(1);
3562         actionList.add(ab.build());
3563         // Create an Apply Action
3564         ApplyActionsBuilder aab = new ApplyActionsBuilder();
3565         aab.setAction(actionList);
3566
3567         // Wrap our Apply Action in an Instruction
3568         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3569
3570         return ib;
3571     }
3572
3573     /**
3574      * Create Pop Vlan Instruction - this remove vlan header
3575      *
3576      * @param ib Map InstructionBuilder without any instructions
3577      * @return ib Map InstructionBuilder with instructions
3578      */
3579     protected static InstructionBuilder createPopVlanInstructions(InstructionBuilder ib) {
3580
3581         List<Action> actionList = new ArrayList<Action>();
3582         ActionBuilder ab = new ActionBuilder();
3583
3584         PopVlanActionBuilder popVlanActionBuilder = new PopVlanActionBuilder();
3585         ab.setAction(new PopVlanActionCaseBuilder().setPopVlanAction(popVlanActionBuilder.build()).build());
3586         ab.setOrder(0);
3587         actionList.add(ab.build());
3588
3589         // Create an Apply Action
3590         ApplyActionsBuilder aab = new ApplyActionsBuilder();
3591         aab.setAction(actionList);
3592
3593         // Wrap our Apply Action in an Instruction
3594         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3595
3596         return ib;
3597     }
3598
3599     /**
3600      * Create Set IPv4 Source Instruction
3601      *
3602      * @param ib        Map InstructionBuilder without any instructions
3603      * @param prefixsrc String containing an IPv4 prefix
3604      * @return ib Map InstructionBuilder with instructions
3605      */
3606     protected static InstructionBuilder createNwSrcInstructions(InstructionBuilder ib, Ipv4Prefix prefixsrc) {
3607
3608         List<Action> actionList = new ArrayList<Action>();
3609         ActionBuilder ab = new ActionBuilder();
3610
3611         SetNwSrcActionBuilder setNwsrcActionBuilder = new SetNwSrcActionBuilder();
3612         Ipv4Builder ipsrc = new Ipv4Builder();
3613         ipsrc.setIpv4Address(prefixsrc);
3614         setNwsrcActionBuilder.setAddress(ipsrc.build());
3615         ab.setAction(new SetNwSrcActionCaseBuilder().setSetNwSrcAction(setNwsrcActionBuilder.build()).build());
3616         actionList.add(ab.build());
3617
3618         // Create an Apply Action
3619         ApplyActionsBuilder aab = new ApplyActionsBuilder();
3620         aab.setAction(actionList);
3621
3622         // Wrap our Apply Action in an Instruction
3623         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3624
3625         return ib;
3626     }
3627
3628     /**
3629      * Create Set IPv4 Destination Instruction
3630      *
3631      * @param ib           Map InstructionBuilder without any instructions
3632      * @param prefixdst    String containing an IPv4 prefix
3633      * @return ib Map InstructionBuilder with instructions
3634      */
3635     protected static InstructionBuilder createNwDstInstructions(InstructionBuilder ib, Ipv4Prefix prefixdst) {
3636
3637         List<Action> actionList = new ArrayList<Action>();
3638         ActionBuilder ab = new ActionBuilder();
3639
3640         SetNwDstActionBuilder setNwDstActionBuilder = new SetNwDstActionBuilder();
3641         Ipv4Builder ipdst = new Ipv4Builder();
3642         ipdst.setIpv4Address(prefixdst);
3643         setNwDstActionBuilder.setAddress(ipdst.build());
3644         ab.setAction(new SetNwDstActionCaseBuilder().setSetNwDstAction(setNwDstActionBuilder.build()).build());
3645         actionList.add(ab.build());
3646
3647         // Create an Apply Action
3648         ApplyActionsBuilder aab = new ApplyActionsBuilder();
3649         aab.setAction(actionList);
3650
3651         // Wrap our Apply Action in an Instruction
3652         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3653
3654         return ib;
3655     }
3656
3657     /**
3658      * Create Drop Instruction
3659      *
3660      * @param ib Map InstructionBuilder without any instructions
3661      * @return ib Map InstructionBuilder with instructions
3662      */
3663     protected static InstructionBuilder createDropInstructions(InstructionBuilder ib) {
3664
3665         DropActionBuilder dab = new DropActionBuilder();
3666         DropAction dropAction = dab.build();
3667         ActionBuilder ab = new ActionBuilder();
3668         ab.setAction(new DropActionCaseBuilder().setDropAction(dropAction).build());
3669         ab.setOrder(0);
3670
3671         // Add our drop action to a list
3672         List<Action> actionList = new ArrayList<Action>();
3673         actionList.add(ab.build());
3674
3675         // Create an Apply Action
3676         ApplyActionsBuilder aab = new ApplyActionsBuilder();
3677         aab.setAction(actionList);
3678
3679         // Wrap our Apply Action in an Instruction
3680         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3681
3682         return ib;
3683     }
3684
3685     /**
3686      * Create GOTO Table Instruction Builder
3687      *
3688      * @param ib      Map InstructionBuilder without any instructions
3689      * @param tableId short representing a flow table ID short representing a flow table ID
3690      * @return ib Map InstructionBuilder with instructions
3691      */
3692     protected static InstructionBuilder createGotoTableInstructions(InstructionBuilder ib, short tableId) {
3693
3694         GoToTableBuilder gttb = new GoToTableBuilder();
3695         gttb.setTableId(tableId);
3696
3697         // Wrap our Apply Action in an InstructionBuilder
3698         ib.setInstruction(new GoToTableCaseBuilder().setGoToTable(gttb.build()).build());
3699
3700         return ib;
3701     }
3702
3703     /**
3704      * Create Set Tunnel ID Instruction Builder
3705      *
3706      * @param ib       Map InstructionBuilder without any instructions
3707      * @param tunnelId BigInteger representing a tunnel ID
3708      * @return ib Map InstructionBuilder with instructions
3709      */
3710     protected static InstructionBuilder createSetTunnelIdInstructions(InstructionBuilder ib, BigInteger tunnelId) {
3711
3712         List<Action> actionList = new ArrayList<Action>();
3713         ActionBuilder ab = new ActionBuilder();
3714         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3715
3716         // Build the Set Tunnel Field Action
3717         TunnelBuilder tunnel = new TunnelBuilder();
3718         tunnel.setTunnelId(tunnelId);
3719         setFieldBuilder.setTunnel(tunnel.build());
3720         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3721         ab.setOrder(0);
3722         actionList.add(ab.build());
3723
3724         ApplyActionsBuilder aab = new ApplyActionsBuilder();
3725         aab.setAction(actionList);
3726
3727         // Wrap the Apply Action in an InstructionBuilder and return
3728         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3729
3730         return ib;
3731     }
3732
3733     /**
3734      * Create Set Source TCP Port Instruction
3735      *
3736      * @param ib      Map InstructionBuilder without any instructions
3737      * @param tcpport Integer representing a source TCP port
3738      * @return ib Map InstructionBuilder with instructions
3739      */
3740     protected static InstructionBuilder createSetSrcTCPPort(InstructionBuilder ib, PortNumber tcpport) {
3741
3742         List<Action> actionList = new ArrayList<Action>();
3743         ActionBuilder ab = new ActionBuilder();
3744         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3745
3746         // Build the Destination TCP Port
3747         PortNumber tcpsrcport = new PortNumber(tcpport);
3748         TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
3749         tcpmatch.setTcpSourcePort(tcpsrcport);
3750
3751         setFieldBuilder.setLayer4Match(tcpmatch.build());
3752         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3753         ab.setKey(new ActionKey(1));
3754         actionList.add(ab.build());
3755
3756         ApplyActionsBuilder aab = new ApplyActionsBuilder();
3757         aab.setAction(actionList);
3758         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3759
3760         return ib;
3761     }
3762
3763     /**
3764      * Create Set Destination TCP Port Instruction
3765      *
3766      * @param ib      Map InstructionBuilder without any instructions
3767      * @param tcpport Integer representing a source TCP port
3768      * @return ib Map InstructionBuilder with instructions
3769      */
3770     protected static InstructionBuilder createSetDstTCPPort(InstructionBuilder ib, PortNumber tcpport) {
3771
3772         List<Action> actionList = new ArrayList<Action>();
3773         ActionBuilder ab = new ActionBuilder();
3774         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3775
3776         // Build the Destination TCP Port
3777         PortNumber tcpdstport = new PortNumber(tcpport);
3778         TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
3779         tcpmatch.setTcpDestinationPort(tcpdstport);
3780
3781         setFieldBuilder.setLayer4Match(tcpmatch.build());
3782         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3783         ab.setKey(new ActionKey(1));
3784         actionList.add(ab.build());
3785
3786         ApplyActionsBuilder aab = new ApplyActionsBuilder();
3787         aab.setAction(actionList);
3788         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3789
3790         return ib;
3791     }
3792
3793     /**
3794      * Create Set Source UDP Port Instruction
3795      *
3796      * @param ib      Map InstructionBuilder without any instructions
3797      * @param udpport Integer representing a source UDP port
3798      * @return ib Map InstructionBuilder with instructions
3799      */
3800     protected static InstructionBuilder createSetSrcUDPPort(InstructionBuilder ib, PortNumber udpport) {
3801
3802         List<Action> actionList = new ArrayList<Action>();
3803         ActionBuilder ab = new ActionBuilder();
3804         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3805
3806         // Build the Destination TCP Port
3807         PortNumber udpsrcport = new PortNumber(udpport);
3808         UdpMatchBuilder udpmatch = new UdpMatchBuilder();
3809         udpmatch.setUdpSourcePort(udpsrcport);
3810
3811         setFieldBuilder.setLayer4Match(udpmatch.build());
3812         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3813         ab.setKey(new ActionKey(1));
3814         actionList.add(ab.build());
3815
3816         ApplyActionsBuilder aab = new ApplyActionsBuilder();
3817         aab.setAction(actionList);
3818         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3819
3820         return ib;
3821     }
3822
3823     /**
3824      * Create Set Destination UDP Port Instruction
3825      *
3826      * @param ib      Map InstructionBuilder without any instructions
3827      * @param udpport Integer representing a destination UDP port
3828      * @return ib Map InstructionBuilder with instructions
3829      */
3830     protected static InstructionBuilder createSetDstUDPPort(InstructionBuilder ib, PortNumber udpport) {
3831
3832         List<Action> actionList = new ArrayList<Action>();
3833         ActionBuilder ab = new ActionBuilder();
3834         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3835
3836         // Build the Destination TCP Port
3837         PortNumber udpdstport = new PortNumber(udpport);
3838         UdpMatchBuilder udpmatch = new UdpMatchBuilder();
3839         udpmatch.setUdpDestinationPort(udpdstport);
3840
3841         setFieldBuilder.setLayer4Match(udpmatch.build());
3842         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3843         ab.setKey(new ActionKey(1));
3844         actionList.add(ab.build());
3845
3846         ApplyActionsBuilder aab = new ApplyActionsBuilder();
3847         aab.setAction(actionList);
3848         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3849
3850         return ib;
3851     }
3852
3853     /**
3854      * Create Set ICMP Code Instruction
3855      *
3856      * @param ib   Map InstructionBuilder without any instructions
3857      * @param code short repesenting an ICMP code
3858      * @return ib Map InstructionBuilder with instructions
3859      */
3860
3861     private static InstructionBuilder createSetIcmpCodeInstruction(InstructionBuilder ib, short code) {
3862
3863         List<Action> actionList = new ArrayList<Action>();
3864         ActionBuilder ab = new ActionBuilder();
3865         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3866         Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
3867
3868         // Build the ICMPv4 Code Match
3869         icmpv4match.setIcmpv4Code(code);
3870         setFieldBuilder.setIcmpv4Match(icmpv4match.build());
3871
3872         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3873         ab.setKey(new ActionKey(0));
3874         actionList.add(ab.build());
3875         ApplyActionsBuilder aab = new ApplyActionsBuilder();
3876         aab.setAction(actionList);
3877
3878         // Wrap our Apply Action in an Instruction
3879         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3880
3881         return ib;
3882     }
3883
3884     /**
3885      * Create Set ICMP Code Instruction
3886      *
3887      * @param ib Map InstructionBuilder without any instructions
3888      * @return ib Map InstructionBuilder with instructions
3889      */
3890     private static InstructionBuilder createSetIcmpTypeInstruction(InstructionBuilder ib, short type) {
3891
3892         List<Action> actionList = new ArrayList<Action>();
3893         ActionBuilder ab = new ActionBuilder();
3894         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3895         Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
3896
3897         // Build the ICMPv4 Code Match
3898         icmpv4match.setIcmpv4Code(type);
3899         setFieldBuilder.setIcmpv4Match(icmpv4match.build());
3900
3901         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3902         ab.setKey(new ActionKey(1));
3903         actionList.add(ab.build());
3904         ApplyActionsBuilder aab = new ApplyActionsBuilder();
3905         aab.setAction(actionList);
3906
3907         // Wrap our Apply Action in an Instruction
3908         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3909
3910         return ib;
3911     }
3912
3913     /**
3914      * Create Decrement TTL Instruction
3915      *
3916      * @param ib Map InstructionBuilder without any instructions
3917      * @return ib Map InstructionBuilder with instructions
3918      */
3919     private static InstructionBuilder createDecNwTtlInstructions(InstructionBuilder ib) {
3920         DecNwTtlBuilder decNwTtlBuilder = new DecNwTtlBuilder();
3921         DecNwTtl decNwTtl = decNwTtlBuilder.build();
3922         ActionBuilder ab = new ActionBuilder();
3923         ab.setAction(new DecNwTtlCaseBuilder().setDecNwTtl(decNwTtl).build());
3924
3925         // Add our drop action to a list
3926         List<Action> actionList = new ArrayList<Action>();
3927         actionList.add(ab.build());
3928
3929         // Create an Apply Action
3930         ApplyActionsBuilder aab = new ApplyActionsBuilder();
3931         aab.setAction(actionList);
3932
3933         // Wrap our Apply Action in an Instruction
3934         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3935
3936         return ib;
3937     }
3938
3939     /**
3940      * Set Src Arp MAC
3941      */
3942     private static InstructionBuilder createSrcArpMacInstructions(InstructionBuilder ib, MacAddress macsrc) {
3943
3944         List<Action> actionList = new ArrayList<Action>();
3945         ActionBuilder ab = new ActionBuilder();
3946
3947         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3948         ArpMatchBuilder arpmatch = new ArpMatchBuilder();
3949         ArpSourceHardwareAddressBuilder arpsrc = new ArpSourceHardwareAddressBuilder();
3950         arpsrc.setAddress(macsrc);
3951         arpmatch.setArpSourceHardwareAddress(arpsrc.build());
3952         setFieldBuilder.setLayer3Match(arpmatch.build());
3953         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3954         ab.setKey(new ActionKey(0));
3955         actionList.add(ab.build());
3956
3957         ApplyActionsBuilder aab = new ApplyActionsBuilder();
3958         aab.setAction(actionList);
3959
3960         return ib;
3961     }
3962
3963     /**
3964      * Set Dst Arp MAC
3965      */
3966     private static InstructionBuilder createDstArpMacInstructions(InstructionBuilder ib, MacAddress macdst) {
3967
3968         List<Action> actionList = new ArrayList<Action>();
3969         ActionBuilder ab = new ActionBuilder();
3970         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3971
3972         ArpMatchBuilder arpmatch = new ArpMatchBuilder();
3973         ArpTargetHardwareAddressBuilder arpdst = new ArpTargetHardwareAddressBuilder();
3974         arpdst.setAddress(macdst);
3975         setFieldBuilder.setLayer3Match(arpmatch.build());
3976         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3977         ab.setKey(new ActionKey(0));
3978         actionList.add(ab.build());
3979
3980         ApplyActionsBuilder aab = new ApplyActionsBuilder();
3981         aab.setAction(actionList);
3982
3983         return ib;
3984     }
3985
3986     /**
3987      * Set Dst Arp IP
3988      */
3989     private static InstructionBuilder createDstArpIpInstructions(InstructionBuilder ib, Ipv4Prefix dstiparp) {
3990
3991         List<Action> actionList = new ArrayList<Action>();
3992         ActionBuilder ab = new ActionBuilder();
3993         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3994
3995         ArpMatchBuilder arpmatch = new ArpMatchBuilder();
3996         arpmatch.setArpTargetTransportAddress(dstiparp);
3997         setFieldBuilder.setLayer3Match(arpmatch.build());
3998         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3999         ab.setKey(new ActionKey(0));
4000         actionList.add(ab.build());
4001
4002         ApplyActionsBuilder aab = new ApplyActionsBuilder();
4003         aab.setAction(actionList);
4004
4005         return ib;
4006     }
4007
4008     /**
4009      * Set Src Arp IP
4010      */
4011     private static InstructionBuilder createSrcArpIpInstructions(InstructionBuilder ib, Ipv4Prefix srciparp) {
4012
4013         List<Action> actionList = new ArrayList<Action>();
4014         ActionBuilder ab = new ActionBuilder();
4015         SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
4016
4017         ArpMatchBuilder arpmatch = new ArpMatchBuilder();
4018         arpmatch.setArpSourceTransportAddress(srciparp);
4019         setFieldBuilder.setLayer3Match(arpmatch.build());
4020         ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
4021         ab.setKey(new ActionKey(0));
4022         actionList.add(ab.build());
4023
4024         ApplyActionsBuilder aab = new ApplyActionsBuilder();
4025         aab.setAction(actionList);
4026
4027         return ib;
4028     }
4029
4030     @Override
4031     public void initializeOFFlowRules(Node openflowNode) {
4032         IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
4033         List<Node> ovsNodes = connectionService.getNodes();
4034         if (ovsNodes == null) return;
4035         for (Node ovsNode : ovsNodes) {
4036             Long brIntDpid = this.getIntegrationBridgeOFDPID(ovsNode);
4037             Long brExDpid = this.getExternalBridgeDpid(ovsNode);
4038             logger.debug("Compare openflowNode to OVS node {} vs {} and {}", openflowNode.getID(), brIntDpid, brExDpid);
4039             String openflowID = openflowNode.getID().toString();
4040             if (openflowID.contains(brExDpid.toString())) {
4041                 this.initializeFlowRules(ovsNode, adminConfigManager.getExternalBridgeName());
4042                 this.triggerInterfaceUpdates(ovsNode);
4043             }
4044             if (openflowID.contains(brIntDpid.toString())) {
4045                 this.initializeFlowRules(ovsNode, adminConfigManager.getIntegrationBridgeName());
4046                 this.triggerInterfaceUpdates(ovsNode);
4047             }
4048         }
4049     }
4050
4051     private NodeBuilder createNodeBuilder(String nodeId) {
4052         NodeBuilder builder = new NodeBuilder();
4053         builder.setId(new NodeId(nodeId));
4054         builder.setKey(new NodeKey(builder.getId()));
4055         return builder;
4056     }
4057
4058     private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeBuilderToInstanceId(NodeBuilder
4059                                                                                                                                              node) {
4060         return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
4061                 node.getKey()).toInstance();
4062     }
4063
4064     private String getInternalBridgeUUID (Node node, String bridgeName) {
4065         try {
4066             OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
4067             Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
4068             if (bridgeTable == null) return null;
4069             for (String key : bridgeTable.keySet()) {
4070                 Bridge bridge = (Bridge)bridgeTable.get(key);
4071                 if (bridge.getName().equals(bridgeName)) return key;
4072             }
4073         } catch (Exception e) {
4074             logger.error("Error getting Bridge Identifier for {} / {}", node, bridgeName, e);
4075         }
4076         return null;
4077     }
4078 }