org.opendaylight.netvirt.natservice.internal.ExternalNetworkGroupInstaller Maven / Gradle / Ivy
/*
* Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.netvirt.natservice.internal;
import com.google.common.base.Strings;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
import org.opendaylight.genius.mdsalutil.ActionInfo;
import org.opendaylight.genius.mdsalutil.BucketInfo;
import org.opendaylight.genius.mdsalutil.GroupEntity;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
import org.opendaylight.genius.mdsalutil.actions.ActionDrop;
import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldEthernetDestination;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
import org.opendaylight.netvirt.elanmanager.api.IElanService;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Singleton
public class ExternalNetworkGroupInstaller {
private static final Logger LOG = LoggerFactory.getLogger(ExternalNetworkGroupInstaller.class);
private final DataBroker broker;
private final IMdsalApiManager mdsalManager;
private final IElanService elanService;
private final IdManagerService idManager;
private final OdlInterfaceRpcService odlInterfaceRpcService;
private final JobCoordinator coordinator;
private final ItmRpcService itmRpcService;
private final IInterfaceManager interfaceManager;
private final NatServiceCounters natServiceCounters;
@Inject
public ExternalNetworkGroupInstaller(final DataBroker broker, final IMdsalApiManager mdsalManager,
final IElanService elanService, final IdManagerService idManager,
final OdlInterfaceRpcService odlInterfaceRpcService,
final JobCoordinator coordinator, final ItmRpcService itmRpcService,
final IInterfaceManager interfaceManager,
NatServiceCounters natServiceCounters) {
this.broker = broker;
this.mdsalManager = mdsalManager;
this.elanService = elanService;
this.idManager = idManager;
this.odlInterfaceRpcService = odlInterfaceRpcService;
this.coordinator = coordinator;
this.itmRpcService = itmRpcService;
this.interfaceManager = interfaceManager;
this.natServiceCounters = natServiceCounters;
}
public void installExtNetGroupEntries(Subnetmap subnetMap) {
if (subnetMap == null) {
LOG.error("installExtNetGroupEntries : Subnetmap is null");
return;
}
if (NatUtil.isIPv6Subnet(subnetMap.getSubnetIp())) {
LOG.debug("installExtNetGroupEntries : Subnet id {} is not an IPv4 subnet, hence skipping.",
subnetMap.getId());
return;
}
Uuid networkId = subnetMap.getNetworkId();
Uuid subnetId = subnetMap.getId();
if (networkId == null) {
LOG.error("installExtNetGroupEntries : No network associated subnet id {}", subnetId.getValue());
return;
}
String macAddress = NatUtil.getSubnetGwMac(broker, subnetId, networkId.getValue());
installExtNetGroupEntries(subnetMap, macAddress);
}
public void installExtNetGroupEntries(Uuid subnetId, String macAddress) {
Subnetmap subnetMap = NatUtil.getSubnetMap(broker, subnetId);
if (subnetMap == null) {
LOG.error("installExtNetGroupEntries : Subnetmap is null");
return;
}
if (NatUtil.isIPv6Subnet(subnetMap.getSubnetIp())) {
LOG.debug("installExtNetGroupEntries : Subnet-id {} is not an IPv4 subnet, hence skipping.",
subnetMap.getId());
return;
}
installExtNetGroupEntries(subnetMap, macAddress);
}
public void installExtNetGroupEntries(Uuid networkId, BigInteger dpnId) {
if (networkId == null) {
return;
}
List subnetIds = NatUtil.getSubnetIdsFromNetworkId(broker, networkId);
if (subnetIds.isEmpty()) {
LOG.error("installExtNetGroupEntries : No subnet ids associated network id {}", networkId.getValue());
return;
}
for (Uuid subnetId : subnetIds) {
String macAddress = NatUtil.getSubnetGwMac(broker, subnetId, networkId.getValue());
installExtNetGroupEntry(networkId, subnetId, dpnId, macAddress);
}
}
private void installExtNetGroupEntries(Subnetmap subnetMap, String macAddress) {
String subnetName = subnetMap.getId().getValue();
Uuid networkId = subnetMap.getNetworkId();
if (networkId == null) {
LOG.error("installExtNetGroupEntries : No network associated subnet id {}", subnetName);
return;
}
Collection extInterfaces = elanService.getExternalElanInterfaces(networkId.getValue());
if (extInterfaces == null || extInterfaces.isEmpty()) {
LOG.trace("installExtNetGroupEntries : No external ELAN interfaces attached to network:{},subnet {}",
networkId, subnetName);
return;
}
long groupId = NatUtil.createGroupId(NatUtil.getGroupIdKey(subnetName), idManager);
LOG.info("installExtNetGroupEntries : Installing ext-net group {} entry for subnet {} with macAddress {} "
+ "(extInterfaces: {})", groupId, subnetName, macAddress, Arrays.toString(extInterfaces.toArray()));
for (String extInterface : extInterfaces) {
BigInteger dpId = NatUtil.getDpnForInterface(odlInterfaceRpcService, extInterface);
if (BigInteger.ZERO.equals(dpId)) {
LOG.info("installExtNetGroupEntries: No DPN for interface {}. NAT ext-net flow will not be installed "
+ "for subnet {}", extInterface, subnetName);
return;
}
installExtNetGroupEntry(groupId, subnetName, extInterface, macAddress, dpId);
}
}
public void installExtNetGroupEntry(Uuid networkId, Uuid subnetId, BigInteger dpnId, String macAddress) {
String subnetName = subnetId.getValue();
String extInterface = elanService.getExternalElanInterface(networkId.getValue(), dpnId);
if (extInterface == null) {
LOG.warn("installExtNetGroupEntry : No external ELAN interface attached to network {} subnet {} DPN id {}",
networkId, subnetName, dpnId);
//return;
}
long groupId = NatUtil.createGroupId(NatUtil.getGroupIdKey(subnetName), idManager);
LOG.info("installExtNetGroupEntry : Installing ext-net group {} entry for subnet {} with macAddress {} "
+ "(extInterface: {})", groupId, subnetName, macAddress, extInterface);
installExtNetGroupEntry(groupId, subnetName, extInterface, macAddress, dpnId);
}
private void installExtNetGroupEntry(long groupId, String subnetName, String extInterface,
String macAddress, BigInteger dpnId) {
coordinator.enqueueJob(NatUtil.getDefaultFibRouteToSNATForSubnetJobKey(subnetName, dpnId), () -> {
GroupEntity groupEntity = buildExtNetGroupEntity(macAddress, subnetName, groupId, extInterface, dpnId);
mdsalManager.syncInstallGroup(groupEntity);
return Collections.emptyList();
});
}
public void removeExtNetGroupEntries(Subnetmap subnetMap) {
if (subnetMap == null) {
return;
}
String subnetName = subnetMap.getId().getValue();
Uuid networkId = subnetMap.getNetworkId();
if (networkId == null) {
LOG.error("removeExtNetGroupEntries : No external network associated subnet id {}", subnetName);
return;
}
Collection extInterfaces = elanService.getExternalElanInterfaces(networkId.getValue());
if (extInterfaces == null || extInterfaces.isEmpty()) {
LOG.debug("removeExtNetGroupEntries : No external ELAN interfaces attached to network {} subnet {}",
networkId, subnetName);
return;
}
long groupId = NatUtil.createGroupId(NatUtil.getGroupIdKey(subnetName), idManager);
for (String extInterface : extInterfaces) {
GroupEntity groupEntity = buildEmptyExtNetGroupEntity(subnetName, groupId, extInterface);
if (groupEntity != null) {
LOG.info("removeExtNetGroupEntries : Remove ext-net Group: id {}, subnet id {}", groupId, subnetName);
natServiceCounters.removeExternalNetworkGroup();
mdsalManager.syncRemoveGroup(groupEntity);
}
}
}
private GroupEntity buildExtNetGroupEntity(String macAddress, String subnetName,
long groupId, String extInterface, BigInteger dpnId) {
List actionList = new ArrayList<>();
final int setFieldEthDestActionPos = 0;
List egressActionList = new ArrayList<>();
if (extInterface != null) {
egressActionList = NatUtil.getEgressActionsForInterface(odlInterfaceRpcService, itmRpcService,
interfaceManager, extInterface, null, setFieldEthDestActionPos + 1, false);
}
if (Strings.isNullOrEmpty(macAddress) || egressActionList.isEmpty()) {
if (Strings.isNullOrEmpty(macAddress)) {
LOG.trace("buildExtNetGroupEntity : Building ext-net group {} entry with drop action since "
+ "GW mac has not been resolved for subnet {} extInterface {}",
groupId, subnetName, extInterface);
} else {
LOG.warn("buildExtNetGroupEntity : Building ext-net group {} entry with drop action since "
+ "no egress actions were found for subnet {} extInterface {}",
groupId, subnetName, extInterface);
}
actionList.add(new ActionDrop());
} else {
LOG.trace("Building ext-net group {} entry for subnet {} extInterface {} macAddress {}",
groupId, subnetName, extInterface, macAddress);
actionList.add(new ActionSetFieldEthernetDestination(setFieldEthDestActionPos, new MacAddress(macAddress)));
actionList.addAll(egressActionList);
}
List listBucketInfo = new ArrayList<>();
listBucketInfo.add(new BucketInfo(actionList));
return MDSALUtil.buildGroupEntity(dpnId, groupId, subnetName, GroupTypes.GroupAll, listBucketInfo);
}
@Nullable
private GroupEntity buildEmptyExtNetGroupEntity(String subnetName, long groupId, String extInterface) {
BigInteger dpId = NatUtil.getDpnForInterface(odlInterfaceRpcService, extInterface);
if (BigInteger.ZERO.equals(dpId)) {
LOG.error("buildEmptyExtNetGroupEntity: No DPN for interface {}. NAT ext-net flow will not be installed "
+ "for subnet {}", extInterface, subnetName);
return null;
}
return MDSALUtil.buildGroupEntity(dpId, groupId, subnetName, GroupTypes.GroupAll, new ArrayList<>());
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy