aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pingu_iface.c3
-rw-r--r--pingu_iface.h1
-rw-r--r--pingu_netlink.c13
-rw-r--r--pingu_netlink.h2
4 files changed, 15 insertions, 4 deletions
diff --git a/pingu_iface.c b/pingu_iface.c
index e2f3c3f..6c5ae2e 100644
--- a/pingu_iface.c
+++ b/pingu_iface.c
@@ -212,7 +212,8 @@ void pingu_iface_cleanup(void)
{
struct pingu_iface *iface;
list_for_each_entry(iface, &iface_list, iface_list_entry) {
- kernel_cleanup_iface(iface);
+ if (iface->has_route_rule)
+ kernel_cleanup_iface_routes(iface);
close(iface->fd);
}
}
diff --git a/pingu_iface.h b/pingu_iface.h
index 87f78e4..154e972 100644
--- a/pingu_iface.h
+++ b/pingu_iface.h
@@ -16,6 +16,7 @@ struct pingu_iface {
int has_link;
int has_address;
int has_binding;
+ int has_route_rule;
int balance;
int balance_weight;
int fd;
diff --git a/pingu_netlink.c b/pingu_netlink.c
index c232f28..c685df2 100644
--- a/pingu_netlink.c
+++ b/pingu_netlink.c
@@ -550,6 +550,8 @@ static void netlink_addr_new_cb(struct nlmsghdr *msg)
RTA_PAYLOAD(rta[IFA_LOCAL]));
pingu_iface_bind_socket(iface, 1);
err = netlink_rule_replace_or_add(&talk_fd, iface);
+ if (err == 0)
+ iface->has_route_rule = 1;
if (err > 0)
log_error("%s: Failed to add route rule: %s", iface->name,
strerror(err));
@@ -784,9 +786,16 @@ err_close_all:
return FALSE;
}
-void kernel_cleanup_iface(struct pingu_iface *iface)
+void kernel_cleanup_iface_routes(struct pingu_iface *iface)
{
- netlink_rule_del(&talk_fd, iface);
+ int err = 0;
+ if (iface->has_route_rule) {
+ err = netlink_rule_del(&talk_fd, iface);
+ if (err == 0)
+ iface->has_route_rule = 0;
+ if (err > 0)
+ log_error("Failed to delete route rule for %s", iface->name);
+ }
}
void kernel_close(void)
diff --git a/pingu_netlink.h b/pingu_netlink.h
index 3298964..be21b85 100644
--- a/pingu_netlink.h
+++ b/pingu_netlink.h
@@ -8,7 +8,7 @@ int kernel_init(struct ev_loop *loop);
int kernel_route_modify(int action, struct pingu_gateway *route,
struct pingu_iface *iface, int table);
int kernel_route_multipath(int action, struct list_head *iface_list, int table);
-void kernel_cleanup_iface(struct pingu_iface *iface);
+void kernel_cleanup_iface_routes(struct pingu_iface *iface);
void kernel_close(void);
#endif