package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ExecutionException;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
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.sal.utils.HexEncode;
+import org.opendaylight.ovsdb.lib.notation.Row;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
+import org.opendaylight.ovsdb.plugin.api.OvsdbConfigurationService;
+import org.opendaylight.ovsdb.plugin.api.OvsdbConnectionService;
+import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
// OSGi Services that we are dependent on.
private volatile MdsalConsumer mdsalConsumer;
private volatile PipelineOrchestrator orchestrator;
+ private volatile OvsdbConfigurationService ovsdbConfigService;
+ private volatile OvsdbConnectionService connectionService;
// Concrete Service that this AbstractServiceInstance represent
private Service service;
this.service = service;
}
- // Let the Concrete service instance class decide if a Bride is part of the pipeline or not.
- public abstract boolean isBridgeInPipeline (String nodeId);
+ public boolean isBridgeInPipeline (String nodeId){
+ String bridgeName = getBridgeName(nodeId.split(":")[1]);
+ logger.debug("isBridgeInPipeline: nodeId {} bridgeName {}", nodeId, bridgeName);
+ if (bridgeName != null && Constants.INTEGRATION_BRIDGE.equalsIgnoreCase(bridgeName)) {
+ return true;
+ }
+ return false;
+ }
+
+ private String getBridgeName(String nodeId){
+ List<org.opendaylight.controller.sal.core.Node> ovsNodes = connectionService.getNodes();
+
+ for (org.opendaylight.controller.sal.core.Node ovsNode : ovsNodes) {
+ Map<String, Row> bridges = ovsdbConfigService.getRows(ovsNode, ovsdbConfigService.getTableName(ovsNode, Bridge.class));
+ if (bridges == null) continue;
+ for (String brUuid : bridges.keySet()) {
+ Bridge bridge = ovsdbConfigService.getTypedRow(ovsNode, Bridge.class, bridges.get(brUuid));
+
+ Set<String> dpids = bridge.getDatapathIdColumn().getData();
+ if (dpids == null || dpids.size() == 0) return null;
+ Long dpid = HexEncode.stringToLong((String) dpids.toArray()[0]);
+ logger.debug("getBridgeName: bridgeDpid {} ofNodeDpid {}", bridge.getDatapathIdColumn().getData().toArray()[0], nodeId);
+ if (dpid.equals(Long.parseLong(nodeId))){
+ // Found the bridge
+ logger.debug("getOvsNode: found ovsNode {} bridge {} for ofNode {}", ovsNode.getNodeIDString(), bridge.getName(), nodeId);
+ return bridge.getName();
+ }
+ }
+ }
+ return null;
+ }
public short getTable() {
return service.getTable();
* @param nodeId Node on which the default pipeline flow is programmed.
*/
protected void programDefaultPipelineRule(String nodeId) {
+ if (!isBridgeInPipeline(nodeId)) {
+ logger.debug("Bridge {} is not in pipeline", nodeId);
+ return;
+ }
MatchBuilder matchBuilder = new MatchBuilder();
FlowBuilder flowBuilder = new FlowBuilder();
NodeBuilder nodeBuilder = createNodeBuilder(nodeId);
import java.util.List;
import java.util.Map;
-import org.opendaylight.controller.sal.utils.Status;
-import org.opendaylight.controller.sal.utils.StatusCode;
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.core.Node.NodeIDType;
+import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.sal.utils.StatusCode;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
import org.opendaylight.ovsdb.openstack.netvirt.api.LoadBalancerConfiguration;
import org.opendaylight.ovsdb.openstack.netvirt.api.LoadBalancerConfiguration.LoadBalancerPoolMember;
import org.opendaylight.ovsdb.openstack.netvirt.api.LoadBalancerProvider;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
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.address.address.Ipv4Builder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
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.inventory.rev130819.NodeId;
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.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxRegCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.ovs.nx.action.rev140421.OfjNxHashFields;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.ovs.nx.action.rev140421.OfjNxMpAlgorithm;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg2;
-import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
-
-import com.google.common.collect.Lists;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxRegCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.ovs.nx.action.rev140421.OfjNxHashFields;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.ovs.nx.action.rev140421.OfjNxMpAlgorithm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.collect.Lists;
public class LoadBalancerService extends AbstractServiceInstance implements LoadBalancerProvider {
private static final Logger logger = LoggerFactory.getLogger(LoadBalancerProvider.class);
super(service);
}
- @Override
- public boolean isBridgeInPipeline (String nodeId) {
- return true;
- }
-
/**
* When this method is called, we do the following for minimizing flow updates:
* 1. Overwrite the solo multipath rule that applies to all members
ab = new ActionBuilder();
ab.setAction(ActionUtils.nxMultipathAction(OfjNxHashFields.NXHASHFIELDSSYMMETRICL4,
- (Integer)0, OfjNxMpAlgorithm.NXMPALGMODULON,
- (Integer)lbConfig.getMembers().size()-1, //By Nicira-Ext spec, this field is max_link minus 1
- (Long)0L, new DstNxRegCaseBuilder().setNxReg(REG_FIELD_B).build(),
- (Integer)0, (Integer)31));
+ 0, OfjNxMpAlgorithm.NXMPALGMODULON,
+ lbConfig.getMembers().size()-1, //By Nicira-Ext spec, this field is max_link minus 1
+ 0L, new DstNxRegCaseBuilder().setNxReg(REG_FIELD_B).build(),
+ 0, 31));
ab.setOrder(1);
ab.setKey(new ActionKey(1));
actionList.add(ab.build());
flowBuilder.setMatch(matchBuilder.build());
flowBuilder.setPriority(DEFAULT_FLOW_PRIORITY);
flowBuilder.setBarrier(true);
- flowBuilder.setTableId((short) this.getTable());
+ flowBuilder.setTableId(this.getTable());
flowBuilder.setKey(key);
flowBuilder.setFlowName(flowId);
flowBuilder.setHardTimeout(0);
*/
private void insertLoadBalancerVIPRulesSecondPass(NodeBuilder nodeBuilder, LoadBalancerConfiguration lbConfig) {
for(Map.Entry<String, LoadBalancerPoolMember> entry : lbConfig.getMembers().entrySet()){
- insertLoadBalancerMemberVIPRulesSecondPass(nodeBuilder, lbConfig.getVip(), (LoadBalancerPoolMember)entry.getValue());
+ insertLoadBalancerMemberVIPRulesSecondPass(nodeBuilder, lbConfig.getVip(), entry.getValue());
}
}
flowBuilder.setMatch(matchBuilder.build());
flowBuilder.setPriority(DEFAULT_FLOW_PRIORITY+1);
flowBuilder.setBarrier(true);
- flowBuilder.setTableId((short) this.getTable());
+ flowBuilder.setTableId(this.getTable());
flowBuilder.setKey(key);
flowBuilder.setFlowName(flowId);
flowBuilder.setHardTimeout(0);
*/
private void insertLoadBalancerReverseRules(NodeBuilder nodeBuilder, LoadBalancerConfiguration lbConfig) {
for(Map.Entry<String, LoadBalancerPoolMember> entry : lbConfig.getMembers().entrySet()){
- insertLoadBalancerMemberReverseRules(nodeBuilder, lbConfig.getVip(), (LoadBalancerPoolMember)entry.getValue());
+ insertLoadBalancerMemberReverseRules(nodeBuilder, lbConfig.getVip(), entry.getValue());
}
}
flowBuilder.setMatch(matchBuilder.build());
flowBuilder.setPriority(DEFAULT_FLOW_PRIORITY);
flowBuilder.setBarrier(true);
- flowBuilder.setTableId((short) this.getTable());
+ flowBuilder.setTableId(this.getTable());
flowBuilder.setKey(key);
flowBuilder.setFlowName(flowId);
flowBuilder.setHardTimeout(0);
FlowKey key = new FlowKey(new FlowId(flowId));
flowBuilder.setPriority(DEFAULT_FLOW_PRIORITY);
flowBuilder.setBarrier(true);
- flowBuilder.setTableId((short) this.getTable());
+ flowBuilder.setTableId(this.getTable());
flowBuilder.setKey(key);
removeFlow(flowBuilder, nodeBuilder);
// Match all second pass rules
for(Map.Entry<String, LoadBalancerPoolMember> entry : lbConfig.getMembers().entrySet()){
- LoadBalancerPoolMember member = (LoadBalancerPoolMember) entry.getValue();
+ LoadBalancerPoolMember member = entry.getValue();
MatchUtils.addNxRegMatch(matchBuilder, new MatchUtils.RegMatch(REG_FIELD_A, SECOND_PASS_REGA_MATCH_VALUE),
new MatchUtils.RegMatch(REG_FIELD_B, (long)member.getIndex()));
MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(lbConfig.getVip()));
*/
private void removeLoadBalancerReverseRules(NodeBuilder nodeBuilder, LoadBalancerConfiguration lbConfig) {
for(Map.Entry<String, LoadBalancerPoolMember> entry : lbConfig.getMembers().entrySet()){
- LoadBalancerPoolMember member = (LoadBalancerPoolMember) entry.getValue();
+ LoadBalancerPoolMember member = entry.getValue();
MatchBuilder matchBuilder = new MatchBuilder();
FlowBuilder flowBuilder = new FlowBuilder();
flowBuilder.setMatch(matchBuilder.build());
flowBuilder.setPriority(DEFAULT_FLOW_PRIORITY);
flowBuilder.setBarrier(true);
- flowBuilder.setTableId((short) this.getTable());
+ flowBuilder.setTableId(this.getTable());
flowBuilder.setKey(key);
removeFlow(flowBuilder, nodeBuilder);
}