| 1316 | */ |
| 1317 | |
| 1318 | static int |
| 1319 | ng_ppp_link_xmit(node_p node, item_p item, uint16_t proto, uint16_t linkNum, int plen) |
| 1320 | { |
| 1321 | const priv_p priv = NG_NODE_PRIVATE(node); |
| 1322 | struct ng_ppp_link *link; |
| 1323 | int len, error; |
| 1324 | struct mbuf *m; |
| 1325 | uint16_t mru; |
| 1326 | |
| 1327 | /* Check if link correct. */ |
| 1328 | if (linkNum >= NG_PPP_MAX_LINKS) { |
| 1329 | ERROUT(ENETDOWN); |
| 1330 | } |
| 1331 | |
| 1332 | /* Get link pointer (optimization). */ |
| 1333 | link = &priv->links[linkNum]; |
| 1334 | |
| 1335 | /* Check link status (if real). */ |
| 1336 | if (link->hook == NULL) { |
| 1337 | ERROUT(ENETDOWN); |
| 1338 | } |
| 1339 | |
| 1340 | /* Extract mbuf. */ |
| 1341 | NGI_GET_M(item, m); |
| 1342 | |
| 1343 | /* Check peer's MRU for this link. */ |
| 1344 | mru = link->conf.mru; |
| 1345 | if (mru != 0 && m->m_pkthdr.len > mru) { |
| 1346 | NG_FREE_M(m); |
| 1347 | ERROUT(EMSGSIZE); |
| 1348 | } |
| 1349 | |
| 1350 | /* Prepend protocol number, possibly compressed. */ |
| 1351 | if ((m = ng_ppp_addproto(m, proto, link->conf.enableProtoComp)) == |
| 1352 | NULL) { |
| 1353 | ERROUT(ENOBUFS); |
| 1354 | } |
| 1355 | |
| 1356 | /* Prepend address and control field (unless compressed). */ |
| 1357 | if (proto == PROT_LCP || !link->conf.enableACFComp) { |
| 1358 | if ((m = ng_ppp_prepend(m, &ng_ppp_acf, 2)) == NULL) |
| 1359 | ERROUT(ENOBUFS); |
| 1360 | } |
| 1361 | |
| 1362 | /* Deliver frame. */ |
| 1363 | len = m->m_pkthdr.len; |
| 1364 | NG_FWD_NEW_DATA(error, item, link->hook, m); |
| 1365 | |
| 1366 | mtx_lock(&priv->xmtx); |
| 1367 | |
| 1368 | /* Update link stats. */ |
| 1369 | link->stats.xmitFrames++; |
| 1370 | link->stats.xmitOctets += len; |
| 1371 | |
| 1372 | /* Update bundle stats. */ |
| 1373 | if (plen > 0) { |
| 1374 | priv->bundleStats.xmitFrames++; |
| 1375 | priv->bundleStats.xmitOctets += plen; |
no test coverage detected