diff options
-rw-r--r-- | pingu_host.c | 7 | ||||
-rw-r--r-- | pingu_iface.c | 9 | ||||
-rw-r--r-- | pingu_iface.h | 2 | ||||
-rw-r--r-- | pingu_netlink.c | 13 | ||||
-rw-r--r-- | pingu_netlink.h | 4 |
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 |