*/
package org.opendaylight.netvirt.vpnmanager;
-import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
+import java.util.concurrent.ExecutionException;
import javax.inject.Inject;
import javax.inject.Singleton;
+import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
-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.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
import org.opendaylight.netvirt.fibmanager.api.IFibManager;
import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.SubnetOpDataEntryBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.SubnetOpDataEntryKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.SubnetToDpn;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.subnet.op.data.entry.SubnetToDpnKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
public class VpnSubnetRouteHandler {
private static final Logger LOG = LoggerFactory.getLogger(VpnSubnetRouteHandler.class);
private static final String LOGGING_PREFIX = "SUBNETROUTE:";
+ private static final String VPN_EVENT_SOURCE_SUBNET_ROUTE = "vpnSubnetRouteEvent";
private final DataBroker dataBroker;
private final SubnetOpDpnManager subOpDpnManager;
private final IBgpManager bgpManager;
}
String vpnName = subnetmap.getVpnId().getValue();
Uint32 vpnId = waitAndGetVpnIdIfInvalid(vpnName);
- if (vpnId.longValue() == VpnConstants.INVALID_ID) {
+ if (VpnConstants.INVALID_ID.equals(vpnId)) {
LOG.error(
"{} onSubnetAddedToVpn: VpnInstance to VPNId mapping not yet available for VpnName {} "
+ "processing subnet {} with IP {}, bailing out now.",
subOpBuilder.setSubnetToDpn(new ArrayList<>());
subOpBuilder.setRouteAdvState(TaskState.Idle);
subOpBuilder.setElanTag(elanTag);
- Long l3Vni = vpnInstanceOpData.getL3vni().toJava();
+ Long l3Vni = vpnInstanceOpData.getL3vni() != null ? vpnInstanceOpData.getL3vni().toJava() : 0L;
subOpBuilder.setL3vni(l3Vni);
subOpEntry = subOpBuilder.build();
SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, subOpIdentifier,
LOG.error("{} onSubnetAddedToVpn: Unable to handle subnet {} with ip {} added to vpn {}", LOGGING_PREFIX,
subnetId.getValue(), subnetIp, vpnName, e);
return;
- } catch (ReadFailedException e) {
+ } catch (InterruptedException | ExecutionException e) {
LOG.error("{} onSubnetAddedToVpn: Failed to read data store for subnet {} ip {} vpn {}", LOGGING_PREFIX,
subnetId, subnetIp, vpnName);
return;
} catch (RuntimeException e) {
LOG.error("{} onSubnetAddedToVpn: Unable to handle subnet {} with ip {} added to vpn {}", LOGGING_PREFIX,
subnetId.getValue(), subnetIp, vpnName, e);
- } catch (ReadFailedException e) {
+ } catch (InterruptedException | ExecutionException e) {
LOG.error("{} onSubnetAddedToVpn: Failed to read data store for subnet {} ip {} vpn {}", LOGGING_PREFIX,
subnetId, subnetIp, vpnName);
} catch (TransactionCommitFailedException ex) {
private Uint32 waitAndGetVpnIdIfInvalid(String vpnName) {
Uint32 vpnId = vpnUtil.getVpnId(vpnName);
- if (vpnId.longValue() == VpnConstants.INVALID_ID) {
+ if (VpnConstants.INVALID_ID.equals(vpnId)) {
LOG.debug("VpnId is invalid, waiting to fetch again: vpnName={}, vpnId={}", vpnName, vpnId);
vpnOpDataSyncer.waitForVpnDataReady(VpnOpDataType.vpnInstanceToId, vpnName,
VpnConstants.PER_VPN_INSTANCE_MAX_WAIT_TIME_IN_MILLISECONDS);
LOG.error("{} onSubnetDeletedFromVpn: Removal of SubnetOpDataEntry for subnet {} subnetIp {}"
+ " vpnId {} failed", LOGGING_PREFIX, subnetId.getValue(), subnetmap.getSubnetIp(),
subnetmap.getVpnId(), ex);
- } catch (ReadFailedException e) {
+ } catch (InterruptedException | ExecutionException e) {
LOG.error("{} onSubnetDeletedFromVpn: Failed to read data store for subnet {} ip {} vpn {}",
LOGGING_PREFIX, subnetId, subnetmap.getSubnetIp(), subnetmap.getVpnId());
} finally {
}
LOG.info("{} onSubnetUpdatedInVpn: subnet {} with Ip {} updated successfully for vpn {}", LOGGING_PREFIX,
subnetId.getValue(), subnetIp, vpnName);
- } catch (ReadFailedException e) {
+ } catch (InterruptedException | ExecutionException e) {
LOG.error("onSubnetUpdatedInVpn: Failed to read data store for subnet{} ip {} elanTag {} vpn {}",subnetId,
subnetIp, elanTag, vpnName);
}
}
SubnetOpDataEntry subnetOpDataEntry = optionalSubs.get();
SubnetOpDataEntryBuilder subOpBuilder = new SubnetOpDataEntryBuilder(subnetOpDataEntry);
- List<SubnetToDpn> subDpnList = subOpBuilder.getSubnetToDpn();
- subDpnList.add(subDpn);
- subOpBuilder.setSubnetToDpn(subDpnList);
+ subOpBuilder.setSubnetToDpn(concat(new ArrayList<SubnetToDpn>(subnetOpDataEntry.getSubnetToDpn().values()),
+ subDpn));
if (subOpBuilder.getRouteAdvState() != TaskState.Advertised) {
if (subOpBuilder.getNhDpnId() == null) {
// No nexthop selected yet, elect one now
} catch (RuntimeException e) { //TODO: Avoid this
LOG.error("{} onPortAddedToSubnet: Unable to handle port {} added to subnet {}", LOGGING_PREFIX,
portId.getValue(), subnetId.getValue(), e);
- } catch (ReadFailedException e) {
+ } catch (InterruptedException | ExecutionException e) {
LOG.error("{} onPortAddedToSubnet: Failed to read data store for port {} subnet {}", LOGGING_PREFIX,
portId, subnetId);
} catch (TransactionCommitFailedException e) {
} catch (RuntimeException e) {
LOG.error("{} onPortRemovedFromSubnet: Unable to handle port {} removed from subnet {}", LOGGING_PREFIX,
portId.getValue(), subnetId.getValue(), e);
- } catch (ReadFailedException e) {
+ } catch (InterruptedException | ExecutionException e) {
LOG.error("{} onPortRemovedFromSubnet: Failed to read data store for port {} subnet {}", LOGGING_PREFIX,
portId, subnetId);
} catch (TransactionCommitFailedException e) {
subOpBuilder.getRouteAdvState(), subOpBuilder.getLastAdvState());
boolean isExternalSubnetVpn = VpnUtil.isExternalSubnetVpn(subnetOpDataEntry.getVpnName(),
subnetId.getValue());
- List<SubnetToDpn> subDpnList = subOpBuilder.getSubnetToDpn();
- subDpnList.add(subDpn);
- subOpBuilder.setSubnetToDpn(subDpnList);
+ subOpBuilder.setSubnetToDpn(concat(new ArrayList<SubnetToDpn>(subnetOpDataEntry.getSubnetToDpn().values()),
+ subDpn));
if (subOpBuilder.getRouteAdvState() != TaskState.Advertised) {
if (subOpBuilder.getNhDpnId() == null) {
// No nexthop selected yet, elect one now
} catch (RuntimeException e) {
LOG.error("{} onInterfaceUp: Unable to handle interface up event for port {} in subnet {}",
LOGGING_PREFIX, intfName, subnetId.getValue(), e);
- } catch (ReadFailedException e) {
+ } catch (InterruptedException | ExecutionException e) {
LOG.error("{} onInterfaceUp: Failed to read data store for interface {} dpn {} subnet {}", LOGGING_PREFIX,
intfName, dpnId, subnetId);
} catch (TransactionCommitFailedException e) {
} catch (RuntimeException e) { //TODO: Remove RuntimeException
LOG.error("{} onInterfaceDown: Unable to handle interface down event for port {} in subnet {}",
LOGGING_PREFIX, interfaceName, subnetId.getValue(), e);
- } catch (ReadFailedException e) {
+ } catch (InterruptedException | ExecutionException e) {
LOG.error("{} onInterfaceDown: Failed to read data store for interface {} dpn {} subnet {}",
LOGGING_PREFIX, interfaceName, dpnId, subnetId.getValue(), e);
} catch (TransactionCommitFailedException ex) {
} catch (TransactionCommitFailedException ex) {
LOG.error("{} updateSubnetRouteOnTunnelUpEvent: Failed to update subnetRoute for subnet {} on dpn {}",
LOGGING_PREFIX, subnetId.getValue(), dpnId.toString(), ex);
- } catch (ReadFailedException e) {
+ } catch (InterruptedException | ExecutionException e) {
LOG.error("{} updateSubnetRouteOnTunnelUpEvent: Failed to read data store for subnet {} on dpn {}",
LOGGING_PREFIX, subnetId.getValue(), dpnId.toString(), e);
}
} catch (RuntimeException e) {
LOG.error("{} updateSubnetRouteOnTunnelDownEvent: Unable to handle tunnel down event for subnetId {}"
+ " dpnId {}", LOGGING_PREFIX, subnetId.getValue(), dpnId.toString(), e);
- } catch (ReadFailedException e) {
+ } catch (InterruptedException | ExecutionException e) {
LOG.error("{} Failed to read data store for subnet {} dpn {}", LOGGING_PREFIX, subnetId, dpnId);
} catch (TransactionCommitFailedException e) {
LOG.error("{} updateSubnetRouteOnTunnelDownEvent: Updation of SubnetOpDataEntry for subnet {}"
l3vni = subOpBuilder.getL3vni();
} else {
label = subOpBuilder.getLabel();
+ if (label.longValue() == VpnConstants.INVALID_LABEL) {
+ LOG.error("publishSubnetRouteToBgp: Label not found for rd {}, subnetIp {}",
+ subOpBuilder.getVrfId(), subOpBuilder.getSubnetCidr());
+ return;
+ }
}
bgpManager.advertisePrefix(subOpBuilder.getVrfId(), null /*macAddress*/, subOpBuilder.getSubnetCidr(),
Arrays.asList(nextHopIp), encapType, label, l3vni,
}
public void deleteSubnetRouteFibEntryFromDS(String rd, String prefix, String vpnName) {
- fibManager.removeFibEntry(rd, prefix, null);
+ fibManager.removeFibEntry(rd, prefix, VPN_EVENT_SOURCE_SUBNET_ROUTE, null);
List<VpnInstanceOpDataEntry> vpnsToImportRoute = vpnUtil.getVpnsImportingMyRoute(vpnName);
for (VpnInstanceOpDataEntry vpnInstance : vpnsToImportRoute) {
String importingRd = vpnInstance.getVrfId();
- fibManager.removeFibEntry(importingRd, prefix, null);
+ fibManager.removeFibEntry(importingRd, prefix, VPN_EVENT_SOURCE_SUBNET_ROUTE, null);
LOG.info("SUBNETROUTE: deleteSubnetRouteFibEntryFromDS: Deleted imported subnet route rd {} prefix {}"
+ " from vpn {} importingRd {}", rd, prefix, vpnInstance.getVpnInstanceName(), importingRd);
}
@SuppressWarnings("checkstyle:IllegalCatch")
private void electNewDpnForSubnetRoute(SubnetOpDataEntryBuilder subOpBuilder, @Nullable Uint64 oldDpnId,
Uuid subnetId, Uuid networkId, boolean isBgpVpn) {
- List<SubnetToDpn> subDpnList = null;
boolean isRouteAdvertised = false;
- subDpnList = subOpBuilder.getSubnetToDpn();
String rd = subOpBuilder.getVrfId();
String subnetIp = subOpBuilder.getSubnetCidr();
String vpnName = subOpBuilder.getVpnName();
String nhTepIp = null;
Uint64 nhDpnId = null;
- for (SubnetToDpn subnetToDpn : subDpnList) {
- if (subnetToDpn.getDpnId().equals(oldDpnId)) {
- // Is this same is as input dpnId, then ignore it
- continue;
- }
- nhDpnId = subnetToDpn.getDpnId();
- if (vpnNodeListener.isConnectedNode(nhDpnId)) {
- // selected dpnId is connected to ODL
- // but does it have a TEP configured at all?
- try {
- nhTepIp = InterfaceUtils.getEndpointIpAddressForDPN(dataBroker, nhDpnId);
- if (nhTepIp != null) {
- isAlternateDpnSelected = true;
- break;
+ Map<SubnetToDpnKey, SubnetToDpn> toDpnKeySubnetToDpnMap = subOpBuilder.getSubnetToDpn();
+ if (toDpnKeySubnetToDpnMap != null) {
+ for (SubnetToDpn subnetToDpn : toDpnKeySubnetToDpnMap.values()) {
+ if (subnetToDpn.getDpnId().equals(oldDpnId)) {
+ // Is this same is as input dpnId, then ignore it
+ continue;
+ }
+ nhDpnId = subnetToDpn.getDpnId();
+ if (vpnNodeListener.isConnectedNode(nhDpnId)) {
+ // selected dpnId is connected to ODL
+ // but does it have a TEP configured at all?
+ try {
+ nhTepIp = InterfaceUtils.getEndpointIpAddressForDPN(dataBroker, nhDpnId);
+ if (nhTepIp != null) {
+ isAlternateDpnSelected = true;
+ break;
+ }
+ } catch (Exception e) {
+ LOG.warn("{} electNewDpnForSubnetRoute: Unable to find TepIp for rd {} subnetroute subnetip {}"
+ + " for dpnid {}, attempt next", LOGGING_PREFIX, rd, subnetIp, nhDpnId.toString(), e);
}
- } catch (Exception e) {
- LOG.warn("{} electNewDpnForSubnetRoute: Unable to find TepIp for rd {} subnetroute subnetip {}"
- + " for dpnid {}, attempt next", LOGGING_PREFIX, rd, subnetIp, nhDpnId.toString(), e);
}
}
}
}
}
- private boolean isRouteAdvertised(SubnetOpDataEntryBuilder subOpBuilder) {
+ private static boolean isRouteAdvertised(SubnetOpDataEntryBuilder subOpBuilder) {
return subOpBuilder.getRouteAdvState() == TaskState.Advertised
|| subOpBuilder.getRouteAdvState() == TaskState.PendingAdvertise;
}
+
+ private static @NonNull List<SubnetToDpn> concat(@Nullable List<SubnetToDpn> list, @NonNull SubnetToDpn entry) {
+ final List<SubnetToDpn> ret = new ArrayList<>();
+ if (list != null) {
+ ret.addAll(list);
+ }
+ ret.add(entry);
+ return ret;
+ }
}