diff --git a/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/dao/OvsdbDao.java b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/dao/OvsdbDao.java index 2dc7e58..96c5654 100644 --- a/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/dao/OvsdbDao.java +++ b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/dao/OvsdbDao.java @@ -1702,10 +1702,25 @@ public class OvsdbDao { public void removeAllSsids(OvsdbClient ovsdbClient, OpensyncAPConfig opensyncAPConfig) { Map currentWifiVifConfigInfo = getProvisionedWifiVifConfigs(ovsdbClient); Map currentWifiRadioConfigInfo = getProvisionedWifiRadioConfigs(ovsdbClient); - List vifConfigsToDelete = new ArrayList<>(); + // This is essentially a cleanup call, if there are multiple same ssid's + // under a single radio we will remove them, and re-create them only + // according to the profiles + Map vifConfigsBySsid = new HashMap<>(); + currentWifiVifConfigInfo.entrySet().stream().forEach(e -> { + if (vifConfigsBySsid.containsKey(e.getValue().ssid)) { + vifConfigsToDelete.add(e.getValue()); + vifConfigsToDelete.add(vifConfigsBySsid.get(e.getValue().ssid)); + } else { + vifConfigsBySsid.put(e.getKey(), e.getValue()); + } + }); + LOG.debug("VifConfigs by SSID {}", vifConfigsBySsid); + LOG.debug("vifConfigsToDelete {}", vifConfigsToDelete); + // Now add any VIFs we have configurations for that are not in the new + // Profiles to the delete list for (Entry vifConfigInfo : currentWifiVifConfigInfo.entrySet()) { LOG.debug("Checking {}", vifConfigInfo.getKey()); WifiRadioConfigInfo radioConfigInfo = null; @@ -1750,7 +1765,9 @@ public class OvsdbDao { for (WifiVifConfigInfo vifConfigInfo : vifConfigsToDelete) { List conditions = new ArrayList<>(); - conditions.add(new Condition("_uuid", Function.EQUALS, new Atom<>(vifConfigInfo.uuid))); + conditions.add(new Condition("ssid", Function.EQUALS, new Atom<>(vifConfigInfo.ssid))); + conditions.add(new Condition("if_name", Function.EQUALS, new Atom<>(vifConfigInfo.ifName))); + operations.add(new Delete(wifiVifConfigDbTable, conditions)); } @@ -1759,26 +1776,44 @@ public class OvsdbDao { OperationResult[] result = fResult.get(ovsdbTimeoutSec, TimeUnit.SECONDS); if (LOG.isDebugEnabled()) { - LOG.debug("Removed existing SSIDs from {}:", wifiVifConfigDbTable); + LOG.debug("Removed SSIDs no longer in use from {}:", wifiVifConfigDbTable); for (OperationResult res : result) { LOG.debug("Op Result {}", res); } } + // get the new list of configured VIFs (these are what remain after + // the deletes) + // we want to see if any of these VIFs has a Vlan that we want to + // save if that Vlan was also used by other VIFs that have been + // deleted + currentWifiVifConfigInfo = getProvisionedWifiVifConfigs(ovsdbClient); + Set configuredVlanIds = new HashSet<>(); + for (WifiVifConfigInfo vifConfig : currentWifiVifConfigInfo.values()) { + if (vifConfig.vlanId > 1) + configuredVlanIds.add(vifConfig.vlanId); + } operations = new ArrayList<>(); - // Add vifs to delete + // Add if_names from the vifs to delete, and from any vlans not in + // the configuredVlanId list above for (WifiVifConfigInfo vifConfigInfo : vifConfigsToDelete) { List conditions = new ArrayList<>(); conditions.add(new Condition("if_name", Function.EQUALS, new Atom<>(vifConfigInfo.ifName))); operations.add(new Delete(wifiInetConfigDbTable, conditions)); + // remove any vlans that are no longer used by other vif configs + if (vifConfigInfo.vlanId > 1 && !configuredVlanIds.contains(vifConfigInfo.vlanId)) { + conditions = new ArrayList<>(); + conditions.add(new Condition("vlan_id", Function.EQUALS, new Atom<>(vifConfigInfo.vlanId))); + operations.add(new Delete(wifiInetConfigDbTable, conditions)); + } } fResult = ovsdbClient.transact(ovsdbName, operations); result = fResult.get(ovsdbTimeoutSec, TimeUnit.SECONDS); if (LOG.isDebugEnabled()) { - LOG.debug("Removed existing InetConfigs from {}:", wifiVifConfigDbTable); + LOG.debug("Removed existing InetConfigs from {}:", wifiInetConfigDbTable); for (OperationResult res : result) { LOG.debug("Op Result {}", res); @@ -2600,6 +2635,8 @@ public class OvsdbDao { if (vlanId > 1) { createVlanNetworkInterfaces(ovsdbClient, vlanId); updateColumns.put("vlan_id", new Atom<>(vlanId)); + } else { + updateColumns.put("vlan_id", new com.vmware.ovsdb.protocol.operation.notation.Set()); } updateColumns.put("mode", new Atom<>("ap")); @@ -3088,9 +3125,20 @@ public class OvsdbDao { boolean enabled = ssidConfig.getSsidAdminState().equals(StateSetting.enabled); try { + Map provisionedVifs = getProvisionedWifiVifConfigs(ovsdbClient); + + List interfaces = new ArrayList<>(); + interfaces.add(ifName); + for (int i = 1; i <= 7; ++i) { + interfaces.add(ifName + "_" + Integer.toString(i)); + } + for (String key : provisionedVifs.keySet()) { + if (key.contains(ifName)) { + interfaces.remove(provisionedVifs.get(key).ifName); + } + } boolean isUpdate = false; - Map provisionedVifs = getProvisionedWifiVifConfigs(ovsdbClient); for (String key : provisionedVifs.keySet()) { if (key.contains(ifName) && key.contains(ssidConfig.getSsid())) { isUpdate = true; @@ -3100,25 +3148,19 @@ public class OvsdbDao { } if (!isUpdate) { - int numberOfInterfaces = 0; - for (String key : getProvisionedWifiVifConfigs(ovsdbClient).keySet()) { - if (key.startsWith(ifName)) { - numberOfInterfaces++; - } - } - - if (numberOfInterfaces >= maxInterfacesPerRadio) { + if (interfaces.isEmpty()) { // this cannot occur, log error, do not try to // provision throw new IllegalStateException("Cannot provision more than " + maxInterfacesPerRadio + " interfaces per Wifi Radio"); - } + } else { + // for a new interface, take the lowest available + // interface for this radio type. + Collections.sort(interfaces); + LOG.debug("Available VIF Interfaces for freqBand {} sorted {}", freqBand, interfaces); + ifName = interfaces.get(0); + LOG.debug("Select ifName {} for new VIF on freqBand {} ", ifName, freqBand); - if (numberOfInterfaces > 0) { - // 1st interface has no number, 2nd has '_1', 3rd - // has - // '_2' etc. - ifName = ifName + "_" + numberOfInterfaces; } } diff --git a/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/dao/models/WifiRadioConfigInfo.java b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/dao/models/WifiRadioConfigInfo.java index ebc7129..e598dff 100644 --- a/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/dao/models/WifiRadioConfigInfo.java +++ b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/dao/models/WifiRadioConfigInfo.java @@ -3,6 +3,7 @@ package com.telecominfraproject.wlan.opensync.ovsdb.dao.models; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Objects; import java.util.Set; import com.vmware.ovsdb.protocol.operation.notation.Uuid; @@ -44,6 +45,30 @@ public class WifiRadioConfigInfo implements Cloneable { } @Override + public int hashCode() { + return Objects.hash(beaconInterval, channel, channelMode, country, enabled, freqBand, htMode, hwConfig, hwType, + ifName, txPower, uuid, vifConfigUuids); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof WifiRadioConfigInfo)) { + return false; + } + WifiRadioConfigInfo other = (WifiRadioConfigInfo) obj; + return beaconInterval == other.beaconInterval && channel == other.channel + && Objects.equals(channelMode, other.channelMode) && Objects.equals(country, other.country) + && enabled == other.enabled && Objects.equals(freqBand, other.freqBand) + && Objects.equals(htMode, other.htMode) && Objects.equals(hwConfig, other.hwConfig) + && Objects.equals(hwType, other.hwType) && Objects.equals(ifName, other.ifName) + && Objects.equals(txPower, other.txPower) && Objects.equals(uuid, other.uuid) + && Objects.equals(vifConfigUuids, other.vifConfigUuids); + } + + @Override public String toString() { return String.format( "WifiRadioConfigInfo [vifConfigUuids=%s, freqBand=%s, channel=%s, txPower=%s, channelMode=%s, enabled=%s, htMode=%s, hwConfig=%s, hwType=%s, country=%s, bcn_int=%s, ifName=%s, uuid=%s]", diff --git a/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/dao/models/WifiVifConfigInfo.java b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/dao/models/WifiVifConfigInfo.java index 0a6984a..55a980e 100644 --- a/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/dao/models/WifiVifConfigInfo.java +++ b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/dao/models/WifiVifConfigInfo.java @@ -1,7 +1,9 @@ package com.telecominfraproject.wlan.opensync.ovsdb.dao.models; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Objects; import java.util.Set; import com.vmware.ovsdb.protocol.operation.notation.Uuid; @@ -38,12 +40,41 @@ public class WifiVifConfigInfo implements Cloneable{ if(security!=null) { ret.security = new HashMap<>(this.security); } + if (macList!=null) { + ret.macList = new HashSet<>(this.macList); + } return ret; }catch(CloneNotSupportedException e) { throw new IllegalStateException("Cannot clone ", e); } } + @Override + public int hashCode() { + return Objects.hash(apBridge, bridge, btm, enabled, ftMobilityDomain, ftPsk, groupRekey, ifName, macList, + macListType, minHwMode, mode, rrm, security, ssid, ssidBroadcast, uapsdEnable, uuid, vifRadioIdx, + vlanId); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof WifiVifConfigInfo)) { + return false; + } + WifiVifConfigInfo other = (WifiVifConfigInfo) obj; + return Objects.equals(apBridge, other.apBridge) && Objects.equals(bridge, other.bridge) && btm == other.btm + && enabled == other.enabled && ftMobilityDomain == other.ftMobilityDomain && ftPsk == other.ftPsk + && groupRekey == other.groupRekey && Objects.equals(ifName, other.ifName) + && Objects.equals(macList, other.macList) && Objects.equals(macListType, other.macListType) + && Objects.equals(minHwMode, other.minHwMode) && Objects.equals(mode, other.mode) && rrm == other.rrm + && Objects.equals(security, other.security) && Objects.equals(ssid, other.ssid) + && Objects.equals(ssidBroadcast, other.ssidBroadcast) && uapsdEnable == other.uapsdEnable + && Objects.equals(uuid, other.uuid) && vifRadioIdx == other.vifRadioIdx && vlanId == other.vlanId; + } + @Override public String toString() { return String.format(