diff --git a/net/mpd5/files/patch-redial b/net/mpd5/files/patch-redial new file mode 100644 index 000000000000..b8f8c18d28c1 --- /dev/null +++ b/net/mpd5/files/patch-redial @@ -0,0 +1,174 @@ +Index: src/lcp.c +=================================================================== +--- src/lcp.c (revision 2452) ++++ src/lcp.c (revision 2454) +@@ -26,6 +26,7 @@ + + #define LCP_ECHO_INTERVAL 5 /* Enable keep alive by default */ + #define LCP_ECHO_TIMEOUT 40 ++ #define LCP_MAX_RESETS 3 + + #define LCP_KNOWN_CODES ( (1 << CODE_CONFIGREQ) \ + | (1 << CODE_CONFIGACK) \ +@@ -180,6 +181,7 @@ LcpInit(Link l) + FsmInit(&lcp->fsm, &gLcpFsmType, l); + lcp->fsm.conf.echo_int = LCP_ECHO_INTERVAL; + lcp->fsm.conf.echo_max = LCP_ECHO_TIMEOUT; ++ lcp->resets = LCP_MAX_RESETS; + lcp->phase = PHASE_DEAD; + + AuthInit(l); +@@ -690,8 +692,17 @@ LcpLayerDown(Fsm fp) + LcpState const lcp = &l->lcp; + + LcpStopActivity(l); +- if (lcp->phase == PHASE_AUTHENTICATE || lcp->phase == PHASE_NETWORK) ++ if (lcp->phase == PHASE_AUTHENTICATE || lcp->phase == PHASE_NETWORK) { + lcp->need_reset = 1; ++ if (lcp->resets > 0) { ++ Log(LG_LCP2, ("[%s] LCP: Reset (%u left)", l->name, (int)lcp->resets)); ++ lcp->resets--; ++ } else { ++ Log(LG_LCP2, ("[%s] LCP: Too many resets", l->name)); ++ FsmFailure(&lcp->fsm, FAIL_NEGOT_FAILURE); ++ lcp->resets = LCP_MAX_RESETS; ++ } ++ } + } + + void LcpOpen(Link l) +Index: src/lcp.h +=================================================================== +--- src/lcp.h (revision 2452) ++++ src/lcp.h (revision 2454) +@@ -87,6 +87,7 @@ + struct fsm fsm; /* Finite state machine */ + + u_char need_reset; /* LCP needs complete reset before ConfReq */ ++ u_char resets; /* LCP resets left before failure */ + }; + typedef struct lcpstate *LcpState; + +Index: src/link.c +=================================================================== +--- src/link.c (revision 2452) ++++ src/link.c (revision 2454) +@@ -52,6 +52,17 @@ + SET_NO + }; + ++ /* Used to prevent auto-up on links closed manually */ ++ enum { ++ LINK_ADMINSTATE_DOWN = 0, ++ LINK_ADMINSTATE_OPERATIONAL ++ }; ++ ++ static const char *linkAdminStateNames[] = { ++ "DOWN", ++ "OPERATIONAL" ++ }; ++ + #define RBUF_SIZE 100 + + /* +@@ -193,6 +204,7 @@ LinkOpenCmd(Context ctx) + { + if (ctx->lnk->tmpl) + Error("impossible to open template"); ++ ctx->lnk->admin_state = LINK_ADMINSTATE_OPERATIONAL; + RecordLinkUpDownReason(NULL, ctx->lnk, 1, STR_MANUALLY, NULL); + LinkOpen(ctx->lnk); + return (0); +@@ -207,6 +219,7 @@ LinkCloseCmd(Context ctx) + { + if (ctx->lnk->tmpl) + Error("impossible to close template"); ++ ctx->lnk->admin_state = LINK_ADMINSTATE_DOWN; + RecordLinkUpDownReason(NULL, ctx->lnk, 0, STR_MANUALLY, NULL); + LinkClose(ctx->lnk); + return (0); +@@ -258,7 +271,7 @@ LinkDown(Link l) + { + Log(LG_LINK, ("[%s] Link: DOWN event", l->name)); + +- if (OPEN_STATE(l->lcp.fsm.state)) { ++ if (OPEN_STATE(l->lcp.fsm.state) || l->admin_state != LINK_ADMINSTATE_DOWN) { + if (((l->conf.max_redial != 0) && (l->num_redial >= l->conf.max_redial)) || + gShutdownInProgress) { + if (l->conf.max_redial >= 0) { +@@ -307,6 +320,8 @@ LinkReopenTimeout(void *arg) + Log(LG_LINK, ("[%s] Link: reconnection attempt %hu", + l->name, l->num_redial)); + RecordLinkUpDownReason(NULL, l, 1, STR_REDIAL, NULL); ++ if (!OPEN_STATE(l->lcp.fsm.state)) ++ LinkOpen(l); + PhysOpen(l); + } + +@@ -411,6 +426,7 @@ LinkCreate(Context ctx, int ac, const char *const av[] + strlcpy(l->name, av[0 + stay], sizeof(l->name)); + l->type = pt; + l->tmpl = tmpl; ++ l->admin_state = LINK_ADMINSTATE_OPERATIONAL; + l->stay = stay; + l->parent = -1; + SLIST_INIT(&l->actions); +@@ -551,6 +567,7 @@ LinkInst(Link lt, const char *name, int tmpl, int stay + SLIST_INSERT_AFTER(ap, a, next); + ap = a; + } ++ l->admin_state = LINK_ADMINSTATE_OPERATIONAL; + l->tmpl = tmpl; + l->stay = stay; + /* Count link as one more child of parent. */ +@@ -1321,6 +1338,7 @@ LinkStat(Context ctx, int ac, const char *const av[], + Printf("\tChildren : %d\r\n", l->children); + else { + Printf("\tState : %s\r\n", gPhysStateNames[l->state]); ++ Printf("\tAdmin. state : %s\r\n", linkAdminStateNames[l->admin_state]); + Printf("\tSession Id : %s\r\n", l->session_id); + Printf("\tPeer ident : %s\r\n", l->lcp.peer_ident); + if (l->state == PHYS_STATE_UP) +Index: src/link.h +=================================================================== +--- src/link.h (revision 2452) ++++ src/link.h (revision 2454) +@@ -115,7 +115,8 @@ + int id; /* Index of this link in gLinks */ + u_char tmpl; /* This is template, not an instance */ + u_char stay; /* Must not disappear */ +- u_char state; /* Device current state */ ++ u_char state; /* Physical device current state */ ++ u_char admin_state; /* Link administrative state */ + u_char joined_bund; /* Link successfully joined bundle */ + u_char originate; /* Who originated the connection */ + u_char die; /* LCP agreed to die */ +Index: src/phys.c +=================================================================== +--- src/phys.c (revision 2452) ++++ src/phys.c (revision 2454) +@@ -590,8 +590,8 @@ PhysMsg(int type, void *arg) + UNREF(l); + return; + } +- Log(LG_PHYS2, ("[%s] device: %s event", +- l->name, MsgName(type))); ++ Log(LG_PHYS2, ("[%s] device: %s event in state %s", ++ l->name, MsgName(type), gPhysStateNames[l->state])); + switch (type) { + case MSG_OPEN: + l->downReasonValid=0; +@@ -599,7 +599,12 @@ PhysMsg(int type, void *arg) + PhysUp(l); + break; + } +- (*l->type->open)(l); ++ /* Redial may result in MSG_OPEN for just opened device */ ++ if (l->state == PHYS_STATE_DOWN) ++ (*l->type->open)(l); ++ else ++ Log(LG_PHYS2, ("[%s] device: OPEN event ignored", ++ l->name)); + break; + case MSG_CLOSE: + (*l->type->close)(l);