diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2011-08-05 12:56:16 +0200 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2011-08-05 13:02:48 +0200 |
commit | b0e778e4b6c39b50b697d049baea2a074a16b189 (patch) | |
tree | 337d47407488aa84369dc38cd95f8577021861c5 | |
parent | 8ef18a61f70a63bdbf8fb1ecbf8ab34a7f287663 (diff) | |
download | pingu-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-- | Makefile | 1 | ||||
-rw-r--r-- | pingu_gateway.c | 104 | ||||
-rw-r--r-- | pingu_gateway.h | 29 | ||||
-rw-r--r-- | pingu_iface.c | 115 | ||||
-rw-r--r-- | pingu_iface.h | 15 |
5 files changed, 145 insertions, 119 deletions
@@ -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; |