aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2011-08-05 12:56:16 +0200
committerNatanael Copa <ncopa@alpinelinux.org>2011-08-05 13:02:48 +0200
commitb0e778e4b6c39b50b697d049baea2a074a16b189 (patch)
tree337d47407488aa84369dc38cd95f8577021861c5
parent8ef18a61f70a63bdbf8fb1ecbf8ab34a7f287663 (diff)
downloadpingu-b0e778e4b6c39b50b697d049baea2a074a16b189.tar.bz2
pingu-b0e778e4b6c39b50b697d049baea2a074a16b189.tar.xz
pingu_gateway: cleanup. split out gateway funcs
To make code cleaner we move all gateway functions to separate file and rename a few functions.
-rw-r--r--Makefile1
-rw-r--r--pingu_gateway.c104
-rw-r--r--pingu_gateway.h29
-rw-r--r--pingu_iface.c115
-rw-r--r--pingu_iface.h15
5 files changed, 145 insertions, 119 deletions
diff --git a/Makefile b/Makefile
index e054c85..c993407 100644
--- a/Makefile
+++ b/Makefile
@@ -19,6 +19,7 @@ pingu_OBJS = \
pingu.o \
pingu_burst.o \
pingu_conf.o \
+ pingu_gateway.o \
pingu_host.o \
pingu_iface.o \
pingu_netlink.o \
diff --git a/pingu_gateway.c b/pingu_gateway.c
new file mode 100644
index 0000000..cdc31c4
--- /dev/null
+++ b/pingu_gateway.c
@@ -0,0 +1,104 @@
+
+#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);
+}
diff --git a/pingu_gateway.h b/pingu_gateway.h
new file mode 100644
index 0000000..62c576b
--- /dev/null
+++ b/pingu_gateway.h
@@ -0,0 +1,29 @@
+#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);
+
+
+
+#endif
diff --git a/pingu_iface.c b/pingu_iface.c
index 8fc56d4..1cf4ca6 100644
--- a/pingu_iface.c
+++ b/pingu_iface.c
@@ -108,28 +108,19 @@ struct pingu_iface *pingu_iface_get_by_name_or_new(const char *name)
if (name != NULL)
strlcpy(iface->name, name, sizeof(iface->name));
-
+
list_init(&iface->ping_list);
list_init(&iface->gateway_list);
list_add(&iface->iface_list_entry, &iface_list);
return iface;
}
-void pingu_iface_flush_gateways(struct pingu_iface *iface)
-{
- struct pingu_gateway *gw, *n;
- list_for_each_entry_safe(gw, n, &iface->gateway_list, gateway_list_entry) {
- list_del(&gw->gateway_list_entry);
- free(gw);
- }
-}
-
void pingu_iface_set_addr(struct pingu_iface *iface, int family,
void *data, int len)
{
sockaddr_init(&iface->primary_addr, family, data);
if (len <= 0 || data == NULL) {
- pingu_iface_flush_gateways(iface);
+ pingu_gateway_del_all(&iface->gateway_list);
log_debug("%s: address removed", iface->name);
return;
}
@@ -137,21 +128,8 @@ void pingu_iface_set_addr(struct pingu_iface *iface, int family,
inet_ntoa(iface->primary_addr.sin.sin_addr));
}
-void pingu_gateway_add_sorted(struct pingu_iface *iface,
- struct pingu_gateway *new_gw)
-{
- struct pingu_gateway *gw;
- list_for_each_entry(gw, &iface->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, &iface->gateway_list);
-}
-
-void pingu_iface_gateway_dump(struct pingu_iface *iface)
+#if 0
+void pingu_gateway_dump(struct pingu_iface *iface)
{
struct pingu_gateway *gw;
list_for_each_entry(gw, &iface->gateway_list, gateway_list_entry) {
@@ -161,94 +139,21 @@ void pingu_iface_gateway_dump(struct pingu_iface *iface)
gw->metric);
}
}
+#endif
-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 pingu_iface *iface,
- struct pingu_gateway *gw)
-{
- struct pingu_gateway *entry;
- list_for_each_entry(entry, &iface->gateway_list, gateway_list_entry) {
- if (gateway_cmp(entry, gw) == 0)
- return entry;
- }
- return NULL;
-}
-
-void pingu_iface_add_gateway(struct pingu_iface *iface,
- struct pingu_gateway *gw)
-{
- struct pingu_gateway *new_gw = pingu_gateway_clone(gw);
- if (new_gw == NULL)
- return;
- pingu_gateway_add_sorted(iface, new_gw);
- log_debug("%s: added default gateway", iface->name);
-}
-
-void pingu_iface_del_gateway(struct pingu_iface *iface,
- struct pingu_gateway *delete)
-{
- struct pingu_gateway *gw = pingu_gateway_get(iface, delete);
- if (gw == NULL)
- return;
- log_debug_gw("removed", gw);
- list_del(&gw->gateway_list_entry);
- free(gw);
-}
-
-void pingu_iface_gw_action(struct pingu_iface *iface,
+void pingu_iface_gw_action(struct pingu_iface *iface,
struct pingu_gateway *gw, int action)
{
switch (action) {
case RTM_NEWROUTE:
- pingu_iface_add_gateway(iface, gw);
+ pingu_gateway_add(&iface->gateway_list, gw);
+ log_debug("%s: added default gateway", iface->name);
break;
case RTM_DELROUTE:
- pingu_iface_del_gateway(iface, gw);
+ pingu_gateway_del(&iface->gateway_list, gw);
+ log_debug("%s: removed default gateway", iface->name);
break;
}
- pingu_iface_gateway_dump(iface);
}
void pingu_iface_update_routes(struct pingu_iface *iface, int action)
diff --git a/pingu_iface.h b/pingu_iface.h
index 8107601..4ef67d4 100644
--- a/pingu_iface.h
+++ b/pingu_iface.h
@@ -4,25 +4,12 @@
#include <netinet/in.h>
#include <ev.h>
+#include "pingu_gateway.h"
#include "sockaddr_util.h"
#include "list.h"
#define PINGU_ROUTE_TABLE_AUTO -1
-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;
-};
-
struct pingu_iface {
char name[32];
int index;