import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.utils.HexEncode;
import org.opendaylight.controller.sal.utils.ServiceHelper;
import org.opendaylight.controller.sal.utils.Status;
import org.opendaylight.controller.sal.utils.StatusCode;
+import org.opendaylight.controller.switchmanager.ISwitchManager;
import org.opendaylight.ovsdb.lib.notation.OvsDBMap;
import org.opendaylight.ovsdb.lib.notation.OvsDBSet;
import org.opendaylight.ovsdb.lib.notation.UUID;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DecNwTtlCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
String bridgeUUID = null;
String tunnelBridgeName = AdminConfigManager.getManager().getIntegrationBridgeName();
OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
- Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
+ Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
if (bridgeTable != null) {
for (String uuid : bridgeTable.keySet()) {
Bridge bridge = (Bridge)bridgeTable.get(uuid);
}
}
- private void programLocalIngressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
- /*
- * Table(0) Rule #2
- * ----------------
- * Match: Ingress Port, Tunnel ID
- * Action: GOTO Local Table (10)
- */
-
- writeTunnelIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort);
-
+ private void programLocalBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long localPort) {
/*
* Table(0) Rule #3
* ----------------
*/
writeDropSrcIface(dpid, localPort);
- }
- private void programRemoteEgressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
- /*
- * Table(1) Rule #1
- * ----------------
- * Match: Drop any remaining Ingress Local VM Packets
- * Action: Drop w/ a low priority
- * -------------------------------------------
- * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
- * actions=output:11,goto_table:2
- */
-
- writeTunnelOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, attachedMac);
+ /*
+ * Table(2) Rule #1
+ * ----------------
+ * Match: Match TunID and Destination DL/dMAC Addr
+ * Action: Output Port
+ * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
+ */
- /*
- * Table(1) Rule #2
- * ----------------
- * Match: Match Tunnel ID and L2 ::::FF:FF Flooding
- * Action: Flood to selected destination TEPs
- * -------------------------------------------
- * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
- * actions=output:10,output:11,goto_table:2
- */
+ writeLocalUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, attachedMac);
- writeTunnelFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort);
+ /*
+ * Table(2) Rule #2
+ * ----------------
+ * Match: Tunnel ID and dMAC (::::FF:FF)
+ * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
+ * actions=output:2,3,4,5
+ */
+
+ writeLocalBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort);
+
+ /*
+ * TODO : Optimize the following 2 writes to be restricted only for the very first port known in a segment.
+ */
+ /*
+ * Table(1) Rule #3
+ * ----------------
+ * Match: Any remaining Ingress Local VM Packets
+ * Action: Drop w/ a low priority
+ * -------------------------------------------
+ * table=1,priority=8192,tun_id=0x5 actions=goto_table:2
+ */
+
+ writeTunnelMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId);
+
+ /*
+ * Table(2) Rule #3
+ * ----------------
+ * Match: Any Remaining Flows w/a TunID
+ * Action: Drop w/ a low priority
+ * table=2,priority=8192,tun_id=0x5 actions=drop
+ */
+
+ writeLocalTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId);
+ }
+ private void programLocalIngressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
/*
- * Table(2) Rule #1
+ * Table(0) Rule #2
* ----------------
- * Match: Match TunID and Destination DL/dMAC Addr
- * Action: Output Port
- * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
+ * Match: Ingress Port, Tunnel ID
+ * Action: GOTO Local Table (10)
*/
- writeLocalUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, attachedMac);
+ writeTunnelIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort);
- /*
- * Table(2) Rule #2
- * ----------------
- * Match: Tunnel ID and dMAC (::::FF:FF)
- * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
- * actions=output:2,3,4,5
- */
+ /*
+ * Table(1) Rule #2
+ * ----------------
+ * Match: Match Tunnel ID and L2 ::::FF:FF Flooding
+ * Action: Flood to selected destination TEPs
+ * -------------------------------------------
+ * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
+ * actions=output:10,output:11,goto_table:2
+ */
+
+ writeTunnelFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort);
- writeLocalBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort);
}
- private void programFloodEgressTunnelBridgeRules(Long dpid, String segmentationId) {
+ private void programRemoteEgressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
/*
- * Table(1) Rule #3
+ * Table(1) Rule #1
* ----------------
- * Match: Any remaining Ingress Local VM Packets
+ * Match: Drop any remaining Ingress Local VM Packets
* Action: Drop w/ a low priority
* -------------------------------------------
- * table=1,priority=8192,tun_id=0x5 actions=goto_table:2
- */
-
- writeTunnelMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId);
-
- /*
- * Table(2) Rule #3
- * ----------------
- * Match: Any Remaining Flows w/a TunID
- * Action: Drop w/ a low priority
- * table=2,priority=8192,tun_id=0x5 actions=drop
+ * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
+ * actions=output:11,goto_table:2
*/
- writeLocalTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId);
+ writeTunnelOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, attachedMac);
}
- private void programTunnelRules (String tunnelType, String segmentationId, InetAddress dst, Node node,
- Interface intf, boolean local) {
+ private Long getIntegrationBridgeOFDPID (Node node) {
try {
-
String bridgeName = AdminConfigManager.getManager().getIntegrationBridgeName();
String brIntId = this.getInternalBridgeUUID(node, bridgeName);
if (brIntId == null) {
logger.error("Unable to spot Bridge Identifier for {} in {}", bridgeName, node);
- return;
+ return 0L;
}
OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brIntId);
Set<String> dpids = bridge.getDatapath_id();
- if (dpids == null || dpids.size() == 0) return;
- Long dpid = Long.valueOf(HexEncode.stringToLong((String) dpids.toArray()[0]));
+ if (dpids == null || dpids.size() == 0) return 0L;
+ return Long.valueOf(HexEncode.stringToLong((String) dpids.toArray()[0]));
+ } catch (Exception e) {
+ logger.error("Error finding Integration Bridge's OF DPID", e);
+ return 0L;
+ }
+ }
+ private void programLocalRules (String tunnelType, String segmentationId, Node node, Interface intf) {
+ try {
+ Long dpid = this.getIntegrationBridgeOFDPID(node);
+ if (dpid == 0L) {
+ logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
+ return;
+ }
+
+ Set<BigInteger> of_ports = intf.getOfport();
+ if (of_ports == null || of_ports.size() <= 0) {
+ logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
+ return;
+ }
+ long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
+
+ Map<String, String> externalIds = intf.getExternal_ids();
+ if (externalIds == null) {
+ logger.error("No external_ids seen in {}", intf);
+ return;
+ }
+
+ String attachedMac = externalIds.get(TenantNetworkManager.EXTERNAL_ID_VM_MAC);
+ if (attachedMac == null) {
+ logger.error("No AttachedMac seen in {}", intf);
+ return;
+ }
+
+ programLocalBridgeRules(node, dpid, segmentationId, attachedMac, localPort);
+ } catch (Exception e) {
+ logger.error("Exception in programming Local Rules for "+intf+" on "+node, e);
+ }
+ }
+
+ private void programTunnelRules (String tunnelType, String segmentationId, InetAddress dst, Node node,
+ Interface intf, boolean local) {
+ try {
+
+ Long dpid = this.getIntegrationBridgeOFDPID(node);
+ if (dpid == 0L) {
+ logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
+ return;
+ }
+ OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
Set<BigInteger> of_ports = intf.getOfport();
if (of_ports == null || of_ports.size() <= 0) {
return;
}
- Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
+ Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
if (intfs != null) {
- for (org.opendaylight.ovsdb.lib.table.internal.Table<?> row : intfs.values()) {
+ for (org.opendaylight.ovsdb.lib.table.Table<?> row : intfs.values()) {
Interface tunIntf = (Interface)row;
if (tunIntf.getName().equals(this.getTunnelName(tunnelType, dst))) {
of_ports = tunIntf.getOfport();
programRemoteEgressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
}
programLocalIngressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
- programFloodEgressTunnelBridgeRules(dpid, segmentationId);
return;
}
}
@Override
public Status handleInterfaceUpdate(String tunnelType, String tunnelKey, Node srcNode, Interface intf) {
- Status status = getTunnelReadinessStatus(srcNode, tunnelKey);
- if (!status.isSuccess()) return status;
+ ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, "default", this);
+ if (switchManager == null) {
+ logger.error("Unable to identify SwitchManager");
+ } else {
+ Long dpid = this.getIntegrationBridgeOFDPID(srcNode);
+ if (dpid == 0L) {
+ logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", srcNode);
+ return new Status(StatusCode.NOTFOUND);
+ }
+ Set<Node> ofNodes = switchManager.getNodes();
+ boolean ofNodeFound = false;
+ if (ofNodes != null) {
+ for (Node ofNode : ofNodes) {
+ if (ofNode.toString().contains(dpid+"")) {
+ logger.debug("Identified the Openflow node via toString {}", ofNode);
+ ofNodeFound = true;
+ break;
+ }
+ }
+ } else {
+ logger.error("Unable to find any Node from SwitchManager");
+ }
+ if (!ofNodeFound) {
+ logger.error("Unable to find OF Node for {} with update {} on node {}", dpid, intf, srcNode);
+ return new Status(StatusCode.NOTFOUND);
+ }
+ }
IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
List<Node> nodes = connectionService.getNodes();
nodes.remove(srcNode);
+ this.programLocalRules(tunnelType, tunnelKey, srcNode, intf);
+
for (Node dstNode : nodes) {
- status = getTunnelReadinessStatus(dstNode, tunnelKey);
- if (!status.isSuccess()) continue;
InetAddress src = AdminConfigManager.getManager().getTunnelEndPoint(srcNode);
InetAddress dst = AdminConfigManager.getManager().getTunnelEndPoint(dstNode);
- status = addTunnelPort(srcNode, tunnelType, src, dst);
+ Status status = addTunnelPort(srcNode, tunnelType, src, dst);
if (status.isSuccess()) {
this.programTunnelRules(tunnelType, tunnelKey, dst, srcNode, intf, true);
}
this.programTunnelRules(tunnelType, tunnelKey, src, dstNode, intf, false);
}
}
+
return new Status(StatusCode.SUCCESS);
}
+ private Status triggerInterfaceUpdates(Node node) {
+ try {
+ OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
+ Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
+ if (intfs != null) {
+ for (org.opendaylight.ovsdb.lib.table.Table<?> row : intfs.values()) {
+ Interface intf = (Interface)row;
+ NeutronNetwork network = TenantNetworkManager.getManager().getTenantNetworkForInterface(intf);
+ logger.debug("Trigger Interface update for {}", intf);
+ if (network != null) {
+ this.handleInterfaceUpdate(network.getProviderNetworkType(), network.getProviderSegmentationID(), node, intf);
+ }
+ }
+ }
+ } catch (Exception e) {
+ logger.error("Error Triggering the lost interface updates for "+ node, e);
+ return new Status(StatusCode.INTERNALERROR, e.getLocalizedMessage());
+ }
+ return new Status(StatusCode.SUCCESS);
+ }
@Override
public Status handleInterfaceUpdate(String tunnelType, String tunnelKey) {
// TODO Auto-generated method stub
return null;
}
+ @Override
+ public Status handleInterfaceDelete(String tunnelType, String tunnelKey, Node source, Interface intf,
+ boolean isLastInstanceOnNode) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
@Override
public void initializeFlowRules(Node node) {
this.initializeFlowRules(node, AdminConfigManager.getManager().getIntegrationBridgeName());
+ this.triggerInterfaceUpdates(node);
}
/**
* @param bridgeName
*/
private void initializeFlowRules(Node node, String bridgeName) {
-
- // TODO : 3 second sleep hack is to make sure the OF connection is established.
- // Correct fix is to check the MD-SAL inventory before proceeding and listen
- // to Inventory update for processing.
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e1) {
- logger.error("Sleep Thread interrupted ",e1);
- }
-
- String brIntId = this.getInternalBridgeUUID(node, bridgeName);
- if (brIntId == null) {
- logger.error("Failed to initialize Flow Rules for {}", node);
+ Long dpid = this.getIntegrationBridgeOFDPID(node);
+ if (dpid == 0L) {
+ logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
return;
}
- try {
- OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
- Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brIntId);
- Set<String> dpids = bridge.getDatapath_id();
- if (dpids == null || dpids.size() == 0) return;
- Long dpid = Long.valueOf(HexEncode.stringToLong((String) dpids.toArray()[0]));
-
- /*
- * Table(0) Rule #1
- * ----------------
- * Match: LLDP (0x88CCL)
- * Action: Packet_In to Controller Reserved Port
- */
+ /*
+ * Table(0) Rule #1
+ * ----------------
+ * Match: LLDP (0x88CCL)
+ * Action: Packet_In to Controller Reserved Port
+ */
- writeLLDPRule(dpid);
- } catch (Exception e) {
- logger.error("Failed to initialize Flow Rules for " + node.toString()+ " Bridge "+bridgeName, e);
- }
+ writeLLDPRule(dpid);
}
/*
// Call the InstructionBuilder Methods Containing Actions
createSendToControllerInstructions(ib);
+ ib.setOrder(0);
+ ib.setKey(new InstructionKey(0));
instructions.add(ib.build());
// Add InstructionBuilder to the Instruction(s)Builder List
// Add InstructionsBuilder to FlowBuilder
flowBuilder.setInstructions(isb.build());
- flowBuilder.setId(new FlowId("10"));
- FlowKey key = new FlowKey(new FlowId(String.valueOf((long) 110)));
+ String flowId = "LLDP";
+ flowBuilder.setId(new FlowId(flowId));
+ FlowKey key = new FlowKey(new FlowId(flowId));
flowBuilder.setBarrier(true);
flowBuilder.setTableId((short) 0);
flowBuilder.setKey(key);
- flowBuilder.setFlowName("LLDP_" + nodeName);
+ flowBuilder.setFlowName(flowId);
flowBuilder.setHardTimeout(0);
flowBuilder.setIdleTimeout(0);
writeFlow(flowBuilder, nodeBuilder);
// Call the InstructionBuilder Methods Containing Actions
createGotoTableInstructions(ib, goToTableId);
+ ib.setOrder(0);
+ ib.setKey(new InstructionKey(0));
instructions.add(ib.build());
// Add InstructionBuilder to the Instruction(s)Builder List
// Add InstructionsBuilder to FlowBuilder
flowBuilder.setInstructions(isb.build());
+ String flowId = "TunnelIn_"+segmentationId+"_"+ofPort;
// Add Flow Attributes
- flowBuilder.setId(new FlowId("20"));
- FlowKey key = new FlowKey(new FlowId(String.valueOf((long) 120)));
+ flowBuilder.setId(new FlowId(flowId));
+ FlowKey key = new FlowKey(new FlowId(flowId));
+ flowBuilder.setStrict(true);
flowBuilder.setBarrier(false);
flowBuilder.setTableId(writeTable);
flowBuilder.setKey(key);
- flowBuilder.setFlowName("TUNIN_" + nodeName);
+ flowBuilder.setFlowName(flowId);
flowBuilder.setHardTimeout(0);
flowBuilder.setIdleTimeout(0);
writeFlow(flowBuilder, nodeBuilder);
// TODO Broken In_Port Match
flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
+ String flowId = "LocalMac_"+segmentationId+"_"+inPort+"_"+attachedMac;
+ // Add Flow Attributes
+ flowBuilder.setId(new FlowId(flowId));
+ FlowKey key = new FlowKey(new FlowId(flowId));
+ flowBuilder.setStrict(true);
+ flowBuilder.setBarrier(false);
+ flowBuilder.setTableId(writeTable);
+ flowBuilder.setKey(key);
+ flowBuilder.setFlowName(flowId);
+ flowBuilder.setHardTimeout(0);
+ flowBuilder.setIdleTimeout(0);
+
// Instantiate the Builders for the OF Actions and Instructions
InstructionBuilder ib = new InstructionBuilder();
InstructionsBuilder isb = new InstructionsBuilder();
// GOTO Instuctions Need to be added first to the List
createGotoTableInstructions(ib, goToTableId);
+ ib.setOrder(0);
+ ib.setKey(new InstructionKey(0));
instructions.add(ib.build());
// TODO Broken SetTunID
createSetTunnelIdInstructions(ib, new BigInteger(segmentationId));
+ ib.setOrder(1);
+ ib.setKey(new InstructionKey(1));
instructions.add(ib.build());
// Add InstructionBuilder to the Instruction(s)Builder List
// Add InstructionsBuilder to FlowBuilder
flowBuilder.setInstructions(isb.build());
- // Add Flow Attributes
- flowBuilder.setId(new FlowId("30"));
- FlowKey key = new FlowKey(new FlowId(String.valueOf((long) 130)));
- flowBuilder.setBarrier(false);
- flowBuilder.setTableId(writeTable);
- flowBuilder.setKey(key);
- flowBuilder.setFlowName("LOCALSMAC_" + nodeName);
- flowBuilder.setHardTimeout(0);
- flowBuilder.setIdleTimeout(0);
writeFlow(flowBuilder, nodeBuilder);
}
// Call the InstructionBuilder Methods Containing Actions
createDropInstructions(ib);
+ ib.setOrder(0);
+ ib.setKey(new InstructionKey(0));
instructions.add(ib.build());
// Add InstructionBuilder to the Instruction(s)Builder List
// Add InstructionsBuilder to FlowBuilder
flowBuilder.setInstructions(isb.build());
+ String flowId = "DropFilter_"+inPort;
// Add Flow Attributes
- flowBuilder.setId(new FlowId("40"));
- FlowKey key = new FlowKey(new FlowId(String.valueOf((long) 140)));
+ flowBuilder.setId(new FlowId(flowId));
+ FlowKey key = new FlowKey(new FlowId(flowId));
+ flowBuilder.setStrict(true);
flowBuilder.setBarrier(false);
flowBuilder.setTableId((short) 0);
flowBuilder.setKey(key);
- flowBuilder.setFlowName("LOCALDROP_" + nodeName);
+ flowBuilder.setFlowName(flowId);
flowBuilder.setPriority(8192);
flowBuilder.setHardTimeout(0);
flowBuilder.setIdleTimeout(0);
flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
+ String flowId = "TunnelOut_"+segmentationId+"_"+OFPortOut+"_"+attachedMac;
+ // Add Flow Attributes
+ flowBuilder.setId(new FlowId(flowId));
+ FlowKey key = new FlowKey(new FlowId(flowId));
+ flowBuilder.setStrict(true);
+ flowBuilder.setBarrier(false);
+ flowBuilder.setTableId(writeTable);
+ flowBuilder.setKey(key);
+ flowBuilder.setFlowName(flowId);
+ flowBuilder.setHardTimeout(0);
+ flowBuilder.setIdleTimeout(0);
// Instantiate the Builders for the OF Actions and Instructions
InstructionBuilder ib = new InstructionBuilder();
InstructionsBuilder isb = new InstructionsBuilder();
// GOTO Instuctions
createGotoTableInstructions(ib, goToTableId);
+ ib.setOrder(0);
+ ib.setKey(new InstructionKey(0));
instructions.add(ib.build());
// Set the Output Port/Iface
createOutputPortInstructions(ib, dpidLong, OFPortOut);
+ ib.setOrder(1);
+ ib.setKey(new InstructionKey(1));
instructions.add(ib.build());
// Add InstructionBuilder to the Instruction(s)Builder List
// Add InstructionsBuilder to FlowBuilder
flowBuilder.setInstructions(isb.build());
- // Add Flow Attributes
- flowBuilder.setId(new FlowId("50"));
- FlowKey key = new FlowKey(new FlowId(String.valueOf((long) 150)));
- flowBuilder.setBarrier(false);
- flowBuilder.setTableId(writeTable);
- flowBuilder.setKey(key);
- flowBuilder.setFlowName("TUNOUT_" + nodeName);
- flowBuilder.setHardTimeout(0);
- flowBuilder.setIdleTimeout(0);
writeFlow(flowBuilder, nodeBuilder);
}
// Match TunnelID
flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
// Match DMAC
- byte[] mask = new byte[] { (byte) 1, 0, 0, 0, 0, 0 };
- flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), mask).build());
+ flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
+
+ String flowId = "TunnelFloodOut_"+segmentationId;
+ // Add Flow Attributes
+ flowBuilder.setId(new FlowId(flowId));
+ FlowKey key = new FlowKey(new FlowId(flowId));
+ flowBuilder.setBarrier(true);
+ flowBuilder.setTableId(writeTable);
+ flowBuilder.setKey(key);
+ flowBuilder.setPriority(16384);
+ flowBuilder.setFlowName(flowId);
+ flowBuilder.setHardTimeout(0);
+ flowBuilder.setIdleTimeout(0);
+
+ Flow flow = this.getFlow(flowBuilder, nodeBuilder);
// Instantiate the Builders for the OF Actions and Instructions
InstructionBuilder ib = new InstructionBuilder();
InstructionsBuilder isb = new InstructionsBuilder();
-
- // Instructions List Stores Individual Instructions
List<Instruction> instructions = new ArrayList<Instruction>();
-
+ List<Instruction> existingInstructions = null;
+ if (flow != null) {
+ Instructions ins = flow.getInstructions();
+ if (ins != null) {
+ existingInstructions = ins.getInstruction();
+ }
+ }
// GOTO Instuction
createGotoTableInstructions(ib, localTable);
+ ib.setOrder(0);
+ ib.setKey(new InstructionKey(0));
instructions.add(ib.build());
// Set the Output Port/Iface
- createOutputPortInstructions(ib, dpidLong, OFPortOut);
+ createOutputPortInstructions(ib, dpidLong, OFPortOut, existingInstructions);
+ ib.setOrder(1);
+ ib.setKey(new InstructionKey(1));
instructions.add(ib.build());
// Add InstructionBuilder to the Instruction(s)Builder List
// Add InstructionsBuilder to FlowBuilder
flowBuilder.setInstructions(isb.build());
- // Add Flow Attributes
- flowBuilder.setId(new FlowId("60"));
- FlowKey key = new FlowKey(new FlowId(String.valueOf((long) 160)));
- flowBuilder.setBarrier(true);
- flowBuilder.setTableId(writeTable);
- flowBuilder.setKey(key);
- flowBuilder.setPriority(16384);
- flowBuilder.setFlowName("TUNFLOODOUT_" + nodeName);
- flowBuilder.setHardTimeout(0);
- flowBuilder.setIdleTimeout(0);
writeFlow(flowBuilder, nodeBuilder);
}
// Call the InstructionBuilder Methods Containing Actions
createGotoTableInstructions(ib, goToTableId);
+ ib.setOrder(0);
+ ib.setKey(new InstructionKey(0));
instructions.add(ib.build());
// Add InstructionBuilder to the Instruction(s)Builder List
// Add InstructionsBuilder to FlowBuilder
flowBuilder.setInstructions(isb.build());
+ String flowId = "TunnelMiss_"+segmentationId;
// Add Flow Attributes
- flowBuilder.setId(new FlowId("70"));
- FlowKey key = new FlowKey(new FlowId(String.valueOf((long) 170)));
+ flowBuilder.setId(new FlowId(flowId));
+ FlowKey key = new FlowKey(new FlowId(flowId));
+ flowBuilder.setStrict(true);
flowBuilder.setBarrier(false);
flowBuilder.setTableId(writeTable);
flowBuilder.setKey(key);
flowBuilder.setPriority(8192);
- flowBuilder.setFlowName("TUNMISS_" + nodeName);
+ flowBuilder.setFlowName(flowId);
flowBuilder.setHardTimeout(0);
flowBuilder.setIdleTimeout(0);
writeFlow(flowBuilder, nodeBuilder);
flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
+ String flowId = "UcastOut_"+segmentationId+"_"+localPort+"_"+attachedMac;
+ // Add Flow Attributes
+ flowBuilder.setId(new FlowId(flowId));
+ FlowKey key = new FlowKey(new FlowId(flowId));
+ flowBuilder.setStrict(true);
+ flowBuilder.setBarrier(false);
+ flowBuilder.setTableId(writeTable);
+ flowBuilder.setKey(key);
+ flowBuilder.setFlowName(flowId);
+ flowBuilder.setHardTimeout(0);
+ flowBuilder.setIdleTimeout(0);
+
// Instantiate the Builders for the OF Actions and Instructions
InstructionBuilder ib = new InstructionBuilder();
InstructionsBuilder isb = new InstructionsBuilder();
// Set the Output Port/Iface
createOutputPortInstructions(ib, dpidLong, localPort);
+ ib.setOrder(0);
+ ib.setKey(new InstructionKey(0));
instructions.add(ib.build());
// Add InstructionBuilder to the Instruction(s)Builder List
// Add InstructionsBuilder to FlowBuilder
flowBuilder.setInstructions(isb.build());
-
- // Add Flow Attributes
- flowBuilder.setId(new FlowId("80"));
- FlowKey key = new FlowKey(new FlowId(String.valueOf((long) 180)));
- flowBuilder.setBarrier(false);
- flowBuilder.setTableId(writeTable);
- flowBuilder.setKey(key);
- flowBuilder.setFlowName("LOCALHOSTUCAST_" + nodeName);
- flowBuilder.setHardTimeout(0);
- flowBuilder.setIdleTimeout(0);
writeFlow(flowBuilder, nodeBuilder);
}
// Create the OF Match using MatchBuilder
flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
- byte[] mask = new byte[] { (byte) 1, 0, 0, 0, 0, 0 };
- flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), mask).build());
+ flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
+ String flowId = "BcastOut_"+segmentationId;
+ // Add Flow Attributes
+ flowBuilder.setId(new FlowId(flowId));
+ FlowKey key = new FlowKey(new FlowId(flowId));
+ flowBuilder.setStrict(true);
+ flowBuilder.setBarrier(false);
+ flowBuilder.setTableId(writeTable);
+ flowBuilder.setKey(key);
+ flowBuilder.setPriority(16384);
+ flowBuilder.setFlowName(flowId);
+ flowBuilder.setHardTimeout(0);
+ flowBuilder.setIdleTimeout(0);
+ Flow flow = this.getFlow(flowBuilder, nodeBuilder);
// Instantiate the Builders for the OF Actions and Instructions
InstructionBuilder ib = new InstructionBuilder();
InstructionsBuilder isb = new InstructionsBuilder();
-
- // Instructions List Stores Individual Instructions
List<Instruction> instructions = new ArrayList<Instruction>();
+ List<Instruction> existingInstructions = null;
+ if (flow != null) {
+ Instructions ins = flow.getInstructions();
+ if (ins != null) {
+ existingInstructions = ins.getInstruction();
+ }
+ }
// Broken OutPort TODO: localPort needs to be a list of Ports)
- createOutputPortInstructions(ib, dpidLong, localPort);
+ createOutputPortInstructions(ib, dpidLong, localPort, existingInstructions);
+ ib.setOrder(0);
+ ib.setKey(new InstructionKey(0));
instructions.add(ib.build());
// Add InstructionBuilder to the Instruction(s)Builder List
// Add InstructionsBuilder to FlowBuilder
flowBuilder.setInstructions(isb.build());
- // Add Flow Attributes
- flowBuilder.setId(new FlowId("90"));
- FlowKey key = new FlowKey(new FlowId(String.valueOf((long) 190)));
- flowBuilder.setBarrier(false);
- flowBuilder.setTableId(writeTable);
- flowBuilder.setKey(key);
- flowBuilder.setPriority(16384);
- flowBuilder.setFlowName("LOCALHOSTBCAST_" + nodeName);
- flowBuilder.setHardTimeout(0);
- flowBuilder.setIdleTimeout(0);
writeFlow(flowBuilder, nodeBuilder);
}
// Call the InstructionBuilder Methods Containing Actions
createDropInstructions(ib);
+ ib.setOrder(0);
+ ib.setKey(new InstructionKey(0));
instructions.add(ib.build());
// Add InstructionBuilder to the Instruction(s)Builder List
// Add InstructionsBuilder to FlowBuilder
flowBuilder.setInstructions(isb.build());
+ String flowId = "LocalTableMiss_"+segmentationId;
// Add Flow Attributes
- flowBuilder.setId(new FlowId("100"));
- FlowKey key = new FlowKey(new FlowId(String.valueOf((long) 200)));
+ flowBuilder.setId(new FlowId(flowId));
+ FlowKey key = new FlowKey(new FlowId(flowId));
+ flowBuilder.setStrict(true);
flowBuilder.setBarrier(false);
flowBuilder.setTableId(writeTable);
flowBuilder.setKey(key);
flowBuilder.setPriority(8192);
- flowBuilder.setFlowName("TUNMISS_" + nodeName);
+ flowBuilder.setFlowName(flowId);
flowBuilder.setHardTimeout(0);
flowBuilder.setIdleTimeout(0);
writeFlow(flowBuilder, nodeBuilder);
}
+ private Flow getFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
+ IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
+ if (mdsalConsumer == null) {
+ logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
+ return null;
+ }
+
+ dataBrokerService = mdsalConsumer.getDataBrokerService();
+
+ if (dataBrokerService == null) {
+ logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
+ return null;
+ }
+
+ InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
+ .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class,
+ new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
+ return (Flow)dataBrokerService.readConfigurationData(path1);
+ }
+
private void writeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
if (mdsalConsumer == null) {
try {
RpcResult<TransactionStatus> result = commitFuture.get();
TransactionStatus status = result.getResult();
+ logger.debug("Transaction Status "+status.toString()+" for Flow "+flowBuilder.getFlowName());
} catch (InterruptedException e) {
logger.error(e.getMessage(), e);
} catch (ExecutionException e) {
* @return matchBuilder Map MatchBuilder Object with a match
*/
- protected static MatchBuilder createDestEthMatch(MatchBuilder matchBuilder, MacAddress dMacAddr, byte[] mask) {
+ protected static MatchBuilder createDestEthMatch(MatchBuilder matchBuilder, MacAddress dMacAddr, MacAddress mask) {
EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
EthernetDestinationBuilder ethDestinationBuilder = new EthernetDestinationBuilder();
// Wrap our Apply Action in an Instruction
ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
- ib.setOrder(0);
- ib.setKey(new InstructionKey(0));
return ib;
}
oab.setOutputNodeConnector(ncid);
ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
- ab.setOrder(5);
- ab.setKey(new ActionKey(5));
+ ab.setOrder(0);
+ ab.setKey(new ActionKey(0));
actionList.add(ab.build());
// Create an Apply Action
return ib;
}
+ /**
+ * Create Output Port Instruction
+ *
+ * @param ib Map InstructionBuilder without any instructions
+ * @param dpidLong Long the datapath ID of a switch/node
+ * @param port Long representing a port on a switch/node
+ * @return ib InstructionBuilder Map with instructions
+ */
+ protected static InstructionBuilder createOutputPortInstructions(InstructionBuilder ib, Long dpidLong, Long port , List<Instruction> instructions) {
+
+ NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
+ logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
+
+ List<Action> actionList = new ArrayList<Action>();
+ ActionBuilder ab = new ActionBuilder();
+
+ List<Action> existingActions = null;
+ if (instructions != null) {
+ for (Instruction in : instructions) {
+ if (in.getInstruction() instanceof ApplyActionsCase) {
+ existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
+ actionList.addAll(existingActions);
+ }
+ }
+ }
+
+ OutputActionBuilder oab = new OutputActionBuilder();
+ oab.setOutputNodeConnector(ncid);
+ ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
+ ab.setOrder(0);
+ ab.setKey(new ActionKey(0));
+ Action newAction = ab.build();
+ boolean addNew = true;
+ for (Action action : actionList) {
+ if (action.getAction() instanceof OutputActionCase) {
+ OutputActionCase opAction = (OutputActionCase)action.getAction();
+ if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
+ addNew = false;
+ break;
+ }
+ }
+ }
+ if (addNew) actionList.add(newAction);
+
+ // Create an Apply Action
+ ApplyActionsBuilder aab = new ApplyActionsBuilder();
+ aab.setAction(actionList);
+ ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
+
+ return ib;
+ }
+
/**
* Create Set Vlan ID Instruction
*
// Wrap our Apply Action in an Instruction
ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
- ib.setOrder(0);
- ib.setKey(new InstructionKey(0));
return ib;
}
// Wrap our Apply Action in an Instruction
ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
- ib.setOrder(0);
- ib.setKey(new InstructionKey(0));
return ib;
}
// Wrap our Apply Action in an InstructionBuilder
ib.setInstruction(new GoToTableCaseBuilder().setGoToTable(gttb.build()).build());
- ib.setOrder(0);
- ib.setKey(new InstructionKey(0));
return ib;
}
aab.setAction(actionList);
// Wrap the Apply Action in an InstructionBuilder and return
- ib.setOrder(0);
- ib.setKey(new InstructionKey(0));
ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
return ib;
ApplyActionsBuilder aab = new ApplyActionsBuilder();
aab.setAction(actionList);
- ib.setKey(new InstructionKey(1));
ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
return ib;
ApplyActionsBuilder aab = new ApplyActionsBuilder();
aab.setAction(actionList);
- ib.setKey(new InstructionKey(1));
ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
return ib;
ApplyActionsBuilder aab = new ApplyActionsBuilder();
aab.setAction(actionList);
- ib.setKey(new InstructionKey(1));
ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
return ib;
ApplyActionsBuilder aab = new ApplyActionsBuilder();
aab.setAction(actionList);
- ib.setKey(new InstructionKey(1));
ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
return ib;
aab.setAction(actionList);
// Wrap our Apply Action in an Instruction
- ib.setKey(new InstructionKey(0));
ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
return ib;
aab.setAction(actionList);
// Wrap our Apply Action in an Instruction
- ib.setKey(new InstructionKey(1));
ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
return ib;
// Wrap our Apply Action in an Instruction
ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
- ib.setKey(new InstructionKey(0));
- ib.setOrder(0);
return ib;
}
@Override
public void initializeOFFlowRules(Node openflowNode) {
+ IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
+ List<Node> ovsNodes = connectionService.getNodes();
+ if (ovsNodes == null) return;
+ for (Node ovsNode : ovsNodes) {
+ Long dpid = this.getIntegrationBridgeOFDPID(ovsNode);
+ logger.debug("Compare openflowNode to OVS br-int node {} vs {}", openflowNode.getID(), dpid);
+ String openflowID = ""+openflowNode.getID();
+ if (openflowID.contains(""+dpid)) {
+ this.initializeFlowRules(ovsNode, AdminConfigManager.getManager().getIntegrationBridgeName());
+ this.triggerInterfaceUpdates(ovsNode);
+ }
+ }
}
private NodeBuilder createNodeBuilder(String nodeId) {
return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
node.getKey()).toInstance();
}
-}
\ No newline at end of file
+}