summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Larson <slioch@eng-140.vyatta.com>2008-01-11 17:26:17 -0800
committerMichael Larson <slioch@eng-140.vyatta.com>2008-01-11 17:26:17 -0800
commit23134a43b8fbb165de1837a388a3dd00064e55cd (patch)
tree467edc9a9f421104dda26ea17f24b3579864512e
parent4430a9399faf5abd7247c01bbab25d9624ce5ea8 (diff)
downloadquagga-23134a43b8fbb165de1837a388a3dd00064e55cd.tar.bz2
quagga-23134a43b8fbb165de1837a388a3dd00064e55cd.tar.xz
added support for filtering of interfaces. filter or exclusion list needs to be be written to exclude
file located in linstatus directory. watchlink accepts sigusr1 to reload filter without requiring restart on configuration change.
-rw-r--r--watchlink/netlink_listener.cc15
-rw-r--r--watchlink/netlink_listener.hh4
-rw-r--r--watchlink/watchlink.cc58
3 files changed, 73 insertions, 4 deletions
diff --git a/watchlink/netlink_listener.cc b/watchlink/netlink_listener.cc
index 6c9fcc51..a13be216 100644
--- a/watchlink/netlink_listener.cc
+++ b/watchlink/netlink_listener.cc
@@ -134,6 +134,21 @@ NetlinkListener::init()
*
**/
bool
+NetlinkListener::process(NetlinkEvent &e, set<string> filter)
+{
+ bool state = process(e);
+ if (state == true && filter.find(e.get_iface()) != filter.end()) {
+ e = NetlinkEvent();
+ state = false;
+ }
+ return state;
+}
+
+/**
+ *
+ *
+ **/
+bool
NetlinkListener::process(NetlinkEvent &e)
{
if (_fd <= 0) {
diff --git a/watchlink/netlink_listener.hh b/watchlink/netlink_listener.hh
index 5b5a3ca7..b73130fd 100644
--- a/watchlink/netlink_listener.hh
+++ b/watchlink/netlink_listener.hh
@@ -29,6 +29,7 @@
#define __NETLINK_LISTENER_HH__
#include "netlink_event.hh"
+#include <set>
#include <string>
class NetlinkListener
@@ -46,6 +47,9 @@ public: //methods
bool
process(NetlinkEvent &e);
+ bool
+ process(NetlinkEvent &e, std::set<std::string> filter);
+
int
get_sock() {return _fd;}
diff --git a/watchlink/watchlink.cc b/watchlink/watchlink.cc
index aee53d09..8d2f0239 100644
--- a/watchlink/watchlink.cc
+++ b/watchlink/watchlink.cc
@@ -29,13 +29,16 @@
#include <iostream>
#include <stdio.h>
#include <string>
+#include <set>
#include <fcntl.h>
#include <syslog.h>
#include <errno.h>
#include <linux/types.h>
#include <sys/socket.h>
+#include <signal.h>
#include <linux/rtnetlink.h>
+#include "rl_str_proc.hh"
#include "netlink_send.hh"
#include "netlink_listener.hh"
#include "netlink_linkstatus.hh"
@@ -52,6 +55,8 @@ struct option longopts[] =
{ 0 }
};
+set<string> g_exclude;
+string g_link_dir = "/var/linkstatus";
/**
*
@@ -73,11 +78,52 @@ usage()
*
*
**/
+set<string>
+load_exclusion_file(const string &link_dir)
+{
+ set<string> coll;
+
+ string file = link_dir + "/exclude";
+ FILE *fp = fopen(file.c_str(), "r");
+ if (fp == NULL) {
+ syslog(LOG_ERR,"load_exclusion_file(), failed to open state file");
+ cerr << "load_exclusion_file(), failed to open state file" << endl;
+ return coll; //means we are still up, ignore...
+ }
+
+ char str[1025];
+ while (fgets(str, 1024, fp)) {
+ string line(str);
+
+ StrProc tokens(line, ",");
+ for (int i = 0; i < tokens.size(); ++i) {
+ coll.insert(tokens.get(i));
+ }
+ }
+ fclose(fp);
+ return coll;
+}
+
+/**
+ *
+ *
+ **/
+static void
+sig_user(int signo)
+{
+ //reload interface exclusion list
+ g_exclude = load_exclusion_file(g_link_dir);
+}
+
+
+/**
+ *
+ *
+ **/
int
main(int argc, char* const argv[])
{
int ch;
- string link_dir = "/var/linkstatus";
bool send_request = false;
bool debug = false;
bool daemon = false;
@@ -94,7 +140,7 @@ main(int argc, char* const argv[])
send_request = true;
break;
case 'l':
- link_dir = optarg;
+ g_link_dir = optarg;
break;
case 'i':
pid_path = optarg;
@@ -129,6 +175,10 @@ main(int argc, char* const argv[])
pid_output(pid_path.c_str());
}
+ //load interface exclusion list
+ g_exclude = load_exclusion_file(g_link_dir);
+
+ signal(SIGUSR1, sig_user);
int sock = nl_listener.init();
if (sock <= 0) {
@@ -149,13 +199,13 @@ main(int argc, char* const argv[])
}
}
- NetlinkLinkStatus nl_ls(sock, link_dir, debug);
+ NetlinkLinkStatus nl_ls(sock, g_link_dir, debug);
while (true) {
// cout << "watchlink: now entering listening mode: " << endl;
NetlinkEvent nl_event;
- if (nl_listener.process(nl_event) == true) {
+ if (nl_listener.process(nl_event, g_exclude) == true) {
if (send_request) {
if (nl_send.send_get(sock, RTM_GETADDR) != 0) {
syslog(LOG_ERR,"watchlink(), error sending. exiting..");