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.internal.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.internal.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 getIntegrationBridgeOFDPID (Node node) {
759 String bridgeName = adminConfigManager.getIntegrationBridgeName();
760 String brIntId = this.getInternalBridgeUUID(node, bridgeName);
761 if (brIntId == null) {
762 logger.error("Unable to spot Bridge Identifier for {} in {}", bridgeName, node);
766 OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
767 Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brIntId);
768 Set<String> dpids = bridge.getDatapath_id();
769 if (dpids == null || dpids.size() == 0) return 0L;
770 return Long.valueOf(HexEncode.stringToLong((String) dpids.toArray()[0]));
771 } catch (Exception e) {
772 logger.error("Error finding Integration Bridge's OF DPID", e);
776 private void programLocalRules (String networkType, String segmentationId, Node node, Interface intf) {
778 Long dpid = this.getIntegrationBridgeOFDPID(node);
780 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
784 Set<BigInteger> of_ports = intf.getOfport();
785 if (of_ports == null || of_ports.size() <= 0) {
786 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
789 long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
791 Map<String, String> externalIds = intf.getExternal_ids();
792 if (externalIds == null) {
793 logger.error("No external_ids seen in {}", intf);
797 String attachedMac = externalIds.get(ITenantNetworkManager.EXTERNAL_ID_VM_MAC);
798 if (attachedMac == null) {
799 logger.error("No AttachedMac seen in {}", intf);
803 /* Program local rules based on network type */
804 if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
805 logger.debug("Program local vlan rules for interface {}", intf.getName());
806 programLocalVlanRules(node, dpid, segmentationId, attachedMac, localPort);
807 } else if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) ||
808 networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) {
809 logger.debug("Program local bridge rules for interface {}", intf.getName());
810 programLocalBridgeRules(node, dpid, segmentationId, attachedMac, localPort);
812 } catch (Exception e) {
813 logger.error("Exception in programming Local Rules for "+intf+" on "+node, e);
817 private void removeLocalRules (String networkType, String segmentationId, Node node, Interface intf) {
819 Long dpid = this.getIntegrationBridgeOFDPID(node);
821 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
825 Set<BigInteger> of_ports = intf.getOfport();
826 if (of_ports == null || of_ports.size() <= 0) {
827 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
830 long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
832 Map<String, String> externalIds = intf.getExternal_ids();
833 if (externalIds == null) {
834 logger.error("No external_ids seen in {}", intf);
838 String attachedMac = externalIds.get(ITenantNetworkManager.EXTERNAL_ID_VM_MAC);
839 if (attachedMac == null) {
840 logger.error("No AttachedMac seen in {}", intf);
844 /* Program local rules based on network type */
845 if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
846 logger.debug("Remove local vlan rules for interface {}", intf.getName());
847 removeLocalVlanRules(node, dpid, segmentationId, attachedMac, localPort);
848 } else if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) ||
849 networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) {
850 logger.debug("Remove local bridge rules for interface {}", intf.getName());
851 removeLocalBridgeRules(node, dpid, segmentationId, attachedMac, localPort);
853 } catch (Exception e) {
854 logger.error("Exception in removing Local Rules for "+intf+" on "+node, e);
858 private void programTunnelRules (String tunnelType, String segmentationId, InetAddress dst, Node node,
859 Interface intf, boolean local) {
862 Long dpid = this.getIntegrationBridgeOFDPID(node);
864 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
867 OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
869 Set<BigInteger> of_ports = intf.getOfport();
870 if (of_ports == null || of_ports.size() <= 0) {
871 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
874 long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
876 Map<String, String> externalIds = intf.getExternal_ids();
877 if (externalIds == null) {
878 logger.error("No external_ids seen in {}", intf);
882 String attachedMac = externalIds.get(ITenantNetworkManager.EXTERNAL_ID_VM_MAC);
883 if (attachedMac == null) {
884 logger.error("No AttachedMac seen in {}", intf);
888 Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
890 for (org.opendaylight.ovsdb.lib.table.internal.Table<?> row : intfs.values()) {
891 Interface tunIntf = (Interface)row;
892 if (tunIntf.getName().equals(this.getTunnelName(tunnelType, dst))) {
893 of_ports = tunIntf.getOfport();
894 if (of_ports == null || of_ports.size() <= 0) {
895 logger.error("Could NOT Identify Tunnel port {} on {}", tunIntf.getName(), node);
898 long tunnelOFPort = ((BigInteger)of_ports.toArray()[0]).longValue();
900 if (tunnelOFPort == -1) {
901 logger.error("Could NOT Identify Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
904 logger.debug("Identified Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
907 programRemoteEgressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
909 logger.trace("program local ingress tunnel rules: node" + node.getNodeIDString() + " intf " + intf.getName());
911 programLocalIngressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
917 } catch (Exception e) {
922 private void removeTunnelRules (String tunnelType, String segmentationId, InetAddress dst, Node node,
923 Interface intf, boolean local, boolean isLastInstanceOnNode) {
926 Long dpid = this.getIntegrationBridgeOFDPID(node);
928 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
931 OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
933 Set<BigInteger> of_ports = intf.getOfport();
934 if (of_ports == null || of_ports.size() <= 0) {
935 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
938 long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
940 Map<String, String> externalIds = intf.getExternal_ids();
941 if (externalIds == null) {
942 logger.error("No external_ids seen in {}", intf);
946 String attachedMac = externalIds.get(ITenantNetworkManager.EXTERNAL_ID_VM_MAC);
947 if (attachedMac == null) {
948 logger.error("No AttachedMac seen in {}", intf);
952 Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
954 for (org.opendaylight.ovsdb.lib.table.internal.Table<?> row : intfs.values()) {
955 Interface tunIntf = (Interface)row;
956 if (tunIntf.getName().equals(this.getTunnelName(tunnelType, dst))) {
957 of_ports = tunIntf.getOfport();
958 if (of_ports == null || of_ports.size() <= 0) {
959 logger.error("Could NOT Identify Tunnel port {} on {}", tunIntf.getName(), node);
962 long tunnelOFPort = ((BigInteger)of_ports.toArray()[0]).longValue();
964 if (tunnelOFPort == -1) {
965 logger.error("Could NOT Identify Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
968 logger.debug("Identified Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
971 removeRemoteEgressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
973 if (local && isLastInstanceOnNode) {
974 removePerTunnelRules(node, dpid, segmentationId, tunnelOFPort);
980 } catch (Exception e) {
985 private void programVlanRules (NeutronNetwork network, Node node, Interface intf) {
986 logger.debug("Program vlan rules for interface {}", intf.getName());
990 Long dpid = this.getIntegrationBridgeOFDPID(node);
992 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
995 OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
997 Set<BigInteger> of_ports = intf.getOfport();
999 while ((of_ports == null) && (timeout > 0)) {
1000 of_ports = intf.getOfport();
1001 if (of_ports == null || of_ports.size() <= 0) {
1002 // Wait for the OVSDB update to sync up the Local cache.
1008 if (of_ports == null || of_ports.size() <= 0) {
1009 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
1013 Map<String, String> externalIds = intf.getExternal_ids();
1014 if (externalIds == null) {
1015 logger.error("No external_ids seen in {}", intf);
1019 String attachedMac = externalIds.get(tenantNetworkManager.EXTERNAL_ID_VM_MAC);
1020 if (attachedMac == null) {
1021 logger.error("No AttachedMac seen in {}", intf);
1025 Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
1026 if (intfs != null) {
1027 for (org.opendaylight.ovsdb.lib.table.internal.Table<?> row : intfs.values()) {
1028 Interface ethIntf = (Interface)row;
1029 if (ethIntf.getName().equalsIgnoreCase(adminConfigManager.getPhysicalInterfaceName(node, network.getProviderPhysicalNetwork()))) {
1030 of_ports = ethIntf.getOfport();
1032 while ((of_ports == null) && (timeout > 0)) {
1033 of_ports = ethIntf.getOfport();
1034 if (of_ports == null || of_ports.size() <= 0) {
1035 // Wait for the OVSDB update to sync up the Local cache.
1042 if (of_ports == null || of_ports.size() <= 0) {
1043 logger.error("Could NOT Identify eth port {} on {}", ethIntf.getName(), node);
1046 long ethOFPort = ((BigInteger)of_ports.toArray()[0]).longValue();
1048 if (ethOFPort == -1) {
1049 logger.error("Could NOT Identify eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node);
1050 throw new Exception("port number < 0");
1052 logger.debug("Identified eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node);
1054 programRemoteEgressVlanRules(node, dpid, network.getProviderSegmentationID(), attachedMac, ethOFPort);
1055 programLocalIngressVlanRules(node, dpid, network.getProviderSegmentationID(), attachedMac, ethOFPort);
1060 } catch (Exception e) {
1061 logger.error("", e);
1065 private void removeVlanRules (NeutronNetwork network, Node node,
1066 Interface intf, boolean isLastInstanceOnNode) {
1067 logger.debug("Remove vlan rules for interface {}", intf.getName());
1071 Long dpid = this.getIntegrationBridgeOFDPID(node);
1073 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
1076 OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
1078 Set<BigInteger> of_ports = intf.getOfport();
1079 if (of_ports == null || of_ports.size() <= 0) {
1080 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
1084 Map<String, String> externalIds = intf.getExternal_ids();
1085 if (externalIds == null) {
1086 logger.error("No external_ids seen in {}", intf);
1090 String attachedMac = externalIds.get(tenantNetworkManager.EXTERNAL_ID_VM_MAC);
1091 if (attachedMac == null) {
1092 logger.error("No AttachedMac seen in {}", intf);
1096 Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
1097 if (intfs != null) {
1098 for (org.opendaylight.ovsdb.lib.table.internal.Table<?> row : intfs.values()) {
1099 Interface ethIntf = (Interface)row;
1100 if (ethIntf.getName().equalsIgnoreCase(adminConfigManager.getPhysicalInterfaceName(node,
1101 network.getProviderPhysicalNetwork()))) {
1102 of_ports = ethIntf.getOfport();
1103 if (of_ports == null || of_ports.size() <= 0) {
1104 logger.error("Could NOT Identify eth port {} on {}", ethIntf.getName(), node);
1107 long ethOFPort = ((BigInteger)of_ports.toArray()[0]).longValue();
1109 if (ethOFPort == -1) {
1110 logger.error("Could NOT Identify eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node);
1111 throw new Exception("port number < 0");
1113 logger.debug("Identified eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node);
1115 removeRemoteEgressVlanRules(node, dpid, network.getProviderSegmentationID(), attachedMac, ethOFPort);
1116 if (isLastInstanceOnNode) {
1117 removePerVlanRules(node, dpid, network.getProviderSegmentationID(), ethOFPort);
1123 } catch (Exception e) {
1124 logger.error("", e);
1129 public Status handleInterfaceUpdate(NeutronNetwork network, Node srcNode, Interface intf) {
1130 ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, "default", this);
1131 if (switchManager == null) {
1132 logger.error("Unable to identify SwitchManager");
1134 Long dpid = this.getIntegrationBridgeOFDPID(srcNode);
1136 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", srcNode);
1137 return new Status(StatusCode.NOTFOUND);
1139 Set<Node> ofNodes = switchManager.getNodes();
1140 boolean ofNodeFound = false;
1141 if (ofNodes != null) {
1142 for (Node ofNode : ofNodes) {
1143 if (ofNode.toString().contains(dpid+"")) {
1144 logger.debug("Identified the Openflow node via toString {}", ofNode);
1150 logger.error("Unable to find any Node from SwitchManager");
1153 logger.error("Unable to find OF Node for {} with update {} on node {}", dpid, intf, srcNode);
1154 return new Status(StatusCode.NOTFOUND);
1158 IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
1159 List<Node> nodes = connectionService.getNodes();
1160 nodes.remove(srcNode);
1161 this.programLocalRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), srcNode, intf);
1163 if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
1164 this.programVlanRules(network, srcNode, intf);
1165 } else if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)
1166 || network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)){
1167 for (Node dstNode : nodes) {
1168 InetAddress src = adminConfigManager.getTunnelEndPoint(srcNode);
1169 InetAddress dst = adminConfigManager.getTunnelEndPoint(dstNode);
1170 Status status = addTunnelPort(srcNode, network.getProviderNetworkType(), src, dst);
1171 if (status.isSuccess()) {
1172 this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), dst, srcNode, intf, true);
1174 addTunnelPort(dstNode, network.getProviderNetworkType(), dst, src);
1175 if (status.isSuccess()) {
1176 this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), src, dstNode, intf, false);
1181 return new Status(StatusCode.SUCCESS);
1184 private Status triggerInterfaceUpdates(Node node) {
1186 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
1187 Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
1188 if (intfs != null) {
1189 for (org.opendaylight.ovsdb.lib.table.internal.Table<?> row : intfs.values()) {
1190 Interface intf = (Interface)row;
1191 NeutronNetwork network = tenantNetworkManager.getTenantNetworkForInterface(intf);
1192 logger.debug("Trigger Interface update for {}", intf);
1193 if (network != null) {
1194 this.handleInterfaceUpdate(network, node, intf);
1198 } catch (Exception e) {
1199 logger.error("Error Triggering the lost interface updates for "+ node, e);
1200 return new Status(StatusCode.INTERNALERROR, e.getLocalizedMessage());
1202 return new Status(StatusCode.SUCCESS);
1205 public Status handleInterfaceUpdate(String tunnelType, String tunnelKey) {
1206 // TODO Auto-generated method stub
1211 public Status handleInterfaceDelete(String tunnelType, NeutronNetwork network, Node srcNode, Interface intf,
1212 boolean isLastInstanceOnNode) {
1213 Status status = new Status(StatusCode.SUCCESS);
1214 IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
1215 List<Node> nodes = connectionService.getNodes();
1216 nodes.remove(srcNode);
1218 logger.info("Delete intf " + intf.getName() + " isLastInstanceOnNode " + isLastInstanceOnNode);
1219 List<String> phyIfName = adminConfigManager.getAllPhysicalInterfaceNames(srcNode);
1220 if (intf.getType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)
1221 || intf.getType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)) {
1222 /* Delete tunnel port */
1224 OvsDBMap<String, String> options = intf.getOptions();
1225 InetAddress src = InetAddress.getByName(options.get("local_ip"));
1226 InetAddress dst = InetAddress.getByName(options.get("remote_ip"));
1227 status = deleteTunnelPort(srcNode, intf.getType(), src, dst);
1228 } catch (Exception e) {
1229 logger.error(e.getMessage(), e);
1231 } else if (phyIfName.contains(intf.getName())) {
1232 deletePhysicalPort(srcNode, intf.getName());
1234 /* delete all other interfaces */
1235 this.removeLocalRules(network.getProviderNetworkType(), network.getProviderSegmentationID(),
1238 if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
1239 this.removeVlanRules(network, srcNode,
1240 intf, isLastInstanceOnNode);
1241 } else if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)
1242 || network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) {
1244 for (Node dstNode : nodes) {
1245 InetAddress src = adminConfigManager.getTunnelEndPoint(srcNode);
1246 InetAddress dst = adminConfigManager.getTunnelEndPoint(dstNode);
1247 logger.info("Remove tunnel rules for interface " + intf.getName() + " on srcNode" + srcNode.getNodeIDString());
1248 this.removeTunnelRules(tunnelType, network.getProviderSegmentationID(),
1249 dst, srcNode, intf, true, isLastInstanceOnNode);
1250 logger.info("Remove tunnel rules for interface " + intf.getName() + " on dstNode" + dstNode.getNodeIDString());
1251 this.removeTunnelRules(tunnelType, network.getProviderSegmentationID(),
1252 src, dstNode, intf, false, isLastInstanceOnNode);
1260 public void initializeFlowRules(Node node) {
1261 this.initializeFlowRules(node, adminConfigManager.getIntegrationBridgeName());
1262 this.triggerInterfaceUpdates(node);
1269 private void initializeFlowRules(Node node, String bridgeName) {
1270 Long dpid = this.getIntegrationBridgeOFDPID(node);
1272 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
1279 * Match: LLDP (0x88CCL)
1280 * Action: Packet_In to Controller Reserved Port
1283 writeLLDPRule(dpid);
1287 * Create an LLDP Flow Rule to encapsulate into
1288 * a packet_in that is sent to the controller
1289 * for topology handling.
1290 * Match: Ethertype 0x88CCL
1291 * Action: Punt to Controller in a Packet_In msg
1294 private void writeLLDPRule(Long dpidLong) {
1296 String nodeName = "openflow:" + dpidLong;
1297 EtherType etherType = new EtherType(0x88CCL);
1299 MatchBuilder matchBuilder = new MatchBuilder();
1300 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1301 FlowBuilder flowBuilder = new FlowBuilder();
1303 // Create Match(es) and Set them in the FlowBuilder Object
1304 flowBuilder.setMatch(createEtherTypeMatch(matchBuilder, etherType).build());
1306 // Create the OF Actions and Instructions
1307 InstructionBuilder ib = new InstructionBuilder();
1308 InstructionsBuilder isb = new InstructionsBuilder();
1310 // Instructions List Stores Individual Instructions
1311 List<Instruction> instructions = new ArrayList<Instruction>();
1313 // Call the InstructionBuilder Methods Containing Actions
1314 createSendToControllerInstructions(ib);
1316 ib.setKey(new InstructionKey(0));
1317 instructions.add(ib.build());
1319 // Add InstructionBuilder to the Instruction(s)Builder List
1320 isb.setInstruction(instructions);
1322 // Add InstructionsBuilder to FlowBuilder
1323 flowBuilder.setInstructions(isb.build());
1325 String flowId = "LLDP";
1326 flowBuilder.setId(new FlowId(flowId));
1327 FlowKey key = new FlowKey(new FlowId(flowId));
1328 flowBuilder.setBarrier(true);
1329 flowBuilder.setTableId((short) 0);
1330 flowBuilder.setKey(key);
1331 flowBuilder.setFlowName(flowId);
1332 flowBuilder.setHardTimeout(0);
1333 flowBuilder.setIdleTimeout(0);
1334 writeFlow(flowBuilder, nodeBuilder);
1338 * (Table:0) Ingress Tunnel Traffic
1339 * Match: OpenFlow InPort and Tunnel ID
1340 * Action: GOTO Local Table (10)
1341 * table=0,tun_id=0x5,in_port=10, actions=goto_table:2
1344 private void handleTunnelIn(Long dpidLong, Short writeTable,
1345 Short goToTableId, String segmentationId,
1346 Long ofPort, boolean write) {
1348 String nodeName = "openflow:" + dpidLong;
1350 BigInteger tunnelId = new BigInteger(segmentationId);
1351 MatchBuilder matchBuilder = new MatchBuilder();
1352 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1353 FlowBuilder flowBuilder = new FlowBuilder();
1355 // Create Match(es) and Set them in the FlowBuilder Object
1356 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, tunnelId).build());
1357 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, ofPort).build());
1360 // Create the OF Actions and Instructions
1361 InstructionBuilder ib = new InstructionBuilder();
1362 InstructionsBuilder isb = new InstructionsBuilder();
1364 // Instructions List Stores Individual Instructions
1365 List<Instruction> instructions = new ArrayList<Instruction>();
1367 // Call the InstructionBuilder Methods Containing Actions
1368 createGotoTableInstructions(ib, goToTableId);
1370 ib.setKey(new InstructionKey(0));
1371 instructions.add(ib.build());
1373 // Add InstructionBuilder to the Instruction(s)Builder List
1374 isb.setInstruction(instructions);
1376 // Add InstructionsBuilder to FlowBuilder
1377 flowBuilder.setInstructions(isb.build());
1380 String flowId = "TunnelIn_"+segmentationId+"_"+ofPort;
1381 // Add Flow Attributes
1382 flowBuilder.setId(new FlowId(flowId));
1383 FlowKey key = new FlowKey(new FlowId(flowId));
1384 flowBuilder.setStrict(true);
1385 flowBuilder.setBarrier(false);
1386 flowBuilder.setTableId(writeTable);
1387 flowBuilder.setKey(key);
1388 flowBuilder.setFlowName(flowId);
1389 flowBuilder.setHardTimeout(0);
1390 flowBuilder.setIdleTimeout(0);
1393 writeFlow(flowBuilder, nodeBuilder);
1395 removeFlow(flowBuilder, nodeBuilder);
1400 * (Table:0) Ingress VLAN Traffic
1401 * Match: OpenFlow InPort and vlan ID
1402 * Action: GOTO Local Table (20)
1403 * table=0,vlan_id=0x5,in_port=10, actions=goto_table:2
1406 private void handleVlanIn(Long dpidLong, Short writeTable, Short goToTableId,
1407 String segmentationId, Long ethPort, boolean write) {
1409 String nodeName = "openflow:" + dpidLong;
1411 MatchBuilder matchBuilder = new MatchBuilder();
1412 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1413 FlowBuilder flowBuilder = new FlowBuilder();
1415 // Create Match(es) and Set them in the FlowBuilder Object
1416 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
1417 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, ethPort).build());
1420 // Create the OF Actions and Instructions
1421 InstructionBuilder ib = new InstructionBuilder();
1422 InstructionsBuilder isb = new InstructionsBuilder();
1424 // Instructions List Stores Individual Instructions
1425 List<Instruction> instructions = new ArrayList<Instruction>();
1427 // Call the InstructionBuilder Methods Containing Actions
1428 createGotoTableInstructions(ib, goToTableId);
1430 ib.setKey(new InstructionKey(0));
1431 instructions.add(ib.build());
1433 // Add InstructionBuilder to the Instruction(s)Builder List
1434 isb.setInstruction(instructions);
1436 // Add InstructionsBuilder to FlowBuilder
1437 flowBuilder.setInstructions(isb.build());
1440 String flowId = "VlanIn_"+segmentationId+"_"+ethPort;
1441 // Add Flow Attributes
1442 flowBuilder.setId(new FlowId(flowId));
1443 FlowKey key = new FlowKey(new FlowId(flowId));
1444 flowBuilder.setStrict(true);
1445 flowBuilder.setBarrier(false);
1446 flowBuilder.setTableId(writeTable);
1447 flowBuilder.setKey(key);
1448 flowBuilder.setFlowName(flowId);
1449 flowBuilder.setHardTimeout(0);
1450 flowBuilder.setIdleTimeout(0);
1452 writeFlow(flowBuilder, nodeBuilder);
1454 removeFlow(flowBuilder, nodeBuilder);
1459 * (Table:0) Egress VM Traffic Towards TEP
1460 * Match: Destination Ethernet Addr and OpenFlow InPort
1461 * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
1462 * table=0,in_port=2,dl_src=00:00:00:00:00:01 \
1463 * actions=set_field:5->tun_id,goto_table=1"
1466 private void handleLocalInPort(Long dpidLong, Short writeTable, Short goToTableId,
1467 String segmentationId, Long inPort, String attachedMac,
1470 String nodeName = "openflow:" + dpidLong;
1472 MatchBuilder matchBuilder = new MatchBuilder();
1473 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1474 FlowBuilder flowBuilder = new FlowBuilder();
1476 // Create the OF Match using MatchBuilder
1477 flowBuilder.setMatch(createEthSrcMatch(matchBuilder, new MacAddress(attachedMac)).build());
1478 // TODO Broken In_Port Match
1479 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
1481 String flowId = "LocalMac_"+segmentationId+"_"+inPort+"_"+attachedMac;
1482 // Add Flow Attributes
1483 flowBuilder.setId(new FlowId(flowId));
1484 FlowKey key = new FlowKey(new FlowId(flowId));
1485 flowBuilder.setStrict(true);
1486 flowBuilder.setBarrier(false);
1487 flowBuilder.setTableId(writeTable);
1488 flowBuilder.setKey(key);
1489 flowBuilder.setFlowName(flowId);
1490 flowBuilder.setHardTimeout(0);
1491 flowBuilder.setIdleTimeout(0);
1494 // Instantiate the Builders for the OF Actions and Instructions
1495 InstructionBuilder ib = new InstructionBuilder();
1496 InstructionsBuilder isb = new InstructionsBuilder();
1498 // Instructions List Stores Individual Instructions
1499 List<Instruction> instructions = new ArrayList<Instruction>();
1501 // GOTO Instuctions Need to be added first to the List
1502 createGotoTableInstructions(ib, goToTableId);
1504 ib.setKey(new InstructionKey(0));
1505 instructions.add(ib.build());
1506 // TODO Broken SetTunID
1507 createSetTunnelIdInstructions(ib, new BigInteger(segmentationId));
1509 ib.setKey(new InstructionKey(1));
1510 instructions.add(ib.build());
1512 // Add InstructionBuilder to the Instruction(s)Builder List
1513 isb.setInstruction(instructions);
1515 // Add InstructionsBuilder to FlowBuilder
1516 flowBuilder.setInstructions(isb.build());
1518 writeFlow(flowBuilder, nodeBuilder);
1520 removeFlow(flowBuilder, nodeBuilder);
1525 * (Table:0) Egress VM Traffic Towards TEP
1526 * Match: Source Ethernet Addr and OpenFlow InPort
1527 * Instruction: Set VLANID and GOTO Table Egress (n)
1528 * table=0,in_port=2,dl_src=00:00:00:00:00:01 \
1529 * actions=push_vlan, set_field:5->vlan_id,goto_table=1"
1532 private void handleLocalInPortSetVlan(Long dpidLong, Short writeTable,
1533 Short goToTableId, String segmentationId,
1534 Long inPort, String attachedMac,
1537 String nodeName = "openflow:" + dpidLong;
1539 MatchBuilder matchBuilder = new MatchBuilder();
1540 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1541 FlowBuilder flowBuilder = new FlowBuilder();
1543 // Create the OF Match using MatchBuilder
1544 flowBuilder.setMatch(createEthSrcMatch(matchBuilder, new MacAddress(attachedMac)).build());
1545 // TODO Broken In_Port Match
1546 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
1548 String flowId = "LocalMac_"+segmentationId+"_"+inPort+"_"+attachedMac;
1549 // Add Flow Attributes
1550 flowBuilder.setId(new FlowId(flowId));
1551 FlowKey key = new FlowKey(new FlowId(flowId));
1552 flowBuilder.setStrict(true);
1553 flowBuilder.setBarrier(false);
1554 flowBuilder.setTableId(writeTable);
1555 flowBuilder.setKey(key);
1556 flowBuilder.setFlowName(flowId);
1557 flowBuilder.setHardTimeout(0);
1558 flowBuilder.setIdleTimeout(0);
1561 // Instantiate the Builders for the OF Actions and Instructions
1562 InstructionBuilder ib = new InstructionBuilder();
1563 InstructionsBuilder isb = new InstructionsBuilder();
1565 // Instructions List Stores Individual Instructions
1566 List<Instruction> instructions = new ArrayList<Instruction>();
1568 // GOTO Instructions Need to be added first to the List
1569 createGotoTableInstructions(ib, goToTableId);
1571 ib.setKey(new InstructionKey(0));
1572 instructions.add(ib.build());
1573 // Set VLAN ID Instruction
1574 createSetVlanInstructions(ib, new VlanId(Integer.valueOf(segmentationId)));
1576 ib.setKey(new InstructionKey(1));
1577 instructions.add(ib.build());
1579 // Add InstructionBuilder to the Instruction(s)Builder List
1580 isb.setInstruction(instructions);
1582 // Add InstructionsBuilder to FlowBuilder
1583 flowBuilder.setInstructions(isb.build());
1585 writeFlow(flowBuilder, nodeBuilder);
1587 removeFlow(flowBuilder, nodeBuilder);
1592 * (Table:0) Drop frames source from a VM that do not
1593 * match the associated MAC address of the local VM.
1594 * Match: Low priority anything not matching the VM SMAC
1596 * table=0,priority=16384,in_port=1 actions=drop"
1599 private void handleDropSrcIface(Long dpidLong, Long inPort, boolean write) {
1601 String nodeName = "openflow:" + dpidLong;
1603 MatchBuilder matchBuilder = new MatchBuilder();
1604 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1605 FlowBuilder flowBuilder = new FlowBuilder();
1607 // Create the OF Match using MatchBuilder
1608 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
1611 // Instantiate the Builders for the OF Actions and Instructions
1612 InstructionBuilder ib = new InstructionBuilder();
1613 InstructionsBuilder isb = new InstructionsBuilder();
1615 // Instructions List Stores Individual Instructions
1616 List<Instruction> instructions = new ArrayList<Instruction>();
1618 // Call the InstructionBuilder Methods Containing Actions
1619 createDropInstructions(ib);
1621 ib.setKey(new InstructionKey(0));
1622 instructions.add(ib.build());
1624 // Add InstructionBuilder to the Instruction(s)Builder List
1625 isb.setInstruction(instructions);
1627 // Add InstructionsBuilder to FlowBuilder
1628 flowBuilder.setInstructions(isb.build());
1631 String flowId = "DropFilter_"+inPort;
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((short) 0);
1638 flowBuilder.setKey(key);
1639 flowBuilder.setFlowName(flowId);
1640 flowBuilder.setPriority(8192);
1641 flowBuilder.setHardTimeout(0);
1642 flowBuilder.setIdleTimeout(0);
1644 writeFlow(flowBuilder, nodeBuilder);
1646 removeFlow(flowBuilder, nodeBuilder);
1651 * (Table:1) Egress Tunnel Traffic
1652 * Match: Destination Ethernet Addr and Local InPort
1653 * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
1654 * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
1655 * actions=output:10,goto_table:2"
1657 private void handleTunnelOut(Long dpidLong, Short writeTable,
1658 Short goToTableId, String segmentationId,
1659 Long OFPortOut, String attachedMac,
1662 String nodeName = "openflow:" + dpidLong;
1664 MatchBuilder matchBuilder = new MatchBuilder();
1665 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1666 FlowBuilder flowBuilder = new FlowBuilder();
1668 // Create the OF Match using MatchBuilder
1669 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
1670 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
1672 String flowId = "TunnelOut_"+segmentationId+"_"+OFPortOut+"_"+attachedMac;
1673 // Add Flow Attributes
1674 flowBuilder.setId(new FlowId(flowId));
1675 FlowKey key = new FlowKey(new FlowId(flowId));
1676 flowBuilder.setStrict(true);
1677 flowBuilder.setBarrier(false);
1678 flowBuilder.setTableId(writeTable);
1679 flowBuilder.setKey(key);
1680 flowBuilder.setFlowName(flowId);
1681 flowBuilder.setHardTimeout(0);
1682 flowBuilder.setIdleTimeout(0);
1685 // Instantiate the Builders for the OF Actions and Instructions
1686 InstructionBuilder ib = new InstructionBuilder();
1687 InstructionsBuilder isb = new InstructionsBuilder();
1689 // Instructions List Stores Individual Instructions
1690 List<Instruction> instructions = new ArrayList<Instruction>();
1693 createGotoTableInstructions(ib, goToTableId);
1695 ib.setKey(new InstructionKey(0));
1696 instructions.add(ib.build());
1697 // Set the Output Port/Iface
1698 createOutputPortInstructions(ib, dpidLong, OFPortOut);
1700 ib.setKey(new InstructionKey(1));
1701 instructions.add(ib.build());
1703 // Add InstructionBuilder to the Instruction(s)Builder List
1704 isb.setInstruction(instructions);
1706 // Add InstructionsBuilder to FlowBuilder
1707 flowBuilder.setInstructions(isb.build());
1709 writeFlow(flowBuilder, nodeBuilder);
1711 removeFlow(flowBuilder, nodeBuilder);
1716 * (Table:1) Egress VLAN Traffic
1717 * Match: Destination Ethernet Addr and VLAN id
1718 * Instruction: GOTO Table Table 2
1719 * table=1,vlan_id=0x5,dl_dst=00:00:00:00:00:08 \
1720 * actions= goto_table:2"
1723 private void handleVlanOut(Long dpidLong, Short writeTable,
1724 Short goToTableId, String segmentationId,
1725 Long ethPort, String attachedMac, boolean write) {
1727 String nodeName = "openflow:" + dpidLong;
1729 MatchBuilder matchBuilder = new MatchBuilder();
1730 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1731 FlowBuilder flowBuilder = new FlowBuilder();
1733 // Create the OF Match using MatchBuilder
1734 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
1735 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
1737 String flowId = "VlanOut_"+segmentationId+"_"+ethPort+"_"+attachedMac;
1738 // Add Flow Attributes
1739 flowBuilder.setId(new FlowId(flowId));
1740 FlowKey key = new FlowKey(new FlowId(flowId));
1741 flowBuilder.setStrict(true);
1742 flowBuilder.setBarrier(false);
1743 flowBuilder.setTableId(writeTable);
1744 flowBuilder.setKey(key);
1745 flowBuilder.setFlowName(flowId);
1746 flowBuilder.setHardTimeout(0);
1747 flowBuilder.setIdleTimeout(0);
1750 // Instantiate the Builders for the OF Actions and Instructions
1751 InstructionBuilder ib = new InstructionBuilder();
1752 InstructionsBuilder isb = new InstructionsBuilder();
1754 // Instructions List Stores Individual Instructions
1755 List<Instruction> instructions = new ArrayList<Instruction>();
1758 createGotoTableInstructions(ib, goToTableId);
1760 ib.setKey(new InstructionKey(0));
1761 instructions.add(ib.build());
1763 // Add InstructionBuilder to the Instruction(s)Builder List
1764 isb.setInstruction(instructions);
1766 // Add InstructionsBuilder to FlowBuilder
1767 flowBuilder.setInstructions(isb.build());
1769 writeFlow(flowBuilder, nodeBuilder);
1771 removeFlow(flowBuilder, nodeBuilder);
1776 * (Table:1) Egress Tunnel Traffic
1777 * Match: Destination Ethernet Addr and Local InPort
1778 * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
1779 * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
1780 * actions=output:10,output:11,goto_table:2
1783 private void handleTunnelFloodOut(Long dpidLong, Short writeTable,
1784 Short localTable, String segmentationId,
1785 Long OFPortOut, boolean write) {
1787 String nodeName = "openflow:" + dpidLong;
1789 MatchBuilder matchBuilder = new MatchBuilder();
1790 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1791 FlowBuilder flowBuilder = new FlowBuilder();
1793 // Create the OF Match using MatchBuilder
1795 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
1798 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
1800 String flowId = "TunnelFloodOut_"+segmentationId;
1801 // Add Flow Attributes
1802 flowBuilder.setId(new FlowId(flowId));
1803 FlowKey key = new FlowKey(new FlowId(flowId));
1804 flowBuilder.setBarrier(true);
1805 flowBuilder.setTableId(writeTable);
1806 flowBuilder.setKey(key);
1807 flowBuilder.setPriority(16384);
1808 flowBuilder.setFlowName(flowId);
1809 flowBuilder.setHardTimeout(0);
1810 flowBuilder.setIdleTimeout(0);
1812 Flow flow = this.getFlow(flowBuilder, nodeBuilder);
1813 // Instantiate the Builders for the OF Actions and Instructions
1814 InstructionBuilder ib = new InstructionBuilder();
1815 InstructionsBuilder isb = new InstructionsBuilder();
1816 List<Instruction> instructions = new ArrayList<Instruction>();
1817 List<Instruction> existingInstructions = null;
1819 Instructions ins = flow.getInstructions();
1821 existingInstructions = ins.getInstruction();
1827 createGotoTableInstructions(ib, localTable);
1829 ib.setKey(new InstructionKey(0));
1830 instructions.add(ib.build());
1831 // Set the Output Port/Iface
1832 //createOutputGroupInstructions(nodeBuilder, ib, dpidLong, OFPortOut, existingInstructions);
1833 createOutputPortInstructions(ib, dpidLong, OFPortOut, existingInstructions);
1835 ib.setKey(new InstructionKey(1));
1836 instructions.add(ib.build());
1838 // Add InstructionBuilder to the Instruction(s)Builder List
1839 isb.setInstruction(instructions);
1841 // Add InstructionsBuilder to FlowBuilder
1842 flowBuilder.setInstructions(isb.build());
1844 writeFlow(flowBuilder, nodeBuilder);
1846 /* remove port from action list */
1847 boolean flowRemove = removeOutputPortFromInstructions(ib, dpidLong,
1848 OFPortOut, existingInstructions);
1850 /* if all port are removed, remove the flow too. */
1851 removeFlow(flowBuilder, nodeBuilder);
1853 /* Install instruction with new output port list*/
1855 ib.setKey(new InstructionKey(0));
1856 instructions.add(ib.build());
1858 // Add InstructionBuilder to the Instruction(s)Builder List
1859 isb.setInstruction(instructions);
1861 // Add InstructionsBuilder to FlowBuilder
1862 flowBuilder.setInstructions(isb.build());
1868 * (Table:1) Egress VLAN Traffic
1869 * Match: Destination Ethernet Addr and VLAN id
1870 * Instruction: GOTO table 2 and Output port eth interface
1871 * Example: table=1,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
1872 * actions=output:eth1,goto_table:2
1875 private void handleVlanFloodOut(Long dpidLong, Short writeTable,
1876 Short localTable, String segmentationId,
1877 Long ethPort, boolean write) {
1879 String nodeName = "openflow:" + dpidLong;
1881 MatchBuilder matchBuilder = new MatchBuilder();
1882 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1883 FlowBuilder flowBuilder = new FlowBuilder();
1885 // Create the OF Match using MatchBuilder
1887 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
1889 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
1891 String flowId = "VlanFloodOut_"+segmentationId;
1892 // Add Flow Attributes
1893 flowBuilder.setId(new FlowId(flowId));
1894 FlowKey key = new FlowKey(new FlowId(flowId));
1895 flowBuilder.setBarrier(true);
1896 flowBuilder.setTableId(writeTable);
1897 flowBuilder.setKey(key);
1898 flowBuilder.setPriority(16384);
1899 flowBuilder.setFlowName(flowId);
1900 flowBuilder.setHardTimeout(0);
1901 flowBuilder.setIdleTimeout(0);
1903 Flow flow = this.getFlow(flowBuilder, nodeBuilder);
1904 // Instantiate the Builders for the OF Actions and Instructions
1905 InstructionBuilder ib = new InstructionBuilder();
1906 InstructionsBuilder isb = new InstructionsBuilder();
1907 List<Instruction> instructions = new ArrayList<Instruction>();
1911 createGotoTableInstructions(ib, localTable);
1913 ib.setKey(new InstructionKey(0));
1914 instructions.add(ib.build());
1915 // Set the Output Port/Iface
1916 createOutputPortInstructions(ib, dpidLong, ethPort);
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 removeFlow(flowBuilder, nodeBuilder);
1934 * (Table:1) Table Drain w/ Catch All
1936 * Action: GOTO Local Table (10)
1937 * table=2,priority=8192,tun_id=0x5 actions=drop
1940 private void handleTunnelMiss(Long dpidLong, Short writeTable,
1941 Short goToTableId, String segmentationId,
1944 String nodeName = "openflow:" + dpidLong;
1946 MatchBuilder matchBuilder = new MatchBuilder();
1947 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1948 FlowBuilder flowBuilder = new FlowBuilder();
1950 // Create Match(es) and Set them in the FlowBuilder Object
1951 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
1954 // Create the OF Actions and Instructions
1955 InstructionBuilder ib = new InstructionBuilder();
1956 InstructionsBuilder isb = new InstructionsBuilder();
1958 // Instructions List Stores Individual Instructions
1959 List<Instruction> instructions = new ArrayList<Instruction>();
1961 // Call the InstructionBuilder Methods Containing Actions
1962 createGotoTableInstructions(ib, goToTableId);
1964 ib.setKey(new InstructionKey(0));
1965 instructions.add(ib.build());
1967 // Add InstructionBuilder to the Instruction(s)Builder List
1968 isb.setInstruction(instructions);
1970 // Add InstructionsBuilder to FlowBuilder
1971 flowBuilder.setInstructions(isb.build());
1974 String flowId = "TunnelMiss_"+segmentationId;
1975 // Add Flow Attributes
1976 flowBuilder.setId(new FlowId(flowId));
1977 FlowKey key = new FlowKey(new FlowId(flowId));
1978 flowBuilder.setStrict(true);
1979 flowBuilder.setBarrier(false);
1980 flowBuilder.setTableId(writeTable);
1981 flowBuilder.setKey(key);
1982 flowBuilder.setPriority(8192);
1983 flowBuilder.setFlowName(flowId);
1984 flowBuilder.setHardTimeout(0);
1985 flowBuilder.setIdleTimeout(0);
1987 writeFlow(flowBuilder, nodeBuilder);
1989 removeFlow(flowBuilder, nodeBuilder);
1995 * (Table:1) Table Drain w/ Catch All
1997 * Action: Output port eth interface
1998 * table=1,priority=8192,vlan_id=0x5 actions= output port:eth1
2001 private void handleVlanMiss(Long dpidLong, Short writeTable,
2002 Short goToTableId, String segmentationId,
2003 Long ethPort, boolean write) {
2005 String nodeName = "openflow:" + dpidLong;
2007 MatchBuilder matchBuilder = new MatchBuilder();
2008 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2009 FlowBuilder flowBuilder = new FlowBuilder();
2011 // Create Match(es) and Set them in the FlowBuilder Object
2012 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
2015 // Create the OF Actions and Instructions
2016 InstructionBuilder ib = new InstructionBuilder();
2017 InstructionsBuilder isb = new InstructionsBuilder();
2019 // Instructions List Stores Individual Instructions
2020 List<Instruction> instructions = new ArrayList<Instruction>();
2022 // Call the InstructionBuilder Methods Containing Actions
2023 //createGotoTableInstructions(ib, goToTableId);
2025 //ib.setKey(new InstructionKey(0));
2026 //instructions.add(ib.build());
2027 // Set the Output Port/Iface
2028 createOutputPortInstructions(ib, dpidLong, ethPort);
2030 ib.setKey(new InstructionKey(1));
2031 instructions.add(ib.build());
2033 // Add InstructionBuilder to the Instruction(s)Builder List
2034 isb.setInstruction(instructions);
2036 // Add InstructionsBuilder to FlowBuilder
2037 flowBuilder.setInstructions(isb.build());
2040 String flowId = "VlanMiss_"+segmentationId;
2041 // Add Flow Attributes
2042 flowBuilder.setId(new FlowId(flowId));
2043 FlowKey key = new FlowKey(new FlowId(flowId));
2044 flowBuilder.setStrict(true);
2045 flowBuilder.setBarrier(false);
2046 flowBuilder.setTableId(writeTable);
2047 flowBuilder.setKey(key);
2048 flowBuilder.setPriority(8192);
2049 flowBuilder.setFlowName(flowId);
2050 flowBuilder.setHardTimeout(0);
2051 flowBuilder.setIdleTimeout(0);
2053 writeFlow(flowBuilder, nodeBuilder);
2055 removeFlow(flowBuilder, nodeBuilder);
2060 * (Table:1) Local Broadcast Flood
2061 * Match: Tunnel ID and dMAC
2062 * Action: Output Port
2063 * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
2066 private void handleLocalUcastOut(Long dpidLong, Short writeTable,
2067 String segmentationId, Long localPort,
2068 String attachedMac, boolean write) {
2070 String nodeName = "openflow:" + dpidLong;
2072 MatchBuilder matchBuilder = new MatchBuilder();
2073 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2074 FlowBuilder flowBuilder = new FlowBuilder();
2076 // Create the OF Match using MatchBuilder
2077 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
2078 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
2080 String flowId = "UcastOut_"+segmentationId+"_"+localPort+"_"+attachedMac;
2081 // Add Flow Attributes
2082 flowBuilder.setId(new FlowId(flowId));
2083 FlowKey key = new FlowKey(new FlowId(flowId));
2084 flowBuilder.setStrict(true);
2085 flowBuilder.setBarrier(false);
2086 flowBuilder.setTableId(writeTable);
2087 flowBuilder.setKey(key);
2088 flowBuilder.setFlowName(flowId);
2089 flowBuilder.setHardTimeout(0);
2090 flowBuilder.setIdleTimeout(0);
2093 // Instantiate the Builders for the OF Actions and Instructions
2094 InstructionBuilder ib = new InstructionBuilder();
2095 InstructionsBuilder isb = new InstructionsBuilder();
2097 // Instructions List Stores Individual Instructions
2098 List<Instruction> instructions = new ArrayList<Instruction>();
2100 // Set the Output Port/Iface
2101 createOutputPortInstructions(ib, dpidLong, localPort);
2103 ib.setKey(new InstructionKey(0));
2104 instructions.add(ib.build());
2106 // Add InstructionBuilder to the Instruction(s)Builder List
2107 isb.setInstruction(instructions);
2109 // Add InstructionsBuilder to FlowBuilder
2110 flowBuilder.setInstructions(isb.build());
2111 writeFlow(flowBuilder, nodeBuilder);
2113 removeFlow(flowBuilder, nodeBuilder);
2118 * (Table:2) Local VLAN unicast
2119 * Match: VLAN ID and dMAC
2120 * Action: Output Port
2121 * table=2,vlan_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
2124 private void handleLocalVlanUcastOut(Long dpidLong, Short writeTable,
2125 String segmentationId, Long localPort,
2126 String attachedMac, boolean write) {
2128 String nodeName = "openflow:" + dpidLong;
2130 MatchBuilder matchBuilder = new MatchBuilder();
2131 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2132 FlowBuilder flowBuilder = new FlowBuilder();
2134 // Create the OF Match using MatchBuilder
2135 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
2136 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
2138 String flowId = "VlanUcastOut_"+segmentationId+"_"+localPort+"_"+attachedMac;
2139 // Add Flow Attributes
2140 flowBuilder.setId(new FlowId(flowId));
2141 FlowKey key = new FlowKey(new FlowId(flowId));
2142 flowBuilder.setStrict(true);
2143 flowBuilder.setBarrier(false);
2144 flowBuilder.setTableId(writeTable);
2145 flowBuilder.setKey(key);
2146 flowBuilder.setFlowName(flowId);
2147 flowBuilder.setHardTimeout(0);
2148 flowBuilder.setIdleTimeout(0);
2151 // Instantiate the Builders for the OF Actions and Instructions
2152 InstructionBuilder ib = new InstructionBuilder();
2153 InstructionsBuilder isb = new InstructionsBuilder();
2155 // Instructions List Stores Individual Instructions
2156 List<Instruction> instructions = new ArrayList<Instruction>();
2157 List<Instruction> instructions_tmp = new ArrayList<Instruction>();
2159 /* Strip vlan and store to tmp instruction space*/
2160 createPopVlanInstructions(ib);
2162 ib.setKey(new InstructionKey(0));
2163 instructions_tmp.add(ib.build());
2165 // Set the Output Port/Iface
2166 ib = new InstructionBuilder();
2167 addOutputPortInstructions(ib, dpidLong, localPort, instructions_tmp);
2169 ib.setKey(new InstructionKey(0));
2170 instructions.add(ib.build());
2172 // Add InstructionBuilder to the Instruction(s)Builder List
2173 isb.setInstruction(instructions);
2175 // Add InstructionsBuilder to FlowBuilder
2176 flowBuilder.setInstructions(isb.build());
2177 writeFlow(flowBuilder, nodeBuilder);
2179 removeFlow(flowBuilder, nodeBuilder);
2184 * (Table:2) Local Broadcast Flood
2185 * Match: Tunnel ID and dMAC (::::FF:FF)
2186 * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
2187 * actions=output:2,3,4,5
2190 private void handleLocalBcastOut(Long dpidLong, Short writeTable,
2191 String segmentationId, Long localPort,
2194 String nodeName = "openflow:" + dpidLong;
2196 MatchBuilder matchBuilder = new MatchBuilder();
2197 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2198 FlowBuilder flowBuilder = new FlowBuilder();
2200 // Create the OF Match using MatchBuilder
2201 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
2202 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
2204 String flowId = "BcastOut_"+segmentationId;
2205 // Add Flow Attributes
2206 flowBuilder.setId(new FlowId(flowId));
2207 FlowKey key = new FlowKey(new FlowId(flowId));
2208 flowBuilder.setStrict(true);
2209 flowBuilder.setBarrier(false);
2210 flowBuilder.setTableId(writeTable);
2211 flowBuilder.setKey(key);
2212 flowBuilder.setPriority(16384);
2213 flowBuilder.setFlowName(flowId);
2214 flowBuilder.setHardTimeout(0);
2215 flowBuilder.setIdleTimeout(0);
2216 Flow flow = this.getFlow(flowBuilder, nodeBuilder);
2217 // Instantiate the Builders for the OF Actions and Instructions
2218 InstructionBuilder ib = new InstructionBuilder();
2219 InstructionsBuilder isb = new InstructionsBuilder();
2220 List<Instruction> instructions = new ArrayList<Instruction>();
2221 List<Instruction> existingInstructions = null;
2223 Instructions ins = flow.getInstructions();
2225 existingInstructions = ins.getInstruction();
2230 // Create output port list
2231 createOutputPortInstructions(ib, dpidLong, localPort, existingInstructions);
2233 ib.setKey(new InstructionKey(0));
2234 instructions.add(ib.build());
2236 // Add InstructionBuilder to the Instruction(s)Builder List
2237 isb.setInstruction(instructions);
2239 // Add InstructionsBuilder to FlowBuilder
2240 flowBuilder.setInstructions(isb.build());
2242 writeFlow(flowBuilder, nodeBuilder);
2244 boolean flowRemove = removeOutputPortFromInstructions(ib, dpidLong, localPort,
2245 existingInstructions);
2247 /* if all ports are removed, remove flow */
2248 removeFlow(flowBuilder, nodeBuilder);
2250 /* Install instruction with new output port list*/
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());
2261 writeFlow(flowBuilder, nodeBuilder);
2267 * (Table:2) Local VLAN Broadcast Flood
2268 * Match: vlan ID and dMAC (::::FF:FF)
2269 * table=2,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
2270 * actions=strip_vlan, output:2,3,4,5
2273 private void handleLocalVlanBcastOut(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(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(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 = "VlanBcastOut_"+segmentationId;
2288 // Add Flow Attributes
2289 flowBuilder.setId(new FlowId(flowId));
2290 FlowKey key = new FlowKey(new FlowId(flowId));
2291 flowBuilder.setStrict(true);
2292 flowBuilder.setBarrier(false);
2293 flowBuilder.setTableId(writeTable);
2294 flowBuilder.setKey(key);
2295 flowBuilder.setPriority(16384);
2296 flowBuilder.setFlowName(flowId);
2297 flowBuilder.setHardTimeout(0);
2298 flowBuilder.setIdleTimeout(0);
2299 Flow flow = this.getFlow(flowBuilder, nodeBuilder);
2300 // Instantiate the Builders for the OF Actions and Instructions
2301 InstructionBuilder ib = new InstructionBuilder();
2302 InstructionsBuilder isb = new InstructionsBuilder();
2303 List<Instruction> instructions = new ArrayList<Instruction>();
2304 List<Instruction> existingInstructions = null;
2305 boolean add_pop_vlan = true;
2307 Instructions ins = flow.getInstructions();
2309 existingInstructions = ins.getInstruction();
2314 if (existingInstructions != null) {
2315 /* Check if pop vlan is already the first action in action list */
2316 List<Action> existingActions = null;
2317 for (Instruction in : existingInstructions) {
2318 if (in.getInstruction() instanceof ApplyActionsCase) {
2319 existingActions = (((ApplyActionsCase)
2320 in.getInstruction()).getApplyActions().getAction());
2321 if (existingActions.get(0).getAction() instanceof PopVlanActionCase) {
2322 add_pop_vlan = false;
2328 existingInstructions = new ArrayList<Instruction>();
2333 createPopVlanInstructions(ib);
2335 ib.setKey(new InstructionKey(0));
2336 existingInstructions.add(ib.build());
2337 ib = new InstructionBuilder();
2341 //createOutputGroupInstructions(nodeBuilder, ib, dpidLong, localPort, existingInstructions);
2342 createOutputPortInstructions(ib, dpidLong, localPort, existingInstructions);
2344 ib.setKey(new InstructionKey(0));
2345 instructions.add(ib.build());
2347 // Add InstructionBuilder to the Instruction(s)Builder List
2348 isb.setInstruction(instructions);
2350 // Add InstructionsBuilder to FlowBuilder
2351 flowBuilder.setInstructions(isb.build());
2353 writeFlow(flowBuilder, nodeBuilder);
2355 //boolean flowRemove = removeOutputPortFromGroup(nodeBuilder, ib, dpidLong,
2356 // localPort, existingInstructions);
2357 boolean flowRemove = removeOutputPortFromInstructions(ib, dpidLong,
2358 localPort, existingInstructions);
2360 /* if all ports are removed, remove flow */
2361 removeFlow(flowBuilder, nodeBuilder);
2363 /* Install instruction with new output port list*/
2365 ib.setKey(new InstructionKey(0));
2366 instructions.add(ib.build());
2368 // Add InstructionBuilder to the Instruction(s)Builder List
2369 isb.setInstruction(instructions);
2371 // Add InstructionsBuilder to FlowBuilder
2372 flowBuilder.setInstructions(isb.build());
2373 writeFlow(flowBuilder, nodeBuilder);
2379 * (Table:1) Local Table Miss
2380 * Match: Any Remaining Flows w/a TunID
2381 * Action: Drop w/ a low priority
2382 * table=2,priority=8192,tun_id=0x5 actions=drop
2385 private void handleLocalTableMiss(Long dpidLong, Short writeTable,
2386 String segmentationId, boolean write) {
2388 String nodeName = "openflow:" + dpidLong;
2390 MatchBuilder matchBuilder = new MatchBuilder();
2391 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2392 FlowBuilder flowBuilder = new FlowBuilder();
2394 // Create Match(es) and Set them in the FlowBuilder Object
2395 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
2398 // Create the OF Actions and Instructions
2399 InstructionBuilder ib = new InstructionBuilder();
2400 InstructionsBuilder isb = new InstructionsBuilder();
2402 // Instructions List Stores Individual Instructions
2403 List<Instruction> instructions = new ArrayList<Instruction>();
2405 // Call the InstructionBuilder Methods Containing Actions
2406 createDropInstructions(ib);
2408 ib.setKey(new InstructionKey(0));
2409 instructions.add(ib.build());
2411 // Add InstructionBuilder to the Instruction(s)Builder List
2412 isb.setInstruction(instructions);
2414 // Add InstructionsBuilder to FlowBuilder
2415 flowBuilder.setInstructions(isb.build());
2418 String flowId = "LocalTableMiss_"+segmentationId;
2419 // Add Flow Attributes
2420 flowBuilder.setId(new FlowId(flowId));
2421 FlowKey key = new FlowKey(new FlowId(flowId));
2422 flowBuilder.setStrict(true);
2423 flowBuilder.setBarrier(false);
2424 flowBuilder.setTableId(writeTable);
2425 flowBuilder.setKey(key);
2426 flowBuilder.setPriority(8192);
2427 flowBuilder.setFlowName(flowId);
2428 flowBuilder.setHardTimeout(0);
2429 flowBuilder.setIdleTimeout(0);
2431 writeFlow(flowBuilder, nodeBuilder);
2433 removeFlow(flowBuilder, nodeBuilder);
2438 * (Table:1) Local Table Miss
2439 * Match: Any Remaining Flows w/a VLAN ID
2440 * Action: Drop w/ a low priority
2441 * table=2,priority=8192,vlan_id=0x5 actions=drop
2444 private void handleLocalVlanTableMiss(Long dpidLong, Short writeTable,
2445 String segmentationId, boolean write) {
2447 String nodeName = "openflow:" + dpidLong;
2449 MatchBuilder matchBuilder = new MatchBuilder();
2450 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
2451 FlowBuilder flowBuilder = new FlowBuilder();
2453 // Create Match(es) and Set them in the FlowBuilder Object
2454 flowBuilder.setMatch(createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build());
2457 // Create the OF Actions and Instructions
2458 InstructionBuilder ib = new InstructionBuilder();
2459 InstructionsBuilder isb = new InstructionsBuilder();
2461 // Instructions List Stores Individual Instructions
2462 List<Instruction> instructions = new ArrayList<Instruction>();
2464 // Call the InstructionBuilder Methods Containing Actions
2465 createDropInstructions(ib);
2467 ib.setKey(new InstructionKey(0));
2468 instructions.add(ib.build());
2470 // Add InstructionBuilder to the Instruction(s)Builder List
2471 isb.setInstruction(instructions);
2473 // Add InstructionsBuilder to FlowBuilder
2474 flowBuilder.setInstructions(isb.build());
2477 String flowId = "LocalTableMiss_"+segmentationId;
2478 // Add Flow Attributes
2479 flowBuilder.setId(new FlowId(flowId));
2480 FlowKey key = new FlowKey(new FlowId(flowId));
2481 flowBuilder.setStrict(true);
2482 flowBuilder.setBarrier(false);
2483 flowBuilder.setTableId(writeTable);
2484 flowBuilder.setKey(key);
2485 flowBuilder.setPriority(8192);
2486 flowBuilder.setFlowName(flowId);
2487 flowBuilder.setHardTimeout(0);
2488 flowBuilder.setIdleTimeout(0);
2490 writeFlow(flowBuilder, nodeBuilder);
2492 removeFlow(flowBuilder, nodeBuilder);
2496 private Group getGroup(GroupBuilder groupBuilder, NodeBuilder nodeBuilder) {
2497 IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2498 if (mdsalConsumer == null) {
2499 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2503 dataBrokerService = mdsalConsumer.getDataBrokerService();
2505 if (dataBrokerService == null) {
2506 logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2510 InstanceIdentifier<Group> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2511 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Group.class,
2512 new GroupKey(groupBuilder.getGroupId())).build();
2513 return (Group)dataBrokerService.readConfigurationData(path1);
2516 private Group writeGroup(GroupBuilder groupBuilder, NodeBuilder nodeBuilder) {
2517 IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2518 if (mdsalConsumer == null) {
2519 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2523 dataBrokerService = mdsalConsumer.getDataBrokerService();
2525 if (dataBrokerService == null) {
2526 logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2529 DataModification<InstanceIdentifier<?>, DataObject> modification = dataBrokerService.beginTransaction();
2530 InstanceIdentifier<Group> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2531 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Group.class,
2532 new GroupKey(groupBuilder.getGroupId())).build();
2533 modification.putConfigurationData(nodeBuilderToInstanceId(nodeBuilder), nodeBuilder.build());
2534 modification.putConfigurationData(path1, groupBuilder.build());
2535 Future<RpcResult<TransactionStatus>> commitFuture = modification.commit();
2538 RpcResult<TransactionStatus> result = commitFuture.get();
2539 TransactionStatus status = result.getResult();
2540 logger.debug("Transaction Status "+status.toString()+" for Group "+groupBuilder.getGroupName());
2541 } catch (InterruptedException e) {
2542 logger.error(e.getMessage(), e);
2543 } catch (ExecutionException e) {
2544 logger.error(e.getMessage(), e);
2546 return (Group)dataBrokerService.readConfigurationData(path1);
2549 private Group removeGroup(GroupBuilder groupBuilder, NodeBuilder nodeBuilder) {
2550 IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2551 if (mdsalConsumer == null) {
2552 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2556 dataBrokerService = mdsalConsumer.getDataBrokerService();
2558 if (dataBrokerService == null) {
2559 logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2562 DataModification<InstanceIdentifier<?>, DataObject> modification = dataBrokerService.beginTransaction();
2563 InstanceIdentifier<Group> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2564 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Group.class,
2565 new GroupKey(groupBuilder.getGroupId())).build();
2566 modification.removeConfigurationData(path1);
2567 Future<RpcResult<TransactionStatus>> commitFuture = modification.commit();
2570 RpcResult<TransactionStatus> result = commitFuture.get();
2571 TransactionStatus status = result.getResult();
2572 logger.debug("Transaction Status "+status.toString()+" for Group "+groupBuilder.getGroupName());
2573 } catch (InterruptedException e) {
2574 logger.error(e.getMessage(), e);
2575 } catch (ExecutionException e) {
2576 logger.error(e.getMessage(), e);
2578 return (Group)dataBrokerService.readConfigurationData(path1);
2580 private Flow getFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
2581 IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2582 if (mdsalConsumer == null) {
2583 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2587 dataBrokerService = mdsalConsumer.getDataBrokerService();
2589 if (dataBrokerService == null) {
2590 logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2594 InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2595 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class,
2596 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
2597 return (Flow)dataBrokerService.readConfigurationData(path1);
2600 private void writeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
2601 IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2602 if (mdsalConsumer == null) {
2603 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
2607 dataBrokerService = mdsalConsumer.getDataBrokerService();
2609 if (dataBrokerService == null) {
2610 logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2613 DataModification<InstanceIdentifier<?>, DataObject> modification = dataBrokerService.beginTransaction();
2614 InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2615 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class,
2616 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
2617 //modification.putOperationalData(nodeBuilderToInstanceId(nodeBuilder), nodeBuilder.build());
2618 //modification.putOperationalData(path1, flowBuilder.build());
2619 modification.putConfigurationData(nodeBuilderToInstanceId(nodeBuilder), nodeBuilder.build());
2620 modification.putConfigurationData(path1, flowBuilder.build());
2621 Future<RpcResult<TransactionStatus>> commitFuture = modification.commit();
2623 RpcResult<TransactionStatus> result = commitFuture.get();
2624 TransactionStatus status = result.getResult();
2625 logger.debug("Transaction Status "+status.toString()+" for Flow "+flowBuilder.getFlowName());
2626 } catch (InterruptedException e) {
2627 logger.error(e.getMessage(), e);
2628 } catch (ExecutionException e) {
2629 logger.error(e.getMessage(), e);
2633 private void removeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
2634 IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
2635 if (mdsalConsumer == null) {
2636 logger.error("ERROR finding MDSAL Service.");
2640 dataBrokerService = mdsalConsumer.getDataBrokerService();
2642 if (dataBrokerService == null) {
2643 logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
2646 DataModification<InstanceIdentifier<?>, DataObject> modification = dataBrokerService.beginTransaction();
2647 InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class)
2648 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
2649 .rev130819.nodes.Node.class, nodeBuilder.getKey())
2650 .augmentation(FlowCapableNode.class).child(Table.class,
2651 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
2652 //modification.removeOperationalData(nodeBuilderToInstanceId(nodeBuilder));
2653 //modification.removeOperationalData(path1);
2654 //modification.removeConfigurationData(nodeBuilderToInstanceId(nodeBuilder));
2655 modification.removeConfigurationData(path1);
2656 Future<RpcResult<TransactionStatus>> commitFuture = modification.commit();
2658 RpcResult<TransactionStatus> result = commitFuture.get();
2659 TransactionStatus status = result.getResult();
2660 logger.debug("Transaction Status "+status.toString()+" for Flow "+flowBuilder.getFlowName());
2661 } catch (InterruptedException e) {
2662 logger.error(e.getMessage(), e);
2663 } catch (ExecutionException e) {
2664 logger.error(e.getMessage(), e);
2669 * Create Ingress Port Match dpidLong, inPort
2671 * @param matchBuilder Map matchBuilder MatchBuilder Object without a match
2672 * @param dpidLong Long the datapath ID of a switch/node
2673 * @param inPort Long ingress port on a switch
2674 * @return matchBuilder Map MatchBuilder Object with a match
2676 protected static MatchBuilder createInPortMatch(MatchBuilder matchBuilder, Long dpidLong, Long inPort) {
2678 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + inPort);
2679 logger.debug("createInPortMatch() Node Connector ID is - Type=openflow: DPID={} inPort={} ", dpidLong, inPort);
2680 matchBuilder.setInPort(NodeConnectorId.getDefaultInstance(ncid.getValue()));
2681 matchBuilder.setInPort(ncid);
2683 return matchBuilder;
2687 * Create EtherType Match
2689 * @param matchBuilder Map matchBuilder MatchBuilder Object without a match
2690 * @param etherType Long EtherType
2691 * @return matchBuilder Map MatchBuilder Object with a match
2693 protected static MatchBuilder createEtherTypeMatch(MatchBuilder matchBuilder, EtherType etherType) {
2695 EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
2696 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2697 ethTypeBuilder.setType(new EtherType(etherType));
2698 ethernetMatch.setEthernetType(ethTypeBuilder.build());
2699 matchBuilder.setEthernetMatch(ethernetMatch.build());
2701 return matchBuilder;
2705 * Create Ethernet Source Match
2707 * @param matchBuilder MatchBuilder Object without a match yet
2708 * @param sMacAddr String representing a source MAC
2709 * @return matchBuilder Map MatchBuilder Object with a match
2711 protected static MatchBuilder createEthSrcMatch(MatchBuilder matchBuilder, MacAddress sMacAddr) {
2713 EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
2714 EthernetSourceBuilder ethSourceBuilder = new EthernetSourceBuilder();
2715 ethSourceBuilder.setAddress(new MacAddress(sMacAddr));
2716 ethernetMatch.setEthernetSource(ethSourceBuilder.build());
2717 matchBuilder.setEthernetMatch(ethernetMatch.build());
2719 return matchBuilder;
2723 * Create Ethernet Destination Match
2725 * @param matchBuilder MatchBuilder Object without a match yet
2726 * @param vlanId Integer representing a VLAN ID Integer representing a VLAN ID
2727 * @return matchBuilder Map MatchBuilder Object with a match
2730 protected static MatchBuilder createVlanIdMatch(MatchBuilder matchBuilder, VlanId vlanId) {
2731 VlanMatchBuilder vlanMatchBuilder = new VlanMatchBuilder();
2732 VlanIdBuilder vlanIdBuilder = new VlanIdBuilder();
2733 vlanIdBuilder.setVlanId(new VlanId(vlanId));
2734 vlanIdBuilder.setVlanIdPresent(true);
2735 vlanMatchBuilder.setVlanId(vlanIdBuilder.build());
2736 matchBuilder.setVlanMatch(vlanMatchBuilder.build());
2738 return matchBuilder;
2742 * Create Ethernet Destination Match
2744 * @param matchBuilder MatchBuilder Object without a match yet
2745 * @param dMacAddr String representing a destination MAC
2746 * @return matchBuilder Map MatchBuilder Object with a match
2749 protected static MatchBuilder createDestEthMatch(MatchBuilder matchBuilder, MacAddress dMacAddr, MacAddress mask) {
2751 EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
2752 EthernetDestinationBuilder ethDestinationBuilder = new EthernetDestinationBuilder();
2753 ethDestinationBuilder.setAddress(new MacAddress(dMacAddr));
2755 ethDestinationBuilder.setMask(mask);
2757 ethernetMatch.setEthernetDestination(ethDestinationBuilder.build());
2758 matchBuilder.setEthernetMatch(ethernetMatch.build());
2760 return matchBuilder;
2764 * Tunnel ID Match Builder
2766 * @param matchBuilder MatchBuilder Object without a match yet
2767 * @param tunnelId BigInteger representing a tunnel ID
2768 * @return matchBuilder Map MatchBuilder Object with a match
2770 protected static MatchBuilder createTunnelIDMatch(MatchBuilder matchBuilder, BigInteger tunnelId) {
2772 TunnelBuilder tunnelBuilder = new TunnelBuilder();
2773 tunnelBuilder.setTunnelId(tunnelId);
2774 matchBuilder.setTunnel(tunnelBuilder.build());
2776 return matchBuilder;
2780 * Match ICMP code and type
2782 * @param matchBuilder MatchBuilder Object without a match yet
2783 * @param type short representing an ICMP type
2784 * @param code short representing an ICMP code
2785 * @return matchBuilder Map MatchBuilder Object with a match
2787 protected static MatchBuilder createICMPv4Match(MatchBuilder matchBuilder, short type, short code) {
2789 EthernetMatchBuilder eth = new EthernetMatchBuilder();
2790 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2791 ethTypeBuilder.setType(new EtherType(0x0800L));
2792 eth.setEthernetType(ethTypeBuilder.build());
2793 matchBuilder.setEthernetMatch(eth.build());
2795 // Build the IPv4 Match requied per OVS Syntax
2796 IpMatchBuilder ipmatch = new IpMatchBuilder();
2797 ipmatch.setIpProtocol((short) 1);
2798 matchBuilder.setIpMatch(ipmatch.build());
2800 // Build the ICMPv4 Match
2801 Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
2802 icmpv4match.setIcmpv4Type(type);
2803 icmpv4match.setIcmpv4Code(code);
2804 matchBuilder.setIcmpv4Match(icmpv4match.build());
2806 return matchBuilder;
2810 * @param matchBuilder MatchBuilder Object without a match yet
2811 * @param dstip String containing an IPv4 prefix
2812 * @return matchBuilder Map Object with a match
2814 private static MatchBuilder createDstL3IPv4Match(MatchBuilder matchBuilder, Ipv4Prefix dstip) {
2816 EthernetMatchBuilder eth = new EthernetMatchBuilder();
2817 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2818 ethTypeBuilder.setType(new EtherType(0x0800L));
2819 eth.setEthernetType(ethTypeBuilder.build());
2820 matchBuilder.setEthernetMatch(eth.build());
2822 Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder();
2823 ipv4match.setIpv4Destination(dstip);
2825 matchBuilder.setLayer3Match(ipv4match.build());
2827 return matchBuilder;
2832 * @param matchBuilder MatchBuilder Object without a match yet
2833 * @param srcip String containing an IPv4 prefix
2834 * @return matchBuilder Map Object with a match
2836 private static MatchBuilder createSrcL3IPv4Match(MatchBuilder matchBuilder, Ipv4Prefix srcip) {
2838 EthernetMatchBuilder eth = new EthernetMatchBuilder();
2839 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2840 ethTypeBuilder.setType(new EtherType(0x0800L));
2841 eth.setEthernetType(ethTypeBuilder.build());
2842 matchBuilder.setEthernetMatch(eth.build());
2844 Ipv4MatchBuilder ipv4Match = new Ipv4MatchBuilder();
2845 Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder();
2846 ipv4match.setIpv4Source(srcip);
2847 matchBuilder.setLayer3Match(ipv4match.build());
2849 return matchBuilder;
2854 * Create Source TCP Port Match
2856 * @param matchBuilder @param matchbuilder MatchBuilder Object without a match yet
2857 * @param tcpport Integer representing a source TCP port
2858 * @return matchBuilder Map MatchBuilder Object with a match
2860 protected static MatchBuilder createSetSrcTcpMatch(MatchBuilder matchBuilder, PortNumber tcpport) {
2862 EthernetMatchBuilder ethType = new EthernetMatchBuilder();
2863 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2864 ethTypeBuilder.setType(new EtherType(0x0800L));
2865 ethType.setEthernetType(ethTypeBuilder.build());
2866 matchBuilder.setEthernetMatch(ethType.build());
2868 IpMatchBuilder ipmatch = new IpMatchBuilder();
2869 ipmatch.setIpProtocol((short) 6);
2870 matchBuilder.setIpMatch(ipmatch.build());
2872 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
2873 tcpmatch.setTcpSourcePort(tcpport);
2874 matchBuilder.setLayer4Match(tcpmatch.build());
2876 return matchBuilder;
2881 * Create Destination TCP Port Match
2883 * @param matchBuilder MatchBuilder Object without a match yet
2884 * @param tcpport Integer representing a destination TCP port
2885 * @return matchBuilder Map MatchBuilder Object with a match
2887 protected static MatchBuilder createSetDstTcpMatch(MatchBuilder matchBuilder, PortNumber tcpport) {
2889 EthernetMatchBuilder ethType = new EthernetMatchBuilder();
2890 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
2891 ethTypeBuilder.setType(new EtherType(0x0800L));
2892 ethType.setEthernetType(ethTypeBuilder.build());
2893 matchBuilder.setEthernetMatch(ethType.build());
2895 IpMatchBuilder ipmatch = new IpMatchBuilder();
2896 ipmatch.setIpProtocol((short) 6);
2897 matchBuilder.setIpMatch(ipmatch.build());
2899 PortNumber dstport = new PortNumber(tcpport);
2900 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
2902 tcpmatch.setTcpDestinationPort(tcpport);
2903 matchBuilder.setLayer4Match(tcpmatch.build());
2905 return matchBuilder;
2909 * Create Send to Controller Reserved Port Instruction (packet_in)
2911 * @param ib Map InstructionBuilder without any instructions
2912 * @return ib Map InstructionBuilder with instructions
2915 protected static InstructionBuilder createSendToControllerInstructions(InstructionBuilder ib) {
2917 List<Action> actionList = new ArrayList<Action>();
2918 ActionBuilder ab = new ActionBuilder();
2920 OutputActionBuilder output = new OutputActionBuilder();
2921 output.setMaxLength(56);
2922 Uri value = new Uri("CONTROLLER");
2923 output.setOutputNodeConnector(value);
2924 ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
2926 ab.setKey(new ActionKey(0));
2927 actionList.add(ab.build());
2929 // Create an Apply Action
2930 ApplyActionsBuilder aab = new ApplyActionsBuilder();
2931 aab.setAction(actionList);
2933 // Wrap our Apply Action in an Instruction
2934 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
2940 * Create Output Port Instruction
2942 * @param ib Map InstructionBuilder without any instructions
2943 * @param dpidLong Long the datapath ID of a switch/node
2944 * @param port Long representing a port on a switch/node
2945 * @return ib InstructionBuilder Map with instructions
2947 protected static InstructionBuilder createOutputPortInstructions(InstructionBuilder ib, Long dpidLong, Long port) {
2949 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
2950 logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} inPort={} ", dpidLong, port);
2952 List<Action> actionList = new ArrayList<Action>();
2953 ActionBuilder ab = new ActionBuilder();
2954 OutputActionBuilder oab = new OutputActionBuilder();
2955 oab.setOutputNodeConnector(ncid);
2957 ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
2959 ab.setKey(new ActionKey(0));
2960 actionList.add(ab.build());
2962 // Create an Apply Action
2963 ApplyActionsBuilder aab = new ApplyActionsBuilder();
2964 aab.setAction(actionList);
2965 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
2971 * Create Output Port Group Instruction
2973 * @param ib Map InstructionBuilder without any instructions
2974 * @param dpidLong Long the datapath ID of a switch/node
2975 * @param port Long representing a port on a switch/node
2976 * @return ib InstructionBuilder Map with instructions
2978 protected InstructionBuilder createOutputPortInstructions(InstructionBuilder ib,
2979 Long dpidLong, Long port ,
2980 List<Instruction> instructions) {
2981 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
2982 logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
2984 List<Action> actionList = new ArrayList<Action>();
2985 ActionBuilder ab = new ActionBuilder();
2987 List<Action> existingActions = null;
2988 if (instructions != null) {
2989 for (Instruction in : instructions) {
2990 if (in.getInstruction() instanceof ApplyActionsCase) {
2991 existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
2992 actionList.addAll(existingActions);
2996 /* Create output action for this port*/
2997 OutputActionBuilder oab = new OutputActionBuilder();
2998 oab.setOutputNodeConnector(ncid);
2999 ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
3000 boolean addNew = true;
3002 /* Find the group action and get the group */
3003 for (Action action : actionList) {
3004 if (action.getAction() instanceof OutputActionCase) {
3005 OutputActionCase opAction = (OutputActionCase)action.getAction();
3006 /* If output port action already in the action list of one of the buckets, skip */
3007 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
3014 ab.setOrder(actionList.size());
3015 ab.setKey(new ActionKey(actionList.size()));
3016 actionList.add(ab.build());
3018 // Create an Apply Action
3019 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3020 aab.setAction(actionList);
3021 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3022 logger.debug("createOutputPortInstructions() : applyAction {}", aab.build());
3027 * Create Output Port Group Instruction
3029 * @param ib Map InstructionBuilder without any instructions
3030 * @param dpidLong Long the datapath ID of a switch/node
3031 * @param port Long representing a port on a switch/node
3032 * @return ib InstructionBuilder Map with instructions
3034 protected InstructionBuilder createOutputGroupInstructions(NodeBuilder nodeBuilder,
3035 InstructionBuilder ib,
3036 Long dpidLong, Long port ,
3037 List<Instruction> instructions) {
3038 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3039 logger.debug("createOutputGroupInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3041 List<Action> actionList = new ArrayList<Action>();
3042 ActionBuilder ab = new ActionBuilder();
3044 List<Action> existingActions = null;
3045 if (instructions != null) {
3046 for (Instruction in : instructions) {
3047 if (in.getInstruction() instanceof ApplyActionsCase) {
3048 existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3049 actionList.addAll(existingActions);
3054 GroupBuilder groupBuilder = new GroupBuilder();
3057 /* Create output action for this port*/
3058 OutputActionBuilder oab = new OutputActionBuilder();
3059 oab.setOutputNodeConnector(ncid);
3060 ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
3061 logger.debug("createOutputGroupInstructions(): output action {}", ab.build());
3062 boolean addNew = true;
3063 boolean groupActionAdded = false;
3065 /* Find the group action and get the group */
3066 for (Action action : actionList) {
3067 if (action.getAction() instanceof GroupActionCase) {
3068 groupActionAdded = true;
3069 GroupActionCase groupAction = (GroupActionCase) action.getAction();
3070 Long id = groupAction.getGroupAction().getGroupId();
3071 String groupName = groupAction.getGroupAction().getGroup();
3072 GroupKey key = new GroupKey(new GroupId(id));
3074 groupBuilder.setGroupId(new GroupId(id));
3075 groupBuilder.setGroupName(groupName);
3076 groupBuilder.setGroupType(GroupTypes.GroupAll);
3077 groupBuilder.setKey(key);
3078 group = getGroup(groupBuilder, nodeBuilder);
3079 logger.debug("createOutputGroupInstructions: group {}", group);
3084 logger.debug("createOutputGroupInstructions: groupActionAdded {}", groupActionAdded);
3085 if (groupActionAdded) {
3086 /* modify the action bucket in group */
3087 groupBuilder = new GroupBuilder(group);
3088 Buckets buckets = groupBuilder.getBuckets();
3089 for (Bucket bucket : buckets.getBucket()) {
3090 List<Action> bucketActions = bucket.getAction();
3091 logger.debug("createOutputGroupInstructions: bucketActions {}", bucketActions);
3092 for (Action action : bucketActions) {
3093 if (action.getAction() instanceof OutputActionCase) {
3094 OutputActionCase opAction = (OutputActionCase)action.getAction();
3095 /* If output port action already in the action list of one of the buckets, skip */
3096 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
3103 logger.debug("createOutputGroupInstructions: addNew {}", addNew);
3105 /* the new output action is not in the bucket, add to bucket */
3106 if (!buckets.getBucket().isEmpty()) {
3107 Bucket bucket = buckets.getBucket().get(0);
3108 List<Action> bucketActionList = new ArrayList<Action>();
3109 bucketActionList.addAll(bucket.getAction());
3110 /* set order for new action and add to action list */
3111 ab.setOrder(bucketActionList.size());
3112 ab.setKey(new ActionKey(bucketActionList.size()));
3113 bucketActionList.add(ab.build());
3115 /* set bucket and buckets list. Reset groupBuilder with new buckets.*/
3116 BucketsBuilder bucketsBuilder = new BucketsBuilder();
3117 List<Bucket> bucketList = new ArrayList<Bucket>();
3118 BucketBuilder bucketBuilder = new BucketBuilder();
3119 bucketBuilder.setBucketId(new BucketId((long) 1));
3120 bucketBuilder.setKey(new BucketKey(new BucketId((long) 1)));
3121 bucketBuilder.setAction(bucketActionList);
3122 bucketList.add(bucketBuilder.build());
3123 bucketsBuilder.setBucket(bucketList);
3124 groupBuilder.setBuckets(bucketsBuilder.build());
3125 logger.debug("createOutputGroupInstructions: bucketList {}", bucketList);
3130 groupBuilder = new GroupBuilder();
3131 groupBuilder.setGroupType(GroupTypes.GroupAll);
3132 groupBuilder.setGroupId(new GroupId(groupId));
3133 groupBuilder.setKey(new GroupKey(new GroupId(groupId)));
3134 groupBuilder.setGroupName("Output port group" + groupId);
3135 groupBuilder.setBarrier(false);
3137 BucketsBuilder bucketBuilder = new BucketsBuilder();
3138 List<Bucket> bucketList = new ArrayList<Bucket>();
3139 BucketBuilder bucket = new BucketBuilder();
3140 bucket.setBucketId(new BucketId((long) 1));
3141 bucket.setKey(new BucketKey(new BucketId((long) 1)));
3143 /* put output action to the bucket */
3144 List<Action> bucketActionList = new ArrayList<Action>();
3145 /* set order for new action and add to action list */
3146 ab.setOrder(bucketActionList.size());
3147 ab.setKey(new ActionKey(bucketActionList.size()));
3148 bucketActionList.add(ab.build());
3150 bucket.setAction(bucketActionList);
3151 bucketList.add(bucket.build());
3152 bucketBuilder.setBucket(bucketList);
3153 groupBuilder.setBuckets(bucketBuilder.build());
3155 /* Add new group action */
3156 GroupActionBuilder groupActionB = new GroupActionBuilder();
3157 groupActionB.setGroupId(groupId);
3158 groupActionB.setGroup("Output port group" + groupId);
3159 ab = new ActionBuilder();
3160 ab.setAction(new GroupActionCaseBuilder().setGroupAction(groupActionB.build()).build());
3161 ab.setOrder(actionList.size());
3162 ab.setKey(new ActionKey(actionList.size()));
3163 actionList.add(ab.build());
3167 logger.debug("createOutputGroupInstructions: group {}", groupBuilder.build());
3168 logger.debug("createOutputGroupInstructions: actionList {}", actionList);
3171 /* rewrite the group to group table */
3172 writeGroup(groupBuilder, nodeBuilder);
3175 // Create an Apply Action
3176 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3177 aab.setAction(actionList);
3178 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3184 * add Output Port action to Instruction action list.
3185 * This is use for flow with single output port actions.
3186 * Flow with mutiple output port actions should use createOutputPortInstructions() method.
3188 * @param ib Map InstructionBuilder without any instructions
3189 * @param dpidLong Long the datapath ID of a switch/node
3190 * @param port Long representing a port on a switch/node
3191 * @return ib InstructionBuilder Map with instructions
3193 protected static InstructionBuilder addOutputPortInstructions(InstructionBuilder ib,
3194 Long dpidLong, Long port ,
3195 List<Instruction> instructions) {
3196 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3197 logger.debug("addOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3199 List<Action> actionList = new ArrayList<Action>();
3200 ActionBuilder ab = new ActionBuilder();
3202 List<Action> existingActions = null;
3203 if (instructions != null) {
3204 for (Instruction in : instructions) {
3205 if (in.getInstruction() instanceof ApplyActionsCase) {
3206 existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3207 actionList.addAll(existingActions);
3212 /* Create output action for this port*/
3213 OutputActionBuilder oab = new OutputActionBuilder();
3214 oab.setOutputNodeConnector(ncid);
3215 ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
3216 ab.setOrder(actionList.size());
3217 ab.setKey(new ActionKey(actionList.size()));
3218 actionList.add(ab.build());
3220 // Create an Apply Action
3221 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3222 aab.setAction(actionList);
3223 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3229 * Remove Output Port from action list in group bucket
3231 * @param ib Map InstructionBuilder without any instructions
3232 * @param dpidLong Long the datapath ID of a switch/node
3233 * @param port Long representing a port on a switch/node
3234 * @return ib InstructionBuilder Map with instructions
3236 protected boolean removeOutputPortFromGroup(NodeBuilder nodeBuilder, InstructionBuilder ib,
3237 Long dpidLong, Long port , List<Instruction> instructions) {
3239 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3240 logger.debug("removeOutputPortFromGroup() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3242 List<Action> actionList = new ArrayList<Action>();
3245 List<Action> existingActions = null;
3246 if (instructions != null) {
3247 for (Instruction in : instructions) {
3248 if (in.getInstruction() instanceof ApplyActionsCase) {
3249 existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3250 actionList.addAll(existingActions);
3256 GroupBuilder groupBuilder = new GroupBuilder();
3258 boolean groupActionAdded = false;
3259 /* Find the group action and get the group */
3260 for (Action action : actionList) {
3261 if (action.getAction() instanceof GroupActionCase) {
3262 groupActionAdded = true;
3263 GroupActionCase groupAction = (GroupActionCase) action.getAction();
3264 Long id = groupAction.getGroupAction().getGroupId();
3265 String groupName = groupAction.getGroupAction().getGroup();
3266 GroupKey key = new GroupKey(new GroupId(id));
3268 groupBuilder.setGroupId(new GroupId(id));
3269 groupBuilder.setGroupName(groupName);
3270 groupBuilder.setGroupType(GroupTypes.GroupAll);
3271 groupBuilder.setKey(key);
3272 group = getGroup(groupBuilder, nodeBuilder);
3277 if (groupActionAdded) {
3278 /* modify the action bucket in group */
3279 groupBuilder = new GroupBuilder(group);
3280 Buckets buckets = groupBuilder.getBuckets();
3281 List<Action> bucketActions = new ArrayList<Action>();
3282 for (Bucket bucket : buckets.getBucket()) {
3284 boolean isPortDeleted = false;
3285 bucketActions = bucket.getAction();
3286 for (Action action : bucketActions) {
3287 if (action.getAction() instanceof OutputActionCase) {
3288 OutputActionCase opAction = (OutputActionCase)action.getAction();
3289 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
3290 /* Find the output port in action list and remove */
3291 index = bucketActions.indexOf(action);
3292 bucketActions.remove(action);
3293 isPortDeleted = true;
3298 if (isPortDeleted && !bucketActions.isEmpty()) {
3299 for (int i = index; i< bucketActions.size(); i++) {
3300 Action action = bucketActions.get(i);
3301 if (action.getOrder() != i) {
3302 /* Shift the action order */
3303 ab = new ActionBuilder();
3304 ab.setAction(action.getAction());
3306 ab.setKey(new ActionKey(i));
3307 Action actionNewOrder = ab.build();
3308 bucketActions.remove(action);
3309 bucketActions.add(i, actionNewOrder);
3313 } else if (bucketActions.isEmpty()) {
3314 /* remove bucket with empty action list */
3315 buckets.getBucket().remove(bucket);
3319 if (!buckets.getBucket().isEmpty()) {
3320 /* rewrite the group to group table */
3321 /* set bucket and buckets list. Reset groupBuilder with new buckets.*/
3322 BucketsBuilder bucketsBuilder = new BucketsBuilder();
3323 List<Bucket> bucketList = new ArrayList<Bucket>();
3324 BucketBuilder bucketBuilder = new BucketBuilder();
3325 bucketBuilder.setBucketId(new BucketId((long) 1));
3326 bucketBuilder.setKey(new BucketKey(new BucketId((long) 1)));
3327 bucketBuilder.setAction(bucketActions);
3328 bucketList.add(bucketBuilder.build());
3329 bucketsBuilder.setBucket(bucketList);
3330 groupBuilder.setBuckets(bucketsBuilder.build());
3331 logger.debug("removeOutputPortFromGroup: bucketList {}", bucketList);
3333 writeGroup(groupBuilder, nodeBuilder);
3334 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3335 aab.setAction(actionList);
3336 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3339 /* remove group with empty bucket. return true to delete flow */
3340 removeGroup(groupBuilder, nodeBuilder);
3344 /* no group for port list. flow can be removed */
3350 * Remove Output Port from Instruction
3352 * @param ib Map InstructionBuilder without any instructions
3353 * @param dpidLong Long the datapath ID of a switch/node
3354 * @param port Long representing a port on a switch/node
3355 * @return ib InstructionBuilder Map with instructions
3357 protected static boolean removeOutputPortFromInstructions(InstructionBuilder ib,
3358 Long dpidLong, Long port , List<Instruction> instructions) {
3360 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
3361 logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
3363 List<Action> actionList = new ArrayList<Action>();
3366 List<Action> existingActions = null;
3367 if (instructions != null) {
3368 for (Instruction in : instructions) {
3369 if (in.getInstruction() instanceof ApplyActionsCase) {
3370 existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
3371 actionList.addAll(existingActions);
3377 int numOutputPort = 0;
3379 boolean isPortDeleted = false;
3380 for (Action action : actionList) {
3381 if (action.getAction() instanceof OutputActionCase) {
3383 OutputActionCase opAction = (OutputActionCase)action.getAction();
3384 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
3385 /* Find the output port in action list and remove */
3386 index = actionList.indexOf(action);
3387 actionList.remove(action);
3388 isPortDeleted = true;
3395 if (isPortDeleted) {
3396 for (int i = index; i< actionList.size(); i++) {
3397 Action action = actionList.get(i);
3398 if (action.getOrder() != i) {
3399 /* Shift the action order */
3400 ab = new ActionBuilder();
3401 ab.setAction(action.getAction());
3403 ab.setKey(new ActionKey(i));
3404 Action actionNewOrder = ab.build();
3405 actionList.remove(action);
3406 actionList.add(i, actionNewOrder);
3411 /* Put new action list in Apply Action instruction */
3412 if (numOutputPort > 0) {
3413 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3414 aab.setAction(actionList);
3415 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3416 logger.debug("createOutputPortInstructions() : applyAction {}", aab.build());
3419 /* if all output port are removed. Return true to indicate flow remove */
3425 * Create Set Vlan ID Instruction - This includes push vlan action, and set field -> vlan vid action
3427 * @param ib Map InstructionBuilder without any instructions
3428 * @param vlanId Integer representing a VLAN ID Integer representing a VLAN ID
3429 * @return ib Map InstructionBuilder with instructions
3431 protected static InstructionBuilder createSetVlanInstructions(InstructionBuilder ib, VlanId vlanId) {
3433 List<Action> actionList = new ArrayList<Action>();
3434 ActionBuilder ab = new ActionBuilder();
3436 /* First we push vlan header */
3437 PushVlanActionBuilder vlan = new PushVlanActionBuilder();
3438 vlan.setEthernetType(new Integer(0x8100));
3439 ab.setAction(new PushVlanActionCaseBuilder().setPushVlanAction(vlan.build()).build());
3441 actionList.add(ab.build());
3443 /* Then we set vlan id value as vlanId */
3444 SetVlanIdActionBuilder vl = new SetVlanIdActionBuilder();
3445 vl.setVlanId(vlanId);
3446 ab = new ActionBuilder();
3447 ab.setAction(new SetVlanIdActionCaseBuilder().setSetVlanIdAction(vl.build()).build());
3449 actionList.add(ab.build());
3450 // Create an Apply Action
3451 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3452 aab.setAction(actionList);
3454 // Wrap our Apply Action in an Instruction
3455 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3461 * Create Pop Vlan Instruction - this remove vlan header
3463 * @param ib Map InstructionBuilder without any instructions
3464 * @return ib Map InstructionBuilder with instructions
3466 protected static InstructionBuilder createPopVlanInstructions(InstructionBuilder ib) {
3468 List<Action> actionList = new ArrayList<Action>();
3469 ActionBuilder ab = new ActionBuilder();
3471 PopVlanActionBuilder popVlanActionBuilder = new PopVlanActionBuilder();
3472 ab.setAction(new PopVlanActionCaseBuilder().setPopVlanAction(popVlanActionBuilder.build()).build());
3474 actionList.add(ab.build());
3476 // Create an Apply Action
3477 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3478 aab.setAction(actionList);
3480 // Wrap our Apply Action in an Instruction
3481 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3487 * Create Set IPv4 Source Instruction
3489 * @param ib Map InstructionBuilder without any instructions
3490 * @param prefixsrc String containing an IPv4 prefix
3491 * @return ib Map InstructionBuilder with instructions
3493 protected static InstructionBuilder createNwSrcInstructions(InstructionBuilder ib, Ipv4Prefix prefixsrc) {
3495 List<Action> actionList = new ArrayList<Action>();
3496 ActionBuilder ab = new ActionBuilder();
3498 SetNwSrcActionBuilder setNwsrcActionBuilder = new SetNwSrcActionBuilder();
3499 Ipv4Builder ipsrc = new Ipv4Builder();
3500 ipsrc.setIpv4Address(prefixsrc);
3501 setNwsrcActionBuilder.setAddress(ipsrc.build());
3502 ab.setAction(new SetNwSrcActionCaseBuilder().setSetNwSrcAction(setNwsrcActionBuilder.build()).build());
3503 actionList.add(ab.build());
3505 // Create an Apply Action
3506 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3507 aab.setAction(actionList);
3509 // Wrap our Apply Action in an Instruction
3510 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3516 * Create Set IPv4 Destination Instruction
3518 * @param ib Map InstructionBuilder without any instructions
3519 * @param prefixdst String containing an IPv4 prefix
3520 * @return ib Map InstructionBuilder with instructions
3522 protected static InstructionBuilder createNwDstInstructions(InstructionBuilder ib, Ipv4Prefix prefixdst) {
3524 List<Action> actionList = new ArrayList<Action>();
3525 ActionBuilder ab = new ActionBuilder();
3527 SetNwDstActionBuilder setNwDstActionBuilder = new SetNwDstActionBuilder();
3528 Ipv4Builder ipdst = new Ipv4Builder();
3529 ipdst.setIpv4Address(prefixdst);
3530 setNwDstActionBuilder.setAddress(ipdst.build());
3531 ab.setAction(new SetNwDstActionCaseBuilder().setSetNwDstAction(setNwDstActionBuilder.build()).build());
3532 actionList.add(ab.build());
3534 // Create an Apply Action
3535 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3536 aab.setAction(actionList);
3538 // Wrap our Apply Action in an Instruction
3539 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3545 * Create Drop Instruction
3547 * @param ib Map InstructionBuilder without any instructions
3548 * @return ib Map InstructionBuilder with instructions
3550 protected static InstructionBuilder createDropInstructions(InstructionBuilder ib) {
3552 DropActionBuilder dab = new DropActionBuilder();
3553 DropAction dropAction = dab.build();
3554 ActionBuilder ab = new ActionBuilder();
3555 ab.setAction(new DropActionCaseBuilder().setDropAction(dropAction).build());
3558 // Add our drop action to a list
3559 List<Action> actionList = new ArrayList<Action>();
3560 actionList.add(ab.build());
3562 // Create an Apply Action
3563 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3564 aab.setAction(actionList);
3566 // Wrap our Apply Action in an Instruction
3567 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3573 * Create GOTO Table Instruction Builder
3575 * @param ib Map InstructionBuilder without any instructions
3576 * @param tableId short representing a flow table ID short representing a flow table ID
3577 * @return ib Map InstructionBuilder with instructions
3579 protected static InstructionBuilder createGotoTableInstructions(InstructionBuilder ib, short tableId) {
3581 GoToTableBuilder gttb = new GoToTableBuilder();
3582 gttb.setTableId(tableId);
3584 // Wrap our Apply Action in an InstructionBuilder
3585 ib.setInstruction(new GoToTableCaseBuilder().setGoToTable(gttb.build()).build());
3591 * Create Set Tunnel ID Instruction Builder
3593 * @param ib Map InstructionBuilder without any instructions
3594 * @param tunnelId BigInteger representing a tunnel ID
3595 * @return ib Map InstructionBuilder with instructions
3597 protected static InstructionBuilder createSetTunnelIdInstructions(InstructionBuilder ib, BigInteger tunnelId) {
3599 List<Action> actionList = new ArrayList<Action>();
3600 ActionBuilder ab = new ActionBuilder();
3601 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3603 // Build the Set Tunnel Field Action
3604 TunnelBuilder tunnel = new TunnelBuilder();
3605 tunnel.setTunnelId(tunnelId);
3606 setFieldBuilder.setTunnel(tunnel.build());
3607 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3609 actionList.add(ab.build());
3611 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3612 aab.setAction(actionList);
3614 // Wrap the Apply Action in an InstructionBuilder and return
3615 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3621 * Create Set Source TCP Port Instruction
3623 * @param ib Map InstructionBuilder without any instructions
3624 * @param tcpport Integer representing a source TCP port
3625 * @return ib Map InstructionBuilder with instructions
3627 protected static InstructionBuilder createSetSrcTCPPort(InstructionBuilder ib, PortNumber tcpport) {
3629 List<Action> actionList = new ArrayList<Action>();
3630 ActionBuilder ab = new ActionBuilder();
3631 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3633 // Build the Destination TCP Port
3634 PortNumber tcpsrcport = new PortNumber(tcpport);
3635 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
3636 tcpmatch.setTcpSourcePort(tcpsrcport);
3638 setFieldBuilder.setLayer4Match(tcpmatch.build());
3639 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3640 ab.setKey(new ActionKey(1));
3641 actionList.add(ab.build());
3643 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3644 aab.setAction(actionList);
3645 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3651 * Create Set Destination TCP Port Instruction
3653 * @param ib Map InstructionBuilder without any instructions
3654 * @param tcpport Integer representing a source TCP port
3655 * @return ib Map InstructionBuilder with instructions
3657 protected static InstructionBuilder createSetDstTCPPort(InstructionBuilder ib, PortNumber tcpport) {
3659 List<Action> actionList = new ArrayList<Action>();
3660 ActionBuilder ab = new ActionBuilder();
3661 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3663 // Build the Destination TCP Port
3664 PortNumber tcpdstport = new PortNumber(tcpport);
3665 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
3666 tcpmatch.setTcpDestinationPort(tcpdstport);
3668 setFieldBuilder.setLayer4Match(tcpmatch.build());
3669 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3670 ab.setKey(new ActionKey(1));
3671 actionList.add(ab.build());
3673 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3674 aab.setAction(actionList);
3675 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3681 * Create Set Source UDP Port Instruction
3683 * @param ib Map InstructionBuilder without any instructions
3684 * @param udpport Integer representing a source UDP port
3685 * @return ib Map InstructionBuilder with instructions
3687 protected static InstructionBuilder createSetSrcUDPPort(InstructionBuilder ib, PortNumber udpport) {
3689 List<Action> actionList = new ArrayList<Action>();
3690 ActionBuilder ab = new ActionBuilder();
3691 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3693 // Build the Destination TCP Port
3694 PortNumber udpsrcport = new PortNumber(udpport);
3695 UdpMatchBuilder udpmatch = new UdpMatchBuilder();
3696 udpmatch.setUdpSourcePort(udpsrcport);
3698 setFieldBuilder.setLayer4Match(udpmatch.build());
3699 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3700 ab.setKey(new ActionKey(1));
3701 actionList.add(ab.build());
3703 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3704 aab.setAction(actionList);
3705 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3711 * Create Set Destination UDP Port Instruction
3713 * @param ib Map InstructionBuilder without any instructions
3714 * @param udpport Integer representing a destination UDP port
3715 * @return ib Map InstructionBuilder with instructions
3717 protected static InstructionBuilder createSetDstUDPPort(InstructionBuilder ib, PortNumber udpport) {
3719 List<Action> actionList = new ArrayList<Action>();
3720 ActionBuilder ab = new ActionBuilder();
3721 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3723 // Build the Destination TCP Port
3724 PortNumber udpdstport = new PortNumber(udpport);
3725 UdpMatchBuilder udpmatch = new UdpMatchBuilder();
3726 udpmatch.setUdpDestinationPort(udpdstport);
3728 setFieldBuilder.setLayer4Match(udpmatch.build());
3729 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3730 ab.setKey(new ActionKey(1));
3731 actionList.add(ab.build());
3733 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3734 aab.setAction(actionList);
3735 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3741 * Create Set ICMP Code Instruction
3743 * @param ib Map InstructionBuilder without any instructions
3744 * @param code short repesenting an ICMP code
3745 * @return ib Map InstructionBuilder with instructions
3748 private static InstructionBuilder createSetIcmpCodeInstruction(InstructionBuilder ib, short code) {
3750 List<Action> actionList = new ArrayList<Action>();
3751 ActionBuilder ab = new ActionBuilder();
3752 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3753 Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
3755 // Build the ICMPv4 Code Match
3756 icmpv4match.setIcmpv4Code(code);
3757 setFieldBuilder.setIcmpv4Match(icmpv4match.build());
3759 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3760 ab.setKey(new ActionKey(0));
3761 actionList.add(ab.build());
3762 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3763 aab.setAction(actionList);
3765 // Wrap our Apply Action in an Instruction
3766 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3772 * Create Set ICMP Code Instruction
3774 * @param ib Map InstructionBuilder without any instructions
3775 * @return ib Map InstructionBuilder with instructions
3777 private static InstructionBuilder createSetIcmpTypeInstruction(InstructionBuilder ib, short type) {
3779 List<Action> actionList = new ArrayList<Action>();
3780 ActionBuilder ab = new ActionBuilder();
3781 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3782 Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
3784 // Build the ICMPv4 Code Match
3785 icmpv4match.setIcmpv4Code(type);
3786 setFieldBuilder.setIcmpv4Match(icmpv4match.build());
3788 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3789 ab.setKey(new ActionKey(1));
3790 actionList.add(ab.build());
3791 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3792 aab.setAction(actionList);
3794 // Wrap our Apply Action in an Instruction
3795 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3801 * Create Decrement TTL Instruction
3803 * @param ib Map InstructionBuilder without any instructions
3804 * @return ib Map InstructionBuilder with instructions
3806 private static InstructionBuilder createDecNwTtlInstructions(InstructionBuilder ib) {
3807 DecNwTtlBuilder decNwTtlBuilder = new DecNwTtlBuilder();
3808 DecNwTtl decNwTtl = decNwTtlBuilder.build();
3809 ActionBuilder ab = new ActionBuilder();
3810 ab.setAction(new DecNwTtlCaseBuilder().setDecNwTtl(decNwTtl).build());
3812 // Add our drop action to a list
3813 List<Action> actionList = new ArrayList<Action>();
3814 actionList.add(ab.build());
3816 // Create an Apply Action
3817 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3818 aab.setAction(actionList);
3820 // Wrap our Apply Action in an Instruction
3821 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
3829 private static InstructionBuilder createSrcArpMacInstructions(InstructionBuilder ib, MacAddress macsrc) {
3831 List<Action> actionList = new ArrayList<Action>();
3832 ActionBuilder ab = new ActionBuilder();
3834 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3835 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
3836 ArpSourceHardwareAddressBuilder arpsrc = new ArpSourceHardwareAddressBuilder();
3837 arpsrc.setAddress(macsrc);
3838 arpmatch.setArpSourceHardwareAddress(arpsrc.build());
3839 setFieldBuilder.setLayer3Match(arpmatch.build());
3840 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3841 ab.setKey(new ActionKey(0));
3842 actionList.add(ab.build());
3844 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3845 aab.setAction(actionList);
3853 private static InstructionBuilder createDstArpMacInstructions(InstructionBuilder ib, MacAddress macdst) {
3855 List<Action> actionList = new ArrayList<Action>();
3856 ActionBuilder ab = new ActionBuilder();
3857 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3859 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
3860 ArpTargetHardwareAddressBuilder arpdst = new ArpTargetHardwareAddressBuilder();
3861 arpdst.setAddress(macdst);
3862 setFieldBuilder.setLayer3Match(arpmatch.build());
3863 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3864 ab.setKey(new ActionKey(0));
3865 actionList.add(ab.build());
3867 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3868 aab.setAction(actionList);
3876 private static InstructionBuilder createDstArpIpInstructions(InstructionBuilder ib, Ipv4Prefix dstiparp) {
3878 List<Action> actionList = new ArrayList<Action>();
3879 ActionBuilder ab = new ActionBuilder();
3880 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3882 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
3883 arpmatch.setArpTargetTransportAddress(dstiparp);
3884 setFieldBuilder.setLayer3Match(arpmatch.build());
3885 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3886 ab.setKey(new ActionKey(0));
3887 actionList.add(ab.build());
3889 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3890 aab.setAction(actionList);
3898 private static InstructionBuilder createSrcArpIpInstructions(InstructionBuilder ib, Ipv4Prefix srciparp) {
3900 List<Action> actionList = new ArrayList<Action>();
3901 ActionBuilder ab = new ActionBuilder();
3902 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
3904 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
3905 arpmatch.setArpSourceTransportAddress(srciparp);
3906 setFieldBuilder.setLayer3Match(arpmatch.build());
3907 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
3908 ab.setKey(new ActionKey(0));
3909 actionList.add(ab.build());
3911 ApplyActionsBuilder aab = new ApplyActionsBuilder();
3912 aab.setAction(actionList);
3918 public void initializeOFFlowRules(Node openflowNode) {
3919 IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
3920 List<Node> ovsNodes = connectionService.getNodes();
3921 if (ovsNodes == null) return;
3922 for (Node ovsNode : ovsNodes) {
3923 Long dpid = this.getIntegrationBridgeOFDPID(ovsNode);
3924 logger.debug("Compare openflowNode to OVS br-int node {} vs {}", openflowNode.getID(), dpid);
3925 String openflowID = ""+openflowNode.getID();
3926 if (openflowID.contains(""+dpid)) {
3927 this.initializeFlowRules(ovsNode, adminConfigManager.getIntegrationBridgeName());
3928 this.triggerInterfaceUpdates(ovsNode);
3933 private NodeBuilder createNodeBuilder(String nodeId) {
3934 NodeBuilder builder = new NodeBuilder();
3935 builder.setId(new NodeId(nodeId));
3936 builder.setKey(new NodeKey(builder.getId()));
3940 private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeBuilderToInstanceId(NodeBuilder
3942 return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
3943 node.getKey()).toInstance();
3946 private String getInternalBridgeUUID (Node node, String bridgeName) {
3948 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
3949 Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
3950 if (bridgeTable == null) return null;
3951 for (String key : bridgeTable.keySet()) {
3952 Bridge bridge = (Bridge)bridgeTable.get(key);
3953 if (bridge.getName().equals(bridgeName)) return key;
3955 } catch (Exception e) {
3956 logger.error("Error getting Bridge Identifier for {} / {}", node, bridgeName, e);