| 278 | |
| 279 | #define MTAG_GIF 1080679712 |
| 280 | static int |
| 281 | gif_transmit(struct ifnet *ifp, struct mbuf *m) |
| 282 | { |
| 283 | struct gif_softc *sc; |
| 284 | struct etherip_header *eth; |
| 285 | #ifdef INET |
| 286 | struct ip *ip; |
| 287 | #endif |
| 288 | #ifdef INET6 |
| 289 | struct ip6_hdr *ip6; |
| 290 | uint32_t t; |
| 291 | #endif |
| 292 | uint32_t af; |
| 293 | uint8_t proto, ecn; |
| 294 | int error; |
| 295 | |
| 296 | NET_EPOCH_ASSERT(); |
| 297 | #ifdef MAC |
| 298 | error = mac_ifnet_check_transmit(ifp, m); |
| 299 | if (error) { |
| 300 | m_freem(m); |
| 301 | goto err; |
| 302 | } |
| 303 | #endif |
| 304 | error = ENETDOWN; |
| 305 | sc = ifp->if_softc; |
| 306 | if ((ifp->if_flags & IFF_MONITOR) != 0 || |
| 307 | (ifp->if_flags & IFF_UP) == 0 || |
| 308 | (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || |
| 309 | sc->gif_family == 0 || |
| 310 | (error = if_tunnel_check_nesting(ifp, m, MTAG_GIF, |
| 311 | V_max_gif_nesting)) != 0) { |
| 312 | m_freem(m); |
| 313 | goto err; |
| 314 | } |
| 315 | /* Now pull back the af that we stashed in the csum_data. */ |
| 316 | if (ifp->if_bridge) |
| 317 | af = AF_LINK; |
| 318 | else |
| 319 | af = m->m_pkthdr.csum_data; |
| 320 | m->m_flags &= ~(M_BCAST|M_MCAST); |
| 321 | M_SETFIB(m, sc->gif_fibnum); |
| 322 | BPF_MTAP2(ifp, &af, sizeof(af), m); |
| 323 | if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); |
| 324 | if_inc_counter(ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len); |
| 325 | /* inner AF-specific encapsulation */ |
| 326 | ecn = 0; |
| 327 | switch (af) { |
| 328 | #ifdef INET |
| 329 | case AF_INET: |
| 330 | proto = IPPROTO_IPV4; |
| 331 | if (m->m_len < sizeof(struct ip)) |
| 332 | m = m_pullup(m, sizeof(struct ip)); |
| 333 | if (m == NULL) { |
| 334 | error = ENOBUFS; |
| 335 | goto err; |
| 336 | } |
| 337 | ip = mtod(m, struct ip *); |
nothing calls this directly
no test coverage detected