aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pingu_host.c7
-rw-r--r--pingu_iface.c9
-rw-r--r--pingu_iface.h2
-rw-r--r--pingu_netlink.c13
-rw-r--r--pingu_netlink.h4
5 files changed, 31 insertions, 4 deletions
diff --git a/pingu_host.c b/pingu_host.c
index 427fe9a..640b928 100644
--- a/pingu_host.c
+++ b/pingu_host.c
@@ -1,4 +1,7 @@
+#include <arpa/inet.h>
+#include <linux/rtnetlink.h>
+
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
@@ -221,6 +224,7 @@ static void execute_action(const char *action)
int pingu_host_set_status(struct pingu_host *host, int status)
{
const char *action;
+ int route_action = 0;
host->burst.active = 0;
if (host->status == status) {
log_debug("%s: %s: status is still %i",
@@ -233,13 +237,16 @@ int pingu_host_set_status(struct pingu_host *host, int status)
switch (host->status) {
case 0:
action = host->down_action;
+ route_action = RTM_DELROUTE;
break;
case 1:
action = host->up_action;
+ route_action = RTM_NEWROUTE;
break;
}
if (action != NULL)
execute_action(action);
+ pingu_iface_update_routes(host->iface, route_action);
exec_route_change_hook();
return status;
}
diff --git a/pingu_iface.c b/pingu_iface.c
index 30cbe9a..78d8e9a 100644
--- a/pingu_iface.c
+++ b/pingu_iface.c
@@ -17,6 +17,7 @@
#include "pingu_host.h"
#include "pingu_iface.h"
#include "pingu_ping.h"
+#include "pingu_netlink.h"
#include "sockaddr_util.h"
static struct list_head iface_list = LIST_INITIALIZER(iface_list);
@@ -245,6 +246,14 @@ void pingu_iface_gw_action(struct pingu_iface *iface,
pingu_iface_gateway_dump(iface);
}
+void pingu_iface_update_routes(struct pingu_iface *iface, int action)
+{
+ struct pingu_gateway *route;
+ list_for_each_entry(route, &iface->gateway_list, gateway_list_entry) {
+ kernel_route_modify(action, route, iface, RT_TABLE_MAIN);
+ }
+}
+
int pingu_iface_init(struct ev_loop *loop, struct list_head *host_list)
{
struct pingu_host *host;
diff --git a/pingu_iface.h b/pingu_iface.h
index 0b52195..14aab04 100644
--- a/pingu_iface.h
+++ b/pingu_iface.h
@@ -40,4 +40,6 @@ void pingu_iface_set_addr(struct pingu_iface *iface, int family,
void pingu_iface_gw_action(struct pingu_iface *iface,
struct pingu_gateway *gw, int action);
+void pingu_iface_update_routes(struct pingu_iface *iface, int action);
+
#endif
diff --git a/pingu_netlink.c b/pingu_netlink.c
index 3ee0745..e16c2d0 100644
--- a/pingu_netlink.c
+++ b/pingu_netlink.c
@@ -416,7 +416,7 @@ static struct pingu_gateway *gw_from_rtmsg(struct pingu_gateway *gw,
}
static void log_route_change(struct pingu_gateway *route,
- struct pingu_iface *iface, int action)
+ char *ifname, int table, int action)
{
char deststr[64], gwstr[64];
char *actionstr = "New";
@@ -426,7 +426,7 @@ static void log_route_change(struct pingu_gateway *route,
sockaddr_to_string(&route->dest, deststr, sizeof(deststr));
sockaddr_to_string(&route->gw_addr, gwstr, sizeof(gwstr));
log_debug("%s route to %s via %s dev %s table %i", actionstr,
- deststr, gwstr, iface->name, iface->route_table);
+ deststr, gwstr, ifname, table);
}
static int is_default_gw(struct pingu_gateway *route)
@@ -465,7 +465,7 @@ static void netlink_route_cb_action(struct nlmsghdr *msg, int action)
if (iface == NULL)
return;
- log_route_change(&route, iface, action);
+ log_route_change(&route, iface->name, iface->route_table, action);
netlink_route_modify(&talk_fd, action, &route,
iface->index, iface->route_table);
@@ -553,6 +553,13 @@ error:
}
+int kernel_route_modify(int action, struct pingu_gateway *route,
+ struct pingu_iface *iface, int table)
+{
+ log_route_change(route, iface->name, table, action);
+ return netlink_route_modify(&talk_fd, action, route, iface->index, table);
+}
+
int kernel_init(struct ev_loop *loop)
{
int i;
diff --git a/pingu_netlink.h b/pingu_netlink.h
index 79fd673..95fb6f3 100644
--- a/pingu_netlink.h
+++ b/pingu_netlink.h
@@ -2,7 +2,9 @@
#define PINGU_NETLINK_H
#include <ev.h>
+#include "pingu_iface.h"
int kernel_init(struct ev_loop *loop);
-
+int kernel_route_modify(int action, struct pingu_gateway *route,
+ struct pingu_iface *iface, int table);
#endif