package org.opendaylight.netvirt.dhcpservice;
+import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
+
import com.google.common.base.Optional;
import java.math.BigInteger;
import java.net.InetAddress;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.ExecutionException;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.stream.Collectors;
-import java.util.stream.IntStream;
import java.util.stream.LongStream;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
+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.binding.api.ReadTransaction;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
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.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.Datastore.Operational;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
import org.opendaylight.genius.mdsalutil.ActionInfo;
import org.opendaylight.netvirt.elanmanager.api.ElanHelper;
import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
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.neutron.networks.rev150712.networks.attributes.networks.Network;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.NetworkKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
public final class DhcpServiceUtils {
private static final Logger LOG = LoggerFactory.getLogger(DhcpServiceUtils.class);
+ private static List<BigInteger> connectedDpnIds = new CopyOnWriteArrayList<>();
private DhcpServiceUtils() { }
public static void setupDhcpFlowEntry(@Nullable BigInteger dpId, short tableId, @Nullable String vmMacAddress,
int addOrRemove,
IMdsalApiManager mdsalUtil, DhcpServiceCounters dhcpServiceCounters,
- WriteTransaction tx) {
+ TypedReadWriteTransaction<Configuration> tx)
+ throws ExecutionException, InterruptedException {
if (dpId == null || dpId.equals(DhcpMConstants.INVALID_DPID) || vmMacAddress == null) {
return;
}
actionsInfos.add(new ActionPuntToController());
instructions.add(new InstructionApplyActions(actionsInfos));
if (addOrRemove == NwConstants.DEL_FLOW) {
- FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId,
- getDhcpFlowRef(dpId, tableId, vmMacAddress),
- DhcpMConstants.DEFAULT_DHCP_FLOW_PRIORITY, "DHCP", 0, 0,
- DhcpMConstants.COOKIE_DHCP_BASE, matches, null);
LOG.trace("Removing DHCP Flow DpId {}, vmMacAddress {}", dpId, vmMacAddress);
dhcpServiceCounters.removeDhcpFlow();
- mdsalUtil.removeFlowToTx(flowEntity, tx);
+ mdsalUtil.removeFlow(tx, dpId, getDhcpFlowRef(dpId, tableId, vmMacAddress), tableId);
} else {
FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId,
getDhcpFlowRef(dpId, tableId, vmMacAddress), DhcpMConstants.DEFAULT_DHCP_FLOW_PRIORITY,
"DHCP", 0, 0, DhcpMConstants.COOKIE_DHCP_BASE, matches, instructions);
LOG.trace("Installing DHCP Flow DpId {}, vmMacAddress {}", dpId, vmMacAddress);
dhcpServiceCounters.installDhcpFlow();
- mdsalUtil.addFlowToTx(flowEntity, tx);
+ mdsalUtil.addFlow(tx, flowEntity);
}
}
public static void setupDhcpDropAction(BigInteger dpId, short tableId, String vmMacAddress, int addOrRemove,
IMdsalApiManager mdsalUtil, DhcpServiceCounters dhcpServiceCounters,
- WriteTransaction tx) {
+ TypedReadWriteTransaction<Configuration> tx)
+ throws ExecutionException, InterruptedException {
if (dpId == null || dpId.equals(DhcpMConstants.INVALID_DPID) || vmMacAddress == null) {
return;
}
// Drop Action
actionsInfos.add(new ActionDrop());
if (addOrRemove == NwConstants.DEL_FLOW) {
- FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId,
- getDhcpFlowRef(dpId, tableId, vmMacAddress),
- DhcpMConstants.DEFAULT_DHCP_FLOW_PRIORITY, "DHCP", 0, 0,
- DhcpMConstants.COOKIE_DHCP_BASE, matches, null);
LOG.trace("Removing DHCP Drop Flow DpId {}, vmMacAddress {}", dpId, vmMacAddress);
dhcpServiceCounters.removeDhcpDropFlow();
- mdsalUtil.removeFlowToTx(flowEntity, tx);
+ mdsalUtil.removeFlow(tx, dpId, getDhcpFlowRef(dpId, tableId, vmMacAddress), tableId);
} else {
FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId,
getDhcpFlowRef(dpId, tableId, vmMacAddress), DhcpMConstants.DEFAULT_DHCP_FLOW_PRIORITY,
"DHCP", 0, 0, DhcpMConstants.COOKIE_DHCP_BASE, matches, instructions);
LOG.trace("Installing DHCP Drop Flow DpId {}, vmMacAddress {}", dpId, vmMacAddress);
dhcpServiceCounters.installDhcpDropFlow();
- mdsalUtil.addFlowToTx(flowEntity, tx);
+ mdsalUtil.addFlow(tx, flowEntity);
}
}
- @SuppressWarnings("checkstyle:IllegalCatch")
public static void setupDhcpArpRequest(BigInteger dpId, short tableId, BigInteger vni, String dhcpIpAddress,
- int lportTag, Long elanTag, boolean add, IMdsalApiManager mdsalUtil) {
+ int lportTag, @Nullable Long elanTag, boolean add,
+ IMdsalApiManager mdsalUtil, TypedReadWriteTransaction<Configuration> tx)
+ throws ExecutionException, InterruptedException {
List<MatchInfo> matches = getDhcpArpMatch(vni, dhcpIpAddress);
if (add) {
Flow flow = MDSALUtil.buildFlowNew(tableId, getDhcpArpFlowRef(dpId, tableId, lportTag, dhcpIpAddress),
DhcpMConstants.DEFAULT_DHCP_ARP_FLOW_PRIORITY, "DHCPArp", 0, 0,
generateDhcpArpCookie(lportTag, dhcpIpAddress), matches, null);
LOG.trace("Removing DHCP ARP Flow DpId {}, DHCP Port IpAddress {}", dpId, dhcpIpAddress);
- mdsalUtil.removeFlow(dpId, flow);
+ mdsalUtil.removeFlow(tx, dpId, flow);
} else {
Flow flow = MDSALUtil.buildFlowNew(tableId, getDhcpArpFlowRef(dpId, tableId, lportTag, dhcpIpAddress),
DhcpMConstants.DEFAULT_DHCP_ARP_FLOW_PRIORITY, "DHCPArp", 0, 0,
generateDhcpArpCookie(lportTag, dhcpIpAddress), matches,
getDhcpArpInstructions(elanTag, lportTag));
LOG.trace("Adding DHCP ARP Flow DpId {}, DHCPPort IpAddress {}", dpId, dhcpIpAddress);
- mdsalUtil.installFlow(dpId, flow);
+ mdsalUtil.addFlow(tx, dpId, flow);
}
}
}
public static List<BigInteger> getListOfDpns(DataBroker broker) {
+ if (!connectedDpnIds.isEmpty()) {
+ return connectedDpnIds;
+ }
return extractDpnsFromNodes(MDSALUtil.read(broker, LogicalDatastoreType.OPERATIONAL,
InstanceIdentifier.builder(Nodes.class).build()));
}
- @Nonnull
- public static List<BigInteger> getListOfDpns(ReadTransaction tx) throws ReadFailedException {
- return extractDpnsFromNodes(tx.read(LogicalDatastoreType.OPERATIONAL,
- InstanceIdentifier.builder(Nodes.class).build()).checkedGet());
- }
-
- @Nonnull
+ @NonNull
private static List<BigInteger> extractDpnsFromNodes(Optional<Nodes> optionalNodes) {
return optionalNodes.toJavaUtil().map(
- nodes -> nodes.getNode().stream().map(Node::getId).filter(Objects::nonNull).map(
+ nodes -> nodes.nonnullNode().stream().map(Node::getId).filter(Objects::nonNull).map(
MDSALUtil::getDpnIdFromNodeName).collect(
Collectors.toList())).orElse(Collections.emptyList());
}
- @Nonnull
+ @NonNull
public static List<BigInteger> getDpnsForElan(String elanInstanceName, DataBroker broker) {
List<BigInteger> elanDpns = new LinkedList<>();
InstanceIdentifier<ElanDpnInterfacesList> elanDpnInstanceIdentifier =
Optional<ElanDpnInterfacesList> elanDpnOptional =
MDSALUtil.read(broker, LogicalDatastoreType.OPERATIONAL, elanDpnInstanceIdentifier);
if (elanDpnOptional.isPresent()) {
- List<DpnInterfaces> dpns = elanDpnOptional.get().getDpnInterfaces();
+ List<DpnInterfaces> dpns = elanDpnOptional.get().nonnullDpnInterfaces();
for (DpnInterfaces dpnInterfaces : dpns) {
elanDpns.add(dpnInterfaces.getDpId());
}
return elanDpns;
}
- public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
- .state.Interface getInterfaceFromOperationalDS(String interfaceName, DataBroker dataBroker) {
+ public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state
+ .@Nullable Interface getInterfaceFromOperationalDS(String interfaceName, DataBroker dataBroker) {
org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
.state.InterfaceKey interfaceKey =
new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
}
+ @Nullable
public static String getSegmentationId(Uuid networkId, DataBroker broker) {
InstanceIdentifier<Network> inst = InstanceIdentifier.create(Neutron.class)
.child(Networks.class).child(Network.class, new NetworkKey(networkId));
return segmentationId;
}
- public static String getNodeIdFromDpnId(BigInteger dpnId) {
- return MDSALUtil.NODE_PREFIX + MDSALUtil.SEPARATOR + dpnId.toString();
- }
-
- public static String getTrunkPortMacAddress(String parentRefName,
- DataBroker broker) {
- InstanceIdentifier<Port> portInstanceIdentifier =
- InstanceIdentifier.create(Neutron.class).child(Ports.class).child(Port.class);
- Optional<Port> trunkPort = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, portInstanceIdentifier);
- if (!trunkPort.isPresent()) {
- LOG.warn("Trunk port {} not available for sub-port", parentRefName);
- return null;
- }
- return trunkPort.get().getMacAddress().getValue();
- }
-
public static String getJobKey(String interfaceName) {
return new StringBuilder().append(DhcpMConstants.DHCP_JOB_KEY_PREFIX).append(interfaceName).toString();
}
- public static void bindDhcpService(String interfaceName, short tableId, WriteTransaction tx) {
+ public static void bindDhcpService(String interfaceName, short tableId, TypedWriteTransaction<Configuration> tx) {
int instructionKey = 0;
List<Instruction> instructions = new ArrayList<>();
instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(tableId, ++instructionKey));
getBoundServices(String.format("%s.%s", "dhcp", interfaceName),
serviceIndex, DhcpMConstants.DEFAULT_FLOW_PRIORITY,
DhcpMConstants.COOKIE_VM_INGRESS_TABLE, instructions);
- tx.put(LogicalDatastoreType.CONFIGURATION,
- buildServiceId(interfaceName, serviceIndex), serviceInfo, WriteTransaction.CREATE_MISSING_PARENTS);
+ tx.put(buildServiceId(interfaceName, serviceIndex), serviceInfo, CREATE_MISSING_PARENTS);
}
- public static void unbindDhcpService(String interfaceName, WriteTransaction tx) {
+ public static void unbindDhcpService(String interfaceName, TypedWriteTransaction<Configuration> tx) {
short serviceIndex = ServiceIndex.getIndex(NwConstants.DHCP_SERVICE_NAME, NwConstants.DHCP_SERVICE_INDEX);
- tx.delete(LogicalDatastoreType.CONFIGURATION,
- buildServiceId(interfaceName, serviceIndex));
+ tx.delete(buildServiceId(interfaceName, serviceIndex));
}
private static InstanceIdentifier<BoundServices> buildServiceId(String interfaceName,
return java.util.Optional.empty();
}
- static IpAddress convertIntToIp(int ipn) {
- String[] array = IntStream.of(24, 16, 8, 0) //
- .map(x -> ipn >> x & 0xFF).boxed() //
- .map(String::valueOf) //
- .toArray(String[]::new);
- return new IpAddress(String.join(".", array).toCharArray());
- }
-
static IpAddress convertLongToIp(long ip) {
String[] array = LongStream.of(24, 16, 8, 0) //
.map(x -> ip >> x & 0xFF).boxed() //
.map(String::valueOf) //
.toArray(String[]::new);
- return new IpAddress(String.join(".", array).toCharArray());
+ return IpAddressBuilder.getDefaultInstance(String.join(".", array));
}
static long convertIpToLong(IpAddress ipa) {
- String[] splitIp = String.valueOf(ipa.getValue()).split("\\.");
+ String[] splitIp = ipa.stringValue().split("\\.");
long result = 0;
for (String part : splitIp) {
result <<= 8;
return interfaceManager.getInterfaceInfoFromOperationalDataStore(interfaceName);
}
- static BigInteger getDpIdFromInterface(IInterfaceManager interfaceManager, String interfaceName) {
- return interfaceManager.getDpnForInterface(interfaceName);
- }
-
public static java.util.Optional<String> getIpV4Address(Port port) {
if (port.getFixedIps() == null) {
return java.util.Optional.empty();
}
@Nullable
- public static String getAndUpdateVmMacAddress(ReadWriteTransaction tx, String interfaceName,
- DhcpManager dhcpManager) throws ReadFailedException {
+ public static String getAndUpdateVmMacAddress(TypedReadWriteTransaction<Operational> tx, String interfaceName,
+ DhcpManager dhcpManager) throws ExecutionException, InterruptedException {
InstanceIdentifier<InterfaceNameMacAddress> instanceIdentifier =
InstanceIdentifier.builder(InterfaceNameMacAddresses.class)
.child(InterfaceNameMacAddress.class, new InterfaceNameMacAddressKey(interfaceName)).build();
- Optional<InterfaceNameMacAddress> existingEntry =
- tx.read(LogicalDatastoreType.OPERATIONAL, instanceIdentifier).checkedGet();
+ Optional<InterfaceNameMacAddress> existingEntry = tx.read(instanceIdentifier).get();
if (!existingEntry.isPresent()) {
LOG.trace("Entry for interface {} missing in InterfaceNameVmMacAddress map", interfaceName);
String vmMacAddress = getNeutronMacAddress(interfaceName, dhcpManager);
new InterfaceNameMacAddressBuilder()
.withKey(new InterfaceNameMacAddressKey(interfaceName))
.setInterfaceName(interfaceName).setMacAddress(vmMacAddress).build();
- tx.merge(LogicalDatastoreType.OPERATIONAL, instanceIdentifier, interfaceNameMacAddress,
- WriteTransaction.CREATE_MISSING_PARENTS);
+ tx.merge(instanceIdentifier, interfaceNameMacAddress, CREATE_MISSING_PARENTS);
return vmMacAddress;
}
return existingEntry.get().getMacAddress();
}
+ @Nullable
private static String getNeutronMacAddress(String interfaceName, DhcpManager dhcpManager) {
Port port = dhcpManager.getNeutronPort(interfaceName);
if (port != null) {
return null;
}
+ @NonNull
public static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
InstanceIdentifier id = buildNetworkMapIdentifier(networkId);
Optional<NetworkMap> optionalNetworkMap = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
if (optionalNetworkMap.isPresent()) {
- return optionalNetworkMap.get().getSubnetIdList();
+ @Nullable List<Uuid> subnetIdList = optionalNetworkMap.get().getSubnetIdList();
+ if (subnetIdList != null) {
+ return subnetIdList;
+ }
}
- return null;
+ return Collections.emptyList();
}
static InstanceIdentifier<NetworkMap> buildNetworkMapIdentifier(Uuid networkId) {
- InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class).child(NetworkMap.class, new
- NetworkMapKey(networkId)).build();
- return id;
+ return InstanceIdentifier.builder(NetworkMaps.class).child(NetworkMap.class,
+ new NetworkMapKey(networkId)).build();
}
public static boolean isIpv4Subnet(DataBroker broker, Uuid subnetUuid) {
final Optional<Subnet> subnet = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, subnetidentifier);
if (subnet.isPresent()) {
Class<? extends IpVersionBase> ipVersionBase = subnet.get().getIpVersion();
- if (ipVersionBase.equals(IpVersionV4.class)) {
- return true;
- }
+ return IpVersionV4.class.equals(ipVersionBase);
}
return false;
}
+ public static void addToDpnIdCache(BigInteger dpnId) {
+ if (!connectedDpnIds.contains(dpnId)) {
+ connectedDpnIds.add(dpnId);
+ }
+ }
+
+ public static void removeFromDpnIdCache(BigInteger dpnId) {
+ connectedDpnIds.remove(dpnId);
+ }
+
}