diff options
author | archie <archie@FreeBSD.org> | 2000-10-06 23:42:02 +0000 |
---|---|---|
committer | archie <archie@FreeBSD.org> | 2000-10-06 23:42:02 +0000 |
commit | a5984fa40eeb4f40d06d1f1266a995af112d7ee5 (patch) | |
tree | 5f45750444c54d176dde7c4165a0bc14cba8d25f /sys/netgraph | |
parent | 61ad84caf216f9c69a3844b1f4fa76b26021231e (diff) | |
download | FreeBSD-src-a5984fa40eeb4f40d06d1f1266a995af112d7ee5.zip FreeBSD-src-a5984fa40eeb4f40d06d1f1266a995af112d7ee5.tar.gz |
More complete fix for multi-link sequence number handling bugs.
Add a new control message for querying the sequence number state.
Diffstat (limited to 'sys/netgraph')
-rw-r--r-- | sys/netgraph/ng_ppp.c | 120 | ||||
-rw-r--r-- | sys/netgraph/ng_ppp.h | 22 |
2 files changed, 101 insertions, 41 deletions
diff --git a/sys/netgraph/ng_ppp.c b/sys/netgraph/ng_ppp.c index a179236..0e9bf71 100644 --- a/sys/netgraph/ng_ppp.c +++ b/sys/netgraph/ng_ppp.c @@ -34,7 +34,7 @@ * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * - * Author: Archie Cobbs <archie@whistle.com> + * Author: Archie Cobbs <archie@freebsd.org> * * $FreeBSD$ * $Whistle: ng_ppp.c,v 1.24 1999/11/01 09:24:52 julian Exp $ @@ -91,29 +91,30 @@ #define MP_LONG_FIRST_FLAG 0x80000000 /* first fragment in frame */ #define MP_LONG_LAST_FLAG 0x40000000 /* last fragment in frame */ -#define MP_NOSEQ INT_MAX /* impossible sequence number */ - -#define MP_SEQ_MASK(priv) ((priv)->conf.recvShortSeq ? \ - MP_SHORT_SEQ_MASK : MP_LONG_SEQ_MASK) +#define MP_NOSEQ 0x7fffffff /* impossible sequence number */ /* Sign extension of MP sequence numbers */ -#define MP_SHORT_EXTEND(s) (((s) & MP_SHORT_SEQ_HIBIT) ? \ - ((s) | ~MP_SHORT_SEQ_MASK) : (s)) -#define MP_LONG_EXTEND(s) (((s) & MP_LONG_SEQ_HIBIT) ? \ - ((s) | ~MP_LONG_SEQ_MASK) : (s)) - -/* Comparision of MP sequence numbers */ -#define MP_SHORT_SEQ_DIFF(x,y) \ - (MP_SHORT_EXTEND(((x) & MP_SHORT_SEQ_MASK) - ((y) & MP_SHORT_SEQ_MASK))) -#define MP_LONG_SEQ_DIFF(x,y) \ - (MP_LONG_EXTEND(((x) & MP_LONG_SEQ_MASK) - ((y) & MP_LONG_SEQ_MASK))) - -#define MP_SEQ_DIFF(priv,x,y) ((priv)->conf.recvShortSeq ? \ - MP_SHORT_SEQ_DIFF((x), (y)) : \ +#define MP_SHORT_EXTEND(s) (((s) & MP_SHORT_SEQ_HIBIT) ? \ + ((s) | ~MP_SHORT_SEQ_MASK) \ + : ((s) & MP_SHORT_SEQ_MASK)) +#define MP_LONG_EXTEND(s) (((s) & MP_LONG_SEQ_HIBIT) ? \ + ((s) | ~MP_LONG_SEQ_MASK) \ + : ((s) & MP_LONG_SEQ_MASK)) + +/* Comparision of MP sequence numbers. Note: all sequence numbers + except priv->xseq are stored with the sign bit extended. */ +#define MP_SHORT_SEQ_DIFF(x,y) MP_SHORT_EXTEND((x) - (y)) +#define MP_LONG_SEQ_DIFF(x,y) MP_LONG_EXTEND((x) - (y)) + +#define MP_RECV_SEQ_DIFF(priv,x,y) \ + ((priv)->conf.recvShortSeq ? \ + MP_SHORT_SEQ_DIFF((x), (y)) : \ MP_LONG_SEQ_DIFF((x), (y))) -#define MP_NEXT_SEQ(priv,seq) (((seq) + 1) & MP_SEQ_MASK(priv)) -#define MP_PREV_SEQ(priv,seq) (((seq) - 1) & MP_SEQ_MASK(priv)) +/* Increment receive sequence number */ +#define MP_NEXT_RECV_SEQ(priv,seq) \ + (((seq) + 1) & ((priv)->conf.recvShortSeq ? \ + MP_SHORT_SEQ_MASK : MP_LONG_SEQ_MASK)) /* Don't fragment transmitted packets smaller than this */ #define MP_MIN_FRAG_LEN 6 @@ -176,7 +177,7 @@ static const char *const ng_ppp_hook_names[] = { struct ng_ppp_link { struct ng_ppp_link_conf conf; /* link configuration */ hook_p hook; /* connection to link data */ - int seq; /* highest rec'd seq# - MSEQ */ + int32_t seq; /* highest rec'd seq# - MSEQ */ struct timeval lastWrite; /* time of last write */ int bytesInQueue; /* bytes in the output queue */ struct ng_ppp_link_stat stats; /* Link stats */ @@ -187,8 +188,8 @@ struct ng_ppp_private { struct ng_ppp_bund_conf conf; /* bundle config */ struct ng_ppp_link_stat bundleStats; /* bundle stats */ struct ng_ppp_link links[NG_PPP_MAX_LINKS];/* per-link info */ - int xseq; /* next out MP seq # */ - int mseq; /* min links[i].seq */ + int32_t xseq; /* next out MP seq # */ + int32_t mseq; /* min links[i].seq */ u_char vjCompHooked; /* VJ comp hooked up? */ u_char allLinksEqual; /* all xmit the same? */ u_char timerActive; /* frag timer active? */ @@ -236,6 +237,22 @@ static void ng_ppp_update(node_p node, int newConf); static void ng_ppp_start_frag_timer(node_p node); static void ng_ppp_stop_frag_timer(node_p node); +/* Parse type for struct ng_ppp_mp_state_type */ +static const struct ng_parse_fixedarray_info ng_ppp_rseq_array_info = { + &ng_parse_hint32_type, + NG_PPP_MAX_LINKS +}; +static const struct ng_parse_type ng_ppp_rseq_array_type = { + &ng_parse_fixedarray_type, + &ng_ppp_rseq_array_info, +}; +static const struct ng_parse_struct_info ng_ppp_mp_state_type_info + = NG_PPP_MP_STATE_TYPE_INFO(&ng_ppp_rseq_array_type); +static const struct ng_parse_type ng_ppp_mp_state_type = { + &ng_parse_struct_type, + &ng_ppp_mp_state_type_info, +}; + /* Parse type for struct ng_ppp_link_conf */ static const struct ng_parse_struct_info ng_ppp_link_type_info = NG_PPP_LINK_TYPE_INFO; @@ -253,7 +270,7 @@ static const struct ng_parse_type ng_ppp_bund_type = { }; /* Parse type for struct ng_ppp_node_conf */ -struct ng_parse_fixedarray_info ng_ppp_array_info = { +static const struct ng_parse_fixedarray_info ng_ppp_array_info = { &ng_ppp_link_type, NG_PPP_MAX_LINKS }; @@ -294,6 +311,13 @@ static const struct ng_cmdlist ng_ppp_cmds[] = { }, { NGM_PPP_COOKIE, + NGM_PPP_GET_MP_STATE, + "getmpstate", + NULL, + &ng_ppp_mp_state_type + }, + { + NGM_PPP_COOKIE, NGM_PPP_GET_LINK_STATS, "getstats", &ng_parse_int16_type, @@ -482,6 +506,24 @@ ng_ppp_rcvmsg(node_p node, struct ng_mesg *msg, conf->links[i] = priv->links[i].conf; break; } + case NGM_PPP_GET_MP_STATE: + { + struct ng_ppp_mp_state *info; + int i; + + NG_MKRESPONSE(resp, msg, sizeof(*info), M_NOWAIT); + if (resp == NULL) + ERROUT(ENOMEM); + info = (struct ng_ppp_mp_state *)resp->data; + bzero(info, sizeof(*info)); + for (i = 0; i < NG_PPP_MAX_LINKS; i++) { + if (priv->links[i].seq != MP_NOSEQ) + info->rseq[i] = priv->links[i].seq; + } + info->mseq = priv->mseq; + info->xseq = priv->xseq; + break; + } case NGM_PPP_GET_LINK_STATS: case NGM_PPP_CLR_LINK_STATS: case NGM_PPP_GETCLR_LINK_STATS: @@ -1035,7 +1077,7 @@ ng_ppp_mp_input(node_p node, int linkNum, struct mbuf *m, meta_p meta) return (ENOBUFS); } shdr = ntohs(*mtod(m, u_int16_t *)); - frag->seq = shdr & MP_SHORT_SEQ_MASK; + frag->seq = MP_SHORT_EXTEND(shdr); frag->first = (shdr & MP_SHORT_FIRST_FLAG) != 0; frag->last = (shdr & MP_SHORT_LAST_FLAG) != 0; diff = MP_SHORT_SEQ_DIFF(frag->seq, priv->mseq); @@ -1053,7 +1095,7 @@ ng_ppp_mp_input(node_p node, int linkNum, struct mbuf *m, meta_p meta) return (ENOBUFS); } lhdr = ntohl(*mtod(m, u_int32_t *)); - frag->seq = lhdr & MP_LONG_SEQ_MASK; + frag->seq = MP_LONG_EXTEND(lhdr); frag->first = (lhdr & MP_LONG_FIRST_FLAG) != 0; frag->last = (lhdr & MP_LONG_LAST_FLAG) != 0; diff = MP_LONG_SEQ_DIFF(frag->seq, priv->mseq); @@ -1077,7 +1119,7 @@ ng_ppp_mp_input(node_p node, int linkNum, struct mbuf *m, meta_p meta) struct ng_ppp_link *const alink = &priv->links[priv->activeLinks[i]]; - if (MP_SEQ_DIFF(priv, alink->seq, priv->mseq) < 0) + if (MP_RECV_SEQ_DIFF(priv, alink->seq, priv->mseq) < 0) priv->mseq = alink->seq; } @@ -1093,7 +1135,7 @@ ng_ppp_mp_input(node_p node, int linkNum, struct mbuf *m, meta_p meta) /* Add fragment to queue, which is sorted by sequence number */ inserted = 0; CIRCLEQ_FOREACH_REVERSE(qent, &priv->frags, f_qent) { - diff = MP_SEQ_DIFF(priv, frag->seq, qent->seq); + diff = MP_RECV_SEQ_DIFF(priv, frag->seq, qent->seq); if (diff > 0) { CIRCLEQ_INSERT_AFTER(&priv->frags, qent, frag, f_qent); inserted = 1; @@ -1130,7 +1172,7 @@ ng_ppp_check_packet(node_p node) /* Check first fragment is the start of a deliverable packet */ qent = CIRCLEQ_FIRST(&priv->frags); - if (!qent->first || MP_SEQ_DIFF(priv, qent->seq, priv->mseq) > 1) + if (!qent->first || MP_RECV_SEQ_DIFF(priv, qent->seq, priv->mseq) > 1) return (0); /* Check that all the fragments are there */ @@ -1138,7 +1180,7 @@ ng_ppp_check_packet(node_p node) qnext = CIRCLEQ_NEXT(qent, f_qent); if (qnext == (void *)&priv->frags) /* end of queue */ return (0); - if (qnext->seq != MP_NEXT_SEQ(priv, qent->seq)) + if (qnext->seq != MP_NEXT_RECV_SEQ(priv, qent->seq)) return (0); qent = qnext; } @@ -1206,12 +1248,12 @@ ng_ppp_frag_trim(node_p node) /* Determine whether first fragment can ever be completed */ CIRCLEQ_FOREACH(qent, &priv->frags, f_qent) { - if (MP_SEQ_DIFF(priv, qent->seq, priv->mseq) >= 0) + if (MP_RECV_SEQ_DIFF(priv, qent->seq, priv->mseq) >= 0) break; qnext = CIRCLEQ_NEXT(qent, f_qent); KASSERT(qnext != (void*)&priv->frags, ("%s: last frag < MSEQ?", __FUNCTION__)); - if (qnext->seq != MP_NEXT_SEQ(priv, qent->seq) + if (qnext->seq != MP_NEXT_RECV_SEQ(priv, qent->seq) || qent->last || qnext->first) { dead = 1; break; @@ -1273,13 +1315,13 @@ ng_ppp_frag_process(node_p node) qent = CIRCLEQ_FIRST(&priv->frags); /* Bump MSEQ if necessary */ - if (MP_SEQ_DIFF(priv, priv->mseq, qent->seq) < 0) { + if (MP_RECV_SEQ_DIFF(priv, priv->mseq, qent->seq) < 0) { priv->mseq = qent->seq; for (i = 0; i < priv->numActiveLinks; i++) { struct ng_ppp_link *const alink = &priv->links[priv->activeLinks[i]]; - if (MP_SEQ_DIFF(priv, + if (MP_RECV_SEQ_DIFF(priv, alink->seq, priv->mseq) < 0) alink->seq = priv->mseq; } @@ -1341,7 +1383,7 @@ ng_ppp_frag_checkstale(node_p node) end = qent; break; } - seq = MP_NEXT_SEQ(priv, seq); + seq = MP_NEXT_RECV_SEQ(priv, seq); } /* If none found, exit */ @@ -1373,13 +1415,13 @@ ng_ppp_frag_checkstale(node_p node) ng_ppp_get_packet(node, &m, &meta); /* Bump MSEQ if necessary */ - if (MP_SEQ_DIFF(priv, priv->mseq, end->seq) < 0) { + if (MP_RECV_SEQ_DIFF(priv, priv->mseq, end->seq) < 0) { priv->mseq = end->seq; for (i = 0; i < priv->numActiveLinks; i++) { struct ng_ppp_link *const alink = &priv->links[priv->activeLinks[i]]; - if (MP_SEQ_DIFF(priv, + if (MP_RECV_SEQ_DIFF(priv, alink->seq, priv->mseq) < 0) alink->seq = priv->mseq; } @@ -1508,7 +1550,7 @@ deliver: shdr = priv->xseq; priv->xseq = - (priv->xseq + 1) % MP_SHORT_SEQ_MASK; + (priv->xseq + 1) & MP_SHORT_SEQ_MASK; if (firstFragment) shdr |= MP_SHORT_FIRST_FLAG; if (lastFragment) @@ -1520,7 +1562,7 @@ deliver: lhdr = priv->xseq; priv->xseq = - (priv->xseq + 1) % MP_LONG_SEQ_MASK; + (priv->xseq + 1) & MP_LONG_SEQ_MASK; if (firstFragment) lhdr |= MP_LONG_FIRST_FLAG; if (lastFragment) diff --git a/sys/netgraph/ng_ppp.h b/sys/netgraph/ng_ppp.h index ce05881..b75931e 100644 --- a/sys/netgraph/ng_ppp.h +++ b/sys/netgraph/ng_ppp.h @@ -34,7 +34,7 @@ * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * - * Author: Archie Cobbs <archie@whistle.com> + * Author: Archie Cobbs <archie@freebsd.org> * * $FreeBSD$ * $Whistle: ng_ppp.h,v 1.8 1999/01/25 02:40:02 archie Exp $ @@ -45,7 +45,7 @@ /* Node type name and magic cookie */ #define NG_PPP_NODE_TYPE "ppp" -#define NGM_PPP_COOKIE 940897794 +#define NGM_PPP_COOKIE 940897795 /* Maximum number of supported links */ #define NG_PPP_MAX_LINKS 16 @@ -78,11 +78,29 @@ enum { NGM_PPP_SET_CONFIG = 1, /* takes struct ng_ppp_node_conf */ NGM_PPP_GET_CONFIG, /* returns ng_ppp_node_conf */ + NGM_PPP_GET_MP_STATE, /* returns ng_ppp_mp_state */ NGM_PPP_GET_LINK_STATS, /* takes link #, returns stats struct */ NGM_PPP_CLR_LINK_STATS, /* takes link #, clears link stats */ NGM_PPP_GETCLR_LINK_STATS, /* takes link #, returns & clrs stats */ }; +/* Multi-link sequence number state (for debugging) */ +struct ng_ppp_mp_state { + int32_t rseq[NG_PPP_MAX_LINKS]; /* highest rec'd MP seq # */ + int32_t mseq; /* min rseq[i] */ + int32_t xseq; /* next xmit MP seq # */ +}; + +/* Keep this in sync with the above structure definition */ +#define NG_PPP_MP_STATE_TYPE_INFO(atype) { \ + { \ + { "rseq", (atype) }, \ + { "mseq", &ng_parse_hint32_type }, \ + { "xseq", &ng_parse_hint32_type }, \ + { NULL }, \ + } \ +} + /* Per-link config structure */ struct ng_ppp_link_conf { u_char enableLink; /* enable this link */ |