import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
-
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import org.apache.commons.lang3.StringUtils;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
import org.opendaylight.netvirt.fibmanager.api.FibHelper;
import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.AddressFamily;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.VrfEntryBase.EncapType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTablesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.macvrfentries.MacVrfEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.macvrfentries.MacVrfEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.macvrfentries.MacVrfEntryKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntryBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntryKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+@Singleton
public class FibDSWriter {
private static final Logger LOG = LoggerFactory.getLogger(FibDSWriter.class);
private final DataBroker dataBroker;
private final SingleTransactionDataBroker singleTxDB;
+ private final BgpUtil bgpUtil;
- public FibDSWriter(final DataBroker dataBroker) {
+ @Inject
+ public FibDSWriter(final DataBroker dataBroker, final BgpUtil bgpUtil) {
this.dataBroker = dataBroker;
+ this.bgpUtil = bgpUtil;
this.singleTxDB = new SingleTransactionDataBroker(dataBroker);
}
.child(VrfEntry.class, new VrfEntryKey(prefix)).build();
VrfEntryBuilder vrfEntryBuilder = new VrfEntryBuilder().setDestPrefix(prefix).setOrigin(origin.getValue());
- buildVpnEncapSpecificInfo(vrfEntryBuilder, encapType, (long)label, l3vni, macAddress,
+ buildVpnEncapSpecificInfo(vrfEntryBuilder, encapType, label, l3vni, macAddress,
gatewayMacAddress, nextHopList);
- BgpUtil.update(dataBroker, LogicalDatastoreType.CONFIGURATION, vrfEntryId, vrfEntryBuilder.build());
+ bgpUtil.update(LogicalDatastoreType.CONFIGURATION, vrfEntryId, vrfEntryBuilder.build());
+ }
+
+ public void addMacEntryToDS(String rd, String macAddress, String prefix,
+ List<String> nextHopList, VrfEntry.EncapType encapType,
+ long l2vni, String gatewayMacAddress, RouteOrigin origin) {
+ if (StringUtils.isEmpty(rd)) {
+ LOG.error("Mac {} not associated with vpn", macAddress);
+ return;
+ }
+
+ Preconditions.checkNotNull(nextHopList, "NextHopList can't be null");
+ for (String nextHop : nextHopList) {
+ if (StringUtils.isEmpty(nextHop)) {
+ LOG.error("nextHop list contains null element for macVrf");
+ return;
+ }
+ }
+
+ MacVrfEntryBuilder macEntryBuilder = new MacVrfEntryBuilder().setOrigin(origin.getValue());
+ buildVpnEncapSpecificInfo(macEntryBuilder, encapType, l2vni, macAddress,
+ gatewayMacAddress, nextHopList);
+ macEntryBuilder.setMac(macAddress);
+ macEntryBuilder.setDestPrefix(prefix);
+ InstanceIdentifier<MacVrfEntry> macEntryId =
+ InstanceIdentifier.builder(FibEntries.class)
+ .child(VrfTables.class, new VrfTablesKey(rd))
+ .child(MacVrfEntry.class, new MacVrfEntryKey(macAddress)).build();
+ bgpUtil.update(LogicalDatastoreType.CONFIGURATION, macEntryId, macEntryBuilder.build());
}
private static void buildVpnEncapSpecificInfo(VrfEntryBuilder builder,
builder.setGatewayMacAddress(gatewayMac);
Long lbl = encapType.equals(VrfEntry.EncapType.Mplsgre) ? label : null;
List<RoutePaths> routePaths = nextHopList.stream()
- .filter(nextHop -> nextHop != null && !nextHop.isEmpty())
- .map(nextHop -> {
- return FibHelper.buildRoutePath(nextHop, lbl);
- }).collect(Collectors.toList());
+ .filter(StringUtils::isNotEmpty)
+ .map(nextHop -> FibHelper.buildRoutePath(nextHop, lbl)).collect(Collectors.toList());
+ builder.setRoutePaths(routePaths);
+ }
+
+ private static void buildVpnEncapSpecificInfo(MacVrfEntryBuilder builder,
+ VrfEntry.EncapType encapType, long l2vni, String macAddress,
+ String gatewayMac, List<String> nextHopList) {
+ builder.setEncapType(encapType);
+ builder.setGatewayMacAddress(gatewayMac);
+ builder.setL2vni(l2vni);
+ List<RoutePaths> routePaths = nextHopList.stream()
+ .filter(StringUtils::isNotEmpty)
+ .map(nextHop -> FibHelper.buildRoutePath(nextHop, null)).collect(Collectors.toList());
builder.setRoutePaths(routePaths);
}
InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).child(
VrfEntry.class, new VrfEntryKey(prefix));
InstanceIdentifier<VrfEntry> vrfEntryId = idBuilder.build();
- BgpUtil.delete(dataBroker, LogicalDatastoreType.CONFIGURATION, vrfEntryId);
+ bgpUtil.delete(LogicalDatastoreType.CONFIGURATION, vrfEntryId);
+
+ }
+
+ public void removeMacEntryFromDS(String rd, String macAddress) {
+
+ if (StringUtils.isEmpty(rd)) {
+ LOG.error("Mac {} not associated with vpn", macAddress);
+ return;
+ }
+ LOG.debug("Removing Mac fib entry with Mac {} from vrf table for rd {}", macAddress, rd);
+
+ InstanceIdentifierBuilder<MacVrfEntry> idBuilder =
+ InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).child(
+ MacVrfEntry.class, new MacVrfEntryKey(macAddress));
+ InstanceIdentifier<MacVrfEntry> macEntryId = idBuilder.build();
+ bgpUtil.delete(LogicalDatastoreType.CONFIGURATION, macEntryId);
}
Optional<VrfEntry> existingVrfEntry =
singleTxDB.syncReadOptional(LogicalDatastoreType.CONFIGURATION, vrfEntryId);
List<RoutePaths> routePaths =
- existingVrfEntry.transform(VrfEntry::getRoutePaths).or(Collections.EMPTY_LIST);
+ existingVrfEntry.toJavaUtil().map(VrfEntry::getRoutePaths).orElse(Collections.emptyList());
if (routePaths.size() == 1) {
if (routePaths.get(0).getNexthopAddress().equals(nextHop)) {
- BgpUtil.delete(dataBroker, LogicalDatastoreType.CONFIGURATION, vrfEntryId);
+ bgpUtil.delete(LogicalDatastoreType.CONFIGURATION, vrfEntryId);
}
} else {
routePaths.stream()
- .map(routePath -> routePath.getNexthopAddress())
+ .map(RoutePaths::getNexthopAddress)
.filter(nextHopAddress -> nextHopAddress.equals(nextHop))
.findFirst()
.ifPresent(nh -> {
InstanceIdentifier<RoutePaths> routePathId =
FibHelper.buildRoutePathId(rd, prefix, nextHop);
- BgpUtil.delete(dataBroker, LogicalDatastoreType.CONFIGURATION,
- routePathId);
+ bgpUtil.delete(LogicalDatastoreType.CONFIGURATION, routePathId);
});
}
} catch (ReadFailedException e) {
}
}
+
+ public synchronized void removeVrfSubFamilyFromDS(String rd, AddressFamily addressFamily) {
+
+ if (rd == null) {
+ return;
+ }
+ LOG.debug("removeVrfSubFamilyFromDS : addressFamily {} from vrf rd {}",
+ addressFamily, rd);
+
+ InstanceIdentifier<VrfTables> id = InstanceIdentifier.create(FibEntries.class)
+ .child(VrfTables.class, new VrfTablesKey(rd));
+ try {
+ VrfTables vrfTable = singleTxDB.syncRead(LogicalDatastoreType.CONFIGURATION, id);
+ if (vrfTable != null) {
+ List<VrfEntry> vrfEntries = vrfTable.getVrfEntry();
+ if (vrfEntries == null) {
+ String errMsg = "removeVrfSubFamilyFromDS : VrfEntry not found for rd " + rd;
+ LOG.error(errMsg);
+ return;
+ }
+ for (VrfEntry vrfEntry : vrfEntries) {
+ boolean found = false;
+ if (vrfEntry.getEncapType() != null) {
+ if (!vrfEntry.getEncapType().equals(EncapType.Mplsgre)
+ && addressFamily == AddressFamily.L2VPN) {
+ found = true;
+ } else if (vrfEntry.getEncapType().equals(EncapType.Mplsgre)) {
+ if (addressFamily == AddressFamily.IPV4
+ && FibHelper.isIpv4Prefix(vrfEntry.getDestPrefix())) {
+ found = true;
+ } else if (addressFamily == AddressFamily.IPV6
+ && FibHelper.isIpv6Prefix(vrfEntry.getDestPrefix())) {
+ found = true;
+ }
+ }
+ }
+ if (found == false) {
+ continue;
+ }
+ bgpUtil.removeVrfEntry(rd, vrfEntry);
+ }
+ }
+ } catch (ReadFailedException rfe) {
+ String errMsg = "removeVrfSubFamilyFromDS : Internal Error rd " + rd;
+ LOG.error(errMsg, rfe);
+ }
+ return;
+ }
+
public synchronized void removeVrfFromDS(String rd) {
LOG.debug("Removing vrf table for rd {}", rd);
InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd));
InstanceIdentifier<VrfTables> vrfTableId = idBuilder.build();
- BgpUtil.delete(dataBroker, LogicalDatastoreType.CONFIGURATION, vrfTableId);
+ bgpUtil.delete(LogicalDatastoreType.CONFIGURATION, vrfTableId);
}
}