summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lbdata.hh1
-rw-r--r--src/lbdecision.cc61
-rw-r--r--src/lbdecision.hh6
-rw-r--r--src/loadbalance.cc9
-rw-r--r--src/loadbalance.hh2
-rw-r--r--src/main.cc28
6 files changed, 95 insertions, 12 deletions
diff --git a/src/lbdata.hh b/src/lbdata.hh
index 8715ef5..d9a6091 100644
--- a/src/lbdata.hh
+++ b/src/lbdata.hh
@@ -101,6 +101,7 @@ class LBHealth {
bool _is_active;
bool _state_changed;
int _interface_index;
+ string _address;
};
diff --git a/src/lbdecision.cc b/src/lbdecision.cc
index e51530a..10a730b 100644
--- a/src/lbdecision.cc
+++ b/src/lbdecision.cc
@@ -138,7 +138,13 @@ if so then this stuff goes here!
// insert_default(string("ip route replace table ") + buf + " default dev " + iface + " via " + iter->second._nexthop, ct);
//need to force the entry on restart as the configuration may have changed.
- execute(string("ip route replace table ") + buf + " default dev " + iface + " via " + iter->second._nexthop, stdout);
+ if (iter->second._nexthop == "dhcp") {
+ string nexthop = fetch_iface_nexthop(iface);
+ execute(string("ip route replace table ") + buf + " default dev " + iface + " via " + nexthop, stdout);
+ }
+ else {
+ execute(string("ip route replace table ") + buf + " default dev " + iface + " via " + iter->second._nexthop, stdout);
+ }
execute(string("ip rule delete table ") + buf, stdout);
@@ -147,13 +153,46 @@ if so then this stuff goes here!
execute(string("ip rule add fwmark ") + hex_buf + " table " + buf, stdout);
if (lbdata._disable_source_nat == false) {
- execute(string("iptables -t nat -A WANLOADBALANCE -m connmark --mark ") + buf + " -j SNAT --to-source " + fetch_iface_addr(iface), stdout);
+ iter->second._address = fetch_iface_addr(iface);
+ execute(string("iptables -t nat -A WANLOADBALANCE -m connmark --mark ") + buf + " -j SNAT --to-source " + iter->second._address, stdout);
}
++iter;
}
execute("ip route flush cache", stdout);
}
+/**
+ * Need to do two things here, check the interfaces for new nexthops and update the routing tables,
+ * and get a new address to update the source nat with.
+ *
+ **/
+void
+LBDecision::update_paths(LBData &lbdata)
+{
+ string stdout;
+ if (lbdata._disable_source_nat == false) {
+ //first let's remove the entry
+ LBData::InterfaceHealthIter iter = lbdata._iface_health_coll.begin();
+ while (iter != lbdata._iface_health_coll.end()) {
+ if (iter->second._nexthop == "dhcp") {
+ string iface = iter->first;
+ string new_addr = fetch_iface_addr(iface);
+ if (new_addr != iter->second._address) {
+ char buf[20];
+ sprintf(buf,"%d",iter->second._interface_index);
+ execute(string("iptables -t nat -D WANLOADBALANCE -m connmark --mark ") + buf + " -j SNAT --to-source " + iter->second._address, stdout);
+ execute(string("iptables -t nat -A WANLOADBALANCE -m connmark --mark ") + buf + " -j SNAT --to-source " + new_addr, stdout);
+ iter->second._address = new_addr;
+
+ //now let's update the nexthop here in the route table
+ string nexthop = fetch_iface_nexthop(iface);
+ execute(string("ip route replace table ") + buf + " default dev " + iface + " via " + nexthop, stdout);
+ }
+ }
+ ++iter;
+ }
+ }
+}
/**
* only responsible for
@@ -489,6 +528,24 @@ LBDecision::insert_default(string cmd, int table)
}
}
+/**
+ * currently only reads the nexthop as maintained by the dhcp client
+ **/
+string
+LBDecision::fetch_iface_nexthop(const string &iface)
+{
+ string file("/var/run/vyatta/dhclient/dhclient-script-router-"+iface);
+ FILE *fp = fopen(file.c_str(),"r");
+ if (fp) {
+ char str[1025];
+ int ct = 0;
+ if ((ct = fread(str, 1, 1024, fp)) > 0) {
+ return string(str);
+ }
+ fclose(fp);
+ }
+ return string("");
+}
/**
* Fetch interface configuration
diff --git a/src/lbdecision.hh b/src/lbdecision.hh
index abac5db..e8771e0 100644
--- a/src/lbdecision.hh
+++ b/src/lbdecision.hh
@@ -24,6 +24,9 @@ public:
init(LBData &lbdata);
void
+ update_paths(LBData &lbdata);
+
+ void
run(LBData &lbdata);
void
@@ -45,6 +48,9 @@ private:
string
fetch_iface_addr(const string &iface);
+ string
+ fetch_iface_nexthop(const string &iface);
+
private:
bool _debug;
};
diff --git a/src/loadbalance.cc b/src/loadbalance.cc
index 40c2840..0324c08 100644
--- a/src/loadbalance.cc
+++ b/src/loadbalance.cc
@@ -70,6 +70,15 @@ LoadBalance::start_cycle()
*
**/
void
+LoadBalance::update_paths()
+{
+ _decision.update_paths(_lbdata);
+}
+
+/**
+ *
+ **/
+void
LoadBalance::health_test()
{
_ph.start(_lbdata);
diff --git a/src/loadbalance.hh b/src/loadbalance.hh
index e4ac80a..b8f4932 100644
--- a/src/loadbalance.hh
+++ b/src/loadbalance.hh
@@ -34,6 +34,8 @@ class LoadBalance
bool start_cycle();
+ void update_paths();
+
void health_test();
void apply_rules();
diff --git a/src/main.cc b/src/main.cc
index 1d3a35d..d42abb9 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -15,20 +15,21 @@
#include <iostream>
#include "loadbalance.hh"
+bool g_check_path = false;
LoadBalance *g_lb = NULL;
pid_t pid_output (const char *path);
static void usage()
{
- cout << "lb -ftidh" << endl;
- cout << "-f [file] configuration file" << endl;
- cout << "-t load configuration file only and exit" << endl;
- cout << "-v print debug output" << endl;
- cout << "-i specify location of pid directory" << endl;
- cout << "-o specify location of output directory" << endl;
- cout << "-d run as daemon" << endl;
- cout << "-h help" << endl;
+ cout << "lb -ftviodh" << endl;
+ cout << " -f [file] configuration file" << endl;
+ cout << " -t load configuration file only and exit" << endl;
+ cout << " -v print debug output" << endl;
+ cout << " -i specify location of pid directory" << endl;
+ cout << " -o specify location of output directory" << endl;
+ cout << " -d run as daemon" << endl;
+ cout << " -h help" << endl;
}
@@ -52,9 +53,10 @@ static void sig_user1(int signo)
static void sig_user2(int signo)
{
- //used to wake up the process
+ //used to wake up the process to check paths
+ g_check_path = true;
cerr << "User signal: " << signo << endl;
- syslog(LOG_ERR, "wan_lb, user exit signal caught, exiting..");
+ syslog(LOG_ERR, "wan_lb, rechecking interfaces..");
}
@@ -148,6 +150,12 @@ int main(int argc, char* argv[])
cout << "main.cc: starting new cycle" << endl;
}
+ //check interface address and nexthop
+ if (g_check_path == true) {
+ g_lb->update_paths();
+ g_check_path = false;
+ }
+
//health test
g_lb->health_test();