EventBus dtoEventBus = new EventBus("DTO events");
interfaceManager = new InterfaceManager(mountDataProvider, dataBroker, NETCONF_WORKER);
dtoEventBus.register(interfaceManager);
- ForwardingManager fwManager = new ForwardingManager(interfaceManager, new BridgeDomainManagerImpl(dataBroker));
+ ForwardingManager fwManager = new ForwardingManager(interfaceManager, new BridgeDomainManagerImpl(dataBroker), dataBroker);
vppRendererPolicyManager = new VppRendererPolicyManager(fwManager, dataBroker);
dtoEventBus.register(vppRendererPolicyManager);
import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanVni;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
/**
* Creates a bridge domain on VPP node and it also adds tunnels of the bridge domain to VXLAN
* full mesh topology
- *
+ *
* @param bridgeDomainName name of bridge domain
* @param vni VXLAN VNI used in full mesh topology for the given bridge domain
- * @param vppNode VPP node where the bridge domain should be created
+ * @param vppNodeId VPP node where the bridge domain should be created
* @return {@link ListenableFuture}
*/
- ListenableFuture<Void> createVxlanBridgeDomainOnVppNode(@Nonnull String bridgeDomainName, @Nonnull VxlanVni vni,
- NodeId vppNode);
+ ListenableFuture<Void> createVxlanBridgeDomainOnVppNode(@Nonnull String bridgeDomainName, VxlanVni vni, @Nonnull NodeId vppNodeId);
+
+ /**
+ * Creates a bridge domain on VPP node and it also adds tunnels of the bridge domain to VLAN
+ * full mesh topology
+ *
+ * @param bridgeDomainName name of bridge domain
+ * @param vlanId VLAN ID used in full mesh topology for the given bridge domain
+ * @param vppNodeId VPP node where the bridge domain should be created
+ * @return {@link ListenableFuture}
+ */
+
+ ListenableFuture<Void> createVlanBridgeDomainOnVppNode(@Nonnull String bridgeDomainName, @Nonnull VlanId vlanId, @Nonnull NodeId vppNodeId);
/**
* Removes a bridge domain from VPP node and it also removes tunnels of the bridge domain from
* VXLAN full mesh topology
- *
+ *
* @param bridgeDomainName name of bridge domain
* @param vppNode VPP node where the bridge domain should be removed from
* @return {@link ListenableFuture}
*/
ListenableFuture<Void> removeBridgeDomainFromVppNode(@Nonnull String bridgeDomainName, NodeId vppNode);
+
}
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.groupbasedpolicy.renderer.vpp.api.BridgeDomainManager;
import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.Config;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.BridgeDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.BridgeDomainKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.bridge.domain.PhysicalLocationRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanVni;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyTypesVbridgeAugment;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyTypesVbridgeAugmentBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyVbridgeAugment;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyVbridgeAugmentBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.topology.types.VbridgeTopologyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vlan.rev160429.NodeVbridgeVlanAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vlan.rev160429.NodeVbridgeVlanAugmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vlan.rev160429.TunnelTypeVlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vlan.rev160429.network.topology.topology.tunnel.parameters.VlanNetworkParametersBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vxlan.rev160429.TunnelTypeVxlan;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vxlan.rev160429.network.topology.topology.tunnel.parameters.VxlanTunnelParametersBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.TopologyTypes;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.TopologyTypesBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.node.attributes.SupportingNodeBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
}
@Override
- public ListenableFuture<Void> createVxlanBridgeDomainOnVppNode(@Nonnull String bridgeDomainName,
- @Nonnull VxlanVni vni, NodeId vppNode) {
+ public ListenableFuture<Void> createVxlanBridgeDomainOnVppNode(@Nonnull String bridgeDomainName, VxlanVni vni,
+ @Nonnull NodeId vppNodeId) {
+ TopologyVbridgeAugment topoAug = new TopologyVbridgeAugmentBuilder().setTunnelType(TunnelTypeVxlan.class)
+ .setArpTermination(false)
+ .setFlood(true)
+ .setForward(true)
+ .setLearn(true)
+ .setUnknownUnicastFlood(true)
+ .setTunnelParameters(new VxlanTunnelParametersBuilder().setVni(vni).build())
+ .build();
+ return createBridgeDomainOnVppNode(bridgeDomainName, topoAug, createBasicVppNodeBuilder(vppNodeId).build());
+ }
+
+ @Override
+ public ListenableFuture<Void> createVlanBridgeDomainOnVppNode(@Nonnull String bridgeDomainName,
+ @Nonnull VlanId vlanId, @Nonnull NodeId vppNodeId) {
+ TopologyVbridgeAugment topoAug = new TopologyVbridgeAugmentBuilder().setTunnelType(TunnelTypeVlan.class)
+ .setArpTermination(false)
+ .setFlood(true)
+ .setForward(true)
+ .setLearn(true)
+ .setUnknownUnicastFlood(true)
+ .setTunnelParameters(new VlanNetworkParametersBuilder().setVlanId(vlanId).build())
+ .build();
+ InstanceIdentifier<BridgeDomain> bridgeDomainConfigIid = InstanceIdentifier.builder(Config.class)
+ .child(BridgeDomain.class, new BridgeDomainKey(bridgeDomainName))
+ .build();
+ ReadOnlyTransaction rTx = dataProvder.newReadOnlyTransaction();
+ CheckedFuture<Optional<BridgeDomain>, ReadFailedException> futureTopology = rTx.read(
+ LogicalDatastoreType.CONFIGURATION, bridgeDomainConfigIid);
+ rTx.close();
+ return Futures.transform(futureTopology, new AsyncFunction<Optional<BridgeDomain>, Void>() {
+
+ @Override
+ public ListenableFuture<Void> apply(Optional<BridgeDomain> optBridgeDomainConf) throws Exception {
+ if (optBridgeDomainConf.isPresent() && optBridgeDomainConf.get().getPhysicalLocationRef() != null) {
+ for (PhysicalLocationRef ref : optBridgeDomainConf.get().getPhysicalLocationRef()) {
+ if (ref.getInterface() != null && ref.getInterface().size() > 0) {
+ NodeVbridgeVlanAugment vppNodeVlanAug = new NodeVbridgeVlanAugmentBuilder().setSuperInterface(
+ ref.getInterface().get(0)).build();
+ Node vppNode = createBasicVppNodeBuilder(vppNodeId).addAugmentation(vppNodeVlanAug.getClass(),
+ vppNodeVlanAug).build();
+ return createBridgeDomainOnVppNode(bridgeDomainName, topoAug, vppNode);
+ }
+ }
+ }
+ return Futures.immediateFailedFuture(new Throwable("Failed to apply config for VLAN bridge domain "
+ + bridgeDomainName));
+ }
+ });
+ }
+
+ private NodeBuilder createBasicVppNodeBuilder(NodeId nodeId) {
+ return new NodeBuilder().setNodeId(nodeId).setSupportingNode(
+ Arrays.asList(new SupportingNodeBuilder().setTopologyRef(SUPPORTING_TOPOLOGY_NETCONF)
+ .setNodeRef(nodeId)
+ .build()));
+ }
+
+ private ListenableFuture<Void> createBridgeDomainOnVppNode(@Nonnull String bridgeDomainName,
+ final TopologyVbridgeAugment vBridgeAug, Node vppNode) {
TopologyKey topologyKey = new TopologyKey(new TopologyId(bridgeDomainName));
ReadOnlyTransaction rTx = dataProvder.newReadOnlyTransaction();
- CheckedFuture<Optional<Topology>, ReadFailedException> futureTopology =
- rTx.read(LogicalDatastoreType.CONFIGURATION, VppIidFactory.getTopologyIid(topologyKey));
+ CheckedFuture<Optional<Topology>, ReadFailedException> futureTopology = rTx.read(
+ LogicalDatastoreType.CONFIGURATION, VppIidFactory.getTopologyIid(topologyKey));
rTx.close();
return Futures.transform(futureTopology, new AsyncFunction<Optional<Topology>, Void>() {
public ListenableFuture<Void> apply(Optional<Topology> optTopology) throws Exception {
WriteTransaction wTx = dataProvder.newWriteOnlyTransaction();
if (!optTopology.isPresent()) {
- TopologyVbridgeAugment vbridgeAugment =
- new TopologyVbridgeAugmentBuilder().setTunnelType(TunnelTypeVxlan.class)
- .setArpTermination(false)
- .setFlood(true)
- .setForward(true)
- .setLearn(true)
- .setUnknownUnicastFlood(true)
- .setTunnelParameters(new VxlanTunnelParametersBuilder().setVni(vni).build())
- .build();
Topology topology = new TopologyBuilder().setKey(topologyKey)
.setTopologyTypes(VBRIDGE_TOPOLOGY_TYPE)
- .addAugmentation(TopologyVbridgeAugment.class, vbridgeAugment)
+ .addAugmentation(TopologyVbridgeAugment.class, vBridgeAug)
.build();
-
wTx.put(LogicalDatastoreType.CONFIGURATION, VppIidFactory.getTopologyIid(topology.getKey()),
topology, true);
}
- Node node = new NodeBuilder().setNodeId(vppNode)
- .setSupportingNode(Arrays.asList(new SupportingNodeBuilder()
- .setTopologyRef(SUPPORTING_TOPOLOGY_NETCONF).setNodeRef(vppNode).build()))
- .build();
- wTx.put(LogicalDatastoreType.CONFIGURATION, VppIidFactory.getNodeIid(topologyKey, node.getKey()),
- node);
+ wTx.put(LogicalDatastoreType.CONFIGURATION, VppIidFactory.getNodeIid(topologyKey, vppNode.getKey()),
+ vppNode);
return wTx.submit();
}
});
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.groupbasedpolicy.renderer.vpp.api.BridgeDomainManager;
import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.manager.BridgeDomainManagerImpl;
import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory;
+import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.NetworkContainment;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.network.containment.Containment;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.network.containment.containment.ForwardingContextContainment;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L2FloodDomain;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.Config;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.VlanNetwork;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.BridgeDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.BridgeDomainKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanVni;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private final InterfaceManager ifaceManager;
private final BridgeDomainManager bdManager;
-
- public ForwardingManager(@Nonnull InterfaceManager ifaceManager, @Nonnull BridgeDomainManager bdManager) {
+ private final DataBroker dataBroker;
+ public ForwardingManager(@Nonnull InterfaceManager ifaceManager, @Nonnull BridgeDomainManager bdManager, @Nonnull DataBroker dataBroker) {
this.ifaceManager = Preconditions.checkNotNull(ifaceManager);
this.bdManager = Preconditions.checkNotNull(bdManager);
+ this.dataBroker = Preconditions.checkNotNull(dataBroker);
+ }
+
+ public Optional<BridgeDomain> readBridgeDomainConfig(String name) {
+ InstanceIdentifier<BridgeDomain> bdIid = InstanceIdentifier.builder(Config.class)
+ .child(BridgeDomain.class, new BridgeDomainKey(name))
+ .build();
+ ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
+ return DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, bdIid, rTx);
}
- public void createVxlanBridgeDomainsOnNodes(SetMultimap<String, NodeId> vppNodesByBridgeDomain) {
+ public void createBridgeDomainOnNodes(SetMultimap<String, NodeId> vppNodesByBridgeDomain) {
for (String bd : vppNodesByBridgeDomain.keySet()) {
+ Optional<BridgeDomain> bdConfig = readBridgeDomainConfig(bd);
Set<NodeId> vppNodes = vppNodesByBridgeDomain.get(bd);
- for (NodeId vppNode : vppNodes) {
- try {
- bdManager.createVxlanBridgeDomainOnVppNode(bd, null, vppNode).get();
- } catch (InterruptedException | ExecutionException e) {
- LOG.warn("Bridge domain {} was not created on node {}", bd, vppNode.getValue(), e);
+ if (bdConfig.isPresent()) {
+ if (bdConfig.get().getType().equals(VlanNetwork.class)) {
+ createVlanBridgeDomains(bd, bdConfig.get().getVlan(), vppNodes);
}
+ } else {
+ createVxlanBridgeDomains(bd, null, vppNodes);
+ }
+ }
+ }
+
+ private void createVxlanBridgeDomains(String bd, VxlanVni vni, Set<NodeId> vppNodes) {
+ for (NodeId vppNode : vppNodes) {
+ try {
+ bdManager.createVxlanBridgeDomainOnVppNode(bd, vni, vppNode).get();
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.warn("Bridge domain {} was not created on node {}", bd, vppNode.getValue(), e);
+ }
+ }
+ }
+
+ private void createVlanBridgeDomains(String bd, VlanId vlanId, Set<NodeId> vppNodes) {
+ for (NodeId vppNode : vppNodes) {
+ try {
+ bdManager.createVlanBridgeDomainOnVppNode(bd, vlanId, vppNode).get();
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.warn("Bridge domain {} was not created on node {}", bd, vppNode.getValue(), e);
}
}
}
- public void removeVxlanBridgeDomainsOnNodes(SetMultimap<String, NodeId> vppNodesByBridgeDomain) {
+ public void removeBridgeDomainOnNodes(SetMultimap<String, NodeId> vppNodesByBridgeDomain) {
for (String bd : vppNodesByBridgeDomain.keySet()) {
Set<NodeId> vppNodes = vppNodesByBridgeDomain.get(bd);
for (NodeId vppNode : vppNodes) {
SetView<RendererEndpointKey> removedRendEps = Sets.difference(rendEpsBefore, rendEpsAfter);
removedRendEps.forEach(rEpKey -> fwManager.removeForwardingForEndpoint(rEpKey, policyCtxBefore));
- fwManager.removeVxlanBridgeDomainsOnNodes(removedVppNodesByL2Fd);
- fwManager.createVxlanBridgeDomainsOnNodes(createdVppNodesByL2Fd);
+ fwManager.removeBridgeDomainOnNodes(removedVppNodesByL2Fd);
+ fwManager.createBridgeDomainOnNodes(createdVppNodesByL2Fd);
SetView<RendererEndpointKey> createdRendEps = Sets.difference(rendEpsAfter, rendEpsBefore);
createdRendEps.forEach(rEpKey -> fwManager.createForwardingForEndpoint(rEpKey, policyCtxAfter));
ImmutableSet<RendererEndpointKey> rEpKeys = policyCtx.getPolicyTable().rowKeySet();
SetMultimap<String, NodeId> vppNodesByL2Fd = resolveVppNodesByL2Fd(rEpKeys, policyCtx);
- fwManager.createVxlanBridgeDomainsOnNodes(vppNodesByL2Fd);
+ fwManager.createBridgeDomainOnNodes(vppNodesByL2Fd);
rEpKeys.forEach(rEpKey -> fwManager.createForwardingForEndpoint(rEpKey, policyCtx));
}
rEpKeys.forEach(rEpKey -> fwManager.removeForwardingForEndpoint(rEpKey, policyCtx));
SetMultimap<String, NodeId> vppNodesByL2Fd = resolveVppNodesByL2Fd(rEpKeys, policyCtx);
- fwManager.removeVxlanBridgeDomainsOnNodes(vppNodesByL2Fd);
+ fwManager.removeBridgeDomainOnNodes(vppNodesByL2Fd);
}
private static SetMultimap<String, NodeId> resolveVppNodesByL2Fd(Set<RendererEndpointKey> rEpKeys,
.thenReturn(Optional.of(mountPointDataBroker));
ifaceManager = new InterfaceManager(mountedDataProviderMock, dataBroker, MoreExecutors.newDirectExecutorService());
bdManager = new BridgeDomainManagerImpl(mountPointDataBroker);
- fwManager = new ForwardingManager(ifaceManager, bdManager);
+ fwManager = new ForwardingManager(ifaceManager, bdManager, dataBroker);
vppRendererPolicyManager = new VppRendererPolicyManager(fwManager, dataBroker);
}