+ return Futures.immediateFuture(null);
+ }
+ InstanceIdentifier<L2> l2Iid =
+ interfaceIid.builder().augmentation(VppInterfaceAugmentation.class).child(L2.class).build();
+ Optional<L2> optL2 = GbpNetconfTransaction.read(vppNodeIid, LogicalDatastoreType.CONFIGURATION,
+ l2Iid, GbpNetconfTransaction.RETRY_COUNT);
+ L2Builder l2Builder = (optL2.isPresent()) ? new L2Builder(optL2.get()) : new L2Builder();
+ L2 l2 = l2Builder.setInterconnection(new BridgeBasedBuilder()
+ .setBridgeDomain(bridgeDomainName)
+ .setBridgedVirtualInterface(enableBvi)
+ .build()).build();
+ LOG.debug("Adding bridge domain {} to interface {}", bridgeDomainName, interfacePath);
+ LOG.info("Debugging L2: iid={}, data={}", l2Iid, l2);
+ final boolean transactionState = GbpNetconfTransaction.netconfSyncedWrite(vppNodeIid, l2Iid, l2,
+ GbpNetconfTransaction.RETRY_COUNT);
+ if (transactionState) {
+ LOG.debug("Adding bridge domain {} to interface {} successful", bridgeDomainName, interfacePath);
+ Set<String> excludedIfaces = excludedFromPolicy.get(vppNodeIid.firstKeyOf(Node.class).getNodeId());
+ if (!isExcludedFromPolicy(vppNodeIid.firstKeyOf(Node.class).getNodeId(),
+ interfaceIid.firstKeyOf(Interface.class).getName())) {
+ // can apply ACLs on interfaces in bridge domains
+ aclWrappers.forEach(aclWrapper -> {
+ LOG.debug("Writing access list for interface {} on a node {}.", interfaceIid, vppNodeIid);
+ aclWrapper.writeAcl(vppNodeIid, interfaceIid.firstKeyOf(Interface.class));
+ aclWrapper.writeAclRefOnIface(vppNodeIid, interfaceIid);
+ });
+ }
+ String bridgeDomainPath = VppPathMapper.bridgeDomainToRestPath(bridgeDomainName);
+ return vppEndpointLocationProvider.replaceLocationForEndpoint(new ExternalLocationCaseBuilder()
+ .setExternalNode(bridgeDomainPath)
+ .setExternalNodeMountPoint(vppNodeIid)
+ .setExternalNodeConnector(interfacePath)
+ .build(), addrEpWithLoc.getKey());
+ } else {
+ final String message =
+ "Adding bridge domain " + bridgeDomainName + " to interface " + interfacePath + " failed";
+ LOG.warn(message);
+ return Futures.immediateFailedFuture(new VppRendererProcessingException(message));
+ }
+ }
+
+ public boolean isExcludedFromPolicy(@Nonnull NodeId nodeId,@Nonnull String interfaceName) {
+ Set<String> excludedIfaces = excludedFromPolicy.get(nodeId);
+ if(excludedIfaces != null && excludedIfaces.contains(interfaceName)) {
+ return true;
+ }
+ return false;
+ }
+
+ public ListenableFuture<Void> configureInterface(InstanceIdentifier<Node> vppIid, InterfaceKey ifaceKey,
+ @Nullable String bridgeDomainName, @Nullable Boolean enableBvi) {
+ L2Builder l2Builder = readL2ForInterface(vppIid, ifaceKey);
+ L2 l2 = l2Builder.setInterconnection(new BridgeBasedBuilder()
+ .setBridgeDomain(bridgeDomainName)
+ .setBridgedVirtualInterface(enableBvi)
+ .build()).build();
+ final boolean transactionState = GbpNetconfTransaction.netconfSyncedWrite(vppIid,
+ VppIidFactory.getL2ForInterfaceIid(ifaceKey), l2, GbpNetconfTransaction.RETRY_COUNT);
+ if (transactionState) {
+ LOG.debug("Adding bridge domain {} to interface {}", bridgeDomainName,
+ VppIidFactory.getInterfaceIID(ifaceKey));
+ return Futures.immediateFuture(null);
+ } else {
+ final String message = "Failed to add bridge domain " + bridgeDomainName + " to interface "
+ + VppIidFactory.getInterfaceIID(ifaceKey);
+ LOG.warn(message);
+ return Futures.immediateFailedFuture(new VppRendererProcessingException(message));
+ }
+ }
+
+ public ListenableFuture<Void> removeInterfaceFromBridgeDomain(InstanceIdentifier<Node> vppIid,
+ InterfaceKey ifaceKey) {
+ L2Builder l2Builder = readL2ForInterface(vppIid, ifaceKey);
+ if (l2Builder.getInterconnection() == null || !(l2Builder.getInterconnection() instanceof BridgeBased)) {
+ LOG.warn("Interface already not in bridge domain {} ", ifaceKey);
+ return Futures.immediateFuture(null);
+ }
+ final boolean transactionState = GbpNetconfTransaction.netconfSyncedDelete(vppIid,
+ VppIidFactory.getL2ForInterfaceIid(ifaceKey), GbpNetconfTransaction.RETRY_COUNT);
+ if (transactionState) {
+ LOG.debug("Removing bridge domain from interface {}", VppIidFactory.getInterfaceIID(ifaceKey));
+ return Futures.immediateFuture(null);
+ } else {
+ final String message = "Failed to remove bridge domain from interface "
+ + VppIidFactory.getInterfaceIID(ifaceKey);
+ LOG.warn(message);
+ return Futures.immediateFailedFuture(new VppRendererProcessingException(message));
+ }
+ }
+
+ private L2Builder readL2ForInterface(InstanceIdentifier<Node> vppIid, InterfaceKey ifaceKey) {
+ InstanceIdentifier<L2> l2Iid = VppIidFactory.getL2ForInterfaceIid(ifaceKey);
+ final ReadOnlyTransaction rwTxRead = VbdNetconfTransaction.NODE_DATA_BROKER_MAP.get(vppIid).getKey()
+ .newReadOnlyTransaction();
+ Optional<L2> optL2 = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, l2Iid, rwTxRead);
+ rwTxRead.close();
+ return (optL2.isPresent()) ? new L2Builder(optL2.get()) : new L2Builder();