aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--pingu_gateway.c128
-rw-r--r--pingu_gateway.h30
-rw-r--r--pingu_iface.c20
-rw-r--r--pingu_iface.h6
-rw-r--r--pingu_netlink.c24
-rw-r--r--pingu_netlink.h2
-rw-r--r--pingu_route.c128
-rw-r--r--pingu_route.h30
9 files changed, 185 insertions, 185 deletions
diff --git a/Makefile b/Makefile
index 99df0bf..5a96546 100644
--- a/Makefile
+++ b/Makefile
@@ -32,11 +32,11 @@ pingu_OBJS = \
pingu_adm.o \
pingu_burst.o \
pingu_conf.o \
- pingu_gateway.o \
pingu_host.o \
pingu_iface.o \
pingu_netlink.o \
pingu_ping.o \
+ pingu_route.o \
sockaddr_util.o \
xlib.o
diff --git a/pingu_gateway.c b/pingu_gateway.c
deleted file mode 100644
index de9b094..0000000
--- a/pingu_gateway.c
+++ /dev/null
@@ -1,128 +0,0 @@
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "list.h"
-#include "log.h"
-#include "pingu_gateway.h"
-
-static void pingu_gateway_add_sorted(struct list_head *gateway_list,
- struct pingu_gateway *new_gw)
-{
- struct pingu_gateway *gw;
- list_for_each_entry(gw, gateway_list, gateway_list_entry) {
- if (gw->metric > new_gw->metric) {
- list_add_tail(&new_gw->gateway_list_entry,
- &gw->gateway_list_entry);
- return;
- }
- }
- list_add_tail(&new_gw->gateway_list_entry, gateway_list);
-}
-
-static struct pingu_gateway *pingu_gateway_clone(struct pingu_gateway *gw)
-{
- struct pingu_gateway *new_gw = calloc(1, sizeof(struct pingu_gateway));
- if (gw == NULL) {
- log_perror("Failed to allocate gateway");
- return NULL;
- }
- /* copy the fields without overwriting the list entry */
- memcpy(&new_gw->dest, &gw->dest, sizeof(new_gw->dest));
- memcpy(&new_gw->gw_addr, &gw->gw_addr, sizeof(new_gw->gw_addr));
- new_gw->dst_len = gw->dst_len;
- new_gw->src_len = gw->src_len;
- new_gw->metric = gw->metric;
- new_gw->protocol = gw->protocol;
- new_gw->scope = gw->scope;
- new_gw->type = gw->type;
- return new_gw;
-}
-
-static void log_debug_gw(char *msg, struct pingu_gateway *gw)
-{
- char destbuf[64], gwaddrbuf[64];
- log_debug("%s: %s/%i via %s metric %i", msg,
- sockaddr_to_string(&gw->dest, destbuf, sizeof(destbuf)),
- gw->dst_len,
- sockaddr_to_string(&gw->gw_addr, gwaddrbuf, sizeof(gwaddrbuf)),
- gw->metric);
-}
-
-static int gateway_cmp(struct pingu_gateway *a, struct pingu_gateway *b)
-{
- int r;
- if (a->dst_len != b->dst_len)
- return a->dst_len - b->dst_len;
- r = sockaddr_cmp(&a->dest, &b->dest);
- if (r != 0)
- return r;
- r = sockaddr_cmp(&a->gw_addr, &b->gw_addr);
- if (r != 0)
- return r;
- return a->metric - b->metric;
-}
-
-static struct pingu_gateway *pingu_gateway_get(struct list_head *gateway_list,
- struct pingu_gateway *gw)
-{
- struct pingu_gateway *entry;
- list_for_each_entry(entry, gateway_list, gateway_list_entry) {
- if (gateway_cmp(entry, gw) == 0)
- return entry;
- }
- return NULL;
-}
-
-void pingu_gateway_del_all(struct list_head *head)
-{
- struct pingu_gateway *gw, *n;
- list_for_each_entry_safe(gw, n, head, gateway_list_entry) {
- list_del(&gw->gateway_list_entry);
- free(gw);
- }
-}
-
-void pingu_gateway_add(struct list_head *gateway_list,
- struct pingu_gateway *gw)
-{
- struct pingu_gateway *new_gw = pingu_gateway_clone(gw);
- if (new_gw == NULL)
- return;
- pingu_gateway_add_sorted(gateway_list, new_gw);
-}
-
-void pingu_gateway_del(struct list_head *gateway_list,
- struct pingu_gateway *delete)
-{
- struct pingu_gateway *gw = pingu_gateway_get(gateway_list, delete);
- if (gw == NULL)
- return;
- log_debug_gw("removed", gw);
- list_del(&gw->gateway_list_entry);
- free(gw);
-}
-
-int is_default_gw(struct pingu_gateway *route)
-{
- switch (route->dest.sa.sa_family) {
- case AF_INET:
- return ((route->dest.sin.sin_addr.s_addr == 0)
- && (route->gw_addr.sin.sin_addr.s_addr != 0));
- break;
- case AF_INET6:
- log_debug("TODO: ipv6");
- break;
- }
- return 0;
-}
-
-struct pingu_gateway *pingu_gateway_first_default(struct list_head *gateway_list)
-{
- struct pingu_gateway *entry;
- list_for_each_entry(entry, gateway_list, gateway_list_entry) {
- if (is_default_gw(entry))
- return entry;
- }
- return NULL;
-}
diff --git a/pingu_gateway.h b/pingu_gateway.h
deleted file mode 100644
index b2f424f..0000000
--- a/pingu_gateway.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef PINGU_GATEWAY_H
-#define PINGU_GATEWAY_H
-
-#include "list.h"
-#include "sockaddr_util.h"
-
-struct pingu_gateway {
- union sockaddr_any gw_addr;
- union sockaddr_any dest;
- union sockaddr_any src;
- unsigned char dst_len;
- unsigned char src_len;
-
- int metric;
- unsigned char protocol;
- unsigned char scope;
- unsigned char type;
- struct list_head gateway_list_entry;
-};
-
-void pingu_gateway_del_all(struct list_head *head);
-void pingu_gateway_add(struct list_head *gateway_list,
- struct pingu_gateway *gw);
-void pingu_gateway_del(struct list_head *gateway_list,
- struct pingu_gateway *gw);
-int is_default_gw(struct pingu_gateway *route);
-struct pingu_gateway *pingu_gateway_first_default(struct list_head *gateway_list);
-
-
-#endif
diff --git a/pingu_iface.c b/pingu_iface.c
index 6816041..5ae0317 100644
--- a/pingu_iface.c
+++ b/pingu_iface.c
@@ -118,7 +118,7 @@ struct pingu_iface *pingu_iface_get_by_name_or_new(const char *name)
strlcpy(iface->name, name, sizeof(iface->name));
list_init(&iface->ping_list);
- list_init(&iface->gateway_list);
+ list_init(&iface->route_list);
list_add(&iface->iface_list_entry, &iface_list);
return iface;
}
@@ -130,7 +130,7 @@ void pingu_iface_set_addr(struct pingu_iface *iface, int family,
if (len <= 0 || data == NULL) {
iface->has_address = 0;
iface->has_binding = 0;
- pingu_gateway_del_all(&iface->gateway_list);
+ pingu_route_del_all(&iface->route_list);
log_debug("%s: address removed", iface->name);
return;
}
@@ -147,10 +147,10 @@ void pingu_iface_set_balance(struct pingu_iface *iface, int balance_weight)
}
#if 0
-void pingu_gateway_dump(struct pingu_iface *iface)
+void pingu_route_dump(struct pingu_iface *iface)
{
- struct pingu_gateway *gw;
- list_for_each_entry(gw, &iface->gateway_list, gateway_list_entry) {
+ struct pingu_route *gw;
+ list_for_each_entry(gw, &iface->route_list, route_list_entry) {
char buf[64];
sockaddr_to_string(&gw->gw_addr, buf, sizeof(buf));
log_debug("dump: %s: via %s metric %i", iface->name, buf,
@@ -160,15 +160,15 @@ void pingu_gateway_dump(struct pingu_iface *iface)
#endif
void pingu_iface_gw_action(struct pingu_iface *iface,
- struct pingu_gateway *gw, int action)
+ struct pingu_route *gw, int action)
{
switch (action) {
case RTM_NEWROUTE:
- pingu_gateway_add(&iface->gateway_list, gw);
+ pingu_route_add(&iface->route_list, gw);
log_debug("%s: added route", iface->name);
break;
case RTM_DELROUTE:
- pingu_gateway_del(&iface->gateway_list, gw);
+ pingu_route_del(&iface->route_list, gw);
log_debug("%s: removed route", iface->name);
break;
}
@@ -178,8 +178,8 @@ void pingu_iface_gw_action(struct pingu_iface *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) {
+ struct pingu_route *route;
+ list_for_each_entry(route, &iface->route_list, route_list_entry) {
if (is_default_gw(route) && iface->has_address)
kernel_route_modify(action, route, iface, RT_TABLE_MAIN);
}
diff --git a/pingu_iface.h b/pingu_iface.h
index 53e240e..14f8ba5 100644
--- a/pingu_iface.h
+++ b/pingu_iface.h
@@ -4,7 +4,7 @@
#include <netinet/in.h>
#include <ev.h>
-#include "pingu_gateway.h"
+#include "pingu_route.h"
#include "sockaddr_util.h"
#include "list.h"
@@ -25,7 +25,7 @@ struct pingu_iface {
int route_table;
struct list_head iface_list_entry;
struct list_head ping_list;
- struct list_head gateway_list;
+ struct list_head route_list;
struct ev_io socket_watcher;
};
@@ -41,7 +41,7 @@ void pingu_iface_set_addr(struct pingu_iface *iface, int family,
void *data, int len);
int pingu_iface_set_route_table(struct pingu_iface *iface, int table);
void pingu_iface_gw_action(struct pingu_iface *iface,
- struct pingu_gateway *gw, int action);
+ struct pingu_route *gw, int action);
void pingu_iface_update_routes(struct pingu_iface *iface, int action);
void pingu_iface_cleanup(void);
diff --git a/pingu_netlink.c b/pingu_netlink.c
index 5c6fba5..212e8e9 100644
--- a/pingu_netlink.c
+++ b/pingu_netlink.c
@@ -299,7 +299,7 @@ static int netlink_enumerate(struct netlink_fd *fd, int family, int type)
}
int netlink_route_modify(struct netlink_fd *fd, int action_type,
- struct pingu_gateway *route,
+ struct pingu_route *route,
int iface_index, int table)
{
struct {
@@ -339,7 +339,7 @@ int netlink_route_modify(struct netlink_fd *fd, int action_type,
static int add_one_nh(struct rtattr *rta, struct rtnexthop *rtnh,
struct pingu_iface *iface,
- struct pingu_gateway *route)
+ struct pingu_route *route)
{
if (route == NULL)
return 0;
@@ -359,7 +359,7 @@ static int add_nexthops(struct nlmsghdr *nlh, size_t nlh_size,
struct rtattr *rta = (void *)buf;
struct rtnexthop *rtnh;
struct pingu_iface *iface;
- struct pingu_gateway *route;
+ struct pingu_route *route;
struct pingu_host *host;
int count = 0;
@@ -369,7 +369,7 @@ static int add_nexthops(struct nlmsghdr *nlh, size_t nlh_size,
rtnh = RTA_DATA(rta);
list_for_each_entry(iface, iface_list, iface_list_entry) {
- route = pingu_gateway_first_default(&iface->gateway_list);
+ route = pingu_route_first_default(&iface->route_list);
switch (action_type) {
case RTM_NEWROUTE:
host = pingu_host_find_by_iface(iface);
@@ -440,14 +440,14 @@ int netlink_route_multipath(struct netlink_fd *fd, int action_type,
}
int netlink_route_replace_or_add(struct netlink_fd *fd,
- struct pingu_gateway *route,
+ struct pingu_route *route,
int iface_index, int table)
{
return netlink_route_modify(fd, RTM_NEWROUTE, route, iface_index, table);
}
int netlink_route_delete(struct netlink_fd *fd,
- struct pingu_gateway *route,
+ struct pingu_route *route,
int iface_index, int table)
{
return netlink_route_modify(fd, RTM_DELROUTE, route, iface_index, table);
@@ -455,9 +455,9 @@ int netlink_route_delete(struct netlink_fd *fd,
static void netlink_route_flush(struct netlink_fd *fd, struct pingu_iface *iface)
{
- struct pingu_gateway *gw;
+ struct pingu_route *gw;
int err;
- list_for_each_entry(gw, &iface->gateway_list, gateway_list_entry) {
+ list_for_each_entry(gw, &iface->route_list, route_list_entry) {
err = netlink_route_delete(fd, gw, iface->index, iface->route_table);
if (err > 0)
log_error("%s: Failed to clean up route in table %i: ",
@@ -609,7 +609,7 @@ static void netlink_addr_del_cb(struct nlmsghdr *nlmsg)
pingu_iface_set_addr(iface, 0, NULL, 0);
}
-static struct pingu_gateway *gw_from_rtmsg(struct pingu_gateway *gw,
+static struct pingu_route *gw_from_rtmsg(struct pingu_route *gw,
struct rtmsg *rtm,
struct rtattr **rta)
{
@@ -635,7 +635,7 @@ static struct pingu_gateway *gw_from_rtmsg(struct pingu_gateway *gw,
return gw;
}
-static void log_route_change(struct pingu_gateway *route,
+static void log_route_change(struct pingu_route *route,
char *ifname, int table, int action)
{
char deststr[64] = "", gwstr[64] = "", viastr[68] = "";
@@ -657,7 +657,7 @@ static void netlink_route_cb_action(struct nlmsghdr *msg, int action)
struct rtmsg *rtm = NLMSG_DATA(msg);
struct rtattr *rta[RTA_MAX+1];
- struct pingu_gateway route;
+ struct pingu_route route;
int err = 0;
/* ignore route changes that we made ourselves via talk_fd */
@@ -768,7 +768,7 @@ error:
}
-int kernel_route_modify(int action, struct pingu_gateway *route,
+int kernel_route_modify(int action, struct pingu_route *route,
struct pingu_iface *iface, int table)
{
log_route_change(route, iface->name, table, action);
diff --git a/pingu_netlink.h b/pingu_netlink.h
index be21b85..d65de1f 100644
--- a/pingu_netlink.h
+++ b/pingu_netlink.h
@@ -5,7 +5,7 @@
#include "pingu_iface.h"
int kernel_init(struct ev_loop *loop);
-int kernel_route_modify(int action, struct pingu_gateway *route,
+int kernel_route_modify(int action, struct pingu_route *route,
struct pingu_iface *iface, int table);
int kernel_route_multipath(int action, struct list_head *iface_list, int table);
void kernel_cleanup_iface_routes(struct pingu_iface *iface);
diff --git a/pingu_route.c b/pingu_route.c
new file mode 100644
index 0000000..efc8ad0
--- /dev/null
+++ b/pingu_route.c
@@ -0,0 +1,128 @@
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "list.h"
+#include "log.h"
+#include "pingu_route.h"
+
+static void pingu_route_add_sorted(struct list_head *route_list,
+ struct pingu_route *new_gw)
+{
+ struct pingu_route *gw;
+ list_for_each_entry(gw, route_list, route_list_entry) {
+ if (gw->metric > new_gw->metric) {
+ list_add_tail(&new_gw->route_list_entry,
+ &gw->route_list_entry);
+ return;
+ }
+ }
+ list_add_tail(&new_gw->route_list_entry, route_list);
+}
+
+static struct pingu_route *pingu_route_clone(struct pingu_route *gw)
+{
+ struct pingu_route *new_gw = calloc(1, sizeof(struct pingu_route));
+ if (gw == NULL) {
+ log_perror("Failed to allocate gateway");
+ return NULL;
+ }
+ /* copy the fields without overwriting the list entry */
+ memcpy(&new_gw->dest, &gw->dest, sizeof(new_gw->dest));
+ memcpy(&new_gw->gw_addr, &gw->gw_addr, sizeof(new_gw->gw_addr));
+ new_gw->dst_len = gw->dst_len;
+ new_gw->src_len = gw->src_len;
+ new_gw->metric = gw->metric;
+ new_gw->protocol = gw->protocol;
+ new_gw->scope = gw->scope;
+ new_gw->type = gw->type;
+ return new_gw;
+}
+
+static void log_debug_gw(char *msg, struct pingu_route *gw)
+{
+ char destbuf[64], gwaddrbuf[64];
+ log_debug("%s: %s/%i via %s metric %i", msg,
+ sockaddr_to_string(&gw->dest, destbuf, sizeof(destbuf)),
+ gw->dst_len,
+ sockaddr_to_string(&gw->gw_addr, gwaddrbuf, sizeof(gwaddrbuf)),
+ gw->metric);
+}
+
+static int gateway_cmp(struct pingu_route *a, struct pingu_route *b)
+{
+ int r;
+ if (a->dst_len != b->dst_len)
+ return a->dst_len - b->dst_len;
+ r = sockaddr_cmp(&a->dest, &b->dest);
+ if (r != 0)
+ return r;
+ r = sockaddr_cmp(&a->gw_addr, &b->gw_addr);
+ if (r != 0)
+ return r;
+ return a->metric - b->metric;
+}
+
+static struct pingu_route *pingu_route_get(struct list_head *route_list,
+ struct pingu_route *gw)
+{
+ struct pingu_route *entry;
+ list_for_each_entry(entry, route_list, route_list_entry) {
+ if (gateway_cmp(entry, gw) == 0)
+ return entry;
+ }
+ return NULL;
+}
+
+void pingu_route_del_all(struct list_head *head)
+{
+ struct pingu_route *gw, *n;
+ list_for_each_entry_safe(gw, n, head, route_list_entry) {
+ list_del(&gw->route_list_entry);
+ free(gw);
+ }
+}
+
+void pingu_route_add(struct list_head *route_list,
+ struct pingu_route *gw)
+{
+ struct pingu_route *new_gw = pingu_route_clone(gw);
+ if (new_gw == NULL)
+ return;
+ pingu_route_add_sorted(route_list, new_gw);
+}
+
+void pingu_route_del(struct list_head *route_list,
+ struct pingu_route *delete)
+{
+ struct pingu_route *gw = pingu_route_get(route_list, delete);
+ if (gw == NULL)
+ return;
+ log_debug_gw("removed", gw);
+ list_del(&gw->route_list_entry);
+ free(gw);
+}
+
+int is_default_gw(struct pingu_route *route)
+{
+ switch (route->dest.sa.sa_family) {
+ case AF_INET:
+ return ((route->dest.sin.sin_addr.s_addr == 0)
+ && (route->gw_addr.sin.sin_addr.s_addr != 0));
+ break;
+ case AF_INET6:
+ log_debug("TODO: ipv6");
+ break;
+ }
+ return 0;
+}
+
+struct pingu_route *pingu_route_first_default(struct list_head *route_list)
+{
+ struct pingu_route *entry;
+ list_for_each_entry(entry, route_list, route_list_entry) {
+ if (is_default_gw(entry))
+ return entry;
+ }
+ return NULL;
+}
diff --git a/pingu_route.h b/pingu_route.h
new file mode 100644
index 0000000..5badb10
--- /dev/null
+++ b/pingu_route.h
@@ -0,0 +1,30 @@
+#ifndef pingu_route_H
+#define pingu_route_H
+
+#include "list.h"
+#include "sockaddr_util.h"
+
+struct pingu_route {
+ union sockaddr_any gw_addr;
+ union sockaddr_any dest;
+ union sockaddr_any src;
+ unsigned char dst_len;
+ unsigned char src_len;
+
+ int metric;
+ unsigned char protocol;
+ unsigned char scope;
+ unsigned char type;
+ struct list_head route_list_entry;
+};
+
+void pingu_route_del_all(struct list_head *head);
+void pingu_route_add(struct list_head *route_list,
+ struct pingu_route *gw);
+void pingu_route_del(struct list_head *route_list,
+ struct pingu_route *gw);
+int is_default_gw(struct pingu_route *route);
+struct pingu_route *pingu_route_first_default(struct list_head *route_list);
+
+
+#endif