aboutsummaryrefslogtreecommitdiffstats
path: root/pingu_iface.c
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2011-08-05 09:37:27 +0200
committerNatanael Copa <ncopa@alpinelinux.org>2011-08-05 09:46:34 +0200
commitdcd2b0e077ff2995660f15ef28580e8a002c5c5f (patch)
treea1e67a24467e5c9600fe738994cb7090ba6917d4 /pingu_iface.c
parentaff9e3e9c991544a8ade2b576da3690dc0dbb071 (diff)
downloadpingu-dcd2b0e077ff2995660f15ef28580e8a002c5c5f.tar.bz2
pingu-dcd2b0e077ff2995660f15ef28580e8a002c5c5f.tar.xz
pingu: implement new config format
New format allows users to define interfaces and ping hosts separately. This means we can run pingu in routing-only mode to set up and manage route tables for multi-isp. We allow the user config a preferred alternate route table for each interface. If not configured, pingu will pick one. Example interface definition looks like: interface eth0 { route-table 10 } Example host definition looks like: host 192.168.0.1 { bind-interface eth0 }
Diffstat (limited to 'pingu_iface.c')
-rw-r--r--pingu_iface.c50
1 files changed, 32 insertions, 18 deletions
diff --git a/pingu_iface.c b/pingu_iface.c
index 85d2524..8fc56d4 100644
--- a/pingu_iface.c
+++ b/pingu_iface.c
@@ -22,6 +22,10 @@
static struct list_head iface_list = LIST_INITIALIZER(iface_list);
+#define PINGU_ROUTE_TABLE_MIN 1
+#define PINGU_ROUTE_TABLE_MAX 253
+unsigned char used_route_table[256];
+
static void pingu_iface_socket_cb(struct ev_loop *loop, struct ev_io *w,
int revents)
{
@@ -71,10 +75,11 @@ struct pingu_iface *pingu_iface_get_by_name(const char *name)
struct pingu_iface *iface;
list_for_each_entry(iface, &iface_list, iface_list_entry) {
if (name == NULL) {
- if (iface->name[0] == '\n')
+ if (iface->name[0] == '\0')
return iface;
- } else if (strncmp(name, iface->name, sizeof(iface->name)) == 0)
+ } else if (strncmp(name, iface->name, sizeof(iface->name)) == 0) {
return iface;
+ }
}
return NULL;
}
@@ -89,7 +94,7 @@ struct pingu_iface *pingu_iface_get_by_index(int index)
return NULL;
}
-struct pingu_iface *pingu_iface_new(const char *name)
+struct pingu_iface *pingu_iface_get_by_name_or_new(const char *name)
{
struct pingu_iface *iface = pingu_iface_get_by_name(name);
if (iface != NULL)
@@ -254,27 +259,36 @@ void pingu_iface_update_routes(struct pingu_iface *iface, int action)
}
}
-int pingu_iface_init(struct ev_loop *loop, struct list_head *host_list)
+int pingu_iface_set_route_table(struct pingu_iface *iface, int table)
{
- struct pingu_host *host;
- struct pingu_iface *iface;
- int autotbl = 10;
- list_for_each_entry(host, host_list, host_list_entry) {
- iface = pingu_iface_get_by_name(host->interface);
- if (iface == NULL) {
- iface = pingu_iface_new(host->interface);
- iface->route_table = autotbl++;
- }
- if (iface == NULL)
- return -1;
- host->iface = iface;
+ static int initialized = 0;
+ int i = 1;
+ if (!initialized) {
+ memset(used_route_table, 0, sizeof(used_route_table));
+ initialized = 1;
+ }
+ if (table == PINGU_ROUTE_TABLE_AUTO) {
+ while (i < 253 && used_route_table[i])
+ i++;
+ table = i;
}
+ if (table < PINGU_ROUTE_TABLE_MIN || table >= PINGU_ROUTE_TABLE_MAX) {
+ log_error("Invalid route table %i", table);
+ return -1;
+ }
+ used_route_table[table] = 1;
+ iface->route_table = table;
+ return table;
+}
+int pingu_iface_init(struct ev_loop *loop)
+{
+ struct pingu_iface *iface;
list_for_each_entry(iface, &iface_list, iface_list_entry) {
+ if (iface->route_table == 0)
+ pingu_iface_set_route_table(iface, PINGU_ROUTE_TABLE_AUTO);
if (pingu_iface_init_socket(loop, iface) == -1)
return -1;
}
-
return 0;
}
-