+
+ public static boolean getSwitchStatus(DataBroker broker, Uint64 switchId) {
+ NodeId nodeId = new NodeId("openflow:" + switchId);
+ LOG.debug("getSwitchStatus : Querying switch with dpnId {} is up/down", nodeId);
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeInstanceId
+ = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight
+ .inventory.rev130819.nodes.Node.class, new NodeKey(nodeId)).build();
+ Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeOptional =
+ SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
+ LogicalDatastoreType.OPERATIONAL, nodeInstanceId);
+ if (nodeOptional.isPresent()) {
+ LOG.debug("getSwitchStatus : Switch {} is up", nodeId);
+ return true;
+ }
+ LOG.debug("getSwitchStatus : Switch {} is down", nodeId);
+ return false;
+ }
+
+ public static boolean isExternalNetwork(DataBroker broker, Uuid networkId) {
+ InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
+ Optional<Networks> networkData =
+ SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
+ broker, LogicalDatastoreType.CONFIGURATION, id);
+ return networkData.isPresent();
+ }
+
+ @Nullable
+ public static String getElanInstancePhysicalNetwok(String elanInstanceName, DataBroker broker) {
+ ElanInstance elanInstance = getElanInstanceByName(elanInstanceName, broker);
+ if (null != elanInstance) {
+ return elanInstance.getPhysicalNetworkName();
+ }
+ return null;
+
+ }
+
+ public static Map<String, String> getOpenvswitchOtherConfigMap(Uint64 dpnId, DataBroker dataBroker) {
+ String otherConfigVal = getProviderMappings(dpnId, dataBroker);
+ return getMultiValueMap(otherConfigVal);
+ }
+
+ public static Map<String, String> getMultiValueMap(String multiKeyValueStr) {
+ if (Strings.isNullOrEmpty(multiKeyValueStr)) {
+ return Collections.emptyMap();
+ }
+
+ Map<String, String> valueMap = new HashMap<>();
+ Splitter splitter = Splitter.on(OTHER_CONFIG_PARAMETERS_DELIMITER);
+ for (String keyValue : splitter.split(multiKeyValueStr)) {
+ String[] split = keyValue.split(OTHER_CONFIG_KEY_VALUE_DELIMITER, 2);
+ if (split.length == 2) {
+ valueMap.put(split[0], split[1]);
+ }
+ }
+
+ return valueMap;
+ }
+
+ public static Optional<Node> getBridgeRefInfo(Uint64 dpnId, DataBroker dataBroker) {
+ InstanceIdentifier<BridgeRefEntry> bridgeRefInfoPath = InstanceIdentifier.create(BridgeRefInfo.class)
+ .child(BridgeRefEntry.class, new BridgeRefEntryKey(dpnId));
+
+ Optional<BridgeRefEntry> bridgeRefEntry =
+ SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
+ LogicalDatastoreType.OPERATIONAL, bridgeRefInfoPath);
+ if (!bridgeRefEntry.isPresent()) {
+ LOG.info("getBridgeRefInfo : bridgeRefEntry is not present for {}", dpnId);
+ return Optional.absent();
+ }
+
+ InstanceIdentifier<Node> nodeId =
+ bridgeRefEntry.get().getBridgeReference().getValue().firstIdentifierOf(Node.class);
+
+ return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
+ LogicalDatastoreType.OPERATIONAL, nodeId);
+ }
+
+ @Nullable
+ public static String getProviderMappings(Uint64 dpId, DataBroker dataBroker) {
+ return getBridgeRefInfo(dpId, dataBroker).toJavaUtil().map(node -> getOpenvswitchOtherConfigs(node,
+ PROVIDER_MAPPINGS, dataBroker)).orElse(null);
+ }
+
+ @Nullable
+ public static String getOpenvswitchOtherConfigs(Node node, String key, DataBroker dataBroker) {
+ OvsdbNodeAugmentation ovsdbNode = node.augmentation(OvsdbNodeAugmentation.class);
+ if (ovsdbNode == null) {
+ Optional<Node> nodeFromReadOvsdbNode = readOvsdbNode(node, dataBroker);
+ if (nodeFromReadOvsdbNode.isPresent()) {
+ ovsdbNode = nodeFromReadOvsdbNode.get().augmentation(OvsdbNodeAugmentation.class);
+ }
+ }
+
+ if (ovsdbNode != null && ovsdbNode.getOpenvswitchOtherConfigs() != null) {
+ for (OpenvswitchOtherConfigs openvswitchOtherConfigs : ovsdbNode.getOpenvswitchOtherConfigs()) {
+ if (Objects.equals(openvswitchOtherConfigs.getOtherConfigKey(), key)) {
+ return openvswitchOtherConfigs.getOtherConfigValue();
+ }
+ }
+ }
+ LOG.info("getOpenvswitchOtherConfigs : OtherConfigs is not present for ovsdbNode {}", node.getNodeId());
+ return null;
+ }
+
+ @NonNull
+ public static Optional<Node> readOvsdbNode(Node bridgeNode, DataBroker dataBroker) {
+ OvsdbBridgeAugmentation bridgeAugmentation = extractBridgeAugmentation(bridgeNode);
+ if (bridgeAugmentation != null) {
+ InstanceIdentifier<Node> ovsdbNodeIid =
+ (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
+ return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
+ LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid);
+ }
+ return Optional.absent();
+
+ }
+
+ @Nullable
+ public static OvsdbBridgeAugmentation extractBridgeAugmentation(Node node) {
+ if (node == null) {
+ return null;
+ }
+ return node.augmentation(OvsdbBridgeAugmentation.class);
+ }
+
+ public static String getDefaultFibRouteToSNATForSubnetJobKey(String subnetName, Uint64 dpnId) {
+ return NatConstants.NAT_DJC_PREFIX + subnetName + dpnId;
+ }
+
+ public static ExternalSubnets getExternalSubnets(DataBroker dataBroker) {
+ InstanceIdentifier<ExternalSubnets> subnetsIdentifier =
+ InstanceIdentifier.builder(ExternalSubnets.class)
+ .build();
+ try {
+ Optional<ExternalSubnets> optionalExternalSubnets = SingleTransactionDataBroker
+ .syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
+ if (optionalExternalSubnets.isPresent()) {
+ return optionalExternalSubnets.get();
+ }
+ } catch (ReadFailedException e) {
+ LOG.error("Failed to read the subnets from the datastore.");
+ }
+ return null;
+
+ }
+
+ public static void addFlow(TypedWriteTransaction<Configuration> confTx, IMdsalApiManager mdsalManager,
+ Uint64 dpId, short tableId, String flowId, int priority, String flowName, Uint64 cookie,
+ List<? extends MatchInfoBase> matches, List<InstructionInfo> instructions) {
+ FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId, priority, flowName,
+ NatConstants.DEFAULT_IDLE_TIMEOUT, NatConstants.DEFAULT_IDLE_TIMEOUT, cookie, matches,
+ instructions);
+ LOG.trace("syncFlow : Installing DpnId {}, flowId {}", dpId, flowId);
+ mdsalManager.addFlow(confTx, flowEntity);
+ }
+
+ public static void removeFlow(TypedReadWriteTransaction<Configuration> confTx, IMdsalApiManager mdsalManager,
+ Uint64 dpId, short tableId, String flowId) throws ExecutionException, InterruptedException {
+ LOG.trace("syncFlow : Removing Acl Flow DpnId {}, flowId {}", dpId, flowId);
+ mdsalManager.removeFlow(confTx, dpId, flowId, tableId);
+ }
+
+ public static String getIpv6FlowRef(Uint64 dpnId, short tableId, Uint32 routerID) {
+ return new StringBuilder().append(NatConstants.IPV6_FLOWID_PREFIX).append(dpnId).append(NatConstants
+ .FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID).toString();
+ }
+
+ public static String getTunnelInterfaceName(Uint64 srcDpId, Uint64 dstDpId,
+ ItmRpcService itmManager) {
+ Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
+ RpcResult<GetTunnelInterfaceNameOutput> rpcResult;
+ try {
+ Future<RpcResult<GetTunnelInterfaceNameOutput>> result = itmManager
+ .getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder().setSourceDpid(srcDpId)
+ .setDestinationDpid(dstDpId).setTunnelType(tunType).build());
+ rpcResult = result.get();
+ if (!rpcResult.isSuccessful()) {
+ tunType = TunnelTypeGre.class ;
+ result = itmManager.getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder()
+ .setSourceDpid(srcDpId)
+ .setDestinationDpid(dstDpId)
+ .setTunnelType(tunType)
+ .build());
+ rpcResult = result.get();
+ if (!rpcResult.isSuccessful()) {
+ LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}",
+ rpcResult.getErrors());
+ } else {
+ return rpcResult.getResult().getInterfaceName();
+ }
+ LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}",
+ rpcResult.getErrors());
+ } else {
+ return rpcResult.getResult().getInterfaceName();
+ }
+ } catch (InterruptedException | ExecutionException | NullPointerException e) {
+ LOG.error("getTunnelInterfaceName : Exception when getting tunnel interface Id for tunnel "
+ + "between {} and {}", srcDpId, dstDpId);
+ }
+ return null;
+ }
+
+ public static Boolean isRouterInterfacePort(DataBroker broker, String ifaceName) {
+ Port neutronPort = getNeutronPort(broker, ifaceName);
+ if (neutronPort == null) {
+ return Boolean.TRUE;
+ } else {
+ return (NatConstants.NETWORK_ROUTER_INTERFACE.equalsIgnoreCase(neutronPort.getDeviceOwner()) ? Boolean.TRUE
+ : Boolean.FALSE);
+ }
+ }
+
+ private static Port getNeutronPort(DataBroker broker, String ifaceName) {
+ InstanceIdentifier<Port>
+ portsIdentifier = InstanceIdentifier.create(Neutron.class)
+ .child(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class)
+ .child(Port.class, new PortKey(new Uuid(ifaceName)));
+ Optional<Port> portsOptional;
+ try {
+ portsOptional = SingleTransactionDataBroker
+ .syncReadOptional(broker, LogicalDatastoreType.CONFIGURATION, portsIdentifier);
+ } catch (ReadFailedException e) {
+ LOG.error("Read Failed Exception While Reading Neutron Port for {}", ifaceName, e);
+ portsOptional = Optional.absent();
+ }
+ if (!portsOptional.isPresent()) {
+ LOG.error("getNeutronPort : No neutron ports found for interface {}", ifaceName);
+ return null;
+ }
+ return portsOptional.get();
+ }
+
+ public static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
+ .instance.to.vpn.id.VpnInstance getVpnIdToVpnInstance(DataBroker broker, String vpnName) {
+ if (vpnName == null) {
+ return null;
+ }
+
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
+ .vpn.instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
+ Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
+ .vpn.instance.to.vpn.id.VpnInstance> vpnInstance = Optional.absent();
+ try {
+ vpnInstance = SingleTransactionDataBroker.syncReadOptional(broker, LogicalDatastoreType.CONFIGURATION, id);
+ } catch (ReadFailedException e) {
+ LOG.error("Failed to read VpnInstance {}", vpnInstance, e);
+ }
+ if (vpnInstance.isPresent()) {
+ return vpnInstance.get();
+ } else {
+ return null;
+ }
+ }
+
+ public static Uint32 getExternalVpnIdForExtNetwork(DataBroker broker, Uuid externalNwUuid) {
+ //Get the VPN ID from the ExternalNetworks model
+ if (externalNwUuid == null) {
+ LOG.error("getExternalVpnIdForExtNetwork : externalNwUuid is null");
+ return null;
+ }
+ Uuid vpnUuid = getVpnIdfromNetworkId(broker, externalNwUuid);
+ if (vpnUuid == null) {
+ LOG.error("NAT Service : vpnUuid is null");
+ return null;
+ }
+ Uint32 vpnId = getVpnId(broker, vpnUuid.getValue());
+ return vpnId;
+ }
+
+ static ReentrantLock lockForNat(final Uint64 dataPath) {
+ // FIXME: wrap this in an Identifier
+ return JvmGlobalLocks.getLockForString(NatConstants.NAT_DJC_PREFIX + dataPath);
+ }
+
+ public static void removeSnatEntriesForPort(DataBroker dataBroker, NaptManager naptManager,
+ IMdsalApiManager mdsalManager, NeutronvpnService neutronVpnService,
+ String interfaceName, String routerName) {
+ Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
+ if (routerId == NatConstants.INVALID_ID) {
+ LOG.error("removeSnatEntriesForPort: routerId not found for routername {}", routerName);
+ return;
+ }
+ Uint64 naptSwitch = getPrimaryNaptfromRouterName(dataBroker, routerName);
+ if (naptSwitch == null || naptSwitch.equals(Uint64.ZERO)) {
+ LOG.error("removeSnatEntriesForPort: NaptSwitch is not elected for router {}"
+ + "with Id {}", routerName, routerId);
+ return;
+ }
+ //getInternalIp for port
+ List<String> fixedIps = getFixedIpsForPort(neutronVpnService, interfaceName);
+ if (fixedIps == null) {
+ LOG.error("removeSnatEntriesForPort: Internal Ips not found for InterfaceName {} in router {} with id {}",
+ interfaceName, routerName, routerId);
+ return;
+ }
+ List<ProtocolTypes> protocolTypesList = getPortocolList();
+ for (String internalIp : fixedIps) {
+ LOG.debug("removeSnatEntriesForPort: Internal Ip retrieved for interface {} is {} in router with Id {}",
+ interfaceName, internalIp, routerId);
+ for (ProtocolTypes protocol : protocolTypesList) {
+ List<Uint16> portList = NatUtil.getInternalIpPortListInfo(dataBroker, routerId, internalIp, protocol);
+ if (portList != null) {
+ for (Uint16 portnum : portList) {
+ //build and remove the flow in outbound table
+ removeNatFlow(mdsalManager, naptSwitch, NwConstants.OUTBOUND_NAPT_TABLE,
+ routerId, internalIp, portnum.toJava(), protocol.getName());
+
+ //build and remove the flow in inboundtable
+
+ removeNatFlow(mdsalManager, naptSwitch, NwConstants.INBOUND_NAPT_TABLE, routerId,
+ internalIp, portnum.toJava(), protocol.getName());
+
+ //Get the external IP address and the port from the model
+
+ NAPTEntryEvent.Protocol proto = protocol.toString().equals(ProtocolTypes.TCP.toString())
+ ? NAPTEntryEvent.Protocol.TCP : NAPTEntryEvent.Protocol.UDP;
+ IpPortExternal ipPortExternal = NatUtil.getExternalIpPortMap(dataBroker, routerId,
+ internalIp, String.valueOf(portnum.toJava()), proto);
+ if (ipPortExternal == null) {
+ LOG.error("removeSnatEntriesForPort: Mapping for internalIp {} "
+ + "with port {} is not found in "
+ + "router with Id {}", internalIp, portnum, routerId);
+ return;
+ }
+ String externalIpAddress = ipPortExternal.getIpAddress();
+ String internalIpPort = internalIp + ":" + portnum.toJava();
+ // delete the entry from IntExtIpPortMap DS
+
+ naptManager.removeFromIpPortMapDS(routerId, internalIpPort, proto);
+ naptManager.removePortFromPool(internalIpPort, externalIpAddress);
+
+ }
+ } else {
+ LOG.debug("removeSnatEntriesForPort: No {} session for interface {} with internalIP {} "
+ + "in router with id {}",
+ protocol, interfaceName, internalIp, routerId);
+ }
+ }
+ // delete the entry from SnatIntIpPortMap DS
+ LOG.debug("removeSnatEntriesForPort: Removing InternalIp :{} of router {} from snatint-ip-port-map",
+ internalIp, routerId);
+ naptManager.removeFromSnatIpPortDS(routerId, internalIp);
+ }
+ }
+
+ private static List<String> getFixedIpsForPort(NeutronvpnService neutronVpnService, String interfname) {
+ LOG.debug("getFixedIpsForPort: getFixedIpsForPort method is called for interface {}", interfname);
+ try {
+ Future<RpcResult<GetFixedIPsForNeutronPortOutput>> result =
+ neutronVpnService.getFixedIPsForNeutronPort(new GetFixedIPsForNeutronPortInputBuilder()
+ .setPortId(new Uuid(interfname)).build());
+
+ RpcResult<GetFixedIPsForNeutronPortOutput> rpcResult = result.get();
+ if (!rpcResult.isSuccessful()) {
+ LOG.error("getFixedIpsForPort: RPC Call to GetFixedIPsForNeutronPortOutput returned with Errors {}",
+ rpcResult.getErrors());
+ } else {
+ return rpcResult.getResult().getFixedIPs();
+ }
+ } catch (InterruptedException | ExecutionException | NullPointerException ex) {
+ LOG.error("getFixedIpsForPort: Exception while receiving fixedIps for port {}", interfname, ex);
+ }
+ return null;
+ }
+
+ private static List<ProtocolTypes> getPortocolList() {
+ List<ProtocolTypes> protocollist = new ArrayList<>();
+ protocollist.add(ProtocolTypes.TCP);
+ protocollist.add(ProtocolTypes.UDP);
+ return protocollist;
+ }
+
+ private static void removeNatFlow(IMdsalApiManager mdsalManager, Uint64 dpnId, short tableId, Uint32 routerId,
+ String ipAddress, int ipPort, String protocol) {
+
+ String switchFlowRef = NatUtil.getNaptFlowRef(dpnId, tableId, String.valueOf(routerId), ipAddress, ipPort,
+ protocol);
+ FlowEntity snatFlowEntity = NatUtil.buildFlowEntity(dpnId, tableId, switchFlowRef);
+
+ mdsalManager.removeFlow(snatFlowEntity);
+ LOG.debug("removeNatFlow: Removed the flow in table {} for the switch with the DPN ID {} for "
+ + "router {} ip {} port {}", tableId, dpnId, routerId, ipAddress, ipPort);
+ }
+
+ public static String getDpnFromNodeRef(NodeRef node) {
+ PathArgument pathArgument = Iterables.get(node.getValue().getPathArguments(), 1);
+ InstanceIdentifier.IdentifiableItem<?, ?> item = Arguments.checkInstanceOf(pathArgument,
+ InstanceIdentifier.IdentifiableItem.class);
+ NodeKey key = Arguments.checkInstanceOf(item.getKey(), NodeKey.class);
+ String dpnKey = key.getId().getValue();
+ String dpnID = null;
+ if (dpnKey.contains(NatConstants.COLON_SEPARATOR)) {
+ dpnID = Uint64.valueOf(dpnKey.split(NatConstants.COLON_SEPARATOR)[1]).toString();
+ }
+ return dpnID;
+ }