import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
-import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityGroup;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.utils.HexEncode;
-import org.opendaylight.controller.sal.utils.Status;
-import org.opendaylight.controller.sal.utils.StatusCode;
+import org.opendaylight.neutron.spi.NeutronNetwork;
+import org.opendaylight.neutron.spi.NeutronSecurityGroup;
import org.opendaylight.ovsdb.lib.notation.Row;
import org.opendaylight.ovsdb.lib.notation.UUID;
import org.opendaylight.ovsdb.openstack.netvirt.NetworkHandler;
import org.opendaylight.ovsdb.openstack.netvirt.api.BridgeConfigurationManager;
import org.opendaylight.ovsdb.openstack.netvirt.api.ClassifierProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.ConfigurationService;
import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
import org.opendaylight.ovsdb.openstack.netvirt.api.EgressAclProvider;
import org.opendaylight.ovsdb.openstack.netvirt.api.IngressAclProvider;
import org.opendaylight.ovsdb.openstack.netvirt.api.TenantNetworkManager;
import org.opendaylight.ovsdb.plugin.api.OvsdbConfigurationService;
import org.opendaylight.ovsdb.plugin.api.OvsdbConnectionService;
+import org.opendaylight.ovsdb.plugin.api.Status;
+import org.opendaylight.ovsdb.plugin.api.StatusCode;
import org.opendaylight.ovsdb.plugin.api.StatusWithUuid;
import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
import org.opendaylight.ovsdb.schema.openvswitch.Interface;
import org.opendaylight.ovsdb.schema.openvswitch.Port;
+import org.opendaylight.ovsdb.utils.mdsal.node.StringConvertor;
import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
private static final short TABLE_0_DEFAULT_INGRESS = 0;
private static final short TABLE_1_ISOLATE_TENANT = 10;
private static final short TABLE_2_LOCAL_FORWARD = 20;
- private static final String OPENFLOW = "openflow:";
private static Long groupId = 1L;
- private volatile org.opendaylight.ovsdb.openstack.netvirt.api.ConfigurationService configurationService;
+ private volatile ConfigurationService configurationService;
private volatile BridgeConfigurationManager bridgeConfigurationManager;
private volatile TenantNetworkManager tenantNetworkManager;
private volatile OvsdbConfigurationService ovsdbConfigurationService;
* Action: Go to table 2
* -------------------------------------------
* Example: table=1,priority=8192,vlan_id=0x5 actions=output:1,goto_table:2
+ * table=110,priority=8192,dl_vlan=2001 actions=output:2
*/
- handleVlanMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
- segmentationId, ethPort, true);
+ handleVlanMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, ethPort, true);
}
private void removeRemoteEgressVlanRules(Node node, Long dpid, String segmentationId,
- String attachedMac, long ethPort) {
+ String attachedMac, long localPort, long ethPort) {
/*
* Table(1) Rule #1
* ----------------
//handleVlanOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD,
// segmentationId, ethPort, attachedMac, false);
+
+ /*
+ * Table(1) Rule #2
+ * ----------------
+ * Match: Match VLAN ID and L2 ::::FF:FF Flooding
+ * Action: Flood to local and remote VLAN members
+ * -------------------------------------------
+ * Example: table=1,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
+ * actions=output:10 (eth port),goto_table:2
+ * table=110, priority=16384,dl_vlan=2001,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=output:2,pop_vlan,output:1,output:3,output:4
+ */
+
+ handleLocalVlanBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, ethPort, false);
}
private void removePerVlanRules(Node node, Long dpid, String segmentationId, long localPort, long ethPort) {
* Example: table=2,priority=8192,vlan_id=0x5 actions=drop
*/
- handleLocalVlanTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId,
- false);
+ //handleLocalVlanTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, false);
/*
* Table(0) Rule #2
* Action: GOTO Local Table 2
*/
- handleVlanIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD,
- segmentationId, ethPort, false);
+ handleVlanIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, segmentationId, ethPort, false);
/*
* Table(1) Rule #2
* table=110, priority=16384,dl_vlan=2001,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=output:2,pop_vlan,output:1,output:3,output:4
*/
- handleLocalVlanBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, ethPort, false);
+ //handleLocalVlanBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, ethPort, false);
/*
* Table(1) Rule #2
* Action: Go to table 2
* -------------------------------------------
* Example: table=1,priority=8192,vlan_id=0x5 actions=output:1,goto_table:2
+ * table=110,priority=8192,dl_vlan=2001 actions=output:2
*/
handleVlanMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, ethPort, false);
Bridge bridge = ovsdbConfigurationService.getTypedRow(node, Bridge.class, bridgeRow);
Set<String> dpids = bridge.getDatapathIdColumn().getData();
if (dpids == null || dpids.size() == 0) return 0L;
- return HexEncode.stringToLong((String) dpids.toArray()[0]);
+ return StringConvertor.dpidStringToLong((String) dpids.toArray()[0]);
} catch (Exception e) {
logger.error("Error finding Bridge's OF DPID", e);
return 0L;
String bridgeName = configurationService.getExternalBridgeName();
String brUuid = this.getInternalBridgeUUID(node, bridgeName);
if (brUuid == null) {
- logger.error("Unable to spot Bridge Identifier for {} in {}", bridgeName, node);
+ // Note: it is okay for certain nodes to not have br-ex configured; not an error
+ logger.info("Unable to spot Bridge Identifier for {} in {}", bridgeName, node);
return 0L;
}
return;
}
- Set<Long> of_ports = intf.getOpenFlowPortColumn().getData();
+ Set<Integer> of_ports = intf.getOpenFlowPortColumn().getData();
if (of_ports == null || of_ports.size() <= 0) {
logger.debug("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
return;
return;
}
- Set<Long> of_ports = intf.getOpenFlowPortColumn().getData();
+ Set<Integer> of_ports = intf.getOpenFlowPortColumn().getData();
if (of_ports == null || of_ports.size() <= 0) {
logger.debug("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
return;
return;
}
- Set<Long> of_ports = intf.getOpenFlowPortColumn().getData();
+ Set<Integer> of_ports = intf.getOpenFlowPortColumn().getData();
if (of_ports == null || of_ports.size() <= 0) {
logger.debug("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
return;
if (!local) {
programRemoteEgressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
}
- logger.trace("program local ingress tunnel rules: node" + node.getNodeIDString() + " intf " + intf.getName());
+ logger.trace("program local ingress tunnel rules: node"
+ + node.getId().getValue() + " intf " + intf.getName());
if (local) {
programLocalIngressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
}
return;
}
- Set<Long> of_ports = intf.getOpenFlowPortColumn().getData();
+ Set<Integer> of_ports = intf.getOpenFlowPortColumn().getData();
if (of_ports == null || of_ports.size() <= 0) {
logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
return;
return;
}
- Set<Long> of_ports = intf.getOpenFlowPortColumn().getData();
+ Set<Integer> of_ports = intf.getOpenFlowPortColumn().getData();
int timeout = 6;
while ((of_ports == null) && (timeout > 0)) {
of_ports = intf.getOpenFlowPortColumn().getData();
return;
}
- Set<Long> of_ports = intf.getOpenFlowPortColumn().getData();
+ Set<Integer> of_ports = intf.getOpenFlowPortColumn().getData();
if (of_ports == null || of_ports.size() <= 0) {
logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
return;
}
logger.debug("Identified eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node);
- removeRemoteEgressVlanRules(node, dpid, network.getProviderSegmentationID(), attachedMac, ethOFPort);
+ removeRemoteEgressVlanRules(node, dpid, network.getProviderSegmentationID(), attachedMac, localPort, ethOFPort);
if (isLastInstanceOnNode) {
removePerVlanRules(node, dpid, network.getProviderSegmentationID(), localPort, ethOFPort);
}
for (Node dstNode : nodes) {
InetAddress src = configurationService.getTunnelEndPoint(srcNode);
InetAddress dst = configurationService.getTunnelEndPoint(dstNode);
- Status status = addTunnelPort(srcNode, network.getProviderNetworkType(), src, dst);
- if (status.isSuccess()) {
- this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), dst, srcNode, intf, true);
- }
- addTunnelPort(dstNode, network.getProviderNetworkType(), dst, src);
- if (status.isSuccess()) {
- this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), src, dstNode, intf, false);
+ if ((src != null) && (dst != null)) {
+ Status status = addTunnelPort(srcNode, network.getProviderNetworkType(), src, dst);
+ if (status.isSuccess()) {
+ this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), dst, srcNode, intf, true);
+ }
+ addTunnelPort(dstNode, network.getProviderNetworkType(), dst, src);
+ if (status.isSuccess()) {
+ this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), src, dstNode, intf, false);
+ }
+ } else {
+ logger.warn("Tunnel end-point configuration missing. Please configure it in OpenVSwitch Table. " +
+ "Check source {} or destination {}",
+ src != null ? src.getHostAddress() : "null",
+ dst != null ? dst.getHostAddress() : "null");
}
}
}
for (Node dstNode : nodes) {
InetAddress src = configurationService.getTunnelEndPoint(srcNode);
InetAddress dst = configurationService.getTunnelEndPoint(dstNode);
- logger.info("Remove tunnel rules for interface " + intf.getName() + " on srcNode " + srcNode.getNodeIDString());
- this.removeTunnelRules(tunnelType, network.getProviderSegmentationID(),
- dst, srcNode, intf, true, isLastInstanceOnNode);
- logger.info("Remove tunnel rules for interface " + intf.getName() + " on dstNode " + dstNode.getNodeIDString());
- this.removeTunnelRules(tunnelType, network.getProviderSegmentationID(),
- src, dstNode, intf, false, isLastInstanceOnNode);
+ if ((src != null) && (dst != null)) {
+ logger.info("Remove tunnel rules for interface "
+ + intf.getName() + " on srcNode " + srcNode.getId().getValue());
+ this.removeTunnelRules(tunnelType, network.getProviderSegmentationID(),
+ dst, srcNode, intf, true, isLastInstanceOnNode);
+ logger.info("Remove tunnel rules for interface "
+ + intf.getName() + " on dstNode " + dstNode.getId().getValue());
+ this.removeTunnelRules(tunnelType, network.getProviderSegmentationID(),
+ src, dstNode, intf, false, isLastInstanceOnNode);
+ } else {
+ logger.warn("Tunnel end-point configuration missing. Please configure it in OpenVSwitch Table. ",
+ "Check source {} or destination {}",
+ src != null ? src.getHostAddress() : "null",
+ dst != null ? dst.getHostAddress() : "null");
+ }
}
}
}
private void writeNormalRule(Long dpidLong) {
- String nodeName = OPENFLOW + dpidLong;
+ String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
MatchBuilder matchBuilder = new MatchBuilder();
NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
List<Instruction> instructions = Lists.newArrayList();
// Call the InstructionBuilder Methods Containing Actions
- InstructionUtils.createNormalInstructions(ib);
+ InstructionUtils.createNormalInstructions(nodeName, ib);
ib.setOrder(0);
ib.setKey(new InstructionKey(0));
instructions.add(ib.build());
* Match: Vlan ID
* Action: Output port eth interface
* table=1,priority=8192,vlan_id=0x5 actions= output port:eth1
+ * table=110,priority=8192,dl_vlan=2001 actions=output:2
*/
private void handleVlanMiss(Long dpidLong, Short writeTable,
* Match: vlan ID and dMAC (::::FF:FF)
* table=2,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
* actions=strip_vlan, output:2,3,4,5
+ * table=110,dl_vlan=2001,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=output:2,pop_vlan,output:1,output:3,output:4
*/
- private void handleLocalVlanBcastOut(Long dpidLong, Short writeTable,
- String segmentationId, Long localPort, Long ethPort,
- boolean write) {
+ private void handleLocalVlanBcastOut(Long dpidLong, Short writeTable, String segmentationId,
+ Long localPort, Long ethPort, boolean write) {
l2ForwardingProvider.programLocalVlanBcastOut(dpidLong, segmentationId, localPort, ethPort, write);
}
InstructionBuilder ib,
Long dpidLong, Long port ,
List<Instruction> instructions) {
- NodeConnectorId ncid = new NodeConnectorId(OPENFLOW + dpidLong + ":" + port);
+ NodeConnectorId ncid = new NodeConnectorId(Constants.OPENFLOW_NODE_PREFIX + dpidLong + ":" + port);
logger.debug("createOutputGroupInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
List<Action> actionList = Lists.newArrayList();
protected boolean removeOutputPortFromGroup(NodeBuilder nodeBuilder, InstructionBuilder ib,
Long dpidLong, Long port , List<Instruction> instructions) {
- NodeConnectorId ncid = new NodeConnectorId(OPENFLOW + dpidLong + ":" + port);
+ NodeConnectorId ncid = new NodeConnectorId(Constants.OPENFLOW_NODE_PREFIX + dpidLong + ":" + port);
logger.debug("removeOutputPortFromGroup() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
List<Action> actionList = Lists.newArrayList();
for (Node ovsNode : ovsNodes) {
Long brIntDpid = this.getIntegrationBridgeOFDPID(ovsNode);
Long brExDpid = this.getExternalBridgeDpid(ovsNode);
- logger.debug("Compare openflowNode to OVS node {} vs {} and {}", openflowNode.getID(), brIntDpid, brExDpid);
- String openflowID = openflowNode.getID().toString();
+ logger.debug("Compare openflowNode to OVS node {} vs {} and {}",
+ openflowNode.getId().getValue(), brIntDpid, brExDpid);
+ String openflowID = openflowNode.getId().getValue();
if (openflowID.contains(brExDpid.toString())) {
this.initializeFlowRules(ovsNode, configurationService.getExternalBridgeName());
this.triggerInterfaceUpdates(ovsNode);
}
}
+ @Override
+ public void notifyFlowCapableNodeEvent(Long dpid, org.opendaylight.ovsdb.openstack.netvirt.api.Action action) {
+ mdsalConsumer.notifyFlowCapableNodeCreateEvent(Constants.OPENFLOW_NODE_PREFIX + dpid, action);
+ }
+
public static NodeBuilder createNodeBuilder(String nodeId) {
NodeBuilder builder = new NodeBuilder();
builder.setId(new NodeId(nodeId));