From a15bd8df2bba80c67555ff562d4e1d3b66fc6a2c Mon Sep 17 00:00:00 2001 From: bodea Date: Mon, 23 May 2005 13:48:29 +0000 Subject: [PATCH] New config option: cluster_master_min_adv which determines the minimum number of up to date slaves required before the master will drop routes. --- Changes | 7 ++++-- Docs/manual.html | 5 ++++ Docs/startup-config.5 | 6 ++++- cluster.c | 55 +++++++++++++++++++++++++++---------------- l2tpns.c | 4 +++- l2tpns.h | 9 +++++-- l2tpns.spec | 2 +- 7 files changed, 61 insertions(+), 27 deletions(-) diff --git a/Changes b/Changes index 15070db..3972fb2 100644 --- a/Changes +++ b/Changes @@ -1,4 +1,4 @@ -* Sun May 22 2005 Brendan O'Dea 2.0.21 +* Mon May 23 2005 Brendan O'Dea 2.0.21 - Cluster changes from Michael, intended to prevent a stray master from trashing a cluster: + Ignore heartbeats from peers claiming to be the master before the @@ -6,12 +6,15 @@ + A master receiving a stray heartbeat sends a unicast HB back, which should cause the rogue to die due to the tie-breaker code. + Keep probing the master for late heartbeats. - + Drop BGP as soon as we become master with peers. + + Drop BGP as soon as we become master with the minumum required peers. + Any PING seen from a master forces an election (rather than just where basetime is zero). + A slave which receives a LASTSEEN message (presumably a restarted master) sends back new message type, C_MASTER which indicates the address of the current master. +- New config option: cluster_master_min_adv which determines the minimum + number of up to date slaves required before the master will drop + routes. * Mon May 16 2005 Brendan O'Dea 2.0.20 - Add handling of "throttle=N" RADIUS attributes. diff --git a/Docs/manual.html b/Docs/manual.html index 8dd2532..f5cf6db 100644 --- a/Docs/manual.html +++ b/Docs/manual.html @@ -332,6 +332,11 @@ Cluster heartbeat timeout in tenths of a second. A new master will be elected when this interval has been passed without seeing a heartbeat from the master. + +
  • cluster_master_min_adv (int)
    +Determines the minumum number of up to date slaves required before the +master will drop routes (default: 1). +
  • BGP routing configuration is entered by the command: diff --git a/Docs/startup-config.5 b/Docs/startup-config.5 index 9fe9178..2af2706 100644 --- a/Docs/startup-config.5 +++ b/Docs/startup-config.5 @@ -2,7 +2,7 @@ .de Id .ds Dt \\$4 \\$5 .. -.Id $Id: startup-config.5,v 1.3.2.1 2005/01/10 07:08:36 bodea Exp $ +.Id $Id: startup-config.5,v 1.3.2.2 2005/05/23 13:48:30 bodea Exp $ .TH STARTUP-CONFIG 5 "\*(Dt" L2TPNS "File Formats and Conventions" .SH NAME startup\-config \- configuration file for l2tpns @@ -179,6 +179,10 @@ Interval in tenths of a second between cluster heartbeat/pings. Cluster heartbeat timeout in tenths of a second. A new master will be elected when this interval has been passed without seeing a heartbeat from the master. +.TP +.B cluster_master_min_adv +Determines the minumum number of up to date slaves required before the +master will drop routes (default: 1). .RE .SS BGP ROUTING The routing configuration section is entered by the command diff --git a/cluster.c b/cluster.c index 48c2059..725adc1 100644 --- a/cluster.c +++ b/cluster.c @@ -1,6 +1,6 @@ // L2TPNS Clustering Stuff -char const *cvs_id_cluster = "$Id: cluster.c,v 1.26.2.9 2005/05/23 12:48:17 bodea Exp $"; +char const *cvs_id_cluster = "$Id: cluster.c,v 1.26.2.10 2005/05/23 13:48:29 bodea Exp $"; #include #include @@ -192,7 +192,7 @@ static void add_type(char **p, int type, int more, char *data, int size) } // advertise our presence via BGP or gratuitous ARP -static void advertise(void) +static void advertise_routes(void) { #ifdef BGP if (bgp_configured) @@ -203,6 +203,15 @@ static void advertise(void) send_garp(config->bind_address); // Start taking traffic. } +// withdraw our routes (BGP only) +static void withdraw_routes(void) +{ +#ifdef BGP + if (bgp_configured) + bgp_enable_routing(0); +#endif /* BGP */ +} + static void cluster_uptodate(void) { if (config->cluster_iam_uptodate) @@ -214,7 +223,7 @@ static void cluster_uptodate(void) config->cluster_iam_uptodate = 1; LOG(0, 0, 0, "Now uptodate with master.\n"); - advertise(); + advertise_routes(); } // @@ -456,17 +465,22 @@ void cluster_check_slaves(void) continue; // Shutdown peer! Skip them. if (peers[i].uptodate) - have_peers = 1; - - if (!peers[i].uptodate) + have_peers++; + else config->cluster_iam_uptodate = 0; // Start fast heartbeats } -#ifdef BGP - // in a cluster, withdraw/add routes when we get a peer/lose all peers - if (bgp_configured && have_peers != had_peers) - bgp_enable_routing(!have_peers); -#endif /* BGP */ + // in a cluster, withdraw/add routes when we get a peer/lose peers + if (have_peers != had_peers) + { + if (had_peers < config->cluster_master_min_adv && + have_peers >= config->cluster_master_min_adv) + withdraw_routes(); + + else if (had_peers >= config->cluster_master_min_adv && + have_peers < config->cluster_master_min_adv) + advertise_routes(); + } } // @@ -479,6 +493,7 @@ void cluster_check_master(void) int last_free = 0; clockt t = TIME; static int probed = 0; + int have_peers; if (config->cluster_iam_master) return; // Only runs on the slaves... @@ -511,7 +526,7 @@ void cluster_check_master(void) LOG(0, 0, 0, "Master timed out! Holding election...\n"); - for (i = 0; i < num_peers; i++) + for (i = have_peers = 0; i < num_peers; i++) { if ((peers[i].timestamp + config->cluster_hb_timeout) < t) continue; // Stale peer! Skip them. @@ -529,6 +544,9 @@ void cluster_check_master(void) LOG(1, 0, 0, "Expecting %s to become master\n", fmtaddr(peers[i].peer, 0)); return; // They'll win the election. Wait for them to come up. } + + if (peers[i].uptodate) + have_peers++; } // Wow. it's been ages since I last heard a heartbeat @@ -540,6 +558,11 @@ void cluster_check_master(void) LOG(0, 0, 0, "I am declaring myself the master!\n"); + if (have_peers < config->cluster_master_min_adv) + advertise_routes(); + else + withdraw_routes(); + if (config->cluster_seq_number == -1) config->cluster_seq_number = 0; @@ -620,14 +643,6 @@ void cluster_check_master(void) config->cluster_undefined_tunnels = 0; config->cluster_iam_uptodate = 1; // assume all peers are up-to-date - if (!num_peers) // lone master - advertise(); -#ifdef BGP - else if (bgp_configured) - bgp_enable_routing(0); -#endif /* BGP */ - - // FIXME. We need to fix up the tunnel control message // queue here! There's a number of other variables we // should also update. diff --git a/l2tpns.c b/l2tpns.c index 70d0c70..055f860 100644 --- a/l2tpns.c +++ b/l2tpns.c @@ -4,7 +4,7 @@ // Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced // vim: sw=8 ts=8 -char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.73.2.9 2005/05/16 04:51:42 bodea Exp $"; +char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.73.2.10 2005/05/23 13:48:29 bodea Exp $"; #include #include @@ -122,6 +122,7 @@ config_descriptt config_values[] = { CONFIG("cluster_interface", cluster_interface, STRING), CONFIG("cluster_hb_interval", cluster_hb_interval, INT), CONFIG("cluster_hb_timeout", cluster_hb_timeout, INT), + CONFIG("cluster_master_min_adv", cluster_master_min_adv, INT), { NULL, 0, 0, 0 }, }; @@ -2685,6 +2686,7 @@ static void initdata(int optdebug, char *optconfig) config->debug = optdebug; config->num_tbfs = MAXTBFS; config->rl_rate = 28; // 28kbps + config->cluster_master_min_adv = 1; if (!(tunnel = shared_malloc(sizeof(tunnelt) * MAXTUNNEL))) { diff --git a/l2tpns.h b/l2tpns.h index 068ec96..a5fbe8e 100644 --- a/l2tpns.h +++ b/l2tpns.h @@ -1,5 +1,5 @@ // L2TPNS Global Stuff -// $Id: l2tpns.h,v 1.49.2.12 2005/05/21 13:05:36 bodea Exp $ +// $Id: l2tpns.h,v 1.49.2.13 2005/05/23 13:48:29 bodea Exp $ #ifndef __L2TPNS_H__ #define __L2TPNS_H__ @@ -451,7 +451,8 @@ typedef struct char old_plugins[64][MAXPLUGINS]; int next_tbf; // Next HTB id available to use - int scheduler_fifo; // If the system has multiple CPUs, use FIFO scheduling policy for this process. + int scheduler_fifo; // If the system has multiple CPUs, use FIFO scheduling + // policy for this process. int lock_pages; // Lock pages into memory. int icmp_rate; // Max number of ICMP unreachable per second to send int max_packets; // DoS prevention: per session limit of packets/0.1s @@ -476,6 +477,10 @@ typedef struct int cluster_hb_timeout; // How many missed heartbeats trigger an election. uint64_t cluster_table_version; // # state changes processed by cluster + + int cluster_master_min_adv; // Master advertises routes while the number of up to date + // slaves is less than this value. + #ifdef BGP #define BGP_NUM_PEERS 2 uint16_t as_number; diff --git a/l2tpns.spec b/l2tpns.spec index 3280818..20e0f4f 100644 --- a/l2tpns.spec +++ b/l2tpns.spec @@ -43,5 +43,5 @@ rm -rf %{buildroot} %attr(644,root,root) /usr/share/man/man[58]/* %changelog -* Sun May 22 2005 Brendan O'Dea 2.0.21-1 +* Mon May 23 2005 Brendan O'Dea 2.0.21-1 - 2.0.21 release, see /usr/share/doc/l2tpns-2.0.21/Changes -- 2.20.1