summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2011-11-13 17:12:49 +0100
committerFelix Fietkau <nbd@openwrt.org>2011-11-13 17:12:49 +0100
commite8714a2ef87d0741ca05e2ef30158452f30fed17 (patch)
tree4d223d367873e9310eb785090723d929211b517e
parentf88662d0361fa1561ee15f544934655a0dbc9414 (diff)
avoid deleting and re-adding duplicate ip addresses and routes, fixes tcp connection loss on dhcp rekey
-rw-r--r--interface-ip.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/interface-ip.c b/interface-ip.c
index 3db7e1a..75f2a8d 100644
--- a/interface-ip.c
+++ b/interface-ip.c
@@ -131,21 +131,25 @@ interface_update_proto_addr(struct vlist_tree *tree,
struct interface *iface;
struct device *dev;
struct device_addr *addr;
+ bool keep = false;
ip = container_of(tree, struct interface_ip_settings, addr);
iface = ip->iface;
dev = iface->l3_dev->dev;
+ if (node_old && node_new)
+ keep = true;
+
if (node_old) {
addr = container_of(node_old, struct device_addr, node);
- if (!(addr->flags & DEVADDR_EXTERNAL) && addr->enabled)
+ if (!(addr->flags & DEVADDR_EXTERNAL) && addr->enabled && !keep)
system_del_address(dev, addr);
free(addr);
}
if (node_new) {
addr = container_of(node_new, struct device_addr, node);
- if (!(addr->flags & DEVADDR_EXTERNAL))
+ if (!(addr->flags & DEVADDR_EXTERNAL) && !keep)
system_add_address(dev, addr);
addr->enabled = true;
}
@@ -159,24 +163,29 @@ interface_update_proto_route(struct vlist_tree *tree,
struct interface_ip_settings *ip;
struct interface *iface;
struct device *dev;
- struct device_route *route;
+ struct device_route *route_old, *route_new;
+ bool keep = false;
ip = container_of(tree, struct interface_ip_settings, route);
iface = ip->iface;
dev = iface->l3_dev->dev;
+ route_old = container_of(node_old, struct device_route, node);
+ route_new = container_of(node_new, struct device_route, node);
+
+ if (node_old && node_new)
+ keep = !memcmp(&route_old->nexthop, &route_new->nexthop, sizeof(route_old->nexthop));
+
if (node_old) {
- route = container_of(node_old, struct device_route, node);
- if (!(route->flags & DEVADDR_EXTERNAL) && route->enabled)
- system_del_route(dev, route);
- free(route);
+ if (!(route_old->flags & DEVADDR_EXTERNAL) && route_old->enabled && !keep)
+ system_del_route(dev, route_old);
+ free(route_old);
}
if (node_new) {
- route = container_of(node_new, struct device_route, node);
- if (!(route->flags & DEVADDR_EXTERNAL))
- system_add_route(dev, route);
- route->enabled = true;
+ if (!(route_new->flags & DEVADDR_EXTERNAL) && !keep)
+ system_add_route(dev, route_new);
+ route_new->enabled = true;
}
}