summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hemminger <stephen.hemminger@vyatta.com>2008-12-19 13:25:41 -0800
committerStephen Hemminger <stephen.hemminger@vyatta.com>2008-12-19 13:55:41 -0800
commitd9730963f05555912e10d8c0d9d811eb10171f1e (patch)
tree2afabcd8bbdea91c05e3b27cd344b43568f9fa05
parent15085798710118c3dd09497ddc48c95be1fd0a29 (diff)
downloadquagga-d9730963f05555912e10d8c0d9d811eb10171f1e.tar.bz2
quagga-d9730963f05555912e10d8c0d9d811eb10171f1e.tar.xz
Handle rename to existing device
In the case of rename, delete_retain would be called twice. Once when the interface is removed from the system, and again when interface is being replaced during rename.
-rw-r--r--lib/if.c17
-rw-r--r--zebra/interface.c23
2 files changed, 24 insertions, 16 deletions
diff --git a/lib/if.c b/lib/if.c
index 7c4fb1a4..f15242a2 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -131,13 +131,14 @@ if_create (const char *name, int namelen)
ifp->name[namelen] = '\0';
listnode_add_sort (iflist, ifp);
- ifp->connected = list_new ();
- ifp->connected->del = (void (*) (void *)) connected_free;
-
- if (if_master.if_new_hook)
- (*if_master.if_new_hook) (ifp);
}
+ ifp->connected = list_new ();
+ ifp->connected->del = (void (*) (void *)) connected_free;
+
+ if (if_master.if_new_hook)
+ (*if_master.if_new_hook) (ifp);
+
return ifp;
}
@@ -149,7 +150,11 @@ if_delete_retain (struct interface *ifp)
(*if_master.if_delete_hook) (ifp);
/* Free connected address list */
- list_delete (ifp->connected);
+ if (ifp->connected)
+ {
+ list_delete (ifp->connected);
+ ifp->connected = NULL;
+ }
}
/* Delete and free interface structure. */
diff --git a/zebra/interface.c b/zebra/interface.c
index 12b2c500..75a3e1cb 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -102,6 +102,7 @@ if_zebra_delete_hook (struct interface *ifp)
route_table_finish (zebra_if->ipv4_subnets);
XFREE (MTYPE_TMP, zebra_if);
+ ifp->info = NULL;
}
return 0;
@@ -496,16 +497,18 @@ if_rename (struct interface *ifp, const char *name)
oifp = if_lookup_by_name(name);
if (oifp)
{
- if (oifp->ifindex != IFINDEX_INTERNAL)
- {
- zlog_warn ("interface rname %s to %s overlaps earlier interface",
- ifp->name, name);
- if_delete_update (oifp);
- }
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug ("interface %s superseded by rename of %s",
- oifp->name, ifp->name);
- if_delete (oifp);
+ if (oifp->ifindex != IFINDEX_INTERNAL)
+ {
+ zlog_err ("interface %s rename to %s overlaps with index %d",
+ ifp->name, name, oifp->ifindex);
+ if_delete_update (oifp);
+ }
+ else if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug ("interface %s index %d superseded by rename of %s",
+ oifp->name, oifp->ifindex, ifp->name);
+
+ listnode_delete (iflist, oifp);
+ XFREE (MTYPE_IF, oifp);
}
strncpy(ifp->name, name, INTERFACE_NAMSIZ);