* bridge_fragment: * * Fragment mbuf chain in multiple packets and prepend ethernet header. */
| 3560 | * Fragment mbuf chain in multiple packets and prepend ethernet header. |
| 3561 | */ |
| 3562 | static int |
| 3563 | bridge_fragment(struct ifnet *ifp, struct mbuf **mp, struct ether_header *eh, |
| 3564 | int snap, struct llc *llc) |
| 3565 | { |
| 3566 | struct mbuf *m = *mp, *nextpkt = NULL, *mprev = NULL, *mcur = NULL; |
| 3567 | struct ip *ip; |
| 3568 | int error = -1; |
| 3569 | |
| 3570 | if (m->m_len < sizeof(struct ip) && |
| 3571 | (m = m_pullup(m, sizeof(struct ip))) == NULL) |
| 3572 | goto dropit; |
| 3573 | ip = mtod(m, struct ip *); |
| 3574 | |
| 3575 | m->m_pkthdr.csum_flags |= CSUM_IP; |
| 3576 | error = ip_fragment(ip, &m, ifp->if_mtu, ifp->if_hwassist); |
| 3577 | if (error) |
| 3578 | goto dropit; |
| 3579 | |
| 3580 | /* |
| 3581 | * Walk the chain and re-add the Ethernet header for |
| 3582 | * each mbuf packet. |
| 3583 | */ |
| 3584 | for (mcur = m; mcur; mcur = mcur->m_nextpkt) { |
| 3585 | nextpkt = mcur->m_nextpkt; |
| 3586 | mcur->m_nextpkt = NULL; |
| 3587 | if (snap) { |
| 3588 | M_PREPEND(mcur, sizeof(struct llc), M_NOWAIT); |
| 3589 | if (mcur == NULL) { |
| 3590 | error = ENOBUFS; |
| 3591 | if (mprev != NULL) |
| 3592 | mprev->m_nextpkt = nextpkt; |
| 3593 | goto dropit; |
| 3594 | } |
| 3595 | bcopy(llc, mtod(mcur, caddr_t),sizeof(struct llc)); |
| 3596 | } |
| 3597 | |
| 3598 | M_PREPEND(mcur, ETHER_HDR_LEN, M_NOWAIT); |
| 3599 | if (mcur == NULL) { |
| 3600 | error = ENOBUFS; |
| 3601 | if (mprev != NULL) |
| 3602 | mprev->m_nextpkt = nextpkt; |
| 3603 | goto dropit; |
| 3604 | } |
| 3605 | bcopy(eh, mtod(mcur, caddr_t), ETHER_HDR_LEN); |
| 3606 | |
| 3607 | /* |
| 3608 | * The previous two M_PREPEND could have inserted one or two |
| 3609 | * mbufs in front so we have to update the previous packet's |
| 3610 | * m_nextpkt. |
| 3611 | */ |
| 3612 | mcur->m_nextpkt = nextpkt; |
| 3613 | if (mprev != NULL) |
| 3614 | mprev->m_nextpkt = mcur; |
| 3615 | else { |
| 3616 | /* The first mbuf in the original chain needs to be |
| 3617 | * updated. */ |
| 3618 | *mp = mcur; |
| 3619 | } |
no test coverage detected