| 2747 | } |
| 2748 | |
| 2749 | static void |
| 2750 | vxlan_rcv_udp_packet(struct mbuf *m, int offset, struct inpcb *inpcb, |
| 2751 | const struct sockaddr *srcsa, void *xvso) |
| 2752 | { |
| 2753 | struct vxlan_socket *vso; |
| 2754 | struct vxlan_header *vxh, vxlanhdr; |
| 2755 | uint32_t vni; |
| 2756 | int error __unused; |
| 2757 | |
| 2758 | M_ASSERTPKTHDR(m); |
| 2759 | vso = xvso; |
| 2760 | offset += sizeof(struct udphdr); |
| 2761 | |
| 2762 | if (m->m_pkthdr.len < offset + sizeof(struct vxlan_header)) |
| 2763 | goto out; |
| 2764 | |
| 2765 | if (__predict_false(m->m_len < offset + sizeof(struct vxlan_header))) { |
| 2766 | m_copydata(m, offset, sizeof(struct vxlan_header), |
| 2767 | (caddr_t) &vxlanhdr); |
| 2768 | vxh = &vxlanhdr; |
| 2769 | } else |
| 2770 | vxh = mtodo(m, offset); |
| 2771 | |
| 2772 | /* |
| 2773 | * Drop if there is a reserved bit set in either the flags or VNI |
| 2774 | * fields of the header. This goes against the specification, but |
| 2775 | * a bit set may indicate an unsupported new feature. This matches |
| 2776 | * the behavior of the Linux implementation. |
| 2777 | */ |
| 2778 | if (vxh->vxlh_flags != htonl(VXLAN_HDR_FLAGS_VALID_VNI) || |
| 2779 | vxh->vxlh_vni & ~VXLAN_VNI_MASK) |
| 2780 | goto out; |
| 2781 | |
| 2782 | vni = ntohl(vxh->vxlh_vni) >> VXLAN_HDR_VNI_SHIFT; |
| 2783 | /* Adjust to the start of the inner Ethernet frame. */ |
| 2784 | m_adj(m, offset + sizeof(struct vxlan_header)); |
| 2785 | |
| 2786 | error = vxlan_input(vso, vni, &m, srcsa); |
| 2787 | MPASS(error != 0 || m == NULL); |
| 2788 | |
| 2789 | out: |
| 2790 | if (m != NULL) |
| 2791 | m_freem(m); |
| 2792 | } |
| 2793 | |
| 2794 | static int |
| 2795 | vxlan_input(struct vxlan_socket *vso, uint32_t vni, struct mbuf **m0, |
nothing calls this directly
no test coverage detected