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.OutputActionCase;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCaseBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionCaseBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwSrcActionCaseBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCaseBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.StripVlanActionCaseBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtl;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtlBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropAction;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropActionBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.dst.action._case.SetNwDstActionBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.src.action._case.SetNwSrcActionBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.vlan.id.action._case.SetVlanIdActionBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.strip.vlan.action._case.StripVlanAction;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.strip.vlan.action._case.StripVlanActionBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCaseBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTableBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpSourceHardwareAddressBuilder;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpTargetHardwareAddressBuilder;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv4MatchBuilder;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
113 import org.opendaylight.yangtools.yang.binding.DataObject;
114 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
115 import org.opendaylight.yangtools.yang.common.RpcResult;
116 import org.slf4j.Logger;
117 import org.slf4j.LoggerFactory;
123 public class OF13Provider implements NetworkProvider {
124 private static final Logger logger = LoggerFactory.getLogger(OF13Provider.class);
125 private DataBrokerService dataBrokerService;
126 private static final short TABLE_0_DEFAULT_INGRESS = 0;
127 private static final short TABLE_1_ISOLATE_TENANT = 10;
128 private static final short TABLE_2_LOCAL_FORWARD = 20;
130 private IAdminConfigManager adminConfigManager;
131 private IInternalNetworkManager internalNetworkManager;
132 private ITenantNetworkManager tenantNetworkManager;
134 public OF13Provider(IAdminConfigManager adminConfigManager,
135 IInternalNetworkManager internalNetworkManager,
136 ITenantNetworkManager tenantNetworkManager) {
137 this.adminConfigManager = adminConfigManager;
138 this.internalNetworkManager = internalNetworkManager;
139 this.tenantNetworkManager = tenantNetworkManager;
143 public boolean hasPerTenantTunneling() {
147 private Status getTunnelReadinessStatus (Node node, String tunnelKey) {
148 InetAddress srcTunnelEndPoint = adminConfigManager.getTunnelEndPoint(node);
149 if (srcTunnelEndPoint == null) {
150 logger.error("Tunnel Endpoint not configured for Node {}", node);
151 return new Status(StatusCode.NOTFOUND, "Tunnel Endpoint not configured for "+ node);
154 if (!internalNetworkManager.isInternalNetworkNeutronReady(node)) {
155 logger.error(node+" is not Overlay ready");
156 return new Status(StatusCode.NOTACCEPTABLE, node+" is not Overlay ready");
159 if (!tenantNetworkManager.isTenantNetworkPresentInNode(node, tunnelKey)) {
160 logger.debug(node+" has no VM corresponding to segment "+ tunnelKey);
161 return new Status(StatusCode.NOTACCEPTABLE, node+" has no VM corresponding to segment "+ tunnelKey);
163 return new Status(StatusCode.SUCCESS);
166 private String getTunnelName(String tunnelType, InetAddress dst) {
167 return tunnelType+"-"+dst.getHostAddress();
170 private boolean isTunnelPresent(Node node, String tunnelName, String bridgeUUID) throws Exception {
171 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
172 Bridge bridge = (Bridge)ovsdbTable.getRow(node, Bridge.NAME.getName(), bridgeUUID);
173 if (bridge != null) {
174 Set<UUID> ports = bridge.getPorts();
175 for (UUID portUUID : ports) {
176 Port port = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), portUUID.toString());
177 if (port != null && port.getName().equalsIgnoreCase(tunnelName)) return true;
183 private String getPortUuid(Node node, String name, String bridgeUUID) throws Exception {
184 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
185 Bridge bridge = (Bridge)ovsdbTable.getRow(node, Bridge.NAME.getName(), bridgeUUID);
186 if (bridge != null) {
187 Set<UUID> ports = bridge.getPorts();
188 for (UUID portUUID : ports) {
189 Port port = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), portUUID.toString());
190 if (port != null && port.getName().equalsIgnoreCase(name)) return portUUID.toString();
196 private Status addTunnelPort (Node node, String tunnelType, InetAddress src, InetAddress dst) {
198 String bridgeUUID = null;
199 String tunnelBridgeName = adminConfigManager.getIntegrationBridgeName();
200 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
201 Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
202 if (bridgeTable != null) {
203 for (String uuid : bridgeTable.keySet()) {
204 Bridge bridge = (Bridge)bridgeTable.get(uuid);
205 if (bridge.getName().equals(tunnelBridgeName)) {
211 if (bridgeUUID == null) {
212 logger.error("Could not find Bridge {} in {}", tunnelBridgeName, node);
213 return new Status(StatusCode.NOTFOUND, "Could not find "+tunnelBridgeName+" in "+node);
215 String portName = getTunnelName(tunnelType, dst);
217 if (this.isTunnelPresent(node, portName, bridgeUUID)) {
218 logger.trace("Tunnel {} is present in {} of {}", portName, tunnelBridgeName, node);
219 return new Status(StatusCode.SUCCESS);
222 Port tunnelPort = new Port();
223 tunnelPort.setName(portName);
224 StatusWithUuid statusWithUuid = ovsdbTable.insertRow(node, Port.NAME.getName(), bridgeUUID, tunnelPort);
225 if (!statusWithUuid.isSuccess()) {
226 logger.error("Failed to insert Tunnel port {} in {}", portName, bridgeUUID);
227 return statusWithUuid;
230 String tunnelPortUUID = statusWithUuid.getUuid().toString();
231 String interfaceUUID = null;
233 while ((interfaceUUID == null) && (timeout > 0)) {
234 tunnelPort = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), tunnelPortUUID);
235 OvsDBSet<UUID> interfaces = tunnelPort.getInterfaces();
236 if (interfaces == null || interfaces.size() == 0) {
237 // Wait for the OVSDB update to sync up the Local cache.
242 interfaceUUID = interfaces.toArray()[0].toString();
243 Interface intf = (Interface)ovsdbTable.getRow(node, Interface.NAME.getName(), interfaceUUID);
244 if (intf == null) interfaceUUID = null;
247 if (interfaceUUID == null) {
248 logger.error("Cannot identify Tunnel Interface for port {}/{}", portName, tunnelPortUUID);
249 return new Status(StatusCode.INTERNALERROR);
252 Interface tunInterface = new Interface();
253 tunInterface.setType(tunnelType);
254 OvsDBMap<String, String> options = new OvsDBMap<String, String>();
255 options.put("key", "flow");
256 options.put("local_ip", src.getHostAddress());
257 options.put("remote_ip", dst.getHostAddress());
258 tunInterface.setOptions(options);
259 Status status = ovsdbTable.updateRow(node, Interface.NAME.getName(), tunnelPortUUID, interfaceUUID, tunInterface);
260 logger.debug("Tunnel {} add status : {}", tunInterface, status);
262 } catch (Exception e) {
263 logger.error("Exception in addTunnelPort", e);
264 return new Status(StatusCode.INTERNALERROR);
268 /* delete port from ovsdb port table */
269 private Status deletePort(Node node, String bridgeName, String portName) {
271 String bridgeUUID = null;
272 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
273 Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
274 if (bridgeTable != null) {
275 for (String uuid : bridgeTable.keySet()) {
276 Bridge bridge = (Bridge)bridgeTable.get(uuid);
277 if (bridge.getName().equals(bridgeName)) {
283 if (bridgeUUID == null) {
284 logger.debug("Could not find Bridge {} in {}", bridgeName, node);
285 return new Status(StatusCode.SUCCESS);
288 String portUUID = this.getPortUuid(node, portName, bridgeUUID);
289 Status status = new Status(StatusCode.SUCCESS);
290 if (portUUID != null) {
291 status = ovsdbTable.deleteRow(node, Port.NAME.getName(), portUUID);
292 if (!status.isSuccess()) {
293 logger.error("Failed to delete port {} in {} status : {}", portName, bridgeUUID,
297 logger.debug("Port {} delete status : {}", portName, status);
300 } catch (Exception e) {
301 logger.error("Exception in deletePort", e);
302 return new Status(StatusCode.INTERNALERROR);
306 private Status deleteTunnelPort(Node node, String tunnelType, InetAddress src, InetAddress dst) {
307 String tunnelBridgeName = adminConfigManager.getIntegrationBridgeName();
308 String portName = getTunnelName(tunnelType, dst);
309 Status status = deletePort(node, tunnelBridgeName, portName);
313 private void programLocalBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long localPort) {
317 * Match: VM sMac and Local Ingress Port
318 * Action:Action: Set Tunnel ID and GOTO Local Table (5)
321 handleLocalInPort(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_1_ISOLATE_TENANT, segmentationId, localPort, attachedMac, true);
326 * Match: Drop any remaining Ingress Local VM Packets
327 * Action: Drop w/ a low priority
330 handleDropSrcIface(dpid, localPort, true);
335 * Match: Match TunID and Destination DL/dMAC Addr
336 * Action: Output Port
337 * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
340 handleLocalUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, attachedMac, true);
345 * Match: Tunnel ID and dMAC (::::FF:FF)
346 * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
347 * actions=output:2,3,4,5
350 handleLocalBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, true);
353 * TODO : Optimize the following 2 writes to be restricted only for the very first port known in a segment.
358 * Match: Any remaining Ingress Local VM Packets
359 * Action: Drop w/ a low priority
360 * -------------------------------------------
361 * table=1,priority=8192,tun_id=0x5 actions=goto_table:2
364 handleTunnelMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, true);
369 * Match: Any Remaining Flows w/a TunID
370 * Action: Drop w/ a low priority
371 * table=2,priority=8192,tun_id=0x5 actions=drop
374 handleLocalTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, true);
377 private void removeLocalBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long localPort) {
381 ** Match: VM sMac and Local Ingress Port
382 ** Action:Action: Set Tunnel ID and GOTO Local Table (5)
385 handleLocalInPort(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_1_ISOLATE_TENANT, segmentationId, localPort, attachedMac, false);
390 ** Match: Drop any remaining Ingress Local VM Packets
391 ** Action: Drop w/ a low priority
394 handleDropSrcIface(dpid, localPort, false);
399 ** Match: Match TunID and Destination DL/dMAC Addr
400 ** Action: Output Port
401 ** table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
404 handleLocalUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, attachedMac, false);
409 ** Match: Tunnel ID and dMAC (::::FF:FF)
410 ** table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
411 ** actions=output:2,3,4,5
414 handleLocalBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, false);
417 private void programLocalIngressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
421 * Match: Ingress Port, Tunnel ID
422 * Action: GOTO Local Table (20)
425 handleTunnelIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, true);
430 * Match: Match Tunnel ID and L2 ::::FF:FF Flooding
431 * Action: Flood to selected destination TEPs
432 * -------------------------------------------
433 * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
434 * actions=output:10,output:11,goto_table:2
437 handleTunnelFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, true);
441 private void programRemoteEgressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
445 * Match: Drop any remaining Ingress Local VM Packets
446 * Action: Drop w/ a low priority
447 * -------------------------------------------
448 * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
449 * actions=output:11,goto_table:2
452 handleTunnelOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, attachedMac, true);
455 private void removeRemoteEgressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
459 ** Match: Drop any remaining Ingress Local VM Packets
460 ** Action: Drop w/ a low priority
461 ** -------------------------------------------
462 ** table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
463 ** actions=output:11,goto_table:2
466 handleTunnelOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, attachedMac, false);
469 /* Remove tunnel rules if last node in this tenant network */
470 private void removePerTunnelRules(Node node, Long dpid, String segmentationId, long tunnelOFPort) {
472 ** TODO : Optimize the following 2 writes to be restricted only for the very first port known in a segment.
477 ** Match: Any remaining Ingress Local VM Packets
478 ** Action: Drop w/ a low priority
479 ** -------------------------------------------
480 ** table=1,priority=8192,tun_id=0x5 actions=goto_table:2
483 handleTunnelMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, false);
488 ** Match: Any Remaining Flows w/a TunID
489 ** Action: Drop w/ a low priority
490 ** table=2,priority=8192,tun_id=0x5 actions=drop
493 handleLocalTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, false);
498 ** Match: Ingress Port, Tunnel ID
499 ** Action: GOTO Local Table (10)
502 handleTunnelIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, false);
507 ** Match: Match Tunnel ID and L2 ::::FF:FF Flooding
508 ** Action: Flood to selected destination TEPs
509 ** -------------------------------------------
510 ** table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
511 ** actions=output:10,output:11,goto_table:2
514 handleTunnelFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, false);
517 private Long getIntegrationBridgeOFDPID (Node node) {
519 String bridgeName = adminConfigManager.getIntegrationBridgeName();
520 String brIntId = this.getInternalBridgeUUID(node, bridgeName);
521 if (brIntId == null) {
522 logger.error("Unable to spot Bridge Identifier for {} in {}", bridgeName, node);
526 OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
527 Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brIntId);
528 Set<String> dpids = bridge.getDatapath_id();
529 if (dpids == null || dpids.size() == 0) return 0L;
530 return Long.valueOf(HexEncode.stringToLong((String) dpids.toArray()[0]));
531 } catch (Exception e) {
532 logger.error("Error finding Integration Bridge's OF DPID", e);
536 private void programLocalRules (String tunnelType, String segmentationId, Node node, Interface intf) {
538 Long dpid = this.getIntegrationBridgeOFDPID(node);
540 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
544 Set<BigInteger> of_ports = intf.getOfport();
545 if (of_ports == null || of_ports.size() <= 0) {
546 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
549 long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
551 Map<String, String> externalIds = intf.getExternal_ids();
552 if (externalIds == null) {
553 logger.error("No external_ids seen in {}", intf);
557 String attachedMac = externalIds.get(ITenantNetworkManager.EXTERNAL_ID_VM_MAC);
558 if (attachedMac == null) {
559 logger.error("No AttachedMac seen in {}", intf);
563 programLocalBridgeRules(node, dpid, segmentationId, attachedMac, localPort);
564 } catch (Exception e) {
565 logger.error("Exception in programming Local Rules for "+intf+" on "+node, e);
569 private void removeLocalRules (String networkType, String segmentationId, Node node, Interface intf) {
571 Long dpid = this.getIntegrationBridgeOFDPID(node);
573 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
577 Set<BigInteger> of_ports = intf.getOfport();
578 if (of_ports == null || of_ports.size() <= 0) {
579 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
582 long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
584 Map<String, String> externalIds = intf.getExternal_ids();
585 if (externalIds == null) {
586 logger.error("No external_ids seen in {}", intf);
590 String attachedMac = externalIds.get(ITenantNetworkManager.EXTERNAL_ID_VM_MAC);
591 if (attachedMac == null) {
592 logger.error("No AttachedMac seen in {}", intf);
596 /* Program local rules based on network type */
597 if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) ||
598 networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) {
599 logger.debug("Remove local bridge rules for interface {}", intf.getName());
600 removeLocalBridgeRules(node, dpid, segmentationId, attachedMac, localPort);
602 } catch (Exception e) {
603 logger.error("Exception in removing Local Rules for "+intf+" on "+node, e);
608 private void programTunnelRules (String tunnelType, String segmentationId, InetAddress dst, Node node,
609 Interface intf, boolean local) {
612 Long dpid = this.getIntegrationBridgeOFDPID(node);
614 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
617 OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
619 Set<BigInteger> of_ports = intf.getOfport();
620 if (of_ports == null || of_ports.size() <= 0) {
621 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
624 long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
626 Map<String, String> externalIds = intf.getExternal_ids();
627 if (externalIds == null) {
628 logger.error("No external_ids seen in {}", intf);
632 String attachedMac = externalIds.get(ITenantNetworkManager.EXTERNAL_ID_VM_MAC);
633 if (attachedMac == null) {
634 logger.error("No AttachedMac seen in {}", intf);
638 Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
640 for (org.opendaylight.ovsdb.lib.table.internal.Table<?> row : intfs.values()) {
641 Interface tunIntf = (Interface)row;
642 if (tunIntf.getName().equals(this.getTunnelName(tunnelType, dst))) {
643 of_ports = tunIntf.getOfport();
644 if (of_ports == null || of_ports.size() <= 0) {
645 logger.error("Could NOT Identify Tunnel port {} on {}", tunIntf.getName(), node);
648 long tunnelOFPort = ((BigInteger)of_ports.toArray()[0]).longValue();
650 if (tunnelOFPort == -1) {
651 logger.error("Could NOT Identify Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
654 logger.debug("Identified Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
657 programRemoteEgressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
659 logger.trace("program local ingress tunnel rules: node" + node.getNodeIDString() + " intf " + intf.getName());
661 programLocalIngressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
667 } catch (Exception e) {
672 private void removeTunnelRules (String tunnelType, String segmentationId, InetAddress dst, Node node,
673 Interface intf, boolean local, boolean isLastInstanceOnNode) {
676 Long dpid = this.getIntegrationBridgeOFDPID(node);
678 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
681 OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
683 Set<BigInteger> of_ports = intf.getOfport();
684 if (of_ports == null || of_ports.size() <= 0) {
685 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
688 long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
690 Map<String, String> externalIds = intf.getExternal_ids();
691 if (externalIds == null) {
692 logger.error("No external_ids seen in {}", intf);
696 String attachedMac = externalIds.get(ITenantNetworkManager.EXTERNAL_ID_VM_MAC);
697 if (attachedMac == null) {
698 logger.error("No AttachedMac seen in {}", intf);
702 Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
704 for (org.opendaylight.ovsdb.lib.table.internal.Table<?> row : intfs.values()) {
705 Interface tunIntf = (Interface)row;
706 if (tunIntf.getName().equals(this.getTunnelName(tunnelType, dst))) {
707 of_ports = tunIntf.getOfport();
708 if (of_ports == null || of_ports.size() <= 0) {
709 logger.error("Could NOT Identify Tunnel port {} on {}", tunIntf.getName(), node);
712 long tunnelOFPort = ((BigInteger)of_ports.toArray()[0]).longValue();
714 if (tunnelOFPort == -1) {
715 logger.error("Could NOT Identify Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
718 logger.debug("Identified Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
721 removeRemoteEgressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
723 if (local && isLastInstanceOnNode) {
724 removePerTunnelRules(node, dpid, segmentationId, tunnelOFPort);
730 } catch (Exception e) {
736 public Status handleInterfaceUpdate(NeutronNetwork network, Node srcNode, Interface intf) {
737 ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, "default", this);
738 if (switchManager == null) {
739 logger.error("Unable to identify SwitchManager");
741 Long dpid = this.getIntegrationBridgeOFDPID(srcNode);
743 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", srcNode);
744 return new Status(StatusCode.NOTFOUND);
746 Set<Node> ofNodes = switchManager.getNodes();
747 boolean ofNodeFound = false;
748 if (ofNodes != null) {
749 for (Node ofNode : ofNodes) {
750 if (ofNode.toString().contains(dpid+"")) {
751 logger.debug("Identified the Openflow node via toString {}", ofNode);
757 logger.error("Unable to find any Node from SwitchManager");
760 logger.error("Unable to find OF Node for {} with update {} on node {}", dpid, intf, srcNode);
761 return new Status(StatusCode.NOTFOUND);
765 IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
766 List<Node> nodes = connectionService.getNodes();
767 nodes.remove(srcNode);
768 this.programLocalRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), srcNode, intf);
770 for (Node dstNode : nodes) {
771 InetAddress src = adminConfigManager.getTunnelEndPoint(srcNode);
772 InetAddress dst = adminConfigManager.getTunnelEndPoint(dstNode);
773 Status status = addTunnelPort(srcNode, network.getProviderNetworkType(), src, dst);
774 if (status.isSuccess()) {
775 this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), dst, srcNode, intf, true);
777 addTunnelPort(dstNode, network.getProviderNetworkType(), dst, src);
778 if (status.isSuccess()) {
779 this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), src, dstNode, intf, false);
783 return new Status(StatusCode.SUCCESS);
786 private Status triggerInterfaceUpdates(Node node) {
788 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
789 Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
791 for (org.opendaylight.ovsdb.lib.table.internal.Table<?> row : intfs.values()) {
792 Interface intf = (Interface)row;
793 NeutronNetwork network = tenantNetworkManager.getTenantNetworkForInterface(intf);
794 logger.debug("Trigger Interface update for {}", intf);
795 if (network != null) {
796 this.handleInterfaceUpdate(network, node, intf);
800 } catch (Exception e) {
801 logger.error("Error Triggering the lost interface updates for "+ node, e);
802 return new Status(StatusCode.INTERNALERROR, e.getLocalizedMessage());
804 return new Status(StatusCode.SUCCESS);
807 public Status handleInterfaceUpdate(String tunnelType, String tunnelKey) {
808 // TODO Auto-generated method stub
813 public Status handleInterfaceDelete(String tunnelType, NeutronNetwork network, Node srcNode, Interface intf,
814 boolean isLastInstanceOnNode) {
815 Status status = new Status(StatusCode.SUCCESS);
816 IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
817 List<Node> nodes = connectionService.getNodes();
818 nodes.remove(srcNode);
820 logger.info("Delete intf " + intf.getName() + " isLastInstanceOnNode " + isLastInstanceOnNode);
821 if (intf.getType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN) || intf.getType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)) {
822 /* Delete tunnel port */
824 OvsDBMap<String, String> options = intf.getOptions();
825 InetAddress src = InetAddress.getByName(options.get("local_ip"));
826 InetAddress dst = InetAddress.getByName(options.get("remote_ip"));
827 status = deleteTunnelPort(srcNode, intf.getType(), src, dst);
828 } catch (Exception e) {
829 logger.error(e.getMessage(), e);
832 /* delete all other interfaces */
833 this.removeLocalRules(tunnelType, network.getProviderSegmentationID(),
836 if (tunnelType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)
837 || tunnelType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) {
838 for (Node dstNode : nodes) {
839 InetAddress src = adminConfigManager.getTunnelEndPoint(srcNode);
840 InetAddress dst = adminConfigManager.getTunnelEndPoint(dstNode);
841 logger.info("Remove tunnel rules for interface " + intf.getName() + " on srcNode" + srcNode.getNodeIDString());
842 this.removeTunnelRules(tunnelType, network.getProviderSegmentationID(),
843 dst, srcNode, intf, true, isLastInstanceOnNode);
844 logger.info("Remove tunnel rules for interface " + intf.getName() + " on dstNode" + dstNode.getNodeIDString());
845 this.removeTunnelRules(tunnelType, network.getProviderSegmentationID(),
846 src, dstNode, intf, false, isLastInstanceOnNode);
854 public void initializeFlowRules(Node node) {
855 this.initializeFlowRules(node, adminConfigManager.getIntegrationBridgeName());
856 this.triggerInterfaceUpdates(node);
863 private void initializeFlowRules(Node node, String bridgeName) {
864 Long dpid = this.getIntegrationBridgeOFDPID(node);
866 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
873 * Match: LLDP (0x88CCL)
874 * Action: Packet_In to Controller Reserved Port
881 * Create an LLDP Flow Rule to encapsulate into
882 * a packet_in that is sent to the controller
883 * for topology handling.
884 * Match: Ethertype 0x88CCL
885 * Action: Punt to Controller in a Packet_In msg
888 private void writeLLDPRule(Long dpidLong) {
890 String nodeName = "openflow:" + dpidLong;
891 EtherType etherType = new EtherType(0x88CCL);
893 MatchBuilder matchBuilder = new MatchBuilder();
894 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
895 FlowBuilder flowBuilder = new FlowBuilder();
897 // Create Match(es) and Set them in the FlowBuilder Object
898 flowBuilder.setMatch(createEtherTypeMatch(matchBuilder, etherType).build());
900 // Create the OF Actions and Instructions
901 InstructionBuilder ib = new InstructionBuilder();
902 InstructionsBuilder isb = new InstructionsBuilder();
904 // Instructions List Stores Individual Instructions
905 List<Instruction> instructions = new ArrayList<Instruction>();
907 // Call the InstructionBuilder Methods Containing Actions
908 createSendToControllerInstructions(ib);
910 ib.setKey(new InstructionKey(0));
911 instructions.add(ib.build());
913 // Add InstructionBuilder to the Instruction(s)Builder List
914 isb.setInstruction(instructions);
916 // Add InstructionsBuilder to FlowBuilder
917 flowBuilder.setInstructions(isb.build());
919 String flowId = "LLDP";
920 flowBuilder.setId(new FlowId(flowId));
921 FlowKey key = new FlowKey(new FlowId(flowId));
922 flowBuilder.setBarrier(true);
923 flowBuilder.setTableId((short) 0);
924 flowBuilder.setKey(key);
925 flowBuilder.setFlowName(flowId);
926 flowBuilder.setHardTimeout(0);
927 flowBuilder.setIdleTimeout(0);
928 writeFlow(flowBuilder, nodeBuilder);
932 * (Table:0) Ingress Tunnel Traffic
933 * Match: OpenFlow InPort and Tunnel ID
934 * Action: GOTO Local Table (10)
935 * table=0,tun_id=0x5,in_port=10, actions=goto_table:2
938 private void handleTunnelIn(Long dpidLong, Short writeTable, Short goToTableId,
939 String segmentationId, Long ofPort, boolean write) {
941 String nodeName = "openflow:" + dpidLong;
943 BigInteger tunnelId = new BigInteger(segmentationId);
944 MatchBuilder matchBuilder = new MatchBuilder();
945 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
946 FlowBuilder flowBuilder = new FlowBuilder();
948 // Create Match(es) and Set them in the FlowBuilder Object
949 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, tunnelId).build());
950 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, ofPort).build());
953 // Create the OF Actions and Instructions
954 InstructionBuilder ib = new InstructionBuilder();
955 InstructionsBuilder isb = new InstructionsBuilder();
957 // Instructions List Stores Individual Instructions
958 List<Instruction> instructions = new ArrayList<Instruction>();
960 // Call the InstructionBuilder Methods Containing Actions
961 createGotoTableInstructions(ib, goToTableId);
963 ib.setKey(new InstructionKey(0));
964 instructions.add(ib.build());
966 // Add InstructionBuilder to the Instruction(s)Builder List
967 isb.setInstruction(instructions);
969 // Add InstructionsBuilder to FlowBuilder
970 flowBuilder.setInstructions(isb.build());
973 String flowId = "TunnelIn_"+segmentationId+"_"+ofPort;
974 // Add Flow Attributes
975 flowBuilder.setId(new FlowId(flowId));
976 FlowKey key = new FlowKey(new FlowId(flowId));
977 flowBuilder.setStrict(true);
978 flowBuilder.setBarrier(false);
979 flowBuilder.setTableId(writeTable);
980 flowBuilder.setKey(key);
981 flowBuilder.setFlowName(flowId);
982 flowBuilder.setHardTimeout(0);
983 flowBuilder.setIdleTimeout(0);
986 writeFlow(flowBuilder, nodeBuilder);
988 removeFlow(flowBuilder, nodeBuilder);
993 * (Table:0) Egress VM Traffic Towards TEP
994 * Match: Destination Ethernet Addr and OpenFlow InPort
995 * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
996 * table=0,in_port=2,dl_src=00:00:00:00:00:01 \
997 * actions=set_field:5->tun_id,goto_table=1"
1000 private void handleLocalInPort(Long dpidLong, Short writeTable, Short goToTableId,
1001 String segmentationId, Long inPort, String attachedMac, boolean write) {
1003 String nodeName = "openflow:" + dpidLong;
1005 MatchBuilder matchBuilder = new MatchBuilder();
1006 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1007 FlowBuilder flowBuilder = new FlowBuilder();
1009 // Create the OF Match using MatchBuilder
1010 flowBuilder.setMatch(createEthSrcMatch(matchBuilder, new MacAddress(attachedMac)).build());
1011 // TODO Broken In_Port Match
1012 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
1014 String flowId = "LocalMac_"+segmentationId+"_"+inPort+"_"+attachedMac;
1015 // Add Flow Attributes
1016 flowBuilder.setId(new FlowId(flowId));
1017 FlowKey key = new FlowKey(new FlowId(flowId));
1018 flowBuilder.setStrict(true);
1019 flowBuilder.setBarrier(false);
1020 flowBuilder.setTableId(writeTable);
1021 flowBuilder.setKey(key);
1022 flowBuilder.setFlowName(flowId);
1023 flowBuilder.setHardTimeout(0);
1024 flowBuilder.setIdleTimeout(0);
1027 // Instantiate the Builders for the OF Actions and Instructions
1028 InstructionBuilder ib = new InstructionBuilder();
1029 InstructionsBuilder isb = new InstructionsBuilder();
1031 // Instructions List Stores Individual Instructions
1032 List<Instruction> instructions = new ArrayList<Instruction>();
1034 // GOTO Instuctions Need to be added first to the List
1035 createGotoTableInstructions(ib, goToTableId);
1037 ib.setKey(new InstructionKey(0));
1038 instructions.add(ib.build());
1039 // TODO Broken SetTunID
1040 createSetTunnelIdInstructions(ib, new BigInteger(segmentationId));
1042 ib.setKey(new InstructionKey(1));
1043 instructions.add(ib.build());
1045 // Add InstructionBuilder to the Instruction(s)Builder List
1046 isb.setInstruction(instructions);
1048 // Add InstructionsBuilder to FlowBuilder
1049 flowBuilder.setInstructions(isb.build());
1051 writeFlow(flowBuilder, nodeBuilder);
1053 removeFlow(flowBuilder, nodeBuilder);
1058 * (Table:0) Drop frames sourced from a VM that do not
1059 * match the associated MAC address of the local VM.
1060 * Match: Low priority anything not matching the VM SMAC
1062 * table=0,priority=16384,in_port=1 actions=drop"
1065 private void handleDropSrcIface(Long dpidLong, Long inPort, boolean write) {
1067 String nodeName = "openflow:" + dpidLong;
1069 MatchBuilder matchBuilder = new MatchBuilder();
1070 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1071 FlowBuilder flowBuilder = new FlowBuilder();
1073 // Create the OF Match using MatchBuilder
1074 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
1077 // Instantiate the Builders for the OF Actions and Instructions
1078 InstructionBuilder ib = new InstructionBuilder();
1079 InstructionsBuilder isb = new InstructionsBuilder();
1081 // Instructions List Stores Individual Instructions
1082 List<Instruction> instructions = new ArrayList<Instruction>();
1084 // Call the InstructionBuilder Methods Containing Actions
1085 createDropInstructions(ib);
1087 ib.setKey(new InstructionKey(0));
1088 instructions.add(ib.build());
1090 // Add InstructionBuilder to the Instruction(s)Builder List
1091 isb.setInstruction(instructions);
1093 // Add InstructionsBuilder to FlowBuilder
1094 flowBuilder.setInstructions(isb.build());
1097 String flowId = "DropFilter_"+inPort;
1098 // Add Flow Attributes
1099 flowBuilder.setId(new FlowId(flowId));
1100 FlowKey key = new FlowKey(new FlowId(flowId));
1101 flowBuilder.setStrict(true);
1102 flowBuilder.setBarrier(false);
1103 flowBuilder.setTableId((short) 0);
1104 flowBuilder.setKey(key);
1105 flowBuilder.setFlowName(flowId);
1106 flowBuilder.setPriority(8192);
1107 flowBuilder.setHardTimeout(0);
1108 flowBuilder.setIdleTimeout(0);
1110 writeFlow(flowBuilder, nodeBuilder);
1112 removeFlow(flowBuilder, nodeBuilder);
1117 * (Table:1) Egress Tunnel Traffic
1118 * Match: Destination Ethernet Addr and Local InPort
1119 * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
1120 * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
1121 * actions=output:10,goto_table:2"
1124 private void handleTunnelOut(Long dpidLong, Short writeTable, Short goToTableId, String segmentationId,
1125 Long OFPortOut, String attachedMac, boolean write) {
1127 String nodeName = "openflow:" + dpidLong;
1129 MatchBuilder matchBuilder = new MatchBuilder();
1130 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1131 FlowBuilder flowBuilder = new FlowBuilder();
1133 // Create the OF Match using MatchBuilder
1134 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
1135 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
1137 String flowId = "TunnelOut_"+segmentationId+"_"+OFPortOut+"_"+attachedMac;
1138 // Add Flow Attributes
1139 flowBuilder.setId(new FlowId(flowId));
1140 FlowKey key = new FlowKey(new FlowId(flowId));
1141 flowBuilder.setStrict(true);
1142 flowBuilder.setBarrier(false);
1143 flowBuilder.setTableId(writeTable);
1144 flowBuilder.setKey(key);
1145 flowBuilder.setFlowName(flowId);
1146 flowBuilder.setHardTimeout(0);
1147 flowBuilder.setIdleTimeout(0);
1150 // Instantiate the Builders for the OF Actions and Instructions
1151 InstructionBuilder ib = new InstructionBuilder();
1152 InstructionsBuilder isb = new InstructionsBuilder();
1154 // Instructions List Stores Individual Instructions
1155 List<Instruction> instructions = new ArrayList<Instruction>();
1158 createGotoTableInstructions(ib, goToTableId);
1160 ib.setKey(new InstructionKey(0));
1161 instructions.add(ib.build());
1162 // Set the Output Port/Iface
1163 createOutputPortInstructions(ib, dpidLong, OFPortOut);
1165 ib.setKey(new InstructionKey(1));
1166 instructions.add(ib.build());
1168 // Add InstructionBuilder to the Instruction(s)Builder List
1169 isb.setInstruction(instructions);
1171 // Add InstructionsBuilder to FlowBuilder
1172 flowBuilder.setInstructions(isb.build());
1174 writeFlow(flowBuilder, nodeBuilder);
1176 removeFlow(flowBuilder, nodeBuilder);
1181 * (Table:1) Egress Tunnel Traffic
1182 * Match: Destination Ethernet Addr and Local InPort
1183 * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
1184 * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
1185 * actions=output:10,output:11,goto_table:2
1188 private void handleTunnelFloodOut(Long dpidLong, Short writeTable, Short localTable,
1189 String segmentationId, Long OFPortOut, boolean write) {
1191 String nodeName = "openflow:" + dpidLong;
1193 MatchBuilder matchBuilder = new MatchBuilder();
1194 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1195 FlowBuilder flowBuilder = new FlowBuilder();
1197 // Create the OF Match using MatchBuilder
1199 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
1202 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
1204 String flowId = "TunnelFloodOut_"+segmentationId;
1205 // Add Flow Attributes
1206 flowBuilder.setId(new FlowId(flowId));
1207 FlowKey key = new FlowKey(new FlowId(flowId));
1208 flowBuilder.setBarrier(true);
1209 flowBuilder.setTableId(writeTable);
1210 flowBuilder.setKey(key);
1211 flowBuilder.setPriority(16384);
1212 flowBuilder.setFlowName(flowId);
1213 flowBuilder.setHardTimeout(0);
1214 flowBuilder.setIdleTimeout(0);
1216 Flow flow = this.getFlow(flowBuilder, nodeBuilder);
1217 // Instantiate the Builders for the OF Actions and Instructions
1218 InstructionBuilder ib = new InstructionBuilder();
1219 InstructionsBuilder isb = new InstructionsBuilder();
1220 List<Instruction> instructions = new ArrayList<Instruction>();
1221 List<Instruction> existingInstructions = null;
1223 Instructions ins = flow.getInstructions();
1225 existingInstructions = ins.getInstruction();
1231 createGotoTableInstructions(ib, localTable);
1233 ib.setKey(new InstructionKey(0));
1234 instructions.add(ib.build());
1235 // Set the Output Port/Iface
1236 createOutputPortInstructions(ib, dpidLong, OFPortOut, existingInstructions);
1238 ib.setKey(new InstructionKey(1));
1239 instructions.add(ib.build());
1241 // Add InstructionBuilder to the Instruction(s)Builder List
1242 isb.setInstruction(instructions);
1244 // Add InstructionsBuilder to FlowBuilder
1245 flowBuilder.setInstructions(isb.build());
1247 writeFlow(flowBuilder, nodeBuilder);
1249 /* remove port from action list */
1250 boolean flowRemove = removeOutputPortFromInstructions(ib, dpidLong,OFPortOut, existingInstructions);
1252 /* if all port are removed, remove the flow too. */
1253 removeFlow(flowBuilder, nodeBuilder);
1255 /* Install instruction with new output port list*/
1257 ib.setKey(new InstructionKey(0));
1258 instructions.add(ib.build());
1260 // Add InstructionBuilder to the Instruction(s)Builder List
1261 isb.setInstruction(instructions);
1263 // Add InstructionsBuilder to FlowBuilder
1264 flowBuilder.setInstructions(isb.build());
1270 * (Table:1) Table Drain w/ Catch All
1272 * Action: GOTO Local Table (10)
1273 * table=2,priority=8192,tun_id=0x5 actions=drop
1276 private void handleTunnelMiss(Long dpidLong, Short writeTable, Short goToTableId, String segmentationId, boolean write) {
1278 String nodeName = "openflow:" + dpidLong;
1280 MatchBuilder matchBuilder = new MatchBuilder();
1281 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1282 FlowBuilder flowBuilder = new FlowBuilder();
1284 // Create Match(es) and Set them in the FlowBuilder Object
1285 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
1288 // Create the OF Actions and Instructions
1289 InstructionBuilder ib = new InstructionBuilder();
1290 InstructionsBuilder isb = new InstructionsBuilder();
1292 // Instructions List Stores Individual Instructions
1293 List<Instruction> instructions = new ArrayList<Instruction>();
1295 // Call the InstructionBuilder Methods Containing Actions
1296 createGotoTableInstructions(ib, goToTableId);
1298 ib.setKey(new InstructionKey(0));
1299 instructions.add(ib.build());
1301 // Add InstructionBuilder to the Instruction(s)Builder List
1302 isb.setInstruction(instructions);
1304 // Add InstructionsBuilder to FlowBuilder
1305 flowBuilder.setInstructions(isb.build());
1308 String flowId = "TunnelMiss_"+segmentationId;
1309 // Add Flow Attributes
1310 flowBuilder.setId(new FlowId(flowId));
1311 FlowKey key = new FlowKey(new FlowId(flowId));
1312 flowBuilder.setStrict(true);
1313 flowBuilder.setBarrier(false);
1314 flowBuilder.setTableId(writeTable);
1315 flowBuilder.setKey(key);
1316 flowBuilder.setPriority(8192);
1317 flowBuilder.setFlowName(flowId);
1318 flowBuilder.setHardTimeout(0);
1319 flowBuilder.setIdleTimeout(0);
1321 writeFlow(flowBuilder, nodeBuilder);
1323 removeFlow(flowBuilder, nodeBuilder);
1328 * (Table:1) Local Broadcast Flood
1329 * Match: Tunnel ID and dMAC
1330 * Action: Output Port
1331 * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
1334 private void handleLocalUcastOut(Long dpidLong, Short writeTable, String segmentationId, Long localPort,
1335 String attachedMac, boolean write) {
1337 String nodeName = "openflow:" + dpidLong;
1339 MatchBuilder matchBuilder = new MatchBuilder();
1340 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1341 FlowBuilder flowBuilder = new FlowBuilder();
1343 // Create the OF Match using MatchBuilder
1344 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
1345 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
1347 String flowId = "UcastOut_"+segmentationId+"_"+localPort+"_"+attachedMac;
1348 // Add Flow Attributes
1349 flowBuilder.setId(new FlowId(flowId));
1350 FlowKey key = new FlowKey(new FlowId(flowId));
1351 flowBuilder.setStrict(true);
1352 flowBuilder.setBarrier(false);
1353 flowBuilder.setTableId(writeTable);
1354 flowBuilder.setKey(key);
1355 flowBuilder.setFlowName(flowId);
1356 flowBuilder.setHardTimeout(0);
1357 flowBuilder.setIdleTimeout(0);
1360 // Instantiate the Builders for 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 // Set the Output Port/Iface
1368 createOutputPortInstructions(ib, dpidLong, localPort);
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());
1378 writeFlow(flowBuilder, nodeBuilder);
1380 removeFlow(flowBuilder, nodeBuilder);
1385 * (Table:1) Local Broadcast Flood
1386 * Match: Tunnel ID and dMAC (::::FF:FF)
1387 * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
1388 * actions=output:2,3,4,5
1391 private void handleLocalBcastOut(Long dpidLong, Short writeTable, String segmentationId,
1392 Long localPort, boolean write) {
1394 String nodeName = "openflow:" + dpidLong;
1396 MatchBuilder matchBuilder = new MatchBuilder();
1397 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1398 FlowBuilder flowBuilder = new FlowBuilder();
1400 // Create the OF Match using MatchBuilder
1401 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
1402 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
1404 String flowId = "BcastOut_"+segmentationId;
1405 // Add Flow Attributes
1406 flowBuilder.setId(new FlowId(flowId));
1407 FlowKey key = new FlowKey(new FlowId(flowId));
1408 flowBuilder.setStrict(true);
1409 flowBuilder.setBarrier(false);
1410 flowBuilder.setTableId(writeTable);
1411 flowBuilder.setKey(key);
1412 flowBuilder.setPriority(16384);
1413 flowBuilder.setFlowName(flowId);
1414 flowBuilder.setHardTimeout(0);
1415 flowBuilder.setIdleTimeout(0);
1416 Flow flow = this.getFlow(flowBuilder, nodeBuilder);
1417 // Instantiate the Builders for the OF Actions and Instructions
1418 InstructionBuilder ib = new InstructionBuilder();
1419 InstructionsBuilder isb = new InstructionsBuilder();
1420 List<Instruction> instructions = new ArrayList<Instruction>();
1421 List<Instruction> existingInstructions = null;
1423 Instructions ins = flow.getInstructions();
1425 existingInstructions = ins.getInstruction();
1430 // Create output port list
1431 createOutputPortInstructions(ib, dpidLong, localPort, existingInstructions);
1433 ib.setKey(new InstructionKey(0));
1434 instructions.add(ib.build());
1436 // Add InstructionBuilder to the Instruction(s)Builder List
1437 isb.setInstruction(instructions);
1439 // Add InstructionsBuilder to FlowBuilder
1440 flowBuilder.setInstructions(isb.build());
1442 writeFlow(flowBuilder, nodeBuilder);
1444 boolean flowRemove = removeOutputPortFromInstructions(ib, dpidLong,
1445 localPort, existingInstructions);
1447 /* if all ports are removed, remove flow */
1448 removeFlow(flowBuilder, nodeBuilder);
1450 /* Install instruction with new output port list*/
1452 ib.setKey(new InstructionKey(0));
1453 instructions.add(ib.build());
1455 // Add InstructionBuilder to the Instruction(s)Builder List
1456 isb.setInstruction(instructions);
1458 // Add InstructionsBuilder to FlowBuilder
1459 flowBuilder.setInstructions(isb.build());
1461 writeFlow(flowBuilder, nodeBuilder);
1467 * (Table:1) Local Table Miss
1468 * Match: Any Remaining Flows w/a TunID
1469 * Action: Drop w/ a low priority
1470 * table=2,priority=8192,tun_id=0x5 actions=drop
1473 private void handleLocalTableMiss(Long dpidLong, Short writeTable, String segmentationId,
1476 String nodeName = "openflow:" + dpidLong;
1478 MatchBuilder matchBuilder = new MatchBuilder();
1479 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1480 FlowBuilder flowBuilder = new FlowBuilder();
1482 // Create Match(es) and Set them in the FlowBuilder Object
1483 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
1486 // Create the OF Actions and Instructions
1487 InstructionBuilder ib = new InstructionBuilder();
1488 InstructionsBuilder isb = new InstructionsBuilder();
1490 // Instructions List Stores Individual Instructions
1491 List<Instruction> instructions = new ArrayList<Instruction>();
1493 // Call the InstructionBuilder Methods Containing Actions
1494 createDropInstructions(ib);
1496 ib.setKey(new InstructionKey(0));
1497 instructions.add(ib.build());
1499 // Add InstructionBuilder to the Instruction(s)Builder List
1500 isb.setInstruction(instructions);
1502 // Add InstructionsBuilder to FlowBuilder
1503 flowBuilder.setInstructions(isb.build());
1506 String flowId = "LocalTableMiss_"+segmentationId;
1507 // Add Flow Attributes
1508 flowBuilder.setId(new FlowId(flowId));
1509 FlowKey key = new FlowKey(new FlowId(flowId));
1510 flowBuilder.setStrict(true);
1511 flowBuilder.setBarrier(false);
1512 flowBuilder.setTableId(writeTable);
1513 flowBuilder.setKey(key);
1514 flowBuilder.setPriority(8192);
1515 flowBuilder.setFlowName(flowId);
1516 flowBuilder.setHardTimeout(0);
1517 flowBuilder.setIdleTimeout(0);
1519 writeFlow(flowBuilder, nodeBuilder);
1521 removeFlow(flowBuilder, nodeBuilder);
1525 private Flow getFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
1526 IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
1527 if (mdsalConsumer == null) {
1528 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
1532 dataBrokerService = mdsalConsumer.getDataBrokerService();
1534 if (dataBrokerService == null) {
1535 logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
1539 InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
1540 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class,
1541 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
1542 return (Flow)dataBrokerService.readConfigurationData(path1);
1545 private void writeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
1546 IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
1547 if (mdsalConsumer == null) {
1548 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
1552 dataBrokerService = mdsalConsumer.getDataBrokerService();
1554 if (dataBrokerService == null) {
1555 logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
1558 DataModification<InstanceIdentifier<?>, DataObject> modification = dataBrokerService.beginTransaction();
1559 InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
1560 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class,
1561 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
1562 modification.putOperationalData(nodeBuilderToInstanceId(nodeBuilder), nodeBuilder.build());
1563 modification.putOperationalData(path1, flowBuilder.build());
1564 modification.putConfigurationData(nodeBuilderToInstanceId(nodeBuilder), nodeBuilder.build());
1565 modification.putConfigurationData(path1, flowBuilder.build());
1566 Future<RpcResult<TransactionStatus>> commitFuture = modification.commit();
1568 RpcResult<TransactionStatus> result = commitFuture.get();
1569 TransactionStatus status = result.getResult();
1570 logger.debug("Transaction Status "+status.toString()+" for Flow "+flowBuilder.getFlowName());
1571 } catch (InterruptedException e) {
1572 logger.error(e.getMessage(), e);
1573 } catch (ExecutionException e) {
1574 logger.error(e.getMessage(), e);
1578 private void removeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
1579 IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
1580 if (mdsalConsumer == null) {
1581 logger.error("ERROR finding MDSAL Service.");
1585 dataBrokerService = mdsalConsumer.getDataBrokerService();
1587 if (dataBrokerService == null) {
1588 logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SALsupport on the Controller.");
1591 DataModification<InstanceIdentifier<?>, DataObject> modification = dataBrokerService.beginTransaction();
1592 InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class)
1593 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
1594 .rev130819.nodes.Node.class, nodeBuilder.getKey())
1595 .augmentation(FlowCapableNode.class).child(Table.class,
1596 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
1597 //modification.removeOperationalData(nodeBuilderToInstanceId(nodeBuilder));
1598 modification.removeOperationalData(path1);
1599 //modification.removeConfigurationData(nodeBuilderToInstanceId(nodeBuilder));
1600 modification.removeConfigurationData(path1);
1601 Future<RpcResult<TransactionStatus>> commitFuture = modification.commit();
1603 RpcResult<TransactionStatus> result = commitFuture.get();
1604 TransactionStatus status = result.getResult();
1605 logger.debug("Transaction Status "+status.toString()+" for Flow "+flowBuilder.getFlowName());
1606 } catch (InterruptedException e) {
1607 logger.error(e.getMessage(), e);
1608 } catch (ExecutionException e) {
1609 logger.error(e.getMessage(), e);
1614 * Create Ingress Port Match dpidLong, inPort
1616 * @param matchBuilder Map matchBuilder MatchBuilder Object without a match
1617 * @param dpidLong Long the datapath ID of a switch/node
1618 * @param inPort Long ingress port on a switch
1619 * @return matchBuilder Map MatchBuilder Object with a match
1621 protected static MatchBuilder createInPortMatch(MatchBuilder matchBuilder, Long dpidLong, Long inPort) {
1623 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + inPort);
1624 logger.debug("createInPortMatch() Node Connector ID is - Type=openflow: DPID={} inPort={} ", dpidLong, inPort);
1625 matchBuilder.setInPort(NodeConnectorId.getDefaultInstance(ncid.getValue()));
1626 matchBuilder.setInPort(ncid);
1628 return matchBuilder;
1632 * Create EtherType Match
1634 * @param matchBuilder Map matchBuilder MatchBuilder Object without a match
1635 * @param etherType Long EtherType
1636 * @return matchBuilder Map MatchBuilder Object with a match
1638 protected static MatchBuilder createEtherTypeMatch(MatchBuilder matchBuilder, EtherType etherType) {
1640 EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
1641 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
1642 ethTypeBuilder.setType(new EtherType(etherType));
1643 ethernetMatch.setEthernetType(ethTypeBuilder.build());
1644 matchBuilder.setEthernetMatch(ethernetMatch.build());
1646 return matchBuilder;
1650 * Create Ethernet Source Match
1652 * @param matchBuilder MatchBuilder Object without a match yet
1653 * @param sMacAddr String representing a source MAC
1654 * @return matchBuilder Map MatchBuilder Object with a match
1656 protected static MatchBuilder createEthSrcMatch(MatchBuilder matchBuilder, MacAddress sMacAddr) {
1658 EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
1659 EthernetSourceBuilder ethSourceBuilder = new EthernetSourceBuilder();
1660 ethSourceBuilder.setAddress(new MacAddress(sMacAddr));
1661 ethernetMatch.setEthernetSource(ethSourceBuilder.build());
1662 matchBuilder.setEthernetMatch(ethernetMatch.build());
1664 return matchBuilder;
1668 * Create Ethernet Destination Match
1670 * @param matchBuilder MatchBuilder Object without a match yet
1671 * @param vlanId Integer representing a VLAN ID Integer representing a VLAN ID
1672 * @return matchBuilder Map MatchBuilder Object with a match
1675 protected static MatchBuilder createVlanIdMatch(MatchBuilder matchBuilder, VlanId vlanId) {
1677 VlanMatchBuilder vlanMatchBuilder = new VlanMatchBuilder();
1678 VlanIdBuilder vlanIdBuilder = new VlanIdBuilder();
1679 vlanIdBuilder.setVlanId(new VlanId(vlanId));
1680 vlanMatchBuilder.setVlanId(vlanIdBuilder.build());
1681 matchBuilder.setVlanMatch(vlanMatchBuilder.build());
1683 return matchBuilder;
1687 * Create Ethernet Destination Match
1689 * @param matchBuilder MatchBuilder Object without a match yet
1690 * @param dMacAddr String representing a destination MAC
1691 * @return matchBuilder Map MatchBuilder Object with a match
1694 protected static MatchBuilder createDestEthMatch(MatchBuilder matchBuilder, MacAddress dMacAddr, MacAddress mask) {
1696 EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
1697 EthernetDestinationBuilder ethDestinationBuilder = new EthernetDestinationBuilder();
1698 ethDestinationBuilder.setAddress(new MacAddress(dMacAddr));
1700 ethDestinationBuilder.setMask(mask);
1702 ethernetMatch.setEthernetDestination(ethDestinationBuilder.build());
1703 matchBuilder.setEthernetMatch(ethernetMatch.build());
1705 return matchBuilder;
1709 * Tunnel ID Match Builder
1711 * @param matchBuilder MatchBuilder Object without a match yet
1712 * @param tunnelId BigInteger representing a tunnel ID
1713 * @return matchBuilder Map MatchBuilder Object with a match
1715 protected static MatchBuilder createTunnelIDMatch(MatchBuilder matchBuilder, BigInteger tunnelId) {
1717 TunnelBuilder tunnelBuilder = new TunnelBuilder();
1718 tunnelBuilder.setTunnelId(tunnelId);
1719 matchBuilder.setTunnel(tunnelBuilder.build());
1721 return matchBuilder;
1725 * Match ICMP code and type
1727 * @param matchBuilder MatchBuilder Object without a match yet
1728 * @param type short representing an ICMP type
1729 * @param code short representing an ICMP code
1730 * @return matchBuilder Map MatchBuilder Object with a match
1732 protected static MatchBuilder createICMPv4Match(MatchBuilder matchBuilder, short type, short code) {
1734 EthernetMatchBuilder eth = new EthernetMatchBuilder();
1735 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
1736 ethTypeBuilder.setType(new EtherType(0x0800L));
1737 eth.setEthernetType(ethTypeBuilder.build());
1738 matchBuilder.setEthernetMatch(eth.build());
1740 // Build the IPv4 Match requied per OVS Syntax
1741 IpMatchBuilder ipmatch = new IpMatchBuilder();
1742 ipmatch.setIpProtocol((short) 1);
1743 matchBuilder.setIpMatch(ipmatch.build());
1745 // Build the ICMPv4 Match
1746 Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
1747 icmpv4match.setIcmpv4Type(type);
1748 icmpv4match.setIcmpv4Code(code);
1749 matchBuilder.setIcmpv4Match(icmpv4match.build());
1751 return matchBuilder;
1755 * @param matchBuilder MatchBuilder Object without a match yet
1756 * @param dstip String containing an IPv4 prefix
1757 * @return matchBuilder Map Object with a match
1759 private static MatchBuilder createDstL3IPv4Match(MatchBuilder matchBuilder, Ipv4Prefix dstip) {
1761 EthernetMatchBuilder eth = new EthernetMatchBuilder();
1762 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
1763 ethTypeBuilder.setType(new EtherType(0x0800L));
1764 eth.setEthernetType(ethTypeBuilder.build());
1765 matchBuilder.setEthernetMatch(eth.build());
1767 Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder();
1768 ipv4match.setIpv4Destination(dstip);
1770 matchBuilder.setLayer3Match(ipv4match.build());
1772 return matchBuilder;
1777 * @param matchBuilder MatchBuilder Object without a match yet
1778 * @param srcip String containing an IPv4 prefix
1779 * @return matchBuilder Map Object with a match
1781 private static MatchBuilder createSrcL3IPv4Match(MatchBuilder matchBuilder, Ipv4Prefix srcip) {
1783 EthernetMatchBuilder eth = new EthernetMatchBuilder();
1784 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
1785 ethTypeBuilder.setType(new EtherType(0x0800L));
1786 eth.setEthernetType(ethTypeBuilder.build());
1787 matchBuilder.setEthernetMatch(eth.build());
1789 Ipv4MatchBuilder ipv4Match = new Ipv4MatchBuilder();
1790 Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder();
1791 ipv4match.setIpv4Source(srcip);
1792 matchBuilder.setLayer3Match(ipv4match.build());
1794 return matchBuilder;
1799 * Create Source TCP Port Match
1801 * @param matchBuilder @param matchbuilder MatchBuilder Object without a match yet
1802 * @param tcpport Integer representing a source TCP port
1803 * @return matchBuilder Map MatchBuilder Object with a match
1805 protected static MatchBuilder createSetSrcTcpMatch(MatchBuilder matchBuilder, PortNumber tcpport) {
1807 EthernetMatchBuilder ethType = new EthernetMatchBuilder();
1808 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
1809 ethTypeBuilder.setType(new EtherType(0x0800L));
1810 ethType.setEthernetType(ethTypeBuilder.build());
1811 matchBuilder.setEthernetMatch(ethType.build());
1813 IpMatchBuilder ipmatch = new IpMatchBuilder();
1814 ipmatch.setIpProtocol((short) 6);
1815 matchBuilder.setIpMatch(ipmatch.build());
1817 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
1818 tcpmatch.setTcpSourcePort(tcpport);
1819 matchBuilder.setLayer4Match(tcpmatch.build());
1821 return matchBuilder;
1826 * Create Destination TCP Port Match
1828 * @param matchBuilder MatchBuilder Object without a match yet
1829 * @param tcpport Integer representing a destination TCP port
1830 * @return matchBuilder Map MatchBuilder Object with a match
1832 protected static MatchBuilder createSetDstTcpMatch(MatchBuilder matchBuilder, PortNumber tcpport) {
1834 EthernetMatchBuilder ethType = new EthernetMatchBuilder();
1835 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
1836 ethTypeBuilder.setType(new EtherType(0x0800L));
1837 ethType.setEthernetType(ethTypeBuilder.build());
1838 matchBuilder.setEthernetMatch(ethType.build());
1840 IpMatchBuilder ipmatch = new IpMatchBuilder();
1841 ipmatch.setIpProtocol((short) 6);
1842 matchBuilder.setIpMatch(ipmatch.build());
1844 PortNumber dstport = new PortNumber(tcpport);
1845 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
1847 tcpmatch.setTcpDestinationPort(tcpport);
1848 matchBuilder.setLayer4Match(tcpmatch.build());
1850 return matchBuilder;
1854 * Create Send to Controller Reserved Port Instruction (packet_in)
1856 * @param ib Map InstructionBuilder without any instructions
1857 * @return ib Map InstructionBuilder with instructions
1860 protected static InstructionBuilder createSendToControllerInstructions(InstructionBuilder ib) {
1862 List<Action> actionList = new ArrayList<Action>();
1863 ActionBuilder ab = new ActionBuilder();
1865 OutputActionBuilder output = new OutputActionBuilder();
1866 output.setMaxLength(56);
1867 Uri value = new Uri("CONTROLLER");
1868 output.setOutputNodeConnector(value);
1869 ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
1871 ab.setKey(new ActionKey(0));
1872 actionList.add(ab.build());
1874 // Create an Apply Action
1875 ApplyActionsBuilder aab = new ApplyActionsBuilder();
1876 aab.setAction(actionList);
1878 // Wrap our Apply Action in an Instruction
1879 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1885 * Create Output Port Instruction
1887 * @param ib Map InstructionBuilder without any instructions
1888 * @param dpidLong Long the datapath ID of a switch/node
1889 * @param port Long representing a port on a switch/node
1890 * @return ib InstructionBuilder Map with instructions
1892 protected static InstructionBuilder createOutputPortInstructions(InstructionBuilder ib, Long dpidLong, Long port) {
1894 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
1895 logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} inPort={} ", dpidLong, port);
1897 List<Action> actionList = new ArrayList<Action>();
1898 ActionBuilder ab = new ActionBuilder();
1899 OutputActionBuilder oab = new OutputActionBuilder();
1900 oab.setOutputNodeConnector(ncid);
1902 ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
1904 ab.setKey(new ActionKey(0));
1905 actionList.add(ab.build());
1907 // Create an Apply Action
1908 ApplyActionsBuilder aab = new ApplyActionsBuilder();
1909 aab.setAction(actionList);
1910 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1916 * Create Output Port Instruction
1918 * @param ib Map InstructionBuilder without any instructions
1919 * @param dpidLong Long the datapath ID of a switch/node
1920 * @param port Long representing a port on a switch/node
1921 * @return ib InstructionBuilder Map with instructions
1923 protected static InstructionBuilder createOutputPortInstructions(InstructionBuilder ib, Long dpidLong, Long port , List<Instruction> instructions) {
1925 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
1926 logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
1928 List<Action> actionList = new ArrayList<Action>();
1929 ActionBuilder ab = new ActionBuilder();
1931 List<Action> existingActions = null;
1932 if (instructions != null) {
1933 for (Instruction in : instructions) {
1934 if (in.getInstruction() instanceof ApplyActionsCase) {
1935 existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
1936 actionList.addAll(existingActions);
1941 OutputActionBuilder oab = new OutputActionBuilder();
1942 oab.setOutputNodeConnector(ncid);
1943 ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
1945 ab.setKey(new ActionKey(0));
1946 Action newAction = ab.build();
1947 boolean addNew = true;
1948 for (Action action : actionList) {
1949 if (action.getAction() instanceof OutputActionCase) {
1950 OutputActionCase opAction = (OutputActionCase)action.getAction();
1951 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
1957 if (addNew) actionList.add(newAction);
1959 // Create an Apply Action
1960 ApplyActionsBuilder aab = new ApplyActionsBuilder();
1961 aab.setAction(actionList);
1962 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1968 * Remove Output Port from Instruction
1970 * @param ib Map InstructionBuilder without any instructions
1971 * @param dpidLong Long the datapath ID of a switch/node
1972 * @param port Long representing a port on a switch/node
1973 * @return ib InstructionBuilder Map with instructions
1975 protected static boolean removeOutputPortFromInstructions(InstructionBuilder ib,
1976 Long dpidLong, Long port , List<Instruction> instructions) {
1978 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
1979 logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
1981 List<Action> actionList = new ArrayList<Action>();
1982 ActionBuilder ab = new ActionBuilder();
1984 List<Action> existingActions = null;
1985 if (instructions != null) {
1986 for (Instruction in : instructions) {
1987 if (in.getInstruction() instanceof ApplyActionsCase) {
1988 existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
1989 actionList.addAll(existingActions);
1995 int numOutputPort = 0;
1996 for (Action action : actionList) {
1997 if (action.getAction() instanceof OutputActionCase) {
1999 OutputActionCase opAction = (OutputActionCase)action.getAction();
2000 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
2001 /* Find the output port in action list and remove */
2002 actionList.remove(action);
2009 /* Put new action list in Apply Action instruction */
2010 if (numOutputPort > 0) {
2011 ApplyActionsBuilder aab = new ApplyActionsBuilder();
2012 aab.setAction(actionList);
2013 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
2016 /* if all output port are removed. Return true to indicate flow remove */
2022 * Create Set Vlan ID Instruction
2024 * @param ib Map InstructionBuilder without any instructions
2025 * @param vlanId Integer representing a VLAN ID Integer representing a VLAN ID
2026 * @return ib Map InstructionBuilder with instructions
2028 protected static InstructionBuilder createSetVlanInstructions(InstructionBuilder ib, VlanId vlanId) {
2030 List<Action> actionList = new ArrayList<Action>();
2031 ActionBuilder ab = new ActionBuilder();
2033 SetVlanIdActionBuilder vl = new SetVlanIdActionBuilder();
2034 vl.setVlanId(vlanId);
2035 ab.setAction(new SetVlanIdActionCaseBuilder().setSetVlanIdAction(vl.build()).build());
2036 actionList.add(ab.build());
2037 // Create an Apply Action
2038 ApplyActionsBuilder aab = new ApplyActionsBuilder();
2039 aab.setAction(actionList);
2041 // Wrap our Apply Action in an Instruction
2042 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
2048 * Create Set IPv4 Destination Instruction
2050 * @param ib Map InstructionBuilder without any instructions
2051 * @return ib Map InstructionBuilder with instructions
2053 protected static InstructionBuilder createStripVlanInstructions(InstructionBuilder ib) {
2055 StripVlanActionBuilder stripVlanActionBuilder = new StripVlanActionBuilder();
2056 StripVlanAction vlanAction = stripVlanActionBuilder.build();
2057 ActionBuilder ab = new ActionBuilder();
2058 ab.setAction(new StripVlanActionCaseBuilder().setStripVlanAction(vlanAction).build());
2060 // Add our drop action to a list
2061 List<Action> actionList = new ArrayList<Action>();
2062 actionList.add(ab.build());
2064 // Create an Apply Action
2065 ApplyActionsBuilder aab = new ApplyActionsBuilder();
2066 aab.setAction(actionList);
2068 // Wrap our Apply Action in an Instruction
2069 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
2075 * Create Set IPv4 Source Instruction
2077 * @param ib Map InstructionBuilder without any instructions
2078 * @param prefixsrc String containing an IPv4 prefix
2079 * @return ib Map InstructionBuilder with instructions
2081 protected static InstructionBuilder createNwSrcInstructions(InstructionBuilder ib, Ipv4Prefix prefixsrc) {
2083 List<Action> actionList = new ArrayList<Action>();
2084 ActionBuilder ab = new ActionBuilder();
2086 SetNwSrcActionBuilder setNwsrcActionBuilder = new SetNwSrcActionBuilder();
2087 Ipv4Builder ipsrc = new Ipv4Builder();
2088 ipsrc.setIpv4Address(prefixsrc);
2089 setNwsrcActionBuilder.setAddress(ipsrc.build());
2090 ab.setAction(new SetNwSrcActionCaseBuilder().setSetNwSrcAction(setNwsrcActionBuilder.build()).build());
2091 actionList.add(ab.build());
2093 // Create an Apply Action
2094 ApplyActionsBuilder aab = new ApplyActionsBuilder();
2095 aab.setAction(actionList);
2097 // Wrap our Apply Action in an Instruction
2098 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
2104 * Create Set IPv4 Destination Instruction
2106 * @param ib Map InstructionBuilder without any instructions
2107 * @param prefixdst String containing an IPv4 prefix
2108 * @return ib Map InstructionBuilder with instructions
2110 protected static InstructionBuilder createNwDstInstructions(InstructionBuilder ib, Ipv4Prefix prefixdst) {
2112 List<Action> actionList = new ArrayList<Action>();
2113 ActionBuilder ab = new ActionBuilder();
2115 SetNwDstActionBuilder setNwDstActionBuilder = new SetNwDstActionBuilder();
2116 Ipv4Builder ipdst = new Ipv4Builder();
2117 ipdst.setIpv4Address(prefixdst);
2118 setNwDstActionBuilder.setAddress(ipdst.build());
2119 ab.setAction(new SetNwDstActionCaseBuilder().setSetNwDstAction(setNwDstActionBuilder.build()).build());
2120 actionList.add(ab.build());
2122 // Create an Apply Action
2123 ApplyActionsBuilder aab = new ApplyActionsBuilder();
2124 aab.setAction(actionList);
2126 // Wrap our Apply Action in an Instruction
2127 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
2133 * Create Drop Instruction
2135 * @param ib Map InstructionBuilder without any instructions
2136 * @return ib Map InstructionBuilder with instructions
2138 protected static InstructionBuilder createDropInstructions(InstructionBuilder ib) {
2140 DropActionBuilder dab = new DropActionBuilder();
2141 DropAction dropAction = dab.build();
2142 ActionBuilder ab = new ActionBuilder();
2143 ab.setAction(new DropActionCaseBuilder().setDropAction(dropAction).build());
2145 // Add our drop action to a list
2146 List<Action> actionList = new ArrayList<Action>();
2147 actionList.add(ab.build());
2149 // Create an Apply Action
2150 ApplyActionsBuilder aab = new ApplyActionsBuilder();
2151 aab.setAction(actionList);
2153 // Wrap our Apply Action in an Instruction
2154 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
2160 * Create GOTO Table Instruction Builder
2162 * @param ib Map InstructionBuilder without any instructions
2163 * @param tableId short representing a flow table ID short representing a flow table ID
2164 * @return ib Map InstructionBuilder with instructions
2166 protected static InstructionBuilder createGotoTableInstructions(InstructionBuilder ib, short tableId) {
2168 GoToTableBuilder gttb = new GoToTableBuilder();
2169 gttb.setTableId(tableId);
2171 // Wrap our Apply Action in an InstructionBuilder
2172 ib.setInstruction(new GoToTableCaseBuilder().setGoToTable(gttb.build()).build());
2178 * Create Set Tunnel ID Instruction Builder
2180 * @param ib Map InstructionBuilder without any instructions
2181 * @param tunnelId BigInteger representing a tunnel ID
2182 * @return ib Map InstructionBuilder with instructions
2184 protected static InstructionBuilder createSetTunnelIdInstructions(InstructionBuilder ib, BigInteger tunnelId) {
2186 List<Action> actionList = new ArrayList<Action>();
2187 ActionBuilder ab = new ActionBuilder();
2188 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
2190 // Build the Set Tunnel Field Action
2191 TunnelBuilder tunnel = new TunnelBuilder();
2192 tunnel.setTunnelId(tunnelId);
2193 setFieldBuilder.setTunnel(tunnel.build());
2194 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
2195 actionList.add(ab.build());
2197 ApplyActionsBuilder aab = new ApplyActionsBuilder();
2198 aab.setAction(actionList);
2200 // Wrap the Apply Action in an InstructionBuilder and return
2201 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
2207 * Create Set Source TCP Port Instruction
2209 * @param ib Map InstructionBuilder without any instructions
2210 * @param tcpport Integer representing a source TCP port
2211 * @return ib Map InstructionBuilder with instructions
2213 protected static InstructionBuilder createSetSrcTCPPort(InstructionBuilder ib, PortNumber tcpport) {
2215 List<Action> actionList = new ArrayList<Action>();
2216 ActionBuilder ab = new ActionBuilder();
2217 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
2219 // Build the Destination TCP Port
2220 PortNumber tcpsrcport = new PortNumber(tcpport);
2221 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
2222 tcpmatch.setTcpSourcePort(tcpsrcport);
2224 setFieldBuilder.setLayer4Match(tcpmatch.build());
2225 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
2226 ab.setKey(new ActionKey(1));
2227 actionList.add(ab.build());
2229 ApplyActionsBuilder aab = new ApplyActionsBuilder();
2230 aab.setAction(actionList);
2231 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
2237 * Create Set Destination TCP Port Instruction
2239 * @param ib Map InstructionBuilder without any instructions
2240 * @param tcpport Integer representing a source TCP port
2241 * @return ib Map InstructionBuilder with instructions
2243 protected static InstructionBuilder createSetDstTCPPort(InstructionBuilder ib, PortNumber tcpport) {
2245 List<Action> actionList = new ArrayList<Action>();
2246 ActionBuilder ab = new ActionBuilder();
2247 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
2249 // Build the Destination TCP Port
2250 PortNumber tcpdstport = new PortNumber(tcpport);
2251 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
2252 tcpmatch.setTcpDestinationPort(tcpdstport);
2254 setFieldBuilder.setLayer4Match(tcpmatch.build());
2255 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
2256 ab.setKey(new ActionKey(1));
2257 actionList.add(ab.build());
2259 ApplyActionsBuilder aab = new ApplyActionsBuilder();
2260 aab.setAction(actionList);
2261 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
2267 * Create Set Source UDP Port Instruction
2269 * @param ib Map InstructionBuilder without any instructions
2270 * @param udpport Integer representing a source UDP port
2271 * @return ib Map InstructionBuilder with instructions
2273 protected static InstructionBuilder createSetSrcUDPPort(InstructionBuilder ib, PortNumber udpport) {
2275 List<Action> actionList = new ArrayList<Action>();
2276 ActionBuilder ab = new ActionBuilder();
2277 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
2279 // Build the Destination TCP Port
2280 PortNumber udpsrcport = new PortNumber(udpport);
2281 UdpMatchBuilder udpmatch = new UdpMatchBuilder();
2282 udpmatch.setUdpSourcePort(udpsrcport);
2284 setFieldBuilder.setLayer4Match(udpmatch.build());
2285 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
2286 ab.setKey(new ActionKey(1));
2287 actionList.add(ab.build());
2289 ApplyActionsBuilder aab = new ApplyActionsBuilder();
2290 aab.setAction(actionList);
2291 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
2297 * Create Set Destination UDP Port Instruction
2299 * @param ib Map InstructionBuilder without any instructions
2300 * @param udpport Integer representing a destination UDP port
2301 * @return ib Map InstructionBuilder with instructions
2303 protected static InstructionBuilder createSetDstUDPPort(InstructionBuilder ib, PortNumber udpport) {
2305 List<Action> actionList = new ArrayList<Action>();
2306 ActionBuilder ab = new ActionBuilder();
2307 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
2309 // Build the Destination TCP Port
2310 PortNumber udpdstport = new PortNumber(udpport);
2311 UdpMatchBuilder udpmatch = new UdpMatchBuilder();
2312 udpmatch.setUdpDestinationPort(udpdstport);
2314 setFieldBuilder.setLayer4Match(udpmatch.build());
2315 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
2316 ab.setKey(new ActionKey(1));
2317 actionList.add(ab.build());
2319 ApplyActionsBuilder aab = new ApplyActionsBuilder();
2320 aab.setAction(actionList);
2321 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
2327 * Create Set ICMP Code Instruction
2329 * @param ib Map InstructionBuilder without any instructions
2330 * @param code short repesenting an ICMP code
2331 * @return ib Map InstructionBuilder with instructions
2334 private static InstructionBuilder createSetIcmpCodeInstruction(InstructionBuilder ib, short code) {
2336 List<Action> actionList = new ArrayList<Action>();
2337 ActionBuilder ab = new ActionBuilder();
2338 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
2339 Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
2341 // Build the ICMPv4 Code Match
2342 icmpv4match.setIcmpv4Code(code);
2343 setFieldBuilder.setIcmpv4Match(icmpv4match.build());
2345 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
2346 ab.setKey(new ActionKey(0));
2347 actionList.add(ab.build());
2348 ApplyActionsBuilder aab = new ApplyActionsBuilder();
2349 aab.setAction(actionList);
2351 // Wrap our Apply Action in an Instruction
2352 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
2358 * Create Set ICMP Code Instruction
2360 * @param ib Map InstructionBuilder without any instructions
2361 * @return ib Map InstructionBuilder with instructions
2363 private static InstructionBuilder createSetIcmpTypeInstruction(InstructionBuilder ib, short type) {
2365 List<Action> actionList = new ArrayList<Action>();
2366 ActionBuilder ab = new ActionBuilder();
2367 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
2368 Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
2370 // Build the ICMPv4 Code Match
2371 icmpv4match.setIcmpv4Code(type);
2372 setFieldBuilder.setIcmpv4Match(icmpv4match.build());
2374 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
2375 ab.setKey(new ActionKey(1));
2376 actionList.add(ab.build());
2377 ApplyActionsBuilder aab = new ApplyActionsBuilder();
2378 aab.setAction(actionList);
2380 // Wrap our Apply Action in an Instruction
2381 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
2387 * Create Decrement TTL Instruction
2389 * @param ib Map InstructionBuilder without any instructions
2390 * @return ib Map InstructionBuilder with instructions
2392 private static InstructionBuilder createDecNwTtlInstructions(InstructionBuilder ib) {
2393 DecNwTtlBuilder decNwTtlBuilder = new DecNwTtlBuilder();
2394 DecNwTtl decNwTtl = decNwTtlBuilder.build();
2395 ActionBuilder ab = new ActionBuilder();
2396 ab.setAction(new DecNwTtlCaseBuilder().setDecNwTtl(decNwTtl).build());
2398 // Add our drop action to a list
2399 List<Action> actionList = new ArrayList<Action>();
2400 actionList.add(ab.build());
2402 // Create an Apply Action
2403 ApplyActionsBuilder aab = new ApplyActionsBuilder();
2404 aab.setAction(actionList);
2406 // Wrap our Apply Action in an Instruction
2407 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
2415 private static InstructionBuilder createSrcArpMacInstructions(InstructionBuilder ib, MacAddress macsrc) {
2417 List<Action> actionList = new ArrayList<Action>();
2418 ActionBuilder ab = new ActionBuilder();
2420 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
2421 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
2422 ArpSourceHardwareAddressBuilder arpsrc = new ArpSourceHardwareAddressBuilder();
2423 arpsrc.setAddress(macsrc);
2424 arpmatch.setArpSourceHardwareAddress(arpsrc.build());
2425 setFieldBuilder.setLayer3Match(arpmatch.build());
2426 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
2427 ab.setKey(new ActionKey(0));
2428 actionList.add(ab.build());
2430 ApplyActionsBuilder aab = new ApplyActionsBuilder();
2431 aab.setAction(actionList);
2439 private static InstructionBuilder createDstArpMacInstructions(InstructionBuilder ib, MacAddress macdst) {
2441 List<Action> actionList = new ArrayList<Action>();
2442 ActionBuilder ab = new ActionBuilder();
2443 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
2445 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
2446 ArpTargetHardwareAddressBuilder arpdst = new ArpTargetHardwareAddressBuilder();
2447 arpdst.setAddress(macdst);
2448 setFieldBuilder.setLayer3Match(arpmatch.build());
2449 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
2450 ab.setKey(new ActionKey(0));
2451 actionList.add(ab.build());
2453 ApplyActionsBuilder aab = new ApplyActionsBuilder();
2454 aab.setAction(actionList);
2462 private static InstructionBuilder createDstArpIpInstructions(InstructionBuilder ib, Ipv4Prefix dstiparp) {
2464 List<Action> actionList = new ArrayList<Action>();
2465 ActionBuilder ab = new ActionBuilder();
2466 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
2468 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
2469 arpmatch.setArpTargetTransportAddress(dstiparp);
2470 setFieldBuilder.setLayer3Match(arpmatch.build());
2471 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
2472 ab.setKey(new ActionKey(0));
2473 actionList.add(ab.build());
2475 ApplyActionsBuilder aab = new ApplyActionsBuilder();
2476 aab.setAction(actionList);
2484 private static InstructionBuilder createSrcArpIpInstructions(InstructionBuilder ib, Ipv4Prefix srciparp) {
2486 List<Action> actionList = new ArrayList<Action>();
2487 ActionBuilder ab = new ActionBuilder();
2488 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
2490 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
2491 arpmatch.setArpSourceTransportAddress(srciparp);
2492 setFieldBuilder.setLayer3Match(arpmatch.build());
2493 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
2494 ab.setKey(new ActionKey(0));
2495 actionList.add(ab.build());
2497 ApplyActionsBuilder aab = new ApplyActionsBuilder();
2498 aab.setAction(actionList);
2504 public void initializeOFFlowRules(Node openflowNode) {
2505 IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
2506 List<Node> ovsNodes = connectionService.getNodes();
2507 if (ovsNodes == null) return;
2508 for (Node ovsNode : ovsNodes) {
2509 Long dpid = this.getIntegrationBridgeOFDPID(ovsNode);
2510 logger.debug("Compare openflowNode to OVS br-int node {} vs {}", openflowNode.getID(), dpid);
2511 String openflowID = ""+openflowNode.getID();
2512 if (openflowID.contains(""+dpid)) {
2513 this.initializeFlowRules(ovsNode, adminConfigManager.getIntegrationBridgeName());
2514 this.triggerInterfaceUpdates(ovsNode);
2519 private NodeBuilder createNodeBuilder(String nodeId) {
2520 NodeBuilder builder = new NodeBuilder();
2521 builder.setId(new NodeId(nodeId));
2522 builder.setKey(new NodeKey(builder.getId()));
2526 private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeBuilderToInstanceId(NodeBuilder
2528 return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
2529 node.getKey()).toInstance();
2532 private String getInternalBridgeUUID (Node node, String bridgeName) {
2534 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
2535 Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
2536 if (bridgeTable == null) return null;
2537 for (String key : bridgeTable.keySet()) {
2538 Bridge bridge = (Bridge)bridgeTable.get(key);
2539 if (bridge.getName().equals(bridgeName)) return key;
2541 } catch (Exception e) {
2542 logger.error("Error getting Bridge Identifier for {} / {}", node, bridgeName, e);