summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Larson <mike@suva.vyatta.com>2008-08-29 10:31:51 -0700
committerMike Larson <mike@suva.vyatta.com>2008-08-29 10:31:51 -0700
commit22610d1769c6dabce2b4675085cab369f2d96331 (patch)
treeb71ab147c70404a6f043a5b60f5a8a32ffb00d05
parentbee9cfb28e0578a564628d61862764b3cdb2b377 (diff)
downloadvyatta-wanloadbalance-22610d1769c6dabce2b4675085cab369f2d96331.tar.gz
vyatta-wanloadbalance-22610d1769c6dabce2b4675085cab369f2d96331.zip
add rule failover support. Failover mode can now be specified on a specific rule. This rule will only direct traffic to a single active interface, on failure of the ping target traffice will be directed out an alternate interface.
note: the one todo item for this feature is to add "stickiness" of an active interface. wlb re-evaluates all rules on an interface state change and this may cause the interface to change for failover mode. supporting this mode requires a less than trivial rewrite of the wlb decision code.:
-rw-r--r--scripts/vyatta-wanloadbalance.pl9
-rw-r--r--src/lbdata.hh4
-rw-r--r--src/lbdatafactory.cc9
-rw-r--r--src/lbdatafactory.hh3
-rw-r--r--src/lbdecision.cc26
-rw-r--r--templates/load-balancing/wan/rule/node.tag/failover/node.def1
6 files changed, 45 insertions, 7 deletions
diff --git a/scripts/vyatta-wanloadbalance.pl b/scripts/vyatta-wanloadbalance.pl
index 9e273c5..49cb05b 100644
--- a/scripts/vyatta-wanloadbalance.pl
+++ b/scripts/vyatta-wanloadbalance.pl
@@ -96,6 +96,15 @@ sub write_rules {
print FILE_LCK "\texclude\n";
}
+ if ($config->exists("$rule failover")) {
+ print FILE_LCK "\tfailover\n";
+ }
+
+ if ($config->exists("$rule failover") && $config->exists("$rule exclude")) {
+ print "failover cannot be configured with exclude\n";
+ exit 1;
+ }
+
my $protocol = $config->returnValue("$rule protocol");
if (defined $protocol) {
print FILE_LCK "\tprotocol " . $protocol . "\n"
diff --git a/src/lbdata.hh b/src/lbdata.hh
index 8077841..f4ddade 100644
--- a/src/lbdata.hh
+++ b/src/lbdata.hh
@@ -24,7 +24,8 @@ class LBRule {
LBRule() :
_proto("all"),
- _exclude(false)
+ _exclude(false),
+ _failover(false)
{}
public:
@@ -38,6 +39,7 @@ class LBRule {
string _d_port_ipt;
bool _exclude;
+ bool _failover;
string _in_iface;
InterfaceDistColl _iface_dist_coll;
diff --git a/src/lbdatafactory.cc b/src/lbdatafactory.cc
index 086beed..16203b8 100644
--- a/src/lbdatafactory.cc
+++ b/src/lbdatafactory.cc
@@ -148,6 +148,9 @@ LBDataFactory::process(const vector<string> &path, int depth, const string &key,
else if (depth > 0 && path[1] == "exclude") {
process_rule_exclude(l_key,l_value);
}
+ else if (depth > 0 && path[1] == "failover") {
+ process_rule_failover(l_key,l_value);
+ }
else {
process_rule(l_key,l_value);
}
@@ -285,6 +288,12 @@ LBDataFactory::process_rule_exclude(const string &key, const string &value)
}
void
+LBDataFactory::process_rule_failover(const string &key, const string &value)
+{
+ _rule_iter->second._failover = true;
+}
+
+void
LBDataFactory::process_rule_source(const string &key, const string &value)
{
if (key == "address") {
diff --git a/src/lbdatafactory.hh b/src/lbdatafactory.hh
index 1f6e0a0..6f5a11a 100644
--- a/src/lbdatafactory.hh
+++ b/src/lbdatafactory.hh
@@ -56,6 +56,9 @@ private:
process_rule_exclude(const string &key, const string &value);
void
+ process_rule_failover(const string &key, const string &value);
+
+ void
process_rule_protocol(const string &key, const string &value);
void
diff --git a/src/lbdecision.cc b/src/lbdecision.cc
index 751659d..e6cafac 100644
--- a/src/lbdecision.cc
+++ b/src/lbdecision.cc
@@ -307,7 +307,7 @@ LBDecision::execute(std::string cmd, std::string &stdout, bool read)
char *buf = NULL;
size_t len = 0;
size_t read_len = 0;
- while ((read_len = getline(&buf, &len, f)) != -1) {
+ while ((read_len = getline(&buf, &len, f)) != (size_t)-1) {
stdout += string(buf) + " ";
}
@@ -334,12 +334,26 @@ LBDecision::get_new_weights(LBData &data, LBRule &rule)
if (_debug) {
cout << "LBDecision::get_new_weights(): " << iter->first << " is active: " << (data.is_active(iter->first) ? "true" : "false") << endl;
}
- if (data.is_active(iter->first)) {
- weights.insert(pair<int,float>(ct,iter->second));
- group += iter->second;
+
+ if (rule._failover == true) { //add single entry if active
+ if (weights.empty() == false) {
+ weights.insert(pair<int,float>(ct,0.));
+ }
+ else {
+ if (data.is_active(iter->first)) {
+ weights.insert(pair<int,float>(ct,1.));
+ group = 1;
+ }
+ }
}
else {
- weights.insert(pair<int,float>(ct,0.));
+ if (data.is_active(iter->first)) {
+ weights.insert(pair<int,float>(ct,iter->second));
+ group += iter->second;
+ }
+ else {
+ weights.insert(pair<int,float>(ct,0.));
+ }
}
++ct;
++iter;
@@ -356,7 +370,7 @@ LBDecision::get_new_weights(LBData &data, LBRule &rule)
if (w_iter->second > 0.) { //can only be an integer value here
w = float(w_iter->second) / float(group);
}
- group -= w_iter->second; //I THINK THIS NEEDS TO BE ADJUSTED TO THE OVERALL REMAINING VALUES. which is this...
+ group -= (int)w_iter->second; //I THINK THIS NEEDS TO BE ADJUSTED TO THE OVERALL REMAINING VALUES. which is this...
if (w < .01) {
weights.erase(w_iter++);
continue;
diff --git a/templates/load-balancing/wan/rule/node.tag/failover/node.def b/templates/load-balancing/wan/rule/node.tag/failover/node.def
new file mode 100644
index 0000000..ae725ff
--- /dev/null
+++ b/templates/load-balancing/wan/rule/node.tag/failover/node.def
@@ -0,0 +1 @@
+help: Set to enable failover for packets matching this rule from wan load balance