summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorslioch <slioch@eng-140.vyatta.com>2008-12-05 12:02:49 -0800
committerslioch <slioch@eng-140.vyatta.com>2008-12-05 12:02:49 -0800
commit35f56aa4dbd1585681aa511717d9da962dbe0dd4 (patch)
tree2a9ba1a77b453a068f845b40ecb0b0f5068e4dba
parentc5c8f6916e7c96d61d9788b0ec54be38e379d4d5 (diff)
downloadvyatta-wanloadbalance-35f56aa4dbd1585681aa511717d9da962dbe0dd4.tar.gz
vyatta-wanloadbalance-35f56aa4dbd1585681aa511717d9da962dbe0dd4.zip
added support for dhcp in daemon. On receiving SIGUSR2 daemon checks and updates new address for snat, and nexthop for lb routing
tables. hook needs to be added to dhclient daemon to send SIGUSR2 to wan_lb so notification is generated on address change event. Note that for this behavior to be active in WLB nexthop needs to be populated with 'dhcp' configuration string. still requires routing paths availble for target testing, which might require an update to the dhcp client script and possible configuration knob.
-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();