2 * Copyright (C) 2013 Red Hat, Inc.
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
8 * Authors : Madhu Venugopal, Brent Salisbury, Dave Tucker
10 package org.opendaylight.ovsdb.neutron.provider;
12 import java.math.BigInteger;
13 import java.net.InetAddress;
14 import java.util.ArrayList;
15 import java.util.List;
18 import java.util.concurrent.ExecutionException;
19 import java.util.concurrent.Future;
21 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
22 import org.opendaylight.controller.md.sal.common.api.data.DataModification;
23 import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
24 import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
25 import org.opendaylight.controller.sal.core.Node;
26 import org.opendaylight.controller.sal.utils.HexEncode;
27 import org.opendaylight.controller.sal.utils.ServiceHelper;
28 import org.opendaylight.controller.sal.utils.Status;
29 import org.opendaylight.controller.sal.utils.StatusCode;
30 import org.opendaylight.controller.switchmanager.ISwitchManager;
31 import org.opendaylight.ovsdb.lib.notation.OvsDBMap;
32 import org.opendaylight.ovsdb.lib.notation.OvsDBSet;
33 import org.opendaylight.ovsdb.lib.notation.UUID;
34 import org.opendaylight.ovsdb.lib.table.Bridge;
35 import org.opendaylight.ovsdb.lib.table.Interface;
36 import org.opendaylight.ovsdb.lib.table.Port;
37 import org.opendaylight.ovsdb.neutron.IAdminConfigManager;
38 import org.opendaylight.ovsdb.neutron.IInternalNetworkManager;
39 import org.opendaylight.ovsdb.neutron.IMDSALConsumer;
40 import org.opendaylight.ovsdb.neutron.NetworkHandler;
41 import org.opendaylight.ovsdb.neutron.ITenantNetworkManager;
42 import org.opendaylight.ovsdb.plugin.IConnectionServiceInternal;
43 import org.opendaylight.ovsdb.plugin.OVSDBConfigService;
44 import org.opendaylight.ovsdb.plugin.StatusWithUuid;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DecNwTtlCaseBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCase;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCaseBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCase;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCaseBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCaseBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionCaseBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwSrcActionCaseBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCaseBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCaseBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtl;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtlBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropAction;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropActionBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.group.action._case.GroupActionBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.vlan.action._case.PushVlanActionBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.dst.action._case.SetNwDstActionBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.src.action._case.SetNwSrcActionBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.vlan.id.action._case.SetVlanIdActionBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCaseBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTableBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.BucketId;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.BucketsBuilder;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.BucketBuilder;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.BucketKey;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.Buckets;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpSourceHardwareAddressBuilder;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpTargetHardwareAddressBuilder;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv4MatchBuilder;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
129 import org.opendaylight.yangtools.yang.binding.DataObject;
130 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
131 import org.opendaylight.yangtools.yang.common.RpcResult;
132 import org.slf4j.Logger;
133 import org.slf4j.LoggerFactory;
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;
147 private IAdminConfigManager adminConfigManager;
148 private IInternalNetworkManager internalNetworkManager;
149 private ITenantNetworkManager tenantNetworkManager;
151 public OF13Provider(IAdminConfigManager adminConfigManager,
152 IInternalNetworkManager internalNetworkManager,
153 ITenantNetworkManager tenantNetworkManager) {
154 this.adminConfigManager = adminConfigManager;
155 this.internalNetworkManager = internalNetworkManager;
156 this.tenantNetworkManager = tenantNetworkManager;
160 public boolean hasPerTenantTunneling() {
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);
171 if (!internalNetworkManager.isInternalNetworkNeutronReady(node)) {
172 logger.error(node+" is not Overlay ready");
173 return new Status(StatusCode.NOTACCEPTABLE, node+" is not Overlay ready");
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);
180 return new Status(StatusCode.SUCCESS);
183 private String getTunnelName(String tunnelType, InetAddress dst) {
184 return tunnelType+"-"+dst.getHostAddress();
187 private boolean isTunnelPresent(Node node, String tunnelName, String bridgeUUID) throws Exception {
188 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
189 Bridge bridge = (Bridge)ovsdbTable.getRow(node, Bridge.NAME.getName(), bridgeUUID);
190 if (bridge != null) {
191 Set<UUID> ports = bridge.getPorts();
192 for (UUID portUUID : ports) {
193 Port port = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), portUUID.toString());
194 if (port != null && port.getName().equalsIgnoreCase(tunnelName)) return true;
200 private String getPortUuid(Node node, String name, String bridgeUUID) throws Exception {
201 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
202 Bridge bridge = (Bridge)ovsdbTable.getRow(node, Bridge.NAME.getName(), bridgeUUID);
203 if (bridge != null) {
204 Set<UUID> ports = bridge.getPorts();
205 for (UUID portUUID : ports) {
206 Port port = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), portUUID.toString());
207 if (port != null && port.getName().equalsIgnoreCase(name)) return portUUID.toString();
213 private Status addTunnelPort (Node node, String tunnelType, InetAddress src, InetAddress dst) {
215 String bridgeUUID = null;
216 String tunnelBridgeName = adminConfigManager.getIntegrationBridgeName();
217 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
218 Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
219 if (bridgeTable != null) {
220 for (String uuid : bridgeTable.keySet()) {
221 Bridge bridge = (Bridge)bridgeTable.get(uuid);
222 if (bridge.getName().equals(tunnelBridgeName)) {
228 if (bridgeUUID == null) {
229 logger.error("Could not find Bridge {} in {}", tunnelBridgeName, node);
230 return new Status(StatusCode.NOTFOUND, "Could not find "+tunnelBridgeName+" in "+node);
232 String portName = getTunnelName(tunnelType, dst);
234 if (this.isTunnelPresent(node, portName, bridgeUUID)) {
235 logger.trace("Tunnel {} is present in {} of {}", portName, tunnelBridgeName, node);
236 return new Status(StatusCode.SUCCESS);
239 Port tunnelPort = new Port();
240 tunnelPort.setName(portName);
241 StatusWithUuid statusWithUuid = ovsdbTable.insertRow(node, Port.NAME.getName(), bridgeUUID, tunnelPort);
242 if (!statusWithUuid.isSuccess()) {
243 logger.error("Failed to insert Tunnel port {} in {}", portName, bridgeUUID);
244 return statusWithUuid;
247 String tunnelPortUUID = statusWithUuid.getUuid().toString();
248 String interfaceUUID = null;
250 while ((interfaceUUID == null) && (timeout > 0)) {
251 tunnelPort = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), tunnelPortUUID);
252 OvsDBSet<UUID> interfaces = tunnelPort.getInterfaces();
253 if (interfaces == null || interfaces.size() == 0) {
254 // Wait for the OVSDB update to sync up the Local cache.
259 interfaceUUID = interfaces.toArray()[0].toString();
260 Interface intf = (Interface)ovsdbTable.getRow(node, Interface.NAME.getName(), interfaceUUID);
261 if (intf == null) interfaceUUID = null;
264 if (interfaceUUID == null) {
265 logger.error("Cannot identify Tunnel Interface for port {}/{}", portName, tunnelPortUUID);
266 return new Status(StatusCode.INTERNALERROR);
269 Interface tunInterface = new Interface();
270 tunInterface.setType(tunnelType);
271 OvsDBMap<String, String> options = new OvsDBMap<String, String>();
272 options.put("key", "flow");
273 options.put("local_ip", src.getHostAddress());
274 options.put("remote_ip", dst.getHostAddress());
275 tunInterface.setOptions(options);
276 Status status = ovsdbTable.updateRow(node, Interface.NAME.getName(), tunnelPortUUID, interfaceUUID, tunInterface);
277 logger.debug("Tunnel {} add status : {}", tunInterface, status);
279 } catch (Exception e) {
280 logger.error("Exception in addTunnelPort", e);
281 return new Status(StatusCode.INTERNALERROR);
285 /* delete port from ovsdb port table */
286 private Status deletePort(Node node, String bridgeName, String portName) {
288 String bridgeUUID = null;
289 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
290 Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
291 if (bridgeTable != null) {
292 for (String uuid : bridgeTable.keySet()) {
293 Bridge bridge = (Bridge)bridgeTable.get(uuid);
294 if (bridge.getName().equals(bridgeName)) {
300 if (bridgeUUID == null) {
301 logger.debug("Could not find Bridge {} in {}", bridgeName, node);
302 return new Status(StatusCode.SUCCESS);
305 String portUUID = this.getPortUuid(node, portName, bridgeUUID);
306 Status status = new Status(StatusCode.SUCCESS);
307 if (portUUID != null) {
308 status = ovsdbTable.deleteRow(node, Port.NAME.getName(), portUUID);
309 if (!status.isSuccess()) {
310 logger.error("Failed to delete port {} in {} status : {}", portName, bridgeUUID,
314 logger.debug("Port {} delete status : {}", portName, status);
317 } catch (Exception e) {
318 logger.error("Exception in deletePort", e);
319 return new Status(StatusCode.INTERNALERROR);
323 private Status deleteTunnelPort(Node node, String tunnelType, InetAddress src, InetAddress dst) {
324 String tunnelBridgeName = adminConfigManager.getIntegrationBridgeName();
325 String portName = getTunnelName(tunnelType, dst);
326 Status status = deletePort(node, tunnelBridgeName, portName);
330 private Status deletePhysicalPort(Node node, String phyIntfName) {
331 String intBridgeName = adminConfigManager.getIntegrationBridgeName();
332 Status status = deletePort(node, intBridgeName, phyIntfName);
336 private void programLocalBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long localPort) {
340 * Match: VM sMac and Local Ingress Port
341 * Action:Action: Set Tunnel ID and GOTO Local Table (5)
344 handleLocalInPort(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_1_ISOLATE_TENANT, segmentationId, localPort, attachedMac, true);
349 * Match: Drop any remaining Ingress Local VM Packets
350 * Action: Drop w/ a low priority
353 handleDropSrcIface(dpid, localPort, true);
358 * Match: Match TunID and Destination DL/dMAC Addr
359 * Action: Output Port
360 * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
363 handleLocalUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, attachedMac, true);
368 * Match: Tunnel ID and dMAC (::::FF:FF)
369 * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
370 * actions=output:2,3,4,5
373 handleLocalBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, true);
376 * TODO : Optimize the following 2 writes to be restricted only for the very first port known in a segment.
381 * Match: Any remaining Ingress Local VM Packets
382 * Action: Drop w/ a low priority
383 * -------------------------------------------
384 * table=1,priority=8192,tun_id=0x5 actions=goto_table:2
387 handleTunnelMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, true);
392 * Match: Any Remaining Flows w/a TunID
393 * Action: Drop w/ a low priority
394 * table=2,priority=8192,tun_id=0x5 actions=drop
397 handleLocalTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, true);
400 private void removeLocalBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long localPort) {
404 * Match: VM sMac and Local Ingress Port
405 * Action:Action: Set Tunnel ID and GOTO Local Table (5)
408 handleLocalInPort(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_1_ISOLATE_TENANT, segmentationId, localPort, attachedMac, false);
413 * Match: Drop any remaining Ingress Local VM Packets
414 * Action: Drop w/ a low priority
417 handleDropSrcIface(dpid, localPort, false);
422 * Match: Match TunID and Destination DL/dMAC Addr
423 * Action: Output Port
424 * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
427 handleLocalUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, attachedMac, false);
432 * Match: Tunnel ID and dMAC (::::FF:FF)
433 * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
434 * actions=output:2,3,4,5
437 handleLocalBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, false);
440 private void programLocalIngressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
444 * Match: Ingress Port, Tunnel ID
445 * Action: GOTO Local Table (20)
448 handleTunnelIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, true);
453 * Match: Match Tunnel ID and L2 ::::FF:FF Flooding
454 * Action: Flood to selected destination TEPs
455 * -------------------------------------------
456 * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
457 * actions=output:10,output:11,goto_table:2
460 handleTunnelFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, true);
464 private void programRemoteEgressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
468 * Match: Drop any remaining Ingress Local VM Packets
469 * Action: Drop w/ a low priority
470 * -------------------------------------------
471 * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
472 * actions=output:11,goto_table:2
475 handleTunnelOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, attachedMac, true);
478 private void removeRemoteEgressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
482 * Match: Drop any remaining Ingress Local VM Packets
483 * Action: Drop w/ a low priority
484 * -------------------------------------------
485 * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
486 * actions=output:11,goto_table:2
489 handleTunnelOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, attachedMac, false);
492 /* Remove tunnel rules if last node in this tenant network */
493 private void removePerTunnelRules(Node node, Long dpid, String segmentationId, long tunnelOFPort) {
495 * TODO : Optimize the following 2 writes to be restricted only for the very first port known in a segment.
500 * Match: Any remaining Ingress Local VM Packets
501 * Action: Drop w/ a low priority
502 * -------------------------------------------
503 * table=1,priority=8192,tun_id=0x5 actions=goto_table:2
506 handleTunnelMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, false);
511 * Match: Any Remaining Flows w/a TunID
512 * Action: Drop w/ a low priority
513 * table=2,priority=8192,tun_id=0x5 actions=drop
516 handleLocalTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, false);
521 * Match: Ingress Port, Tunnel ID
522 * Action: GOTO Local Table (10)
525 handleTunnelIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, false);
530 * Match: Match Tunnel ID and L2 ::::FF:FF Flooding
531 * Action: Flood to selected destination TEPs
532 * -------------------------------------------
533 * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
534 * actions=output:10,output:11,goto_table:2
537 handleTunnelFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, false);
540 private void programLocalVlanRules(Node node, Long dpid, String segmentationId, String attachedMac, long localPort) {
544 * Match: VM sMac and Local Ingress Port
545 * Action: Set VLAN ID and GOTO Local Table 1
548 handleLocalInPortSetVlan(dpid, TABLE_0_DEFAULT_INGRESS,
549 TABLE_1_ISOLATE_TENANT, segmentationId, localPort,
555 * Match: Drop any remaining Ingress Local VM Packets
556 * Action: Drop w/ a low priority
559 handleDropSrcIface(dpid, localPort, true);
564 * Match: Match VLAN ID and Destination DL/dMAC Addr
565 * Action: strip vlan, output to local port
566 * Example: table=2,vlan_id=0x5,dl_dst=00:00:00:00:00:01 actions= strip vlan, output:2
569 handleLocalVlanUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
570 localPort, attachedMac, true);
575 * Match: VLAN ID and dMAC (::::FF:FF)
576 * Action: strip vlan, output to all local ports in this vlan
577 * Example: table=2,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
578 * actions= strip_vlan, output:2,3,4,5
581 handleLocalVlanBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
587 * Match: Any Remaining Flows w/a VLAN ID
588 * Action: Drop w/ a low priority
589 * Example: table=2,priority=8192,vlan_id=0x5 actions=drop
592 handleLocalVlanTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
596 private void removeLocalVlanRules(Node node, Long dpid,
597 String segmentationId, String attachedMac,
602 * Match: VM sMac and Local Ingress Port
603 * Action: Set VLAN ID and GOTO Local Table 1
606 handleLocalInPortSetVlan(dpid, TABLE_0_DEFAULT_INGRESS,
607 TABLE_1_ISOLATE_TENANT, segmentationId, localPort,
613 * Match: Drop any remaining Ingress Local VM Packets
614 * Action: Drop w/ a low priority
617 handleDropSrcIface(dpid, localPort, false);
622 * Match: Match VLAN ID and Destination DL/dMAC Addr
623 * Action: strip vlan, output to local port
624 * Example: table=2,vlan_id=0x5,dl_dst=00:00:00:00:00:01 actions= strip vlan, output:2
627 handleLocalVlanUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
628 localPort, attachedMac, false);
633 * Match: VLAN ID and dMAC (::::FF:FF)
634 * Action: strip vlan, output to all local ports in this vlan
635 * Example: table=2,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
636 * actions= strip_vlan, output:2,3,4,5
639 handleLocalVlanBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
643 private void programLocalIngressVlanRules(Node node, Long dpid, String segmentationId, String attachedMac, long ethPort) {
647 * Match: Ingress port = physical interface, Vlan ID
648 * Action: GOTO Local Table 2
651 handleVlanIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD,
652 segmentationId, ethPort, true);
657 * Match: Match VLAN ID and L2 ::::FF:FF Flooding
658 * Action: Flood to local and remote VLAN members
659 * -------------------------------------------
660 * Example: table=1,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
661 * actions=output:10 (eth port),goto_table:2
664 handleVlanFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
665 segmentationId, ethPort, true);
668 private void programRemoteEgressVlanRules(Node node, Long dpid, String segmentationId, String attachedMac, long ethPort) {
672 * Match: Destination MAC is local VM MAC and vlan id
673 * Action: go to table 2
674 * -------------------------------------------
675 * Example: table=1,vlan_id=0x5,dl_dst=00:00:00:00:00:08 \
676 * actions=goto_table:2
679 handleVlanOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
680 segmentationId, ethPort, attachedMac, true);
686 * Action: Go to table 2
687 * -------------------------------------------
688 * Example: table=1,priority=8192,vlan_id=0x5 actions=output:1,goto_table:2
691 handleVlanMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
692 segmentationId, ethPort, true);
695 private void removeRemoteEgressVlanRules(Node node, Long dpid, String segmentationId, String attachedMac, long ethPort) {
699 * Match: Destination MAC is local VM MAC and vlan id
700 * Action: go to table 2
701 * -------------------------------------------
702 * Example: table=1,vlan_id=0x5,dl_dst=00:00:00:00:00:08 \
703 * actions=goto_table:2
706 handleVlanOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
707 segmentationId, ethPort, attachedMac, false);
710 private void removePerVlanRules(Node node, Long dpid, String segmentationId, long ethPort) {
714 * Match: Any Remaining Flows w/a VLAN ID
715 * Action: Drop w/ a low priority
716 * Example: table=2,priority=8192,vlan_id=0x5 actions=drop
719 handleLocalVlanTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
725 * Match: Ingress port = physical interface, Vlan ID
726 * Action: GOTO Local Table 2
729 handleVlanIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD,
730 segmentationId, ethPort, false);
735 * Match: Match VLAN ID and L2 ::::FF:FF Flooding
736 * Action: Flood to local and remote VLAN members
737 * -------------------------------------------
738 * Example: table=1,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
739 * actions=output:10 (eth port),goto_table:2
742 handleVlanFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
743 segmentationId, ethPort, false);
749 * Action: Go to table 2
750 * -------------------------------------------
751 * Example: table=1,priority=8192,vlan_id=0x5 actions=output:1,goto_table:2
754 handleVlanMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
755 segmentationId, ethPort, false);
757 private Long getDpid (Node node, String bridgeUuid) {
759 OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
760 Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), bridgeUuid);
761 Set<String> dpids = bridge.getDatapath_id();
762 if (dpids == null || dpids.size() == 0) return 0L;
763 return Long.valueOf(HexEncode.stringToLong((String) dpids.toArray()[0]));
764 } catch (Exception e) {
765 logger.error("Error finding Bridge's OF DPID", e);
770 private Long getIntegrationBridgeOFDPID (Node node) {
772 String bridgeName = adminConfigManager.getIntegrationBridgeName();
773 String brIntId = this.getInternalBridgeUUID(node, bridgeName);
774 if (brIntId == null) {
775 logger.error("Unable to spot Bridge Identifier for {} in {}", bridgeName, node);
779 return getDpid(node, brIntId);
780 } catch (Exception e) {
781 logger.error("Error finding Integration Bridge's OF DPID", e);
786 private Long getExternalBridgeDpid (Node node) {
788 String bridgeName = adminConfigManager.getExternalBridgeName();
789 String brUuid = this.getInternalBridgeUUID(node, bridgeName);
790 if (brUuid == null) {
791 logger.error("Unable to spot Bridge Identifier for {} in {}", bridgeName, node);
795 return getDpid(node, brUuid);
796 } catch (Exception e) {
797 logger.error("Error finding External Bridge's OF DPID", e);
802 private void programLocalRules (String networkType, String segmentationId, Node node, Interface intf) {
804 Long dpid = this.getIntegrationBridgeOFDPID(node);
806 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
810 Set<BigInteger> of_ports = intf.getOfport();
811 if (of_ports == null || of_ports.size() <= 0) {
812 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
815 long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
817 Map<String, String> externalIds = intf.getExternal_ids();
818 if (externalIds == null) {
819 logger.error("No external_ids seen in {}", intf);
823 String attachedMac = externalIds.get(ITenantNetworkManager.EXTERNAL_ID_VM_MAC);
824 if (attachedMac == null) {
825 logger.error("No AttachedMac seen in {}", intf);
829 /* Program local rules based on network type */
830 if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
831 logger.debug("Program local vlan rules for interface {}", intf.getName());
832 programLocalVlanRules(node, dpid, segmentationId, attachedMac, localPort);
833 } else if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) ||
834 networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) {
835 logger.debug("Program local bridge rules for interface {}", intf.getName());
836 programLocalBridgeRules(node, dpid, segmentationId, attachedMac, localPort);
838 } catch (Exception e) {
839 logger.error("Exception in programming Local Rules for "+intf+" on "+node, e);
843 private void removeLocalRules (String networkType, String segmentationId, Node node, Interface intf) {
845 Long dpid = this.getIntegrationBridgeOFDPID(node);
847 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
851 Set<BigInteger> of_ports = intf.getOfport();
852 if (of_ports == null || of_ports.size() <= 0) {
853 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
856 long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
858 Map<String, String> externalIds = intf.getExternal_ids();
859 if (externalIds == null) {
860 logger.error("No external_ids seen in {}", intf);
864 String attachedMac = externalIds.get(ITenantNetworkManager.EXTERNAL_ID_VM_MAC);
865 if (attachedMac == null) {
866 logger.error("No AttachedMac seen in {}", intf);
870 /* Program local rules based on network type */
871 if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
872 logger.debug("Remove local vlan rules for interface {}", intf.getName());
873 removeLocalVlanRules(node, dpid, segmentationId, attachedMac, localPort);
874 } else if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) ||
875 networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) {
876 logger.debug("Remove local bridge rules for interface {}", intf.getName());
877 removeLocalBridgeRules(node, dpid, segmentationId, attachedMac, localPort);
879 } catch (Exception e) {
880 logger.error("Exception in removing Local Rules for "+intf+" on "+node, e);
884 private void programTunnelRules (String tunnelType, String segmentationId, InetAddress dst, Node node,
885 Interface intf, boolean local) {
888 Long dpid = this.getIntegrationBridgeOFDPID(node);
890 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
893 OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
895 Set<BigInteger> of_ports = intf.getOfport();
896 if (of_ports == null || of_ports.size() <= 0) {
897 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
900 long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
902 Map<String, String> externalIds = intf.getExternal_ids();
903 if (externalIds == null) {
904 logger.error("No external_ids seen in {}", intf);
908 String attachedMac = externalIds.get(ITenantNetworkManager.EXTERNAL_ID_VM_MAC);
909 if (attachedMac == null) {
910 logger.error("No AttachedMac seen in {}", intf);
914 Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
916 for (org.opendaylight.ovsdb.lib.table.Table<?> row : intfs.values()) {
917 Interface tunIntf = (Interface)row;
918 if (tunIntf.getName().equals(this.getTunnelName(tunnelType, dst))) {
919 of_ports = tunIntf.getOfport();
920 if (of_ports == null || of_ports.size() <= 0) {
921 logger.error("Could NOT Identify Tunnel port {} on {}", tunIntf.getName(), node);
924 long tunnelOFPort = ((BigInteger)of_ports.toArray()[0]).longValue();
926 if (tunnelOFPort == -1) {
927 logger.error("Could NOT Identify Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
930 logger.debug("Identified Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
933 programRemoteEgressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
935 logger.trace("program local ingress tunnel rules: node" + node.getNodeIDString() + " intf " + intf.getName());
937 programLocalIngressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
943 } catch (Exception e) {
948 private void removeTunnelRules (String tunnelType, String segmentationId, InetAddress dst, Node node,
949 Interface intf, boolean local, boolean isLastInstanceOnNode) {
952 Long dpid = this.getIntegrationBridgeOFDPID(node);
954 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
957 OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
959 Set<BigInteger> of_ports = intf.getOfport();
960 if (of_ports == null || of_ports.size() <= 0) {
961 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
964 long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
966 Map<String, String> externalIds = intf.getExternal_ids();
967 if (externalIds == null) {
968 logger.error("No external_ids seen in {}", intf);
972 String attachedMac = externalIds.get(ITenantNetworkManager.EXTERNAL_ID_VM_MAC);
973 if (attachedMac == null) {
974 logger.error("No AttachedMac seen in {}", intf);
978 Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
980 for (org.opendaylight.ovsdb.lib.table.Table<?> row : intfs.values()) {
981 Interface tunIntf = (Interface)row;
982 if (tunIntf.getName().equals(this.getTunnelName(tunnelType, dst))) {
983 of_ports = tunIntf.getOfport();
984 if (of_ports == null || of_ports.size() <= 0) {
985 logger.error("Could NOT Identify Tunnel port {} on {}", tunIntf.getName(), node);
988 long tunnelOFPort = ((BigInteger)of_ports.toArray()[0]).longValue();
990 if (tunnelOFPort == -1) {
991 logger.error("Could NOT Identify Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
994 logger.debug("Identified Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
997 removeRemoteEgressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
999 if (local && isLastInstanceOnNode) {
1000 removePerTunnelRules(node, dpid, segmentationId, tunnelOFPort);
1006 } catch (Exception e) {
1007 logger.error("", e);
1011 private void programVlanRules (NeutronNetwork network, Node node, Interface intf) {
1012 logger.debug("Program vlan rules for interface {}", intf.getName());
1016 Long dpid = this.getIntegrationBridgeOFDPID(node);
1018 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
1021 OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
1023 Set<BigInteger> of_ports = intf.getOfport();
1025 while ((of_ports == null) && (timeout > 0)) {
1026 of_ports = intf.getOfport();
1027 if (of_ports == null || of_ports.size() <= 0) {
1028 // Wait for the OVSDB update to sync up the Local cache.
1034 if (of_ports == null || of_ports.size() <= 0) {
1035 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
1039 Map<String, String> externalIds = intf.getExternal_ids();
1040 if (externalIds == null) {
1041 logger.error("No external_ids seen in {}", intf);
1045 String attachedMac = externalIds.get(tenantNetworkManager.EXTERNAL_ID_VM_MAC);
1046 if (attachedMac == null) {
1047 logger.error("No AttachedMac seen in {}", intf);
1051 Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
1052 if (intfs != null) {
1053 for (org.opendaylight.ovsdb.lib.table.Table<?> row : intfs.values()) {
1054 Interface ethIntf = (Interface)row;
1055 if (ethIntf.getName().equalsIgnoreCase(adminConfigManager.getPhysicalInterfaceName(node, network.getProviderPhysicalNetwork()))) {
1056 of_ports = ethIntf.getOfport();
1058 while ((of_ports == null) && (timeout > 0)) {
1059 of_ports = ethIntf.getOfport();
1060 if (of_ports == null || of_ports.size() <= 0) {
1061 // Wait for the OVSDB update to sync up the Local cache.
1068 if (of_ports == null || of_ports.size() <= 0) {
1069 logger.error("Could NOT Identify eth port {} on {}", ethIntf.getName(), node);
1072 long ethOFPort = ((BigInteger)of_ports.toArray()[0]).longValue();
1074 if (ethOFPort == -1) {
1075 logger.error("Could NOT Identify eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node);
1076 throw new Exception("port number < 0");
1078 logger.debug("Identified eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node);
1080 programRemoteEgressVlanRules(node, dpid, network.getProviderSegmentationID(), attachedMac, ethOFPort);
1081 programLocalIngressVlanRules(node, dpid, network.getProviderSegmentationID(), attachedMac, ethOFPort);
1086 } catch (Exception e) {
1087 logger.error("", e);
1091 private void removeVlanRules (NeutronNetwork network, Node node,
1092 Interface intf, boolean isLastInstanceOnNode) {
1093 logger.debug("Remove vlan rules for interface {}", intf.getName());
1097 Long dpid = this.getIntegrationBridgeOFDPID(node);
1099 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
1102 OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
1104 Set<BigInteger> of_ports = intf.getOfport();
1105 if (of_ports == null || of_ports.size() <= 0) {
1106 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
1110 Map<String, String> externalIds = intf.getExternal_ids();
1111 if (externalIds == null) {
1112 logger.error("No external_ids seen in {}", intf);
1116 String attachedMac = externalIds.get(tenantNetworkManager.EXTERNAL_ID_VM_MAC);
1117 if (attachedMac == null) {
1118 logger.error("No AttachedMac seen in {}", intf);
1122 Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
1123 if (intfs != null) {
1124 for (org.opendaylight.ovsdb.lib.table.Table<?> row : intfs.values()) {
1125 Interface ethIntf = (Interface)row;
1126 if (ethIntf.getName().equalsIgnoreCase(adminConfigManager.getPhysicalInterfaceName(node,
1127 network.getProviderPhysicalNetwork()))) {
1128 of_ports = ethIntf.getOfport();
1129 if (of_ports == null || of_ports.size() <= 0) {
1130 logger.error("Could NOT Identify eth port {} on {}", ethIntf.getName(), node);
1133 long ethOFPort = ((BigInteger)of_ports.toArray()[0]).longValue();
1135 if (ethOFPort == -1) {
1136 logger.error("Could NOT Identify eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node);
1137 throw new Exception("port number < 0");
1139 logger.debug("Identified eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node);
1141 removeRemoteEgressVlanRules(node, dpid, network.getProviderSegmentationID(), attachedMac, ethOFPort);
1142 if (isLastInstanceOnNode) {
1143 removePerVlanRules(node, dpid, network.getProviderSegmentationID(), ethOFPort);
1149 } catch (Exception e) {
1150 logger.error("", e);
1155 public Status handleInterfaceUpdate(NeutronNetwork network, Node srcNode, Interface intf) {
1156 ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, "default", this);
1157 if (switchManager == null) {
1158 logger.error("Unable to identify SwitchManager");
1160 Long dpid = this.getIntegrationBridgeOFDPID(srcNode);
1162 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", srcNode);
1163 return new Status(StatusCode.NOTFOUND);
1165 Set<Node> ofNodes = switchManager.getNodes();
1166 boolean ofNodeFound = false;
1167 if (ofNodes != null) {
1168 for (Node ofNode : ofNodes) {
1169 if (ofNode.toString().contains(dpid+"")) {
1170 logger.debug("Identified the Openflow node via toString {}", ofNode);
1176 logger.error("Unable to find any Node from SwitchManager");
1179 logger.error("Unable to find OF Node for {} with update {} on node {}", dpid, intf, srcNode);
1180 return new Status(StatusCode.NOTFOUND);
1184 IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
1185 List<Node> nodes = connectionService.getNodes();
1186 nodes.remove(srcNode);
1187 this.programLocalRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), srcNode, intf);
1189 if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
1190 this.programVlanRules(network, srcNode, intf);
1191 } else if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)
1192 || network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)){
1193 for (Node dstNode : nodes) {
1194 InetAddress src = adminConfigManager.getTunnelEndPoint(srcNode);
1195 InetAddress dst = adminConfigManager.getTunnelEndPoint(dstNode);
1196 Status status = addTunnelPort(srcNode, network.getProviderNetworkType(), src, dst);
1197 if (status.isSuccess()) {
1198 this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), dst, srcNode, intf, true);
1200 addTunnelPort(dstNode, network.getProviderNetworkType(), dst, src);
1201 if (status.isSuccess()) {
1202 this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), src, dstNode, intf, false);
1207 return new Status(StatusCode.SUCCESS);
1210 private Status triggerInterfaceUpdates(Node node) {
1212 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
1213 Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
1214 if (intfs != null) {
1215 for (org.opendaylight.ovsdb.lib.table.Table<?> row : intfs.values()) {
1216 Interface intf = (Interface)row;
1217 NeutronNetwork network = tenantNetworkManager.getTenantNetworkForInterface(intf);
1218 logger.debug("Trigger Interface update for {}", intf);
1219 if (network != null) {
1220 this.handleInterfaceUpdate(network, node, intf);
1224 } catch (Exception e) {
1225 logger.error("Error Triggering the lost interface updates for "+ node, e);
1226 return new Status(StatusCode.INTERNALERROR, e.getLocalizedMessage());
1228 return new Status(StatusCode.SUCCESS);
1231 public Status handleInterfaceUpdate(String tunnelType, String tunnelKey) {
1232 // TODO Auto-generated method stub
1237 public Status handleInterfaceDelete(String tunnelType, NeutronNetwork network, Node srcNode, Interface intf,
1238 boolean isLastInstanceOnNode) {
1239 Status status = new Status(StatusCode.SUCCESS);
1240 IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
1241 List<Node> nodes = connectionService.getNodes();
1242 nodes.remove(srcNode);
1244 logger.info("Delete intf " + intf.getName() + " isLastInstanceOnNode " + isLastInstanceOnNode);
1245 List<String> phyIfName = adminConfigManager.getAllPhysicalInterfaceNames(srcNode);
1246 if (intf.getType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)
1247 || intf.getType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)) {
1248 /* Delete tunnel port */
1250 OvsDBMap<String, String> options = intf.getOptions();
1251 InetAddress src = InetAddress.getByName(options.get("local_ip"));
1252 InetAddress dst = InetAddress.getByName(options.get("remote_ip"));
1253 status = deleteTunnelPort(srcNode, intf.getType(), src, dst);
1254 } catch (Exception e) {
1255 logger.error(e.getMessage(), e);
1257 } else if (phyIfName.contains(intf.getName())) {
1258 deletePhysicalPort(srcNode, intf.getName());
1260 /* delete all other interfaces */
1261 this.removeLocalRules(network.getProviderNetworkType(), network.getProviderSegmentationID(),
1264 if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
1265 this.removeVlanRules(network, srcNode,
1266 intf, isLastInstanceOnNode);
1267 } else if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)
1268 || network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) {
1270 for (Node dstNode : nodes) {
1271 InetAddress src = adminConfigManager.getTunnelEndPoint(srcNode);
1272 InetAddress dst = adminConfigManager.getTunnelEndPoint(dstNode);
1273 logger.info("Remove tunnel rules for interface " + intf.getName() + " on srcNode" + srcNode.getNodeIDString());
1274 this.removeTunnelRules(tunnelType, network.getProviderSegmentationID(),
1275 dst, srcNode, intf, true, isLastInstanceOnNode);
1276 logger.info("Remove tunnel rules for interface " + intf.getName() + " on dstNode" + dstNode.getNodeIDString());
1277 this.removeTunnelRules(tunnelType, network.getProviderSegmentationID(),
1278 src, dstNode, intf, false, isLastInstanceOnNode);
1286 public void initializeFlowRules(Node node) {
1287 this.initializeFlowRules(node, adminConfigManager.getIntegrationBridgeName());
1288 this.initializeFlowRules(node, adminConfigManager.getExternalBridgeName());
1289 this.triggerInterfaceUpdates(node);
1296 private void initializeFlowRules(Node node, String bridgeName) {
1297 String bridgeUuid = this.getInternalBridgeUUID(node, bridgeName);
1298 if (bridgeUuid == null) {
1302 Long dpid = getDpid(node, bridgeUuid);
1305 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
1312 * Match: LLDP (0x88CCL)
1313 * Action: Packet_In to Controller Reserved Port
1316 writeLLDPRule(dpid);
1317 if (bridgeName == adminConfigManager.getExternalBridgeName()) {
1318 writeNormalRule(dpid);
1323 * Create an LLDP Flow Rule to encapsulate into
1324 * a packet_in that is sent to the controller
1325 * for topology handling.
1326 * Match: Ethertype 0x88CCL
1327 * Action: Punt to Controller in a Packet_In msg
1330 private void writeLLDPRule(Long dpidLong) {
1332 String nodeName = "openflow:" + dpidLong;
1333 EtherType etherType = new EtherType(0x88CCL);
1335 MatchBuilder matchBuilder = new MatchBuilder();
1336 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1337 FlowBuilder flowBuilder = new FlowBuilder();
1339 // Create Match(es) and Set them in the FlowBuilder Object
1340 flowBuilder.setMatch(createEtherTypeMatch(matchBuilder, etherType).build());
1342 // Create the OF Actions and Instructions
1343 InstructionBuilder ib = new InstructionBuilder();
1344 InstructionsBuilder isb = new InstructionsBuilder();
1346 // Instructions List Stores Individual Instructions
1347 List<Instruction> instructions = new ArrayList<Instruction>();
1349 // Call the InstructionBuilder Methods Containing Actions
1350 createSendToControllerInstructions(ib);
1352 ib.setKey(new InstructionKey(0));
1353 instructions.add(ib.build());
1355 // Add InstructionBuilder to the Instruction(s)Builder List
1356 isb.setInstruction(instructions);
1358 // Add InstructionsBuilder to FlowBuilder
1359 flowBuilder.setInstructions(isb.build());
1361 String flowId = "LLDP";
1362 flowBuilder.setId(new FlowId(flowId));
1363 FlowKey key = new FlowKey(new FlowId(flowId));
1364 flowBuilder.setBarrier(true);
1365 flowBuilder.setTableId((short) 0);
1366 flowBuilder.setKey(key);
1367 flowBuilder.setFlowName(flowId);
1368 flowBuilder.setHardTimeout(0);
1369 flowBuilder.setIdleTimeout(0);
1370 writeFlow(flowBuilder, nodeBuilder);
1374 * Create a NORMAL Table Miss Flow Rule
1376 * Action: forward to NORMAL pipeline
1379 private void writeNormalRule(Long dpidLong) {
1381 String nodeName = "openflow:" + dpidLong;
1383 MatchBuilder matchBuilder = new MatchBuilder();
1384 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1385 FlowBuilder flowBuilder = new FlowBuilder();
1387 // Create the OF Actions and Instructions
1388 InstructionBuilder ib = new InstructionBuilder();
1389 InstructionsBuilder isb = new InstructionsBuilder();
1391 // Instructions List Stores Individual Instructions
1392 List<Instruction> instructions = new ArrayList<Instruction>();
1394 // Call the InstructionBuilder Methods Containing Actions
1395 createNormalInstructions(ib);
1397 ib.setKey(new InstructionKey(0));
1398 instructions.add(ib.build());
1400 // Add InstructionBuilder to the Instruction(s)Builder List
1401 isb.setInstruction(instructions);
1403 // Add InstructionsBuilder to FlowBuilder
1404 flowBuilder.setInstructions(isb.build());
1406 String flowId = "NORMAL";
1407 flowBuilder.setId(new FlowId(flowId));
1408 FlowKey key = new FlowKey(new FlowId(flowId));
1409 flowBuilder.setMatch(matchBuilder.build());
1410 flowBuilder.setPriority(0);
1411 flowBuilder.setBarrier(true);
1412 flowBuilder.setTableId((short) 0);
1413 flowBuilder.setKey(key);
1414 flowBuilder.setFlowName(flowId);
1415 flowBuilder.setHardTimeout(0);
1416 flowBuilder.setIdleTimeout(0);
1417 writeFlow(flowBuilder, nodeBuilder);
1421 * (Table:0) Ingress Tunnel Traffic
1422 * Match: OpenFlow InPort and Tunnel ID
1423 * Action: GOTO Local Table (10)
1424 * table=0,tun_id=0x5,in_port=10, actions=goto_table:2
1427 private void handleTunnelIn(Long dpidLong, Short writeTable,
1428 Short goToTableId, String segmentationId,
1429 Long ofPort, boolean write) {
1431 String nodeName = "openflow:" + dpidLong;
1433 BigInteger tunnelId = new BigInteger(segmentationId);
1434 MatchBuilder matchBuilder = new MatchBuilder();
1435 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1436 FlowBuilder flowBuilder = new FlowBuilder();
1438 // Create Match(es) and Set them in the FlowBuilder Object
1439 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, tunnelId).build());
1440 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, ofPort).build());
1443 // Create the OF Actions and Instructions
1444 InstructionBuilder ib = new InstructionBuilder();
1445 InstructionsBuilder isb = new InstructionsBuilder();
1447 // Instructions List Stores Individual Instructions
1448 List<Instruction> instructions = new ArrayList<Instruction>();
1450 // Call the InstructionBuilder Methods Containing Actions
1451 createGotoTableInstructions(ib, goToTableId);
1453 ib.setKey(new InstructionKey(0));
1454 instructions.add(ib.build());
1456 // Add InstructionBuilder to the Instruction(s)Builder List
1457 isb.setInstruction(instructions);
1459 // Add InstructionsBuilder to FlowBuilder
1460 flowBuilder.setInstructions(isb.build());
1463 String flowId = "TunnelIn_"+segmentationId+"_"+ofPort;
1464 // Add Flow Attributes
1465 flowBuilder.setId(new FlowId(flowId));
1466 FlowKey key = new FlowKey(new FlowId(flowId));
1467 flowBuilder.setStrict(true);
1468 flowBuilder.setBarrier(false);
1469 flowBuilder.setTableId(writeTable);
1470 flowBuilder.setKey(key);
1471 flowBuilder.setFlowName(flowId);
1472 flowBuilder.setHardTimeout(0);
1473 flowBuilder.setIdleTimeout(0);
1476 writeFlow(flowBuilder, nodeBuilder);
1478 removeFlow(flowBuilder, nodeBuilder);
1483 * (Table:0) Ingress VLAN Traffic
1484 * Match: OpenFlow InPort and vlan ID
1485 * Action: GOTO Local Table (20)
1486 * table=0,vlan_id=0x5,in_port=10, actions=goto_table:2
1489 private void handleVlanIn(Long dpidLong, Short writeTable, Short goToTableId,
1490 String segmentationId, Long ethPort, boolean write) {
1492 String nodeName = "openflow:" + dpidLong;
1494 MatchBuilder matchBuilder = new MatchBuilder();
1495 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1496 FlowBuilder flowBuilder = new FlowBuilder();
1498 // Create Match(es) and Set them in the FlowBuilder Object
1499 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
1500 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, ethPort).build());
1503 // Create the OF Actions and Instructions
1504 InstructionBuilder ib = new InstructionBuilder();
1505 InstructionsBuilder isb = new InstructionsBuilder();
1507 // Instructions List Stores Individual Instructions
1508 List<Instruction> instructions = new ArrayList<Instruction>();
1510 // Call the InstructionBuilder Methods Containing Actions
1511 createGotoTableInstructions(ib, goToTableId);
1513 ib.setKey(new InstructionKey(0));
1514 instructions.add(ib.build());
1516 // Add InstructionBuilder to the Instruction(s)Builder List
1517 isb.setInstruction(instructions);
1519 // Add InstructionsBuilder to FlowBuilder
1520 flowBuilder.setInstructions(isb.build());
1523 String flowId = "VlanIn_"+segmentationId+"_"+ethPort;
1524 // Add Flow Attributes
1525 flowBuilder.setId(new FlowId(flowId));
1526 FlowKey key = new FlowKey(new FlowId(flowId));
1527 flowBuilder.setStrict(true);
1528 flowBuilder.setBarrier(false);
1529 flowBuilder.setTableId(writeTable);
1530 flowBuilder.setKey(key);
1531 flowBuilder.setFlowName(flowId);
1532 flowBuilder.setHardTimeout(0);
1533 flowBuilder.setIdleTimeout(0);
1535 writeFlow(flowBuilder, nodeBuilder);
1537 removeFlow(flowBuilder, nodeBuilder);
1542 * (Table:0) Egress VM Traffic Towards TEP
1543 * Match: Destination Ethernet Addr and OpenFlow InPort
1544 * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
1545 * table=0,in_port=2,dl_src=00:00:00:00:00:01 \
1546 * actions=set_field:5->tun_id,goto_table=1"
1549 private void handleLocalInPort(Long dpidLong, Short writeTable, Short goToTableId,
1550 String segmentationId, Long inPort, String attachedMac,
1553 String nodeName = "openflow:" + dpidLong;
1555 MatchBuilder matchBuilder = new MatchBuilder();
1556 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1557 FlowBuilder flowBuilder = new FlowBuilder();
1559 // Create the OF Match using MatchBuilder
1560 flowBuilder.setMatch(createEthSrcMatch(matchBuilder, new MacAddress(attachedMac)).build());
1561 // TODO Broken In_Port Match
1562 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
1564 String flowId = "LocalMac_"+segmentationId+"_"+inPort+"_"+attachedMac;
1565 // Add Flow Attributes
1566 flowBuilder.setId(new FlowId(flowId));
1567 FlowKey key = new FlowKey(new FlowId(flowId));
1568 flowBuilder.setStrict(true);
1569 flowBuilder.setBarrier(false);
1570 flowBuilder.setTableId(writeTable);
1571 flowBuilder.setKey(key);
1572 flowBuilder.setFlowName(flowId);
1573 flowBuilder.setHardTimeout(0);
1574 flowBuilder.setIdleTimeout(0);
1577 // Instantiate the Builders for the OF Actions and Instructions
1578 InstructionBuilder ib = new InstructionBuilder();
1579 InstructionsBuilder isb = new InstructionsBuilder();
1581 // Instructions List Stores Individual Instructions
1582 List<Instruction> instructions = new ArrayList<Instruction>();
1584 // GOTO Instuctions Need to be added first to the List
1585 createGotoTableInstructions(ib, goToTableId);
1587 ib.setKey(new InstructionKey(0));
1588 instructions.add(ib.build());
1589 // TODO Broken SetTunID
1590 createSetTunnelIdInstructions(ib, new BigInteger(segmentationId));
1592 ib.setKey(new InstructionKey(1));
1593 instructions.add(ib.build());
1595 // Add InstructionBuilder to the Instruction(s)Builder List
1596 isb.setInstruction(instructions);
1598 // Add InstructionsBuilder to FlowBuilder
1599 flowBuilder.setInstructions(isb.build());
1601 writeFlow(flowBuilder, nodeBuilder);
1603 removeFlow(flowBuilder, nodeBuilder);
1608 * (Table:0) Egress VM Traffic Towards TEP
1609 * Match: Source Ethernet Addr and OpenFlow InPort
1610 * Instruction: Set VLANID and GOTO Table Egress (n)
1611 * table=0,in_port=2,dl_src=00:00:00:00:00:01 \
1612 * actions=push_vlan, set_field:5->vlan_id,goto_table=1"
1615 private void handleLocalInPortSetVlan(Long dpidLong, Short writeTable,
1616 Short goToTableId, String segmentationId,
1617 Long inPort, String attachedMac,
1620 String nodeName = "openflow:" + dpidLong;
1622 MatchBuilder matchBuilder = new MatchBuilder();
1623 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1624 FlowBuilder flowBuilder = new FlowBuilder();
1626 // Create the OF Match using MatchBuilder
1627 flowBuilder.setMatch(createEthSrcMatch(matchBuilder, new MacAddress(attachedMac)).build());
1628 // TODO Broken In_Port Match
1629 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
1631 String flowId = "LocalMac_"+segmentationId+"_"+inPort+"_"+attachedMac;
1632 // Add Flow Attributes
1633 flowBuilder.setId(new FlowId(flowId));
1634 FlowKey key = new FlowKey(new FlowId(flowId));
1635 flowBuilder.setStrict(true);
1636 flowBuilder.setBarrier(false);
1637 flowBuilder.setTableId(writeTable);
1638 flowBuilder.setKey(key);
1639 flowBuilder.setFlowName(flowId);
1640 flowBuilder.setHardTimeout(0);
1641 flowBuilder.setIdleTimeout(0);
1644 // Instantiate the Builders for the OF Actions and Instructions
1645 InstructionBuilder ib = new InstructionBuilder();
1646 InstructionsBuilder isb = new InstructionsBuilder();
1648 // Instructions List Stores Individual Instructions
1649 List<Instruction> instructions = new ArrayList<Instruction>();
1651 // GOTO Instructions Need to be added first to the List
1652 createGotoTableInstructions(ib, goToTableId);
1654 ib.setKey(new InstructionKey(0));
1655 instructions.add(ib.build());
1656 // Set VLAN ID Instruction
1657 createSetVlanInstructions(ib, new VlanId(Integer.valueOf(segmentationId)));
1659 ib.setKey(new InstructionKey(1));
1660 instructions.add(ib.build());
1662 // Add InstructionBuilder to the Instruction(s)Builder List
1663 isb.setInstruction(instructions);
1665 // Add InstructionsBuilder to FlowBuilder
1666 flowBuilder.setInstructions(isb.build());
1668 writeFlow(flowBuilder, nodeBuilder);
1670 removeFlow(flowBuilder, nodeBuilder);
1675 * (Table:0) Drop frames source from a VM that do not
1676 * match the associated MAC address of the local VM.
1677 * Match: Low priority anything not matching the VM SMAC
1679 * table=0,priority=16384,in_port=1 actions=drop"
1682 private void handleDropSrcIface(Long dpidLong, Long inPort, boolean write) {
1684 String nodeName = "openflow:" + dpidLong;
1686 MatchBuilder matchBuilder = new MatchBuilder();
1687 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1688 FlowBuilder flowBuilder = new FlowBuilder();
1690 // Create the OF Match using MatchBuilder
1691 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
1694 // Instantiate the Builders for the OF Actions and Instructions
1695 InstructionBuilder ib = new InstructionBuilder();
1696 InstructionsBuilder isb = new InstructionsBuilder();
1698 // Instructions List Stores Individual Instructions
1699 List<Instruction> instructions = new ArrayList<Instruction>();
1701 // Call the InstructionBuilder Methods Containing Actions
1702 createDropInstructions(ib);
1704 ib.setKey(new InstructionKey(0));
1705 instructions.add(ib.build());
1707 // Add InstructionBuilder to the Instruction(s)Builder List
1708 isb.setInstruction(instructions);
1710 // Add InstructionsBuilder to FlowBuilder
1711 flowBuilder.setInstructions(isb.build());
1714 String flowId = "DropFilter_"+inPort;
1715 // Add Flow Attributes
1716 flowBuilder.setId(new FlowId(flowId));
1717 FlowKey key = new FlowKey(new FlowId(flowId));
1718 flowBuilder.setStrict(true);
1719 flowBuilder.setBarrier(false);
1720 flowBuilder.setTableId((short) 0);
1721 flowBuilder.setKey(key);
1722 flowBuilder.setFlowName(flowId);
1723 flowBuilder.setPriority(8192);
1724 flowBuilder.setHardTimeout(0);
1725 flowBuilder.setIdleTimeout(0);
1727 writeFlow(flowBuilder, nodeBuilder);
1729 removeFlow(flowBuilder, nodeBuilder);
1734 * (Table:1) Egress Tunnel Traffic
1735 * Match: Destination Ethernet Addr and Local InPort
1736 * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
1737 * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
1738 * actions=output:10,goto_table:2"
1740 private void handleTunnelOut(Long dpidLong, Short writeTable,
1741 Short goToTableId, String segmentationId,
1742 Long OFPortOut, String attachedMac,
1745 String nodeName = "openflow:" + dpidLong;
1747 MatchBuilder matchBuilder = new MatchBuilder();
1748 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1749 FlowBuilder flowBuilder = new FlowBuilder();
1751 // Create the OF Match using MatchBuilder
1752 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
1753 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
1755 String flowId = "TunnelOut_"+segmentationId+"_"+OFPortOut+"_"+attachedMac;
1756 // Add Flow Attributes
1757 flowBuilder.setId(new FlowId(flowId));
1758 FlowKey key = new FlowKey(new FlowId(flowId));
1759 flowBuilder.setStrict(true);
1760 flowBuilder.setBarrier(false);
1761 flowBuilder.setTableId(writeTable);
1762 flowBuilder.setKey(key);
1763 flowBuilder.setFlowName(flowId);
1764 flowBuilder.setHardTimeout(0);
1765 flowBuilder.setIdleTimeout(0);
1768 // Instantiate the Builders for the OF Actions and Instructions
1769 InstructionBuilder ib = new InstructionBuilder();
1770 InstructionsBuilder isb = new InstructionsBuilder();
1772 // Instructions List Stores Individual Instructions
1773 List<Instruction> instructions = new ArrayList<Instruction>();
1776 createGotoTableInstructions(ib, goToTableId);
1778 ib.setKey(new InstructionKey(0));
1779 instructions.add(ib.build());
1780 // Set the Output Port/Iface
1781 createOutputPortInstructions(ib, dpidLong, OFPortOut);
1783 ib.setKey(new InstructionKey(1));
1784 instructions.add(ib.build());
1786 // Add InstructionBuilder to the Instruction(s)Builder List
1787 isb.setInstruction(instructions);
1789 // Add InstructionsBuilder to FlowBuilder
1790 flowBuilder.setInstructions(isb.build());
1792 writeFlow(flowBuilder, nodeBuilder);
1794 removeFlow(flowBuilder, nodeBuilder);
1799 * (Table:1) Egress VLAN Traffic
1800 * Match: Destination Ethernet Addr and VLAN id
1801 * Instruction: GOTO Table Table 2
1802 * table=1,vlan_id=0x5,dl_dst=00:00:00:00:00:08 \
1803 * actions= goto_table:2"
1806 private void handleVlanOut(Long dpidLong, Short writeTable,
1807 Short goToTableId, String segmentationId,
1808 Long ethPort, String attachedMac, boolean write) {
1810 String nodeName = "openflow:" + dpidLong;
1812 MatchBuilder matchBuilder = new MatchBuilder();
1813 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1814 FlowBuilder flowBuilder = new FlowBuilder();
1816 // Create the OF Match using MatchBuilder
1817 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
1818 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
1820 String flowId = "VlanOut_"+segmentationId+"_"+ethPort+"_"+attachedMac;
1821 // Add Flow Attributes
1822 flowBuilder.setId(new FlowId(flowId));
1823 FlowKey key = new FlowKey(new FlowId(flowId));
1824 flowBuilder.setStrict(true);
1825 flowBuilder.setBarrier(false);
1826 flowBuilder.setTableId(writeTable);
1827 flowBuilder.setKey(key);
1828 flowBuilder.setFlowName(flowId);
1829 flowBuilder.setHardTimeout(0);
1830 flowBuilder.setIdleTimeout(0);
1833 // Instantiate the Builders for the OF Actions and Instructions
1834 InstructionBuilder ib = new InstructionBuilder();
1835 InstructionsBuilder isb = new InstructionsBuilder();
1837 // Instructions List Stores Individual Instructions
1838 List<Instruction> instructions = new ArrayList<Instruction>();
1841 createGotoTableInstructions(ib, goToTableId);
1843 ib.setKey(new InstructionKey(0));
1844 instructions.add(ib.build());
1846 // Add InstructionBuilder to the Instruction(s)Builder List
1847 isb.setInstruction(instructions);
1849 // Add InstructionsBuilder to FlowBuilder
1850 flowBuilder.setInstructions(isb.build());
1852 writeFlow(flowBuilder, nodeBuilder);
1854 removeFlow(flowBuilder, nodeBuilder);
1859 * (Table:1) Egress Tunnel Traffic
1860 * Match: Destination Ethernet Addr and Local InPort
1861 * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
1862 * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
1863 * actions=output:10,output:11,goto_table:2
1866 private void handleTunnelFloodOut(Long dpidLong, Short writeTable,
1867 Short localTable, String segmentationId,
1868 Long OFPortOut, boolean write) {
1870 String nodeName = "openflow:" + dpidLong;
1872 MatchBuilder matchBuilder = new MatchBuilder();
1873 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1874 FlowBuilder flowBuilder = new FlowBuilder();
1876 // Create the OF Match using MatchBuilder
1878 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
1881 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
1883 String flowId = "TunnelFloodOut_"+segmentationId;
1884 // Add Flow Attributes
1885 flowBuilder.setId(new FlowId(flowId));
1886 FlowKey key = new FlowKey(new FlowId(flowId));
1887 flowBuilder.setBarrier(true);
1888 flowBuilder.setTableId(writeTable);
1889 flowBuilder.setKey(key);
1890 flowBuilder.setPriority(16384);
1891 flowBuilder.setFlowName(flowId);
1892 flowBuilder.setHardTimeout(0);
1893 flowBuilder.setIdleTimeout(0);
1895 Flow flow = this.getFlow(flowBuilder, nodeBuilder);
1896 // Instantiate the Builders for the OF Actions and Instructions
1897 InstructionBuilder ib = new InstructionBuilder();
1898 InstructionsBuilder isb = new InstructionsBuilder();
1899 List<Instruction> instructions = new ArrayList<Instruction>();
1900 List<Instruction> existingInstructions = null;
1902 Instructions ins = flow.getInstructions();
1904 existingInstructions = ins.getInstruction();
1910 createGotoTableInstructions(ib, localTable);
1912 ib.setKey(new InstructionKey(0));
1913 instructions.add(ib.build());
1914 // Set the Output Port/Iface
1915 //createOutputGroupInstructions(nodeBuilder, ib, dpidLong, OFPortOut, existingInstructions);
1916 createOutputPortInstructions(ib, dpidLong, OFPortOut, existingInstructions);
1918 ib.setKey(new InstructionKey(1));
1919 instructions.add(ib.build());
1921 // Add InstructionBuilder to the Instruction(s)Builder List
1922 isb.setInstruction(instructions);
1924 // Add InstructionsBuilder to FlowBuilder
1925 flowBuilder.setInstructions(isb.build());
1927 writeFlow(flowBuilder, nodeBuilder);
1929 /* remove port from action list */
1930 boolean flowRemove = removeOutputPortFromInstructions(ib, dpidLong,
1931 OFPortOut, existingInstructions);
1933 /* if all port are removed, remove the flow too. */
1934 removeFlow(flowBuilder, nodeBuilder);
1936 /* Install instruction with new output port list*/
1938 ib.setKey(new InstructionKey(0));
1939 instructions.add(ib.build());
1941 // Add InstructionBuilder to the Instruction(s)Builder List
1942 isb.setInstruction(instructions);
1944 // Add InstructionsBuilder to FlowBuilder
1945 flowBuilder.setInstructions(isb.build());
1951 * (Table:1) Egress VLAN Traffic
1952 * Match: Destination Ethernet Addr and VLAN id
1953 * Instruction: GOTO table 2 and Output port eth interface
1954 * Example: table=1,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
1955 * actions=output:eth1,goto_table:2
1958 private void handleVlanFloodOut(Long dpidLong, Short writeTable,
1959 Short localTable, String segmentationId,
1960 Long ethPort, boolean write) {
1962 String nodeName = "openflow:" + dpidLong;
1964 MatchBuilder matchBuilder = new MatchBuilder();
1965 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1966 FlowBuilder flowBuilder = new FlowBuilder();
1968 // Create the OF Match using MatchBuilder
1970 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
1972 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
1974 String flowId = "VlanFloodOut_"+segmentationId;
1975 // Add Flow Attributes
1976 flowBuilder.setId(new FlowId(flowId));
1977 FlowKey key = new FlowKey(new FlowId(flowId));
1978 flowBuilder.setBarrier(true);
1979 flowBuilder.setTableId(writeTable);
1980 flowBuilder.setKey(key);
1981 flowBuilder.setPriority(16384);
1982 flowBuilder.setFlowName(flowId);
1983 flowBuilder.setHardTimeout(0);
1984 flowBuilder.setIdleTimeout(0);
1986 Flow flow = this.getFlow(flowBuilder, nodeBuilder);
1987 // Instantiate the Builders for the OF Actions and Instructions
1988 InstructionBuilder ib = new InstructionBuilder();
1989 InstructionsBuilder isb = new InstructionsBuilder();
1990 List<Instruction> instructions = new ArrayList<Instruction>();
1994 createGotoTableInstructions(ib, localTable);
1996 ib.setKey(new InstructionKey(0));
1997 instructions.add(ib.build());
1998 // Set the Output Port/Iface
1999 createOutputPortInstructions(ib, dpidLong, ethPort);
2001 ib.setKey(new InstructionKey(1));
2002 instructions.add(ib.build());
2004 // Add InstructionBuilder to the Instruction(s)Builder List
2005 isb.setInstruction(instructions);
2007 // Add InstructionsBuilder to FlowBuilder
2008 flowBuilder.setInstructions(isb.build());
2010 writeFlow(flowBuilder, nodeBuilder);
2012 removeFlow(flowBuilder, nodeBuilder);
2017 * (Table:1) Table Drain w/ Catch All
2019 * Action: GOTO Local Table (10)
2020 * table=2,priority=8192,tun_id=0x5 actions=drop
2023 private void handleTunnelMiss(Long dpidLong, Short writeTable,
2024 Short goToTableId, String segmentationId,
2027 String nodeName = "openflow:" + dpidLong;
2029 MatchBuilder matchBuilder = new MatchBuilder();
2030 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2031 FlowBuilder flowBuilder = new FlowBuilder();
2033 // Create Match(es) and Set them in the FlowBuilder Object
2034 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
2037 // Create the OF Actions and Instructions
2038 InstructionBuilder ib = new InstructionBuilder();
2039 InstructionsBuilder isb = new InstructionsBuilder();
2041 // Instructions List Stores Individual Instructions
2042 List<Instruction> instructions = new ArrayList<Instruction>();
2044 // Call the InstructionBuilder Methods Containing Actions
2045 createGotoTableInstructions(ib, goToTableId);
2047 ib.setKey(new InstructionKey(0));
2048 instructions.add(ib.build());
2050 // Add InstructionBuilder to the Instruction(s)Builder List
2051 isb.setInstruction(instructions);
2053 // Add InstructionsBuilder to FlowBuilder
2054 flowBuilder.setInstructions(isb.build());
2057 String flowId = "TunnelMiss_"+segmentationId;
2058 // Add Flow Attributes
2059 flowBuilder.setId(new FlowId(flowId));
2060 FlowKey key = new FlowKey(new FlowId(flowId));
2061 flowBuilder.setStrict(true);
2062 flowBuilder.setBarrier(false);
2063 flowBuilder.setTableId(writeTable);
2064 flowBuilder.setKey(key);
2065 flowBuilder.setPriority(8192);
2066 flowBuilder.setFlowName(flowId);
2067 flowBuilder.setHardTimeout(0);
2068 flowBuilder.setIdleTimeout(0);
2070 writeFlow(flowBuilder, nodeBuilder);
2072 removeFlow(flowBuilder, nodeBuilder);
2078 * (Table:1) Table Drain w/ Catch All
2080 * Action: Output port eth interface
2081 * table=1,priority=8192,vlan_id=0x5 actions= output port:eth1
2084 private void handleVlanMiss(Long dpidLong, Short writeTable,
2085 Short goToTableId, String segmentationId,
2086 Long ethPort, boolean write) {
2088 String nodeName = "openflow:" + dpidLong;
2090 MatchBuilder matchBuilder = new MatchBuilder();
2091 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2092 FlowBuilder flowBuilder = new FlowBuilder();
2094 // Create Match(es) and Set them in the FlowBuilder Object
2095 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
2098 // Create the OF Actions and Instructions
2099 InstructionBuilder ib = new InstructionBuilder();
2100 InstructionsBuilder isb = new InstructionsBuilder();
2102 // Instructions List Stores Individual Instructions
2103 List<Instruction> instructions = new ArrayList<Instruction>();
2105 // Call the InstructionBuilder Methods Containing Actions
2106 //createGotoTableInstructions(ib, goToTableId);
2108 //ib.setKey(new InstructionKey(0));
2109 //instructions.add(ib.build());
2110 // Set the Output Port/Iface
2111 createOutputPortInstructions(ib, dpidLong, ethPort);
2113 ib.setKey(new InstructionKey(1));
2114 instructions.add(ib.build());
2116 // Add InstructionBuilder to the Instruction(s)Builder List
2117 isb.setInstruction(instructions);
2119 // Add InstructionsBuilder to FlowBuilder
2120 flowBuilder.setInstructions(isb.build());
2123 String flowId = "VlanMiss_"+segmentationId;
2124 // Add Flow Attributes
2125 flowBuilder.setId(new FlowId(flowId));
2126 FlowKey key = new FlowKey(new FlowId(flowId));
2127 flowBuilder.setStrict(true);
2128 flowBuilder.setBarrier(false);
2129 flowBuilder.setTableId(writeTable);
2130 flowBuilder.setKey(key);
2131 flowBuilder.setPriority(8192);
2132 flowBuilder.setFlowName(flowId);
2133 flowBuilder.setHardTimeout(0);
2134 flowBuilder.setIdleTimeout(0);
2136 writeFlow(flowBuilder, nodeBuilder);
2138 removeFlow(flowBuilder, nodeBuilder);
2143 * (Table:1) Local Broadcast Flood
2144 * Match: Tunnel ID and dMAC
2145 * Action: Output Port
2146 * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
2149 private void handleLocalUcastOut(Long dpidLong, Short writeTable,
2150 String segmentationId, Long localPort,
2151 String attachedMac, boolean write) {
2153 String nodeName = "openflow:" + dpidLong;
2155 MatchBuilder matchBuilder = new MatchBuilder();
2156 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2157 FlowBuilder flowBuilder = new FlowBuilder();
2159 // Create the OF Match using MatchBuilder
2160 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
2161 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
2163 String flowId = "UcastOut_"+segmentationId+"_"+localPort+"_"+attachedMac;
2164 // Add Flow Attributes
2165 flowBuilder.setId(new FlowId(flowId));
2166 FlowKey key = new FlowKey(new FlowId(flowId));
2167 flowBuilder.setStrict(true);
2168 flowBuilder.setBarrier(false);
2169 flowBuilder.setTableId(writeTable);
2170 flowBuilder.setKey(key);
2171 flowBuilder.setFlowName(flowId);
2172 flowBuilder.setHardTimeout(0);
2173 flowBuilder.setIdleTimeout(0);
2176 // Instantiate the Builders for the OF Actions and Instructions
2177 InstructionBuilder ib = new InstructionBuilder();
2178 InstructionsBuilder isb = new InstructionsBuilder();
2180 // Instructions List Stores Individual Instructions
2181 List<Instruction> instructions = new ArrayList<Instruction>();
2183 // Set the Output Port/Iface
2184 createOutputPortInstructions(ib, dpidLong, localPort);
2186 ib.setKey(new InstructionKey(0));
2187 instructions.add(ib.build());
2189 // Add InstructionBuilder to the Instruction(s)Builder List
2190 isb.setInstruction(instructions);
2192 // Add InstructionsBuilder to FlowBuilder
2193 flowBuilder.setInstructions(isb.build());
2194 writeFlow(flowBuilder, nodeBuilder);
2196 removeFlow(flowBuilder, nodeBuilder);
2201 * (Table:2) Local VLAN unicast
2202 * Match: VLAN ID and dMAC
2203 * Action: Output Port
2204 * table=2,vlan_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
2207 private void handleLocalVlanUcastOut(Long dpidLong, Short writeTable,
2208 String segmentationId, Long localPort,
2209 String attachedMac, boolean write) {
2211 String nodeName = "openflow:" + dpidLong;
2213 MatchBuilder matchBuilder = new MatchBuilder();
2214 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2215 FlowBuilder flowBuilder = new FlowBuilder();
2217 // Create the OF Match using MatchBuilder
2218 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
2219 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
2221 String flowId = "VlanUcastOut_"+segmentationId+"_"+localPort+"_"+attachedMac;
2222 // Add Flow Attributes
2223 flowBuilder.setId(new FlowId(flowId));
2224 FlowKey key = new FlowKey(new FlowId(flowId));
2225 flowBuilder.setStrict(true);
2226 flowBuilder.setBarrier(false);
2227 flowBuilder.setTableId(writeTable);
2228 flowBuilder.setKey(key);
2229 flowBuilder.setFlowName(flowId);
2230 flowBuilder.setHardTimeout(0);
2231 flowBuilder.setIdleTimeout(0);
2234 // Instantiate the Builders for the OF Actions and Instructions
2235 InstructionBuilder ib = new InstructionBuilder();
2236 InstructionsBuilder isb = new InstructionsBuilder();
2238 // Instructions List Stores Individual Instructions
2239 List<Instruction> instructions = new ArrayList<Instruction>();
2240 List<Instruction> instructions_tmp = new ArrayList<Instruction>();
2242 /* Strip vlan and store to tmp instruction space*/
2243 createPopVlanInstructions(ib);
2245 ib.setKey(new InstructionKey(0));
2246 instructions_tmp.add(ib.build());
2248 // Set the Output Port/Iface
2249 ib = new InstructionBuilder();
2250 addOutputPortInstructions(ib, dpidLong, localPort, instructions_tmp);
2252 ib.setKey(new InstructionKey(0));
2253 instructions.add(ib.build());
2255 // Add InstructionBuilder to the Instruction(s)Builder List
2256 isb.setInstruction(instructions);
2258 // Add InstructionsBuilder to FlowBuilder
2259 flowBuilder.setInstructions(isb.build());
2260 writeFlow(flowBuilder, nodeBuilder);
2262 removeFlow(flowBuilder, nodeBuilder);
2267 * (Table:2) Local Broadcast Flood
2268 * Match: Tunnel ID and dMAC (::::FF:FF)
2269 * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
2270 * actions=output:2,3,4,5
2273 private void handleLocalBcastOut(Long dpidLong, Short writeTable,
2274 String segmentationId, Long localPort,
2277 String nodeName = "openflow:" + dpidLong;
2279 MatchBuilder matchBuilder = new MatchBuilder();
2280 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2281 FlowBuilder flowBuilder = new FlowBuilder();
2283 // Create the OF Match using MatchBuilder
2284 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
2285 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
2287 String flowId = "BcastOut_"+segmentationId;
2288 // Add Flow Attributes
2289 flowBuilder.setId(new FlowId(flowId));
2290 FlowKey key = new FlowKey(new FlowId(flowId));
2291 flowBuilder.setStrict(true);
2292 flowBuilder.setBarrier(false);
2293 flowBuilder.setTableId(writeTable);
2294 flowBuilder.setKey(key);
2295 flowBuilder.setPriority(16384);
2296 flowBuilder.setFlowName(flowId);
2297 flowBuilder.setHardTimeout(0);
2298 flowBuilder.setIdleTimeout(0);
2299 Flow flow = this.getFlow(flowBuilder, nodeBuilder);
2300 // Instantiate the Builders for the OF Actions and Instructions
2301 InstructionBuilder ib = new InstructionBuilder();
2302 InstructionsBuilder isb = new InstructionsBuilder();
2303 List<Instruction> instructions = new ArrayList<Instruction>();
2304 List<Instruction> existingInstructions = null;
2306 Instructions ins = flow.getInstructions();
2308 existingInstructions = ins.getInstruction();
2313 // Create output port list
2314 createOutputPortInstructions(ib, dpidLong, localPort, existingInstructions);
2316 ib.setKey(new InstructionKey(0));
2317 instructions.add(ib.build());
2319 // Add InstructionBuilder to the Instruction(s)Builder List
2320 isb.setInstruction(instructions);
2322 // Add InstructionsBuilder to FlowBuilder
2323 flowBuilder.setInstructions(isb.build());
2325 writeFlow(flowBuilder, nodeBuilder);
2327 boolean flowRemove = removeOutputPortFromInstructions(ib, dpidLong, localPort,
2328 existingInstructions);
2330 /* if all ports are removed, remove flow */
2331 removeFlow(flowBuilder, nodeBuilder);
2333 /* Install instruction with new output port list*/
2335 ib.setKey(new InstructionKey(0));
2336 instructions.add(ib.build());
2338 // Add InstructionBuilder to the Instruction(s)Builder List
2339 isb.setInstruction(instructions);
2341 // Add InstructionsBuilder to FlowBuilder
2342 flowBuilder.setInstructions(isb.build());
2344 writeFlow(flowBuilder, nodeBuilder);
2350 * (Table:2) Local VLAN Broadcast Flood
2351 * Match: vlan ID and dMAC (::::FF:FF)
2352 * table=2,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
2353 * actions=strip_vlan, output:2,3,4,5
2356 private void handleLocalVlanBcastOut(Long dpidLong, Short writeTable,
2357 String segmentationId, Long localPort,
2360 String nodeName = "openflow:" + dpidLong;
2362 MatchBuilder matchBuilder = new MatchBuilder();
2363 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2364 FlowBuilder flowBuilder = new FlowBuilder();
2366 // Create the OF Match using MatchBuilder
2367 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
2368 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
2370 String flowId = "VlanBcastOut_"+segmentationId;
2371 // Add Flow Attributes
2372 flowBuilder.setId(new FlowId(flowId));
2373 FlowKey key = new FlowKey(new FlowId(flowId));
2374 flowBuilder.setStrict(true);
2375 flowBuilder.setBarrier(false);
2376 flowBuilder.setTableId(writeTable);
2377 flowBuilder.setKey(key);
2378 flowBuilder.setPriority(16384);
2379 flowBuilder.setFlowName(flowId);
2380 flowBuilder.setHardTimeout(0);
2381 flowBuilder.setIdleTimeout(0);
2382 Flow flow = this.getFlow(flowBuilder, nodeBuilder);
2383 // Instantiate the Builders for the OF Actions and Instructions
2384 InstructionBuilder ib = new InstructionBuilder();
2385 InstructionsBuilder isb = new InstructionsBuilder();
2386 List<Instruction> instructions = new ArrayList<Instruction>();
2387 List<Instruction> existingInstructions = null;
2388 boolean add_pop_vlan = true;
2390 Instructions ins = flow.getInstructions();
2392 existingInstructions = ins.getInstruction();
2397 if (existingInstructions != null) {
2398 /* Check if pop vlan is already the first action in action list */
2399 List<Action> existingActions = null;
2400 for (Instruction in : existingInstructions) {
2401 if (in.getInstruction() instanceof ApplyActionsCase) {
2402 existingActions = (((ApplyActionsCase)
2403 in.getInstruction()).getApplyActions().getAction());
2404 if (existingActions.get(0).getAction() instanceof PopVlanActionCase) {
2405 add_pop_vlan = false;
2411 existingInstructions = new ArrayList<Instruction>();
2416 createPopVlanInstructions(ib);
2418 ib.setKey(new InstructionKey(0));
2419 existingInstructions.add(ib.build());
2420 ib = new InstructionBuilder();
2424 //createOutputGroupInstructions(nodeBuilder, ib, dpidLong, localPort, existingInstructions);
2425 createOutputPortInstructions(ib, dpidLong, localPort, existingInstructions);
2427 ib.setKey(new InstructionKey(0));
2428 instructions.add(ib.build());
2430 // Add InstructionBuilder to the Instruction(s)Builder List
2431 isb.setInstruction(instructions);
2433 // Add InstructionsBuilder to FlowBuilder
2434 flowBuilder.setInstructions(isb.build());
2436 writeFlow(flowBuilder, nodeBuilder);
2438 //boolean flowRemove = removeOutputPortFromGroup(nodeBuilder, ib, dpidLong,
2439 // localPort, existingInstructions);
2440 boolean flowRemove = removeOutputPortFromInstructions(ib, dpidLong,
2441 localPort, existingInstructions);
2443 /* if all ports are removed, remove flow */
2444 removeFlow(flowBuilder, nodeBuilder);
2446 /* Install instruction with new output port list*/
2448 ib.setKey(new InstructionKey(0));
2449 instructions.add(ib.build());
2451 // Add InstructionBuilder to the Instruction(s)Builder List
2452 isb.setInstruction(instructions);
2454 // Add InstructionsBuilder to FlowBuilder
2455 flowBuilder.setInstructions(isb.build());
2456 writeFlow(flowBuilder, nodeBuilder);
2462 * (Table:1) Local Table Miss
2463 * Match: Any Remaining Flows w/a TunID
2464 * Action: Drop w/ a low priority
2465 * table=2,priority=8192,tun_id=0x5 actions=drop
2468 private void handleLocalTableMiss(Long dpidLong, Short writeTable,
2469 String segmentationId, boolean write) {
2471 String nodeName = "openflow:" + dpidLong;
2473 MatchBuilder matchBuilder = new MatchBuilder();
2474 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2475 FlowBuilder flowBuilder = new FlowBuilder();
2477 // Create Match(es) and Set them in the FlowBuilder Object
2478 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
2481 // Create the OF Actions and Instructions
2482 InstructionBuilder ib = new InstructionBuilder();
2483 InstructionsBuilder isb = new InstructionsBuilder();
2485 // Instructions List Stores Individual Instructions
2486 List<Instruction> instructions = new ArrayList<Instruction>();
2488 // Call the InstructionBuilder Methods Containing Actions
2489 createDropInstructions(ib);
2491 ib.setKey(new InstructionKey(0));
2492 instructions.add(ib.build());
2494 // Add InstructionBuilder to the Instruction(s)Builder List
2495 isb.setInstruction(instructions);
2497 // Add InstructionsBuilder to FlowBuilder
2498 flowBuilder.setInstructions(isb.build());
2501 String flowId = "LocalTableMiss_"+segmentationId;
2502 // Add Flow Attributes
2503 flowBuilder.setId(new FlowId(flowId));
2504 FlowKey key = new FlowKey(new FlowId(flowId));
2505 flowBuilder.setStrict(true);
2506 flowBuilder.setBarrier(false);
2507 flowBuilder.setTableId(writeTable);
2508 flowBuilder.setKey(key);
2509 flowBuilder.setPriority(8192);
2510 flowBuilder.setFlowName(flowId);
2511 flowBuilder.setHardTimeout(0);
2512 flowBuilder.setIdleTimeout(0);
2514 writeFlow(flowBuilder, nodeBuilder);
2516 removeFlow(flowBuilder, nodeBuilder);
2521 * (Table:1) Local Table Miss
2522 * Match: Any Remaining Flows w/a VLAN ID
2523 * Action: Drop w/ a low priority
2524 * table=2,priority=8192,vlan_id=0x5 actions=drop
2527 private void handleLocalVlanTableMiss(Long dpidLong, Short writeTable,
2528 String segmentationId, boolean write) {
2530 String nodeName = "openflow:" + dpidLong;
2532 MatchBuilder matchBuilder = new MatchBuilder();
2533 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2534 FlowBuilder flowBuilder = new FlowBuilder();
2536 // Create Match(es) and Set them in the FlowBuilder Object
2537 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
2540 // Create the OF Actions and Instructions
2541 InstructionBuilder ib = new InstructionBuilder();
2542 InstructionsBuilder isb = new InstructionsBuilder();
2544 // Instructions List Stores Individual Instructions
2545 List<Instruction> instructions = new ArrayList<Instruction>();
2547 // Call the InstructionBuilder Methods Containing Actions
2548 createDropInstructions(ib);
2550 ib.setKey(new InstructionKey(0));
2551 instructions.add(ib.build());
2553 // Add InstructionBuilder to the Instruction(s)Builder List
2554 isb.setInstruction(instructions);
2556 // Add InstructionsBuilder to FlowBuilder
2557 flowBuilder.setInstructions(isb.build());
2560 String flowId = "LocalTableMiss_"+segmentationId;
2561 // Add Flow Attributes
2562 flowBuilder.setId(new FlowId(flowId));
2563 FlowKey key = new FlowKey(new FlowId(flowId));
2564 flowBuilder.setStrict(true);
2565 flowBuilder.setBarrier(false);
2566 flowBuilder.setTableId(writeTable);
2567 flowBuilder.setKey(key);
2568 flowBuilder.setPriority(8192);
2569 flowBuilder.setFlowName(flowId);
2570 flowBuilder.setHardTimeout(0);
2571 flowBuilder.setIdleTimeout(0);
2573 writeFlow(flowBuilder, nodeBuilder);
2575 removeFlow(flowBuilder, nodeBuilder);
2579 private Group getGroup(GroupBuilder groupBuilder, NodeBuilder nodeBuilder) {
2580 IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2581 if (mdsalConsumer == null) {
2582 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2586 dataBrokerService = mdsalConsumer.getDataBrokerService();
2588 if (dataBrokerService == null) {
2589 logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2593 InstanceIdentifier<Group> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2594 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Group.class,
2595 new GroupKey(groupBuilder.getGroupId())).build();
2596 return (Group)dataBrokerService.readConfigurationData(path1);
2599 private Group writeGroup(GroupBuilder groupBuilder, NodeBuilder nodeBuilder) {
2600 IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2601 if (mdsalConsumer == null) {
2602 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2606 dataBrokerService = mdsalConsumer.getDataBrokerService();
2608 if (dataBrokerService == null) {
2609 logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2612 DataModification<InstanceIdentifier<?>, DataObject> modification = dataBrokerService.beginTransaction();
2613 InstanceIdentifier<Group> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2614 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Group.class,
2615 new GroupKey(groupBuilder.getGroupId())).build();
2616 modification.putConfigurationData(nodeBuilderToInstanceId(nodeBuilder), nodeBuilder.build());
2617 modification.putConfigurationData(path1, groupBuilder.build());
2618 Future<RpcResult<TransactionStatus>> commitFuture = modification.commit();
2621 RpcResult<TransactionStatus> result = commitFuture.get();
2622 TransactionStatus status = result.getResult();
2623 logger.debug("Transaction Status "+status.toString()+" for Group "+groupBuilder.getGroupName());
2624 } catch (InterruptedException e) {
2625 logger.error(e.getMessage(), e);
2626 } catch (ExecutionException e) {
2627 logger.error(e.getMessage(), e);
2629 return (Group)dataBrokerService.readConfigurationData(path1);
2632 private Group removeGroup(GroupBuilder groupBuilder, NodeBuilder nodeBuilder) {
2633 IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2634 if (mdsalConsumer == null) {
2635 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2639 dataBrokerService = mdsalConsumer.getDataBrokerService();
2641 if (dataBrokerService == null) {
2642 logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2645 DataModification<InstanceIdentifier<?>, DataObject> modification = dataBrokerService.beginTransaction();
2646 InstanceIdentifier<Group> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2647 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Group.class,
2648 new GroupKey(groupBuilder.getGroupId())).build();
2649 modification.removeConfigurationData(path1);
2650 Future<RpcResult<TransactionStatus>> commitFuture = modification.commit();
2653 RpcResult<TransactionStatus> result = commitFuture.get();
2654 TransactionStatus status = result.getResult();
2655 logger.debug("Transaction Status "+status.toString()+" for Group "+groupBuilder.getGroupName());
2656 } catch (InterruptedException e) {
2657 logger.error(e.getMessage(), e);
2658 } catch (ExecutionException e) {
2659 logger.error(e.getMessage(), e);
2661 return (Group)dataBrokerService.readConfigurationData(path1);
2663 private Flow getFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
2664 IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2665 if (mdsalConsumer == null) {
2666 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2670 dataBrokerService = mdsalConsumer.getDataBrokerService();
2672 if (dataBrokerService == null) {
2673 logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2677 InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2678 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class,
2679 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
2680 return (Flow)dataBrokerService.readConfigurationData(path1);
2683 private void writeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
2684 IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2685 if (mdsalConsumer == null) {
2686 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2690 dataBrokerService = mdsalConsumer.getDataBrokerService();
2692 if (dataBrokerService == null) {
2693 logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2696 DataModification<InstanceIdentifier<?>, DataObject> modification = dataBrokerService.beginTransaction();
2697 InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2698 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class,
2699 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
2700 //modification.putOperationalData(nodeBuilderToInstanceId(nodeBuilder), nodeBuilder.build());
2701 //modification.putOperationalData(path1, flowBuilder.build());
2702 modification.putConfigurationData(nodeBuilderToInstanceId(nodeBuilder), nodeBuilder.build());
2703 modification.putConfigurationData(path1, flowBuilder.build());
2704 Future<RpcResult<TransactionStatus>> commitFuture = modification.commit();
2706 RpcResult<TransactionStatus> result = commitFuture.get();
2707 TransactionStatus status = result.getResult();
2708 logger.debug("Transaction Status "+status.toString()+" for Flow "+flowBuilder.getFlowName());
2709 } catch (InterruptedException e) {
2710 logger.error(e.getMessage(), e);
2711 } catch (ExecutionException e) {
2712 logger.error(e.getMessage(), e);
2716 private void removeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
2717 IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2718 if (mdsalConsumer == null) {
2719 logger.error("ERROR finding MDSAL Service.");
2723 dataBrokerService = mdsalConsumer.getDataBrokerService();
2725 if (dataBrokerService == null) {
2726 logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2729 DataModification<InstanceIdentifier<?>, DataObject> modification = dataBrokerService.beginTransaction();
2730 InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class)
2731 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2732 .rev130819.nodes.Node.class, nodeBuilder.getKey())
2733 .augmentation(FlowCapableNode.class).child(Table.class,
2734 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
2735 //modification.removeOperationalData(nodeBuilderToInstanceId(nodeBuilder));
2736 //modification.removeOperationalData(path1);
2737 //modification.removeConfigurationData(nodeBuilderToInstanceId(nodeBuilder));
2738 modification.removeConfigurationData(path1);
2739 Future<RpcResult<TransactionStatus>> commitFuture = modification.commit();
2741 RpcResult<TransactionStatus> result = commitFuture.get();
2742 TransactionStatus status = result.getResult();
2743 logger.debug("Transaction Status "+status.toString()+" for Flow "+flowBuilder.getFlowName());
2744 } catch (InterruptedException e) {
2745 logger.error(e.getMessage(), e);
2746 } catch (ExecutionException e) {
2747 logger.error(e.getMessage(), e);
2752 * Create Ingress Port Match dpidLong, inPort
2754 * @param matchBuilder Map matchBuilder MatchBuilder Object without a match
2755 * @param dpidLong Long the datapath ID of a switch/node
2756 * @param inPort Long ingress port on a switch
2757 * @return matchBuilder Map MatchBuilder Object with a match
2759 protected static MatchBuilder createInPortMatch(MatchBuilder matchBuilder, Long dpidLong, Long inPort) {
2761 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + inPort);
2762 logger.debug("createInPortMatch() Node Connector ID is - Type=openflow: DPID={} inPort={} ", dpidLong, inPort);
2763 matchBuilder.setInPort(NodeConnectorId.getDefaultInstance(ncid.getValue()));
2764 matchBuilder.setInPort(ncid);
2766 return matchBuilder;
2770 * Create EtherType Match
2772 * @param matchBuilder Map matchBuilder MatchBuilder Object without a match
2773 * @param etherType Long EtherType
2774 * @return matchBuilder Map MatchBuilder Object with a match
2776 protected static MatchBuilder createEtherTypeMatch(MatchBuilder matchBuilder, EtherType etherType) {
2778 EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
2779 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2780 ethTypeBuilder.setType(new EtherType(etherType));
2781 ethernetMatch.setEthernetType(ethTypeBuilder.build());
2782 matchBuilder.setEthernetMatch(ethernetMatch.build());
2784 return matchBuilder;
2788 * Create Ethernet Source Match
2790 * @param matchBuilder MatchBuilder Object without a match yet
2791 * @param sMacAddr String representing a source MAC
2792 * @return matchBuilder Map MatchBuilder Object with a match
2794 protected static MatchBuilder createEthSrcMatch(MatchBuilder matchBuilder, MacAddress sMacAddr) {
2796 EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
2797 EthernetSourceBuilder ethSourceBuilder = new EthernetSourceBuilder();
2798 ethSourceBuilder.setAddress(new MacAddress(sMacAddr));
2799 ethernetMatch.setEthernetSource(ethSourceBuilder.build());
2800 matchBuilder.setEthernetMatch(ethernetMatch.build());
2802 return matchBuilder;
2806 * Create Ethernet Destination Match
2808 * @param matchBuilder MatchBuilder Object without a match yet
2809 * @param vlanId Integer representing a VLAN ID Integer representing a VLAN ID
2810 * @return matchBuilder Map MatchBuilder Object with a match
2813 protected static MatchBuilder createVlanIdMatch(MatchBuilder matchBuilder, VlanId vlanId) {
2814 VlanMatchBuilder vlanMatchBuilder = new VlanMatchBuilder();
2815 VlanIdBuilder vlanIdBuilder = new VlanIdBuilder();
2816 vlanIdBuilder.setVlanId(new VlanId(vlanId));
2817 vlanIdBuilder.setVlanIdPresent(true);
2818 vlanMatchBuilder.setVlanId(vlanIdBuilder.build());
2819 matchBuilder.setVlanMatch(vlanMatchBuilder.build());
2821 return matchBuilder;
2825 * Create Ethernet Destination Match
2827 * @param matchBuilder MatchBuilder Object without a match yet
2828 * @param dMacAddr String representing a destination MAC
2829 * @return matchBuilder Map MatchBuilder Object with a match
2832 protected static MatchBuilder createDestEthMatch(MatchBuilder matchBuilder, MacAddress dMacAddr, MacAddress mask) {
2834 EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
2835 EthernetDestinationBuilder ethDestinationBuilder = new EthernetDestinationBuilder();
2836 ethDestinationBuilder.setAddress(new MacAddress(dMacAddr));
2838 ethDestinationBuilder.setMask(mask);
2840 ethernetMatch.setEthernetDestination(ethDestinationBuilder.build());
2841 matchBuilder.setEthernetMatch(ethernetMatch.build());
2843 return matchBuilder;
2847 * Tunnel ID Match Builder
2849 * @param matchBuilder MatchBuilder Object without a match yet
2850 * @param tunnelId BigInteger representing a tunnel ID
2851 * @return matchBuilder Map MatchBuilder Object with a match
2853 protected static MatchBuilder createTunnelIDMatch(MatchBuilder matchBuilder, BigInteger tunnelId) {
2855 TunnelBuilder tunnelBuilder = new TunnelBuilder();
2856 tunnelBuilder.setTunnelId(tunnelId);
2857 matchBuilder.setTunnel(tunnelBuilder.build());
2859 return matchBuilder;
2863 * Match ICMP code and type
2865 * @param matchBuilder MatchBuilder Object without a match yet
2866 * @param type short representing an ICMP type
2867 * @param code short representing an ICMP code
2868 * @return matchBuilder Map MatchBuilder Object with a match
2870 protected static MatchBuilder createICMPv4Match(MatchBuilder matchBuilder, short type, short code) {
2872 EthernetMatchBuilder eth = new EthernetMatchBuilder();
2873 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2874 ethTypeBuilder.setType(new EtherType(0x0800L));
2875 eth.setEthernetType(ethTypeBuilder.build());
2876 matchBuilder.setEthernetMatch(eth.build());
2878 // Build the IPv4 Match requied per OVS Syntax
2879 IpMatchBuilder ipmatch = new IpMatchBuilder();
2880 ipmatch.setIpProtocol((short) 1);
2881 matchBuilder.setIpMatch(ipmatch.build());
2883 // Build the ICMPv4 Match
2884 Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
2885 icmpv4match.setIcmpv4Type(type);
2886 icmpv4match.setIcmpv4Code(code);
2887 matchBuilder.setIcmpv4Match(icmpv4match.build());
2889 return matchBuilder;
2893 * @param matchBuilder MatchBuilder Object without a match yet
2894 * @param dstip String containing an IPv4 prefix
2895 * @return matchBuilder Map Object with a match
2897 private static MatchBuilder createDstL3IPv4Match(MatchBuilder matchBuilder, Ipv4Prefix dstip) {
2899 EthernetMatchBuilder eth = new EthernetMatchBuilder();
2900 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2901 ethTypeBuilder.setType(new EtherType(0x0800L));
2902 eth.setEthernetType(ethTypeBuilder.build());
2903 matchBuilder.setEthernetMatch(eth.build());
2905 Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder();
2906 ipv4match.setIpv4Destination(dstip);
2908 matchBuilder.setLayer3Match(ipv4match.build());
2910 return matchBuilder;
2915 * @param matchBuilder MatchBuilder Object without a match yet
2916 * @param srcip String containing an IPv4 prefix
2917 * @return matchBuilder Map Object with a match
2919 private static MatchBuilder createSrcL3IPv4Match(MatchBuilder matchBuilder, Ipv4Prefix srcip) {
2921 EthernetMatchBuilder eth = new EthernetMatchBuilder();
2922 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2923 ethTypeBuilder.setType(new EtherType(0x0800L));
2924 eth.setEthernetType(ethTypeBuilder.build());
2925 matchBuilder.setEthernetMatch(eth.build());
2927 Ipv4MatchBuilder ipv4Match = new Ipv4MatchBuilder();
2928 Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder();
2929 ipv4match.setIpv4Source(srcip);
2930 matchBuilder.setLayer3Match(ipv4match.build());
2932 return matchBuilder;
2937 * Create Source TCP Port Match
2939 * @param matchBuilder @param matchbuilder MatchBuilder Object without a match yet
2940 * @param tcpport Integer representing a source TCP port
2941 * @return matchBuilder Map MatchBuilder Object with a match
2943 protected static MatchBuilder createSetSrcTcpMatch(MatchBuilder matchBuilder, PortNumber tcpport) {
2945 EthernetMatchBuilder ethType = new EthernetMatchBuilder();
2946 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2947 ethTypeBuilder.setType(new EtherType(0x0800L));
2948 ethType.setEthernetType(ethTypeBuilder.build());
2949 matchBuilder.setEthernetMatch(ethType.build());
2951 IpMatchBuilder ipmatch = new IpMatchBuilder();
2952 ipmatch.setIpProtocol((short) 6);
2953 matchBuilder.setIpMatch(ipmatch.build());
2955 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
2956 tcpmatch.setTcpSourcePort(tcpport);
2957 matchBuilder.setLayer4Match(tcpmatch.build());
2959 return matchBuilder;
2964 * Create Destination TCP Port Match
2966 * @param matchBuilder MatchBuilder Object without a match yet
2967 * @param tcpport Integer representing a destination TCP port
2968 * @return matchBuilder Map MatchBuilder Object with a match
2970 protected static MatchBuilder createSetDstTcpMatch(MatchBuilder matchBuilder, PortNumber tcpport) {
2972 EthernetMatchBuilder ethType = new EthernetMatchBuilder();
2973 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2974 ethTypeBuilder.setType(new EtherType(0x0800L));
2975 ethType.setEthernetType(ethTypeBuilder.build());
2976 matchBuilder.setEthernetMatch(ethType.build());
2978 IpMatchBuilder ipmatch = new IpMatchBuilder();
2979 ipmatch.setIpProtocol((short) 6);
2980 matchBuilder.setIpMatch(ipmatch.build());
2982 PortNumber dstport = new PortNumber(tcpport);
2983 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
2985 tcpmatch.setTcpDestinationPort(tcpport);
2986 matchBuilder.setLayer4Match(tcpmatch.build());
2988 return matchBuilder;
2992 * Create Send to Controller Reserved Port Instruction (packet_in)
2994 * @param ib Map InstructionBuilder without any instructions
2995 * @return ib Map InstructionBuilder with instructions
2998 protected static InstructionBuilder createSendToControllerInstructions(InstructionBuilder ib) {
3000 List<Action> actionList = new ArrayList<Action>();
3001 ActionBuilder ab = new ActionBuilder();
3003 OutputActionBuilder output = new OutputActionBuilder();
3004 output.setMaxLength(0xffff);
3005 Uri value = new Uri("CONTROLLER");
3006 output.setOutputNodeConnector(value);
3007 ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
3009 ab.setKey(new ActionKey(0));
3010 actionList.add(ab.build());
3012 // Create an Apply Action
3013 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3014 aab.setAction(actionList);
3016 // Wrap our Apply Action in an Instruction
3017 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3023 * Create NORMAL Reserved Port Instruction (packet_in)
3025 * @param ib Map InstructionBuilder without any instructions
3026 * @return ib Map InstructionBuilder with instructions
3029 protected static InstructionBuilder createNormalInstructions(InstructionBuilder ib) {
3031 List<Action> actionList = new ArrayList<Action>();
3032 ActionBuilder ab = new ActionBuilder();
3034 OutputActionBuilder output = new OutputActionBuilder();
3035 Uri value = new Uri("NORMAL");
3036 output.setOutputNodeConnector(value);
3037 ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
3039 ab.setKey(new ActionKey(0));
3040 actionList.add(ab.build());
3042 // Create an Apply Action
3043 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3044 aab.setAction(actionList);
3046 // Wrap our Apply Action in an Instruction
3047 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3053 * Create Output Port Instruction
3055 * @param ib Map InstructionBuilder without any instructions
3056 * @param dpidLong Long the datapath ID of a switch/node
3057 * @param port Long representing a port on a switch/node
3058 * @return ib InstructionBuilder Map with instructions
3060 protected static InstructionBuilder createOutputPortInstructions(InstructionBuilder ib, Long dpidLong, Long port) {
3062 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3063 logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} inPort={} ", dpidLong, port);
3065 List<Action> actionList = new ArrayList<Action>();
3066 ActionBuilder ab = new ActionBuilder();
3067 OutputActionBuilder oab = new OutputActionBuilder();
3068 oab.setOutputNodeConnector(ncid);
3070 ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
3072 ab.setKey(new ActionKey(0));
3073 actionList.add(ab.build());
3075 // Create an Apply Action
3076 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3077 aab.setAction(actionList);
3078 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3084 * Create Output Port Group Instruction
3086 * @param ib Map InstructionBuilder without any instructions
3087 * @param dpidLong Long the datapath ID of a switch/node
3088 * @param port Long representing a port on a switch/node
3089 * @return ib InstructionBuilder Map with instructions
3091 protected InstructionBuilder createOutputPortInstructions(InstructionBuilder ib,
3092 Long dpidLong, Long port ,
3093 List<Instruction> instructions) {
3094 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3095 logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3097 List<Action> actionList = new ArrayList<Action>();
3098 ActionBuilder ab = new ActionBuilder();
3100 List<Action> existingActions = null;
3101 if (instructions != null) {
3102 for (Instruction in : instructions) {
3103 if (in.getInstruction() instanceof ApplyActionsCase) {
3104 existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3105 actionList.addAll(existingActions);
3109 /* Create output action for this port*/
3110 OutputActionBuilder oab = new OutputActionBuilder();
3111 oab.setOutputNodeConnector(ncid);
3112 ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
3113 boolean addNew = true;
3115 /* Find the group action and get the group */
3116 for (Action action : actionList) {
3117 if (action.getAction() instanceof OutputActionCase) {
3118 OutputActionCase opAction = (OutputActionCase)action.getAction();
3119 /* If output port action already in the action list of one of the buckets, skip */
3120 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
3127 ab.setOrder(actionList.size());
3128 ab.setKey(new ActionKey(actionList.size()));
3129 actionList.add(ab.build());
3131 // Create an Apply Action
3132 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3133 aab.setAction(actionList);
3134 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3135 logger.debug("createOutputPortInstructions() : applyAction {}", aab.build());
3140 * Create Output Port Group Instruction
3142 * @param ib Map InstructionBuilder without any instructions
3143 * @param dpidLong Long the datapath ID of a switch/node
3144 * @param port Long representing a port on a switch/node
3145 * @return ib InstructionBuilder Map with instructions
3147 protected InstructionBuilder createOutputGroupInstructions(NodeBuilder nodeBuilder,
3148 InstructionBuilder ib,
3149 Long dpidLong, Long port ,
3150 List<Instruction> instructions) {
3151 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3152 logger.debug("createOutputGroupInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3154 List<Action> actionList = new ArrayList<Action>();
3155 ActionBuilder ab = new ActionBuilder();
3157 List<Action> existingActions = null;
3158 if (instructions != null) {
3159 for (Instruction in : instructions) {
3160 if (in.getInstruction() instanceof ApplyActionsCase) {
3161 existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3162 actionList.addAll(existingActions);
3167 GroupBuilder groupBuilder = new GroupBuilder();
3170 /* Create output action for this port*/
3171 OutputActionBuilder oab = new OutputActionBuilder();
3172 oab.setOutputNodeConnector(ncid);
3173 ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
3174 logger.debug("createOutputGroupInstructions(): output action {}", ab.build());
3175 boolean addNew = true;
3176 boolean groupActionAdded = false;
3178 /* Find the group action and get the group */
3179 for (Action action : actionList) {
3180 if (action.getAction() instanceof GroupActionCase) {
3181 groupActionAdded = true;
3182 GroupActionCase groupAction = (GroupActionCase) action.getAction();
3183 Long id = groupAction.getGroupAction().getGroupId();
3184 String groupName = groupAction.getGroupAction().getGroup();
3185 GroupKey key = new GroupKey(new GroupId(id));
3187 groupBuilder.setGroupId(new GroupId(id));
3188 groupBuilder.setGroupName(groupName);
3189 groupBuilder.setGroupType(GroupTypes.GroupAll);
3190 groupBuilder.setKey(key);
3191 group = getGroup(groupBuilder, nodeBuilder);
3192 logger.debug("createOutputGroupInstructions: group {}", group);
3197 logger.debug("createOutputGroupInstructions: groupActionAdded {}", groupActionAdded);
3198 if (groupActionAdded) {
3199 /* modify the action bucket in group */
3200 groupBuilder = new GroupBuilder(group);
3201 Buckets buckets = groupBuilder.getBuckets();
3202 for (Bucket bucket : buckets.getBucket()) {
3203 List<Action> bucketActions = bucket.getAction();
3204 logger.debug("createOutputGroupInstructions: bucketActions {}", bucketActions);
3205 for (Action action : bucketActions) {
3206 if (action.getAction() instanceof OutputActionCase) {
3207 OutputActionCase opAction = (OutputActionCase)action.getAction();
3208 /* If output port action already in the action list of one of the buckets, skip */
3209 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
3216 logger.debug("createOutputGroupInstructions: addNew {}", addNew);
3218 /* the new output action is not in the bucket, add to bucket */
3219 if (!buckets.getBucket().isEmpty()) {
3220 Bucket bucket = buckets.getBucket().get(0);
3221 List<Action> bucketActionList = new ArrayList<Action>();
3222 bucketActionList.addAll(bucket.getAction());
3223 /* set order for new action and add to action list */
3224 ab.setOrder(bucketActionList.size());
3225 ab.setKey(new ActionKey(bucketActionList.size()));
3226 bucketActionList.add(ab.build());
3228 /* set bucket and buckets list. Reset groupBuilder with new buckets.*/
3229 BucketsBuilder bucketsBuilder = new BucketsBuilder();
3230 List<Bucket> bucketList = new ArrayList<Bucket>();
3231 BucketBuilder bucketBuilder = new BucketBuilder();
3232 bucketBuilder.setBucketId(new BucketId((long) 1));
3233 bucketBuilder.setKey(new BucketKey(new BucketId((long) 1)));
3234 bucketBuilder.setAction(bucketActionList);
3235 bucketList.add(bucketBuilder.build());
3236 bucketsBuilder.setBucket(bucketList);
3237 groupBuilder.setBuckets(bucketsBuilder.build());
3238 logger.debug("createOutputGroupInstructions: bucketList {}", bucketList);
3243 groupBuilder = new GroupBuilder();
3244 groupBuilder.setGroupType(GroupTypes.GroupAll);
3245 groupBuilder.setGroupId(new GroupId(groupId));
3246 groupBuilder.setKey(new GroupKey(new GroupId(groupId)));
3247 groupBuilder.setGroupName("Output port group" + groupId);
3248 groupBuilder.setBarrier(false);
3250 BucketsBuilder bucketBuilder = new BucketsBuilder();
3251 List<Bucket> bucketList = new ArrayList<Bucket>();
3252 BucketBuilder bucket = new BucketBuilder();
3253 bucket.setBucketId(new BucketId((long) 1));
3254 bucket.setKey(new BucketKey(new BucketId((long) 1)));
3256 /* put output action to the bucket */
3257 List<Action> bucketActionList = new ArrayList<Action>();
3258 /* set order for new action and add to action list */
3259 ab.setOrder(bucketActionList.size());
3260 ab.setKey(new ActionKey(bucketActionList.size()));
3261 bucketActionList.add(ab.build());
3263 bucket.setAction(bucketActionList);
3264 bucketList.add(bucket.build());
3265 bucketBuilder.setBucket(bucketList);
3266 groupBuilder.setBuckets(bucketBuilder.build());
3268 /* Add new group action */
3269 GroupActionBuilder groupActionB = new GroupActionBuilder();
3270 groupActionB.setGroupId(groupId);
3271 groupActionB.setGroup("Output port group" + groupId);
3272 ab = new ActionBuilder();
3273 ab.setAction(new GroupActionCaseBuilder().setGroupAction(groupActionB.build()).build());
3274 ab.setOrder(actionList.size());
3275 ab.setKey(new ActionKey(actionList.size()));
3276 actionList.add(ab.build());
3280 logger.debug("createOutputGroupInstructions: group {}", groupBuilder.build());
3281 logger.debug("createOutputGroupInstructions: actionList {}", actionList);
3284 /* rewrite the group to group table */
3285 writeGroup(groupBuilder, nodeBuilder);
3288 // Create an Apply Action
3289 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3290 aab.setAction(actionList);
3291 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3297 * add Output Port action to Instruction action list.
3298 * This is use for flow with single output port actions.
3299 * Flow with mutiple output port actions should use createOutputPortInstructions() method.
3301 * @param ib Map InstructionBuilder without any instructions
3302 * @param dpidLong Long the datapath ID of a switch/node
3303 * @param port Long representing a port on a switch/node
3304 * @return ib InstructionBuilder Map with instructions
3306 protected static InstructionBuilder addOutputPortInstructions(InstructionBuilder ib,
3307 Long dpidLong, Long port ,
3308 List<Instruction> instructions) {
3309 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3310 logger.debug("addOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3312 List<Action> actionList = new ArrayList<Action>();
3313 ActionBuilder ab = new ActionBuilder();
3315 List<Action> existingActions = null;
3316 if (instructions != null) {
3317 for (Instruction in : instructions) {
3318 if (in.getInstruction() instanceof ApplyActionsCase) {
3319 existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3320 actionList.addAll(existingActions);
3325 /* Create output action for this port*/
3326 OutputActionBuilder oab = new OutputActionBuilder();
3327 oab.setOutputNodeConnector(ncid);
3328 ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
3329 ab.setOrder(actionList.size());
3330 ab.setKey(new ActionKey(actionList.size()));
3331 actionList.add(ab.build());
3333 // Create an Apply Action
3334 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3335 aab.setAction(actionList);
3336 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3342 * Remove Output Port from action list in group bucket
3344 * @param ib Map InstructionBuilder without any instructions
3345 * @param dpidLong Long the datapath ID of a switch/node
3346 * @param port Long representing a port on a switch/node
3347 * @return ib InstructionBuilder Map with instructions
3349 protected boolean removeOutputPortFromGroup(NodeBuilder nodeBuilder, InstructionBuilder ib,
3350 Long dpidLong, Long port , List<Instruction> instructions) {
3352 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3353 logger.debug("removeOutputPortFromGroup() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3355 List<Action> actionList = new ArrayList<Action>();
3358 List<Action> existingActions = null;
3359 if (instructions != null) {
3360 for (Instruction in : instructions) {
3361 if (in.getInstruction() instanceof ApplyActionsCase) {
3362 existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3363 actionList.addAll(existingActions);
3369 GroupBuilder groupBuilder = new GroupBuilder();
3371 boolean groupActionAdded = false;
3372 /* Find the group action and get the group */
3373 for (Action action : actionList) {
3374 if (action.getAction() instanceof GroupActionCase) {
3375 groupActionAdded = true;
3376 GroupActionCase groupAction = (GroupActionCase) action.getAction();
3377 Long id = groupAction.getGroupAction().getGroupId();
3378 String groupName = groupAction.getGroupAction().getGroup();
3379 GroupKey key = new GroupKey(new GroupId(id));
3381 groupBuilder.setGroupId(new GroupId(id));
3382 groupBuilder.setGroupName(groupName);
3383 groupBuilder.setGroupType(GroupTypes.GroupAll);
3384 groupBuilder.setKey(key);
3385 group = getGroup(groupBuilder, nodeBuilder);
3390 if (groupActionAdded) {
3391 /* modify the action bucket in group */
3392 groupBuilder = new GroupBuilder(group);
3393 Buckets buckets = groupBuilder.getBuckets();
3394 List<Action> bucketActions = new ArrayList<Action>();
3395 for (Bucket bucket : buckets.getBucket()) {
3397 boolean isPortDeleted = false;
3398 bucketActions = bucket.getAction();
3399 for (Action action : bucketActions) {
3400 if (action.getAction() instanceof OutputActionCase) {
3401 OutputActionCase opAction = (OutputActionCase)action.getAction();
3402 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
3403 /* Find the output port in action list and remove */
3404 index = bucketActions.indexOf(action);
3405 bucketActions.remove(action);
3406 isPortDeleted = true;
3411 if (isPortDeleted && !bucketActions.isEmpty()) {
3412 for (int i = index; i< bucketActions.size(); i++) {
3413 Action action = bucketActions.get(i);
3414 if (action.getOrder() != i) {
3415 /* Shift the action order */
3416 ab = new ActionBuilder();
3417 ab.setAction(action.getAction());
3419 ab.setKey(new ActionKey(i));
3420 Action actionNewOrder = ab.build();
3421 bucketActions.remove(action);
3422 bucketActions.add(i, actionNewOrder);
3426 } else if (bucketActions.isEmpty()) {
3427 /* remove bucket with empty action list */
3428 buckets.getBucket().remove(bucket);
3432 if (!buckets.getBucket().isEmpty()) {
3433 /* rewrite the group to group table */
3434 /* set bucket and buckets list. Reset groupBuilder with new buckets.*/
3435 BucketsBuilder bucketsBuilder = new BucketsBuilder();
3436 List<Bucket> bucketList = new ArrayList<Bucket>();
3437 BucketBuilder bucketBuilder = new BucketBuilder();
3438 bucketBuilder.setBucketId(new BucketId((long) 1));
3439 bucketBuilder.setKey(new BucketKey(new BucketId((long) 1)));
3440 bucketBuilder.setAction(bucketActions);
3441 bucketList.add(bucketBuilder.build());
3442 bucketsBuilder.setBucket(bucketList);
3443 groupBuilder.setBuckets(bucketsBuilder.build());
3444 logger.debug("removeOutputPortFromGroup: bucketList {}", bucketList);
3446 writeGroup(groupBuilder, nodeBuilder);
3447 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3448 aab.setAction(actionList);
3449 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3452 /* remove group with empty bucket. return true to delete flow */
3453 removeGroup(groupBuilder, nodeBuilder);
3457 /* no group for port list. flow can be removed */
3463 * Remove Output Port from Instruction
3465 * @param ib Map InstructionBuilder without any instructions
3466 * @param dpidLong Long the datapath ID of a switch/node
3467 * @param port Long representing a port on a switch/node
3468 * @return ib InstructionBuilder Map with instructions
3470 protected static boolean removeOutputPortFromInstructions(InstructionBuilder ib,
3471 Long dpidLong, Long port , List<Instruction> instructions) {
3473 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3474 logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3476 List<Action> actionList = new ArrayList<Action>();
3479 List<Action> existingActions = null;
3480 if (instructions != null) {
3481 for (Instruction in : instructions) {
3482 if (in.getInstruction() instanceof ApplyActionsCase) {
3483 existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3484 actionList.addAll(existingActions);
3490 int numOutputPort = 0;
3492 boolean isPortDeleted = false;
3493 for (Action action : actionList) {
3494 if (action.getAction() instanceof OutputActionCase) {
3496 OutputActionCase opAction = (OutputActionCase)action.getAction();
3497 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
3498 /* Find the output port in action list and remove */
3499 index = actionList.indexOf(action);
3500 actionList.remove(action);
3501 isPortDeleted = true;
3508 if (isPortDeleted) {
3509 for (int i = index; i< actionList.size(); i++) {
3510 Action action = actionList.get(i);
3511 if (action.getOrder() != i) {
3512 /* Shift the action order */
3513 ab = new ActionBuilder();
3514 ab.setAction(action.getAction());
3516 ab.setKey(new ActionKey(i));
3517 Action actionNewOrder = ab.build();
3518 actionList.remove(action);
3519 actionList.add(i, actionNewOrder);
3524 /* Put new action list in Apply Action instruction */
3525 if (numOutputPort > 0) {
3526 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3527 aab.setAction(actionList);
3528 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3529 logger.debug("createOutputPortInstructions() : applyAction {}", aab.build());
3532 /* if all output port are removed. Return true to indicate flow remove */
3538 * Create Set Vlan ID Instruction - This includes push vlan action, and set field -> vlan vid action
3540 * @param ib Map InstructionBuilder without any instructions
3541 * @param vlanId Integer representing a VLAN ID Integer representing a VLAN ID
3542 * @return ib Map InstructionBuilder with instructions
3544 protected static InstructionBuilder createSetVlanInstructions(InstructionBuilder ib, VlanId vlanId) {
3546 List<Action> actionList = new ArrayList<Action>();
3547 ActionBuilder ab = new ActionBuilder();
3549 /* First we push vlan header */
3550 PushVlanActionBuilder vlan = new PushVlanActionBuilder();
3551 vlan.setEthernetType(new Integer(0x8100));
3552 ab.setAction(new PushVlanActionCaseBuilder().setPushVlanAction(vlan.build()).build());
3554 actionList.add(ab.build());
3556 /* Then we set vlan id value as vlanId */
3557 SetVlanIdActionBuilder vl = new SetVlanIdActionBuilder();
3558 vl.setVlanId(vlanId);
3559 ab = new ActionBuilder();
3560 ab.setAction(new SetVlanIdActionCaseBuilder().setSetVlanIdAction(vl.build()).build());
3562 actionList.add(ab.build());
3563 // Create an Apply Action
3564 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3565 aab.setAction(actionList);
3567 // Wrap our Apply Action in an Instruction
3568 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3574 * Create Pop Vlan Instruction - this remove vlan header
3576 * @param ib Map InstructionBuilder without any instructions
3577 * @return ib Map InstructionBuilder with instructions
3579 protected static InstructionBuilder createPopVlanInstructions(InstructionBuilder ib) {
3581 List<Action> actionList = new ArrayList<Action>();
3582 ActionBuilder ab = new ActionBuilder();
3584 PopVlanActionBuilder popVlanActionBuilder = new PopVlanActionBuilder();
3585 ab.setAction(new PopVlanActionCaseBuilder().setPopVlanAction(popVlanActionBuilder.build()).build());
3587 actionList.add(ab.build());
3589 // Create an Apply Action
3590 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3591 aab.setAction(actionList);
3593 // Wrap our Apply Action in an Instruction
3594 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3600 * Create Set IPv4 Source Instruction
3602 * @param ib Map InstructionBuilder without any instructions
3603 * @param prefixsrc String containing an IPv4 prefix
3604 * @return ib Map InstructionBuilder with instructions
3606 protected static InstructionBuilder createNwSrcInstructions(InstructionBuilder ib, Ipv4Prefix prefixsrc) {
3608 List<Action> actionList = new ArrayList<Action>();
3609 ActionBuilder ab = new ActionBuilder();
3611 SetNwSrcActionBuilder setNwsrcActionBuilder = new SetNwSrcActionBuilder();
3612 Ipv4Builder ipsrc = new Ipv4Builder();
3613 ipsrc.setIpv4Address(prefixsrc);
3614 setNwsrcActionBuilder.setAddress(ipsrc.build());
3615 ab.setAction(new SetNwSrcActionCaseBuilder().setSetNwSrcAction(setNwsrcActionBuilder.build()).build());
3616 actionList.add(ab.build());
3618 // Create an Apply Action
3619 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3620 aab.setAction(actionList);
3622 // Wrap our Apply Action in an Instruction
3623 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3629 * Create Set IPv4 Destination Instruction
3631 * @param ib Map InstructionBuilder without any instructions
3632 * @param prefixdst String containing an IPv4 prefix
3633 * @return ib Map InstructionBuilder with instructions
3635 protected static InstructionBuilder createNwDstInstructions(InstructionBuilder ib, Ipv4Prefix prefixdst) {
3637 List<Action> actionList = new ArrayList<Action>();
3638 ActionBuilder ab = new ActionBuilder();
3640 SetNwDstActionBuilder setNwDstActionBuilder = new SetNwDstActionBuilder();
3641 Ipv4Builder ipdst = new Ipv4Builder();
3642 ipdst.setIpv4Address(prefixdst);
3643 setNwDstActionBuilder.setAddress(ipdst.build());
3644 ab.setAction(new SetNwDstActionCaseBuilder().setSetNwDstAction(setNwDstActionBuilder.build()).build());
3645 actionList.add(ab.build());
3647 // Create an Apply Action
3648 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3649 aab.setAction(actionList);
3651 // Wrap our Apply Action in an Instruction
3652 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3658 * Create Drop Instruction
3660 * @param ib Map InstructionBuilder without any instructions
3661 * @return ib Map InstructionBuilder with instructions
3663 protected static InstructionBuilder createDropInstructions(InstructionBuilder ib) {
3665 DropActionBuilder dab = new DropActionBuilder();
3666 DropAction dropAction = dab.build();
3667 ActionBuilder ab = new ActionBuilder();
3668 ab.setAction(new DropActionCaseBuilder().setDropAction(dropAction).build());
3671 // Add our drop action to a list
3672 List<Action> actionList = new ArrayList<Action>();
3673 actionList.add(ab.build());
3675 // Create an Apply Action
3676 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3677 aab.setAction(actionList);
3679 // Wrap our Apply Action in an Instruction
3680 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3686 * Create GOTO Table Instruction Builder
3688 * @param ib Map InstructionBuilder without any instructions
3689 * @param tableId short representing a flow table ID short representing a flow table ID
3690 * @return ib Map InstructionBuilder with instructions
3692 protected static InstructionBuilder createGotoTableInstructions(InstructionBuilder ib, short tableId) {
3694 GoToTableBuilder gttb = new GoToTableBuilder();
3695 gttb.setTableId(tableId);
3697 // Wrap our Apply Action in an InstructionBuilder
3698 ib.setInstruction(new GoToTableCaseBuilder().setGoToTable(gttb.build()).build());
3704 * Create Set Tunnel ID Instruction Builder
3706 * @param ib Map InstructionBuilder without any instructions
3707 * @param tunnelId BigInteger representing a tunnel ID
3708 * @return ib Map InstructionBuilder with instructions
3710 protected static InstructionBuilder createSetTunnelIdInstructions(InstructionBuilder ib, BigInteger tunnelId) {
3712 List<Action> actionList = new ArrayList<Action>();
3713 ActionBuilder ab = new ActionBuilder();
3714 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3716 // Build the Set Tunnel Field Action
3717 TunnelBuilder tunnel = new TunnelBuilder();
3718 tunnel.setTunnelId(tunnelId);
3719 setFieldBuilder.setTunnel(tunnel.build());
3720 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3722 actionList.add(ab.build());
3724 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3725 aab.setAction(actionList);
3727 // Wrap the Apply Action in an InstructionBuilder and return
3728 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3734 * Create Set Source TCP Port Instruction
3736 * @param ib Map InstructionBuilder without any instructions
3737 * @param tcpport Integer representing a source TCP port
3738 * @return ib Map InstructionBuilder with instructions
3740 protected static InstructionBuilder createSetSrcTCPPort(InstructionBuilder ib, PortNumber tcpport) {
3742 List<Action> actionList = new ArrayList<Action>();
3743 ActionBuilder ab = new ActionBuilder();
3744 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3746 // Build the Destination TCP Port
3747 PortNumber tcpsrcport = new PortNumber(tcpport);
3748 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
3749 tcpmatch.setTcpSourcePort(tcpsrcport);
3751 setFieldBuilder.setLayer4Match(tcpmatch.build());
3752 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3753 ab.setKey(new ActionKey(1));
3754 actionList.add(ab.build());
3756 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3757 aab.setAction(actionList);
3758 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3764 * Create Set Destination TCP Port Instruction
3766 * @param ib Map InstructionBuilder without any instructions
3767 * @param tcpport Integer representing a source TCP port
3768 * @return ib Map InstructionBuilder with instructions
3770 protected static InstructionBuilder createSetDstTCPPort(InstructionBuilder ib, PortNumber tcpport) {
3772 List<Action> actionList = new ArrayList<Action>();
3773 ActionBuilder ab = new ActionBuilder();
3774 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3776 // Build the Destination TCP Port
3777 PortNumber tcpdstport = new PortNumber(tcpport);
3778 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
3779 tcpmatch.setTcpDestinationPort(tcpdstport);
3781 setFieldBuilder.setLayer4Match(tcpmatch.build());
3782 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3783 ab.setKey(new ActionKey(1));
3784 actionList.add(ab.build());
3786 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3787 aab.setAction(actionList);
3788 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3794 * Create Set Source UDP Port Instruction
3796 * @param ib Map InstructionBuilder without any instructions
3797 * @param udpport Integer representing a source UDP port
3798 * @return ib Map InstructionBuilder with instructions
3800 protected static InstructionBuilder createSetSrcUDPPort(InstructionBuilder ib, PortNumber udpport) {
3802 List<Action> actionList = new ArrayList<Action>();
3803 ActionBuilder ab = new ActionBuilder();
3804 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3806 // Build the Destination TCP Port
3807 PortNumber udpsrcport = new PortNumber(udpport);
3808 UdpMatchBuilder udpmatch = new UdpMatchBuilder();
3809 udpmatch.setUdpSourcePort(udpsrcport);
3811 setFieldBuilder.setLayer4Match(udpmatch.build());
3812 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3813 ab.setKey(new ActionKey(1));
3814 actionList.add(ab.build());
3816 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3817 aab.setAction(actionList);
3818 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3824 * Create Set Destination UDP Port Instruction
3826 * @param ib Map InstructionBuilder without any instructions
3827 * @param udpport Integer representing a destination UDP port
3828 * @return ib Map InstructionBuilder with instructions
3830 protected static InstructionBuilder createSetDstUDPPort(InstructionBuilder ib, PortNumber udpport) {
3832 List<Action> actionList = new ArrayList<Action>();
3833 ActionBuilder ab = new ActionBuilder();
3834 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3836 // Build the Destination TCP Port
3837 PortNumber udpdstport = new PortNumber(udpport);
3838 UdpMatchBuilder udpmatch = new UdpMatchBuilder();
3839 udpmatch.setUdpDestinationPort(udpdstport);
3841 setFieldBuilder.setLayer4Match(udpmatch.build());
3842 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3843 ab.setKey(new ActionKey(1));
3844 actionList.add(ab.build());
3846 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3847 aab.setAction(actionList);
3848 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3854 * Create Set ICMP Code Instruction
3856 * @param ib Map InstructionBuilder without any instructions
3857 * @param code short repesenting an ICMP code
3858 * @return ib Map InstructionBuilder with instructions
3861 private static InstructionBuilder createSetIcmpCodeInstruction(InstructionBuilder ib, short code) {
3863 List<Action> actionList = new ArrayList<Action>();
3864 ActionBuilder ab = new ActionBuilder();
3865 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3866 Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
3868 // Build the ICMPv4 Code Match
3869 icmpv4match.setIcmpv4Code(code);
3870 setFieldBuilder.setIcmpv4Match(icmpv4match.build());
3872 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3873 ab.setKey(new ActionKey(0));
3874 actionList.add(ab.build());
3875 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3876 aab.setAction(actionList);
3878 // Wrap our Apply Action in an Instruction
3879 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3885 * Create Set ICMP Code Instruction
3887 * @param ib Map InstructionBuilder without any instructions
3888 * @return ib Map InstructionBuilder with instructions
3890 private static InstructionBuilder createSetIcmpTypeInstruction(InstructionBuilder ib, short type) {
3892 List<Action> actionList = new ArrayList<Action>();
3893 ActionBuilder ab = new ActionBuilder();
3894 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3895 Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
3897 // Build the ICMPv4 Code Match
3898 icmpv4match.setIcmpv4Code(type);
3899 setFieldBuilder.setIcmpv4Match(icmpv4match.build());
3901 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3902 ab.setKey(new ActionKey(1));
3903 actionList.add(ab.build());
3904 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3905 aab.setAction(actionList);
3907 // Wrap our Apply Action in an Instruction
3908 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3914 * Create Decrement TTL Instruction
3916 * @param ib Map InstructionBuilder without any instructions
3917 * @return ib Map InstructionBuilder with instructions
3919 private static InstructionBuilder createDecNwTtlInstructions(InstructionBuilder ib) {
3920 DecNwTtlBuilder decNwTtlBuilder = new DecNwTtlBuilder();
3921 DecNwTtl decNwTtl = decNwTtlBuilder.build();
3922 ActionBuilder ab = new ActionBuilder();
3923 ab.setAction(new DecNwTtlCaseBuilder().setDecNwTtl(decNwTtl).build());
3925 // Add our drop action to a list
3926 List<Action> actionList = new ArrayList<Action>();
3927 actionList.add(ab.build());
3929 // Create an Apply Action
3930 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3931 aab.setAction(actionList);
3933 // Wrap our Apply Action in an Instruction
3934 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3942 private static InstructionBuilder createSrcArpMacInstructions(InstructionBuilder ib, MacAddress macsrc) {
3944 List<Action> actionList = new ArrayList<Action>();
3945 ActionBuilder ab = new ActionBuilder();
3947 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3948 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
3949 ArpSourceHardwareAddressBuilder arpsrc = new ArpSourceHardwareAddressBuilder();
3950 arpsrc.setAddress(macsrc);
3951 arpmatch.setArpSourceHardwareAddress(arpsrc.build());
3952 setFieldBuilder.setLayer3Match(arpmatch.build());
3953 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3954 ab.setKey(new ActionKey(0));
3955 actionList.add(ab.build());
3957 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3958 aab.setAction(actionList);
3966 private static InstructionBuilder createDstArpMacInstructions(InstructionBuilder ib, MacAddress macdst) {
3968 List<Action> actionList = new ArrayList<Action>();
3969 ActionBuilder ab = new ActionBuilder();
3970 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3972 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
3973 ArpTargetHardwareAddressBuilder arpdst = new ArpTargetHardwareAddressBuilder();
3974 arpdst.setAddress(macdst);
3975 setFieldBuilder.setLayer3Match(arpmatch.build());
3976 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3977 ab.setKey(new ActionKey(0));
3978 actionList.add(ab.build());
3980 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3981 aab.setAction(actionList);
3989 private static InstructionBuilder createDstArpIpInstructions(InstructionBuilder ib, Ipv4Prefix dstiparp) {
3991 List<Action> actionList = new ArrayList<Action>();
3992 ActionBuilder ab = new ActionBuilder();
3993 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3995 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
3996 arpmatch.setArpTargetTransportAddress(dstiparp);
3997 setFieldBuilder.setLayer3Match(arpmatch.build());
3998 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3999 ab.setKey(new ActionKey(0));
4000 actionList.add(ab.build());
4002 ApplyActionsBuilder aab = new ApplyActionsBuilder();
4003 aab.setAction(actionList);
4011 private static InstructionBuilder createSrcArpIpInstructions(InstructionBuilder ib, Ipv4Prefix srciparp) {
4013 List<Action> actionList = new ArrayList<Action>();
4014 ActionBuilder ab = new ActionBuilder();
4015 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
4017 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
4018 arpmatch.setArpSourceTransportAddress(srciparp);
4019 setFieldBuilder.setLayer3Match(arpmatch.build());
4020 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
4021 ab.setKey(new ActionKey(0));
4022 actionList.add(ab.build());
4024 ApplyActionsBuilder aab = new ApplyActionsBuilder();
4025 aab.setAction(actionList);
4031 public void initializeOFFlowRules(Node openflowNode) {
4032 IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
4033 List<Node> ovsNodes = connectionService.getNodes();
4034 if (ovsNodes == null) return;
4035 for (Node ovsNode : ovsNodes) {
4036 Long brIntDpid = this.getIntegrationBridgeOFDPID(ovsNode);
4037 Long brExDpid = this.getExternalBridgeDpid(ovsNode);
4038 logger.debug("Compare openflowNode to OVS node {} vs {} and {}", openflowNode.getID(), brIntDpid, brExDpid);
4039 String openflowID = openflowNode.getID().toString();
4040 if (openflowID.contains(brExDpid.toString())) {
4041 this.initializeFlowRules(ovsNode, adminConfigManager.getExternalBridgeName());
4042 this.triggerInterfaceUpdates(ovsNode);
4044 if (openflowID.contains(brIntDpid.toString())) {
4045 this.initializeFlowRules(ovsNode, adminConfigManager.getIntegrationBridgeName());
4046 this.triggerInterfaceUpdates(ovsNode);
4051 private NodeBuilder createNodeBuilder(String nodeId) {
4052 NodeBuilder builder = new NodeBuilder();
4053 builder.setId(new NodeId(nodeId));
4054 builder.setKey(new NodeKey(builder.getId()));
4058 private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeBuilderToInstanceId(NodeBuilder
4060 return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
4061 node.getKey()).toInstance();
4064 private String getInternalBridgeUUID (Node node, String bridgeName) {
4066 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
4067 Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
4068 if (bridgeTable == null) return null;
4069 for (String key : bridgeTable.keySet()) {
4070 Bridge bridge = (Bridge)bridgeTable.get(key);
4071 if (bridge.getName().equals(bridgeName)) return key;
4073 } catch (Exception e) {
4074 logger.error("Error getting Bridge Identifier for {} / {}", node, bridgeName, e);