diff options
author | Martin Mares <mj@ucw.cz> | 1999-03-26 22:33:36 +0100 |
---|---|---|
committer | Martin Mares <mj@ucw.cz> | 1999-03-26 22:33:36 +0100 |
commit | b5239f223874b87dd7c9de4d624cdf1230022111 (patch) | |
tree | 36c5ec9add41e42ca48343bd4e1663ecd79fb5bd /nest | |
parent | f79a749d0b9a5a7509db9ad6c547bbabc0457675 (diff) | |
download | bird-b5239f223874b87dd7c9de4d624cdf1230022111.tar bird-b5239f223874b87dd7c9de4d624cdf1230022111.zip |
Don't try to manipulate neighbor lists for copied interface structures.
This avoids few nasty references to free memory.
Diffstat (limited to 'nest')
-rw-r--r-- | nest/iface.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/nest/iface.c b/nest/iface.c index 9a02a3f..002646b 100644 --- a/nest/iface.c +++ b/nest/iface.c @@ -144,7 +144,7 @@ neigh_if_down(struct iface *i) for(m=i->neigh; n = m;) { m = n->sibling; - DBG("Flushing neighbor %I on %s\n", n->addr, n->iface->name); + DBG("Flushing neighbor %I on %s\n", n->addr, i->name); n->iface = NULL; if (n->proto->neigh_notify && n->proto->core_state != FS_FLUSHING) n->proto->neigh_notify(n); @@ -153,8 +153,8 @@ neigh_if_down(struct iface *i) rem_node(&n->n); sl_free(neigh_slab, n); } - i->neigh = NULL; } + i->neigh = NULL; } void @@ -248,6 +248,7 @@ if_copy(struct iface *to, struct iface *from) to->flags = from->flags; to->mtu = from->mtu; to->index = from->index; + to->neigh = from->neigh; } static unsigned @@ -270,7 +271,7 @@ if_changed(struct iface *i, struct iface *j) } static void -if_notify_change(unsigned c, struct iface *old, struct iface *new) +if_notify_change(unsigned c, struct iface *old, struct iface *new, struct iface *real) { struct proto *p; @@ -281,14 +282,14 @@ if_notify_change(unsigned c, struct iface *old, struct iface *new) if_dump(new); if (c & IF_CHANGE_UP) - neigh_if_up(new); + neigh_if_up(real); WALK_LIST(p, proto_list) if (p->if_notify) p->if_notify(p, c, new, old); if (c & IF_CHANGE_DOWN) - neigh_if_down(old); + neigh_if_down(real); } void @@ -310,15 +311,17 @@ if_update(struct iface *new) DBG("Interface %s changed too much -- forcing down/up transition\n", i->name); if (i->flags & IF_UP) { + struct iface j; + memcpy(&j, i, sizeof(struct iface)); i->flags &= ~IF_UP; - if_notify_change(IF_CHANGE_DOWN | IF_CHANGE_FLAGS, i, NULL); + if_notify_change(IF_CHANGE_DOWN | IF_CHANGE_FLAGS, &j, i, i); } rem_node(&i->n); goto newif; } c = if_changed(i, new); if (c) - if_notify_change(c, i, new); + if_notify_change(c, i, new, i); if_copy(i, new); /* Even if c==0 as we might need to update i->index et al. */ i->flags |= IF_UPDATED; return; @@ -330,7 +333,7 @@ newif: i->flags |= IF_UPDATED; add_tail(&iface_list, &i->n); if_notify_change(IF_CHANGE_CREATE | ((i->flags & IF_UP) ? IF_CHANGE_UP : 0) - | IF_CHANGE_FLAGS | IF_CHANGE_MTU, NULL, i); + | IF_CHANGE_FLAGS | IF_CHANGE_MTU, NULL, i, i); } void @@ -356,7 +359,7 @@ if_end_update(void) memcpy(&j, i, sizeof(struct iface)); i->flags = (i->flags & ~(IF_LINK_UP | IF_UP)) | IF_ADMIN_DOWN; if (i->flags != j.flags) - if_notify_change(IF_CHANGE_DOWN | IF_CHANGE_FLAGS, &j, i); + if_notify_change(IF_CHANGE_DOWN | IF_CHANGE_FLAGS, &j, i, i); } } |