| 2574 | } |
| 2575 | |
| 2576 | static int |
| 2577 | vxlan_encap6(struct vxlan_softc *sc, const union vxlan_sockaddr *fvxlsa, |
| 2578 | struct mbuf *m) |
| 2579 | { |
| 2580 | #ifdef INET6 |
| 2581 | struct ifnet *ifp; |
| 2582 | struct ip6_hdr *ip6; |
| 2583 | const struct in6_addr *srcaddr, *dstaddr; |
| 2584 | uint16_t srcport, dstport; |
| 2585 | int len, mcast, error; |
| 2586 | struct route_in6 route, *ro; |
| 2587 | struct sockaddr_in6 *sin6; |
| 2588 | uint32_t csum_flags; |
| 2589 | |
| 2590 | NET_EPOCH_ASSERT(); |
| 2591 | |
| 2592 | ifp = sc->vxl_ifp; |
| 2593 | srcaddr = &sc->vxl_src_addr.in6.sin6_addr; |
| 2594 | srcport = vxlan_pick_source_port(sc, m); |
| 2595 | dstaddr = &fvxlsa->in6.sin6_addr; |
| 2596 | dstport = fvxlsa->in6.sin6_port; |
| 2597 | |
| 2598 | M_PREPEND(m, sizeof(struct ip6_hdr) + sizeof(struct vxlanudphdr), |
| 2599 | M_NOWAIT); |
| 2600 | if (m == NULL) { |
| 2601 | if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); |
| 2602 | return (ENOBUFS); |
| 2603 | } |
| 2604 | |
| 2605 | len = m->m_pkthdr.len; |
| 2606 | |
| 2607 | ip6 = mtod(m, struct ip6_hdr *); |
| 2608 | ip6->ip6_flow = 0; /* BMV: Keep in forwarding entry? */ |
| 2609 | ip6->ip6_vfc = IPV6_VERSION; |
| 2610 | ip6->ip6_plen = 0; |
| 2611 | ip6->ip6_nxt = IPPROTO_UDP; |
| 2612 | ip6->ip6_hlim = sc->vxl_ttl; |
| 2613 | ip6->ip6_src = *srcaddr; |
| 2614 | ip6->ip6_dst = *dstaddr; |
| 2615 | |
| 2616 | vxlan_encap_header(sc, m, sizeof(struct ip6_hdr), srcport, dstport); |
| 2617 | |
| 2618 | mcast = (m->m_flags & (M_MCAST | M_BCAST)) ? 1 : 0; |
| 2619 | m->m_flags &= ~(M_MCAST | M_BCAST); |
| 2620 | |
| 2621 | ro = NULL; |
| 2622 | m->m_pkthdr.csum_flags &= CSUM_FLAGS_TX; |
| 2623 | if (m->m_pkthdr.csum_flags != 0) { |
| 2624 | /* |
| 2625 | * HW checksum (L3 and/or L4) or TSO has been requested. Look |
| 2626 | * up the ifnet for the outbound route and verify that the |
| 2627 | * outbound ifnet can perform the requested operation on the |
| 2628 | * inner frame. |
| 2629 | */ |
| 2630 | bzero(&route, sizeof(route)); |
| 2631 | ro = &route; |
| 2632 | sin6 = (struct sockaddr_in6 *)&ro->ro_dst; |
| 2633 | sin6->sin6_family = AF_INET6; |
no test coverage detected