diff options
-rw-r--r-- | src/lbdata.hh | 1 | ||||
-rw-r--r-- | src/lbdecision.cc | 61 | ||||
-rw-r--r-- | src/lbdecision.hh | 6 | ||||
-rw-r--r-- | src/loadbalance.cc | 9 | ||||
-rw-r--r-- | src/loadbalance.hh | 2 | ||||
-rw-r--r-- | src/main.cc | 28 |
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(); |