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
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.AdminConfigManager;
38 import org.opendaylight.ovsdb.neutron.IMDSALConsumer;
39 import org.opendaylight.ovsdb.neutron.InternalNetworkManager;
40 import org.opendaylight.ovsdb.neutron.TenantNetworkManager;
41 import org.opendaylight.ovsdb.plugin.IConnectionServiceInternal;
42 import org.opendaylight.ovsdb.plugin.OVSDBConfigService;
43 import org.opendaylight.ovsdb.plugin.StatusWithUuid;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DecNwTtlCaseBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCaseBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionCaseBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwSrcActionCaseBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCaseBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.StripVlanActionCaseBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtl;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtlBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropAction;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropActionBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.dst.action._case.SetNwDstActionBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.src.action._case.SetNwSrcActionBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.vlan.id.action._case.SetVlanIdActionBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.strip.vlan.action._case.StripVlanAction;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.strip.vlan.action._case.StripVlanActionBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCaseBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTableBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpSourceHardwareAddressBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpTargetHardwareAddressBuilder;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv4MatchBuilder;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
112 import org.opendaylight.yangtools.yang.binding.DataObject;
113 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
114 import org.opendaylight.yangtools.yang.common.RpcResult;
115 import org.slf4j.Logger;
116 import org.slf4j.LoggerFactory;
122 class OF13ProviderManager extends ProviderNetworkManager {
123 private static final Logger logger = LoggerFactory.getLogger(OF13ProviderManager.class);
124 private DataBrokerService dataBrokerService;
125 private static final short TABLE_0_DEFAULT_INGRESS = 0;
126 private static final short TABLE_1_ISOLATE_TENANT = 10;
127 private static final short TABLE_2_LOCAL_FORWARD = 20;
130 public boolean hasPerTenantTunneling() {
134 private Status getTunnelReadinessStatus (Node node, String tunnelKey) {
135 InetAddress srcTunnelEndPoint = AdminConfigManager.getManager().getTunnelEndPoint(node);
136 if (srcTunnelEndPoint == null) {
137 logger.error("Tunnel Endpoint not configured for Node {}", node);
138 return new Status(StatusCode.NOTFOUND, "Tunnel Endpoint not configured for "+ node);
141 if (!InternalNetworkManager.getManager().isInternalNetworkNeutronReady(node)) {
142 logger.error(node+" is not Overlay ready");
143 return new Status(StatusCode.NOTACCEPTABLE, node+" is not Overlay ready");
146 if (!TenantNetworkManager.getManager().isTenantNetworkPresentInNode(node, tunnelKey)) {
147 logger.debug(node+" has no VM corresponding to segment "+ tunnelKey);
148 return new Status(StatusCode.NOTACCEPTABLE, node+" has no VM corresponding to segment "+ tunnelKey);
150 return new Status(StatusCode.SUCCESS);
153 private String getTunnelName(String tunnelType, InetAddress dst) {
154 return tunnelType+"-"+dst.getHostAddress();
157 private boolean isTunnelPresent(Node node, String tunnelName, String bridgeUUID) throws Exception {
158 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
159 Bridge bridge = (Bridge)ovsdbTable.getRow(node, Bridge.NAME.getName(), bridgeUUID);
160 if (bridge != null) {
161 Set<UUID> ports = bridge.getPorts();
162 for (UUID portUUID : ports) {
163 Port port = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), portUUID.toString());
164 if (port != null && port.getName().equalsIgnoreCase(tunnelName)) return true;
170 private Status addTunnelPort (Node node, String tunnelType, InetAddress src, InetAddress dst) {
172 String bridgeUUID = null;
173 String tunnelBridgeName = AdminConfigManager.getManager().getIntegrationBridgeName();
174 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
175 Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
176 if (bridgeTable != null) {
177 for (String uuid : bridgeTable.keySet()) {
178 Bridge bridge = (Bridge)bridgeTable.get(uuid);
179 if (bridge.getName().equals(tunnelBridgeName)) {
185 if (bridgeUUID == null) {
186 logger.error("Could not find Bridge {} in {}", tunnelBridgeName, node);
187 return new Status(StatusCode.NOTFOUND, "Could not find "+tunnelBridgeName+" in "+node);
189 String portName = getTunnelName(tunnelType, dst);
191 if (this.isTunnelPresent(node, portName, bridgeUUID)) {
192 logger.trace("Tunnel {} is present in {} of {}", portName, tunnelBridgeName, node);
193 return new Status(StatusCode.SUCCESS);
196 Port tunnelPort = new Port();
197 tunnelPort.setName(portName);
198 StatusWithUuid statusWithUuid = ovsdbTable.insertRow(node, Port.NAME.getName(), bridgeUUID, tunnelPort);
199 if (!statusWithUuid.isSuccess()) {
200 logger.error("Failed to insert Tunnel port {} in {}", portName, bridgeUUID);
201 return statusWithUuid;
204 String tunnelPortUUID = statusWithUuid.getUuid().toString();
205 String interfaceUUID = null;
207 while ((interfaceUUID == null) && (timeout > 0)) {
208 tunnelPort = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), tunnelPortUUID);
209 OvsDBSet<UUID> interfaces = tunnelPort.getInterfaces();
210 if (interfaces == null || interfaces.size() == 0) {
211 // Wait for the OVSDB update to sync up the Local cache.
216 interfaceUUID = interfaces.toArray()[0].toString();
217 Interface intf = (Interface)ovsdbTable.getRow(node, Interface.NAME.getName(), interfaceUUID);
218 if (intf == null) interfaceUUID = null;
221 if (interfaceUUID == null) {
222 logger.error("Cannot identify Tunnel Interface for port {}/{}", portName, tunnelPortUUID);
223 return new Status(StatusCode.INTERNALERROR);
226 Interface tunInterface = new Interface();
227 tunInterface.setType(tunnelType);
228 OvsDBMap<String, String> options = new OvsDBMap<String, String>();
229 options.put("key", "flow");
230 options.put("local_ip", src.getHostAddress());
231 options.put("remote_ip", dst.getHostAddress());
232 tunInterface.setOptions(options);
233 Status status = ovsdbTable.updateRow(node, Interface.NAME.getName(), tunnelPortUUID, interfaceUUID, tunInterface);
234 logger.debug("Tunnel {} add status : {}", tunInterface, status);
236 } catch (Exception e) {
237 logger.error("Exception in addTunnelPort", e);
238 return new Status(StatusCode.INTERNALERROR);
242 private void programLocalBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long localPort) {
246 * Match: VM sMac and Local Ingress Port
247 * Action:Action: Set Tunnel ID and GOTO Local Table (5)
250 writeLocalInPort(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_1_ISOLATE_TENANT, segmentationId, localPort, attachedMac);
255 * Match: Drop any remaining Ingress Local VM Packets
256 * Action: Drop w/ a low priority
259 writeDropSrcIface(dpid, localPort);
264 * Match: Match TunID and Destination DL/dMAC Addr
265 * Action: Output Port
266 * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
269 writeLocalUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, attachedMac);
274 * Match: Tunnel ID and dMAC (::::FF:FF)
275 * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
276 * actions=output:2,3,4,5
279 writeLocalBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort);
282 * TODO : Optimize the following 2 writes to be restricted only for the very first port known in a segment.
287 * Match: Any remaining Ingress Local VM Packets
288 * Action: Drop w/ a low priority
289 * -------------------------------------------
290 * table=1,priority=8192,tun_id=0x5 actions=goto_table:2
293 writeTunnelMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId);
298 * Match: Any Remaining Flows w/a TunID
299 * Action: Drop w/ a low priority
300 * table=2,priority=8192,tun_id=0x5 actions=drop
303 writeLocalTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId);
306 private void programLocalIngressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
310 * Match: Ingress Port, Tunnel ID
311 * Action: GOTO Local Table (10)
314 writeTunnelIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort);
317 private void programRemoteEgressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
321 * Match: Drop any remaining Ingress Local VM Packets
322 * Action: Drop w/ a low priority
323 * -------------------------------------------
324 * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
325 * actions=output:11,goto_table:2
328 writeTunnelOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, attachedMac);
333 * Match: Match Tunnel ID and L2 ::::FF:FF Flooding
334 * Action: Flood to selected destination TEPs
335 * -------------------------------------------
336 * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
337 * actions=output:10,output:11,goto_table:2
340 writeTunnelFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort);
343 private Long getIntegrationBridgeOFDPID (Node node) {
345 String bridgeName = AdminConfigManager.getManager().getIntegrationBridgeName();
346 String brIntId = this.getInternalBridgeUUID(node, bridgeName);
347 if (brIntId == null) {
348 logger.error("Unable to spot Bridge Identifier for {} in {}", bridgeName, node);
352 OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
353 Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brIntId);
354 Set<String> dpids = bridge.getDatapath_id();
355 if (dpids == null || dpids.size() == 0) return 0L;
356 return Long.valueOf(HexEncode.stringToLong((String) dpids.toArray()[0]));
357 } catch (Exception e) {
358 logger.error("Error finding Integration Bridge's OF DPID", e);
362 private void programLocalRules (String tunnelType, String segmentationId, Node node, Interface intf) {
364 Long dpid = this.getIntegrationBridgeOFDPID(node);
366 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
370 Set<BigInteger> of_ports = intf.getOfport();
371 if (of_ports == null || of_ports.size() <= 0) {
372 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
375 long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
377 Map<String, String> externalIds = intf.getExternal_ids();
378 if (externalIds == null) {
379 logger.error("No external_ids seen in {}", intf);
383 String attachedMac = externalIds.get(TenantNetworkManager.EXTERNAL_ID_VM_MAC);
384 if (attachedMac == null) {
385 logger.error("No AttachedMac seen in {}", intf);
389 programLocalBridgeRules(node, dpid, segmentationId, attachedMac, localPort);
390 } catch (Exception e) {
391 logger.error("Exception in programming Local Rules for "+intf+" on "+node, e);
395 private void programTunnelRules (String tunnelType, String segmentationId, InetAddress dst, Node node,
396 Interface intf, boolean local) {
399 Long dpid = this.getIntegrationBridgeOFDPID(node);
401 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
404 OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
406 Set<BigInteger> of_ports = intf.getOfport();
407 if (of_ports == null || of_ports.size() <= 0) {
408 logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
411 long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
413 Map<String, String> externalIds = intf.getExternal_ids();
414 if (externalIds == null) {
415 logger.error("No external_ids seen in {}", intf);
419 String attachedMac = externalIds.get(TenantNetworkManager.EXTERNAL_ID_VM_MAC);
420 if (attachedMac == null) {
421 logger.error("No AttachedMac seen in {}", intf);
425 Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
427 for (org.opendaylight.ovsdb.lib.table.internal.Table<?> row : intfs.values()) {
428 Interface tunIntf = (Interface)row;
429 if (tunIntf.getName().equals(this.getTunnelName(tunnelType, dst))) {
430 of_ports = tunIntf.getOfport();
431 if (of_ports == null || of_ports.size() <= 0) {
432 logger.error("Could NOT Identify Tunnel port {} on {}", tunIntf.getName(), node);
435 long tunnelOFPort = ((BigInteger)of_ports.toArray()[0]).longValue();
437 if (tunnelOFPort == -1) {
438 logger.error("Could NOT Identify Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
441 logger.debug("Identified Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node);
444 programRemoteEgressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
446 programLocalIngressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
451 } catch (Exception e) {
457 public Status handleInterfaceUpdate(String tunnelType, String tunnelKey, Node srcNode, Interface intf) {
458 ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, "default", this);
459 if (switchManager == null) {
460 logger.error("Unable to identify SwitchManager");
462 Long dpid = this.getIntegrationBridgeOFDPID(srcNode);
464 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", srcNode);
465 return new Status(StatusCode.NOTFOUND);
467 Set<Node> ofNodes = switchManager.getNodes();
468 boolean ofNodeFound = false;
469 if (ofNodes != null) {
470 for (Node ofNode : ofNodes) {
471 if (ofNode.toString().contains(dpid+"")) {
472 logger.info("Identified the Openflow node via toString {}", ofNode);
478 logger.error("Unable to find any Node from SwitchManager");
481 logger.error("Unable to find OF Node for {} with update {} on node {}", dpid, intf, srcNode);
482 return new Status(StatusCode.NOTFOUND);
486 IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
487 List<Node> nodes = connectionService.getNodes();
488 nodes.remove(srcNode);
489 this.programLocalRules(tunnelType, tunnelKey, srcNode, intf);
491 for (Node dstNode : nodes) {
492 Status status = getTunnelReadinessStatus(dstNode, tunnelKey);
493 if (!status.isSuccess()) continue;
494 InetAddress src = AdminConfigManager.getManager().getTunnelEndPoint(srcNode);
495 InetAddress dst = AdminConfigManager.getManager().getTunnelEndPoint(dstNode);
496 status = addTunnelPort(srcNode, tunnelType, src, dst);
497 if (status.isSuccess()) {
498 this.programTunnelRules(tunnelType, tunnelKey, dst, srcNode, intf, true);
500 addTunnelPort(dstNode, tunnelType, dst, src);
501 if (status.isSuccess()) {
502 this.programTunnelRules(tunnelType, tunnelKey, src, dstNode, intf, false);
506 return new Status(StatusCode.SUCCESS);
509 private Status triggerInterfaceUpdates(Node node) {
511 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
512 Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
514 for (org.opendaylight.ovsdb.lib.table.internal.Table<?> row : intfs.values()) {
515 Interface intf = (Interface)row;
516 NeutronNetwork network = TenantNetworkManager.getManager().getTenantNetworkForInterface(intf);
517 logger.debug("Trigger Interface update for {}", intf);
518 if (network != null) {
519 this.handleInterfaceUpdate(network.getProviderNetworkType(), network.getProviderSegmentationID(), node, intf);
523 } catch (Exception e) {
524 logger.error("Error Triggering the lost interface updates for "+ node, e);
525 return new Status(StatusCode.INTERNALERROR, e.getLocalizedMessage());
527 return new Status(StatusCode.SUCCESS);
530 public Status handleInterfaceUpdate(String tunnelType, String tunnelKey) {
531 // TODO Auto-generated method stub
536 public Status deleteTunnels(String tunnelType, String tunnelKey, Node source, Interface intf) {
537 // TODO Auto-generated method stub
542 public void initializeFlowRules(Node node) {
543 this.initializeFlowRules(node, AdminConfigManager.getManager().getIntegrationBridgeName());
544 this.triggerInterfaceUpdates(node);
551 private void initializeFlowRules(Node node, String bridgeName) {
552 Long dpid = this.getIntegrationBridgeOFDPID(node);
554 logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
561 * Match: LLDP (0x88CCL)
562 * Action: Packet_In to Controller Reserved Port
569 * Create an LLDP Flow Rule to encapsulate into
570 * a packet_in that is sent to the controller
571 * for topology handling.
572 * Match: Ethertype 0x88CCL
573 * Action: Punt to Controller in a Packet_In msg
576 private void writeLLDPRule(Long dpidLong) {
578 String nodeName = "openflow:" + dpidLong;
579 EtherType etherType = new EtherType(0x88CCL);
581 MatchBuilder matchBuilder = new MatchBuilder();
582 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
583 FlowBuilder flowBuilder = new FlowBuilder();
585 // Create Match(es) and Set them in the FlowBuilder Object
586 flowBuilder.setMatch(createEtherTypeMatch(matchBuilder, etherType).build());
588 // Create the OF Actions and Instructions
589 InstructionBuilder ib = new InstructionBuilder();
590 InstructionsBuilder isb = new InstructionsBuilder();
592 // Instructions List Stores Individual Instructions
593 List<Instruction> instructions = new ArrayList<Instruction>();
595 // Call the InstructionBuilder Methods Containing Actions
596 createSendToControllerInstructions(ib);
597 instructions.add(ib.build());
599 // Add InstructionBuilder to the Instruction(s)Builder List
600 isb.setInstruction(instructions);
602 // Add InstructionsBuilder to FlowBuilder
603 flowBuilder.setInstructions(isb.build());
605 String flowId = "LLDP";
606 flowBuilder.setId(new FlowId(flowId));
607 FlowKey key = new FlowKey(new FlowId(flowId));
608 flowBuilder.setBarrier(true);
609 flowBuilder.setTableId((short) 0);
610 flowBuilder.setKey(key);
611 flowBuilder.setFlowName(flowId);
612 flowBuilder.setHardTimeout(0);
613 flowBuilder.setIdleTimeout(0);
614 writeFlow(flowBuilder, nodeBuilder);
618 * (Table:0) Ingress Tunnel Traffic
619 * Match: OpenFlow InPort and Tunnel ID
620 * Action: GOTO Local Table (10)
621 * table=0,tun_id=0x5,in_port=10, actions=goto_table:2
624 private void writeTunnelIn(Long dpidLong, Short writeTable, Short goToTableId, String segmentationId, Long ofPort) {
626 String nodeName = "openflow:" + dpidLong;
628 BigInteger tunnelId = new BigInteger(segmentationId);
629 MatchBuilder matchBuilder = new MatchBuilder();
630 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
631 FlowBuilder flowBuilder = new FlowBuilder();
633 // Create Match(es) and Set them in the FlowBuilder Object
634 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, tunnelId).build());
635 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, ofPort).build());
637 // Create the OF Actions and Instructions
638 InstructionBuilder ib = new InstructionBuilder();
639 InstructionsBuilder isb = new InstructionsBuilder();
641 // Instructions List Stores Individual Instructions
642 List<Instruction> instructions = new ArrayList<Instruction>();
644 // Call the InstructionBuilder Methods Containing Actions
645 createGotoTableInstructions(ib, goToTableId);
646 instructions.add(ib.build());
648 // Add InstructionBuilder to the Instruction(s)Builder List
649 isb.setInstruction(instructions);
651 // Add InstructionsBuilder to FlowBuilder
652 flowBuilder.setInstructions(isb.build());
654 String flowId = "TunnelIn_"+segmentationId+"_"+ofPort;
655 // Add Flow Attributes
656 flowBuilder.setId(new FlowId(flowId));
657 FlowKey key = new FlowKey(new FlowId(flowId));
658 flowBuilder.setBarrier(false);
659 flowBuilder.setTableId(writeTable);
660 flowBuilder.setKey(key);
661 flowBuilder.setFlowName(flowId);
662 flowBuilder.setHardTimeout(0);
663 flowBuilder.setIdleTimeout(0);
664 writeFlow(flowBuilder, nodeBuilder);
668 * (Table:0) Egress VM Traffic Towards TEP
669 * Match: Destination Ethernet Addr and OpenFlow InPort
670 * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
671 * table=0,in_port=2,dl_src=00:00:00:00:00:01 \
672 * actions=set_field:5->tun_id,goto_table=1"
675 private void writeLocalInPort(Long dpidLong, Short writeTable, Short goToTableId, String segmentationId, Long inPort, String attachedMac) {
677 String nodeName = "openflow:" + dpidLong;
679 MatchBuilder matchBuilder = new MatchBuilder();
680 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
681 FlowBuilder flowBuilder = new FlowBuilder();
683 // Create the OF Match using MatchBuilder
684 flowBuilder.setMatch(createEthSrcMatch(matchBuilder, new MacAddress(attachedMac)).build());
685 // TODO Broken In_Port Match
686 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
688 // Instantiate the Builders for the OF Actions and Instructions
689 InstructionBuilder ib = new InstructionBuilder();
690 InstructionsBuilder isb = new InstructionsBuilder();
692 // Instructions List Stores Individual Instructions
693 List<Instruction> instructions = new ArrayList<Instruction>();
695 // GOTO Instuctions Need to be added first to the List
696 createGotoTableInstructions(ib, goToTableId);
697 instructions.add(ib.build());
698 // TODO Broken SetTunID
699 createSetTunnelIdInstructions(ib, new BigInteger(segmentationId));
700 instructions.add(ib.build());
702 // Add InstructionBuilder to the Instruction(s)Builder List
703 isb.setInstruction(instructions);
705 // Add InstructionsBuilder to FlowBuilder
706 flowBuilder.setInstructions(isb.build());
708 String flowId = "LocalMac_"+segmentationId+"_"+inPort+"_"+attachedMac;
709 // Add Flow Attributes
710 flowBuilder.setId(new FlowId(flowId));
711 FlowKey key = new FlowKey(new FlowId(flowId));
712 flowBuilder.setBarrier(false);
713 flowBuilder.setTableId(writeTable);
714 flowBuilder.setKey(key);
715 flowBuilder.setFlowName(flowId);
716 flowBuilder.setHardTimeout(0);
717 flowBuilder.setIdleTimeout(0);
718 writeFlow(flowBuilder, nodeBuilder);
722 * (Table:0) Drop frames sourced from a VM that do not
723 * match the associated MAC address of the local VM.
724 * Match: Low priority anything not matching the VM SMAC
726 * table=0,priority=16384,in_port=1 actions=drop"
729 private void writeDropSrcIface(Long dpidLong, Long inPort) {
731 String nodeName = "openflow:" + dpidLong;
733 MatchBuilder matchBuilder = new MatchBuilder();
734 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
735 FlowBuilder flowBuilder = new FlowBuilder();
737 // Create the OF Match using MatchBuilder
738 flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
740 // Instantiate the Builders for the OF Actions and Instructions
741 InstructionBuilder ib = new InstructionBuilder();
742 InstructionsBuilder isb = new InstructionsBuilder();
744 // Instructions List Stores Individual Instructions
745 List<Instruction> instructions = new ArrayList<Instruction>();
747 // Call the InstructionBuilder Methods Containing Actions
748 createDropInstructions(ib);
749 instructions.add(ib.build());
751 // Add InstructionBuilder to the Instruction(s)Builder List
752 isb.setInstruction(instructions);
754 // Add InstructionsBuilder to FlowBuilder
755 flowBuilder.setInstructions(isb.build());
757 String flowId = "DropFilter_"+inPort;
758 // Add Flow Attributes
759 flowBuilder.setId(new FlowId(flowId));
760 FlowKey key = new FlowKey(new FlowId(flowId));
761 flowBuilder.setBarrier(false);
762 flowBuilder.setStrict(true);
763 flowBuilder.setTableId((short) 0);
764 flowBuilder.setKey(key);
765 flowBuilder.setFlowName(flowId);
766 flowBuilder.setPriority(8192);
767 flowBuilder.setHardTimeout(0);
768 flowBuilder.setIdleTimeout(0);
769 writeFlow(flowBuilder, nodeBuilder);
773 * (Table:1) Egress Tunnel Traffic
774 * Match: Destination Ethernet Addr and Local InPort
775 * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
776 * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
777 * actions=output:10,goto_table:2"
780 private void writeTunnelOut(Long dpidLong, Short writeTable, Short goToTableId, String segmentationId , Long OFPortOut, String attachedMac) {
782 String nodeName = "openflow:" + dpidLong;
784 MatchBuilder matchBuilder = new MatchBuilder();
785 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
786 FlowBuilder flowBuilder = new FlowBuilder();
788 // Create the OF Match using MatchBuilder
789 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
790 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
792 // Instantiate the Builders for the OF Actions and Instructions
793 InstructionBuilder ib = new InstructionBuilder();
794 InstructionsBuilder isb = new InstructionsBuilder();
796 // Instructions List Stores Individual Instructions
797 List<Instruction> instructions = new ArrayList<Instruction>();
800 createGotoTableInstructions(ib, goToTableId);
801 instructions.add(ib.build());
802 // Set the Output Port/Iface
803 createOutputPortInstructions(ib, dpidLong, OFPortOut);
804 instructions.add(ib.build());
806 // Add InstructionBuilder to the Instruction(s)Builder List
807 isb.setInstruction(instructions);
809 // Add InstructionsBuilder to FlowBuilder
810 flowBuilder.setInstructions(isb.build());
812 String flowId = "TunnelOut_"+segmentationId+"_"+OFPortOut+"_"+attachedMac;
813 // Add Flow Attributes
814 flowBuilder.setId(new FlowId(flowId));
815 FlowKey key = new FlowKey(new FlowId(flowId));
816 flowBuilder.setBarrier(false);
817 flowBuilder.setTableId(writeTable);
818 flowBuilder.setKey(key);
819 flowBuilder.setFlowName(flowId);
820 flowBuilder.setHardTimeout(0);
821 flowBuilder.setIdleTimeout(0);
822 writeFlow(flowBuilder, nodeBuilder);
826 * (Table:1) Egress Tunnel Traffic
827 * Match: Destination Ethernet Addr and Local InPort
828 * Instruction: Set TunnelID and GOTO Table Tunnel Table (n)
829 * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
830 * actions=output:10,output:11,goto_table:2
833 private void writeTunnelFloodOut(Long dpidLong, Short writeTable, Short localTable, String segmentationId, Long OFPortOut) {
835 String nodeName = "openflow:" + dpidLong;
837 MatchBuilder matchBuilder = new MatchBuilder();
838 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
839 FlowBuilder flowBuilder = new FlowBuilder();
841 // Create the OF Match using MatchBuilder
843 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
846 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
848 String flowId = "TunnelFloodOut_"+segmentationId;
849 // Add Flow Attributes
850 flowBuilder.setId(new FlowId(flowId));
851 FlowKey key = new FlowKey(new FlowId(flowId));
852 flowBuilder.setBarrier(true);
853 flowBuilder.setTableId(writeTable);
854 flowBuilder.setKey(key);
855 flowBuilder.setPriority(16384);
856 flowBuilder.setFlowName(flowId);
857 flowBuilder.setHardTimeout(0);
858 flowBuilder.setIdleTimeout(0);
860 Flow flow = this.getFlow(flowBuilder, nodeBuilder);
861 // Instantiate the Builders for the OF Actions and Instructions
862 InstructionBuilder ib = new InstructionBuilder();
863 InstructionsBuilder isb = new InstructionsBuilder();
864 List<Instruction> instructions = new ArrayList<Instruction>();
865 List<Instruction> existingInstructions = null;
867 Instructions ins = flow.getInstructions();
869 existingInstructions = ins.getInstruction();
873 createGotoTableInstructions(ib, localTable);
875 ib.setKey(new InstructionKey(0));
876 instructions.add(ib.build());
877 // Set the Output Port/Iface
878 createOutputPortInstructions(ib, dpidLong, OFPortOut, existingInstructions);
880 ib.setKey(new InstructionKey(1));
881 instructions.add(ib.build());
883 // Add InstructionBuilder to the Instruction(s)Builder List
884 isb.setInstruction(instructions);
886 // Add InstructionsBuilder to FlowBuilder
887 flowBuilder.setInstructions(isb.build());
889 writeFlow(flowBuilder, nodeBuilder);
893 * (Table:1) Table Drain w/ Catch All
895 * Action: GOTO Local Table (10)
896 * table=2,priority=8192,tun_id=0x5 actions=drop
899 private void writeTunnelMiss(Long dpidLong, Short writeTable, Short goToTableId, String segmentationId) {
901 String nodeName = "openflow:" + dpidLong;
903 MatchBuilder matchBuilder = new MatchBuilder();
904 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
905 FlowBuilder flowBuilder = new FlowBuilder();
907 // Create Match(es) and Set them in the FlowBuilder Object
908 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
910 // Create the OF Actions and Instructions
911 InstructionBuilder ib = new InstructionBuilder();
912 InstructionsBuilder isb = new InstructionsBuilder();
914 // Instructions List Stores Individual Instructions
915 List<Instruction> instructions = new ArrayList<Instruction>();
917 // Call the InstructionBuilder Methods Containing Actions
918 createGotoTableInstructions(ib, goToTableId);
919 instructions.add(ib.build());
921 // Add InstructionBuilder to the Instruction(s)Builder List
922 isb.setInstruction(instructions);
924 // Add InstructionsBuilder to FlowBuilder
925 flowBuilder.setInstructions(isb.build());
927 String flowId = "TunnelMiss_"+segmentationId;
928 // Add Flow Attributes
929 flowBuilder.setId(new FlowId(flowId));
930 FlowKey key = new FlowKey(new FlowId(flowId));
931 flowBuilder.setBarrier(false);
932 flowBuilder.setTableId(writeTable);
933 flowBuilder.setKey(key);
934 flowBuilder.setPriority(8192);
935 flowBuilder.setFlowName(flowId);
936 flowBuilder.setHardTimeout(0);
937 flowBuilder.setIdleTimeout(0);
938 writeFlow(flowBuilder, nodeBuilder);
942 * (Table:1) Local Broadcast Flood
943 * Match: Tunnel ID and dMAC
944 * Action: Output Port
945 * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
948 private void writeLocalUcastOut(Long dpidLong, Short writeTable, String segmentationId, Long localPort, String attachedMac) {
950 String nodeName = "openflow:" + dpidLong;
952 MatchBuilder matchBuilder = new MatchBuilder();
953 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
954 FlowBuilder flowBuilder = new FlowBuilder();
956 // Create the OF Match using MatchBuilder
957 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
958 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
960 // Instantiate the Builders for the OF Actions and Instructions
961 InstructionBuilder ib = new InstructionBuilder();
962 InstructionsBuilder isb = new InstructionsBuilder();
964 // Instructions List Stores Individual Instructions
965 List<Instruction> instructions = new ArrayList<Instruction>();
967 // Set the Output Port/Iface
968 createOutputPortInstructions(ib, dpidLong, localPort);
969 instructions.add(ib.build());
971 // Add InstructionBuilder to the Instruction(s)Builder List
972 isb.setInstruction(instructions);
974 // Add InstructionsBuilder to FlowBuilder
975 flowBuilder.setInstructions(isb.build());
977 String flowId = "UcastOut_"+segmentationId+"_"+localPort+"_"+attachedMac;
978 // Add Flow Attributes
979 flowBuilder.setId(new FlowId(flowId));
980 FlowKey key = new FlowKey(new FlowId(flowId));
981 flowBuilder.setBarrier(false);
982 flowBuilder.setTableId(writeTable);
983 flowBuilder.setKey(key);
984 flowBuilder.setFlowName(flowId);
985 flowBuilder.setHardTimeout(0);
986 flowBuilder.setIdleTimeout(0);
987 writeFlow(flowBuilder, nodeBuilder);
991 * (Table:1) Local Broadcast Flood
992 * Match: Tunnel ID and dMAC (::::FF:FF)
993 * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
994 * actions=output:2,3,4,5
997 private void writeLocalBcastOut(Long dpidLong, Short writeTable, String segmentationId, Long localPort) {
999 String nodeName = "openflow:" + dpidLong;
1001 MatchBuilder matchBuilder = new MatchBuilder();
1002 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1003 FlowBuilder flowBuilder = new FlowBuilder();
1005 // Create the OF Match using MatchBuilder
1006 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
1007 flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
1009 String flowId = "BcastOut_"+segmentationId;
1010 // Add Flow Attributes
1011 flowBuilder.setId(new FlowId(flowId));
1012 FlowKey key = new FlowKey(new FlowId(flowId));
1013 flowBuilder.setBarrier(false);
1014 flowBuilder.setTableId(writeTable);
1015 flowBuilder.setKey(key);
1016 flowBuilder.setPriority(16384);
1017 flowBuilder.setFlowName(flowId);
1018 flowBuilder.setHardTimeout(0);
1019 flowBuilder.setIdleTimeout(0);
1020 Flow flow = this.getFlow(flowBuilder, nodeBuilder);
1021 // Instantiate the Builders for the OF Actions and Instructions
1022 InstructionBuilder ib = new InstructionBuilder();
1023 InstructionsBuilder isb = new InstructionsBuilder();
1024 List<Instruction> instructions = new ArrayList<Instruction>();
1025 List<Instruction> existingInstructions = null;
1027 Instructions ins = flow.getInstructions();
1029 existingInstructions = ins.getInstruction();
1033 // Broken OutPort TODO: localPort needs to be a list of Ports)
1034 createOutputPortInstructions(ib, dpidLong, localPort, existingInstructions);
1036 ib.setKey(new InstructionKey(0));
1037 instructions.add(ib.build());
1039 // Add InstructionBuilder to the Instruction(s)Builder List
1040 isb.setInstruction(instructions);
1042 // Add InstructionsBuilder to FlowBuilder
1043 flowBuilder.setInstructions(isb.build());
1045 writeFlow(flowBuilder, nodeBuilder);
1049 * (Table:1) Local Table Miss
1050 * Match: Any Remaining Flows w/a TunID
1051 * Action: Drop w/ a low priority
1052 * table=2,priority=8192,tun_id=0x5 actions=drop
1055 private void writeLocalTableMiss(Long dpidLong, Short writeTable, String segmentationId) {
1057 String nodeName = "openflow:" + dpidLong;
1059 MatchBuilder matchBuilder = new MatchBuilder();
1060 NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
1061 FlowBuilder flowBuilder = new FlowBuilder();
1063 // Create Match(es) and Set them in the FlowBuilder Object
1064 flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
1066 // Create the OF Actions and Instructions
1067 InstructionBuilder ib = new InstructionBuilder();
1068 InstructionsBuilder isb = new InstructionsBuilder();
1070 // Instructions List Stores Individual Instructions
1071 List<Instruction> instructions = new ArrayList<Instruction>();
1073 // Call the InstructionBuilder Methods Containing Actions
1074 createDropInstructions(ib);
1075 instructions.add(ib.build());
1077 // Add InstructionBuilder to the Instruction(s)Builder List
1078 isb.setInstruction(instructions);
1080 // Add InstructionsBuilder to FlowBuilder
1081 flowBuilder.setInstructions(isb.build());
1083 String flowId = "LocalTableMiss_"+segmentationId;
1084 // Add Flow Attributes
1085 flowBuilder.setId(new FlowId(flowId));
1086 FlowKey key = new FlowKey(new FlowId(flowId));
1087 flowBuilder.setBarrier(false);
1088 flowBuilder.setStrict(true);
1089 flowBuilder.setTableId(writeTable);
1090 flowBuilder.setKey(key);
1091 flowBuilder.setPriority(8192);
1092 flowBuilder.setFlowName(flowId);
1093 flowBuilder.setHardTimeout(0);
1094 flowBuilder.setIdleTimeout(0);
1095 writeFlow(flowBuilder, nodeBuilder);
1098 private Flow getFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
1099 IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
1100 if (mdsalConsumer == null) {
1101 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
1105 dataBrokerService = mdsalConsumer.getDataBrokerService();
1107 if (dataBrokerService == null) {
1108 logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
1112 InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
1113 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class,
1114 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
1115 return (Flow)dataBrokerService.readConfigurationData(path1);
1118 private void writeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
1119 IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
1120 if (mdsalConsumer == null) {
1121 logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
1125 dataBrokerService = mdsalConsumer.getDataBrokerService();
1127 if (dataBrokerService == null) {
1128 logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
1131 DataModification<InstanceIdentifier<?>, DataObject> modification = dataBrokerService.beginTransaction();
1132 InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
1133 .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class,
1134 new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
1135 modification.putOperationalData(nodeBuilderToInstanceId(nodeBuilder), nodeBuilder.build());
1136 modification.putOperationalData(path1, flowBuilder.build());
1137 modification.putConfigurationData(nodeBuilderToInstanceId(nodeBuilder), nodeBuilder.build());
1138 modification.putConfigurationData(path1, flowBuilder.build());
1139 Future<RpcResult<TransactionStatus>> commitFuture = modification.commit();
1141 RpcResult<TransactionStatus> result = commitFuture.get();
1142 TransactionStatus status = result.getResult();
1143 logger.debug("Transaction Status "+status.toString()+" for Flow "+flowBuilder.getFlowName());
1144 } catch (InterruptedException e) {
1145 logger.error(e.getMessage(), e);
1146 } catch (ExecutionException e) {
1147 logger.error(e.getMessage(), e);
1152 * Create Ingress Port Match dpidLong, inPort
1154 * @param matchBuilder Map matchBuilder MatchBuilder Object without a match
1155 * @param dpidLong Long the datapath ID of a switch/node
1156 * @param inPort Long ingress port on a switch
1157 * @return matchBuilder Map MatchBuilder Object with a match
1159 protected static MatchBuilder createInPortMatch(MatchBuilder matchBuilder, Long dpidLong, Long inPort) {
1161 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + inPort);
1162 logger.debug("createInPortMatch() Node Connector ID is - Type=openflow: DPID={} inPort={} ", dpidLong, inPort);
1163 matchBuilder.setInPort(NodeConnectorId.getDefaultInstance(ncid.getValue()));
1164 matchBuilder.setInPort(ncid);
1166 return matchBuilder;
1170 * Create EtherType Match
1172 * @param matchBuilder Map matchBuilder MatchBuilder Object without a match
1173 * @param etherType Long EtherType
1174 * @return matchBuilder Map MatchBuilder Object with a match
1176 protected static MatchBuilder createEtherTypeMatch(MatchBuilder matchBuilder, EtherType etherType) {
1178 EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
1179 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
1180 ethTypeBuilder.setType(new EtherType(etherType));
1181 ethernetMatch.setEthernetType(ethTypeBuilder.build());
1182 matchBuilder.setEthernetMatch(ethernetMatch.build());
1184 return matchBuilder;
1188 * Create Ethernet Source Match
1190 * @param matchBuilder MatchBuilder Object without a match yet
1191 * @param sMacAddr String representing a source MAC
1192 * @return matchBuilder Map MatchBuilder Object with a match
1194 protected static MatchBuilder createEthSrcMatch(MatchBuilder matchBuilder, MacAddress sMacAddr) {
1196 EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
1197 EthernetSourceBuilder ethSourceBuilder = new EthernetSourceBuilder();
1198 ethSourceBuilder.setAddress(new MacAddress(sMacAddr));
1199 ethernetMatch.setEthernetSource(ethSourceBuilder.build());
1200 matchBuilder.setEthernetMatch(ethernetMatch.build());
1202 return matchBuilder;
1206 * Create Ethernet Destination Match
1208 * @param matchBuilder MatchBuilder Object without a match yet
1209 * @param vlanId Integer representing a VLAN ID Integer representing a VLAN ID
1210 * @return matchBuilder Map MatchBuilder Object with a match
1213 protected static MatchBuilder createVlanIdMatch(MatchBuilder matchBuilder, VlanId vlanId) {
1215 VlanMatchBuilder vlanMatchBuilder = new VlanMatchBuilder();
1216 VlanIdBuilder vlanIdBuilder = new VlanIdBuilder();
1217 vlanIdBuilder.setVlanId(new VlanId(vlanId));
1218 vlanMatchBuilder.setVlanId(vlanIdBuilder.build());
1219 matchBuilder.setVlanMatch(vlanMatchBuilder.build());
1221 return matchBuilder;
1225 * Create Ethernet Destination Match
1227 * @param matchBuilder MatchBuilder Object without a match yet
1228 * @param dMacAddr String representing a destination MAC
1229 * @return matchBuilder Map MatchBuilder Object with a match
1232 protected static MatchBuilder createDestEthMatch(MatchBuilder matchBuilder, MacAddress dMacAddr, MacAddress mask) {
1234 EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
1235 EthernetDestinationBuilder ethDestinationBuilder = new EthernetDestinationBuilder();
1236 ethDestinationBuilder.setAddress(new MacAddress(dMacAddr));
1238 ethDestinationBuilder.setMask(mask);
1240 ethernetMatch.setEthernetDestination(ethDestinationBuilder.build());
1241 matchBuilder.setEthernetMatch(ethernetMatch.build());
1243 return matchBuilder;
1247 * Tunnel ID Match Builder
1249 * @param matchBuilder MatchBuilder Object without a match yet
1250 * @param tunnelId BigInteger representing a tunnel ID
1251 * @return matchBuilder Map MatchBuilder Object with a match
1253 protected static MatchBuilder createTunnelIDMatch(MatchBuilder matchBuilder, BigInteger tunnelId) {
1255 TunnelBuilder tunnelBuilder = new TunnelBuilder();
1256 tunnelBuilder.setTunnelId(tunnelId);
1257 matchBuilder.setTunnel(tunnelBuilder.build());
1259 return matchBuilder;
1263 * Match ICMP code and type
1265 * @param matchBuilder MatchBuilder Object without a match yet
1266 * @param type short representing an ICMP type
1267 * @param code short representing an ICMP code
1268 * @return matchBuilder Map MatchBuilder Object with a match
1270 protected static MatchBuilder createICMPv4Match(MatchBuilder matchBuilder, short type, short code) {
1272 EthernetMatchBuilder eth = new EthernetMatchBuilder();
1273 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
1274 ethTypeBuilder.setType(new EtherType(0x0800L));
1275 eth.setEthernetType(ethTypeBuilder.build());
1276 matchBuilder.setEthernetMatch(eth.build());
1278 // Build the IPv4 Match requied per OVS Syntax
1279 IpMatchBuilder ipmatch = new IpMatchBuilder();
1280 ipmatch.setIpProtocol((short) 1);
1281 matchBuilder.setIpMatch(ipmatch.build());
1283 // Build the ICMPv4 Match
1284 Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
1285 icmpv4match.setIcmpv4Type(type);
1286 icmpv4match.setIcmpv4Code(code);
1287 matchBuilder.setIcmpv4Match(icmpv4match.build());
1289 return matchBuilder;
1293 * @param matchBuilder MatchBuilder Object without a match yet
1294 * @param dstip String containing an IPv4 prefix
1295 * @return matchBuilder Map Object with a match
1297 private static MatchBuilder createDstL3IPv4Match(MatchBuilder matchBuilder, Ipv4Prefix dstip) {
1299 EthernetMatchBuilder eth = new EthernetMatchBuilder();
1300 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
1301 ethTypeBuilder.setType(new EtherType(0x0800L));
1302 eth.setEthernetType(ethTypeBuilder.build());
1303 matchBuilder.setEthernetMatch(eth.build());
1305 Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder();
1306 ipv4match.setIpv4Destination(dstip);
1308 matchBuilder.setLayer3Match(ipv4match.build());
1310 return matchBuilder;
1315 * @param matchBuilder MatchBuilder Object without a match yet
1316 * @param srcip String containing an IPv4 prefix
1317 * @return matchBuilder Map Object with a match
1319 private static MatchBuilder createSrcL3IPv4Match(MatchBuilder matchBuilder, Ipv4Prefix srcip) {
1321 EthernetMatchBuilder eth = new EthernetMatchBuilder();
1322 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
1323 ethTypeBuilder.setType(new EtherType(0x0800L));
1324 eth.setEthernetType(ethTypeBuilder.build());
1325 matchBuilder.setEthernetMatch(eth.build());
1327 Ipv4MatchBuilder ipv4Match = new Ipv4MatchBuilder();
1328 Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder();
1329 ipv4match.setIpv4Source(srcip);
1330 matchBuilder.setLayer3Match(ipv4match.build());
1332 return matchBuilder;
1337 * Create Source TCP Port Match
1339 * @param matchBuilder @param matchbuilder MatchBuilder Object without a match yet
1340 * @param tcpport Integer representing a source TCP port
1341 * @return matchBuilder Map MatchBuilder Object with a match
1343 protected static MatchBuilder createSetSrcTcpMatch(MatchBuilder matchBuilder, PortNumber tcpport) {
1345 EthernetMatchBuilder ethType = new EthernetMatchBuilder();
1346 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
1347 ethTypeBuilder.setType(new EtherType(0x0800L));
1348 ethType.setEthernetType(ethTypeBuilder.build());
1349 matchBuilder.setEthernetMatch(ethType.build());
1351 IpMatchBuilder ipmatch = new IpMatchBuilder();
1352 ipmatch.setIpProtocol((short) 6);
1353 matchBuilder.setIpMatch(ipmatch.build());
1355 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
1356 tcpmatch.setTcpSourcePort(tcpport);
1357 matchBuilder.setLayer4Match(tcpmatch.build());
1359 return matchBuilder;
1364 * Create Destination TCP Port Match
1366 * @param matchBuilder MatchBuilder Object without a match yet
1367 * @param tcpport Integer representing a destination TCP port
1368 * @return matchBuilder Map MatchBuilder Object with a match
1370 protected static MatchBuilder createSetDstTcpMatch(MatchBuilder matchBuilder, PortNumber tcpport) {
1372 EthernetMatchBuilder ethType = new EthernetMatchBuilder();
1373 EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
1374 ethTypeBuilder.setType(new EtherType(0x0800L));
1375 ethType.setEthernetType(ethTypeBuilder.build());
1376 matchBuilder.setEthernetMatch(ethType.build());
1378 IpMatchBuilder ipmatch = new IpMatchBuilder();
1379 ipmatch.setIpProtocol((short) 6);
1380 matchBuilder.setIpMatch(ipmatch.build());
1382 PortNumber dstport = new PortNumber(tcpport);
1383 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
1385 tcpmatch.setTcpDestinationPort(tcpport);
1386 matchBuilder.setLayer4Match(tcpmatch.build());
1388 return matchBuilder;
1392 * Create Send to Controller Reserved Port Instruction (packet_in)
1394 * @param ib Map InstructionBuilder without any instructions
1395 * @return ib Map InstructionBuilder with instructions
1398 protected static InstructionBuilder createSendToControllerInstructions(InstructionBuilder ib) {
1400 List<Action> actionList = new ArrayList<Action>();
1401 ActionBuilder ab = new ActionBuilder();
1403 OutputActionBuilder output = new OutputActionBuilder();
1404 output.setMaxLength(56);
1405 Uri value = new Uri("CONTROLLER");
1406 output.setOutputNodeConnector(value);
1407 ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
1409 ab.setKey(new ActionKey(0));
1410 actionList.add(ab.build());
1412 // Create an Apply Action
1413 ApplyActionsBuilder aab = new ApplyActionsBuilder();
1414 aab.setAction(actionList);
1416 // Wrap our Apply Action in an Instruction
1417 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1419 ib.setKey(new InstructionKey(0));
1425 * Create Output Port Instruction
1427 * @param ib Map InstructionBuilder without any instructions
1428 * @param dpidLong Long the datapath ID of a switch/node
1429 * @param port Long representing a port on a switch/node
1430 * @return ib InstructionBuilder Map with instructions
1432 protected static InstructionBuilder createOutputPortInstructions(InstructionBuilder ib, Long dpidLong, Long port) {
1434 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
1435 logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} inPort={} ", dpidLong, port);
1437 List<Action> actionList = new ArrayList<Action>();
1438 ActionBuilder ab = new ActionBuilder();
1439 OutputActionBuilder oab = new OutputActionBuilder();
1440 oab.setOutputNodeConnector(ncid);
1442 ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
1444 ab.setKey(new ActionKey(5));
1445 actionList.add(ab.build());
1447 // Create an Apply Action
1448 ApplyActionsBuilder aab = new ApplyActionsBuilder();
1449 aab.setAction(actionList);
1450 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1456 * Create Output Port Instruction
1458 * @param ib Map InstructionBuilder without any instructions
1459 * @param dpidLong Long the datapath ID of a switch/node
1460 * @param port Long representing a port on a switch/node
1461 * @return ib InstructionBuilder Map with instructions
1463 protected static InstructionBuilder createOutputPortInstructions(InstructionBuilder ib, Long dpidLong, Long port , List<Instruction> instructions) {
1465 NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
1466 logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
1468 List<Action> actionList = new ArrayList<Action>();
1469 ActionBuilder ab = new ActionBuilder();
1471 List<Action> existingActions = null;
1472 if (instructions != null) {
1473 for (Instruction in : instructions) {
1474 if (in.getInstruction() instanceof ApplyActionsCase) {
1475 existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
1476 actionList.addAll(existingActions);
1481 OutputActionBuilder oab = new OutputActionBuilder();
1482 oab.setOutputNodeConnector(ncid);
1483 ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
1485 ab.setKey(new ActionKey(0));
1486 Action newAction = ab.build();
1487 boolean addNew = true;
1488 for (Action action : actionList) {
1489 if (action.getAction() instanceof OutputActionCase) {
1490 OutputActionCase opAction = (OutputActionCase)action.getAction();
1491 if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
1497 if (addNew) actionList.add(newAction);
1499 // Create an Apply Action
1500 ApplyActionsBuilder aab = new ApplyActionsBuilder();
1501 aab.setAction(actionList);
1502 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1508 * Create Set Vlan ID Instruction
1510 * @param ib Map InstructionBuilder without any instructions
1511 * @param vlanId Integer representing a VLAN ID Integer representing a VLAN ID
1512 * @return ib Map InstructionBuilder with instructions
1514 protected static InstructionBuilder createSetVlanInstructions(InstructionBuilder ib, VlanId vlanId) {
1516 List<Action> actionList = new ArrayList<Action>();
1517 ActionBuilder ab = new ActionBuilder();
1519 SetVlanIdActionBuilder vl = new SetVlanIdActionBuilder();
1520 vl.setVlanId(vlanId);
1521 ab.setAction(new SetVlanIdActionCaseBuilder().setSetVlanIdAction(vl.build()).build());
1522 actionList.add(ab.build());
1523 // Create an Apply Action
1524 ApplyActionsBuilder aab = new ApplyActionsBuilder();
1525 aab.setAction(actionList);
1527 // Wrap our Apply Action in an Instruction
1528 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1534 * Create Set IPv4 Destination Instruction
1536 * @param ib Map InstructionBuilder without any instructions
1537 * @return ib Map InstructionBuilder with instructions
1539 protected static InstructionBuilder createStripVlanInstructions(InstructionBuilder ib) {
1541 StripVlanActionBuilder stripVlanActionBuilder = new StripVlanActionBuilder();
1542 StripVlanAction vlanAction = stripVlanActionBuilder.build();
1543 ActionBuilder ab = new ActionBuilder();
1544 ab.setAction(new StripVlanActionCaseBuilder().setStripVlanAction(vlanAction).build());
1546 // Add our drop action to a list
1547 List<Action> actionList = new ArrayList<Action>();
1548 actionList.add(ab.build());
1550 // Create an Apply Action
1551 ApplyActionsBuilder aab = new ApplyActionsBuilder();
1552 aab.setAction(actionList);
1554 // Wrap our Apply Action in an Instruction
1555 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1557 ib.setKey(new InstructionKey(0));
1563 * Create Set IPv4 Source Instruction
1565 * @param ib Map InstructionBuilder without any instructions
1566 * @param prefixsrc String containing an IPv4 prefix
1567 * @return ib Map InstructionBuilder with instructions
1569 protected static InstructionBuilder createNwSrcInstructions(InstructionBuilder ib, Ipv4Prefix prefixsrc) {
1571 List<Action> actionList = new ArrayList<Action>();
1572 ActionBuilder ab = new ActionBuilder();
1574 SetNwSrcActionBuilder setNwsrcActionBuilder = new SetNwSrcActionBuilder();
1575 Ipv4Builder ipsrc = new Ipv4Builder();
1576 ipsrc.setIpv4Address(prefixsrc);
1577 setNwsrcActionBuilder.setAddress(ipsrc.build());
1578 ab.setAction(new SetNwSrcActionCaseBuilder().setSetNwSrcAction(setNwsrcActionBuilder.build()).build());
1579 actionList.add(ab.build());
1581 // Create an Apply Action
1582 ApplyActionsBuilder aab = new ApplyActionsBuilder();
1583 aab.setAction(actionList);
1585 // Wrap our Apply Action in an Instruction
1586 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1592 * Create Set IPv4 Destination Instruction
1594 * @param ib Map InstructionBuilder without any instructions
1595 * @param prefixdst String containing an IPv4 prefix
1596 * @return ib Map InstructionBuilder with instructions
1598 protected static InstructionBuilder createNwDstInstructions(InstructionBuilder ib, Ipv4Prefix prefixdst) {
1600 List<Action> actionList = new ArrayList<Action>();
1601 ActionBuilder ab = new ActionBuilder();
1603 SetNwDstActionBuilder setNwDstActionBuilder = new SetNwDstActionBuilder();
1604 Ipv4Builder ipdst = new Ipv4Builder();
1605 ipdst.setIpv4Address(prefixdst);
1606 setNwDstActionBuilder.setAddress(ipdst.build());
1607 ab.setAction(new SetNwDstActionCaseBuilder().setSetNwDstAction(setNwDstActionBuilder.build()).build());
1608 actionList.add(ab.build());
1610 // Create an Apply Action
1611 ApplyActionsBuilder aab = new ApplyActionsBuilder();
1612 aab.setAction(actionList);
1614 // Wrap our Apply Action in an Instruction
1615 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1621 * Create Drop Instruction
1623 * @param ib Map InstructionBuilder without any instructions
1624 * @return ib Map InstructionBuilder with instructions
1626 protected static InstructionBuilder createDropInstructions(InstructionBuilder ib) {
1628 DropActionBuilder dab = new DropActionBuilder();
1629 DropAction dropAction = dab.build();
1630 ActionBuilder ab = new ActionBuilder();
1631 ab.setAction(new DropActionCaseBuilder().setDropAction(dropAction).build());
1633 // Add our drop action to a list
1634 List<Action> actionList = new ArrayList<Action>();
1635 actionList.add(ab.build());
1637 // Create an Apply Action
1638 ApplyActionsBuilder aab = new ApplyActionsBuilder();
1639 aab.setAction(actionList);
1641 // Wrap our Apply Action in an Instruction
1642 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1644 ib.setKey(new InstructionKey(0));
1650 * Create GOTO Table Instruction Builder
1652 * @param ib Map InstructionBuilder without any instructions
1653 * @param tableId short representing a flow table ID short representing a flow table ID
1654 * @return ib Map InstructionBuilder with instructions
1656 protected static InstructionBuilder createGotoTableInstructions(InstructionBuilder ib, short tableId) {
1658 GoToTableBuilder gttb = new GoToTableBuilder();
1659 gttb.setTableId(tableId);
1661 // Wrap our Apply Action in an InstructionBuilder
1662 ib.setInstruction(new GoToTableCaseBuilder().setGoToTable(gttb.build()).build());
1664 ib.setKey(new InstructionKey(0));
1670 * Create Set Tunnel ID Instruction Builder
1672 * @param ib Map InstructionBuilder without any instructions
1673 * @param tunnelId BigInteger representing a tunnel ID
1674 * @return ib Map InstructionBuilder with instructions
1676 protected static InstructionBuilder createSetTunnelIdInstructions(InstructionBuilder ib, BigInteger tunnelId) {
1678 List<Action> actionList = new ArrayList<Action>();
1679 ActionBuilder ab = new ActionBuilder();
1680 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1682 // Build the Set Tunnel Field Action
1683 TunnelBuilder tunnel = new TunnelBuilder();
1684 tunnel.setTunnelId(tunnelId);
1685 setFieldBuilder.setTunnel(tunnel.build());
1686 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1687 actionList.add(ab.build());
1689 ApplyActionsBuilder aab = new ApplyActionsBuilder();
1690 aab.setAction(actionList);
1692 // Wrap the Apply Action in an InstructionBuilder and return
1694 ib.setKey(new InstructionKey(0));
1695 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1701 * Create Set Source TCP Port Instruction
1703 * @param ib Map InstructionBuilder without any instructions
1704 * @param tcpport Integer representing a source TCP port
1705 * @return ib Map InstructionBuilder with instructions
1707 protected static InstructionBuilder createSetSrcTCPPort(InstructionBuilder ib, PortNumber tcpport) {
1709 List<Action> actionList = new ArrayList<Action>();
1710 ActionBuilder ab = new ActionBuilder();
1711 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1713 // Build the Destination TCP Port
1714 PortNumber tcpsrcport = new PortNumber(tcpport);
1715 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
1716 tcpmatch.setTcpSourcePort(tcpsrcport);
1718 setFieldBuilder.setLayer4Match(tcpmatch.build());
1719 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1720 ab.setKey(new ActionKey(1));
1721 actionList.add(ab.build());
1723 ApplyActionsBuilder aab = new ApplyActionsBuilder();
1724 aab.setAction(actionList);
1725 ib.setKey(new InstructionKey(1));
1726 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1732 * Create Set Destination TCP Port Instruction
1734 * @param ib Map InstructionBuilder without any instructions
1735 * @param tcpport Integer representing a source TCP port
1736 * @return ib Map InstructionBuilder with instructions
1738 protected static InstructionBuilder createSetDstTCPPort(InstructionBuilder ib, PortNumber tcpport) {
1740 List<Action> actionList = new ArrayList<Action>();
1741 ActionBuilder ab = new ActionBuilder();
1742 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1744 // Build the Destination TCP Port
1745 PortNumber tcpdstport = new PortNumber(tcpport);
1746 TcpMatchBuilder tcpmatch = new TcpMatchBuilder();
1747 tcpmatch.setTcpDestinationPort(tcpdstport);
1749 setFieldBuilder.setLayer4Match(tcpmatch.build());
1750 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1751 ab.setKey(new ActionKey(1));
1752 actionList.add(ab.build());
1754 ApplyActionsBuilder aab = new ApplyActionsBuilder();
1755 aab.setAction(actionList);
1756 ib.setKey(new InstructionKey(1));
1757 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1763 * Create Set Source UDP Port Instruction
1765 * @param ib Map InstructionBuilder without any instructions
1766 * @param udpport Integer representing a source UDP port
1767 * @return ib Map InstructionBuilder with instructions
1769 protected static InstructionBuilder createSetSrcUDPPort(InstructionBuilder ib, PortNumber udpport) {
1771 List<Action> actionList = new ArrayList<Action>();
1772 ActionBuilder ab = new ActionBuilder();
1773 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1775 // Build the Destination TCP Port
1776 PortNumber udpsrcport = new PortNumber(udpport);
1777 UdpMatchBuilder udpmatch = new UdpMatchBuilder();
1778 udpmatch.setUdpSourcePort(udpsrcport);
1780 setFieldBuilder.setLayer4Match(udpmatch.build());
1781 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1782 ab.setKey(new ActionKey(1));
1783 actionList.add(ab.build());
1785 ApplyActionsBuilder aab = new ApplyActionsBuilder();
1786 aab.setAction(actionList);
1787 ib.setKey(new InstructionKey(1));
1788 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1794 * Create Set Destination UDP Port Instruction
1796 * @param ib Map InstructionBuilder without any instructions
1797 * @param udpport Integer representing a destination UDP port
1798 * @return ib Map InstructionBuilder with instructions
1800 protected static InstructionBuilder createSetDstUDPPort(InstructionBuilder ib, PortNumber udpport) {
1802 List<Action> actionList = new ArrayList<Action>();
1803 ActionBuilder ab = new ActionBuilder();
1804 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1806 // Build the Destination TCP Port
1807 PortNumber udpdstport = new PortNumber(udpport);
1808 UdpMatchBuilder udpmatch = new UdpMatchBuilder();
1809 udpmatch.setUdpDestinationPort(udpdstport);
1811 setFieldBuilder.setLayer4Match(udpmatch.build());
1812 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1813 ab.setKey(new ActionKey(1));
1814 actionList.add(ab.build());
1816 ApplyActionsBuilder aab = new ApplyActionsBuilder();
1817 aab.setAction(actionList);
1818 ib.setKey(new InstructionKey(1));
1819 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1825 * Create Set ICMP Code Instruction
1827 * @param ib Map InstructionBuilder without any instructions
1828 * @param code short repesenting an ICMP code
1829 * @return ib Map InstructionBuilder with instructions
1832 private static InstructionBuilder createSetIcmpCodeInstruction(InstructionBuilder ib, short code) {
1834 List<Action> actionList = new ArrayList<Action>();
1835 ActionBuilder ab = new ActionBuilder();
1836 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1837 Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
1839 // Build the ICMPv4 Code Match
1840 icmpv4match.setIcmpv4Code(code);
1841 setFieldBuilder.setIcmpv4Match(icmpv4match.build());
1843 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1844 ab.setKey(new ActionKey(0));
1845 actionList.add(ab.build());
1846 ApplyActionsBuilder aab = new ApplyActionsBuilder();
1847 aab.setAction(actionList);
1849 // Wrap our Apply Action in an Instruction
1850 ib.setKey(new InstructionKey(0));
1851 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1857 * Create Set ICMP Code Instruction
1859 * @param ib Map InstructionBuilder without any instructions
1860 * @return ib Map InstructionBuilder with instructions
1862 private static InstructionBuilder createSetIcmpTypeInstruction(InstructionBuilder ib, short type) {
1864 List<Action> actionList = new ArrayList<Action>();
1865 ActionBuilder ab = new ActionBuilder();
1866 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1867 Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
1869 // Build the ICMPv4 Code Match
1870 icmpv4match.setIcmpv4Code(type);
1871 setFieldBuilder.setIcmpv4Match(icmpv4match.build());
1873 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1874 ab.setKey(new ActionKey(1));
1875 actionList.add(ab.build());
1876 ApplyActionsBuilder aab = new ApplyActionsBuilder();
1877 aab.setAction(actionList);
1879 // Wrap our Apply Action in an Instruction
1880 ib.setKey(new InstructionKey(1));
1881 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1887 * Create Decrement TTL Instruction
1889 * @param ib Map InstructionBuilder without any instructions
1890 * @return ib Map InstructionBuilder with instructions
1892 private static InstructionBuilder createDecNwTtlInstructions(InstructionBuilder ib) {
1893 DecNwTtlBuilder decNwTtlBuilder = new DecNwTtlBuilder();
1894 DecNwTtl decNwTtl = decNwTtlBuilder.build();
1895 ActionBuilder ab = new ActionBuilder();
1896 ab.setAction(new DecNwTtlCaseBuilder().setDecNwTtl(decNwTtl).build());
1898 // Add our drop action to a list
1899 List<Action> actionList = new ArrayList<Action>();
1900 actionList.add(ab.build());
1902 // Create an Apply Action
1903 ApplyActionsBuilder aab = new ApplyActionsBuilder();
1904 aab.setAction(actionList);
1906 // Wrap our Apply Action in an Instruction
1907 ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
1908 ib.setKey(new InstructionKey(0));
1917 private static InstructionBuilder createSrcArpMacInstructions(InstructionBuilder ib, MacAddress macsrc) {
1919 List<Action> actionList = new ArrayList<Action>();
1920 ActionBuilder ab = new ActionBuilder();
1922 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1923 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
1924 ArpSourceHardwareAddressBuilder arpsrc = new ArpSourceHardwareAddressBuilder();
1925 arpsrc.setAddress(macsrc);
1926 arpmatch.setArpSourceHardwareAddress(arpsrc.build());
1927 setFieldBuilder.setLayer3Match(arpmatch.build());
1928 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1929 ab.setKey(new ActionKey(0));
1930 actionList.add(ab.build());
1932 ApplyActionsBuilder aab = new ApplyActionsBuilder();
1933 aab.setAction(actionList);
1941 private static InstructionBuilder createDstArpMacInstructions(InstructionBuilder ib, MacAddress macdst) {
1943 List<Action> actionList = new ArrayList<Action>();
1944 ActionBuilder ab = new ActionBuilder();
1945 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1947 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
1948 ArpTargetHardwareAddressBuilder arpdst = new ArpTargetHardwareAddressBuilder();
1949 arpdst.setAddress(macdst);
1950 setFieldBuilder.setLayer3Match(arpmatch.build());
1951 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1952 ab.setKey(new ActionKey(0));
1953 actionList.add(ab.build());
1955 ApplyActionsBuilder aab = new ApplyActionsBuilder();
1956 aab.setAction(actionList);
1964 private static InstructionBuilder createDstArpIpInstructions(InstructionBuilder ib, Ipv4Prefix dstiparp) {
1966 List<Action> actionList = new ArrayList<Action>();
1967 ActionBuilder ab = new ActionBuilder();
1968 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1970 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
1971 arpmatch.setArpTargetTransportAddress(dstiparp);
1972 setFieldBuilder.setLayer3Match(arpmatch.build());
1973 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1974 ab.setKey(new ActionKey(0));
1975 actionList.add(ab.build());
1977 ApplyActionsBuilder aab = new ApplyActionsBuilder();
1978 aab.setAction(actionList);
1986 private static InstructionBuilder createSrcArpIpInstructions(InstructionBuilder ib, Ipv4Prefix srciparp) {
1988 List<Action> actionList = new ArrayList<Action>();
1989 ActionBuilder ab = new ActionBuilder();
1990 SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
1992 ArpMatchBuilder arpmatch = new ArpMatchBuilder();
1993 arpmatch.setArpSourceTransportAddress(srciparp);
1994 setFieldBuilder.setLayer3Match(arpmatch.build());
1995 ab.setAction(new SetFieldCaseBuilder().setSetField(setFieldBuilder.build()).build());
1996 ab.setKey(new ActionKey(0));
1997 actionList.add(ab.build());
1999 ApplyActionsBuilder aab = new ApplyActionsBuilder();
2000 aab.setAction(actionList);
2006 public void initializeOFFlowRules(Node openflowNode) {
2007 IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
2008 List<Node> ovsNodes = connectionService.getNodes();
2009 if (ovsNodes == null) return;
2010 for (Node ovsNode : ovsNodes) {
2011 Long dpid = this.getIntegrationBridgeOFDPID(ovsNode);
2012 logger.debug("Compare openflowNode to OVS br-int node {} vs {}", openflowNode.getID(), dpid);
2013 String openflowID = (String)openflowNode.getID();
2014 if (openflowID.contains(""+dpid)) {
2015 this.initializeFlowRules(ovsNode, AdminConfigManager.getManager().getIntegrationBridgeName());
2016 this.triggerInterfaceUpdates(ovsNode);
2021 private NodeBuilder createNodeBuilder(String nodeId) {
2022 NodeBuilder builder = new NodeBuilder();
2023 builder.setId(new NodeId(nodeId));
2024 builder.setKey(new NodeKey(builder.getId()));
2028 private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeBuilderToInstanceId(NodeBuilder
2030 return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
2031 node.getKey()).toInstance();