import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.renderer.forwarding.by.tenant.RendererNetworkDomainKey;
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.groupbasedpolicy.vpp_renderer.rev160425.config.GbpBridgeDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.GbpBridgeDomainKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint.InterfaceTypeChoice;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.LoopbackCase;
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.v3po.rev161214.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;
private static final Logger LOG = LoggerFactory.getLogger(ForwardingManager.class);
@VisibleForTesting
- static long WAIT_FOR_BD_CREATION = 10; // seconds
+ private byte WAIT_FOR_BD_PROCESSING = 60; // seconds
private long lastVxlanVni = 1L;
private final Map<String, VxlanVni> vxlanVniByBridgeDomain = new HashMap<>();
private final InterfaceManager ifaceManager;
this.dataBroker = Preconditions.checkNotNull(dataBroker);
}
- public Optional<BridgeDomain> readBridgeDomainConfig(String name) {
- InstanceIdentifier<BridgeDomain> bdIid = InstanceIdentifier.builder(Config.class)
- .child(BridgeDomain.class, new BridgeDomainKey(name))
+ public Optional<GbpBridgeDomain> readGbpBridgeDomainConfig(String name) {
+ InstanceIdentifier<GbpBridgeDomain> bdIid = InstanceIdentifier.builder(Config.class)
+ .child(GbpBridgeDomain.class, new GbpBridgeDomainKey(name))
.build();
ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
return DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, bdIid, rTx);
public void createBridgeDomainOnNodes(SetMultimap<String, NodeId> vppNodesByBridgeDomain) {
for (String bd : vppNodesByBridgeDomain.keySet()) {
- Optional<BridgeDomain> bdConfig = readBridgeDomainConfig(bd);
+ Optional<GbpBridgeDomain> bdConfig = readGbpBridgeDomainConfig(bd);
Set<NodeId> vppNodes = vppNodesByBridgeDomain.get(bd);
if (bdConfig.isPresent()) {
if (bdConfig.get().getType().equals(VlanNetwork.class)) {
}
}
- private void createVxlanBridgeDomains(String bd, VxlanVni vni, Set<NodeId> vppNodes) {
+ private void createVxlanBridgeDomains(final String bd, final VxlanVni vni, final Set<NodeId> vppNodes) {
for (NodeId vppNode : vppNodes) {
try {
LOG.debug("Creating VXLAN bridge-domain {} on node {} with VNI {}", bd, vppNode.getValue(),
vni);
- // TODO think about propagating ListenableFuture - timeout set as workaround
- bdManager.createVxlanBridgeDomainOnVppNode(bd, vni, vppNode).get(WAIT_FOR_BD_CREATION,
+ bdManager.createVxlanBridgeDomainOnVppNode(bd, vni, vppNode).get(WAIT_FOR_BD_PROCESSING,
TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException e) {
LOG.warn("VXLAN Bridge domain {} was not created on node {}", bd, vppNode.getValue(), e);
} catch (TimeoutException e) {
LOG.warn("Probably, VXLAN Bridge domain {} was not created on node {} because BridgeDomainManager "
- + "did not respond by {} seconds.", bd, vppNode.getValue(), WAIT_FOR_BD_CREATION, e);
+ + "did not respond by {} seconds. Check VBD log for more details",
+ bd, vppNode.getValue(), WAIT_FOR_BD_PROCESSING, e);
}
}
}
- private void createVlanBridgeDomains(String bd, VlanId vlanId, Set<NodeId> vppNodes) {
+ private void createVlanBridgeDomains(final String bd, final VlanId vlanId, final Set<NodeId> vppNodes) {
for (NodeId vppNode : vppNodes) {
try {
LOG.debug("Creating VLAN bridge-domain {} on node {} with VLAN ID {}", bd, vppNode.getValue(),
vlanId.getValue());
- // TODO think about propagating ListenableFuture - timeout set as workaround
- bdManager.createVlanBridgeDomainOnVppNode(bd, vlanId, vppNode).get(WAIT_FOR_BD_CREATION,
+ bdManager.createVlanBridgeDomainOnVppNode(bd, vlanId, vppNode).get(WAIT_FOR_BD_PROCESSING,
TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException e) {
LOG.warn("VLAN Bridge domain {} was not created on node {}", bd, vppNode.getValue(), e);
} catch (TimeoutException e) {
LOG.warn("Probably, VLAN Bridge domain {} was not created on node {} because BridgeDomainManager "
- + "did not respond by {} seconds.", bd, vppNode.getValue(), WAIT_FOR_BD_CREATION, e);
+ + "did not respond by {} seconds. Check VBD log for more details",
+ bd, vppNode.getValue(), WAIT_FOR_BD_PROCESSING, e);
}
}
}
- public void removeBridgeDomainOnNodes(SetMultimap<String, NodeId> vppNodesByBridgeDomain) {
+ public void removeBridgeDomainOnNodes(final SetMultimap<String, NodeId> vppNodesByBridgeDomain) {
for (String bd : vppNodesByBridgeDomain.keySet()) {
Set<NodeId> vppNodes = vppNodesByBridgeDomain.get(bd);
for (NodeId vppNode : vppNodes) {
try {
- bdManager.removeBridgeDomainFromVppNode(bd, vppNode).get(WAIT_FOR_BD_CREATION,
+ bdManager.removeBridgeDomainFromVppNode(bd, vppNode).get(WAIT_FOR_BD_PROCESSING,
TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException e) {
LOG.warn("Bridge domain {} was not removed from node {}", bd, vppNode.getValue(), e);
} catch (TimeoutException e) {
LOG.warn("Probably, bridge domain {} was not removed from node {} because BridgeDomainManager "
- + "did not respond by {} seconds.", bd, vppNode.getValue(), WAIT_FOR_BD_CREATION, e);
+ + "did not respond by {} seconds. Check VBD log for more details",
+ bd, vppNode.getValue(), WAIT_FOR_BD_PROCESSING, e);
}
}
}
ExternalLocationCase rEpLoc = resolveAndValidateLocation(rEp);
if (Strings.isNullOrEmpty(rEpLoc.getExternalNodeConnector())) {
// TODO add it to the status for renderer manager
- LOG.info("Rednerer endpoint does not have external-node-connector therefore it is ignored {}", rEp);
+ LOG.info("Renderer endpoint does not have external-node-connector therefore it is ignored {}", rEp);
return;
}
java.util.Optional<String> optL2FloodDomain = resolveL2FloodDomain(rEp, policyCtx);
if (!optL2FloodDomain.isPresent()) {
// TODO add it to the status for renderer manager
- LOG.info("Rednerer endpoint does not have l2FloodDomain as network containment {}", rEp);
+ LOG.info("Renderer endpoint does not have l2FloodDomain as network containment {}", rEp);
return;
}
String l2FloodDomain = optL2FloodDomain.get();
try {
- ifaceManager.addBridgeDomainToInterface(l2FloodDomain, rEp).get();
+ ifaceManager.addBridgeDomainToInterface(l2FloodDomain, rEp, isBviForEndpoint(rEp)).get();
LOG.debug("Interface added to bridge-domain {} for endpoint {}", l2FloodDomain, rEp);
} catch (InterruptedException | ExecutionException e) {
// TODO add it to the status for renderer manager
LOG.warn("Interface was not added to bridge-domain {} for endpoint {}", l2FloodDomain, rEp, e);
}
} else {
- LOG.debug("Forwarding is not created - Location of renderer endpoint contains "
+ LOG.warn("Forwarding is not created - Location of renderer endpoint contains "
+ "external-node therefore VPP renderer assumes that interface for endpoint is "
+ "already assigned in bridge-domain representing external-node. {}", rEp);
}
}
+ private boolean isBviForEndpoint(AddressEndpointWithLocation rEp) {
+ VppEndpointKey vppEndpointKey =
+ new VppEndpointKey(rEp.getAddress(), rEp.getAddressType(), rEp.getContextId(), rEp.getContextType());
+ ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
+ Optional<VppEndpoint> vppEndpointOptional =
+ DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
+ InstanceIdentifier.builder(Config.class).child(VppEndpoint.class, vppEndpointKey).build(), rTx);
+ if (vppEndpointOptional.isPresent()) {
+ InterfaceTypeChoice interfaceTypeChoice = vppEndpointOptional.get().getInterfaceTypeChoice();
+ if (interfaceTypeChoice instanceof LoopbackCase) {
+ LOG.trace("Vpp renderer endpoint {} IS a BVI interface.", rEp.getKey());
+ return ((LoopbackCase) interfaceTypeChoice).isBvi();
+ }
+ }
+ rTx.close();
+ LOG.trace("Vpp renderer endpoint {} IS NOT a BVI interface.", rEp.getKey());
+ return false;
+ }
+
public void removeForwardingForEndpoint(RendererEndpointKey rEpKey, PolicyContext policyCtx) {
AddressEndpointWithLocation rEp = policyCtx.getAddrEpByKey().get(KeyFactory.addressEndpointKey(rEpKey));
ExternalLocationCase rEpLoc = resolveAndValidateLocation(rEp);
// nothing was created for endpoint therefore nothing is removed
return;
}
-
if (!Strings.isNullOrEmpty(rEpLoc.getExternalNode())) {
try {
ifaceManager.deleteBridgeDomainFromInterface(rEp).get();
LOG.warn("bridge-domain was not deleted from interface for endpoint {}", rEp, e);
}
} else {
- LOG.debug("Forwarding is not removed - Location of renderer endpoint does not contain "
+ LOG.warn("Forwarding is not removed - Location of renderer endpoint does not contain "
+ "external-node therefore VPP renderer assumes that interface for endpoint is not "
+ "assigned to bridge-domain representing external-node. {}", rEp);
}
.map(RendererForwardingContext::getContextId)
.map(ContextId::getValue);
if (!optL2Fd.isPresent()) {
- LOG.info("network-domain-containment in endpoint does not have L2-flood-domain as parent. "
+ LOG.warn("network-domain-containment in endpoint does not have L2-flood-domain as parent. "
+ "This case is not supported in VPP renderer. {}", ep);
}
return optL2Fd;
return java.util.Optional.empty();
}
- public static @Nonnull java.util.Optional<RendererForwardingContext> getForwardingCtxForParent(
+ private static @Nonnull java.util.Optional<RendererForwardingContext> getForwardingCtxForParent(
@Nullable TenantId tenant, @Nullable Parent parent,
Table<TenantId, RendererForwardingContextKey, RendererForwardingContext> forwardingCtxTable) {
if (tenant == null || parent == null) {
return java.util.Optional.empty();
}
+ @VisibleForTesting
+ void setTimer(byte time) {
+ WAIT_FOR_BD_PROCESSING = time;
+ }
}