Skip to content

Commit

Permalink
Fix dns route update
Browse files Browse the repository at this point in the history
  • Loading branch information
xinnige committed May 13, 2024
1 parent 5500878 commit 44159b6
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 25 deletions.
69 changes: 47 additions & 22 deletions plugins/routing/routing_plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ class RoutingPlugin extends Plugin {
}
if (!af || af == 4) {
// remove DNS specific routes
if (_.isArray(this._dnsRoutes)) {
for (const dnsRoute of this._dnsRoutes)
await routing.removeRouteFromTable(dnsRoute.dest, dnsRoute.gw, dnsRoute.viaIntf, "main", 4).catch((err) => { });
if (_.isObject(this._dnsRoutes)) {
for (const dnsRoute of Object.keys(this._dnsRoutes).map(key => this._dnsRoutes[key]))
await routing.removeRouteFromTable(dnsRoute.dest, dnsRoute.gw, dnsRoute.viaIntf, dnsRoute.tableName ? dnsRoute.tableName :"main", 4).catch((err) => { });
}
this._dnsRoutes = [];
this._dnsRoutes = {};
}
break;
}
Expand Down Expand Up @@ -188,18 +188,19 @@ class RoutingPlugin extends Plugin {
}
}

async _removeDeviceDnsRouting(intfPlugins, tableName, af = null) {
async _removeDeviceDnsRouting(intfPlugins, af = null) {
if (!intfPlugins) {
return;
}
if (!af || af == 4) {
for (const intf of intfPlugins) {
const dns = await intf.getDNSNameservers();
if (_.isArray(dns) && dns.length > 0) {
for (const dnsIP of dns) {
await routing.removeRouteFromTable(dnsIP, null, intf.name, tableName, 4).catch((err) => {
this.log.warn(`fail to remove route -4 ${dnsIP} dev ${intf.name} table ${tableName}, err:`, err.message)});
if (this._dnsRoutes && _.isArray(this._dnsRoutes[intf.name])) {
for (const dnsRoute of this._dnsRoutes[intf.name]){
await routing.removeRouteFromTable(dnsRoute.dest, dnsRoute.gw, dnsRoute.viaIntf, dnsRoute.tableName ? dnsRoute.tableName: "main", 4).catch((err) => {
this.log.warn('fail to remove dns route from table main, err:', err.message)
})
}
delete (this._dnsRoutes, intf.name);
}
}
}
Expand All @@ -223,6 +224,22 @@ class RoutingPlugin extends Plugin {
}
}

_updateDnsRouteCache(dnsIP, gw, viaIntf, metric, tableName="main") {
if (!this._dnsRoutes){
this._dnsRoutes = {}
}
if (!this._dnsRoutes[viaIntf]) {
this._dnsRoutes[viaIntf] = [];
}
for (const dns of this._dnsRoutes[viaIntf]) {
if (dns.dest == dnsIP && dns.gw == gw && dns.viaIntf == viaIntf && dns.metric == metric && dns.tableName == tableName) {
// ensure no duplicates
return;
}
}
this._dnsRoutes[viaIntf].push({dest: dnsIP, gw: gw, viaIntf: viaIntf, metric: metric, tableName: tableName});
}

async refreshGlobalIntfRoutes(intf, af = null) {
await lock.acquire(LOCK_SHARED, async () => {
// update global routes
Expand Down Expand Up @@ -277,7 +294,6 @@ class RoutingPlugin extends Plugin {
if (_.isArray(mainRules) && mainRules.length > 0) {
for (const rule of mainRules) {
if (rule.includes('default') || !rule.includes('via')) { // skip default
this.log.debug('[skip] del table main', rule);
continue
}
const cmd = `sudo ip -${af} route del ${rule} dev ${intf} table main`;
Expand All @@ -291,7 +307,9 @@ class RoutingPlugin extends Plugin {
for (const dnsIP of dns) {
await routing.addRouteToTable(dnsIP, gw, intf, routing.RT_GLOBAL_DEFAULT, metric, 4).catch((err) => {
this.log.warn(`fail to add route -4 ${dnsIP} via ${gw} dev ${intf} table ${routing.RT_GLOBAL_DEFAULT}, err:`, err.message)});
await routing.addRouteToTable(dnsIP, gw, intf, "main", metric, 4).catch((err) => {
await routing.addRouteToTable(dnsIP, gw, intf, "main", metric, 4).then(() => {
this._updateDnsRouteCache(dnsIP, gw, viaIntf, metric, "main");
}).catch((err) => {
this.log.warn(`fail to add route -4 ${dnsIP} via ${gw} dev ${intf} table main, err:`, err.message)});
}
}
Expand Down Expand Up @@ -383,13 +401,14 @@ class RoutingPlugin extends Plugin {
}
if (!af || af == 4) {
// remove DNS specific routes
if (_.isArray(this._dnsRoutes)) {
for (const dnsRoute of this._dnsRoutes)
await routing.removeRouteFromTable(dnsRoute.dest, dnsRoute.gw, dnsRoute.viaIntf, "main", 4).catch((err) => {
if (_.isObject(this._dnsRoutes)) {
for (const dnsRoute of Object.keys(this._dnsRoutes).map(key => this._dnsRoutes[key])) {
await routing.removeRouteFromTable(dnsRoute.dest, dnsRoute.gw, dnsRoute.viaIntf, dnsRoute.tableName ? dnsRoute.tableName : "main", 4).catch((err) => {
this.log.warn('fail to remove dns route from table main, err:', err.message)
});
}
}
this._dnsRoutes = [];
this._dnsRoutes = {};
}
}

Expand All @@ -402,7 +421,7 @@ class RoutingPlugin extends Plugin {
const deadWANIntfs = this.getUnreadyWANPlugins();
await this._removeDeviceRouting(deadWANIntfs, routing.RT_GLOBAL_DEFAULT, af);
await this._removeDeviceRouting(deadWANIntfs, routing.RT_GLOBAL_LOCAL, af);
await this._removeDeviceDnsRouting(deadWANIntfs, "main", af);
await this._removeDeviceDnsRouting(deadWANIntfs, af, "main");
await this._removeDeviceDefaultRouting(deadWANIntfs, "main", af);
} else {
await routing.flushRoutingTable(routing.RT_GLOBAL_DEFAULT, af);
Expand All @@ -411,8 +430,6 @@ class RoutingPlugin extends Plugin {

if (!this.pluginConfig || !this.pluginConfig.smooth_failover) {
await this._removeMainRoutes(af);
} else if (!af || af == 4) {
this._dnsRoutes = [];
}

const type = this.networkConfig.default.type || "single";
Expand Down Expand Up @@ -469,10 +486,11 @@ class RoutingPlugin extends Plugin {
this.log.error(`Failed to add route to ${routing.RT_GLOBAL_DEFAULT} for dns ${dnsIP} via ${gw} dev ${viaIntf}`, err.message);
});
// update all dns routes via the same interface but with new metrics in main table
await this.upsertRouteToTable(dnsIP, gw, viaIntf, "main", metric, 4).catch((err) => {
await this.upsertRouteToTable(dnsIP, gw, viaIntf, "main", metric, 4).then(() => {
this._updateDnsRouteCache(dnsIP, gw, viaIntf, metric, "main");
}).catch((err) => {
this.log.error(`Failed to add route to main for dns ${dnsIP} via ${gw} dev ${viaIntf}`, err.message);
});
this._dnsRoutes.push({dest: dnsIP, gw: gw, viaIntf: viaIntf, metric: metric});
}
}
} else {
Expand Down Expand Up @@ -558,7 +576,14 @@ class RoutingPlugin extends Plugin {
await routing.addRouteToTable(dnsIP, gw, viaIntf, "main", metric, 4, true).catch((err) => {
this.log.error(`Failed to add route to main for dns ${dnsIP} via ${gw} dev ${viaIntf}`, err.message);
});
this._dnsRoutes.push({dest: dnsIP, gw: gw, viaIntf: viaIntf, metric: metric});
if (!this._dnsRoutes){
log.warn("should init _dnsRoutes in load_balance mode");
this._dnsRoutes = {}
}
if (!this._dnsRoutes[viaIntf]) {
this._dnsRoutes[viaIntf] = [];
}
this._dnsRoutes[viaIntf].push({dest: dnsIP, gw: gw, viaIntf: viaIntf, metric: metric, tableName: "main"});
}
}
} else {
Expand Down
10 changes: 7 additions & 3 deletions tests/plugins/test_routing.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,13 @@ describe('Test Routing WAN', function(){
it('should remove dead target route rules', async() => {
await exec("sudo ip route flush table eth0.288_default dev eth0.288").catch((err) => {});
await exec("sudo ip route add table eth0.288_default default via 10.88.8.1").catch((err) => {log.error("add route", err.message)});
await exec("sudo ip route add table eth0.288_default 8.8.8.8 dev eth0.288").catch((err) => {log.error("add route", err.message)});
await exec("sudo ip route add table eth0.288_default 10.8.8.8 dev eth0.288").catch((err) => {log.error("add route", err.message)});
await exec("sudo ip route add table eth0.288_default 8.8.8.8 via 10.88.8.1 dev eth0.288 metric 101").catch((err) => {log.error("add route", err.message)});
await exec("sudo ip route add table eth0.288_default 10.8.8.8 via 10.88.8.1 dev eth0.288 metric 101").catch((err) => {log.error("add route", err.message)});

this.plugin._dnsRoutes = {"eth0.288":[
{dest: '8.8.8.8', viaIntf: 'eth0.288', gw: '10.88.8.1', metric: 101, tableName: 'eth0.288_default'},
{dest: '10.8.8.8', viaIntf: 'eth0.288', gw: '10.88.8.1', metric: 101, tableName: 'eth0.288_default'},
]};
const deadWANs = this.plugin.getUnreadyWANPlugins();
expect(deadWANs[0].name).to.be.equal('eth0.288');
expect(await deadWANs[0].getDNSNameservers()).to.be.eql(['10.8.8.8', '8.8.8.8']);
Expand All @@ -134,7 +138,7 @@ describe('Test Routing WAN', function(){
expect(results.length).to.be.equal(2);

// remove dns routes
await this.plugin._removeDeviceDnsRouting(deadWANs, "eth0.288_default");
await this.plugin._removeDeviceDnsRouting(deadWANs);
results = await routing.searchRouteRules(null, null, 'eth0.288', 'eth0.288_default');
expect(results.length).to.be.equal(0);
});
Expand Down

0 comments on commit 44159b6

Please sign in to comment.