* Same as above, but for IPv6. * Cut-and-pasted from ip6_input.c. * XXX Should we update ip6stat, or not? */
| 3507 | * XXX Should we update ip6stat, or not? |
| 3508 | */ |
| 3509 | static int |
| 3510 | bridge_ip6_checkbasic(struct mbuf **mp) |
| 3511 | { |
| 3512 | struct mbuf *m = *mp; |
| 3513 | struct ip6_hdr *ip6; |
| 3514 | |
| 3515 | /* |
| 3516 | * If the IPv6 header is not aligned, slurp it up into a new |
| 3517 | * mbuf with space for link headers, in the event we forward |
| 3518 | * it. Otherwise, if it is aligned, make sure the entire base |
| 3519 | * IPv6 header is in the first mbuf of the chain. |
| 3520 | */ |
| 3521 | if (IP6_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) { |
| 3522 | struct ifnet *inifp = m->m_pkthdr.rcvif; |
| 3523 | if ((m = m_copyup(m, sizeof(struct ip6_hdr), |
| 3524 | (max_linkhdr + 3) & ~3)) == NULL) { |
| 3525 | /* XXXJRT new stat, please */ |
| 3526 | IP6STAT_INC(ip6s_toosmall); |
| 3527 | in6_ifstat_inc(inifp, ifs6_in_hdrerr); |
| 3528 | goto bad; |
| 3529 | } |
| 3530 | } else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) { |
| 3531 | struct ifnet *inifp = m->m_pkthdr.rcvif; |
| 3532 | if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) { |
| 3533 | IP6STAT_INC(ip6s_toosmall); |
| 3534 | in6_ifstat_inc(inifp, ifs6_in_hdrerr); |
| 3535 | goto bad; |
| 3536 | } |
| 3537 | } |
| 3538 | |
| 3539 | ip6 = mtod(m, struct ip6_hdr *); |
| 3540 | |
| 3541 | if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { |
| 3542 | IP6STAT_INC(ip6s_badvers); |
| 3543 | in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); |
| 3544 | goto bad; |
| 3545 | } |
| 3546 | |
| 3547 | /* Checks out, proceed */ |
| 3548 | *mp = m; |
| 3549 | return (0); |
| 3550 | |
| 3551 | bad: |
| 3552 | *mp = m; |
| 3553 | return (-1); |
| 3554 | } |
| 3555 | #endif /* INET6 */ |
| 3556 | |
| 3557 | /* |
no test coverage detected