* Deliver a frame out on the bundle, i.e., figure out how to fragment * the frame across the individual PPP links and do so. */
| 1986 | * the frame across the individual PPP links and do so. |
| 1987 | */ |
| 1988 | static int |
| 1989 | ng_ppp_mp_xmit(node_p node, item_p item, uint16_t proto) |
| 1990 | { |
| 1991 | const priv_p priv = NG_NODE_PRIVATE(node); |
| 1992 | const int hdr_len = priv->conf.xmitShortSeq ? 2 : 4; |
| 1993 | int distrib[NG_PPP_MAX_LINKS]; |
| 1994 | int firstFragment; |
| 1995 | int activeLinkNum; |
| 1996 | struct mbuf *m; |
| 1997 | int plen; |
| 1998 | int frags; |
| 1999 | int32_t seq; |
| 2000 | |
| 2001 | /* At least one link must be active */ |
| 2002 | if (priv->numActiveLinks == 0) { |
| 2003 | NG_FREE_ITEM(item); |
| 2004 | return (ENETDOWN); |
| 2005 | } |
| 2006 | |
| 2007 | /* Save length for later stats. */ |
| 2008 | plen = NGI_M(item)->m_pkthdr.len; |
| 2009 | |
| 2010 | if (!priv->conf.enableMultilink) { |
| 2011 | return (ng_ppp_link_xmit(node, item, proto, |
| 2012 | priv->activeLinks[0], plen)); |
| 2013 | } |
| 2014 | |
| 2015 | /* Check peer's MRRU for this bundle. */ |
| 2016 | if (plen > priv->conf.mrru) { |
| 2017 | NG_FREE_ITEM(item); |
| 2018 | return (EMSGSIZE); |
| 2019 | } |
| 2020 | |
| 2021 | /* Extract mbuf. */ |
| 2022 | NGI_GET_M(item, m); |
| 2023 | |
| 2024 | /* Prepend protocol number, possibly compressed. */ |
| 2025 | if ((m = ng_ppp_addproto(m, proto, 1)) == NULL) { |
| 2026 | NG_FREE_ITEM(item); |
| 2027 | return (ENOBUFS); |
| 2028 | } |
| 2029 | |
| 2030 | /* Clear distribution plan */ |
| 2031 | bzero(&distrib, priv->numActiveLinks * sizeof(distrib[0])); |
| 2032 | |
| 2033 | mtx_lock(&priv->xmtx); |
| 2034 | |
| 2035 | /* Round-robin strategy */ |
| 2036 | if (priv->conf.enableRoundRobin) { |
| 2037 | activeLinkNum = priv->lastLink++ % priv->numActiveLinks; |
| 2038 | distrib[activeLinkNum] = m->m_pkthdr.len; |
| 2039 | goto deliver; |
| 2040 | } |
| 2041 | |
| 2042 | /* Strategy when all links are equivalent (optimize the common case) */ |
| 2043 | if (priv->allLinksEqual) { |
| 2044 | int numFrags, fraction, remain; |
| 2045 | int i; |
no test coverage detected