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