Re: ospf6d crashes on interface add

2011-07-06 Thread Claudio Jeker
On Thu, Jul 07, 2011 at 06:57:30AM +0200, Claudio Jeker wrote:
> On Wed, Jun 01, 2011 at 10:46:29PM +0200, Martin Pelikan wrote:
> > Hi!
> > 
> > So my last attempt wasn't met with much appreciation, so I'll slow down:
> > 
> > - when I add a vlan(4), vether(4) or something, my ospf6d dies
> > - I don't like that
> > - therefore, with new release comes new diff
> > - this time I tried to make it as small as possible, in separate parts
> > 
> > It doesn't fix departures (if_leave_group jumps on a non-existing
> > interface), but I guess people don't remove interfaces that often. 
> > I will rewrite and post the rest of the big one if someone shows
> > interest in this bit.
> > 
> 
> The diff is somewhat wrong and confused me for a few days until my brain
> got kickstarted with some good scotch.
> The problem is not IFADD/IFDELETE but IFADDRADD and IFADDRDEL. The ospf
> engine should only have interfaces that are configured in their interface
> list (aka cflags & F_IFACE_CONFIGURED) the other interfaces do not matter
> at all and only the parent needs to track them.
> 
> So here is a what I suppose as a fix for this problem. This seems to work
> acording to my quick testing.
> -- 
> :wq Claudio
> 
> Index: kroute.c
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/kroute.c,v
> retrieving revision 1.33
> diff -u -p -r1.33 kroute.c
> --- kroute.c  7 Jul 2011 03:56:59 -   1.33
> +++ kroute.c  7 Jul 2011 04:52:53 -
> @@ -812,10 +812,13 @@ if_change(u_short ifindex, int flags, st
>   if (wasvalid == isvalid)
>   return; /* nothing changed wrt validity */
>  
> - /* notify ospfe about interface link state */
> - if (iface->cflags & F_IFACE_CONFIGURED)
> + /* inform engine and rde about state change if interface is used */
> + if (iface->cflags & F_IFACE_CONFIGURED) {
>   main_imsg_compose_ospfe(IMSG_IFINFO, 0, iface,
>   sizeof(struct iface));
> + main_imsg_compose_rde(IMSG_IFINFO, 0, iface,
> + sizeof(struct iface));
> + }
>  
>   /* update redistribute list */
>   RB_FOREACH(kr, kroute_tree, &krt) {

Ugh, this hunk belongs to an other diff and needs to be removed.
Fixed diff below

-- 
:wq Claudio

Index: kroute.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/kroute.c,v
retrieving revision 1.33
diff -u -p -r1.33 kroute.c
--- kroute.c7 Jul 2011 03:56:59 -   1.33
+++ kroute.c7 Jul 2011 04:52:53 -
@@ -899,12 +902,15 @@ if_newaddr(u_short ifindex, struct socka
}
 
TAILQ_INSERT_TAIL(&iface->ifa_list, ia, entry);
-   ifc.addr = ia->addr;
-   ifc.dstbrd = ia->dstbrd;
-   ifc.prefixlen = ia->prefixlen;
-   ifc.ifindex = ifindex;
-   main_imsg_compose_ospfe(IMSG_IFADDRNEW, 0, &ifc, sizeof(ifc));
-   main_imsg_compose_rde(IMSG_IFADDRNEW, 0, &ifc, sizeof(ifc));
+   /* inform engine and rde if interface is used */
+   if (iface->cflags & F_IFACE_CONFIGURED) {
+   ifc.addr = ia->addr;
+   ifc.dstbrd = ia->dstbrd;
+   ifc.prefixlen = ia->prefixlen;
+   ifc.ifindex = ifindex;
+   main_imsg_compose_ospfe(IMSG_IFADDRNEW, 0, &ifc, sizeof(ifc));
+   main_imsg_compose_rde(IMSG_IFADDRNEW, 0, &ifc, sizeof(ifc));
+   }
 }
 
 void
@@ -944,14 +950,17 @@ if_deladdr(u_short ifindex, struct socka
log_debug("if_deladdr: ifindex %u, addr %s/%d",
ifindex, log_in6addr(&ia->addr), ia->prefixlen);
TAILQ_REMOVE(&iface->ifa_list, ia, entry);
-   ifc.addr = ia->addr;
-   ifc.dstbrd = ia->dstbrd;
-   ifc.prefixlen = ia->prefixlen;
-   ifc.ifindex = ifindex;
-   main_imsg_compose_ospfe(IMSG_IFADDRDEL, 0, &ifc,
-   sizeof(ifc));
-   main_imsg_compose_rde(IMSG_IFADDRDEL, 0, &ifc,
-   sizeof(ifc));
+   /* inform engine and rde if interface is used */
+   if (iface->cflags & F_IFACE_CONFIGURED) {
+   ifc.addr = ia->addr;
+   ifc.dstbrd = ia->dstbrd;
+   ifc.prefixlen = ia->prefixlen;
+   ifc.ifindex = ifindex;
+   main_imsg_compose_ospfe(IMSG_IFADDRDEL, 0, &ifc,
+   sizeof(ifc));
+   main_imsg_compose_rde(IMSG_IFADDRDEL, 0, &ifc,
+   sizeof(ifc));
+   }
free(ia);
return;
}



Re: ospf6d crashes on interface add

2011-07-06 Thread Claudio Jeker
On Wed, Jun 01, 2011 at 10:46:29PM +0200, Martin Pelikan wrote:
> Hi!
> 
> So my last attempt wasn't met with much appreciation, so I'll slow down:
> 
> - when I add a vlan(4), vether(4) or something, my ospf6d dies
> - I don't like that
> - therefore, with new release comes new diff
> - this time I tried to make it as small as possible, in separate parts
> 
> It doesn't fix departures (if_leave_group jumps on a non-existing
> interface), but I guess people don't remove interfaces that often. 
> I will rewrite and post the rest of the big one if someone shows
> interest in this bit.
> 

The diff is somewhat wrong and confused me for a few days until my brain
got kickstarted with some good scotch.
The problem is not IFADD/IFDELETE but IFADDRADD and IFADDRDEL. The ospf
engine should only have interfaces that are configured in their interface
list (aka cflags & F_IFACE_CONFIGURED) the other interfaces do not matter
at all and only the parent needs to track them.

So here is a what I suppose as a fix for this problem. This seems to work
acording to my quick testing.
-- 
:wq Claudio

Index: kroute.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/kroute.c,v
retrieving revision 1.33
diff -u -p -r1.33 kroute.c
--- kroute.c7 Jul 2011 03:56:59 -   1.33
+++ kroute.c7 Jul 2011 04:52:53 -
@@ -812,10 +812,13 @@ if_change(u_short ifindex, int flags, st
if (wasvalid == isvalid)
return; /* nothing changed wrt validity */
 
-   /* notify ospfe about interface link state */
-   if (iface->cflags & F_IFACE_CONFIGURED)
+   /* inform engine and rde about state change if interface is used */
+   if (iface->cflags & F_IFACE_CONFIGURED) {
main_imsg_compose_ospfe(IMSG_IFINFO, 0, iface,
sizeof(struct iface));
+   main_imsg_compose_rde(IMSG_IFINFO, 0, iface,
+   sizeof(struct iface));
+   }
 
/* update redistribute list */
RB_FOREACH(kr, kroute_tree, &krt) {
@@ -899,12 +902,15 @@ if_newaddr(u_short ifindex, struct socka
}
 
TAILQ_INSERT_TAIL(&iface->ifa_list, ia, entry);
-   ifc.addr = ia->addr;
-   ifc.dstbrd = ia->dstbrd;
-   ifc.prefixlen = ia->prefixlen;
-   ifc.ifindex = ifindex;
-   main_imsg_compose_ospfe(IMSG_IFADDRNEW, 0, &ifc, sizeof(ifc));
-   main_imsg_compose_rde(IMSG_IFADDRNEW, 0, &ifc, sizeof(ifc));
+   /* inform engine and rde if interface is used */
+   if (iface->cflags & F_IFACE_CONFIGURED) {
+   ifc.addr = ia->addr;
+   ifc.dstbrd = ia->dstbrd;
+   ifc.prefixlen = ia->prefixlen;
+   ifc.ifindex = ifindex;
+   main_imsg_compose_ospfe(IMSG_IFADDRNEW, 0, &ifc, sizeof(ifc));
+   main_imsg_compose_rde(IMSG_IFADDRNEW, 0, &ifc, sizeof(ifc));
+   }
 }
 
 void
@@ -944,14 +950,17 @@ if_deladdr(u_short ifindex, struct socka
log_debug("if_deladdr: ifindex %u, addr %s/%d",
ifindex, log_in6addr(&ia->addr), ia->prefixlen);
TAILQ_REMOVE(&iface->ifa_list, ia, entry);
-   ifc.addr = ia->addr;
-   ifc.dstbrd = ia->dstbrd;
-   ifc.prefixlen = ia->prefixlen;
-   ifc.ifindex = ifindex;
-   main_imsg_compose_ospfe(IMSG_IFADDRDEL, 0, &ifc,
-   sizeof(ifc));
-   main_imsg_compose_rde(IMSG_IFADDRDEL, 0, &ifc,
-   sizeof(ifc));
+   /* inform engine and rde if interface is used */
+   if (iface->cflags & F_IFACE_CONFIGURED) {
+   ifc.addr = ia->addr;
+   ifc.dstbrd = ia->dstbrd;
+   ifc.prefixlen = ia->prefixlen;
+   ifc.ifindex = ifindex;
+   main_imsg_compose_ospfe(IMSG_IFADDRDEL, 0, &ifc,
+   sizeof(ifc));
+   main_imsg_compose_rde(IMSG_IFADDRDEL, 0, &ifc,
+   sizeof(ifc));
+   }
free(ia);
return;
}



Re: ospf6d crashes on interface add

2011-06-16 Thread Andre Keller
Hi Martin

thanks for your patch. This patch works for me on OpenBSD 4.9-stable and
-current. Still some issues left but at least ospf6d does not crash on
interface add...

it would be really nice if this gets into the tree...


Am 01.06.2011 22:46, schrieb Martin Pelikan:
> Hi!
>
> So my last attempt wasn't met with much appreciation, so I'll slow down:
>
> - when I add a vlan(4), vether(4) or something, my ospf6d dies
> - I don't like that
> - therefore, with new release comes new diff
> - this time I tried to make it as small as possible, in separate parts
>
> It doesn't fix departures (if_leave_group jumps on a non-existing
> interface), but I guess people don't remove interfaces that often. 
> I will rewrite and post the rest of the big one if someone shows
> interest in this bit.
>
> --
> Martin Pelikan
>
>
> Index: kroute.c
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/kroute.c,v
> retrieving revision 1.30
> diff -u -p -r1.30 kroute.c
> --- kroute.c  7 Mar 2011 07:43:02 -   1.30
> +++ kroute.c  1 Jun 2011 20:36:31 -
> @@ -973,15 +973,22 @@ if_announce(void *msg)
>   if ((iface = if_new(ifan->ifan_index, ifan->ifan_name)) == NULL)
>   fatal("if_announce failed");
>   iface->cflags |= F_IFACE_AVAIL;
> + main_imsg_compose_rde(IMSG_IFADD, 0,
> + iface, sizeof(struct iface));
> + main_imsg_compose_ospfe(IMSG_IFADD, 0,
> + iface, sizeof(struct iface));
>   break;
>   case IFAN_DEPARTURE:
> - iface = if_find(ifan->ifan_index);
> - if (iface->cflags & F_IFACE_CONFIGURED) {
> - main_imsg_compose_rde(IMSG_IFDELETE, 0,
> - &iface->ifindex, sizeof(iface->ifindex));
> - main_imsg_compose_ospfe(IMSG_IFDELETE, 0,
> - &iface->ifindex, sizeof(iface->ifindex));
> + if ((iface = if_find(ifan->ifan_index)) == NULL)  {
> + log_warn("someone announced departure of non-existing "
> + "interface %s - possible race condition?",
> + ifan->ifan_name);
> + return;
>   }
> + main_imsg_compose_rde(IMSG_IFDELETE, 0,
> + &iface->ifindex, sizeof(iface->ifindex));
> + main_imsg_compose_ospfe(IMSG_IFDELETE, 0,
> + &iface->ifindex, sizeof(iface->ifindex));
>   if_del(iface);
>   break;
>   }
> Index: ospfe.c
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/ospfe.c,v
> retrieving revision 1.34
> diff -u -p -r1.34 ospfe.c
> --- ospfe.c   2 May 2011 09:24:00 -   1.34
> +++ ospfe.c   1 Jun 2011 20:36:31 -
> @@ -299,16 +299,16 @@ ospfe_dispatch_main(int fd, short event,
>   }
>   break;
>   case IMSG_IFADD:
> - if ((iface = malloc(sizeof(struct iface))) == NULL)
> - fatal(NULL);
> - memcpy(iface, imsg.data, sizeof(struct iface));
> + ifp = imsg.data;
> + if ((iface = if_new(ifp->ifindex, ifp->name)) == NULL)
> + fatalx("IFADD in ospfe");
>  
> - LIST_INIT(&iface->nbr_list);
> - TAILQ_INIT(&iface->ls_ack_list);
> - RB_INIT(&iface->lsa_tree);
> + /* ifaces from config belong to some area */
> + if ((iface->cflags & F_IFACE_CONFIGURED) &&
> + (area = area_find(oeconf, iface->area_id)) != NULL)
> + LIST_INSERT_HEAD(&area->iface_list, iface,
> + entry);
>  
> - area = area_find(oeconf, iface->area_id);
> - LIST_INSERT_HEAD(&area->iface_list, iface, entry);
>   break;
>   case IMSG_IFDELETE:
>   if (imsg.hdr.len != IMSG_HEADER_SIZE +
> Index: rde.c
> ===
> RCS file: /cvs/src/usr.sbin/ospf6d/rde.c,v
> retrieving revision 1.52
> diff -u -p -r1.52 rde.c
> --- rde.c 5 May 2011 15:58:02 -   1.52
> +++ rde.c 1 Jun 2011 20:36:31 -
> @@ -623,7 +623,7 @@ rde_dispatch_parent(int fd, short event,
>  {
>   static struct area  *narea;
>   struct area *area;
> - struct iface*iface;
> + struct iface*iface, *ifp;
>   struct ifaddrchange *ifc;
>   struct iface_addr   *ia, *nia;
>   struct imsg  imsg;
> @@ -710,16 +710,16 @@ rde_dispatch_parent(int fd, short event,
>   0, -1, &kr, sizeof(kr));
>   break;
>   case IMSG_IF

Re: ospf6d crashes on interface add

2011-06-01 Thread Martin Pelikan
Hi!

So my last attempt wasn't met with much appreciation, so I'll slow down:

- when I add a vlan(4), vether(4) or something, my ospf6d dies
- I don't like that
- therefore, with new release comes new diff
- this time I tried to make it as small as possible, in separate parts

It doesn't fix departures (if_leave_group jumps on a non-existing
interface), but I guess people don't remove interfaces that often. 
I will rewrite and post the rest of the big one if someone shows
interest in this bit.

--
Martin Pelikan


Index: kroute.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/kroute.c,v
retrieving revision 1.30
diff -u -p -r1.30 kroute.c
--- kroute.c7 Mar 2011 07:43:02 -   1.30
+++ kroute.c1 Jun 2011 20:36:31 -
@@ -973,15 +973,22 @@ if_announce(void *msg)
if ((iface = if_new(ifan->ifan_index, ifan->ifan_name)) == NULL)
fatal("if_announce failed");
iface->cflags |= F_IFACE_AVAIL;
+   main_imsg_compose_rde(IMSG_IFADD, 0,
+   iface, sizeof(struct iface));
+   main_imsg_compose_ospfe(IMSG_IFADD, 0,
+   iface, sizeof(struct iface));
break;
case IFAN_DEPARTURE:
-   iface = if_find(ifan->ifan_index);
-   if (iface->cflags & F_IFACE_CONFIGURED) {
-   main_imsg_compose_rde(IMSG_IFDELETE, 0,
-   &iface->ifindex, sizeof(iface->ifindex));
-   main_imsg_compose_ospfe(IMSG_IFDELETE, 0,
-   &iface->ifindex, sizeof(iface->ifindex));
+   if ((iface = if_find(ifan->ifan_index)) == NULL)  {
+   log_warn("someone announced departure of non-existing "
+   "interface %s - possible race condition?",
+   ifan->ifan_name);
+   return;
}
+   main_imsg_compose_rde(IMSG_IFDELETE, 0,
+   &iface->ifindex, sizeof(iface->ifindex));
+   main_imsg_compose_ospfe(IMSG_IFDELETE, 0,
+   &iface->ifindex, sizeof(iface->ifindex));
if_del(iface);
break;
}
Index: ospfe.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/ospfe.c,v
retrieving revision 1.34
diff -u -p -r1.34 ospfe.c
--- ospfe.c 2 May 2011 09:24:00 -   1.34
+++ ospfe.c 1 Jun 2011 20:36:31 -
@@ -299,16 +299,16 @@ ospfe_dispatch_main(int fd, short event,
}
break;
case IMSG_IFADD:
-   if ((iface = malloc(sizeof(struct iface))) == NULL)
-   fatal(NULL);
-   memcpy(iface, imsg.data, sizeof(struct iface));
+   ifp = imsg.data;
+   if ((iface = if_new(ifp->ifindex, ifp->name)) == NULL)
+   fatalx("IFADD in ospfe");
 
-   LIST_INIT(&iface->nbr_list);
-   TAILQ_INIT(&iface->ls_ack_list);
-   RB_INIT(&iface->lsa_tree);
+   /* ifaces from config belong to some area */
+   if ((iface->cflags & F_IFACE_CONFIGURED) &&
+   (area = area_find(oeconf, iface->area_id)) != NULL)
+   LIST_INSERT_HEAD(&area->iface_list, iface,
+   entry);
 
-   area = area_find(oeconf, iface->area_id);
-   LIST_INSERT_HEAD(&area->iface_list, iface, entry);
break;
case IMSG_IFDELETE:
if (imsg.hdr.len != IMSG_HEADER_SIZE +
Index: rde.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/rde.c,v
retrieving revision 1.52
diff -u -p -r1.52 rde.c
--- rde.c   5 May 2011 15:58:02 -   1.52
+++ rde.c   1 Jun 2011 20:36:31 -
@@ -623,7 +623,7 @@ rde_dispatch_parent(int fd, short event,
 {
static struct area  *narea;
struct area *area;
-   struct iface*iface;
+   struct iface*iface, *ifp;
struct ifaddrchange *ifc;
struct iface_addr   *ia, *nia;
struct imsg  imsg;
@@ -710,16 +710,16 @@ rde_dispatch_parent(int fd, short event,
0, -1, &kr, sizeof(kr));
break;
case IMSG_IFADD:
-   if ((iface = malloc(sizeof(struct iface))) == NULL)
-   fatal(NULL);
-   memcpy(iface, imsg.data, sizeof(struct iface));
-
-   LIST_INIT(&iface->nbr_list);
-   TAILQ_INIT(&iface->ls_ack_list);
-   RB_INIT(&iface

Re: ospf6d crashes on interface add

2011-02-13 Thread Stefan Sperling
On Wed, Feb 09, 2011 at 12:22:58PM +0100, Martin Pelikan wrote:
> On Wed, Jan 26, 2011 at 04:44:30PM +0100, Martin Pelikan wrote:
> > Hello tech@, claudio@ in particular,
> > this diff corrects the behavior of ospf6d when:
> > - vlan/vether/? interface is added with some inet6 address
> > - a configured interface is removed (please test with usb devs)
> > In both cases the daemon crashes.  Also, it contains various fixes
> > 
> > Desired behavior:
> > - remove if -> withdraw all its routes, but keep running
> > - add previously configured if -> announce all its routes back
> > - add unconfigured if -> get everyone to know about it without crashing
> 
> Even in the recent -beta one can crash ospf6d easily, just by typing
> # ifconfig vlan7 vlan 7 vlandev 
> even in the simplest of possible setups.
> 
> I run this diff on a production router where vlans are being added
> dynamically from admin's web page, without any problem for two weeks.
> Is there any chance people won't have to patch tne 4.9-release? :-)
> What's the problem? Is it too complicated or have I missed something
> again?
> 
> Thanks for any feedback.

I would say that this got delayed because claudio was (or still is?)
on vacation. I could review this. However, it's very close to release now
so I won't bother with it now unless a couple of people have tested your
diff to see if there are any unexpected side effects. Given the lack of
responses it seems nobody else has tested it?

I don't have an ospf6 test setup anymore, and never had one of reasonable
size (only virtual machines which became useless for several months while
qemu was broken). So for me, it's important that a lot of ospf6d users
test diffs in their production setup (or close approximations of that setup).
Especially while claudio is away...

So I suppose that this will be looked at after release, and those running
ospf6d on -current will get to test it then. Sorry.



Re: ospf6d crashes on interface add

2011-02-09 Thread Martin Pelikan
On Wed, Jan 26, 2011 at 04:44:30PM +0100, Martin Pelikan wrote:
> Hello tech@, claudio@ in particular,
> this diff corrects the behavior of ospf6d when:
> - vlan/vether/? interface is added with some inet6 address
> - a configured interface is removed (please test with usb devs)
> In both cases the daemon crashes.  Also, it contains various fixes
> 
> Desired behavior:
> - remove if -> withdraw all its routes, but keep running
> - add previously configured if -> announce all its routes back
> - add unconfigured if -> get everyone to know about it without crashing

Even in the recent -beta one can crash ospf6d easily, just by typing
# ifconfig vlan7 vlan 7 vlandev 
even in the simplest of possible setups.

I run this diff on a production router where vlans are being added
dynamically from admin's web page, without any problem for two weeks.
Is there any chance people won't have to patch tne 4.9-release? :-)
What's the problem? Is it too complicated or have I missed something
again?

Thanks for any feedback.

--
Martin Pelikan



ospf6d crashes on interface add

2011-01-26 Thread Martin Pelikan
Hello tech@, claudio@ in particular,
this diff corrects the behavior of ospf6d when:
- vlan/vether/? interface is added with some inet6 address
- a configured interface is removed (please test with usb devs)
In both cases the daemon crashes.  Also, it contains various fixes
useful for debugging, cleans up and removes a possible memory leak.
The patched version adds all interfaces into iflist in all three
processes, which might be useful in the future when the user reloads
configuration.

Known problems:
- Crazy user types "for i = 1 to 1000 do ifconfig vlan$i create" and
  then destroy -> some interfaces get stuck and if_find says it can't
  find them. I couldn't find out the cause of this. An error prints.
- When you destroy a configured vlan interface, its routes won't
  withdraw. They are marked with DOWN flag, but then the parent sends
  IMSG_NETWORK_ADD, which leaves me with the question about purpose of
  IMSG_NETWORK_DEL. Any ideas? Or an elegant diff?

Desired behavior:
- remove if -> withdraw all its routes, but keep running
- add previously configured if -> announce all its routes back
- add unconfigured if -> get everyone to know about it without crashing

Comments? Corrections? Thanks in advance.
--
Martin Pelikan


Index: area.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/area.c,v
retrieving revision 1.4
diff -u -p -r1.4 area.c
--- area.c  28 Dec 2008 20:08:31 -  1.4
+++ area.c  26 Jan 2011 15:20:38 -
@@ -56,7 +56,6 @@ area_del(struct area *area)
 
/* clean lists */
while ((iface = LIST_FIRST(&area->iface_list)) != NULL) {
-   LIST_REMOVE(iface, entry);
if_del(iface);
}
 
Index: interface.c
===
RCS file: /cvs/src/usr.sbin/ospf6d/interface.c,v
retrieving revision 1.15
diff -u -p -r1.15 interface.c
--- interface.c 20 Sep 2009 20:45:06 -  1.15
+++ interface.c 26 Jan 2011 15:20:38 -
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -205,7 +206,7 @@ if_new(u_short ifindex, char *ifname)
struct iface*iface;
 
if ((iface = calloc(1, sizeof(*iface))) == NULL)
-   err(1, "if_new: calloc");
+   return (NULL);
 
iface->state = IF_STA_DOWN;
 
@@ -259,7 +260,7 @@ if_del(struct iface *iface)
 {
struct nbr  *nbr = NULL;
 
-   log_debug("if_del: interface %s", iface->name);
+   log_debug("if_del(pid %d): interface %s", getpid(), iface->name);
 
/* revert the demotion when the interface is deleted */
if ((iface->state & (IF_STA_MULTI | IF_STA_POINTTOPOINT)) == 0)
@@ -277,6 +278,11 @@ if_del(struct iface *iface)
evtimer_del(&iface->lsack_tx_timer);
 
ls_ack_list_clr(iface);
+
+   /* interfaces from config used to belong to some area */
+   if (iface->cflags & F_IFACE_CONFIGURED)
+   LIST_REMOVE(iface, entry);
+
TAILQ_REMOVE(&iflist, iface, list);
free(iface);
 }
@@ -728,8 +734,8 @@ if_join_group(struct iface *iface, struc
mreq.ipv6mr_multiaddr = *addr;
mreq.ipv6mr_interface = iface->ifindex;
 
-   if (setsockopt(iface->fd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
-   &mreq, sizeof(mreq)) < 0) {
+   if (iface->fd > 0 && setsockopt(iface->fd, IPPROTO_IPV6,
+   IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) < 0) {
log_warn("if_join_group: error IPV6_JOIN_GROUP, "
"interface %s address %s", iface->name,
log_in6addr(addr));
@@ -762,12 +768,15 @@ if_leave_group(struct iface *iface, stru
mreq.ipv6mr_multiaddr = *addr;
mreq.ipv6mr_interface = iface->ifindex;
 
-   if (setsockopt(iface->fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
-   (void *)&mreq, sizeof(mreq)) < 0) {
-   log_warn("if_leave_group: error IPV6_LEAVE_GROUP, "
-   "interface %s address %s", iface->name,
-   log_in6addr(addr));
-   return (-1);
+   if (iface->fd > 0 && setsockopt(iface->fd, IPPROTO_IPV6,
+   IPV6_LEAVE_GROUP, (void *)&mreq, sizeof(mreq)) < 0) {
+   /* the interface might be already gone */
+   if (errno != ENXIO) {
+   log_warn("if_leave_group: error "
+   "IPV6_LEAVE_GROUP, interface %s address %s",
+   iface->name, log_in6addr(addr));
+   return (-1);
+   }
}
break;
case IF_TYPE_POINTOMULTIPOINT:
@@ -790,9 +799,14 @@ if_set_mcast(struct iface *iface)
case IF_TYPE_BROADCAST:
if (setsock