diff -ur mpd-5.6/conf/dictionary.mpd mpd-5.6-lutz/conf/dictionary.mpd
--- mpd-5.6/conf/dictionary.mpd	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/conf/dictionary.mpd	2013-04-25 13:28:49.000000000 +0200
@@ -27,6 +27,7 @@
 ATTRIBUTE	mpd-iface-name	20	string
 ATTRIBUTE	mpd-iface-descr	21	string
 ATTRIBUTE	mpd-iface-group	22	string
+ATTRIBUTE	mpd-term-cause	23	string
 ATTRIBUTE	mpd-drop-user	154	integer
 
 END-VENDOR	mpd
diff -ur mpd-5.6/src/Makefile mpd-5.6-lutz/src/Makefile
--- mpd-5.6/src/Makefile	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/Makefile	2013-02-01 00:45:22.000000000 +0100
@@ -10,7 +10,7 @@
 PROG?=			mpd5
 PREFIX?=		/usr/local
 BINDIR?=		${PREFIX}/sbin
-VERSION=		5.6
+VERSION=		5.6-iks2
 NOMAN=
 NO_MAN=
 
diff -ur mpd-5.6/src/auth.c mpd-5.6-lutz/src/auth.c
--- mpd-5.6/src/auth.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/auth.c	2013-04-24 14:33:51.000000000 +0200
@@ -44,11 +44,11 @@
   static void		AuthTimeout(void *arg);
   static int		AuthGetExternalPassword(char * extcmd, char *authname,
 			    char *password, size_t passlen);
-  static void		AuthAsync(void *arg);
-  static void		AuthAsyncFinish(void *arg, int was_canceled);
+  static void		AuthAsync(int typ, void *arg);
+  static void		AuthAsyncFinish(int typ, void *arg, int was_canceled);
   static int		AuthPreChecks(AuthData auth);
-  static void		AuthAccount(void *arg);
-  static void		AuthAccountFinish(void *arg, int was_canceled);
+  static void		AuthAccount(int typ, void *arg);
+  static void		AuthAccountFinish(int typ, void *arg, int was_canceled);
   static void		AuthInternal(AuthData auth);
   static int		AuthExternal(AuthData auth);
   static int		AuthExternalAcct(AuthData auth);
@@ -154,6 +154,17 @@
     { 0,	0,			NULL		},
   };
 
+  static MsgHandler acct_queue, auth_queue;
+
+int
+AuthSetup()
+{
+   MsgParallelRegister(&acct_queue, AuthAccount, AuthAccountFinish);
+   MsgParallelRegister(&auth_queue, AuthAsync, AuthAsyncFinish);
+   return 0;
+}
+
+
 void
 ACLCopy(struct acl *src, struct acl **dst)
 {
@@ -313,10 +324,10 @@
 {
     Auth	a = &l->lcp.auth;
   
-    if (a->thread)
-	paction_cancel(&a->thread);
-    if (a->acct_thread)
-	paction_cancel(&a->acct_thread);
+    if (a->auth_msg)
+	MsgAsyncCancel(&a->auth_msg);
+    if (a->acct_msg)
+	MsgAsyncCancel(&a->acct_msg);
     Freee(a->conf.extauth_script);
     Freee(a->conf.extacct_script);
 }
@@ -439,7 +450,7 @@
 
   /* Sanity check */
   if (l->lcp.phase != PHASE_AUTHENTICATE && l->lcp.phase != PHASE_NETWORK) {
-    Log(LG_AUTH, ("[%s] AUTH: rec'd stray packet", l->name));
+    Log(LG_ERR|LG_AUTH, ("[%s] AUTH: rec'd stray packet", l->name));
     mbfree(bp);
     return;
   }
@@ -448,7 +459,7 @@
 
   /* Sanity check length */
   if (len < sizeof(fsmh)) {
-    Log(LG_AUTH, ("[%s] AUTH: rec'd runt packet: %d bytes",
+    Log(LG_ERR|LG_AUTH, ("[%s] AUTH: rec'd runt packet: %d bytes",
       l->name, len));
     mbfree(bp);
     return;
@@ -538,8 +549,10 @@
       ProtoName(proto), AuthCode(proto, code, buf, sizeof(buf)), id, plen));
   }
 
+  MUTEX_LOCK(gNgMutex);
   /* Send it out */
   NgFuncWritePppFrameLink(l, proto, bp);
+  MUTEX_UNLOCK(gNgMutex);
 }
 
 /*
@@ -682,7 +695,7 @@
   PapStop(&a->pap);
   ChapStop(&a->chap);
   EapStop(&a->eap);
-  paction_cancel(&a->thread);
+  MsgAsyncCancel(&a->auth_msg);
 }
 
 /*
@@ -813,9 +826,9 @@
     AuthData		auth;
       
     /* maybe an outstanding thread is running */
-    if (a->acct_thread) {
+    if (a->acct_msg) {
 	if (type == AUTH_ACCT_START || type == AUTH_ACCT_STOP) {
-	    paction_cancel(&a->acct_thread);
+	    MsgAsyncCancel(&a->acct_msg);
 	} else {
 	    Log(LG_AUTH2, ("[%s] ACCT: Accounting thread is already running", 
     		l->name));
@@ -896,12 +909,7 @@
 	auth = AuthDataNew(l);
 	auth->acct_type = type;
 
-	if (paction_start(&a->acct_thread, &gGiantMutex, AuthAccount, 
-		AuthAccountFinish, auth) == -1) {
-	    Log(LG_ERR, ("[%s] ACCT: Couldn't start thread: %d", 
-    		l->name, errno));
-	    AuthDataDestroy(auth);
-	}
+        MsgAsyncSend(&a->acct_msg, &acct_queue, 0, auth);
     }
 
 }
@@ -931,7 +939,7 @@
  */
  
 static void
-AuthAccount(void *arg)
+AuthAccount(int typ, void *arg)
 {
     AuthData	const auth = (AuthData)arg;
     int		err = 0;
@@ -966,7 +974,7 @@
  */
  
 static void
-AuthAccountFinish(void *arg, int was_canceled)
+AuthAccountFinish(int typ, void *arg, int was_canceled)
 {
     AuthData		auth = (AuthData)arg;
     Link 		l;
@@ -991,7 +999,9 @@
     if (l == NULL) {
 	AuthDataDestroy(auth);
 	return;
-    }    
+    } else {
+        MsgFree(&l->lcp.auth.acct_msg);
+    }
 
     if (auth->drop_user && auth->acct_type != AUTH_ACCT_STOP) {
 	Log(LG_AUTH, ("[%s] ACCT: Link close requested by the accounting", 
@@ -1103,7 +1113,7 @@
     }
 
     /* Check if we are ready to process request. */
-    if (a->thread) {
+    if (a->auth_msg) {
 	auth->status = AUTH_STATUS_BUSY;
 	auth->finish(l, auth);
 	return;
@@ -1117,14 +1127,7 @@
 	return;
     }
 
-    if (paction_start(&a->thread, &gGiantMutex, AuthAsync, 
-	AuthAsyncFinish, auth) == -1) {
-	Log(LG_ERR, ("[%s] AUTH: Couldn't start thread: %d", 
-    	    l->name, errno));
-	auth->status = AUTH_STATUS_FAIL;
-	auth->why_fail = AUTH_FAIL_NOT_EXPECTED;
-	auth->finish(l, auth);
-    }
+    MsgAsyncSend(&a->auth_msg, &auth_queue, 0, auth);
 }
 
 /*
@@ -1135,7 +1138,7 @@
  */
  
 static void
-AuthAsync(void *arg)
+AuthAsync(int typ, void *arg)
 {
     AuthData	const auth = (AuthData)arg;
 
@@ -1145,7 +1148,7 @@
         auth->params.authentic = AUTH_CONF_EXT_AUTH;
 	Log(LG_AUTH, ("[%s] AUTH: Trying EXTERNAL", auth->info.lnkname));
 	if (AuthExternal(auth)) {
-	    Log(LG_AUTH, ("[%s] AUTH: EXTERNAL returned error",
+	    Log(LG_ERR|LG_AUTH, ("[%s] AUTH: EXTERNAL returned error",
     		auth->info.lnkname));
 	} else {
 	    Log(LG_AUTH, ("[%s] AUTH: EXTERNAL returned: %s",
@@ -1164,7 +1167,7 @@
 	auth->params.authentic = AUTH_CONF_RADIUS_AUTH;
 	Log(LG_AUTH, ("[%s] AUTH: Trying RADIUS", auth->info.lnkname));
 	if (RadiusAuthenticate(auth)) {
-	    Log(LG_AUTH, ("[%s] AUTH: RADIUS returned error",
+	    Log(LG_ERR|LG_AUTH, ("[%s] AUTH: RADIUS returned error",
     		auth->info.lnkname));
 	} else {
 	    Log(LG_AUTH, ("[%s] AUTH: RADIUS returned: %s", 
@@ -1236,7 +1239,7 @@
  */
  
 static void
-AuthAsyncFinish(void *arg, int was_canceled)
+AuthAsyncFinish(int typ, void *arg, int was_canceled)
 {
     AuthData	auth = (AuthData)arg;
     Link	l;
@@ -1705,7 +1708,7 @@
     }
 
     if (num >= gMaxLogins) {
-	Log(LG_AUTH, ("[%s] AUTH: Name: \"%s\" max. number of logins exceeded",
+	Log(LG_ERR|LG_AUTH, ("[%s] AUTH: Name: \"%s\" max. number of logins exceeded",
 	    auth->info.lnkname, auth->params.authname));
         auth->status = AUTH_STATUS_FAIL;
         auth->why_fail = AUTH_FAIL_INVALID_LOGIN;
@@ -2215,7 +2218,7 @@
 	    j = 0;
 	    SLIST_FOREACH(r1, &auth->params.routes, next) {
 	      if (!u_rangecompare(&r->dest, &r1->dest)) {
-	        Log(LG_AUTH, ("[%s] Ext-auth: Duplicate route", auth->info.lnkname));
+	        Log(LG_ERR|LG_AUTH, ("[%s] Ext-auth: Duplicate route", auth->info.lnkname));
 	        j = 1;
 	      }
 	    };
@@ -2242,7 +2245,7 @@
 	    j = 0;
 	    SLIST_FOREACH(r1, &auth->params.routes, next) {
 	      if (!u_rangecompare(&r->dest, &r1->dest)) {
-	        Log(LG_AUTH, ("[%s] Ext-auth: Duplicate route", auth->info.lnkname));
+	        Log(LG_ERR|LG_AUTH, ("[%s] Ext-auth: Duplicate route", auth->info.lnkname));
 	        j = 1;
 	      }
 	    };
diff -ur mpd-5.6/src/auth.h mpd-5.6-lutz/src/auth.h
--- mpd-5.6/src/auth.h	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/auth.h	2013-02-04 22:50:14.000000000 +0100
@@ -215,8 +215,8 @@
     struct papinfo	pap;		/* PAP state */
     struct chapinfo	chap;		/* CHAP state */
     struct eapinfo	eap;		/* EAP state */
-    struct paction	*thread;	/* async auth thread */
-    struct paction	*acct_thread;	/* async accounting auth thread */
+    Msg			auth_msg;	/* async auth */
+    Msg			acct_msg;	/* async accounting */
     struct authconf	conf;		/* Auth backends, RADIUS, etc. */
     struct authparams	params;		/* params to pass to from auth backend */
     struct ng_ppp_link_stat64	prev_stats;	/* Previous link statistics */
@@ -287,6 +287,7 @@
  * FUNCTIONS
  */
 
+  extern int		AuthSetup(void);
   extern void		AuthInit(Link l);
   extern void		AuthInst(Auth auth, Auth autht);
   extern void		AuthShutdown(Link l);
diff -ur mpd-5.6/src/bund.c mpd-5.6-lutz/src/bund.c
--- mpd-5.6/src/bund.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/bund.c	2013-03-30 23:51:16.000000000 +0100
@@ -355,8 +355,10 @@
 	b->originate = l->originate;
     }
 
+    MUTEX_LOCK(gNgMutex);
     /* Update PPP node configuration */
     NgFuncSetConfig(b);
+    MUTEX_UNLOCK(gNgMutex);
 
     /* copy msession_id to link */
     strlcpy(l->msession_id, b->msession_id, sizeof(l->msession_id));
@@ -379,6 +381,12 @@
 
     AuthAccountStart(l, AUTH_ACCT_START);
 
+    if (Enabled(&gGlobalConf.options, GLOBAL_CONF_DELAYEDONESHOT) &&
+       !Enabled(&gGlobalConf.options, GLOBAL_CONF_ONESHOT)) {
+       /* enable one-shot, because real work started */
+       Enable(&gGlobalConf.options, GLOBAL_CONF_ONESHOT);
+    }
+
     return(b->n_up);
 }
 
@@ -400,10 +408,12 @@
 
     AuthAccountStart(l, AUTH_ACCT_STOP);
 
+    MUTEX_LOCK(gNgMutex);
     /* Disable link */
     b->pppConfig.links[l->bundleIndex].enableLink = 0;
     b->pppConfig.links[l->bundleIndex].mru = LCP_DEFAULT_MRU;
     NgFuncSetConfig(b);
+    MUTEX_UNLOCK(gNgMutex);
 
     LinkNgLeave(l);
     l->joined_bund = 0;
@@ -1106,7 +1116,7 @@
 	REF(b);
 
 	/* Get message channel */
-	MsgRegister(&b->msgs, BundMsg);
+	MsgSerialRegister(&b->msgs, BundMsg);
 
 	/* Initialize bundle configuration */
 	b->conf.retry_timeout = BUND_DEFAULT_RETRY;
@@ -1377,6 +1387,7 @@
     l = 0;
 #endif
 
+  MUTEX_LOCK(gNgMutex);
 #ifndef NG_PPP_STATS64
   if (NgFuncGetStats(b, l, &stats) != -1) {
     b->stats.xmitFrames += abs(stats.xmitFrames - b->oldStats.xmitFrames);
@@ -1393,6 +1404,7 @@
 #else
     NgFuncGetStats64(b, l, &b->stats);
 #endif
+  MUTEX_UNLOCK(gNgMutex);
 }
 
 /* 
@@ -1419,11 +1431,13 @@
 void
 BundResetStats(Bund b)
 {
+  MUTEX_LOCK(gNgMutex);
   NgFuncClrStats(b, NG_PPP_BUNDLE_LINKNUM);
   memset(&b->stats, 0, sizeof(b->stats));
 #ifndef NG_PPP_STATS64
   memset(&b->oldStats, 0, sizeof(b->oldStats));
 #endif
+  MUTEX_UNLOCK(gNgMutex);
 }
 
 /*
@@ -1544,11 +1558,13 @@
 
 	    struct ng_ppp_link_stat	oldStats;
 	
+	    MUTEX_LOCK(gNgMutex);
 	    /* Get updated link traffic statistics */
 	    oldStats = l->bm.idleStats;
 	    NgFuncGetStats(l->bund, l->bundleIndex, &l->bm.idleStats);
 	    b->bm.traffic[0][0] += l->bm.idleStats.recvOctets - oldStats.recvOctets;
 	    b->bm.traffic[1][0] += l->bm.idleStats.xmitOctets - oldStats.xmitOctets;
+	    MUTEX_UNLOCK(gNgMutex);
 	}
     }
 
@@ -1669,6 +1685,7 @@
     int			newIface = 0;
     int			newPpp = 0;
 
+    MUTEX_LOCK(gNgMutex);
     /* Create new iface node */
     if (NgFuncCreateIface(b,
 	b->iface.ifname, sizeof(b->iface.ifname)) < 0) {
@@ -1708,10 +1725,12 @@
 	goto fail;
     }
 
+    MUTEX_UNLOCK(gNgMutex);
     /* OK */
     return(0);
 
 fail:
+    MUTEX_UNLOCK(gNgMutex);
     BundNgShutdown(b, newIface, newPpp);
     return(-1);
 }
@@ -1725,6 +1744,7 @@
 {
     char	path[NG_PATHSIZ];
 
+    MUTEX_LOCK(gNgMutex);
     if (iface) {
 	snprintf(path, sizeof(path), "%s:", b->iface.ngname);
 	NgFuncShutdownNode(gLinksCsock, b->name, path);
@@ -1734,6 +1754,7 @@
 	NgFuncShutdownNode(gLinksCsock, b->name, path);
     }
     b->hook[0] = 0;
+    MUTEX_UNLOCK(gNgMutex);
 }
 
 /*
diff -ur mpd-5.6/src/ccp.c mpd-5.6-lutz/src/ccp.c
--- mpd-5.6/src/ccp.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/ccp.c	2013-03-28 16:52:28.000000000 +0100
@@ -165,14 +165,17 @@
 {
     char	name[NG_NODESIZ];
 
+    MUTEX_LOCK(gNgMutex);
     /* Create a netgraph socket node */
     snprintf(name, sizeof(name), "mpd%d-cso", gPid);
     if (NgMkSockNode(name, &gCcpCsock, &gCcpDsock) < 0) {
 	Perror("CcpsInit(): can't create %s node", NG_SOCKET_NODE_TYPE);
+        MUTEX_UNLOCK(gNgMutex);
 	return(-1);
     }
     (void) fcntl(gCcpCsock, F_SETFD, 1);
     (void) fcntl(gCcpDsock, F_SETFD, 1);
+    MUTEX_UNLOCK(gNgMutex);
 
     /* Listen for happenings on our node */
     EventRegister(&gCcpCtrlEvent, EVENT_READ,
@@ -315,11 +318,14 @@
     int			i, len;
     ng_ID_t		id;
 
+    MUTEX_LOCK(gNgMutex);
     /* Read message */
     if ((len = NgRecvMsg(gCcpCsock, &u.msg, sizeof(u), raddr)) < 0) {
 	Perror("CcpNgCtrlEvent: can't read message");
+        MUTEX_UNLOCK(gNgMutex);
 	return;
     }
+    MUTEX_UNLOCK(gNgMutex);
     
     if (sscanf(raddr, "[%x]:", &id) != 1) {
 	Log(LG_ERR, ("CcpNgCtrlEvent: can't decode sender id: '%s'",
@@ -424,8 +430,11 @@
 	    /* Packet requiring decompression */
 	    bp = CcpDataInput(b, bp);
 	}
-	if (bp)
+	if (bp) {
+	    MUTEX_LOCK(gNgMutex);
 	    NgFuncWriteFrame(gCcpDsock, naddr.sg_data, b->name, bp);
+	    MUTEX_UNLOCK(gNgMutex);
+	}
     }
 }
 
@@ -802,6 +811,7 @@
     return;
   }
 
+  MUTEX_LOCK(gNgMutex);
   if (ccp->xmit != NULL && ccp->xmit->Compress != NULL) {
     /* Connect a hook from the ppp node to our socket node */
     snprintf(cn.path, sizeof(cn.path), "[%x]:", b->nodeID);
@@ -837,6 +847,8 @@
   b->pppConfig.bund.enableDecompression = (ccp->recv != NULL)?ccp->recv->mode:0;
   NgFuncSetConfig(b);
 
+  MUTEX_UNLOCK(gNgMutex);
+
   /* Update interface MTU */
   BundUpdateParams(b);
 }
@@ -851,14 +863,17 @@
     Bund 	b = (Bund)fp->arg;
   CcpState	const ccp = &b->ccp;
 
+  MUTEX_LOCK(gNgMutex);
   /* Update PPP node config */
   b->pppConfig.bund.enableCompression = 0;
   b->pppConfig.bund.enableDecompression = 0;
   NgFuncSetConfig(b);
+  MUTEX_UNLOCK(gNgMutex);
 
   /* Update interface MTU */
   BundUpdateParams(b);
   
+  MUTEX_LOCK(gNgMutex);
   if (ccp->xmit != NULL && ccp->xmit->Compress != NULL) {
     char	hook[NG_HOOKSIZ];
     /* Disconnect hook. */
@@ -879,6 +894,7 @@
 
   ccp->xmit_resets = 0;
   ccp->recv_resets = 0;
+  MUTEX_UNLOCK(gNgMutex);
 }
 
 /*
diff -ur mpd-5.6/src/ccp_deflate.c mpd-5.6-lutz/src/ccp_deflate.c
--- mpd-5.6/src/ccp_deflate.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/ccp_deflate.c	2013-03-28 16:52:13.000000000 +0100
@@ -75,6 +75,7 @@
     const char		*deflatehook, *ppphook;
     ng_ID_t		id;
 
+    MUTEX_LOCK(gNgMutex);
     /* Initialize configuration structure */
     memset(&conf, 0, sizeof(conf));
     conf.enable = 1;
@@ -96,6 +97,7 @@
     if (NgSendMsg(gCcpCsock, path,
     	    NGM_GENERIC_COOKIE, NGM_MKPEER, &mp, sizeof(mp)) < 0) {
 	Perror("[%s] can't create %s node", b->name, mp.type);
+        MUTEX_UNLOCK(gNgMutex);
 	return(-1);
     }
 
@@ -115,9 +117,11 @@
 	Perror("[%s] can't config %s node at %s",
     	    b->name, NG_DEFLATE_NODE_TYPE, path);
 	NgFuncShutdownNode(gCcpCsock, b->name, path);
+        MUTEX_UNLOCK(gNgMutex);
 	return(-1);
     }
 
+    MUTEX_UNLOCK(gNgMutex);
     return 0;
 }
 
@@ -170,6 +174,7 @@
 {
     char		path[NG_PATHSIZ];
 
+    MUTEX_LOCK(gNgMutex);
     /* Remove node */
     if (dir == COMP_DIR_XMIT) {
 	snprintf(path, sizeof(path), "[%x]:", b->ccp.comp_node_id);
@@ -179,6 +184,7 @@
 	b->ccp.decomp_node_id = 0;
     }
     NgFuncShutdownNode(gCcpCsock, b->name, path);
+    MUTEX_UNLOCK(gNgMutex);
 }
 
 /*
@@ -189,12 +195,14 @@
 DeflateRecvResetReq(Bund b, int id, Mbuf bp, int *noAck)
 {
     char		path[NG_PATHSIZ];
+    MUTEX_LOCK(gNgMutex);
     /* Forward ResetReq to the DEFLATE compression node */
     snprintf(path, sizeof(path), "[%x]:", b->ccp.comp_node_id);
     if (NgSendMsg(gCcpCsock, path,
     	    NGM_DEFLATE_COOKIE, NGM_DEFLATE_RESETREQ, NULL, 0) < 0) {
 	Perror("[%s] reset-req to %s node", b->name, NG_DEFLATE_NODE_TYPE);
     }
+    MUTEX_UNLOCK(gNgMutex);
     return(NULL);
 }
 
@@ -216,12 +224,14 @@
 DeflateRecvResetAck(Bund b, int id, Mbuf bp)
 {
     char		path[NG_PATHSIZ];
+    MUTEX_LOCK(gNgMutex);
     /* Forward ResetReq to the DEFLATE compression node */
     snprintf(path, sizeof(path), "[%x]:", b->ccp.decomp_node_id);
     if (NgSendMsg(gCcpCsock, path,
     	    NGM_DEFLATE_COOKIE, NGM_DEFLATE_RESETREQ, NULL, 0) < 0) {
 	Perror("[%s] reset-ack to %s node", b->name, NG_DEFLATE_NODE_TYPE);
     }
+    MUTEX_UNLOCK(gNgMutex);
 }
 
 /*
@@ -341,11 +351,14 @@
 	default:
 	    assert(0);
     }
+    MUTEX_LOCK(gNgMutex);
     if (NgFuncSendQuery(path, NGM_DEFLATE_COOKIE, NGM_DEFLATE_GET_STATS, NULL, 0, 
 	&u.reply, sizeof(u), NULL) < 0) {
 	    Perror("[%s] can't get %s stats", b->name, NG_DEFLATE_NODE_TYPE);
+            MUTEX_UNLOCK(gNgMutex);
 	    return(0);
     }
+    MUTEX_UNLOCK(gNgMutex);
     memcpy(&stats, u.reply.data, sizeof(stats));
     switch (dir) {
 	case COMP_DIR_XMIT:
diff -ur mpd-5.6/src/ccp_mppc.c mpd-5.6-lutz/src/ccp_mppc.c
--- mpd-5.6/src/ccp_mppc.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/ccp_mppc.c	2013-03-28 16:51:57.000000000 +0100
@@ -184,6 +184,7 @@
         }
     }
 
+    MUTEX_LOCK(gNgMutex);
     /* Attach a new MPPC node to the PPP node */
     snprintf(path, sizeof(path), "[%x]:", b->nodeID);
     strcpy(mp.type, NG_MPPC_NODE_TYPE);
@@ -192,6 +193,7 @@
     if (NgSendMsg(gCcpCsock, path,
 	    NGM_GENERIC_COOKIE, NGM_MKPEER, &mp, sizeof(mp)) < 0) {
 	Perror("[%s] can't create %s node", b->name, mp.type);
+        MUTEX_UNLOCK(gNgMutex);
 	return(-1);
     }
 
@@ -211,9 +213,12 @@
 	Perror("[%s] can't config %s node at %s",
     	    b->name, NG_MPPC_NODE_TYPE, path);
 	NgFuncShutdownNode(gCcpCsock, b->name, path);
+        MUTEX_UNLOCK(gNgMutex);
 	return(-1);
     }
 
+    MUTEX_UNLOCK(gNgMutex);
+
     /* Done */
     return(0);
 }
@@ -331,7 +336,9 @@
 	snprintf(path, sizeof(path), "[%x]:", b->ccp.decomp_node_id);
 	b->ccp.decomp_node_id = 0;
     }
+    MUTEX_LOCK(gNgMutex);
     NgFuncShutdownNode(gCcpCsock, b->name, path);
+    MUTEX_UNLOCK(gNgMutex);
 }
 
 /*
@@ -489,12 +496,14 @@
 MppcRecvResetReq(Bund b, int id, Mbuf bp, int *noAck)
 {
     char		path[NG_PATHSIZ];
+    MUTEX_LOCK(gNgMutex);
     /* Forward ResetReq to the MPPC compression node */
     snprintf(path, sizeof(path), "[%x]:", b->ccp.comp_node_id);
     if (NgSendMsg(gCcpCsock, path,
     	    NGM_MPPC_COOKIE, NGM_MPPC_RESETREQ, NULL, 0) < 0) {
 	Perror("[%s] reset-req to %s node", b->name, NG_MPPC_NODE_TYPE);
     }
+    MUTEX_UNLOCK(gNgMutex);
 
     /* No ResetAck required for MPPC */
     if (noAck)
@@ -750,9 +759,11 @@
     struct ngm_mkpeer		mp;
     int				cs, ds;
 
+    MUTEX_LOCK(gNgMutex);
     /* Create a netgraph socket node */
     if (NgMkSockNode(NULL, &cs, &ds) < 0) {
 	Perror("MppcTestCap: can't create socket node");
+        MUTEX_UNLOCK(gNgMutex);
     	return(-1);
     }
 
@@ -795,6 +806,7 @@
 done:
     close(cs);
     close(ds);
+    MUTEX_UNLOCK(gNgMutex);
     return(0);
 }
 
diff -ur mpd-5.6/src/ccp_pred1.c mpd-5.6-lutz/src/ccp_pred1.c
--- mpd-5.6/src/ccp_pred1.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/ccp_pred1.c	2013-03-28 16:51:46.000000000 +0100
@@ -139,6 +139,7 @@
         pred1hook = NG_PRED1_HOOK_DECOMP;
     }
 
+    MUTEX_LOCK(gNgMutex);
     /* Attach a new PRED1 node to the PPP node */
     snprintf(path, sizeof(path), "[%x]:", b->nodeID);
     strcpy(mp.type, NG_PRED1_NODE_TYPE);
@@ -147,6 +148,7 @@
     if (NgSendMsg(gCcpCsock, path,
     	    NGM_GENERIC_COOKIE, NGM_MKPEER, &mp, sizeof(mp)) < 0) {
 	Perror("[%s] can't create %s node", b->name, mp.type);
+        MUTEX_UNLOCK(gNgMutex);
 	return(-1);
     }
 
@@ -166,8 +168,10 @@
 	Perror("[%s] can't config %s node at %s",
     	    b->name, NG_PRED1_NODE_TYPE, path);
 	NgFuncShutdownNode(gCcpCsock, b->name, path);
+        MUTEX_UNLOCK(gNgMutex);
 	return(-1);
     }
+    MUTEX_UNLOCK(gNgMutex);
 #endif
     return 0;
 }
@@ -204,7 +208,9 @@
 	snprintf(path, sizeof(path), "[%x]:", b->ccp.decomp_node_id);
 	b->ccp.decomp_node_id = 0;
     }
+    MUTEX_LOCK(gNgMutex);
     NgFuncShutdownNode(gCcpCsock, b->name, path);
+    MUTEX_UNLOCK(gNgMutex);
 #endif
 }
 
@@ -384,12 +390,14 @@
   p->xmit_stats.Errors++;
 #else
     char		path[NG_PATHSIZ];
+    MUTEX_LOCK(gNgMutex);
     /* Forward ResetReq to the Predictor1 compression node */
     snprintf(path, sizeof(path), "[%x]:", b->ccp.comp_node_id);
     if (NgSendMsg(gCcpCsock, path,
     	    NGM_PRED1_COOKIE, NGM_PRED1_RESETREQ, NULL, 0) < 0) {
 	Perror("[%s] reset to %s node", b->name, NG_PRED1_NODE_TYPE);
     }
+    MUTEX_UNLOCK(gNgMutex);
 #endif
 return(NULL);
 }
@@ -418,12 +426,14 @@
     Pred1Init(b, COMP_DIR_RECV);
 #else
     char		path[NG_PATHSIZ];
+    MUTEX_LOCK(gNgMutex);
     /* Forward ResetReq to the Predictor1 decompression node */
     snprintf(path, sizeof(path), "[%x]:", b->ccp.decomp_node_id);
     if (NgSendMsg(gCcpCsock, path,
     	    NGM_PRED1_COOKIE, NGM_PRED1_RESETREQ, NULL, 0) < 0) {
 	Perror("[%s] reset to %s node", b->name, NG_PRED1_NODE_TYPE);
     }
+    MUTEX_UNLOCK(gNgMutex);
 #endif
 }
 
@@ -539,11 +549,14 @@
 	default:
 	    assert(0);
     }
+    MUTEX_LOCK(gNgMutex);
     if (NgFuncSendQuery(path, NGM_PRED1_COOKIE, NGM_PRED1_GET_STATS, NULL, 0, 
 	&u.reply, sizeof(u), NULL) < 0) {
 	    Perror("[%s] can't get %s stats", b->name, NG_PRED1_NODE_TYPE);
+            MUTEX_UNLOCK(gNgMutex);
 	    return(0);
     }
+    MUTEX_UNLOCK(gNgMutex);
     memcpy(&stats, u.reply.data, sizeof(stats));
     switch (dir) {
 	case COMP_DIR_XMIT:
diff -ur mpd-5.6/src/command.c mpd-5.6-lutz/src/command.c
--- mpd-5.6/src/command.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/command.c	2013-04-22 00:20:51.000000000 +0200
@@ -75,6 +75,7 @@
     SET_L2TPLIMIT,
 #endif
     SET_MAX_CHILDREN,
+    SET_QUEUE_DELAY,
 #ifdef USE_NG_BPF
     SET_FILTER
 #endif
@@ -148,6 +149,8 @@
 #endif
     { "max-children {num}",		"Max number of children",
 	GlobalSetCommand, NULL, 2, (void *) SET_MAX_CHILDREN },
+    { "queue-delay {num}",		"Delay in milliseconds in message queue processing",
+	GlobalSetCommand, NULL, 2, (void *) SET_QUEUE_DELAY },
 #ifdef USE_NG_BPF
     { "filter {num} add|clear [\"{flt}\"]",	"Global traffic filters management",
 	GlobalSetCommand, NULL, 2, (void *) SET_FILTER },
@@ -160,6 +163,7 @@
     { 0,	GLOBAL_CONF_TCPWRAPPER,	"tcp-wrapper"	},
 #endif
     { 0,	GLOBAL_CONF_ONESHOT,	"one-shot"	},
+    { 0,	GLOBAL_CONF_DELAYEDONESHOT,	"delayed-one-shot"	},
     { 0,	0,			NULL		},
   };
 
@@ -682,6 +686,14 @@
 	    gMaxChildren = val;
       break;
 
+    case SET_QUEUE_DELAY:
+	val = atoi(*av);
+	if (val < 0 || val > 120)
+	    Error("Incorrect delay time.");
+	else
+	    gQueueDelay = val;
+      break;
+
 #ifdef USE_NG_BPF
     case SET_FILTER:
 	if (ac == 4 && strcasecmp(av[1], "add") == 0) {
@@ -937,6 +949,7 @@
     Printf("	pptplimit	: %d\r\n", gPPTPtunlimit);
 #endif
     Printf("	max-children	: %d\r\n", gMaxChildren);
+    Printf("	queue-delay (ms): %d\r\n", gQueueDelay);
     Printf("Global options:\r\n");
     OptStat(ctx, &gGlobalConf.options, gGlobalConfList);
 #ifdef USE_NG_BPF
diff -ur mpd-5.6/src/command.h mpd-5.6-lutz/src/command.h
--- mpd-5.6/src/command.h	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/command.h	2013-03-29 17:52:36.000000000 +0100
@@ -31,7 +31,8 @@
 #ifdef USE_WRAP
     GLOBAL_CONF_TCPWRAPPER,	/* enable tcp-wrapper */
 #endif
-    GLOBAL_CONF_ONESHOT		/* enable OneShot mode */
+    GLOBAL_CONF_ONESHOT,	/* enable OneShot mode */
+    GLOBAL_CONF_DELAYEDONESHOT	/* enable DelayedOneShot mode */
   };
 
   struct globalconf {
diff -ur mpd-5.6/src/eap.c mpd-5.6-lutz/src/eap.c
--- mpd-5.6/src/eap.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/eap.c	2013-03-28 16:51:33.000000000 +0100
@@ -510,8 +510,10 @@
       l->name, EapCode(f->code, buf, sizeof(buf)), f->id, htons(f->length)));
   } 
 
+  MUTEX_LOCK(gNgMutex);
   bp = mbcopyback(NULL, 0, a->params.eapmsg, a->params.eapmsg_len);
   NgFuncWritePppFrameLink(l, PROTO_EAP, bp);
+  MUTEX_UNLOCK(gNgMutex);
 }
 
 /*
diff -ur mpd-5.6/src/ecp.c mpd-5.6-lutz/src/ecp.c
--- mpd-5.6/src/ecp.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/ecp.c	2013-03-28 16:51:26.000000000 +0100
@@ -168,14 +168,17 @@
 {
     char	name[NG_NODESIZ];
 
+    MUTEX_LOCK(gNgMutex);
     /* Create a netgraph socket node */
     snprintf(name, sizeof(name), "mpd%d-eso", gPid);
     if (NgMkSockNode(name, &gEcpCsock, &gEcpDsock) < 0) {
 	Perror("EcpsInit(): can't create %s node", NG_SOCKET_NODE_TYPE);
+        MUTEX_UNLOCK(gNgMutex);
 	return(-1);
     }
     (void) fcntl(gEcpCsock, F_SETFD, 1);
     (void) fcntl(gEcpDsock, F_SETFD, 1);
+    MUTEX_UNLOCK(gNgMutex);
 
     /* Listen for happenings on our node */
     EventRegister(&gEcpDataEvent, EVENT_READ,
@@ -353,8 +356,11 @@
 	    /* Packet requiring decompression */
 	    bp = EcpDataInput(b, bp);
 	}
-	if (bp)
+	if (bp) {
+	    MUTEX_LOCK(gNgMutex);
 	    NgFuncWriteFrame(gEcpDsock, naddr.sg_data, b->name, bp);
+	    MUTEX_UNLOCK(gNgMutex);
+	}
     }
 }
 
@@ -638,6 +644,7 @@
   EcpState	const ecp = &b->ecp;
   struct ngm_connect    cn;
 
+  MUTEX_LOCK(gNgMutex);
   /* Initialize */
   if (ecp->xmit && ecp->xmit->Init)
     (*ecp->xmit->Init)(b, ECP_DIR_XMIT);
@@ -676,6 +683,7 @@
   b->pppConfig.bund.enableEncryption = (ecp->xmit != NULL);
   b->pppConfig.bund.enableDecryption = (ecp->recv != NULL);
   NgFuncSetConfig(b);
+  MUTEX_UNLOCK(gNgMutex);
 
   /* Update interface MTU */
   BundUpdateParams(b);
@@ -693,14 +701,17 @@
     Bund 	b = (Bund)fp->arg;
   EcpState	const ecp = &b->ecp;
 
+  MUTEX_LOCK(gNgMutex);
   /* Update PPP node config */
   b->pppConfig.bund.enableEncryption = 0;
   b->pppConfig.bund.enableDecryption = 0;
   NgFuncSetConfig(b);
+  MUTEX_UNLOCK(gNgMutex);
 
   /* Update interface MTU */
   BundUpdateParams(b);
 
+  MUTEX_LOCK(gNgMutex);
   if (ecp->xmit != NULL && ecp->xmit->Encrypt != NULL) {
     char	hook[NG_HOOKSIZ];
     /* Disconnect hook. */
@@ -722,6 +733,7 @@
     
   ecp->xmit_resets = 0;
   ecp->recv_resets = 0;
+  MUTEX_UNLOCK(gNgMutex);
 }
 
 /*
diff -ur mpd-5.6/src/fsm.c mpd-5.6-lutz/src/fsm.c
--- mpd-5.6/src/fsm.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/fsm.c	2013-03-28 16:51:09.000000000 +0100
@@ -227,12 +227,14 @@
     /* Prepend to payload */
     bp = mbcopyback(payload, -(int)sizeof(hdr), &hdr, sizeof(hdr));
 
+    MUTEX_LOCK(gNgMutex);
     /* Send it out */
     if (fp->type->link_layer) {
 	NgFuncWritePppFrameLink((Link)fp->arg, fp->type->proto, bp);
     } else {
 	NgFuncWritePppFrame(b, NG_PPP_BUNDLE_LINKNUM, fp->type->proto, bp);
     }
+    MUTEX_UNLOCK(gNgMutex);
 }
 
 /*
@@ -1404,6 +1406,7 @@
 	return;
     }
 
+    MUTEX_LOCK(gNgMutex);
     /* See if there was any traffic since last time */
     oldStats = fp->idleStats;
     NgFuncGetStats(b, l ?
@@ -1412,6 +1415,7 @@
 	fp->quietCount = 0;
     else
 	fp->quietCount++;
+    MUTEX_UNLOCK(gNgMutex);
 
     /* See if peer hasn't responded for too many requests */
     switch (fp->quietCount) {
diff -ur mpd-5.6/src/iface.c mpd-5.6-lutz/src/iface.c
--- mpd-5.6/src/iface.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/iface.c	2013-04-24 23:10:19.000000000 +0200
@@ -1281,10 +1281,12 @@
 	if (iface->dodCache.ts + MAX_DOD_CACHE_DELAY < time(NULL))
     	    mbfree(iface->dodCache.pkt);
 	else {
+	    MUTEX_LOCK(gNgMutex);
     	    if (NgFuncWritePppFrame(b, NG_PPP_BUNDLE_LINKNUM,
 		    iface->dodCache.proto, iface->dodCache.pkt) < 0) {
 		Perror("[%s] can't write cached pkt", b->name);
     	    }
+	    MUTEX_UNLOCK(gNgMutex);
 	}
 	iface->dodCache.pkt = NULL;
     }
@@ -1846,7 +1848,7 @@
     int s;
     char buf[48], buf1[48];
 
-    Log(LG_IFACE2, ("[%s] IFACE: %s address %s->%s %s %s",
+    Log(LG_IFACE, ("[%s] IFACE: %s address %s->%s %s %s",
 	b->name, add?"Add":"Remove", u_rangetoa(self, buf, sizeof(buf)), 
 	((peer != NULL)?u_addrtoa(peer, buf1, sizeof(buf1)):""),
 	add?"to":"from", b->iface.ifname));
@@ -1902,7 +1904,7 @@
 
 	res = ioctl(s, add?SIOCAIFADDR_IN6:SIOCDIFADDR_IN6, &ifra6);
 	if (res == -1) {
-	    Perror("[%s] IFACE: %s IPv6 address %s %s failed", 
+	    Perror("[%s] IFACE: %s IPv6 address %s %s failed",
 		b->name, add?"Adding":"Removing", add?"to":"from", b->iface.ifname);
 	}
 	break;
@@ -1987,8 +1989,13 @@
 
     nb = cp - (char *)&rtmes;
     rtmes.m_rtm.rtm_msglen = nb;
+retry_route:
     wb = write(s, &rtmes, nb);
     if (wb < 0) {
+        if(rtmes.m_rtm.rtm_type == RTM_ADD) {
+	   rtmes.m_rtm.rtm_type = RTM_CHANGE;
+	   goto retry_route;
+	}
     	Log(LG_ERR, ("[%s] IFACE: %s route %s %s failed: %s",
 	    b->name, cmdstr, u_rangetoa(dst, buf, sizeof(buf)), 
 	    ((gw != NULL)?u_addrtoa(gw, buf1, sizeof(buf1)):""),
@@ -2149,12 +2156,15 @@
     strcpy(cn.ourhook, hook);
     snprintf(cn.path, sizeof(cn.path), "%s:", b->iface.ngname);
     strcpy(cn.peerhook, NG_IFACE_HOOK_INET);
+    MUTEX_LOCK(gNgMutex);
     if (NgSendMsg(gLinksCsock, path,
     	    NGM_GENERIC_COOKIE, NGM_CONNECT, &cn, sizeof(cn)) < 0) {
 	Perror("[%s] can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\"",
 	    b->name, path, cn.ourhook, cn.path, cn.peerhook);
+	MUTEX_UNLOCK(gNgMutex);
 	goto fail;
     }
+    MUTEX_UNLOCK(gNgMutex);
 
     if (ready) {
 #ifdef USE_NG_NETFLOW
@@ -2233,11 +2243,13 @@
 #endif
     b->iface.mss_up = 0;
 
+    MUTEX_LOCK(gNgMutex);
     snprintf(path, sizeof(path), "[%x]:", b->nodeID);
     NgFuncDisconnect(gLinksCsock, b->name, path, NG_PPP_HOOK_INET);
 
     snprintf(path, sizeof(path), "%s:", b->iface.ngname);
     NgFuncDisconnect(gLinksCsock, b->name, path, NG_IFACE_HOOK_INET);
+    MUTEX_UNLOCK(gNgMutex);
 }
 
 static int
@@ -2265,6 +2277,7 @@
   
     }
 
+    MUTEX_LOCK(gNgMutex);
     /* Connect graph to the iface node. */
     strcpy(cn.ourhook, hook);
     snprintf(cn.path, sizeof(cn.path), "%s:", b->iface.ngname);
@@ -2273,8 +2286,10 @@
     	    NGM_GENERIC_COOKIE, NGM_CONNECT, &cn, sizeof(cn)) < 0) {
 	Perror("[%s] can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\"",
 	    b->name, path, cn.ourhook, cn.path, cn.peerhook);
+	MUTEX_UNLOCK(gNgMutex);
 	goto fail;
     }
+    MUTEX_UNLOCK(gNgMutex);
 
     /* OK */
     return(0);
@@ -2296,11 +2311,13 @@
 	IfaceShutdownTee(b, 1);
     b->iface.tee6_up = 0;
 
+    MUTEX_LOCK(gNgMutex);
     snprintf(path, sizeof(path), "[%x]:", b->nodeID);
     NgFuncDisconnect(gLinksCsock, b->name, path, NG_PPP_HOOK_IPV6);
 
     snprintf(path, sizeof(path), "%s:", b->iface.ngname);
     NgFuncDisconnect(gLinksCsock, b->name, path, NG_IFACE_HOOK_INET6);
+    MUTEX_UNLOCK(gNgMutex);
 }
 
 #ifdef USE_NG_NAT
@@ -2314,6 +2331,7 @@
 #ifdef NG_NAT_LOG
     struct ng_nat_mode	mode;
 #endif  
+    MUTEX_LOCK(gNgMutex);
     Log(LG_IFACE2, ("[%s] IFACE: Connecting NAT", b->name));
   
     strcpy(mp.type, NG_NAT_NODE_TYPE);
@@ -2323,6 +2341,7 @@
 	NGM_GENERIC_COOKIE, NGM_MKPEER, &mp, sizeof(mp)) < 0) {
       Perror("[%s] can't create %s node at \"%s\"->\"%s\"",
 	b->name, NG_NAT_NODE_TYPE, path, mp.ourhook);
+      MUTEX_UNLOCK(gNgMutex);
       return(-1);
     }
     strlcat(path, ".", NG_PATHSIZ);
@@ -2331,6 +2350,7 @@
     if (NgSendMsg(gLinksCsock, path,
 	NGM_GENERIC_COOKIE, NGM_NAME, &nm, sizeof(nm)) < 0) {
       Perror("[%s] can't name %s node", b->name, NG_NAT_NODE_TYPE);
+      MUTEX_UNLOCK(gNgMutex);
       return(-1);
     }
     strcpy(hook, NG_NAT_HOOK_OUT);
@@ -2373,6 +2393,7 @@
     }
 #endif
 
+    MUTEX_UNLOCK(gNgMutex);
     return(0);
 }
 
@@ -2383,6 +2404,7 @@
     char	path[NG_PATHSIZ];
     int k;
 
+    MUTEX_LOCK(gNgMutex);
     if (u_addrempty(&nat->alias_addr)) {
 	snprintf(path, sizeof(path), "mpd%d-%s-nat:", gPid, b->name);
 	if (NgSendMsg(gLinksCsock, path,
@@ -2390,6 +2412,7 @@
 		&b->iface.self_addr.addr.u.ip4,
 		sizeof(b->iface.self_addr.addr.u.ip4)) < 0) {
 	    Perror("[%s] can't set NAT ip", b->name);
+	    MUTEX_UNLOCK(gNgMutex);
 	    return (-1);
 	}
     }
@@ -2425,6 +2448,7 @@
       }
     }
 #endif
+    MUTEX_UNLOCK(gNgMutex);
     return (0);
 }
 
@@ -2434,7 +2458,9 @@
     char	path[NG_PATHSIZ];
 
     snprintf(path, sizeof(path), "mpd%d-%s-nat:", gPid, b->name);
+    MUTEX_LOCK(gNgMutex);
     NgFuncShutdownNode(gLinksCsock, b->name, path);
+    MUTEX_UNLOCK(gNgMutex);
 }
 #endif /* USE_NG_NAT */
 
@@ -2444,6 +2470,7 @@
     struct ngm_mkpeer	mp;
     struct ngm_name	nm;
 
+    MUTEX_LOCK(gNgMutex);
     Log(LG_IFACE2, ("[%s] IFACE: Connecting tee%s", b->name, v6?"6":""));
   
     strcpy(mp.type, NG_TEE_NODE_TYPE);
@@ -2453,6 +2480,7 @@
 	NGM_GENERIC_COOKIE, NGM_MKPEER, &mp, sizeof(mp)) < 0) {
       Perror("[%s] can't create %s node at \"%s\"->\"%s\"",
 	b->name, NG_TEE_NODE_TYPE, path, mp.ourhook);
+      MUTEX_UNLOCK(gNgMutex);
       return(-1);
     }
     strlcat(path, ".", NG_PATHSIZ);
@@ -2461,10 +2489,12 @@
     if (NgSendMsg(gLinksCsock, path,
 	NGM_GENERIC_COOKIE, NGM_NAME, &nm, sizeof(nm)) < 0) {
       Perror("[%s] can't name %s node", b->name, NG_TEE_NODE_TYPE);
+      MUTEX_UNLOCK(gNgMutex);
       return(-1);
     }
     strcpy(hook, NG_TEE_HOOK_LEFT);
 
+    MUTEX_UNLOCK(gNgMutex);
     return(0);
 }
 
@@ -2473,8 +2503,10 @@
 {
     char	path[NG_PATHSIZ];
 
+    MUTEX_LOCK(gNgMutex);
     snprintf(path, sizeof(path), "%s-tee%s:", b->iface.ifname, v6?"6":"");
     NgFuncShutdownNode(gLinksCsock, b->name, path);
+    MUTEX_UNLOCK(gNgMutex);
 }
 
 #ifdef USE_NG_IPACCT
@@ -2490,6 +2522,7 @@
 	int		data;
     } ipam;
 
+    MUTEX_LOCK(gNgMutex);
     Log(LG_IFACE2, ("[%s] IFACE: Connecting ipacct", b->name));
   
     strcpy(mp.type, NG_TEE_NODE_TYPE);
@@ -2499,6 +2532,7 @@
 	NGM_GENERIC_COOKIE, NGM_MKPEER, &mp, sizeof(mp)) < 0) {
       Perror("[%s] can't create %s node at \"%s\"->\"%s\"",
 	b->name, NG_TEE_NODE_TYPE, path, mp.ourhook);
+      MUTEX_UNLOCK(gNgMutex);
       return(-1);
     }
     strlcat(path, ".", NG_PATHSIZ);
@@ -2507,6 +2541,7 @@
     if (NgSendMsg(gLinksCsock, path,
 	NGM_GENERIC_COOKIE, NGM_NAME, &nm, sizeof(nm)) < 0) {
       Perror("[%s] can't name %s node", b->name, NG_TEE_NODE_TYPE);
+      MUTEX_UNLOCK(gNgMutex);
       return(-1);
     }
     strcpy(hook, NG_TEE_HOOK_LEFT);
@@ -2518,6 +2553,7 @@
 	NGM_GENERIC_COOKIE, NGM_MKPEER, &mp, sizeof(mp)) < 0) {
       Perror("[%s] can't create %s node at \"%s\"->\"%s\"",
 	b->name, NG_IPACCT_NODE_TYPE, path, mp.ourhook);
+      MUTEX_UNLOCK(gNgMutex);
       return(-1);
     }
     snprintf(path1, sizeof(path1), "%s.%s", path, NG_TEE_HOOK_RIGHT2LEFT);
@@ -2525,6 +2561,7 @@
     if (NgSendMsg(gLinksCsock, path1,
 	NGM_GENERIC_COOKIE, NGM_NAME, &nm, sizeof(nm)) < 0) {
       Perror("[%s] can't name %s node", b->name, NG_IPACCT_NODE_TYPE);
+      MUTEX_UNLOCK(gNgMutex);
       return(-1);
     }
     strcpy(cn.ourhook, NG_TEE_HOOK_LEFT2RIGHT);
@@ -2534,6 +2571,7 @@
 	sizeof(cn)) < 0) {
       Perror("[%s] can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\"",
         b->name, path, cn.ourhook, cn.path, cn.peerhook);
+      MUTEX_UNLOCK(gNgMutex);
       return (-1);
     }
     
@@ -2542,12 +2580,14 @@
     if (NgSendMsg(gLinksCsock, path1, NGM_IPACCT_COOKIE, NGM_IPACCT_SETDLT, 
 	&ipam, sizeof(ipam)) < 0) {
       Perror("[%s] can't set DLT \"%s\"->\"%s\"", b->name, path, ipam.m.hname);
+      MUTEX_UNLOCK(gNgMutex);
       return (-1);
     }
     ipam.data = 10000;
     if (NgSendMsg(gLinksCsock, path1, NGM_IPACCT_COOKIE, NGM_IPACCT_STHRS, 
 	&ipam, sizeof(ipam)) < 0) {
       Perror("[%s] can't set DLT \"%s\"->\"%s\"", b->name, path, ipam.m.hname);
+      MUTEX_UNLOCK(gNgMutex);
       return (-1);
     }
     
@@ -2556,15 +2596,18 @@
     if (NgSendMsg(gLinksCsock, path1, NGM_IPACCT_COOKIE, NGM_IPACCT_SETDLT, 
 	&ipam, sizeof(ipam)) < 0) {
       Perror("[%s] can't set DLT \"%s\"->\"%s\"", b->name, path, ipam.m.hname);
+      MUTEX_UNLOCK(gNgMutex);
       return (-1);
     }
     ipam.data = 10000;
     if (NgSendMsg(gLinksCsock, path1, NGM_IPACCT_COOKIE, NGM_IPACCT_STHRS, 
 	&ipam, sizeof(ipam)) < 0) {
       Perror("[%s] can't set DLT \"%s\"->\"%s\"", b->name, path, ipam.m.hname);
+      MUTEX_UNLOCK(gNgMutex);
       return (-1);
     }
 
+    MUTEX_UNLOCK(gNgMutex);
     return(0);
 }
 
@@ -2573,8 +2616,10 @@
 {
     char	path[NG_PATHSIZ];
 
+    MUTEX_LOCK(gNgMutex);
     snprintf(path, sizeof(path), "%s_acct_tee:", b->iface.ifname);
     NgFuncShutdownNode(gLinksCsock, b->name, path);
+    MUTEX_UNLOCK(gNgMutex);
 }
 #endif
 
@@ -2591,12 +2636,15 @@
     nif = gNetflowIface + b->id*2 + out;
 #endif
 
+    MUTEX_LOCK(gNgMutex);
     Log(LG_IFACE2, ("[%s] IFACE: Connecting netflow (%s)", b->name, out?"out":"in"));
   
     /* Create global ng_netflow(4) node if not yet. */
     if (gNetflowNodeID == 0) {
-	if (NgFuncInitGlobalNetflow())
+	if (NgFuncInitGlobalNetflow()) {
+	    MUTEX_UNLOCK(gNgMutex);
 	    return(-1);
+	}
     }
 
     /* Connect ng_netflow(4) node to the ng_bpf(4)/ng_tee(4) node. */
@@ -2617,6 +2665,7 @@
 	sizeof(cn)) < 0) {
       Perror("[%s] can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\"",
         b->name, path, cn.ourhook, cn.path, cn.peerhook);
+      MUTEX_UNLOCK(gNgMutex);
       return (-1);
     }
     strlcat(path, ".", NG_PATHSIZ);
@@ -2630,6 +2679,7 @@
 #ifndef NG_NETFLOW_CONF_INGRESS
     }
 #endif
+    MUTEX_UNLOCK(gNgMutex);
     return (0);
 }
 
@@ -2650,6 +2700,7 @@
     nif = gNetflowIface + b->id*2 + out;
 #endif
     
+    MUTEX_LOCK(gNgMutex);
     /* Configure data link type and interface index. */
     snprintf(path, sizeof(path), "[%x]:", gNetflowNodeID);
     nf_setdlt.iface = nif;
@@ -2685,8 +2736,10 @@
     }
 #endif
 
+    MUTEX_UNLOCK(gNgMutex);
     return 0;
 fail:
+    MUTEX_UNLOCK(gNgMutex);
     return -1;
 }
 
@@ -2703,11 +2756,13 @@
     nif = gNetflowIface + b->id*2 + out;
 #endif
 
+    MUTEX_LOCK(gNgMutex);
     snprintf(path, NG_PATHSIZ, "[%x]:", gNetflowNodeID);
     snprintf(hook, NG_HOOKSIZ, "%s%d", NG_NETFLOW_HOOK_DATA, nif);
     NgFuncDisconnect(gLinksCsock, b->name, path, hook);
     snprintf(hook, NG_HOOKSIZ, "%s%d", NG_NETFLOW_HOOK_OUT, nif);
     NgFuncDisconnect(gLinksCsock, b->name, path, hook);
+    MUTEX_UNLOCK(gNgMutex);
 }
 #endif
 
@@ -2721,6 +2776,7 @@
 	struct ngm_connect	cn;
 #endif
 
+        MUTEX_LOCK(gNgMutex);
 	Log(LG_IFACE2, ("[%s] IFACE: Connecting tcpmssfix", b->name));
   
 #ifdef USE_NG_TCPMSS
@@ -2793,8 +2849,10 @@
     }
 #endif /* USE_NG_TCPMSS */
 
+    MUTEX_UNLOCK(gNgMutex);
     return (0);
 fail:
+    MUTEX_UNLOCK(gNgMutex);
     return (-1);
 }
 
@@ -2811,6 +2869,7 @@
   struct	ng_tcpmss_config tcpmsscfg;
   char		path[NG_PATHSIZ];
 
+  MUTEX_LOCK(gNgMutex);
   snprintf(path, sizeof(path), "mpd%d-%s-mss:", gPid, b->name);
 
   /* Send configure message. */
@@ -2829,6 +2888,7 @@
       &tcpmsscfg, sizeof(tcpmsscfg)) < 0) {
     Perror("[%s] can't configure %s node program", b->name, NG_TCPMSS_NODE_TYPE);
   }
+  MUTEX_UNLOCK(gNgMutex);
 #else
     union {
 	u_char			buf[NG_BPF_HOOKPROG_SIZE(TCPSYN_PROG_LEN)];
@@ -2837,6 +2897,7 @@
     struct ng_bpf_hookprog	*const hp = &u.hprog;
     char			hook[NG_HOOKSIZ];
 
+    MUTEX_LOCK(gNgMutex);
     /* Setup programs for ng_bpf hooks */
     snprintf(hook, sizeof(hook), "i%d", b->id);
 
@@ -2889,6 +2950,7 @@
 	    NGM_BPF_SET_PROGRAM, hp, NG_BPF_HOOKPROG_SIZE(hp->bpf_prog_len)) < 0)
 	Perror("[%s] can't set %s node program", b->name, NG_BPF_NODE_TYPE);
 
+    MUTEX_UNLOCK(gNgMutex);
 #endif /* USE_NG_TCPMSS */
 }
 
@@ -2897,6 +2959,7 @@
 {
 	char	path[NG_PATHSIZ];
 
+        MUTEX_LOCK(gNgMutex);
 #ifdef USE_NG_TCPMSS
 	snprintf(path, sizeof(path), "mpd%d-%s-mss:", gPid, b->name);
 	NgFuncShutdownNode(gLinksCsock, b->name, path);
@@ -2904,6 +2967,7 @@
 	snprintf(path, sizeof(path), "i%d", b->id);
 	NgFuncShutdownNode(gLinksCsock, b->name, path);
 #endif
+        MUTEX_UNLOCK(gNgMutex);
 }
 #endif /* defined(USE_NG_TCPMSS) || (!defined(USE_NG_TCPMSS) && defined(USE_NG_BPF)) */
 
@@ -2914,6 +2978,7 @@
     struct ngm_mkpeer	mp;
     struct ngm_name	nm;
 
+    MUTEX_LOCK(gNgMutex);
     if (b->params.acl_limits[0] || b->params.acl_limits[1]) {
 
 	Log(LG_IFACE2, ("[%s] IFACE: Connecting limits", b->name));
@@ -2947,8 +3012,10 @@
 
     }
 
+    MUTEX_UNLOCK(gNgMutex);
     return (0);
 fail:
+    MUTEX_UNLOCK(gNgMutex);
     return (-1);
 }
 
@@ -3120,6 +3187,7 @@
 			sprintf(hp->ifMatch, "%d-%d-m", dir, num);
 			sprintf(inhookn[0], "%d-%d-mi", dir, num);
 
+		        MUTEX_LOCK(gNgMutex);
 			/* Connect nomatch hook to bpf itself. */
 			strcpy(cn.ourhook, hp->ifMatch);
 			strcpy(cn.path, path);
@@ -3130,6 +3198,7 @@
 			        b->name, path, cn.ourhook, cn.path, cn.peerhook);
 			}
 			strcpy(stathook, inhookn[0]);
+		        MUTEX_UNLOCK(gNgMutex);
 		    }
 		} else if (strcasecmp(av[p], "pass") == 0) {
 		    strcpy(hp->ifMatch, outhook);
@@ -3144,6 +3213,7 @@
 		    struct ng_car_bulkconf car;
 		    char		tmppath[NG_PATHSIZ];
 
+		    MUTEX_LOCK(gNgMutex);
 		    sprintf(hp->ifMatch, "%d-%d-m", dir, num);
 
 		    /* Create a car node for traffic shaping. */
@@ -3242,6 +3312,7 @@
 			sprintf(inhookn[0], "%d-%d-mi", dir, num);
 			strcpy(stathook, inhookn[0]);
 		    }
+		    MUTEX_UNLOCK(gNgMutex);
 #endif /* USE_NG_CAR */
 	        } else {
 		    Log(LG_ERR, ("[%s] IFACE: unknown action: '%s'",
@@ -3251,6 +3322,7 @@
 		
 		/* Prepare nomatch */
 		if (l->next && strcasecmp(av[0], "all")) {
+		    MUTEX_LOCK(gNgMutex);
 		    /* If there is next limit and there is possible nomatch,
 		     * then pass nomatch there. */
 		    sprintf(hp->ifNotMatch, "%d-%d-n", dir, num);
@@ -3265,6 +3337,7 @@
 			Perror("[%s] IFACE: can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\"",
 			    b->name, path, cn.ourhook, cn.path, cn.peerhook);
 		    }
+		    MUTEX_UNLOCK(gNgMutex);
 		} else {
 		    /* There is no next limit, pass nomatch. */
 		    strcpy(hp->ifNotMatch, outhook);
@@ -3300,12 +3373,14 @@
 			    SLIST_INSERT_HEAD(&ss->src, sss, next);
 			}
 		
+		        MUTEX_LOCK(gNgMutex);
 		        strcpy(hp->thisHook, inhook[i]);
 		        if (NgSendMsg(gLinksCsock, path, NGM_BPF_COOKIE, NGM_BPF_SET_PROGRAM,
 		    		hp, NG_BPF_HOOKPROG_SIZE(hp->bpf_prog_len)) < 0) {
 			    Perror("[%s] IFACE: can't set %s node program",
 	    		        b->name, NG_BPF_NODE_TYPE);
 			}
+		        MUTEX_UNLOCK(gNgMutex);
 		    }
 		    strcpy(inhook[i], inhookn[i]);
 		}
@@ -3313,6 +3388,7 @@
 		num++;
 	    }
 	
+	    MUTEX_LOCK(gNgMutex);
 	    /* Connect left hooks to output */
 	    for (i = 0; i < 2; i++) {
 		if (inhook[i][0] != 0) {
@@ -3330,6 +3406,7 @@
 		    }
 		}
 	    }
+	    MUTEX_UNLOCK(gNgMutex);
 	}
     }
     Freee(hpu);
@@ -3352,8 +3429,10 @@
     }
 
     if (b->params.acl_limits[0] || b->params.acl_limits[1]) {
+        MUTEX_LOCK(gNgMutex);
 	snprintf(path, sizeof(path), "[%x]:", b->iface.limitID);
 	NgFuncShutdownNode(gLinksCsock, b->name, path);
+        MUTEX_UNLOCK(gNgMutex);
     }
 
     for (i = 0; i < ACL_DIRS; i++) {
@@ -3397,6 +3476,7 @@
 		SLIST_INSERT_HEAD(&stat->stat[dir], ssr, next);
 	    }
     
+	    MUTEX_LOCK(gNgMutex);
 	    SLIST_FOREACH(sss, &ss->src, next) {
 		if (NgSendMsg(gLinksCsock, path,
     		    NGM_BPF_COOKIE, NGM_BPF_GET_STATS, sss->hook, strlen(sss->hook)+1) < 0)
@@ -3423,6 +3503,7 @@
 		    break;
 		}
 	    }
+	    MUTEX_UNLOCK(gNgMutex);
 	}
     }
 }
diff -ur mpd-5.6/src/input.c mpd-5.6-lutz/src/input.c
--- mpd-5.6/src/input.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/input.c	2013-03-28 16:49:23.000000000 +0100
@@ -247,7 +247,9 @@
 		    Log(LG_ECHO, ("[%s] rec'd %s #%d, replying...",
 			b->name, FsmCodeName(hdr->code), hdr->id));
 		    MBDATAU(pkt)[0] = CODE_ECHOREP;
+		    MUTEX_LOCK(gNgMutex);
 		    NgFuncWritePppFrame(b, NG_PPP_BUNDLE_LINKNUM, PROTO_LCP, pkt);
+		    MUTEX_UNLOCK(gNgMutex);
 		    return;
 
 		case CODE_ECHOREP:
diff -ur mpd-5.6/src/ipcp.c mpd-5.6-lutz/src/ipcp.c
--- mpd-5.6/src/ipcp.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/ipcp.c	2013-04-24 12:20:07.000000000 +0200
@@ -246,11 +246,15 @@
   Printf("  %15s\r\n", inet_ntoa(ipcp->want_nbns[1]));
 
 #ifdef USE_NG_VJC
+  MUTEX_LOCK(gNgMutex);
   /* Get VJC state */
   snprintf(path, sizeof(path), "mpd%d-%s:%s", gPid, ctx->bund->name, NG_PPP_HOOK_VJC_IP);
   if (NgFuncSendQuery(path, NGM_VJC_COOKIE, NGM_VJC_GET_STATE,
-      NULL, 0, &u.reply, sizeof(u), NULL) < 0)
+      NULL, 0, &u.reply, sizeof(u), NULL) < 0) {
+    MUTEX_UNLOCK(gNgMutex);
     return(0);
+  }
+  MUTEX_UNLOCK(gNgMutex);
 
   Printf("VJ Compression:\r\n");
   Printf("\tOut comp : %d\r\n", sls->sls_compressed);
@@ -320,7 +324,7 @@
     /* Get allowed IP addresses from config and/or from current bundle */
     if (ipcp->conf.self_ippool[0]) {
 	if (IPPoolGet(ipcp->conf.self_ippool, &ipcp->self_allow.addr)) {
-	    Log(LG_IPCP, ("[%s] IPCP: Can't get IP from pool \"%s\" for self",
+	    Log(LG_ERR|LG_IPCP, ("[%s] IPCP: Can't get IP from pool \"%s\" for self",
 		b->name, ipcp->conf.self_ippool));
 	} else {
 	    Log(LG_IPCP, ("[%s] IPCP: Got IP %s from pool \"%s\" for self",
@@ -338,7 +342,7 @@
     else if (b->params.ippool[0]) {
 	/* Get IP from pool if needed */
 	if (IPPoolGet(b->params.ippool, &ipcp->peer_allow.addr)) {
-	    Log(LG_IPCP, ("[%s] IPCP: Can't get IP from pool \"%s\" for peer",
+	    Log(LG_ERR|LG_IPCP, ("[%s] IPCP: Can't get IP from pool \"%s\" for peer",
 		b->name, b->params.ippool));
 	} else {
 	    Log(LG_IPCP, ("[%s] IPCP: Got IP %s from pool \"%s\" for peer",
@@ -350,7 +354,7 @@
 	}
     } else if (ipcp->conf.ippool[0]) {
 	if (IPPoolGet(ipcp->conf.ippool, &ipcp->peer_allow.addr)) {
-	    Log(LG_IPCP, ("[%s] IPCP: Can't get IP from pool \"%s\"",
+	    Log(LG_ERR|LG_IPCP, ("[%s] IPCP: Can't get IP from pool \"%s\"",
 		b->name, ipcp->conf.ippool));
 	} else {
 	    Log(LG_IPCP, ("[%s] IPCP: Got IP %s from pool \"%s\" for peer",
@@ -545,10 +549,12 @@
 	vjc.maxChannel = ipcp->peer_comp.maxchan;
 	vjc.compressCID = ipcp->peer_comp.compcid;
         snprintf(path, sizeof(path), "[%x]:%s", b->nodeID, NG_PPP_HOOK_VJC_IP);
+	MUTEX_LOCK(gNgMutex);
 	if (NgSendMsg(gLinksCsock, path,
     		NGM_VJC_COOKIE, NGM_VJC_SET_CONFIG, &vjc, sizeof(vjc)) < 0) {
 	    Perror("[%s] can't config %s node", b->name, NG_VJC_NODE_TYPE);
 	}
+	MUTEX_UNLOCK(gNgMutex);
     }
 #endif /* USE_NG_VJC */
 
@@ -558,7 +564,9 @@
     b->pppConfig.bund.enableVJCompression = vjc.enableComp;
     b->pppConfig.bund.enableVJDecompression = vjc.enableDecomp;
 #endif
+    MUTEX_LOCK(gNgMutex);
     NgFuncSetConfig(b);
+    MUTEX_UNLOCK(gNgMutex);
 
     BundNcpsJoin(b, NCP_IPCP);
 }
@@ -585,7 +593,9 @@
     b->pppConfig.bund.enableVJCompression = 0;
     b->pppConfig.bund.enableVJDecompression = 0;
 #endif
+    MUTEX_LOCK(gNgMutex);
     NgFuncSetConfig(b);
+    MUTEX_UNLOCK(gNgMutex);
 
 #ifdef USE_NG_VJC
     if (ntohs(ipcp->peer_comp.proto) == PROTO_VJCOMP || 
@@ -905,6 +915,7 @@
   char path[NG_PATHSIZ];
   struct ngm_name	nm;
 
+  MUTEX_LOCK(gNgMutex);
   /* Add a VJ compression node */
   snprintf(path, sizeof(path), "[%x]:", b->nodeID);
   strcpy(mp.type, NG_VJC_NODE_TYPE);
@@ -954,8 +965,10 @@
     goto fail;
   }
 
+    MUTEX_UNLOCK(gNgMutex);
     return 0;
 fail:
+    MUTEX_UNLOCK(gNgMutex);
     return -1;
 }
 
@@ -964,8 +977,10 @@
 {
     char	path[NG_PATHSIZ];
 
+    MUTEX_LOCK(gNgMutex);
     snprintf(path, sizeof(path), "[%x]:%s", b->nodeID, NG_PPP_HOOK_VJC_IP);
     NgFuncShutdownNode(gLinksCsock, b->name, path);
+    MUTEX_UNLOCK(gNgMutex);
 }
 #endif /* USE_NG_VJC */
 
diff -ur mpd-5.6/src/ipv6cp.c mpd-5.6-lutz/src/ipv6cp.c
--- mpd-5.6/src/ipv6cp.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/ipv6cp.c	2013-03-28 16:48:56.000000000 +0100
@@ -300,7 +300,9 @@
 
     /* Enable IP packets in the PPP node */
     b->pppConfig.bund.enableIPv6 = 1;
+    MUTEX_LOCK(gNgMutex);
     NgFuncSetConfig(b);
+    MUTEX_UNLOCK(gNgMutex);
 
     BundNcpsJoin(b, NCP_IPV6CP);
 }
@@ -320,7 +322,9 @@
 
     /* Turn off IP packets */
     b->pppConfig.bund.enableIPv6 = 0;
+    MUTEX_LOCK(gNgMutex);
     NgFuncSetConfig(b);
+    MUTEX_UNLOCK(gNgMutex);
 }
 
 /*
diff -ur mpd-5.6/src/l2tp.c mpd-5.6-lutz/src/l2tp.c
--- mpd-5.6/src/l2tp.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/l2tp.c	2013-04-24 12:16:51.000000000 +0200
@@ -399,7 +399,7 @@
 
 	/* Sanity check. */
 	if (l->state != PHYS_STATE_DOWN) {
-		Log(LG_PHYS, ("[%s] L2TP: allready active", l->name));
+		Log(LG_ERR|LG_PHYS, ("[%s] L2TP: allready active", l->name));
 		return;
 	};
 
@@ -536,9 +536,11 @@
 	    tun->ctrl, u_addrtoa(&tun->self_addr,buf,sizeof(buf)), tun->self_port,
 	    u_addrtoa(&tun->peer_addr,buf2,sizeof(buf2)), tun->peer_port));
 
+	MUTEX_LOCK(gNgMutex);
 	/* Get a temporary netgraph socket node */
 	if (NgMkSockNode(NULL, &csock, &dsock) == -1) {
 	    Perror("[%s] NgMkSockNode", l->name);
+	    MUTEX_UNLOCK(gNgMutex);
 	    goto fail;
 	}
 
@@ -555,6 +557,7 @@
 	if (NgSendMsg(csock, namebuf, NGM_GENERIC_COOKIE,
 	    NGM_MKPEER, &mkpeer, sizeof(mkpeer)) == -1) {
 		Perror("[%s] mkpeer", l->name);
+		MUTEX_UNLOCK(gNgMutex);
 		goto fail;
 	}
 
@@ -569,12 +572,14 @@
 	if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
 	    NGM_KSOCKET_SETOPT, sockopt, sizeof(sockopt_buf)) == -1) {
 		Perror("[%s] setsockopt", l->name);
+		MUTEX_UNLOCK(gNgMutex);
 		goto fail;
 	}
 	sockopt->name = SO_REUSEPORT;
 	if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
 	    NGM_KSOCKET_SETOPT, sockopt, sizeof(sockopt_buf)) == -1) {
 		Perror("[%s] setsockopt", l->name);
+		MUTEX_UNLOCK(gNgMutex);
 		goto fail;
 	}
 
@@ -584,6 +589,7 @@
 	    if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
 		NGM_KSOCKET_BIND, &sas, sas.ss_len) == -1) {
 		    Perror("[%s] bind", l->name);
+		    MUTEX_UNLOCK(gNgMutex);
 		    goto fail;
 	    }
 	}
@@ -593,6 +599,7 @@
 	      NGM_KSOCKET_CONNECT, &sas, sas.ss_len) == -1
 	    && errno != EINPROGRESS) {
 		Perror("[%s] connect", l->name);
+		MUTEX_UNLOCK(gNgMutex);
 		goto fail;
 	}
 
@@ -605,6 +612,7 @@
 	} else {
 	    sockaddrtou_addr(getsas,&tun->self_addr,&tun->self_port);
 	}
+	MUTEX_UNLOCK(gNgMutex);
 
 	/* Add peer to our hash table */
 	if (ghash_put(gL2tpTuns, tun) == -1) {
@@ -704,9 +712,11 @@
 	
 	if (node_id != 0) {
 
+	    MUTEX_LOCK(gNgMutex);
 	    /* Get a temporary netgraph socket node */
 	    if (NgMkSockNode(NULL, &csock, NULL) == -1) {
 		Perror("L2TP: NgMkSockNode");
+		MUTEX_UNLOCK(gNgMutex);
 		return;
 	    }
 	
@@ -715,6 +725,7 @@
 	    NgFuncDisconnect(csock, l->name, path, hook);
 	
 	    close(csock);
+	    MUTEX_UNLOCK(gNgMutex);
 	}
     }
 }
@@ -1194,7 +1205,7 @@
 		ppp_l2tp_avp_ptrs_destroy(&ptrs);
 		return;
 	}
-	Log(LG_PHYS, ("L2TP: No free link with requested parameters "
+	Log(LG_ERR|LG_PHYS, ("L2TP: No free link with requested parameters "
 	    "was found"));
 failed:
 	ppp_l2tp_terminate(sess, L2TP_RESULT_AVAIL_TEMP, 0, NULL);
@@ -1305,6 +1316,7 @@
 	char		path[NG_PATHSIZ];
 	struct ngm_connect      cn;
 
+	MUTEX_LOCK(gNgMutex);
 	/* Get a temporary netgraph socket node */
 	if (NgMkSockNode(NULL, &csock, NULL) == -1) {
 		Perror("L2TP: NgMkSockNode");
@@ -1319,7 +1331,7 @@
 
 	/* Connect our ng_ppp(4) node link hook and ng_l2tp(4) node. */
 	if (!PhysGetUpperHook(l, cn.path, cn.peerhook)) {
-	    Log(LG_PHYS, ("[%s] L2TP: can't get upper hook", l->name));
+	    Log(LG_ERR|LG_PHYS, ("[%s] L2TP: can't get upper hook", l->name));
 	    goto fail;
 	}
 	snprintf(path, sizeof(path), "[%lx]:", (u_long)node_id);
@@ -1330,11 +1342,13 @@
     		    l->name, path, cn.ourhook, cn.path, cn.peerhook);
 		goto fail;
 	}
+	MUTEX_UNLOCK(gNgMutex);
 	ppp_l2tp_sess_hooked(pi->sess);
 	close(csock);
 	return;
 
 fail:
+	MUTEX_UNLOCK(gNgMutex);
 	/* Clean up after failure */
 	ppp_l2tp_terminate(pi->sess, L2TP_RESULT_ERROR,
 	    L2TP_ERROR_GENERIC, strerror(errno));
@@ -1433,7 +1447,7 @@
 		}
 	}
 	if (pi == NULL) {
-		Log(LG_PHYS, ("L2TP: No link with requested parameters "
+		Log(LG_ERR|LG_PHYS, ("L2TP: No link with requested parameters "
 		    "was found"));
 		goto fail;
 	}
@@ -1472,9 +1486,11 @@
 	}
 	ppp_l2tp_ctrl_set_cookie(tun->ctrl, tun);
 
+	MUTEX_LOCK(gNgMutex);
 	/* Get a temporary netgraph socket node */
 	if (NgMkSockNode(NULL, &csock, &dsock) == -1) {
 		Perror("L2TP: NgMkSockNode");
+		MUTEX_UNLOCK(gNgMutex);
 		goto fail;
 	}
 
@@ -1487,12 +1503,14 @@
 	if (NgSendMsg(csock, ".:", NGM_GENERIC_COOKIE,
 	    NGM_CONNECT, &connect, sizeof(connect)) == -1) {
 		Perror("L2TP: connect");
+		MUTEX_UNLOCK(gNgMutex);
 		goto fail;
 	}
 
 	/* Write the received packet to the node */
 	if (NgSendData(dsock, hook, (u_char *)buf, len) == -1) {
 		Perror("L2TP: NgSendData");
+		MUTEX_UNLOCK(gNgMutex);
 		goto fail;
 	}
 
@@ -1502,6 +1520,7 @@
 	if (NgSendMsg(csock, ".:", NGM_GENERIC_COOKIE,
 	    NGM_RMHOOK, &rmhook, sizeof(rmhook)) == -1) {
 		Perror("L2TP: rmhook");
+		MUTEX_UNLOCK(gNgMutex);
 		goto fail;
 	}
 
@@ -1517,6 +1536,7 @@
 	if (NgSendMsg(csock, namebuf, NGM_GENERIC_COOKIE,
 	    NGM_MKPEER, &mkpeer, sizeof(mkpeer)) == -1) {
 		Perror("L2TP: mkpeer");
+		MUTEX_UNLOCK(gNgMutex);
 		goto fail;
 	}
 
@@ -1531,12 +1551,14 @@
 	if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
 	    NGM_KSOCKET_SETOPT, sockopt, sizeof(sockopt_buf)) == -1) {
 		Perror("L2TP: setsockopt");
+		MUTEX_UNLOCK(gNgMutex);
 		goto fail;
 	}
 	sockopt->name = SO_REUSEPORT;
 	if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
 	    NGM_KSOCKET_SETOPT, sockopt, sizeof(sockopt_buf)) == -1) {
 		Perror("L2TP: setsockopt");
+		MUTEX_UNLOCK(gNgMutex);
 		goto fail;
 	}
 
@@ -1545,6 +1567,7 @@
 	if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
 	    NGM_KSOCKET_BIND, &sas, sas.ss_len) == -1) {
 		Perror("L2TP: bind");
+		MUTEX_UNLOCK(gNgMutex);
 		goto fail;
 	}
 
@@ -1553,8 +1576,10 @@
 	      NGM_KSOCKET_CONNECT, &peer_sas, peer_sas.ss_len) == -1
 	    && errno != EINPROGRESS) {
 		Perror("L2TP: connect");
+		MUTEX_UNLOCK(gNgMutex);
 		goto fail;
 	}
+	MUTEX_UNLOCK(gNgMutex);
 
 	/* Add peer to our hash table */
 	if (ghash_put(gL2tpTuns, tun) == -1) {
diff -ur mpd-5.6/src/l2tp_ctrl.c mpd-5.6-lutz/src/l2tp_ctrl.c
--- mpd-5.6/src/l2tp_ctrl.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/l2tp_ctrl.c	2013-04-24 12:13:56.000000000 +0200
@@ -476,6 +476,7 @@
 	/* Debugging */
 	Log(LOG_DEBUG, ("L2TP: %s invoked", __FUNCTION__));
 
+	MUTEX_LOCK(gNgMutex);
 	/* Select an unused, non-zero local tunnel ID */
 	while (ctrl->config.tunnel_id == 0
 	    || ghash_get(ppp_l2tp_ctrls, ctrl) != NULL)
@@ -594,6 +595,7 @@
 
 	ctrl->state = CS_IDLE;		/* wait for peer's sccrq */
 
+	MUTEX_UNLOCK(gNgMutex);
 	/* Expect some sort of reply */
 	ppp_l2tp_ctrl_check_reply(ctrl);
 
@@ -608,6 +610,7 @@
 		(void)close(ctrl->csock);	/* l2tp node will go away too */
 	if (ctrl->dsock >= 0)
 		(void)close(ctrl->dsock);
+	MUTEX_UNLOCK(gNgMutex);
 	pevent_unregister(&ctrl->reply_timer);
 	pevent_unregister(&ctrl->ctrl_event);
 	pevent_unregister(&ctrl->data_event);
@@ -1008,10 +1011,12 @@
 ppp_l2tp_sess_hooked(struct ppp_l2tp_sess *sess) {
 	char path[32];
 
+	MUTEX_LOCK(gNgMutex);
 	snprintf(path, sizeof(path), "[%lx]:", (u_long)sess->node_id);
 	(void)NgSendMsg(sess->ctrl->csock, path,
 	    NGM_GENERIC_COOKIE, NGM_SHUTDOWN, NULL, 0);
 	sess->node_id = 0;
+	MUTEX_UNLOCK(gNgMutex);
 }
 
 /************************************************************************
@@ -1057,10 +1062,14 @@
 
 	strlcpy(ctrl->peer_name, ptrs->hostname->hostname, sizeof(ctrl->peer_name));
 
+	MUTEX_LOCK(gNgMutex);
 	/* Update netgraph node configuration */
 	if (NgSendMsg(ctrl->csock, NG_L2TP_HOOK_CTRL, NGM_L2TP_COOKIE,
-	    NGM_L2TP_SET_CONFIG, &ctrl->config, sizeof(ctrl->config)) == -1)
+	    NGM_L2TP_SET_CONFIG, &ctrl->config, sizeof(ctrl->config)) == -1) {
+		MUTEX_UNLOCK(gNgMutex);
 		return (-1);
+	}
+	MUTEX_UNLOCK(gNgMutex);
 
 	/* See if there is a challenge AVP */
 	if (ptrs->challenge != NULL) {
@@ -1102,11 +1111,15 @@
 ppp_l2tp_ctrl_setup_2(struct ppp_l2tp_ctrl *ctrl,
 	struct ppp_l2tp_avp_ptrs *ptrs)
 {
+	MUTEX_LOCK(gNgMutex);
 	/* Peer now knows our tunnel ID */
 	ctrl->config.match_id = 1;
 	if (NgSendMsg(ctrl->csock, NG_L2TP_HOOK_CTRL, NGM_L2TP_COOKIE,
-	    NGM_L2TP_SET_CONFIG, &ctrl->config, sizeof(ctrl->config)) == -1)
+	    NGM_L2TP_SET_CONFIG, &ctrl->config, sizeof(ctrl->config)) == -1) {
+		MUTEX_UNLOCK(gNgMutex);
 		return (-1);
+	}
+	MUTEX_UNLOCK(gNgMutex);
 
 	/* Verify peer's challenge response */
 	if (ctrl->secret != NULL) {
@@ -1261,8 +1274,13 @@
 		ppp_l2tp_ctrl_dump(ctrl, avps, "L2TP: XMIT(0x%04x) ",
 		    ntohs(session_id));
 	}
-	if (NgSendData(ctrl->dsock, NG_L2TP_HOOK_CTRL, data, 2 + len) == -1)
+
+	MUTEX_LOCK(gNgMutex);
+	if (NgSendData(ctrl->dsock, NG_L2TP_HOOK_CTRL, data, 2 + len) == -1) {
+		MUTEX_UNLOCK(gNgMutex);
 		goto fail;
+	}
+	MUTEX_UNLOCK(gNgMutex);
 
 	/* Done */
 	goto done;
@@ -1527,6 +1545,7 @@
 	struct ngm_mkpeer mkpeer;
 	char path[64];
 
+	MUTEX_LOCK(gNgMutex);
 	/* If link side is waiting for confirmation, schedule it */
 	if (sess->side == SIDE_LNS || sess->orig == ORIG_LOCAL) {
 		pevent_unregister(&sess->notify_timer);
@@ -1572,11 +1591,13 @@
 		goto fail;
 	}
 
+	MUTEX_UNLOCK(gNgMutex);
 	/* Call is now established */
 	sess->state = SS_ESTABLISHED;
 	return (0);
 
 fail:
+	MUTEX_UNLOCK(gNgMutex);
 	/* Clean up after failure */
 	pevent_unregister(&sess->notify_timer);
 	return (-1);
@@ -1987,13 +2008,16 @@
 	struct ng_mesg *const msg = &buf.msg;
 	char raddr[NG_PATHSIZ];
 
+	MUTEX_LOCK(gNgMutex);
 	/* Read netgraph control message */
 	if (NgRecvMsg(ctrl->csock, msg, sizeof(buf), raddr) < 0) {
 		Perror("L2TP: error reading control message");
+		MUTEX_UNLOCK(gNgMutex);
 		ppp_l2tp_ctrl_close(ctrl, L2TP_RESULT_ERROR,
 		    L2TP_ERROR_GENERIC, strerror(errno));
 		return;
 	}
+	MUTEX_UNLOCK(gNgMutex);
 
 	/* Examine message */
 	switch (msg->header.typecookie) {
@@ -2398,9 +2422,11 @@
 		ppp_l2tp_sess_destroy(&sess);
 	}
 
+	MUTEX_LOCK(gNgMutex);
 	/* Destroy netgraph node */
 	(void)NgSendMsg(ctrl->csock, NG_L2TP_HOOK_CTRL,
 	    NGM_GENERIC_COOKIE, NGM_SHUTDOWN, NULL, 0);
+	MUTEX_UNLOCK(gNgMutex);
 
 	/* Destroy control connection */
 	ghash_remove(ppp_l2tp_ctrls, ctrl);
@@ -2454,8 +2480,10 @@
 	}
 	ghash_remove(ctrl->sessions, sess);
 	snprintf(path, sizeof(path), "[%lx]:", (u_long)sess->node_id);
+	MUTEX_LOCK(gNgMutex);
 	(void)NgSendMsg(ctrl->csock, path,
 	    NGM_GENERIC_COOKIE, NGM_SHUTDOWN, NULL, 0);
+	MUTEX_UNLOCK(gNgMutex);
 	ppp_l2tp_avp_list_destroy(&sess->my_avps);
 	ppp_l2tp_avp_list_destroy(&sess->peer_avps);
 	pevent_unregister(&sess->notify_timer);
diff -ur mpd-5.6/src/link.c mpd-5.6-lutz/src/link.c
--- mpd-5.6/src/link.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/link.c	2013-04-24 12:07:27.000000000 +0200
@@ -157,14 +157,17 @@
 {
     char	name[NG_NODESIZ];
 
+    MUTEX_LOCK(gNgMutex);
     /* Create a netgraph socket node */
     snprintf(name, sizeof(name), "mpd%d-lso", gPid);
     if (NgMkSockNode(name, &gLinksCsock, &gLinksDsock) < 0) {
 	Perror("LinksInit(): can't create %s node", NG_SOCKET_NODE_TYPE);
+	MUTEX_UNLOCK(gNgMutex);
 	return(-1);
     }
     (void) fcntl(gLinksCsock, F_SETFD, 1);
     (void) fcntl(gLinksDsock, F_SETFD, 1);
+    MUTEX_UNLOCK(gNgMutex);
 
     /* Listen for happenings on our node */
     EventRegister(&gLinksDataEvent, EVENT_READ,
@@ -463,7 +466,7 @@
         PhysInit(l);
         LcpInit(l);
 	
-	MsgRegister(&l->msgs, LinkMsg);
+	MsgSerialRegister(&l->msgs, LinkMsg);
 
 	/* Find a free link pointer */
         for (k = 0; k < gNumLinks && gLinks[k] != NULL; k++);
@@ -579,7 +582,7 @@
 void
 LinkShutdownCheck(Link l, short state)
 {
-    if (state == ST_INITIAL && l->lcp.auth.acct_thread == NULL &&
+    if (state == ST_INITIAL && l->lcp.auth.acct_msg == NULL &&
 	    l->die && !l->stay && l->state == PHYS_STATE_DOWN) {
 	REF(l);
 	MsgSend(&l->msgs, MSG_SHUTDOWN, l);
@@ -597,7 +600,7 @@
     struct linkaction	*a;
 
     Log(LG_LINK, ("[%s] Link: Shutdown", l->name));
-
+   
     /* Late divorce for DoD case */
     if (l->bund) {
 	l->bund->links[l->bundleIndex] = NULL;
@@ -636,6 +639,8 @@
 	Freee(l->downReason);
     MsgUnRegister(&l->msgs);
     UNREF(l);
+    
+   
     CheckOneShot();
 }
 
@@ -653,6 +658,7 @@
     struct ngm_mkpeer	mp;
     struct ngm_name	nm;
 
+    MUTEX_LOCK(gNgMutex);
     /* Initialize structures */
     memset(&mp, 0, sizeof(mp));
     memset(&nm, 0, sizeof(nm));
@@ -684,10 +690,12 @@
 	goto fail;
     };
 
+    MUTEX_UNLOCK(gNgMutex);
     /* OK */
     return(0);
 
 fail:
+    MUTEX_UNLOCK(gNgMutex);
     LinkNgShutdown(l);
     return(-1);
 }
@@ -702,6 +710,7 @@
     char		path[NG_PATHSIZ];
     struct ngm_connect	cn;
 
+    MUTEX_LOCK(gNgMutex);
     snprintf(path, sizeof(path), "[%lx]:", (u_long)l->nodeID);
 
     memset(&cn, 0, sizeof(cn));
@@ -713,10 +722,12 @@
       NGM_GENERIC_COOKIE, NGM_CONNECT, &cn, sizeof(cn)) < 0) {
 	Perror("[%s] can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\"",
 	    l->name, path, cn.ourhook, cn.path, cn.peerhook);
+	MUTEX_UNLOCK(gNgMutex);
 	return(-1);
     }
     
     NgFuncDisconnect(gLinksCsock, l->name, path, NG_TEE_HOOK_LEFT2RIGHT);
+    MUTEX_UNLOCK(gNgMutex);
     return (0);
 }
 
@@ -730,6 +741,7 @@
     char		path[NG_PATHSIZ];
     struct ngm_connect	cn;
 
+    MUTEX_LOCK(gNgMutex);
     memset(&cn, 0, sizeof(cn));
     snprintf(cn.path, sizeof(cn.path), "[%lx]:", (u_long)l->nodeID);
     strcpy(cn.ourhook, l->hook);
@@ -738,11 +750,13 @@
       NGM_GENERIC_COOKIE, NGM_CONNECT, &cn, sizeof(cn)) < 0) {
 	Perror("[%s] can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\"",
 	    l->name, ".:", cn.ourhook, cn.path, cn.peerhook);
+	MUTEX_UNLOCK(gNgMutex);
 	return(-1);
     }
 
     snprintf(path, sizeof(path), "[%lx]:", (u_long)l->nodeID);
     NgFuncDisconnect(gLinksCsock, l->name, path, NG_TEE_HOOK_RIGHT);
+    MUTEX_UNLOCK(gNgMutex);
     return (0);
 }
 
@@ -760,19 +774,22 @@
     snprintf(path, sizeof(path), "[%lx]:", (u_long)l->nodeID);
     strcpy(cn.ourhook, NG_TEE_HOOK_RIGHT);
     if (!PhysGetUpperHook(l, cn.path, cn.peerhook)) {
-        Log(LG_PHYS, ("[%s] Link: can't get repeater hook", l->name));
+        Log(LG_ERR|LG_PHYS, ("[%s] Link: can't get repeater hook", l->name));
         return (-1);
     }
+    MUTEX_LOCK(gNgMutex);
     if (NgSendMsg(gLinksCsock, path,
       NGM_GENERIC_COOKIE, NGM_CONNECT, &cn, sizeof(cn)) < 0) {
 	Perror("[%s] can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\"",
 	    l->name, path, cn.ourhook, cn.path, cn.peerhook);
+	MUTEX_UNLOCK(gNgMutex);
 	return(-1);
     }
 
     /* Shutdown link tee node */
     NgFuncShutdownNode(gLinksCsock, l->name, path);
     l->hook[0] = 0;
+    MUTEX_UNLOCK(gNgMutex);
     return (0);
 }
 
@@ -783,9 +800,11 @@
 void
 LinkNgShutdown(Link l)
 {
+    MUTEX_LOCK(gNgMutex);
     if (l->hook[0])
 	NgFuncShutdownNode(gLinksCsock, l->name, l->hook);
     l->hook[0] = 0;
+    MUTEX_UNLOCK(gNgMutex);
 }
 
 /*
@@ -931,7 +950,9 @@
 	    if (naddr.sg_data[0] == 'o') {
 		IfaceCorrectMSS(bp, MAXMSS(b->iface.mtu));
 		naddr.sg_data[0] = 'i';
+		MUTEX_LOCK(gNgMutex);
 		NgFuncWriteFrame(gLinksDsock, naddr.sg_data, b->name, bp);
+		MUTEX_UNLOCK(gNgMutex);
 		continue;
 	    }
 
@@ -939,7 +960,9 @@
 	    if (naddr.sg_data[0] == 'i') {
 		IfaceCorrectMSS(bp, MAXMSS(b->iface.mtu));
 		naddr.sg_data[0] = 'o';
+		MUTEX_LOCK(gNgMutex);
 		NgFuncWriteFrame(gLinksDsock, naddr.sg_data, b->name, bp);
+		MUTEX_UNLOCK(gNgMutex);
 		continue;
 	    }
 #endif
@@ -1326,6 +1349,7 @@
 #ifndef NG_PPP_STATS64
     struct ng_ppp_link_stat	stats;
 
+    MUTEX_LOCK(gNgMutex);
     if (NgFuncGetStats(l->bund, l->bundleIndex, &stats) != -1) {
 	l->stats.xmitFrames += abs(stats.xmitFrames - l->oldStats.xmitFrames);
 	l->stats.xmitOctets += abs(stats.xmitOctets - l->oldStats.xmitOctets);
@@ -1336,11 +1360,15 @@
         l->stats.dupFragments += abs(stats.dupFragments - l->oldStats.dupFragments);
         l->stats.dropFragments += abs(stats.dropFragments - l->oldStats.dropFragments);
     }
+    MUTEX_UNLOCK(gNgMutex);
 
     l->oldStats = stats;
 #else
+    MUTEX_LOCK(gNgMutex);
     NgFuncGetStats64(l->bund, l->bundleIndex, &l->stats);
+    MUTEX_UNLOCK(gNgMutex);
 #endif
+   
 }
 
 /*
@@ -1350,12 +1378,14 @@
 void
 LinkResetStats(Link l)
 {
+    MUTEX_LOCK(gNgMutex);
     if (l->bund)
 	NgFuncClrStats(l->bund, l->bundleIndex);
     memset(&l->stats, 0, sizeof(l->stats));
 #ifndef NG_PPP_STATS64
     memset(&l->oldStats, 0, sizeof(l->oldStats));
 #endif
+    MUTEX_UNLOCK(gNgMutex);
 }
 
 /*
diff -ur mpd-5.6/src/main.c mpd-5.6-lutz/src/main.c
--- mpd-5.6/src/main.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/main.c	2013-04-25 13:21:27.659354000 +0200
@@ -59,6 +59,8 @@
 				"Set configuration file"	},
     { 0, 'o',	"one-shot",	"",
 				"Terminate daemon after last link shutdown"	},
+    { 0, 'O',	"delayed-one-shot",	"",
+				"Terminate daemon after last active link shutdown"	},
     { 1, 'p',	"pidfile",	"filename",
 				"Set PID filename"		},
 #ifdef SYSLOG_FACILITY
@@ -119,6 +121,7 @@
   struct globalconf	gGlobalConf;
 
   pthread_mutex_t	gGiantMutex;
+  pthread_mutex_t	gNgMutex;
 
   const char		*gConfigFile = CONF_FILE;
   const char		*gConfDirectory = PATH_CONF_DIR;
@@ -179,6 +182,17 @@
     memcpy(args, av, ac * sizeof(*av));	/* Copy to preserve "ps" output */
     OptParse(ac - 1, args + 1);
 
+    ret = pthread_mutex_init (&gGiantMutex, NULL);
+    if (ret != 0) {
+	Log(LG_ERR, ("Could not create giant mutex %d", ret));
+	exit(EX_UNAVAILABLE);
+    }
+    ret = pthread_mutex_init (&gNgMutex, NULL);
+    if (ret != 0) {
+	Log(LG_ERR, ("Could not create NetGraph mutex %d", ret));
+	exit(EX_UNAVAILABLE);
+    }
+
     /* init console-stuff */
     ConsoleInit(&gConsole);
 
@@ -233,7 +247,8 @@
 #ifdef CCP_MPPC
     MppcTestCap();
 #endif
-    if ((LinksInit() != 0) || (CcpsInit() != 0) || (EcpsInit() != 0))
+    if ((LinksInit() != 0) || (CcpsInit() != 0) || (EcpsInit() != 0) ||
+	(MsgSetup() != 0) || (AuthSetup() != 0))
 	exit(EX_UNAVAILABLE);
     
     /* Init device types. */
@@ -244,12 +259,6 @@
 	}
     }
 
-    ret = pthread_mutex_init (&gGiantMutex, NULL);
-    if (ret != 0) {
-	Log(LG_ERR, ("Could not create giant mutex %d", ret));
-	exit(EX_UNAVAILABLE);
-    }
-
     /* Create signaling pipe */
     if ((ret = pipe(gSignalPipe)) != 0) {
 	Log(LG_ERR, ("Could not create signal pipe %d", ret));
@@ -259,6 +268,7 @@
       EVENT_RECURRING, SignalHandler, NULL) != 0)
 	exit(EX_UNAVAILABLE);
 
+   
     /* Register for some common fatal signals so we can exit cleanly */
     signal(SIGINT, SendSignal);
     signal(SIGTERM, SendSignal);
@@ -367,7 +377,9 @@
     if (code != EX_TERMINATE)	/* kludge to avoid double shutdown */
 	CloseIfaces();
 
+    MUTEX_LOCK(gNgMutex);
     NgFuncShutdownGlobal();
+    MUTEX_UNLOCK(gNgMutex);
 
     /* Blow away all netgraph nodes */
     for (k = 0; k < gNumBundles; k++) {
@@ -529,7 +541,7 @@
 CheckOneShot(void)
 {
     int	i;
-    if (!Enabled(&gGlobalConf.options, GLOBAL_CONF_ONESHOT))
+    if (gShutdownInProgress || !Enabled(&gGlobalConf.options, GLOBAL_CONF_ONESHOT))
 	return;
     for (i = 0; i < gNumLinks; i++) {
 	if (gLinks[i] && !gLinks[i]->tmpl)
@@ -608,6 +620,9 @@
 	case 'o':
 	    Enable(&gGlobalConf.options, GLOBAL_CONF_ONESHOT);
     	    return(0);
+	case 'O':
+	    Enable(&gGlobalConf.options, GLOBAL_CONF_DELAYEDONESHOT);
+    	    return(0);
 	case 'p':
     	    gPidFile = *av;
     	    return(1);
diff -ur mpd-5.6/src/modem.c mpd-5.6-lutz/src/modem.c
--- mpd-5.6/src/modem.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/modem.c	2013-03-28 16:46:04.000000000 +0100
@@ -351,6 +351,7 @@
     TimerStop(&m->checkTimer);
     TimerStop(&m->startTimer);
     TimerStop(&m->reportTimer);
+    MUTEX_LOCK(gNgMutex);
     if (*m->ttynode != '\0') {
 	char	path[NG_PATHSIZ];
 
@@ -365,6 +366,7 @@
 	close(m->csock);
 	m->csock = -1;
     }
+    MUTEX_UNLOCK(gNgMutex);
     ExclusiveCloseDevice(l->name, m->fd, m->device);
     m->lastClosed = time(NULL);
     m->answering = FALSE;
@@ -383,14 +385,17 @@
     ModemInfo	const m = (ModemInfo) l->info;
     char	path[NG_PATHSIZ];
 
+    MUTEX_LOCK(gNgMutex);
     /* Update async config */
     m->acfg.accm = xmit|recv;
     snprintf(path, sizeof(path), "%s:%s", m->ttynode, NG_TTY_HOOK);
     if (NgSendMsg(m->csock, path, NGM_ASYNC_COOKIE,
       NGM_ASYNC_CMD_SET_CONFIG, &m->acfg, sizeof(m->acfg)) < 0) {
 	Perror("[%s] MODEM: can't update config for %s", l->name, path);
+	MUTEX_UNLOCK(gNgMutex);
 	return (-1);
     }
+    MUTEX_UNLOCK(gNgMutex);
     return (0);
 }
 
@@ -527,9 +532,11 @@
     int	tty[2];
 #endif
 
+    MUTEX_LOCK(gNgMutex);
     /* Get a temporary netgraph socket node */
     if (NgMkSockNode(NULL, &m->csock, NULL) < 0) {
 	Perror("[%s] MODEM: NgMkSockNode failed", l->name);
+	MUTEX_UNLOCK(gNgMutex);
 	return(-1);
     }
 
@@ -548,6 +555,7 @@
 	if (ioctl(m->fd, TIOCSETD, &ldisc) < 0) {
 	    Perror("[%s] ioctl(TIOCSETD, %d)", l->name, ldisc);
 	    close(m->csock);
+	    MUTEX_UNLOCK(gNgMutex);
 	    return(-1);
 	}
     }
@@ -556,6 +564,7 @@
     if (ioctl(m->fd, NGIOCGINFO, &ngtty) < 0) {
 	Perror("[%s] MODEM: ioctl(NGIOCGINFO)", l->name);
 	close(m->csock);
+	MUTEX_UNLOCK(gNgMutex);
 	return(-1);
     }
     strlcpy(m->ttynode, ngtty.name, sizeof(m->ttynode));
@@ -569,6 +578,7 @@
 	Perror("[%s] MODEM: can't connect %s node on %s", l->name,
 	    NG_TTY_NODE_TYPE, ".");
 	close(m->csock);
+	MUTEX_UNLOCK(gNgMutex);
 	return(-1);
     }
     snprintf(path, sizeof(path), ".:%s", NG_TTY_HOOK);
@@ -578,6 +588,7 @@
 	    Perror("[%s] MODEM: can't locate %s node on %s (%d)", l->name,
 	    NG_TTY_NODE_TYPE, path, errno);
 	    close(m->csock);
+	    MUTEX_UNLOCK(gNgMutex);
 	    return(-1);
 	}
     }
@@ -589,6 +600,7 @@
           NGM_TTY_SET_TTY, &tty, sizeof(tty)) < 0) {
 	Perror("[%s] MODEM: can't hook tty to fd %d", l->name, m->fd);
 	close(m->csock);
+	MUTEX_UNLOCK(gNgMutex);
 	return(-1);
     }
     /* Disconnect temporary hook. */
@@ -597,6 +609,7 @@
 	    NGM_GENERIC_COOKIE, NGM_RMHOOK, &rm, sizeof(rm)) < 0) {
 	Perror("[%s] MODEM: can't remove hook %s", l->name, NG_TTY_HOOK);
 	close(m->csock);
+	MUTEX_UNLOCK(gNgMutex);
 	return(-1);
     }
 #endif
@@ -607,6 +620,7 @@
       NGM_TTY_SET_HOTCHAR, &hotchar, sizeof(hotchar)) < 0) {
 	Perror("[%s] MODEM: can't set hotchar", l->name);
 	close(m->csock);
+	MUTEX_UNLOCK(gNgMutex);
 	return(-1);
     }
 
@@ -618,6 +632,7 @@
       NGM_MKPEER, &ngm, sizeof(ngm)) < 0) {
 	Perror("[%s] MODEM: can't connect %s node", l->name, NG_ASYNC_NODE_TYPE);
 	close(m->csock);
+	MUTEX_UNLOCK(gNgMutex);
 	return(-1);
     }
 
@@ -632,6 +647,7 @@
       NGM_ASYNC_CMD_SET_CONFIG, &m->acfg, sizeof(m->acfg)) < 0) {
 	Perror("[%s] MODEM: can't config %s", l->name, path);
 	close(m->csock);
+	MUTEX_UNLOCK(gNgMutex);
 	return(-1);
     }
 
@@ -639,6 +655,7 @@
     if (!PhysGetUpperHook(l, cn.path, cn.peerhook)) {
 	Log(LG_PHYS, ("[%s] MODEM: can't get upper hook", l->name));
 	close(m->csock);
+	MUTEX_UNLOCK(gNgMutex);
 	return (-1);
     }
     snprintf(cn.ourhook, sizeof(cn.ourhook), NG_ASYNC_HOOK_SYNC);
@@ -647,9 +664,11 @@
 	Perror("[%s] MODEM: can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\"",
 	    l->name, path, cn.ourhook, cn.path, cn.peerhook);
 	close(m->csock);
+	MUTEX_UNLOCK(gNgMutex);
 	return (-1);
     }
 
+    MUTEX_UNLOCK(gNgMutex);
     return(0);
 }
 
@@ -752,8 +771,10 @@
       || stats.asyncRunts || stats.asyncOverflows)) {
 	Log(LG_PHYS, ("[%s] NEW FRAME ERRS: FCS %u RUNT %u OVFL %u", l->name,
           stats.asyncBadCheckSums, stats.asyncRunts, stats.asyncOverflows));
+	MUTEX_LOCK(gNgMutex);
 	(void) NgSendMsg(m->csock, path,
 	    NGM_ASYNC_COOKIE, NGM_ASYNC_CMD_CLR_STATS, NULL, 0);
+	MUTEX_UNLOCK(gNgMutex);
     }
 
     /* Restart timer */
@@ -775,15 +796,18 @@
 	struct ng_mesg	resp;
     } u;
 
+    MUTEX_LOCK(gNgMutex);
     /* Get stats */
     snprintf(path, sizeof(path), "%s:%s", m->ttynode, NG_TTY_HOOK);
     if (NgFuncSendQuery(path, NGM_ASYNC_COOKIE, NGM_ASYNC_CMD_GET_STATS,
       NULL, 0, &u.resp, sizeof(u), NULL) < 0) {
 	Perror("[%s] MODEM: can't get stats", l->name);
+	MUTEX_UNLOCK(gNgMutex);
 	return(-1);
     }
 
     memcpy(sp, u.resp.data, sizeof(*sp));
+    MUTEX_UNLOCK(gNgMutex);
     return(0);
 }
 
diff -ur mpd-5.6/src/msg.c mpd-5.6-lutz/src/msg.c
--- mpd-5.6/src/msg.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/msg.c	2013-04-22 00:14:59.000000000 +0200
@@ -16,67 +16,256 @@
 
 /* Which pipe file descriptor is which */
 
-  #define PIPE_READ		0
-  #define PIPE_WRITE		1
-
   struct mpmsg
   {
     int		type;
     void	(*func)(int type, void *arg);
+    void	(*final)(int type, void *arg, int canceled);
     void	*arg;
     const char	*dbg;
+    int		refs;
+    int 	canceled;
+    struct paction *thread;
   };
-  typedef struct mpmsg	*Msg;
-
-  #define	MSG_QUEUE_LEN	8192
-  #define	MSG_QUEUE_MASK	0x1FFF
-
-  struct mpmsg	msgqueue[MSG_QUEUE_LEN];
-  int		msgqueueh = 0;
-  int		msgqueuet = 0;
-  #define	QUEUELEN()	((msgqueueh >= msgqueuet)?	\
-	(msgqueueh - msgqueuet):(msgqueueh + MSG_QUEUE_LEN - msgqueuet))
-
-  int           msgpipe[2];
-  int		msgpipesent = 0;
-  EventRef	msgevent;
 
 /*
  * INTERNAL FUNCTIONS
  */
 
-  static void	MsgEvent(int type, void *cookie);
+  static void	SerialAction(void *arg);
+  static void	SerialDied(void *arg, int canceled);
+  static void	ParallelAction(void *arg);
+  static void	ParallelDied(void *arg, int canceled);
+
+  static struct queue_data {
+     struct mesg_port * port;
+     struct paction * dispatcher;
+     void (*action)(void * arg);
+     void (*terminate)(void * arg, int canceled);
+     int max_workers;
+     struct mesg_port * worker_port;
+     struct worker_data {
+	Msg msg;
+	struct queue_data * queue;
+     } *workers;	  
+  } queue[] = {
+     { .action = SerialAction  , .terminate = SerialDied   , .max_workers = 0 },
+     { .action = ParallelAction, .terminate = ParallelDied , .max_workers = 8 },
+  };
+
+  static void	ParallelWorker(void *arg);
+  static void	ParallelWorkerDied(void *arg, int canceled);
+  static int	ReuseWorker(struct worker_data * worker);
+
+  int		gQueueDelay = 20;
+
+static void
+update_overload(void) {
+   int i,o=0;
+   time_t now;
+   static time_t last_reported = 0;
+   static int peak[2] = {0};
+   
+   time(&now);
+   
+   for(i=0; i<sizeof(queue)/sizeof(*queue); i++)
+     if(queue[i].port) {
+	int l = mesg_port_qlen(queue[i].port);
+	o += l * (2 + queue[i].max_workers);
+	if(peak[i] < l)
+	  peak[i] = l;
+     }
+   
+   SETOVERLOAD(o);
+   if(now > last_reported) {
+      Log(LG_ALWAYS, ("Queues had up to %d (serial) and %d (parallel) entries.",
+		      peak[0], peak[1]));
+      peak[0] = 0;
+      peak[1] = 0;
+      last_reported = now + (60 - 1);  /* 1 second due to strict less then */
+   }
+   
+}
+
+
+int
+MsgSetup(void)
+{
+   int i;
+   for(i=0; i<sizeof(queue)/sizeof(*queue); i++) {
+      if(NULL == (queue[i].port = mesg_port_create(MB_MP))) {
+	 Perror("%s: mesg_port_create failed with %s",
+		__FUNCTION__, strerror(errno));
+	 return(-1);
+      }
+      if (paction_start(&queue[i].dispatcher, &gGiantMutex,
+			queue[i].action, queue[i].terminate,
+			&queue[i]) == -1) {
+	 Perror("%s: error paction_start: %s", __FUNCTION__, strerror(errno));
+	 return(-1);
+      }
+      if(queue[i].max_workers > 0) {
+	 int j;
+	 
+	 if(NULL == (queue[i].worker_port = mesg_port_create(MB_MP))) {
+	    Perror("%s: mesg_port_create failed with %s",
+		   __FUNCTION__, strerror(errno));
+	    return(-1);
+	 }
+	 
+	 queue[i].workers = Malloc(MB_MP, queue[i].max_workers * sizeof(*queue[i].workers));
+	 assert(queue[i].workers);
+	 
+	 for(j=0; j<queue[i].max_workers; j++) {
+	    queue[i].workers[j].queue = &queue[i];
+	    if(-1 == ReuseWorker(&(queue[i].workers[j]))) {
+	       return(-1);
+	    }
+	 }
+      }
+   }
+   
+   return 0;
+}
+
+int
+ReuseWorker(struct worker_data * worker)
+{
+   assert(worker);
+   assert(worker->queue);
+   assert(worker->queue->worker_port);
+   
+   RESETREF(worker->msg, NULL);
+   
+   if(-1 == mesg_port_put(worker->queue->worker_port, worker)) {
+      Perror("%s: mesg_port_put failed with %s",
+	     __FUNCTION__, strerror(errno));
+      return -1;
+   }
+   
+   return 0;
+}
+
+void
+SerialAction(void *arg) 
+{
+   struct queue_data * q = arg;
+   
+   while(1) {
+      Msg msg = mesg_port_get(q->port, -1);
+      assert(msg);
+      GIANT_MUTEX_LOCK();
+      if(!msg->canceled) {
+	 Log(LG_EVENTS, ("EVENT: Serial processing msg %d to %s", msg->type, msg->dbg));
+	 (*msg->func)(msg->type, msg->arg);
+	 Log(LG_EVENTS, ("EVENT: Serial processing msg %d to %s done", msg->type, msg->dbg));
+      }
+      RESETREF(msg, NULL);
+      update_overload();
+      GIANT_MUTEX_UNLOCK();
+      usleep(gQueueDelay * 1000);
+   }
+}
+
+void
+SerialDied(void *arg, int canceled)
+{
+   Perror("%s: Dispatcher %s unexpectedly. Stop processing.",
+	  __FUNCTION__, (canceled ? "was canceled" : "died"));
+}
+
+
+void
+ParallelWorker(void *arg)
+{
+   struct worker_data * worker = arg;
+   Msg msg;
+   
+   assert(worker);
+   assert(worker->msg);
+   
+   msg = worker->msg;
+
+   Log(LG_EVENTS, ("EVENT: Parallel processing msg %d to %s", msg->type, msg->dbg));
+   assert(msg->func);
+   (*msg->func)(msg->type, msg->arg);
+   Log(LG_EVENTS, ("EVENT: Parallel processing msg %d to %s done", msg->type, msg->dbg));
+}
+
+void
+ParallelWorkerDied(void *arg, int canceled)
+{
+   struct worker_data * worker = arg;
+   Msg msg;
+   
+   assert(worker);
+   assert(worker->msg);
+   
+   msg = worker->msg;
+
+   if(msg->final) {
+      Log(LG_EVENTS, ("EVENT: Cleanup processing msg %d to %s with %d", msg->type, msg->dbg, canceled));
+      (*msg->final)(msg->type, msg->arg, canceled);
+      Log(LG_EVENTS, ("EVENT: Cleanup processing msg %d to %s with %d done", msg->type, msg->dbg, canceled));
+   } else {
+      Log(LG_EVENTS, ("EVENT: Skipping cleanup processing msg %d to %s with %d", msg->type, msg->dbg, canceled));
+   }
+   
+   ReuseWorker(worker);
+}
+
+void
+ParallelAction(void *arg)
+{
+   struct queue_data * q = arg;
+   
+   while(1) {
+      Msg msg = mesg_port_get(q->port, -1);
+      struct worker_data * worker = mesg_port_get(q->worker_port, -1);
+      
+      assert(msg);
+      assert(worker);
+      assert(worker->queue);
+      
+      REF(msg);
+      worker->msg = msg;
+      
+      if(!msg->canceled) {
+	 if(-1 == paction_start(&(msg->thread), &gGiantMutex,
+				ParallelWorker, ParallelWorkerDied, worker)) {
+	    Perror("%s: paction_start failed with %s\n", __FUNCTION__, strerror(errno));
+	    ReuseWorker(worker);
+	 }
+      } else {
+	 ParallelWorkerDied(worker, 1);
+      }
+      
+      RESETREF(msg, NULL);
+      update_overload();
+   }
+}
+
+void
+ParallelDied(void *arg, int canceled)
+{
+   Perror("%s: Dispatcher %s unexpectedly. Stop processing.",
+	  __FUNCTION__, (canceled ? "was canceled" : "died"));
+}
+
+
 
 /*
  * MsgRegister()
  */
 
 void
-MsgRegister2(MsgHandler *m, void (*func)(int type, void *arg), const char *dbg)
+MsgRegister2(MsgHandler *m, void (*func)(int type, void *arg), void(*final)(int typ, void *arg, int was_canceled), const char *dbg, enum msghandlermodel model)
 {
-    if ((msgpipe[0]==0) || (msgpipe[1]==0)) {
-	if (pipe(msgpipe) < 0) {
-	    Perror("%s: Can't create message pipe", 
-		__FUNCTION__);
-	    DoExit(EX_ERRDEAD);
-	}
-	fcntl(msgpipe[PIPE_READ], F_SETFD, 1);
-	fcntl(msgpipe[PIPE_WRITE], F_SETFD, 1);
-
-	if (fcntl(msgpipe[PIPE_READ], F_SETFL, O_NONBLOCK) < 0)
-    	    Perror("%s: fcntl", __FUNCTION__);
-	if (fcntl(msgpipe[PIPE_WRITE], F_SETFL, O_NONBLOCK) < 0)
-    	    Perror("%s: fcntl", __FUNCTION__);
-
-	if (EventRegister(&msgevent, EVENT_READ,
-		msgpipe[PIPE_READ], EVENT_RECURRING, MsgEvent, NULL) < 0) {
-	    Perror("%s: Can't register event", __FUNCTION__);
-	    DoExit(EX_ERRDEAD);
-        }
-    }
-
+    assert(m);
     m->func = func;
+    m->final = final;
     m->dbg = dbg;
+    m->model = model;
 }
 
 /*
@@ -86,63 +275,73 @@
 void
 MsgUnRegister(MsgHandler *m)
 {
+    assert(m);
     m->func = NULL;
+    m->final = NULL;
     m->dbg = NULL;
+    m->model = -1;
 }
 
 /*
- * MsgEvent()
+ * MsgSend()
  */
 
-static void
-MsgEvent(int type, void *cookie)
+void
+MsgAsyncSend(Msg *mc, MsgHandler *m, int type, void *arg)
 {
-    char	buf[16];
-    /* flush signaling pipe */
-    msgpipesent = 0;
-    while (read(msgpipe[PIPE_READ], buf, sizeof(buf)) == sizeof(buf));
-
-    while (msgqueuet != msgqueueh) {
-	Log(LG_EVENTS, ("EVENT: Message %d to %s received",
-	    msgqueue[msgqueuet].type, msgqueue[msgqueuet].dbg));
-	(*(msgqueue[msgqueuet].func))(msgqueue[msgqueuet].type, msgqueue[msgqueuet].arg);
-	Log(LG_EVENTS, ("EVENT: Message %d to %s processed",
-	    msgqueue[msgqueuet].type, msgqueue[msgqueuet].dbg));
-
-	msgqueuet = (msgqueuet + 1) & MSG_QUEUE_MASK;
-	SETOVERLOAD(QUEUELEN());
-    }
-}
+   Msg msg;
 
-/*
- * MsgSend()
- */
+   assert(m);
+   assert(m->func);
+   assert(m->model >= 0 && m->model <= 1);
+   
+   if(mc != NULL)
+     *mc  = NULL;
+   
+   msg = Malloc(MB_MP, sizeof(*msg));
+   assert(msg);
+   msg->type = type;
+   msg->arg = arg;
+   msg->func = m->func;
+   msg->final = m->final;
+   msg->dbg = m->dbg;
+   REF(msg);			       /* my copy */
+   
+   REF(msg);			       /* send msg */
+   if(-1 == mesg_port_put(queue[m->model].port, msg)) {
+      Perror("%s: mesg_port_put failed with %s",
+	     __FUNCTION__, strerror(errno));
+      UNREF(msg);		       /* msg was not send */
+   } else {
+      Log(LG_EVENTS, ("EVENT: Message %d to %s sent", type, m->dbg));
+      if(mc != NULL) {
+	 REF(msg);		       /* hand out a other copy */
+	 *mc = msg;
+      }
+   }
+   RESETREF(msg, NULL);		       /* destroy my copy */
+}
 
 void
-MsgSend(MsgHandler *m, int type, void *arg)
+MsgAsyncCancel(Msg *mc)
 {
-    assert(m);
-    assert(m->func);
+   assert(mc);
+   if(*mc) {
+      Msg msg = *mc;
+      Log(LG_EVENTS, ("EVENT: Canceling msg %d to %s", msg->type, msg->dbg));
+      msg->canceled = 1;
+      paction_cancel(&(msg->thread));
+   }
+   MsgFree(mc);
+}
 
-    msgqueue[msgqueueh].type = type;
-    msgqueue[msgqueueh].func = m->func;
-    msgqueue[msgqueueh].arg = arg;
-    msgqueue[msgqueueh].dbg = m->dbg;
-
-    msgqueueh = (msgqueueh + 1) & MSG_QUEUE_MASK;
-    if (msgqueuet == msgqueueh) {
-        Log(LG_ERR, ("%s: Fatal message queue overflow!", __FUNCTION__));
-        DoExit(EX_ERRDEAD);
-    }
-
-    SETOVERLOAD(QUEUELEN());
-
-    if (!msgpipesent) {
-	char	buf[1] = { 0x2a };
-	if (write(msgpipe[PIPE_WRITE], buf, 1) > 0)
-	    msgpipesent = 1;
-    }
-    Log(LG_EVENTS, ("EVENT: Message %d to %s sent", type, m->dbg));
+void
+MsgFree(Msg *mc)
+{
+   assert(mc);
+   if(*mc) {
+      RESETREF(*mc, NULL);
+   }
 }
 
 /*
diff -ur mpd-5.6/src/msg.h mpd-5.6-lutz/src/msg.h
--- mpd-5.6/src/msg.h	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/msg.h	2013-02-04 23:17:47.000000000 +0100
@@ -27,20 +27,31 @@
   struct msghandler
   {
     void	(*func)(int type, void *arg);
+    void 	(*final)(int typ, void *arg, int was_canceled);
     const char	*dbg;
+    enum msghandlermodel { MsgSerial = 0, MsgParallel = 1 } model;
   };
-
   typedef struct msghandler	MsgHandler;
 
+  typedef struct mpmsg	*	Msg;
+   
+
 /*
  * FUNCTIONS
  */
 
-#define	MsgRegister(m, func)	\
-	    MsgRegister2(m, func, #func "()")
-  extern void		MsgRegister2(MsgHandler *m, void (*func)(int typ, void *arg), const char *dbg);
+#define	MsgSerialRegister(m, func)	\
+	    MsgRegister2(m, func, NULL, #func "()", MsgSerial)
+#define	MsgParallelRegister(m, func, final)	\
+	    MsgRegister2(m, func, final, #func "()", MsgParallel)
+  extern int		MsgSetup(void);
+  extern void		MsgRegister2(MsgHandler *m, void (*func)(int typ, void *arg), void(*final)(int typ, void *arg, int was_canceled), const char *dbg, enum msghandlermodel model);
   extern void		MsgUnRegister(MsgHandler *m);
-  extern void		MsgSend(MsgHandler *m, int type, void *arg);
+#define MsgSend(m, type, arg)	\
+   	    MsgAsyncSend(NULL, m, type, arg);
+  extern void		MsgAsyncSend(Msg *mc, MsgHandler *m, int type, void *arg);
+  extern void		MsgAsyncCancel(Msg *mc);
+  extern void		MsgFree(Msg *mc);
   extern const char	*MsgName(int msg);
 
 #endif
diff -ur mpd-5.6/src/ng.c mpd-5.6-lutz/src/ng.c
--- mpd-5.6/src/ng.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/ng.c	2013-04-24 12:02:18.000000000 +0200
@@ -111,7 +111,7 @@
     struct ngm_connect	cn;
 
     if (!PhysGetUpperHook(l, path, cn.ourhook)) {
-        Log(LG_PHYS, ("[%s] NG: can't get upper hook", l->name));
+        Log(LG_ERR|LG_PHYS, ("[%s] NG: can't get upper hook", l->name));
 	goto fail;
     }
     
diff -ur mpd-5.6/src/phys.c mpd-5.6-lutz/src/phys.c
--- mpd-5.6/src/phys.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/phys.c	2013-02-04 22:54:06.000000000 +0100
@@ -67,7 +67,7 @@
 int
 PhysInit(Link l)
 {
-    MsgRegister(&l->pmsgs, PhysMsg);
+    MsgSerialRegister(&l->pmsgs, PhysMsg);
 
     /* Initialize type specific stuff */
     if ((l->type->init)(l) < 0) {
@@ -475,7 +475,7 @@
 PhysIsBusy(Link l)
 {
     return (l->die || l->rep || l->state != PHYS_STATE_DOWN ||
-	l->lcp.fsm.state != ST_INITIAL || l->lcp.auth.acct_thread != NULL ||
+	l->lcp.fsm.state != ST_INITIAL || l->lcp.auth.acct_msg != NULL ||
 	(l->tmpl && (l->children >= l->conf.max_children || gChildren >= gMaxChildren)));
 }
 
diff -ur mpd-5.6/src/ppp.h mpd-5.6-lutz/src/ppp.h
--- mpd-5.6/src/ppp.h	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/ppp.h	2013-04-22 00:12:25.000000000 +0200
@@ -46,6 +46,7 @@
 #include "contrib/libpdel/util/pevent.h"
 #include "contrib/libpdel/util/paction.h"
 #include "contrib/libpdel/util/ghash.h"
+#include "contrib/libpdel/util/mesg_port.h"
 #else
 #include <pdel/structs/structs.h>
 #include <pdel/structs/type/array.h>
@@ -53,6 +54,7 @@
 #include <pdel/util/pevent.h>
 #include <pdel/util/paction.h>
 #include <pdel/util/ghash.h>
+#include <pdel/util/mesg_port.h>
 #endif
 
 #include <netgraph/ng_message.h>
@@ -193,6 +195,7 @@
   extern int		gBackground;
   extern int		gShutdownInProgress;
   extern int		gOverload;
+  extern int		gQueueDelay;
   extern pid_t		gPid;
   extern int		gRouteSeq;
 
@@ -215,6 +218,7 @@
 
   extern struct pevent_ctx	*gPeventCtx;
   extern pthread_mutex_t	gGiantMutex;	/* Giant Mutex */
+  extern pthread_mutex_t	gNgMutex;	/* NetGraph Mutex */
 
   extern const char	*gVersion;		/* Program version string */
   extern const char	*gConfigFile;		/* Main config file */
diff -ur mpd-5.6/src/pppoe.c mpd-5.6-lutz/src/pppoe.c
--- mpd-5.6/src/pppoe.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/pppoe.c	2013-04-24 11:58:30.000000000 +0200
@@ -257,6 +257,7 @@
 	snprintf(session_hook, sizeof(session_hook), "mpd%d-%d", 
 	    gPid, l->id);
 	
+   	MUTEX_LOCK(gNgMutex);
 	if (pe->incoming == 1) {
 		Log(LG_PHYS2, ("[%s] PppoeOpen() on incoming call", l->name));
 
@@ -267,10 +268,12 @@
 		/* Connect ng_tee(4) node to the ng_ppp(4) node. */
 		memset(&cn, 0, sizeof(cn));
 		if (!PhysGetUpperHook(l, cn.path, cn.peerhook)) {
-		    Log(LG_PHYS, ("[%s] PPPoE: can't get upper hook", l->name));
+		    Log(LG_ERR|LG_PHYS, ("[%s] PPPoE: can't get upper hook", l->name));
 		    goto fail3;
 		}
 		snprintf(cn.ourhook, sizeof(cn.ourhook), "right");
+	   
+	   
 		if (NgSendMsg(pe->PIf->csock, path, NGM_GENERIC_COOKIE, NGM_CONNECT, 
 		    &cn, sizeof(cn)) < 0) {
 			Perror("[%s] PPPoE: can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\"",
@@ -289,12 +292,14 @@
 		    l->state = PHYS_STATE_UP;
 		    PhysUp(l);
 		}
+	   	MUTEX_UNLOCK(gNgMutex);
 		return;
 	}
 
+   	MUTEX_UNLOCK(gNgMutex);
 	/* Sanity check. */
 	if (l->state != PHYS_STATE_DOWN) {
-		Log(LG_PHYS, ("[%s] PPPoE allready active", l->name));
+		Log(LG_ERR|LG_PHYS, ("[%s] PPPoE allready active", l->name));
 		return;
 	};
 
@@ -307,12 +312,13 @@
 	    goto fail;
 	}
 
+   	MUTEX_LOCK(gNgMutex);
 	/* Connect our ng_ppp(4) node link hook to the ng_pppoe(4) node. */
 	strlcpy(cn.ourhook, session_hook, sizeof(cn.ourhook));
 	snprintf(path, sizeof(path), "[%x]:", pe->PIf->node_id);
 
 	if (!PhysGetUpperHook(l, cn.path, cn.peerhook)) {
-	    Log(LG_PHYS, ("[%s] PPPoE: can't get upper hook", l->name));
+	    Log(LG_ERR|LG_PHYS, ("[%s] PPPoE: can't get upper hook", l->name));
 	    goto fail2;
 	}
 	
@@ -346,12 +352,14 @@
 	strlcpy(pe->real_session, pe->session, sizeof(pe->real_session));
 	pe->agent_cid[0] = 0;
 	pe->agent_rid[0] = 0;
+   	MUTEX_UNLOCK(gNgMutex);
 	return;
 
 fail3:
 	snprintf(path, sizeof(path), "[%x]:", pe->PIf->node_id);
 fail2:
 	NgFuncDisconnect(pe->PIf->csock, l->name, path, session_hook);
+   	MUTEX_UNLOCK(gNgMutex);
 fail:	
 	PhysDown(l, STR_ERROR, NULL);
 	return;
@@ -416,6 +424,7 @@
 	if (l->state == PHYS_STATE_DOWN)
 		return;
 
+   	MUTEX_LOCK(gNgMutex);
 	snprintf(path, sizeof(path), "[%x]:", pi->PIf->node_id);
 	snprintf(session_hook, sizeof(session_hook), "mpd%d-%d",
 	    gPid, l->id);
@@ -428,6 +437,7 @@
 	pi->real_session[0] = 0;
 	pi->agent_cid[0] = 0;
 	pi->agent_rid[0] = 0;
+   	MUTEX_UNLOCK(gNgMutex);
 }
 
 /*
@@ -448,11 +458,15 @@
 	
 	struct PppoeIf  *PIf = (struct PppoeIf*)arg;
 	
+   	MUTEX_LOCK(gNgMutex);
 	/* Read control message. */
 	if (NgRecvMsg(PIf->csock, &u.resp, sizeof(u), path) < 0) {
 		Perror("PPPoE: error reading message from \"%s\"", path);
+	   	MUTEX_UNLOCK(gNgMutex);
 		return;
 	}
+   	MUTEX_UNLOCK(gNgMutex);
+
 	if (u.resp.header.typecookie != NGM_PPPOE_COOKIE) {
 		Log(LG_ERR, ("PPPoE: rec'd cookie %lu from \"%s\"",
 		    (u_long)u.resp.header.typecookie, path));
@@ -683,9 +697,11 @@
 		return (0);
 	}
 
+   	MUTEX_LOCK(gNgMutex);
 	/* Create a new netgraph node */
 	if (NgMkSockNode(NULL, &PIf->csock, &PIf->dsock) < 0) {
 		Perror("[%s] PPPoE: can't create ctrl socket", iface);
+	   	MUTEX_UNLOCK(gNgMutex);
 		return(0);
 	}
 	(void)fcntl(PIf->csock, F_SETFD, 1);
@@ -702,6 +718,7 @@
 			    iface);
 			close(PIf->csock);
 			close(PIf->dsock);
+		   	MUTEX_UNLOCK(gNgMutex);
 			return (0);
 		}
 
@@ -712,6 +729,7 @@
 			    iface);
 			close(PIf->csock);
 			close(PIf->dsock);
+		   	MUTEX_UNLOCK(gNgMutex);
 			return (0);
 		}
 
@@ -728,6 +746,7 @@
 			Perror("PPPoE: Cannot load ng_ether");
 			close(PIf->csock);
 			close(PIf->dsock);
+		   	MUTEX_UNLOCK(gNgMutex);
 			assert (0);
 		}
 		gNgEtherLoaded = TRUE;
@@ -743,6 +762,7 @@
 		Perror("[%s] Cannot send a netgraph message: %s", iface, path);
 		close(PIf->csock);
 		close(PIf->dsock);
+	   	MUTEX_UNLOCK(gNgMutex);
 		return (0);
 	}
 
@@ -752,6 +772,7 @@
 		Perror("[%s] Cannot get netgraph response", iface);
 		close(PIf->csock);
 		close(PIf->dsock);
+	   	MUTEX_UNLOCK(gNgMutex);
 		return (0);
 	}
 
@@ -766,6 +787,7 @@
 		    iface, ninfo->type, path));
 		close(PIf->csock);
 		close(PIf->dsock);
+	   	MUTEX_UNLOCK(gNgMutex);
 		return (0);
 	}
 
@@ -789,6 +811,7 @@
 			    path, nlink->nodeinfo.type));
 			close(PIf->csock);
 			close(PIf->dsock);
+		   	MUTEX_UNLOCK(gNgMutex);
 			return (0);
 		}
 		PIf->node_id = nlink->nodeinfo.id;
@@ -810,6 +833,7 @@
 			    iface, NG_PPPOE_NODE_TYPE, path, hook);
 			close(PIf->csock);
 			close(PIf->dsock);
+		   	MUTEX_UNLOCK(gNgMutex);
 			return (0);
 		}
 
@@ -819,10 +843,12 @@
 			Perror("[%s] Cannot get pppoe node id", iface);
 			close(PIf->csock);
 			close(PIf->dsock);
+		   	MUTEX_UNLOCK(gNgMutex);
 			return (0);
 		};
 	};
 
+   	MUTEX_UNLOCK(gNgMutex);
 	/* Register an event listening to the control and data sockets. */
 	EventRegister(&(PIf->ctrlEvent), EVENT_READ, PIf->csock,
 	    EVENT_RECURRING, PppoeCtrlReadEvent, PIf);
@@ -922,14 +948,18 @@
 	} u;
 	struct ngpppoe_init_data *const idata = &u.poeid;
 
+   	MUTEX_LOCK(gNgMutex);
 	switch (sz = NgRecvData(PIf->dsock, response, sizeof(response), rhook)) {
           case -1:
 	    Log(LG_ERR, ("NgRecvData: %d", sz));
+	    MUTEX_UNLOCK(gNgMutex);
             return;
           case 0:
             Log(LG_ERR, ("NgRecvData: socket closed"));
+	    MUTEX_UNLOCK(gNgMutex);
             return;
         }
+   	MUTEX_UNLOCK(gNgMutex);
 
 	if (strncmp(rhook, "listen-", 7)) {
 		Log(LG_ERR, ("PPPoE: data from unknown hook \"%s\"", rhook));
@@ -1015,12 +1045,13 @@
 	    l = LinkInst(l, NULL, 0, 0);
 
 	if (l == NULL) {
-		Log(LG_PHYS, ("No free PPPoE link with requested parameters "
+		Log(LG_ERR|LG_PHYS, ("No free PPPoE link with requested parameters "
 		    "was found"));
 		return;
 	}
 	pi = (PppoeInfo)l->info;
 	
+   	MUTEX_LOCK(gNgMutex);
 	Log(LG_PHYS, ("[%s] Accepting PPPoE connection", l->name));
 
 	/* Path to the ng_pppoe */
@@ -1113,6 +1144,7 @@
 
 	Log(LG_PHYS2, ("[%s] PPPoE response sent", l->name));
 
+   	MUTEX_UNLOCK(gNgMutex);
 	/* Set a timer to limit connection time. */
 	TimerInit(&pi->connectTimer, "PPPoE-connect",
 	    PPPOE_CONNECT_TIMEOUT * SECONDS, PppoeConnectTimeout, l);
@@ -1127,6 +1159,7 @@
 	};
 
 close_socket:
+   	MUTEX_UNLOCK(gNgMutex);
 	Log(LG_PHYS, ("[%s] PPPoE connection not accepted due to error",
 	    l->name));
 
@@ -1247,6 +1280,7 @@
 
 	snprintf(path, sizeof(path), "[%x]:", PIf->node_id);
 	
+   	MUTEX_LOCK(gNgMutex);
 	/* Connect our socket node link hook to the ng_pppoe(4) node. */
 	memset(&cn, 0, sizeof(cn));
 	strcpy(cn.path, path);
@@ -1258,6 +1292,7 @@
 		Log(LG_ERR, ("PPPoE: Can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\": %s",
 		    ".:", cn.ourhook, cn.path, cn.peerhook,
 		    strerror(errno)));
+	   	MUTEX_UNLOCK(gNgMutex);
 		return(0);
 	}
 
@@ -1271,12 +1306,14 @@
 	    idata, sizeof(*idata) + idata->data_len) < 0) {
 		Perror("PPPoE: Can't send NGM_PPPOE_LISTEN to %s hook %s",
 		     path, idata->hook);
+	   	MUTEX_UNLOCK(gNgMutex);
 		return (0);
 	}
 
 	Log(LG_PHYS, ("PPPoE: waiting for connection on %s, service \"%s\"",
 		PIf->ifnodepath, idata->data));
 	    
+   	MUTEX_UNLOCK(gNgMutex);
 	return (1);
 }
 
@@ -1291,6 +1328,7 @@
 	if (!pi->list)
 	    return(1);	/* Do this only once */
 
+   	MUTEX_LOCK(gNgMutex);
 	pi->list->refs--;
 	
 	if (pi->list->refs == 0) {
@@ -1307,6 +1345,7 @@
 	}
 	    
 	pi->list = NULL;
+   	MUTEX_UNLOCK(gNgMutex);
 	return (1);
 }
 
diff -ur mpd-5.6/src/pptp.c mpd-5.6-lutz/src/pptp.c
--- mpd-5.6/src/pptp.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/pptp.c	2013-04-24 11:55:57.000000000 +0200
@@ -294,7 +294,7 @@
     switch (l->state) {
 	case PHYS_STATE_DOWN:
     	    if (PptpOriginate(l) < 0) {
-		Log(LG_PHYS, ("[%s] PPTP call failed", l->name));
+		Log(LG_ERR|LG_PHYS, ("[%s] PPTP call failed", l->name));
 		PhysDown(l, STR_ERROR, NULL);
 		return;
     	    }
@@ -450,8 +450,10 @@
 	if (pptp->tun == NULL)
 		return;
 
+   	MUTEX_LOCK(gNgMutex);
 	/* Get a temporary netgraph socket node */
 	if (NgMkSockNode(NULL, &csock, NULL) == -1) {
+	   	MUTEX_UNLOCK(gNgMutex);
 		Perror("PPTP: NgMkSockNode");
 		return;
 	}
@@ -472,6 +474,7 @@
 	}
 	
 	close(csock);
+   	MUTEX_UNLOCK(gNgMutex);
 	
 	pptp->tun = NULL;
 }
@@ -838,13 +841,15 @@
     u_addrtosockaddr(&u_peer_addr, 0, &peer_addr);
 
     if (!PhysGetUpperHook(l, path, hook)) {
-        Log(LG_PHYS, ("[%s] PPTP: can't get upper hook", l->name));
+        Log(LG_ERR|LG_PHYS, ("[%s] PPTP: can't get upper hook", l->name));
         return(-1);
     }
     
+    MUTEX_LOCK(gNgMutex);
     /* Get a temporary netgraph socket node */
     if (NgMkSockNode(NULL, &csock, NULL) == -1) {
 	Perror("PPTP: NgMkSockNode");
+   	MUTEX_UNLOCK(gNgMutex);
 	return(-1);
     }
 
@@ -866,6 +871,7 @@
 	    Perror("[%s] PPTP: ghash_put", l->name);
 	    Freee(tun);
 	    close(csock);
+	    MUTEX_UNLOCK(gNgMutex);
 	    return(-1);
 	}
     
@@ -883,6 +889,7 @@
 	    ghash_remove(gPptpTuns, tun);
 	    Freee(tun);
 	    close(csock);
+	    MUTEX_UNLOCK(gNgMutex);
 	    return(-1);
 	}
 
@@ -892,6 +899,7 @@
 	    ghash_remove(gPptpTuns, tun);
 	    Freee(tun);
 	    close(csock);
+	    MUTEX_UNLOCK(gNgMutex);
 	    return(-1);
 	};
 	tun->refs++;
@@ -910,6 +918,7 @@
 	  NGM_MKPEER, &mkp, sizeof(mkp)) < 0) {
 	    Perror("[%s] PPTP: can't attach %s node", l->name, NG_KSOCKET_NODE_TYPE);
 	    close(csock);
+	    MUTEX_UNLOCK(gNgMutex);
 	    return(-1);
 	}
 	snprintf(ksockpath, sizeof(ksockpath),
@@ -930,6 +939,7 @@
           NGM_KSOCKET_BIND, &self_addr, self_addr.ss_len) < 0) {
 	    Perror("[%s] PPTP: can't bind() %s node", l->name, NG_KSOCKET_NODE_TYPE);
 	    close(csock);
+	    MUTEX_UNLOCK(gNgMutex);
 	    return(-1);
 	}
 
@@ -940,6 +950,7 @@
 	    Perror("[%s] PPTP: can't connect() %s node",
     	        l->name, NG_KSOCKET_NODE_TYPE);
 	    close(csock);
+	    MUTEX_UNLOCK(gNgMutex);
     	    return(-1);
         }
 #ifdef	NG_PPTPGRE_HOOK_SESSION_F
@@ -953,6 +964,7 @@
 	    Perror("[%s] PPTP: can't connect to %s node",
     		l->name, NG_PPTPGRE_NODE_TYPE);
 	    close(csock);
+	    MUTEX_UNLOCK(gNgMutex);
 	    return(-1);
 	}
 	tun->refs++;
@@ -972,10 +984,12 @@
       NGM_PPTPGRE_SET_CONFIG, &gc, sizeof(gc)) < 0) {
 	Perror("[%s] PPTP: can't config %s node", l->name, NG_PPTPGRE_NODE_TYPE);
 	close(csock);
+   	MUTEX_UNLOCK(gNgMutex);
 	return(-1);
     }
   
     close(csock);
+    MUTEX_UNLOCK(gNgMutex);
 
     return(0);
 }
@@ -1087,7 +1101,7 @@
 
     /* If no link is suitable, can't take the call */
     if (l == NULL) {
-	Log(LG_PHYS, ("No free PPTP link with requested parameters "
+	Log(LG_ERR|LG_PHYS, ("No free PPTP link with requested parameters "
 	    "was found"));
 	return(linfo);
     }
diff -ur mpd-5.6/src/pptp_ctrl.c mpd-5.6-lutz/src/pptp_ctrl.c
--- mpd-5.6/src/pptp_ctrl.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/pptp_ctrl.c	2013-04-24 11:54:34.000000000 +0200
@@ -695,7 +695,7 @@
   /* Find/create control block */
   if ((c = PptpCtrlGetCtrl(TRUE, locip, ip, port,
       ebuf, sizeof(ebuf))) == NULL) {
-    Log(LG_PHYS2, ("%s", ebuf));
+    Log(LG_ERR|LG_PHYS2, ("%s", ebuf));
     return;
   }
 
@@ -826,7 +826,7 @@
     /* Initialize a new control block */
     if ((c = PptpCtrlGetCtrl(FALSE, &self_addr, &peer_addr, peer_port,
     	    ebuf, sizeof(ebuf))) == NULL) {
-	Log(LG_PHYS2, ("PPTP: Control connection failed: %s", ebuf));
+	Log(LG_ERR|LG_PHYS2, ("PPTP: Control connection failed: %s", ebuf));
 	close(sock);
 	return;
     }
@@ -856,7 +856,7 @@
 
   /* Check whether the connection was successful or not */
   if (getpeername(c->csock, (struct sockaddr *) &addr, &addrLen) < 0) {
-    Log(LG_PHYS2, ("pptp%d: connection to %s %d failed",
+    Log(LG_ERR|LG_PHYS2, ("pptp%d: connection to %s %d failed",
       c->id, u_addrtoa(&c->peer_addr,buf,sizeof(buf)), c->peer_port));
     PptpCtrlKillCtrl(c);
     return;
@@ -901,7 +901,7 @@
   /* Get local IP address */
   addrLen = sizeof(self);
   if (getsockname(c->csock, (struct sockaddr *) &self, &addrLen) < 0) {
-    Log(LG_PHYS2, ("pptp%d: %s: %s", c->id, "getsockname", strerror(errno)));
+    Log(LG_ERR|LG_PHYS2, ("pptp%d: %s: %s", c->id, "getsockname", strerror(errno)));
 abort:
     PptpCtrlKillCtrl(c);
     return;
@@ -911,7 +911,7 @@
   /* Get remote IP address */
   addrLen = sizeof(peer);
   if (getpeername(c->csock, (struct sockaddr *) &peer, &addrLen) < 0) {
-    Log(LG_PHYS2, ("pptp%d: %s: %s", c->id, "getpeername", strerror(errno)));
+    Log(LG_ERR|LG_PHYS2, ("pptp%d: %s: %s", c->id, "getpeername", strerror(errno)));
     goto abort;
   }
   sockaddrtou_addr(&peer, &c->peer_addr, &c->peer_port);
@@ -923,7 +923,7 @@
   /* Turn of Nagle algorithm on the TCP socket, since we are going to
      be writing complete control frames one at a time */
   if (setsockopt(c->csock, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) < 0)
-    Log(LG_PHYS2, ("pptp%d: %s: %s", c->id, "setsockopt", strerror(errno)));
+    Log(LG_ERR|LG_PHYS2, ("pptp%d: %s: %s", c->id, "setsockopt", strerror(errno)));
 
   /* Register for events on control and data sockets */
   EventRegister(&c->ctrlEvent, EVENT_READ,
@@ -971,9 +971,9 @@
     if (nread < 0) {
       if (errno == EAGAIN)
 	return;
-      Log(LG_PHYS2, ("pptp%d: %s: %s", c->id, "read", strerror(errno)));
+      Log(LG_ERR|LG_PHYS2, ("pptp%d: %s: %s", c->id, "read", strerror(errno)));
     } else
-      Log(LG_PHYS2, ("pptp%d: ctrl connection closed by peer", c->id));
+      Log(LG_ERR|LG_PHYS2, ("pptp%d: ctrl connection closed by peer", c->id));
     goto abort;
   }
   LogDumpBuf(LG_FRAME, c->frame.buf + c->flen, nread,
@@ -988,15 +988,15 @@
     Log(LG_FRAME, ("pptp%d: got hdr", c->id));
     PptpCtrlDump(LG_FRAME, 0, hdr);
     if (hdr->msgType != PPTP_CTRL_MSG_TYPE) {
-      Log(LG_PHYS2, ("pptp%d: invalid msg type %d", c->id, hdr->msgType));
+      Log(LG_ERR|LG_PHYS2, ("pptp%d: invalid msg type %d", c->id, hdr->msgType));
       goto abort;
     }
     if (hdr->magic != PPTP_MAGIC) {
-      Log(LG_PHYS2, ("pptp%d: invalid magic %x", c->id, hdr->type));
+      Log(LG_ERR|LG_PHYS2, ("pptp%d: invalid magic %x", c->id, hdr->type));
       goto abort;
     }
     if (!PPTP_VALID_CTRL_TYPE(hdr->type)) {
-      Log(LG_PHYS2, ("pptp%d: invalid ctrl type %d", c->id, hdr->type));
+      Log(LG_ERR|LG_PHYS2, ("pptp%d: invalid ctrl type %d", c->id, hdr->type));
       goto abort;
     }
     if (hdr->resv0 != 0) {
@@ -1006,7 +1006,7 @@
 #endif
     }
     if (hdr->length != sizeof(*hdr) + gPptpMsgInfo[hdr->type].length) {
-      Log(LG_PHYS2, ("pptp%d: invalid length %d for type %d",
+      Log(LG_ERR|LG_PHYS2, ("pptp%d: invalid length %d for type %d",
 	c->id, hdr->length, hdr->type));
 abort:
       PptpCtrlKillCtrl(c);
@@ -1082,13 +1082,13 @@
 
   /* Check for invalid message and call or control state combinations */
   if (!ch && ((1 << c->state) & mi->states) == 0) {
-    Log(LG_PHYS2, ("pptp%d: got %s in state %s",
+    Log(LG_ERR|LG_PHYS2, ("pptp%d: got %s in state %s",
       c->id, gPptpMsgInfo[type].name, gPptpCtrlStates[c->state]));
     PptpCtrlKillCtrl(c);
     return;
   }
   if (ch && ((1 << ch->state) & mi->states) == 0) {
-    Log(LG_PHYS2, ("pptp%d-%d: got %s in state %s",
+    Log(LG_ERR|LG_PHYS2, ("pptp%d-%d: got %s in state %s",
       c->id, ch->id, gPptpMsgInfo[type].name, gPptpChanStates[ch->state]));
     PptpCtrlKillCtrl(c);
     return;
@@ -1139,9 +1139,9 @@
   /* Send it; if TCP buffer is full, we abort the connection */
   if ((nwrote = write(c->csock, frame.buf, totlen)) != totlen) {
     if (nwrote < 0)
-      Log(LG_PHYS2, ("pptp%d: %s: %s", c->id, "write", strerror(errno)));
+      Log(LG_ERR|LG_PHYS2, ("pptp%d: %s: %s", c->id, "write", strerror(errno)));
     else
-      Log(LG_PHYS2, ("pptp%d: only wrote %d/%d", c->id, nwrote, totlen));
+      Log(LG_ERR|LG_PHYS2, ("pptp%d: only wrote %d/%d", c->id, nwrote, totlen));
     PptpCtrlKillCtrl(c);
     return -1;
   }
@@ -2020,7 +2020,7 @@
 
     /* Check protocol version */
     if (req->vers != PPTP_PROTO_VERS) {
-	Log(LG_PHYS2, ("pptp%d: incompatible protocol 0x%04x", c->id, req->vers));
+	Log(LG_ERR|LG_PHYS2, ("pptp%d: incompatible protocol 0x%04x", c->id, req->vers));
 	reply.result = PPTP_SCCR_RESL_VERS;
 	if (PptpCtrlWriteMsg(c, PPTP_StartCtrlConnReply, &reply) == -1)
 	    return;
@@ -2045,7 +2045,7 @@
 
     /* Is peer happy? */
     if (rep->result != 0 && rep->result != PPTP_SCCR_RESL_OK) {
-	Log(LG_PHYS2, ("pptp%d: my %s failed, result=%s err=%s",
+	Log(LG_ERR|LG_PHYS2, ("pptp%d: my %s failed, result=%s err=%s",
     	    c->id, gPptpMsgInfo[PPTP_StartCtrlConnRequest].name,
     	    PPTP_SCCR_RESL_CODE(rep->result), PPTP_ERROR_CODE(rep->err)));
 	PptpCtrlKillCtrl(c);
@@ -2056,7 +2056,7 @@
     if (rep->vers != PPTP_PROTO_VERS) {
 	struct pptpStopCtrlConnRequest	req;
 
-	Log(LG_PHYS2, ("pptp%d: incompatible protocol 0x%04x", c->id, rep->vers));
+	Log(LG_ERR|LG_PHYS2, ("pptp%d: incompatible protocol 0x%04x", c->id, rep->vers));
 	memset(&req, 0, sizeof(req));
 	req.reason = PPTP_SCCR_REAS_PROTO;
 	PptpCtrlNewCtrlState(c, PPTP_CTRL_ST_WAIT_STOP_REPLY);
@@ -2124,11 +2124,11 @@
 PptpEchoReply(PptpCtrl c, struct pptpEchoReply *rep)
 {
   if (rep->result != PPTP_ECHO_RESL_OK) {
-    Log(LG_PHYS2, ("pptp%d: echo reply failed: res=%s err=%s",
+    Log(LG_ERR|LG_PHYS2, ("pptp%d: echo reply failed: res=%s err=%s",
       c->id, PPTP_ECHO_RESL_CODE(rep->result), PPTP_ERROR_CODE(rep->err)));
     PptpCtrlKillCtrl(c);
   } else if (rep->id != c->echoId) {
-    Log(LG_PHYS2, ("pptp%d: bogus echo reply: %u != %u",
+    Log(LG_ERR|LG_PHYS2, ("pptp%d: bogus echo reply: %u != %u",
       c->id, rep->id, c->echoId));
     PptpCtrlKillCtrl(c);
   }
@@ -2162,7 +2162,7 @@
   if ((ch = PptpCtrlGetChan(c, PPTP_CHAN_ST_WAIT_ANSWER, FALSE, FALSE,
       req->bearType, req->frameType, req->minBps, req->maxBps,
       PPTP_STR_INTERNAL_CALLING, calledNum, subAddress)) == NULL) {
-    Log(LG_PHYS2, ("pptp%d: no free channels for outgoing call", c->id));
+    Log(LG_ERR|LG_PHYS2, ("pptp%d: no free channels for outgoing call", c->id));
     goto chFail;
   }
 
@@ -2210,7 +2210,7 @@
       "pptp%d-%d: outgoing call failed: res=%s err=%s",
       c->id, ch->id, PPTP_OCR_RESL_CODE(reply->result),
       PPTP_ERROR_CODE(reply->err));
-    Log(LG_PHYS2, ("%s", errmsg));
+    Log(LG_ERR|LG_PHYS2, ("%s", errmsg));
     (*ch->linfo.result)(ch->linfo.cookie, errmsg, 0);
     PptpCtrlKillChan(ch, "remote outgoing call failed");
     return;
@@ -2266,7 +2266,7 @@
   if ((ch = PptpCtrlGetChan(c, PPTP_CHAN_ST_WAIT_CONNECT, FALSE, TRUE,
       req->bearType, 0, 0, INT_MAX,
       callingNum, calledNum, subAddress)) == NULL) {
-    Log(LG_PHYS2, ("pptp%d: no free channels for incoming call", c->id));
+    Log(LG_ERR|LG_PHYS2, ("pptp%d: no free channels for incoming call", c->id));
     reply.result = PPTP_ICR_RESL_ERR;
     reply.err = PPTP_ERROR_NO_RESOURCE;
     goto done;
@@ -2325,7 +2325,7 @@
       "pptp%d-%d: peer denied incoming call: res=%s err=%s",
       c->id, ch->id, PPTP_ICR_RESL_CODE(reply->result),
       PPTP_ERROR_CODE(reply->err));
-    Log(LG_PHYS2, ("%s", errmsg));
+    Log(LG_ERR|LG_PHYS2, ("%s", errmsg));
     (*ch->linfo.result)(ch->linfo.cookie, errmsg, 0);
     PptpCtrlKillChan(ch, "peer denied incoming call");
     return;
@@ -2369,7 +2369,7 @@
   PptpCtrl			const c = ch->ctrl;
 
   if (PPTP_CHAN_IS_PNS(ch)) {
-    Log(LG_PHYS2, ("pptp%d-%d: got %s, but we are PNS for this call",
+    Log(LG_ERR|LG_PHYS2, ("pptp%d-%d: got %s, but we are PNS for this call",
       c->id, ch->id, gPptpMsgInfo[PPTP_CallClearRequest].name));
     PptpCtrlKillCtrl(c);
     return;
diff -ur mpd-5.6/src/radius.c mpd-5.6-lutz/src/radius.c
--- mpd-5.6/src/radius.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/radius.c	2013-05-03 22:05:22.000000000 +0200
@@ -201,7 +201,7 @@
     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_USER_NAME: %s", 
 	auth->info.lnkname, auth->params.authname));
     if (rad_put_string(auth->radius.handle, RAD_USER_NAME, auth->params.authname) == -1) {
-	Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_USER_NAME failed %s", 
+	Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_USER_NAME failed %s", 
     	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	auth->status = AUTH_STATUS_FAIL;    
 	return;
@@ -217,7 +217,7 @@
 	    auth->info.lnkname, mlen, auth->params.eapmsg_len));
 	memcpy(chunk, &auth->params.eapmsg[pos], mlen);
 	if (rad_put_attr(auth->radius.handle, RAD_EAP_MESSAGE, chunk, mlen) == -1) {
-    	    Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_EAP_MESSAGE failed %s",
+    	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_EAP_MESSAGE failed %s",
 		auth->info.lnkname, rad_strerror(auth->radius.handle)));
     	    auth->status = AUTH_STATUS_FAIL;      
     	    return;
@@ -313,7 +313,7 @@
 	    s->sharedsecret,
 	    c->radius_timeout,
 	    c->radius_retries) == -1) {
-		Log(LG_RADIUS, ("[%s] RADIUS: Adding server error: %s", auth->info.lnkname,
+		Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Adding server error: %s", auth->info.lnkname,
 		    rad_strerror(auth->radius.handle)));
 		return (RAD_NACK);
         }
@@ -325,7 +325,7 @@
 	    s->sharedsecret,
 	    c->radius_timeout,
 	    c->radius_retries) == -1) {
-		Log(LG_RADIUS, ("[%s] RADIUS: Adding server error: %s", auth->info.lnkname, 
+		Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Adding server error: %s", auth->info.lnkname, 
 		    rad_strerror(auth->radius.handle)));
 		return (RAD_NACK);
         }
@@ -469,13 +469,13 @@
     if (request_type == RAD_ACCESS_REQUEST) {
   
 	if ((auth->radius.handle = rad_open()) == NULL) {
-    	    Log(LG_RADIUS, ("[%s] RADIUS: rad_open failed", auth->info.lnkname));
+    	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: rad_open failed", auth->info.lnkname));
     	    return (RAD_NACK);
 	}
     } else { /* RAD_ACCOUNTING_REQUEST */
   
 	if ((auth->radius.handle = rad_acct_open()) == NULL) {
-    	    Log(LG_RADIUS, ("[%s] RADIUS: rad_acct_open failed", auth->info.lnkname));
+    	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: rad_acct_open failed", auth->info.lnkname));
     	    return (RAD_NACK);
 	}
     }
@@ -483,7 +483,7 @@
     if (conf->file && strlen(conf->file)) {
 	Log(LG_RADIUS2, ("[%s] RADIUS: using %s", auth->info.lnkname, conf->file));
 	if (rad_config(auth->radius.handle, conf->file) != 0) {
-    	    Log(LG_RADIUS, ("[%s] RADIUS: rad_config: %s", auth->info.lnkname, 
+    	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: rad_config: %s", auth->info.lnkname, 
     		rad_strerror(auth->radius.handle)));
     	    return (RAD_NACK);
 	}
@@ -508,7 +508,7 @@
     return RAD_NACK;
 
   if (rad_create_request(auth->radius.handle, request_type) == -1) {
-    Log(LG_RADIUS, ("[%s] RADIUS: rad_create_request: %s", 
+    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: rad_create_request: %s", 
       auth->info.lnkname, rad_strerror(auth->radius.handle)));
     return (RAD_NACK);
   }
@@ -517,7 +517,7 @@
 	tmpval = conf->identifier;
     } else {
 	if (gethostname(host, sizeof(host)) == -1) {
-	    Log(LG_RADIUS, ("[%s] RADIUS: gethostname() for RAD_NAS_IDENTIFIER failed", 
+	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: gethostname() for RAD_NAS_IDENTIFIER failed", 
     		auth->info.lnkname));
 	    return (RAD_NACK);
 	}
@@ -526,7 +526,7 @@
     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_NAS_IDENTIFIER: %s", 
 	auth->info.lnkname, tmpval));
     if (rad_put_string(auth->radius.handle, RAD_NAS_IDENTIFIER, tmpval) == -1)  {
-	Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_NAS_IDENTIFIER failed %s", auth->info.lnkname,
+	Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_NAS_IDENTIFIER failed %s", auth->info.lnkname,
     	    rad_strerror(auth->radius.handle)));
 	return (RAD_NACK);
     }
@@ -535,7 +535,7 @@
     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_NAS_IP_ADDRESS: %s", 
       auth->info.lnkname, inet_ntoa(conf->radius_me)));
     if (rad_put_addr(auth->radius.handle, RAD_NAS_IP_ADDRESS, conf->radius_me) == -1) {
-      Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_NAS_IP_ADDRESS failed %s", 
+      Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_NAS_IP_ADDRESS failed %s", 
 	auth->info.lnkname, rad_strerror(auth->radius.handle)));
       return (RAD_NACK);
     }
@@ -545,7 +545,7 @@
     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_NAS_IPV6_ADDRESS: %s", 
       auth->info.lnkname, u_addrtoa(&conf->radius_mev6,buf,sizeof(buf))));
     if (rad_put_attr(auth->radius.handle, RAD_NAS_IPV6_ADDRESS, &conf->radius_mev6.u.ip6, sizeof(conf->radius_mev6.u.ip6)) == -1) {
-      Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_NAS_IPV6_ADDRESS failed %s", 
+      Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_NAS_IPV6_ADDRESS failed %s", 
 	auth->info.lnkname, rad_strerror(auth->radius.handle)));
       return (RAD_NACK);
     }
@@ -559,7 +559,7 @@
 	&& request_type != RAD_ACCOUNTING_REQUEST) {
     Log(LG_RADIUS2, ("[%s] RADIUS: Put Message Authenticator", auth->info.lnkname));
     if (rad_put_message_authentic(auth->radius.handle) == -1) {
-      Log(LG_RADIUS, ("[%s] RADIUS: Put message_authentic failed %s", 
+      Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put message_authentic failed %s", 
         auth->info.lnkname, rad_strerror(auth->radius.handle)));
       return (RAD_NACK);
     }
@@ -568,7 +568,7 @@
     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_SESSION_ID: %s", 
 	auth->info.lnkname, auth->info.session_id));
     if (rad_put_string(auth->radius.handle, RAD_ACCT_SESSION_ID, auth->info.session_id) != 0) {
-	Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_SESSION_ID: %s", 
+	Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_SESSION_ID: %s", 
     	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	return (RAD_NACK);
     }
@@ -576,7 +576,7 @@
     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_NAS_PORT: %d", 
 	auth->info.lnkname, auth->info.linkID));
     if (rad_put_int(auth->radius.handle, RAD_NAS_PORT, auth->info.linkID) == -1)  {
-	Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_NAS_PORT failed %s", 
+	Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_NAS_PORT failed %s", 
     	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	return (RAD_NACK);
     }
@@ -602,7 +602,7 @@
     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_NAS_PORT_TYPE: %d", 
 	auth->info.lnkname, porttype));
     if (rad_put_int(auth->radius.handle, RAD_NAS_PORT_TYPE, porttype) == -1) {
-	Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_NAS_PORT_TYPE failed %s", 
+	Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_NAS_PORT_TYPE failed %s", 
     	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	return (RAD_NACK);
     }
@@ -610,7 +610,7 @@
     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_SERVICE_TYPE: RAD_FRAMED", 
 	auth->info.lnkname));
     if (rad_put_int(auth->radius.handle, RAD_SERVICE_TYPE, RAD_FRAMED) == -1) {
-	Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_SERVICE_TYPE failed %s", 
+	Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_SERVICE_TYPE failed %s", 
     	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	return (RAD_NACK);
     }
@@ -618,7 +618,7 @@
     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_FRAMED_PROTOCOL: RAD_PPP", 
 	auth->info.lnkname));
     if (rad_put_int(auth->radius.handle, RAD_FRAMED_PROTOCOL, RAD_PPP) == -1) {
-	Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_FRAMED_PROTOCOL failed %s", 
+	Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_FRAMED_PROTOCOL failed %s", 
     	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	return (RAD_NACK);
     }
@@ -628,7 +628,7 @@
 	Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_STATE: 0x%s", auth->info.lnkname, tmpval));
 	Freee(tmpval);
 	if (rad_put_attr(auth->radius.handle, RAD_STATE, auth->params.state, auth->params.state_len) == -1) {
-    	    Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_STATE failed %s", 
+    	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_STATE failed %s", 
     		auth->info.lnkname, rad_strerror(auth->radius.handle)));
     	    return (RAD_NACK);
 	}
@@ -639,7 +639,7 @@
 	Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_CLASS: 0x%s", auth->info.lnkname, tmpval));
 	Freee(tmpval);
 	if (rad_put_attr(auth->radius.handle, RAD_CLASS, auth->params.class, auth->params.class_len) == -1) {
-    	    Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_CLASS failed %s", 
+    	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_CLASS failed %s", 
     		auth->info.lnkname, rad_strerror(auth->radius.handle)));
     	    return (RAD_NACK);
 	}
@@ -649,7 +649,7 @@
         auth->info.lnkname, auth->params.callingnum));
     if (rad_put_string(auth->radius.handle, RAD_CALLING_STATION_ID,
     	    auth->params.callingnum) == -1) {
-        Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_CALLING_STATION_ID failed %s",
+        Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_CALLING_STATION_ID failed %s",
     	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
     	return (RAD_NACK);
     }
@@ -657,7 +657,7 @@
 	auth->info.lnkname, auth->params.callednum));
     if (rad_put_string(auth->radius.handle, RAD_CALLED_STATION_ID,
     	    auth->params.callednum) == -1) {
-    	Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_CALLED_STATION_ID failed %s",
+    	Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_CALLED_STATION_ID failed %s",
 	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
     	return (RAD_NACK);
     }
@@ -667,7 +667,7 @@
     	auth->info.lnkname, auth->params.peeriface));
 	if (rad_put_string(auth->radius.handle, RAD_NAS_PORT_ID,
 	        auth->params.peeriface) == -1) {
-	    Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_NAS_PORT_ID failed %s",
+	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_NAS_PORT_ID failed %s",
 		auth->info.lnkname, rad_strerror(auth->radius.handle)));
 		return (RAD_NACK);
 	}
@@ -676,7 +676,7 @@
     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MPD_LINK: %s", 
         auth->info.lnkname, auth->info.lnkname));
     if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_LINK, auth->info.lnkname) != 0) {
-	Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_LINK: %s", auth->info.lnkname,
+	Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_LINK: %s", auth->info.lnkname,
 	    rad_strerror(auth->radius.handle)));
     	return (RAD_NACK);
     }
@@ -685,7 +685,7 @@
 	auth->info.lnkname, auth->info.peer_ident));
     if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD,
       RAD_MPD_PEER_IDENT, auth->info.peer_ident) != 0) {
-	Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_PEER_IDENT failed %s",
+	Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_PEER_IDENT failed %s",
 	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	return (RAD_NACK);
     }
@@ -722,7 +722,7 @@
 	Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_TUNNEL_TYPE: %d", 
 	    auth->info.lnkname, porttype));
 	if (rad_put_int(auth->radius.handle, RAD_TUNNEL_TYPE, porttype) == -1) {
-	    Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_TUNNEL_TYPE failed %s", 
+	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_TUNNEL_TYPE failed %s", 
     		auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	    return (RAD_NACK);
 	}
@@ -741,7 +741,7 @@
 	Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_TUNNEL_MEDIUM_TYPE: %d", 
 	    auth->info.lnkname, porttype));
 	if (rad_put_int(auth->radius.handle, RAD_TUNNEL_MEDIUM_TYPE, porttype) == -1) {
-	    Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_TUNNEL_MEDIUM_TYPE failed %s", 
+	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_TUNNEL_MEDIUM_TYPE failed %s", 
     		auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	    return (RAD_NACK);
 	}
@@ -755,7 +755,7 @@
     		auth->info.lnkname, tmpval));
 	    if (rad_put_string_tag(auth->radius.handle, RAD_TUNNEL_SERVER_ENDPOINT,
     		    0, tmpval) == -1) {
-    		Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_TUNNEL_SERVER_ENDPOINT failed %s",
+    		Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_TUNNEL_SERVER_ENDPOINT failed %s",
     	    	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
     		return (RAD_NACK);
 	    }
@@ -770,7 +770,7 @@
     		auth->info.lnkname, tmpval));
 	    if (rad_put_string_tag(auth->radius.handle, RAD_TUNNEL_CLIENT_ENDPOINT,
     		    0, tmpval) == -1) {
-    		Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_TUNNEL_CLIENT_ENDPOINT failed %s",
+    		Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_TUNNEL_CLIENT_ENDPOINT failed %s",
     	    	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
     		return (RAD_NACK);
 	    }
@@ -785,7 +785,7 @@
     		auth->info.lnkname, tmpval));
 	    if (rad_put_string_tag(auth->radius.handle, RAD_TUNNEL_SERVER_AUTH_ID,
     		    0, tmpval) == -1) {
-    		Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_TUNNEL_SERVER_AUTH_ID failed %s",
+    		Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_TUNNEL_SERVER_AUTH_ID failed %s",
     	    	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
     		return (RAD_NACK);
 	    }
@@ -800,7 +800,7 @@
     		auth->info.lnkname, tmpval));
 	    if (rad_put_string_tag(auth->radius.handle, RAD_TUNNEL_CLIENT_AUTH_ID,
     		    0, tmpval) == -1) {
-    		Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_TUNNEL_CLIENT_AUTH_ID failed %s",
+    		Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_TUNNEL_CLIENT_AUTH_ID failed %s",
     	    	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
     		return (RAD_NACK);
 	    }
@@ -813,7 +813,7 @@
     		auth->info.lnkname, auth->params.selfname));
 	    if (rad_put_vendor_string(auth->radius.handle, 3561, 1,
     		    auth->params.selfname) == -1) {
-    		Log(LG_RADIUS, ("[%s] RADIUS: Put ADSL-Agent-Circuit-Id failed %s",
+    		Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put ADSL-Agent-Circuit-Id failed %s",
     	    	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
     		return (RAD_NACK);
 	    }
@@ -823,7 +823,7 @@
     		auth->info.lnkname, auth->params.peername));
 	    if (rad_put_vendor_string(auth->radius.handle, 3561, 2,
     		    auth->params.peername) == -1) {
-    		Log(LG_RADIUS, ("[%s] RADIUS: Put ADSL-Agent-Remote-Id failed %s",
+    		Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put ADSL-Agent-Remote-Id failed %s",
     	    	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
     		return (RAD_NACK);
 	    }
@@ -849,7 +849,7 @@
   Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_USER_NAME: %s", 
     auth->info.lnkname, auth->params.authname));
   if (rad_put_string(auth->radius.handle, RAD_USER_NAME, auth->params.authname) == -1) {
-    Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_USER_NAME failed %s", 
+    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_USER_NAME failed %s", 
       auth->info.lnkname, rad_strerror(auth->radius.handle)));
     return (RAD_NACK);
   }
@@ -859,7 +859,7 @@
 
       case CHAP_ALG_MSOFT:
 	if (cp->value_len != 49) {
-	  Log(LG_RADIUS, ("[%s] RADIUS: RADIUS_CHAP (MSOFTv1) unrecognised key length %d/%d",
+	  Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: RADIUS_CHAP (MSOFTv1) unrecognised key length %d/%d",
 	    auth->info.lnkname, cp->value_len, 49));
 	  return (RAD_NACK);
 	}
@@ -868,7 +868,7 @@
 	  auth->info.lnkname));
 	if (rad_put_vendor_attr(auth->radius.handle, RAD_VENDOR_MICROSOFT, RAD_MICROSOFT_MS_CHAP_CHALLENGE,
 	    cp->chal_data, cp->chal_len) == -1)  {
-	  Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MICROSOFT_MS_CHAP_CHALLENGE failed %s",
+	  Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_MICROSOFT_MS_CHAP_CHALLENGE failed %s",
 	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	  return (RAD_NACK);
 	}
@@ -883,7 +883,7 @@
 	  auth->info.lnkname));
 	if (rad_put_vendor_attr(auth->radius.handle, RAD_VENDOR_MICROSOFT, RAD_MICROSOFT_MS_CHAP_RESPONSE,
 	    &rad_mschapval, sizeof(rad_mschapval)) == -1)  {
-	  Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MICROSOFT_MS_CHAP_RESPONSE failed %s",
+	  Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_MICROSOFT_MS_CHAP_RESPONSE failed %s",
 	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	  return (RAD_NACK);
 	}
@@ -900,7 +900,7 @@
 	  auth->info.lnkname));
 	if (rad_put_vendor_attr(auth->radius.handle, RAD_VENDOR_MICROSOFT,
 	    RAD_MICROSOFT_MS_CHAP_CHALLENGE, cp->chal_data, cp->chal_len) == -1) {
-	  Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MICROSOFT_MS_CHAP_CHALLENGE failed %s",
+	  Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_MICROSOFT_MS_CHAP_CHALLENGE failed %s",
 	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	  return (RAD_NACK);
 	}
@@ -919,7 +919,7 @@
 	  auth->info.lnkname));
 	if (rad_put_vendor_attr(auth->radius.handle, RAD_VENDOR_MICROSOFT, RAD_MICROSOFT_MS_CHAP2_RESPONSE,
 	    &rad_mschapv2val, sizeof(rad_mschapv2val)) == -1)  {
-	  Log(LG_RADIUS, ("[%s] RADIUS: Put vendor_attr(RAD_MICROSOFT_MS_CHAP2_RESPONSE failed %s",
+	  Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put vendor_attr(RAD_MICROSOFT_MS_CHAP2_RESPONSE failed %s",
 	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	  return (RAD_NACK);
 	}
@@ -932,14 +932,14 @@
 	Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_CHAP_CHALLENGE",
 	  auth->info.lnkname));
 	if (rad_put_attr(auth->radius.handle, RAD_CHAP_CHALLENGE, cp->chal_data, cp->chal_len) == -1) {
-	  Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_CHAP_CHALLENGE failed %s",
+	  Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_CHAP_CHALLENGE failed %s",
 	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	  return (RAD_NACK);
 	}
 	Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_CHAP_PASSWORD",
 	  auth->info.lnkname));
 	if (rad_put_attr(auth->radius.handle, RAD_CHAP_PASSWORD, &rad_chapval, cp->value_len + 1) == -1) {
-	  Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_CHAP_PASSWORD failed %s",
+	  Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_CHAP_PASSWORD failed %s",
 	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	  return (RAD_NACK);
 	}
@@ -955,7 +955,7 @@
     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_USER_PASSWORD",
       auth->info.lnkname));
     if (rad_put_string(auth->radius.handle, RAD_USER_PASSWORD, pp->peer_pass) == -1) {
-      Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_USER_PASSWORD failed %s", 
+      Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_USER_PASSWORD failed %s", 
 	auth->info.lnkname, rad_strerror(auth->radius.handle)));
       return (RAD_NACK);
     }
@@ -980,7 +980,7 @@
 	Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_STATUS_TYPE: RAD_START", 
     	    auth->info.lnkname));
 	if (rad_put_int(auth->radius.handle, RAD_ACCT_STATUS_TYPE, RAD_START)) {
-    	    Log(LG_RADIUS, ("[%s] RADIUS: Put STATUS_TYPE: %s", 
+    	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put STATUS_TYPE: %s", 
 		auth->info.lnkname, rad_strerror(auth->radius.handle)));
     	    return (RAD_NACK);
 	}
@@ -989,7 +989,7 @@
     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_FRAMED_IP_ADDRESS: %s", 
 	auth->info.lnkname, inet_ntoa(auth->info.peer_addr)));
     if (rad_put_addr(auth->radius.handle, RAD_FRAMED_IP_ADDRESS, auth->info.peer_addr)) {
-	Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_FRAMED_IP_ADDRESS: %s", 
+	Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_FRAMED_IP_ADDRESS: %s", 
     	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	return (RAD_NACK);
     }
@@ -1000,7 +1000,7 @@
 	Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_FRAMED_IP_NETMASK: %s", 
 	    auth->info.lnkname, inet_ntoa(ip)));
 	if (rad_put_addr(auth->radius.handle, RAD_FRAMED_IP_NETMASK, ip)) {
-	    Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_FRAMED_IP_NETMASK: %s", 
+	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_FRAMED_IP_NETMASK: %s", 
     		auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	    return (RAD_NACK);
 	}
@@ -1010,7 +1010,7 @@
     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_USER_NAME: %s", 
 	auth->info.lnkname, username));
     if (rad_put_string(auth->radius.handle, RAD_USER_NAME, username) != 0) {
-	Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_USER_NAME: %s", 
+	Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_USER_NAME: %s", 
     	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	return (RAD_NACK);
     }
@@ -1018,7 +1018,7 @@
     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_MULTI_SESSION_ID: %s", 
 	auth->info.lnkname, auth->info.msession_id));
     if (rad_put_string(auth->radius.handle, RAD_ACCT_MULTI_SESSION_ID, auth->info.msession_id) != 0) {
-	Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_MULTI_SESSION_ID: %s", 
+	Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_MULTI_SESSION_ID: %s", 
     	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	return (RAD_NACK);
     }
@@ -1026,7 +1026,7 @@
     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MPD_BUNDLE: %s", 
         auth->info.lnkname, auth->info.bundname));
     if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_BUNDLE, auth->info.bundname) != 0) {
-	Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_BUNDLE: %s", auth->info.lnkname,
+	Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_BUNDLE: %s", auth->info.lnkname,
 	    rad_strerror(auth->radius.handle)));
 	return (RAD_NACK);
     }
@@ -1034,7 +1034,7 @@
     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MPD_IFACE: %s", 
         auth->info.lnkname, auth->info.ifname));
     if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_IFACE, auth->info.ifname) != 0) {
-	Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_IFACE: %s", auth->info.lnkname,
+	Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_IFACE: %s", auth->info.lnkname,
 	    rad_strerror(auth->radius.handle)));
 	return (RAD_NACK);
     }
@@ -1042,7 +1042,7 @@
     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MPD_IFACE_INDEX: %u", 
         auth->info.lnkname, auth->info.ifindex));
     if (rad_put_vendor_int(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_IFACE_INDEX, auth->info.ifindex) != 0) {
-	Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_IFACE_INDEX: %s", auth->info.lnkname,
+	Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_IFACE_INDEX: %s", auth->info.lnkname,
 	    rad_strerror(auth->radius.handle)));
 	return (RAD_NACK);
     }
@@ -1050,7 +1050,7 @@
     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MPD_PEER_IDENT: %s",
 	auth->info.lnkname, auth->info.peer_ident));
     if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_PEER_IDENT, auth->info.peer_ident) != 0) {
-	Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_PEER_IDENT failed %s",
+	Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_PEER_IDENT failed %s",
 	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	return (RAD_NACK);
     }
@@ -1058,7 +1058,7 @@
     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_LINK_COUNT: %d", 
 	auth->info.lnkname, auth->info.n_links));
     if (rad_put_int(auth->radius.handle, RAD_ACCT_LINK_COUNT, auth->info.n_links) != 0) {
-	Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_LINK_COUNT failed: %s", 
+	Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_LINK_COUNT failed: %s", 
     	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	return (RAD_NACK);
     }
@@ -1071,7 +1071,7 @@
     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_AUTHENTIC: %d", 
 	auth->info.lnkname, authentic));
     if (rad_put_int(auth->radius.handle, RAD_ACCT_AUTHENTIC, authentic) != 0) {
-	Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_AUTHENTIC failed: %s",
+	Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_AUTHENTIC failed: %s",
     	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	return (RAD_NACK);
     }
@@ -1088,49 +1088,57 @@
         Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_STATUS_TYPE: RAD_STOP", 
 	    auth->info.lnkname));
         if (rad_put_int(auth->radius.handle, RAD_ACCT_STATUS_TYPE, RAD_STOP)) {
-	    Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_STATUS_TYPE: %s", 
+	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_STATUS_TYPE: %s", 
 		auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	    return (RAD_NACK);
         }
-
+       
 	if ((auth->info.downReason == NULL) || (!strcmp(auth->info.downReason, ""))) {
 	  termCause = RAD_TERM_NAS_REQUEST;
-	} else if (!strncmp(auth->info.downReason, STR_MANUALLY, strlen(STR_MANUALLY))) {
-	  termCause = RAD_TERM_ADMIN_RESET;
-	} else if (!strncmp(auth->info.downReason, STR_PEER_DISC, strlen(STR_PEER_DISC))) {
-	  termCause = RAD_TERM_USER_REQUEST;
-	} else if (!strncmp(auth->info.downReason, STR_ADMIN_SHUTDOWN, strlen(STR_ADMIN_SHUTDOWN))) {
-	  termCause = RAD_TERM_ADMIN_REBOOT;
-	} else if (!strncmp(auth->info.downReason, STR_FATAL_SHUTDOWN, strlen(STR_FATAL_SHUTDOWN))) {
-	  termCause = RAD_TERM_NAS_REBOOT;
-	} else if (!strncmp(auth->info.downReason, STR_IDLE_TIMEOUT, strlen(STR_IDLE_TIMEOUT))) {
-	  termCause = RAD_TERM_IDLE_TIMEOUT;
-	} else if (!strncmp(auth->info.downReason, STR_SESSION_TIMEOUT, strlen(STR_SESSION_TIMEOUT))) {
-	  termCause = RAD_TERM_SESSION_TIMEOUT;
-	} else if (!strncmp(auth->info.downReason, STR_DROPPED, strlen(STR_DROPPED))) {
-	  termCause = RAD_TERM_LOST_CARRIER;
-	} else if (!strncmp(auth->info.downReason, STR_ECHO_TIMEOUT, strlen(STR_ECHO_TIMEOUT))) {
-	  termCause = RAD_TERM_LOST_SERVICE;
-	} else if (!strncmp(auth->info.downReason, STR_PROTO_ERR, strlen(STR_PROTO_ERR))) {
-	  termCause = RAD_TERM_SERVICE_UNAVAILABLE;
-	} else if (!strncmp(auth->info.downReason, STR_LOGIN_FAIL, strlen(STR_LOGIN_FAIL))) {
-	  termCause = RAD_TERM_USER_ERROR;
-	} else if (!strncmp(auth->info.downReason, STR_PORT_UNNEEDED, strlen(STR_PORT_UNNEEDED))) {
-	  termCause = RAD_TERM_PORT_UNNEEDED;
-	};
+	} else {
+	   Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MPD_TERM_CAUSE: %s", 
+			    auth->info.lnkname, auth->info.downReason));
+	   if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_TERM_CAUSE, auth->info.downReason) != 0) {
+	      Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_TERM_CAUSE: %s", auth->info.lnkname,
+				     rad_strerror(auth->radius.handle)));
+	   }
+	   if (!strncmp(auth->info.downReason, STR_MANUALLY, strlen(STR_MANUALLY))) {
+	      termCause = RAD_TERM_ADMIN_RESET;
+	   } else if (!strncmp(auth->info.downReason, STR_PEER_DISC, strlen(STR_PEER_DISC))) {
+	      termCause = RAD_TERM_USER_REQUEST;
+	   } else if (!strncmp(auth->info.downReason, STR_ADMIN_SHUTDOWN, strlen(STR_ADMIN_SHUTDOWN))) {
+	      termCause = RAD_TERM_ADMIN_REBOOT;
+	   } else if (!strncmp(auth->info.downReason, STR_FATAL_SHUTDOWN, strlen(STR_FATAL_SHUTDOWN))) {
+	      termCause = RAD_TERM_NAS_REBOOT;
+	   } else if (!strncmp(auth->info.downReason, STR_IDLE_TIMEOUT, strlen(STR_IDLE_TIMEOUT))) {
+	      termCause = RAD_TERM_IDLE_TIMEOUT;
+	   } else if (!strncmp(auth->info.downReason, STR_SESSION_TIMEOUT, strlen(STR_SESSION_TIMEOUT))) {
+	      termCause = RAD_TERM_SESSION_TIMEOUT;
+	   } else if (!strncmp(auth->info.downReason, STR_DROPPED, strlen(STR_DROPPED))) {
+	      termCause = RAD_TERM_LOST_CARRIER;
+	   } else if (!strncmp(auth->info.downReason, STR_ECHO_TIMEOUT, strlen(STR_ECHO_TIMEOUT))) {
+	      termCause = RAD_TERM_LOST_SERVICE;
+	   } else if (!strncmp(auth->info.downReason, STR_PROTO_ERR, strlen(STR_PROTO_ERR))) {
+	      termCause = RAD_TERM_SERVICE_UNAVAILABLE;
+	   } else if (!strncmp(auth->info.downReason, STR_LOGIN_FAIL, strlen(STR_LOGIN_FAIL))) {
+	      termCause = RAD_TERM_USER_ERROR;
+	   } else if (!strncmp(auth->info.downReason, STR_PORT_UNNEEDED, strlen(STR_PORT_UNNEEDED))) {
+	      termCause = RAD_TERM_PORT_UNNEEDED;
+	   }
+	}
+
 	Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_TERMINATE_CAUSE: %s, RADIUS: %d",
 	  auth->info.lnkname, auth->info.downReason, termCause));
-
         if (rad_put_int(auth->radius.handle, RAD_ACCT_TERMINATE_CAUSE, termCause) != 0) {
-	    Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_TERMINATE_CAUSE failed: %s",
+	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_TERMINATE_CAUSE failed: %s",
 		auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	    return (RAD_NACK);
-        } 
+        }
     } else {
         Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_STATUS_TYPE: RAD_UPDATE", 
 	    auth->info.lnkname));
         if (rad_put_int(auth->radius.handle, RAD_ACCT_STATUS_TYPE, RAD_UPDATE)) {
-	    Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_STATUS_TYPE: %s", 
+	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_STATUS_TYPE: %s", 
 		auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	    return (RAD_NACK);
         }
@@ -1139,7 +1147,7 @@
     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_SESSION_TIME: %ld", 
         auth->info.lnkname, (long int)(time(NULL) - auth->info.last_up)));
     if (rad_put_int(auth->radius.handle, RAD_ACCT_SESSION_TIME, time(NULL) - auth->info.last_up) != 0) {
-        Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_SESSION_TIME failed: %s",
+        Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_SESSION_TIME failed: %s",
 	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
         return (RAD_NACK);
     }
@@ -1156,7 +1164,7 @@
 	if (rad_put_int(auth->radius.handle, RAD_ACCT_INPUT_OCTETS, auth->info.stats.recvOctets % MAX_U_INT32) != 0 ||
 	    rad_put_int(auth->radius.handle, RAD_ACCT_INPUT_PACKETS, auth->info.stats.recvFrames) != 0 ||
 	    rad_put_int(auth->radius.handle, RAD_ACCT_INPUT_GIGAWORDS, auth->info.stats.recvOctets / MAX_U_INT32) != 0) {
-    		Log(LG_RADIUS, ("[%s] RADIUS: Put input stats: %s", auth->info.lnkname,
+    		Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put input stats: %s", auth->info.lnkname,
 		    rad_strerror(auth->radius.handle)));
     		return (RAD_NACK);
 	}
@@ -1173,7 +1181,7 @@
 	if (rad_put_int(auth->radius.handle, RAD_ACCT_OUTPUT_OCTETS, auth->info.stats.xmitOctets % MAX_U_INT32) != 0 ||
 	    rad_put_int(auth->radius.handle, RAD_ACCT_OUTPUT_PACKETS, auth->info.stats.xmitFrames) != 0 ||
 	    rad_put_int(auth->radius.handle, RAD_ACCT_OUTPUT_GIGAWORDS, auth->info.stats.xmitOctets / MAX_U_INT32) != 0) {
-    		Log(LG_RADIUS, ("[%s] RADIUS: Put output stats: %s", auth->info.lnkname,
+    		Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put output stats: %s", auth->info.lnkname,
 		    rad_strerror(auth->radius.handle)));
     		return (RAD_NACK);
 	}
@@ -1186,7 +1194,7 @@
 	Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MPD_INPUT_OCTETS: %s", 
     	    auth->info.lnkname, str));
 	if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_INPUT_OCTETS, str) != 0) {
-    	    Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_INPUT_OCTETS: %s", auth->info.lnkname,
+    	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_INPUT_OCTETS: %s", auth->info.lnkname,
 		rad_strerror(auth->radius.handle)));
 	}
 	snprintf(str, sizeof(str), "%s:%llu",
@@ -1194,7 +1202,7 @@
 	Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MPD_INPUT_PACKETS: %s", 
     	    auth->info.lnkname, str));
 	if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_INPUT_PACKETS, str) != 0) {
-    	    Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_INPUT_PACKETS: %s", auth->info.lnkname,
+    	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_INPUT_PACKETS: %s", auth->info.lnkname,
 		rad_strerror(auth->radius.handle)));
 	}
 	if (strcmp(ssr->name,auth->params.std_acct[0]) == 0) {
@@ -1207,7 +1215,7 @@
 	    if (rad_put_int(auth->radius.handle, RAD_ACCT_INPUT_OCTETS, ssr->Octets % MAX_U_INT32) != 0 ||
 		rad_put_int(auth->radius.handle, RAD_ACCT_INPUT_PACKETS, ssr->Packets) != 0 ||
 		rad_put_int(auth->radius.handle, RAD_ACCT_INPUT_GIGAWORDS, ssr->Octets / MAX_U_INT32) != 0) {
-    		    Log(LG_RADIUS, ("[%s] RADIUS: Put input stats: %s", auth->info.lnkname,
+    		    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put input stats: %s", auth->info.lnkname,
 			rad_strerror(auth->radius.handle)));
     		    return (RAD_NACK);
 	    }
@@ -1220,7 +1228,7 @@
 	Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MPD_OUTPUT_OCTETS: %s", 
     	    auth->info.lnkname, str));
 	if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_OUTPUT_OCTETS, str) != 0) {
-    	    Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_OUTPUT_OCTETS: %s", auth->info.lnkname,
+    	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_OUTPUT_OCTETS: %s", auth->info.lnkname,
 		rad_strerror(auth->radius.handle)));
 	}
 	snprintf(str, sizeof(str), "%s:%llu",
@@ -1228,7 +1236,7 @@
 	Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MPD_OUTPUT_PACKETS: %s", 
     	    auth->info.lnkname, str));
 	if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_OUTPUT_PACKETS, str) != 0) {
-    	    Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_OUTPUT_PACKETS: %s", auth->info.lnkname,
+    	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_OUTPUT_PACKETS: %s", auth->info.lnkname,
 		rad_strerror(auth->radius.handle)));
 	}
 	if (strcmp(ssr->name,auth->params.std_acct[1]) == 0) {
@@ -1241,7 +1249,7 @@
 	    if (rad_put_int(auth->radius.handle, RAD_ACCT_OUTPUT_OCTETS, ssr->Octets % MAX_U_INT32) != 0 ||
 		rad_put_int(auth->radius.handle, RAD_ACCT_OUTPUT_PACKETS, ssr->Packets) != 0 ||
 		rad_put_int(auth->radius.handle, RAD_ACCT_OUTPUT_GIGAWORDS, ssr->Octets / MAX_U_INT32) != 0) {
-    		    Log(LG_RADIUS, ("[%s] RADIUS: Put output stats: %s", auth->info.lnkname,
+    		    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Put output stats: %s", auth->info.lnkname,
 			rad_strerror(auth->radius.handle)));
     		    return (RAD_NACK);
 	    }
@@ -1264,7 +1272,7 @@
 	auth->info.lnkname, auth->params.authname));
     n = rad_init_send_request(auth->radius.handle, &fd, &tv);
     if (n != 0) {
-	Log(LG_RADIUS, ("[%s] RADIUS: rad_init_send_request failed: %d %s",
+	Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: rad_init_send_request failed: %d %s",
     	    auth->info.lnkname, n, rad_strerror(auth->radius.handle)));
         return (RAD_NACK);
     }
@@ -1282,7 +1290,7 @@
 	n = poll(fds,1,tv.tv_sec*1000+tv.tv_usec/1000);
 
 	if (n == -1) {
-    	    Log(LG_RADIUS, ("[%s] RADIUS: poll failed %s", auth->info.lnkname, 
+    	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: poll failed %s", auth->info.lnkname, 
     		strerror(errno)));
     	    return (RAD_NACK);
 	}
@@ -1331,13 +1339,13 @@
     	    break;
 
 	case -1:
-    	    Log(LG_RADIUS, ("[%s] RADIUS: rad_send_request for user '%s' failed: %s",
+    	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: rad_send_request for user '%s' failed: %s",
     		auth->info.lnkname, auth->params.authname,
 		rad_strerror(auth->radius.handle)));
     	    return (RAD_NACK);
       
 	default:
-    	    Log(LG_RADIUS, ("[%s] RADIUS: rad_send_request: unexpected return value: %d", 
+    	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: rad_send_request: unexpected return value: %d", 
     		auth->info.lnkname, n));
     	    return (RAD_NACK);
     }
@@ -1462,7 +1470,7 @@
 	Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_FRAMED_ROUTE: %s ",
 	  auth->info.lnkname, route));
 	if (!ParseRange(route, &range, ALLOW_IPV4)) {
-	  Log(LG_RADIUS, ("[%s] RADIUS: Get RAD_FRAMED_ROUTE: Bad route \"%s\"",
+	  Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Get RAD_FRAMED_ROUTE: Bad route \"%s\"",
 	    auth->info.lnkname, route));
 	  free(route);
 	  break;
@@ -1473,7 +1481,7 @@
 	j = 0;
 	SLIST_FOREACH(r1, &auth->params.routes, next) {
 	  if (!u_rangecompare(&r->dest, &r1->dest)) {
-	    Log(LG_RADIUS, ("[%s] RADIUS: Duplicate route %s",
+	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Duplicate route %s",
 		auth->info.lnkname, route));
 	    j = 1;
 	  }
@@ -1491,7 +1499,7 @@
 	Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_FRAMED_IPV6_ROUTE: %s ",
 	  auth->info.lnkname, route));
 	if (!ParseRange(route, &range, ALLOW_IPV6)) {
-	  Log(LG_RADIUS, ("[%s] RADIUS: Get RAD_FRAMED_IPV6_ROUTE: Bad route \"%s\"", auth->info.lnkname, route));
+	  Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Get RAD_FRAMED_IPV6_ROUTE: Bad route \"%s\"", auth->info.lnkname, route));
 	  free(route);
 	  break;
 	}
@@ -1501,7 +1509,7 @@
 	j = 0;
 	SLIST_FOREACH(r1, &auth->params.routes, next) {
 	  if (!u_rangecompare(&r->dest, &r1->dest)) {
-	    Log(LG_RADIUS, ("[%s] RADIUS: Duplicate route %s",
+	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Duplicate route %s",
 		auth->info.lnkname, route));
 	    j = 1;
 	  }
@@ -1537,7 +1545,7 @@
 	Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_FRAMED_MTU: %u ",
 	  auth->info.lnkname, i));
 	if (i < IFACE_MIN_MTU || i > IFACE_MAX_MTU) {
-	  Log(LG_RADIUS, ("[%s] RADIUS: Get RAD_FRAMED_MTU: invalid MTU: %u ",
+	  Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Get RAD_FRAMED_MTU: invalid MTU: %u ",
 	    auth->info.lnkname, i));
 	  auth->params.mtu = 0;
 	  break;
@@ -1594,7 +1602,7 @@
 
       case RAD_VENDOR_SPECIFIC:
 	if ((res = rad_get_vendor_attr(&vendor, &data, &len)) == -1) {
-	  Log(LG_RADIUS, ("[%s] RADIUS: Get vendor attr failed: %s ",
+	  Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Get vendor attr failed: %s ",
 	    auth->info.lnkname, rad_strerror(auth->radius.handle)));
 	  return RAD_NACK;
 	}
@@ -1641,7 +1649,7 @@
 		    auth->info.lnkname));
 		}
 		if ((tmpval = rad_cvt_string((const char *)data, len)) == NULL) {
-		    Log(LG_RADIUS, ("[%s] RADIUS: rad_cvt_string failed: %s",
+		    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: rad_cvt_string failed: %s",
 			auth->info.lnkname, rad_strerror(auth->radius.handle)));
 		    return RAD_NACK;
 		}
@@ -1667,7 +1675,7 @@
 		  auth->info.lnkname));
 		tmpkey = rad_demangle_mppe_key(auth->radius.handle, data, len, &tmpkey_len);
 		if (!tmpkey) {
-		  Log(LG_RADIUS, ("[%s] RADIUS: rad_demangle_mppe_key failed: %s",
+		  Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: rad_demangle_mppe_key failed: %s",
 		    auth->info.lnkname, rad_strerror(auth->radius.handle)));
 		  return RAD_NACK;
 		}
@@ -1682,7 +1690,7 @@
 		  auth->info.lnkname));
 		tmpkey = rad_demangle_mppe_key(auth->radius.handle, data, len, &tmpkey_len);
 		if (!tmpkey) {
-		  Log(LG_RADIUS, ("[%s] RADIUS: rad_demangle_mppe_key failed: %s",
+		  Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: rad_demangle_mppe_key failed: %s",
 		    auth->info.lnkname, rad_strerror(auth->radius.handle)));
 		  return RAD_NACK;
 		}
@@ -1697,14 +1705,14 @@
 		  auth->info.lnkname));
 
 		if (len != 32) {
-		  Log(LG_RADIUS, ("[%s] RADIUS: Server returned garbage %d of expected %d Bytes",
+		  Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Server returned garbage %d of expected %d Bytes",
 		    auth->info.lnkname, (int)len, 32));
 		  return RAD_NACK;
 		}
 
 		tmpkey = rad_demangle(auth->radius.handle, data, len);
 		if (tmpkey == NULL) {
-		  Log(LG_RADIUS, ("[%s] RADIUS: rad_demangle failed: %s",
+		  Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: rad_demangle failed: %s",
 		    auth->info.lnkname, rad_strerror(auth->radius.handle)));
 		  return RAD_NACK;
 		}
@@ -1845,7 +1853,7 @@
 	      acl2 = strsep(&acl1, "#");
 	      i = atol(acl2);
 	      if (i <= 0 || i > ACL_FILTERS) {
-	        Log(LG_RADIUS, ("[%s] RADIUS: Wrong filter number: %i",
+	        Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Wrong filter number: %i",
 		  auth->info.lnkname, i));
 	        free(acl);
 	        break;
@@ -1966,7 +1974,7 @@
 	/* sanity check, this happens when FreeRADIUS has no msoft-dictionary loaded */
 	if (auth->proto == PROTO_CHAP && auth->alg == CHAP_ALG_MSOFTv2
 		&& auth->mschapv2resp == NULL && auth->status == AUTH_STATUS_SUCCESS) {
-	    Log(LG_RADIUS, ("[%s] RADIUS: PANIC no MS-CHAP2-Success received from server!",
+	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: PANIC no MS-CHAP2-Success received from server!",
     		auth->info.lnkname));
 	    return RAD_NACK;
 	}
@@ -2003,7 +2011,7 @@
 	    j = 0;
 	    SLIST_FOREACH(r1, &auth->params.routes, next) {
 		if (!u_rangecompare(&r->dest, &r1->dest)) {
-		    Log(LG_RADIUS, ("[%s] RADIUS: Duplicate route", auth->info.lnkname));
+		    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Duplicate route", auth->info.lnkname));
 		    j = 1;
 		}
 	    };
diff -ur mpd-5.6/src/radius.h mpd-5.6-lutz/src/radius.h
--- mpd-5.6/src/radius.h	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/radius.h	2013-04-25 13:18:17.000000000 +0200
@@ -117,6 +117,7 @@
   #define RAD_MPD_IFACE_NAME	20
   #define RAD_MPD_IFACE_DESCR	21
   #define RAD_MPD_IFACE_GROUP	22
+  #define RAD_MPD_TERM_CAUSE	23
   #define RAD_MPD_DROP_USER	154
 
   /* Configuration options */
diff -ur mpd-5.6/src/radsrv.c mpd-5.6-lutz/src/radsrv.c
--- mpd-5.6/src/radsrv.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/radsrv.c	2013-04-24 11:34:31.000000000 +0200
@@ -239,7 +239,7 @@
 		break;
 	    case RAD_VENDOR_SPECIFIC:
 		if ((res = rad_get_vendor_attr(&vendor, &data, &len)) == -1) {
-		    Log(LG_RADIUS, ("radsrv: Get vendor attr failed: %s ",
+		    Log(LG_ERR|LG_RADIUS, ("radsrv: Get vendor attr failed: %s ",
 			rad_strerror(w->handle)));
 		    break;
 		}
@@ -312,7 +312,7 @@
 		          acl2 = strsep(&acl1, "#");
 		          i = atol(acl2);
 		          if (i <= 0 || i > ACL_FILTERS) {
-		            Log(LG_RADIUS, ("radsrv: Wrong filter number: %i", i));
+		            Log(LG_ERR|LG_RADIUS, ("radsrv: Wrong filter number: %i", i));
 		            free(acl);
 	    		    break;
 			  }
@@ -659,13 +659,13 @@
 	Log(LG_RADIUS2, ("radsrv: Adding client %s", s->hostname));
 	if (rad_add_server (w->handle, s->hostname,
 		0, s->sharedsecret, 0, 0) == -1) {
-		Log(LG_RADIUS, ("radsrv: Adding client error: %s",
+		Log(LG_ERR|LG_RADIUS, ("radsrv: Adding client error: %s",
 		    rad_strerror(w->handle)));
 	}
 	s = s->next;
     }
 
-    Log(LG_ERR, ("radsrv: listening on %s %d", 
+    Log(LG_ALWAYS, ("radsrv: listening on %s %d", 
 	u_addrtoa(&w->addr,addrstr,sizeof(addrstr)), w->port));
     return (0);
 }
@@ -686,7 +686,7 @@
     rad_close(w->handle);
     w->handle = NULL;
 
-    Log(LG_ERR, ("radsrv: stop listening"));
+    Log(LG_ALWAYS, ("radsrv: stop listening"));
     return (0);
 }
 
diff -ur mpd-5.6/src/rep.c mpd-5.6-lutz/src/rep.c
--- mpd-5.6/src/rep.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/rep.c	2013-04-24 11:31:36.000000000 +0200
@@ -36,11 +36,13 @@
     
     Log(LG_REP, ("[%s] Rep: INCOMING event from %s (0)",
 	r->name, l->name));
-	
+
+    MUTEX_LOCK(gNgMutex);
     if (r->csock <= 0) {
 	/* Create a new netgraph node to control TCP ksocket node. */
 	if (NgMkSockNode(NULL, &r->csock, NULL) < 0) {
     	    Perror("[%s] Rep: can't create control socket", r->name);
+	    MUTEX_UNLOCK(gNgMutex);
     	    PhysClose(l);
 	    return;
 	}
@@ -55,6 +57,7 @@
     	Perror("[%s] Rep: can't attach %s %s node",
     	    l->name, NG_TEE_NODE_TYPE, mkp.ourhook);
 	close(r->csock);
+   	MUTEX_UNLOCK(gNgMutex);
     	PhysClose(l);
 	return;
     }
@@ -63,10 +66,12 @@
     if ((r->node_id = NgGetNodeID(r->csock, ".:tee")) == 0) {
 	Perror("[%s] Rep: Cannot get %s node id", l->name, NG_TEE_NODE_TYPE);
 	close(r->csock);
+   	MUTEX_UNLOCK(gNgMutex);
     	PhysClose(l);
 	return;
     };
     
+    MUTEX_UNLOCK(gNgMutex);
     PhysGetCallingNum(r->links[0], buf, sizeof(buf));
     PhysSetCallingNum(r->links[1], buf);
 
@@ -97,11 +102,13 @@
     if (r->p_up == 3 && r->csock > 0 && r->node_id) {
 	char path[NG_PATHSIZ];
 	
+   	MUTEX_LOCK(gNgMutex);
 	snprintf(path, sizeof(path), "[%x]:", r->node_id);
 	NgFuncShutdownNode(r->csock, r->name, path);
 	r->node_id = 0;
 	close(r->csock);
 	r->csock = -1;
+   	MUTEX_UNLOCK(gNgMutex);
     }
 }
 
@@ -126,10 +133,12 @@
     if (r->csock > 0 && r->node_id) {
 	char path[NG_PATHSIZ];
 	
+   	MUTEX_LOCK(gNgMutex);
 	snprintf(path, sizeof(path), "[%x]:", r->node_id);
 	NgFuncShutdownNode(r->csock, r->name, path);
 	r->node_id = 0;
 	close(r->csock);
+   	MUTEX_UNLOCK(gNgMutex);
 	r->csock = -1;
     }
     
@@ -251,17 +260,17 @@
     int		k;
 
     if ((l = LinkFind(out)) == NULL) {
-	Log(LG_REP, ("[%s] Can't find link \"%s\"", in->name, out));
+	Log(LG_ERR|LG_REP, ("[%s] Can't find link \"%s\"", in->name, out));
 	return (-1);
     }
     if (PhysIsBusy(l)) {
-	Log(LG_REP, ("[%s] Link \"%s\" is busy", in->name, out));
+	Log(LG_ERR|LG_REP, ("[%s] Link \"%s\" is busy", in->name, out));
 	return (-1);
     }
     if (l->tmpl)
 	l = LinkInst(l, NULL, 0, 0);
     if (!l) {
-	Log(LG_REP, ("[%s] Can't create link \"%s\"", in->name, out));
+	Log(LG_ERR|LG_REP, ("[%s] Can't create link \"%s\"", in->name, out));
 	return (-1);
     }
 
@@ -310,10 +319,12 @@
     if (r->csock > 0 && r->node_id) {
 	char path[NG_PATHSIZ];
 	
+   	MUTEX_LOCK(gNgMutex);
 	snprintf(path, sizeof(path), "[%x]:", r->node_id);
 	NgFuncShutdownNode(r->csock, r->name, path);
 	r->node_id = 0;
 	close(r->csock);
+   	MUTEX_UNLOCK(gNgMutex);
 	r->csock = -1;
     }
     r->dead = 1;
diff -ur mpd-5.6/src/tcp.c mpd-5.6-lutz/src/tcp.c
--- mpd-5.6/src/tcp.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/tcp.c	2013-04-24 11:30:56.000000000 +0200
@@ -216,6 +216,7 @@
 	int 			rval;
 	char 			buf[48];
 
+   	MUTEX_LOCK(gNgMutex);
 	/* Create a new netgraph node to control TCP ksocket node. */
 	if (NgMkSockNode(NULL, &pi->csock, NULL) < 0) {
 		Perror("[%s] TCP can't create control socket", l->name);
@@ -224,7 +225,7 @@
 	(void)fcntl(pi->csock, F_SETFD, 1);
 
         if (!PhysGetUpperHook(l, path, hook)) {
-		Log(LG_PHYS, ("[%s] TCP: can't get upper hook", l->name));
+		Log(LG_ERR|LG_PHYS, ("[%s] TCP: can't get upper hook", l->name));
     		goto fail;
         }
     
@@ -343,8 +344,10 @@
 		    u_addrtoa(&pi->conf.peer_addr.addr, buf, sizeof(buf)), pi->conf.peer_port));
 	}
 
+   	MUTEX_UNLOCK(gNgMutex);
 	return;
 fail:
+   	MUTEX_UNLOCK(gNgMutex);
 	l->state = PHYS_STATE_DOWN;
 	TcpDoClose(l);
 	PhysDown(l, STR_ERROR, NULL);
@@ -371,6 +374,7 @@
 
 	assert(type == EVENT_READ);
 
+   	MUTEX_LOCK(gNgMutex);
 	/* Check whether the connection was successful or not. */
 	if (NgRecvMsg(pi->csock, &cn.resp, sizeof(cn), path) < 0) {
 		Perror("[%s] error reading message from \"%s\"", l->name, path);
@@ -381,7 +385,7 @@
 	assert(cn.resp.header.cmd == NGM_KSOCKET_CONNECT);
 
 	if (cn.rval != 0) {
-		Log(LG_PHYS, ("[%s] failed to connect: %s", l->name,
+		Log(LG_ERR|LG_PHYS, ("[%s] failed to connect: %s", l->name,
 		    strerror(cn.rval)));
 		goto failed;
 	}
@@ -389,11 +393,13 @@
 	/* Report connected. */
 	Log(LG_PHYS, ("[%s] connection established", l->name));
 
+   	MUTEX_UNLOCK(gNgMutex);
 	l->state = PHYS_STATE_UP;
 	PhysUp(l);
 
 	return;
 failed:
+   	MUTEX_UNLOCK(gNgMutex);
 	l->state = PHYS_STATE_DOWN;
 	TcpDoClose(l);
 	PhysDown(l, STR_ERROR, NULL);
@@ -423,6 +429,7 @@
 
 	assert(type == EVENT_READ);
 
+   	MUTEX_LOCK(gNgMutex);
 	/* Accept cloned ng_ksocket(4). */
 	if (NgRecvMsg(If->csock, &ac.resp, sizeof(ac), NULL) < 0) {
 		Perror("TCP: error reading message from \"%s\"", path);
@@ -495,11 +502,12 @@
 
 		PhysIncoming(l);
 	} else {
-	    Log(LG_PHYS, ("No free TCP link with requested parameters "
+	    Log(LG_ERR|LG_PHYS, ("No free TCP link with requested parameters "
 	        "was found"));
 	    snprintf(path, sizeof(path), "[%x]:", ac.id);
 	    NgFuncShutdownNode(If->csock, "", path);
 	}
+   	MUTEX_UNLOCK(gNgMutex);
 
 failed:
 	/* Tell that we are willing to receive accept message. */
@@ -507,6 +515,7 @@
 	    NGM_KSOCKET_ACCEPT, NULL, 0) < 0) {
 		Perror("TCP: can't accept on %s node", NG_KSOCKET_NODE_TYPE);
 	}
+   	MUTEX_UNLOCK(gNgMutex);
 	EventRegister(&If->ctrlEvent, EVENT_READ, If->csock,
 	    0, TcpAcceptEvent, If);
 }
@@ -566,6 +575,7 @@
 	    return;
 	};
 
+   	MUTEX_LOCK(gNgMutex);
 	if (pi->node_id != 0) {
 	    snprintf(path, sizeof(path), "[%lx]:", (u_long)pi->node_id);
 	    NgFuncShutdownNode(pi->csock, l->name, path);
@@ -579,6 +589,8 @@
 	}
 	
 	close(pi->csock);
+   	MUTEX_UNLOCK(gNgMutex);
+   
 	pi->csock = -1;
 	pi->node_id = 0;
 }
@@ -750,9 +762,11 @@
 	u_addrcopy(&pi->conf.self_addr,&pi->If->self_addr);
 	pi->If->self_port=pi->conf.self_port;
 	
+   	MUTEX_LOCK(gNgMutex);
 	/* Create a new netgraph node */
 	if (NgMkSockNode(NULL, &pi->If->csock, NULL) < 0) {
 	    Perror("TCP: can't create ctrl socket");
+	    MUTEX_UNLOCK(gNgMutex);
 	    return(0);
 	}
 	(void)fcntl(pi->If->csock, F_SETFD, 1);
@@ -805,6 +819,7 @@
 
 	Log(LG_PHYS, ("TCP: waiting for connection on %s %u",
 	    u_addrtoa(&pi->If->self_addr, buf, sizeof(buf)), pi->If->self_port));
+   	MUTEX_UNLOCK(gNgMutex);
 	EventRegister(&pi->If->ctrlEvent, EVENT_READ, pi->If->csock,
 	    0, TcpAcceptEvent, pi->If);
 
@@ -812,6 +827,7 @@
 fail2:
 	NgSendMsg(pi->If->csock, LISTENHOOK, NGM_GENERIC_COOKIE, NGM_SHUTDOWN,
 	    NULL, 0);
+   	MUTEX_UNLOCK(gNgMutex);
 	return (0);
 }
 
diff -ur mpd-5.6/src/udp.c mpd-5.6-lutz/src/udp.c
--- mpd-5.6/src/udp.c	2011-12-21 15:58:49.000000000 +0100
+++ mpd-5.6-lutz/src/udp.c	2013-04-24 11:29:23.000000000 +0200
@@ -219,6 +219,7 @@
         struct ng_ksocket_sockopt *const ksso = &u.ksso;
 	int			csock;
 
+   	MUTEX_LOCK(gNgMutex);
 	/* Create a new netgraph node to control TCP ksocket node. */
 	if (NgMkSockNode(NULL, &csock, NULL) < 0) {
 		Perror("[%s] TCP can't create control socket", l->name);
@@ -227,7 +228,7 @@
 	(void)fcntl(csock, F_SETFD, 1);
 
         if (!PhysGetUpperHook(l, path, hook)) {
-		Log(LG_PHYS, ("[%s] UDP: can't get upper hook", l->name));
+		Log(LG_ERR, ("[%s] UDP: can't get upper hook", l->name));
     		goto fail;
         }
 
@@ -311,6 +312,7 @@
     }
   
     close(csock);
+    MUTEX_UNLOCK(gNgMutex);
 
     /* OK */
     l->state = PHYS_STATE_UP;
@@ -318,6 +320,7 @@
     return;
 
 fail:
+    MUTEX_UNLOCK(gNgMutex);
     UdpDoClose(l);
     pi->incoming=0;
     l->state = PHYS_STATE_DOWN;
@@ -378,9 +381,11 @@
 	if (pi->node_id == 0)
 		return;
 
+   	MUTEX_LOCK(gNgMutex);
 	/* Get a temporary netgraph socket node */
 	if (NgMkSockNode(NULL, &csock, NULL) == -1) {
 		Perror("UDP: NgMkSockNode");
+	   	MUTEX_UNLOCK(gNgMutex);
 		return;
 	}
 	
@@ -389,6 +394,7 @@
 	NgFuncShutdownNode(csock, l->name, path);
 	
 	close(csock);
+   	MUTEX_UNLOCK(gNgMutex);
 	
 	pi->node_id = 0;
 }
@@ -539,7 +545,7 @@
 
 	saddrlen = sizeof(saddr);
 	if ((pktlen = recvfrom(If->csock, pktbuf, sizeof(pktbuf), MSG_DONTWAIT, (struct sockaddr *)(&saddr), &saddrlen)) < 0) {
-	    Log(LG_PHYS, ("recvfrom() error: %s", strerror(errno)));
+	    Log(LG_ERR|LG_PHYS, ("recvfrom() error: %s", strerror(errno)));
 	}
 
 	sockaddrtou_addr(&saddr, &addr, &port);
@@ -600,7 +606,7 @@
 
 		PhysIncoming(l);
 	} else {
-		Log(LG_PHYS, ("No free UDP link with requested parameters "
+		Log(LG_ERR|LG_PHYS, ("No free UDP link with requested parameters "
 	    	    "was found"));
 	}
 
