mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-28 17:12:22 +00:00
ucentral-event: add VLAN reference counting to prevent race condition
When a station roams between bands on the same VLAN, the vlan_remove event from the old band can arrive after the vlan_add event from the new band, causing the VLAN to be incorrectly deleted whilst still in use. Add reference counting that tracks how many interfaces are using each VLAN ID. Only create VLAN devices on the first reference and only remove them when the last reference is dropped. On startup, initialise refcounts from current station state to handle daemon restarts correctly. Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
push(REQUIRE_SEARCH_PATH, '/usr/share/ucentral/*.uc');
|
||||
|
||||
import * as libubus from 'ubus';
|
||||
import * as libuci from 'uci';
|
||||
import * as uloop from 'uloop';
|
||||
@@ -36,6 +38,7 @@ let ucentral_running = false;
|
||||
let pending_events = [];
|
||||
let relay = {};
|
||||
let net_config = {};
|
||||
let vlan_refcount = {};
|
||||
|
||||
|
||||
function config_load() {
|
||||
@@ -52,6 +55,20 @@ function config_load() {
|
||||
net_config = {};
|
||||
}
|
||||
|
||||
function vlan_refcount_init() {
|
||||
let stations = require('wifi.station');
|
||||
|
||||
vlan_refcount = {};
|
||||
|
||||
for (let k, v in stations) {
|
||||
let vlan = split(k, '-v')[1];
|
||||
let count = length(v);
|
||||
if (vlan && count > 0) {
|
||||
vlan_refcount[vlan] = count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function match(object, type, list) {
|
||||
if (object in list || type in list)
|
||||
return true;
|
||||
@@ -258,6 +275,13 @@ handlers = {
|
||||
},
|
||||
|
||||
vlan_add: function(notify) {
|
||||
let vlan_id = `${notify.data.vlan_id}`;
|
||||
vlan_refcount[vlan_id] = (vlan_refcount[vlan_id] || 0) + 1;
|
||||
|
||||
if (vlan_refcount[vlan_id] > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.config.swconfig)
|
||||
return handlers.vlan_add_swconfig(notify);
|
||||
|
||||
@@ -280,6 +304,14 @@ handlers = {
|
||||
},
|
||||
|
||||
vlan_remove: function(notify) {
|
||||
let vlan_id = `${notify.data.vlan_id}`;
|
||||
vlan_refcount[vlan_id] = (vlan_refcount[vlan_id] || 1) - 1;
|
||||
|
||||
if (vlan_refcount[vlan_id] > 0) {
|
||||
return;
|
||||
}
|
||||
delete vlan_refcount[vlan_id];
|
||||
|
||||
if (config.config.swconfig)
|
||||
return;
|
||||
for (let wan in wan_ports) {
|
||||
@@ -624,6 +656,7 @@ let ubus_methods = {
|
||||
};
|
||||
|
||||
config_load();
|
||||
vlan_refcount_init();
|
||||
|
||||
hapd_subscriber = ubus.subscriber(hapd_subscriber_notify_cb, hapd_subscriber_remove_cb);
|
||||
dhcp_subscriber = ubus.subscriber(dhcp_subscriber_notify_cb, dhcp_subscriber_remove_cb);
|
||||
|
||||
Reference in New Issue
Block a user