--- a/src/wm2/src/wm2_radio.c +++ b/src/wm2/src/wm2_radio.c @@ -772,6 +772,36 @@ wm2_cconf_get(const struct schema_Wifi_V return n; } +static bool wm2_vconf_validate_config(struct schema_Wifi_Radio_Config *rconf, + struct schema_Wifi_VIF_Config *vconf) +{ + int i; + struct schema_Wifi_VIF_Config vconf2; + json_t *where; + + for (i = 0; i < rconf->vif_configs_len; i++) { + if (!(where = ovsdb_where_uuid("_uuid", rconf->vif_configs[i].uuid))) + continue; + + memset(&vconf2, 0, sizeof(vconf2)); + + if (ovsdb_table_select_one_where(&table_Wifi_VIF_Config, where, &vconf2)) + { + if (!strcmp((const char *)&(vconf2._uuid), (const char *)&vconf->_uuid)) + continue; /* Same vconf */ + if (!strcmp(vconf2.ssid, vconf->ssid)) { + LOGN("%s: duplicate SSID (%s) in %s", vconf->if_name, vconf->ssid, vconf2.if_name); + return false; /* Different vconf, same SSID => invalid */ + } + if (!strcmp(vconf2.if_name, vconf->if_name)) { + LOGN("%s: duplicate if_name in %s", vconf->if_name, vconf2.if_name); + return false; /* Different vconf, same if_name => invalid */ + } + } + } + return true; +} + static void wm2_vconf_recalc(const char *ifname, bool force) { @@ -833,6 +863,11 @@ wm2_vconf_recalc(const char *ifname, boo return; } + if ( !wm2_vconf_validate_config(&rconf, &vconf)) { + LOGI("%s: invalid VIF config found", vconf.if_name); + return; + } + if (!ovsdb_table_select_one(&table_Wifi_Radio_State, SCHEMA_COLUMN(Wifi_Radio_State, if_name), rconf.if_name, @@ -1142,13 +1177,23 @@ wm2_op_vconf(const struct schema_Wifi_VI { struct schema_Wifi_VIF_Config tmp; json_t *where; + struct schema_Wifi_Radio_Config rconf; memcpy(&tmp, vconf, sizeof(tmp)); + memset(&rconf, 0, sizeof(rconf)); + LOGI("%s @ %s: updating vconf", vconf->if_name, phy); REQUIRE(vconf->if_name, strlen(vconf->if_name) > 0); REQUIRE(vconf->if_name, vconf->_partial_update); if (!(where = ovsdb_where_simple(SCHEMA_COLUMN(Wifi_Radio_Config, if_name), phy))) return; + if (ovsdb_table_select_one_where(&table_Wifi_Radio_Config, where, &rconf)) { + if (!wm2_vconf_validate_config(&rconf, &tmp)) { + return; + } + } + if (!(where = ovsdb_where_simple(SCHEMA_COLUMN(Wifi_Radio_Config, if_name), phy))) + return; REQUIRE(vconf->if_name, ovsdb_table_upsert_with_parent(&table_Wifi_VIF_Config, &tmp, false, // uuid not needed