X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=neutron%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fovsdb%2Fneutron%2Fprovider%2FOF13ProviderManager.java;h=f42c6a5dc1605e92a7f30dc8017bb111996c7d8d;hb=2d6df58c7a9c108b36fc1e1bc51983493b944e3a;hp=d1e98732ca541e3cc72d86183bbcfaa79f26b7f2;hpb=ea2947920d8921da42734578c95b24e6605ebbad;p=ovsdb.git diff --git a/neutron/src/main/java/org/opendaylight/ovsdb/neutron/provider/OF13ProviderManager.java b/neutron/src/main/java/org/opendaylight/ovsdb/neutron/provider/OF13ProviderManager.java index d1e98732c..f42c6a5dc 100644 --- a/neutron/src/main/java/org/opendaylight/ovsdb/neutron/provider/OF13ProviderManager.java +++ b/neutron/src/main/java/org/opendaylight/ovsdb/neutron/provider/OF13ProviderManager.java @@ -9,12 +9,63 @@ */ package org.opendaylight.ovsdb.neutron.provider; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import org.opendaylight.controller.md.sal.common.api.TransactionStatus; +import org.opendaylight.controller.md.sal.common.api.data.DataModification; +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.ovsdb.lib.table.Bridge; import org.opendaylight.ovsdb.lib.table.Interface; +import org.opendaylight.ovsdb.neutron.AdminConfigManager; +import org.opendaylight.ovsdb.neutron.IMDSALConsumer; +import org.opendaylight.ovsdb.plugin.OVSDBConfigService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +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.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.NodeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.RpcResult; + +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.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; +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.model.match.types.rev131026.match.EthernetMatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder; +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.output.action._case.OutputActionBuilder; +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.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey; class OF13ProviderManager extends ProviderNetworkManager { + private static final Logger logger = LoggerFactory.getLogger(OF13ProviderManager.class); + private DataBrokerService dataBrokerService; + @Override public boolean hasPerTenantTunneling() { return false; @@ -34,9 +85,136 @@ class OF13ProviderManager extends ProviderNetworkManager { @Override public void initializeFlowRules(Node node) { + this.initializeFlowRules(node, AdminConfigManager.getManager().getIntegrationBridgeName()); + } + + private void initializeFlowRules(Node node, String bridgeName) { + try { + // 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. + Thread.sleep(3000); + } catch (Exception e) { + e.printStackTrace(); + } + String brIntId = this.getInternalBridgeUUID(node, bridgeName); + if (brIntId == null) { + logger.error("Failed to initialize Flow Rules for {}", node); + return; + } + + try { + OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this); + Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brIntId); + Set dpids = bridge.getDatapath_id(); + if (dpids == null || dpids.size() == 0) return; + Long dpidLong = Long.valueOf(HexEncode.stringToLong((String)dpids.toArray()[0])); + writeLLDPRule(dpidLong); + } catch (Exception e) { + logger.error("Failed to initialize Flow Rules for "+node.toString(), e); + } + } + + private void writeLLDPRule(Long dpidLong) { + String nodeName = "openflow:"+dpidLong; + NodeBuilder tn = createNodeBuilder(nodeName); + FlowBuilder flow = new FlowBuilder(); + flow.setMatch(createLLDPMatch().build()); + flow.setInstructions(this.createSentToControllerInstructions().build()); + // TODO : Investigate the need for this. + FlowKey key = new FlowKey(new FlowId(new Long(123))); + flow.setBarrier(false); + flow.setTableId((short)0); + flow.setKey(key); + flow.setFlowName("LLDP_" + nodeName); + writeFlow(flow, tn); + } + + private void writeFlow(FlowBuilder flow, 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; + } + + dataBrokerService = mdsalConsumer.getDataBrokerService(); + + if (dataBrokerService == null) { + logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller."); + return; + } + DataModification, DataObject> modification = dataBrokerService.beginTransaction(); + InstanceIdentifier 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(flow.getTableId())).child(Flow.class, flow.getKey()) + .build(); + modification.putOperationalData(nodeBuilderToInstanceId(nodeBuilder), nodeBuilder.build()); + modification.putOperationalData(path1, flow.build()); + modification.putConfigurationData(nodeBuilderToInstanceId(nodeBuilder), nodeBuilder.build()); + modification.putConfigurationData(path1, flow.build()); + Future> commitFuture = modification.commit(); + try { + RpcResult result = commitFuture.get(); + TransactionStatus status = result.getResult(); + } catch (InterruptedException e) { + logger.error(e.getMessage(), e); + } catch (ExecutionException e) { + logger.error(e.getMessage(), e); + } + } + + private static MatchBuilder createLLDPMatch() { + MatchBuilder match = new MatchBuilder(); + EthernetMatchBuilder eth = new EthernetMatchBuilder(); + EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder(); + ethTypeBuilder.setType(new EtherType(0x88CCL)); + eth.setEthernetType(ethTypeBuilder.build()); + match.setEthernetMatch(eth.build()); + return match; + } + + private InstructionsBuilder createSentToControllerInstructions() { + List actionList = new ArrayList(); + ActionBuilder ab = new ActionBuilder(); + + OutputActionBuilder output = new OutputActionBuilder(); + output.setMaxLength(56); + Uri value = new Uri("CONTROLLER"); + output.setOutputNodeConnector(value); + ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build()); + ab.setOrder(0); + ab.setKey(new ActionKey(0)); + actionList.add(ab.build()); + // Create an Apply Action + ApplyActionsBuilder aab = new ApplyActionsBuilder(); + aab.setAction(actionList); + + // Wrap our Apply Action in an Instruction + InstructionBuilder ib = new InstructionBuilder(); + ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build()); + ib.setOrder(0); + ib.setKey(new InstructionKey(0)); + + // Put our Instruction in a list of Instructions + InstructionsBuilder isb = new InstructionsBuilder(); + List instructions = new ArrayList(); + instructions.add(ib.build()); + isb.setInstruction(instructions); + return isb; } @Override public void initializeOFFlowRules(Node openflowNode) { } + + private NodeBuilder createNodeBuilder(String nodeId) { + NodeBuilder builder = new NodeBuilder(); + builder.setId(new NodeId(nodeId)); + builder.setKey(new NodeKey(builder.getId())); + return builder; + } + + private InstanceIdentifier nodeBuilderToInstanceId(NodeBuilder node) { + return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class, node.getKey()).toInstance(); + } }