aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2011-09-09 11:32:54 +0200
committerNatanael Copa <ncopa@alpinelinux.org>2011-09-09 11:49:15 +0200
commit78f7022bed26685f49dcbf7a5ab2489106bc1300 (patch)
treefab67a398f63d49efb0b34809adb7bbcaecf39ef
parent3236826dd6ae7f441f166ed1c58ffa328fc3b728 (diff)
downloadpingu-78f7022bed26685f49dcbf7a5ab2489106bc1300.tar.bz2
pingu-78f7022bed26685f49dcbf7a5ab2489106bc1300.tar.xz
pingu_netlink: delete the exact multipath we created
We need to keep track how we created the multipath and delete the corresponding.
-rw-r--r--pingu_iface.h1
-rw-r--r--pingu_netlink.c27
2 files changed, 21 insertions, 7 deletions
diff --git a/pingu_iface.h b/pingu_iface.h
index 154e972..7d3ad4c 100644
--- a/pingu_iface.h
+++ b/pingu_iface.h
@@ -17,6 +17,7 @@ struct pingu_iface {
int has_address;
int has_binding;
int has_route_rule;
+ int has_multipath;
int balance;
int balance_weight;
int fd;
diff --git a/pingu_netlink.c b/pingu_netlink.c
index c35e8f2..735df81 100644
--- a/pingu_netlink.c
+++ b/pingu_netlink.c
@@ -337,9 +337,9 @@ 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_iface *iface,
+ struct pingu_gateway *route)
{
- struct pingu_gateway *route = pingu_gateway_first_default(&iface->gateway_list);
if (route == NULL)
return 0;
netlink_add_subrtattr_addr_any(rta, 1024, RTA_GATEWAY,
@@ -352,12 +352,13 @@ static int add_one_nh(struct rtattr *rta, struct rtnexthop *rtnh,
}
static int add_nexthops(struct nlmsghdr *nlh, size_t nlh_size,
- struct list_head *iface_list)
+ struct list_head *iface_list, int action_type)
{
char buf[1024];
struct rtattr *rta = (void *)buf;
struct rtnexthop *rtnh;
struct pingu_iface *iface;
+ struct pingu_gateway *route;
int count = 0;
memset(buf, 0, sizeof(buf));
@@ -366,12 +367,24 @@ 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) {
- if ((!iface->balance) || iface->index == 0 || list_empty(&iface->gateway_list))
- continue;
+ route = pingu_gateway_first_default(&iface->gateway_list);
+ switch (action_type) {
+ case RTM_NEWROUTE:
+ if ((!iface->balance) || iface->index == 0
+ || route == NULL)
+ continue;
+ iface->has_multipath = 1;
+ break;
+ case RTM_DELROUTE:
+ if (!iface->has_multipath)
+ continue;
+ iface->has_multipath = 0;
+ break;
+ }
memset(rtnh, 0, sizeof(*rtnh));
rtnh->rtnh_len = sizeof(*rtnh);
rta->rta_len += rtnh->rtnh_len;
- count += add_one_nh(rta, rtnh, iface);
+ count += add_one_nh(rta, rtnh, iface, route);
rtnh = RTNH_NEXT(rtnh);
}
if (rta->rta_len > RTA_LENGTH(0))
@@ -411,7 +424,7 @@ int netlink_route_multipath(struct netlink_fd *fd, int action_type,
netlink_add_rtattr_addr_any(&req.nlh, sizeof(req), RTA_DST,
&dest);
- count = add_nexthops(&req.nlh, sizeof(req), iface_list);
+ count = add_nexthops(&req.nlh, sizeof(req), iface_list, action_type);
if (count == 0)
return 0;