* Encapsulate the data packet in PIM Register message and send it to the RP. */
| 2463 | * Encapsulate the data packet in PIM Register message and send it to the RP. |
| 2464 | */ |
| 2465 | static int |
| 2466 | pim_register_send_rp(struct ip *ip, struct vif *vifp, struct mbuf *mb_copy, |
| 2467 | struct mfc *rt) |
| 2468 | { |
| 2469 | struct mbuf *mb_first; |
| 2470 | struct ip *ip_outer; |
| 2471 | struct pim_encap_pimhdr *pimhdr; |
| 2472 | int len = ntohs(ip->ip_len); |
| 2473 | vifi_t vifi = rt->mfc_parent; |
| 2474 | |
| 2475 | VIF_LOCK_ASSERT(); |
| 2476 | |
| 2477 | if ((vifi >= V_numvifs) || in_nullhost(V_viftable[vifi].v_lcl_addr)) { |
| 2478 | m_freem(mb_copy); |
| 2479 | return EADDRNOTAVAIL; /* The iif vif is invalid */ |
| 2480 | } |
| 2481 | |
| 2482 | /* |
| 2483 | * Add a new mbuf with the encapsulating header |
| 2484 | */ |
| 2485 | mb_first = m_gethdr(M_NOWAIT, MT_DATA); |
| 2486 | if (mb_first == NULL) { |
| 2487 | m_freem(mb_copy); |
| 2488 | return ENOBUFS; |
| 2489 | } |
| 2490 | mb_first->m_data += max_linkhdr; |
| 2491 | mb_first->m_len = sizeof(pim_encap_iphdr) + sizeof(pim_encap_pimhdr); |
| 2492 | mb_first->m_next = mb_copy; |
| 2493 | |
| 2494 | mb_first->m_pkthdr.len = len + mb_first->m_len; |
| 2495 | |
| 2496 | /* |
| 2497 | * Fill in the encapsulating IP and PIM header |
| 2498 | */ |
| 2499 | ip_outer = mtod(mb_first, struct ip *); |
| 2500 | *ip_outer = pim_encap_iphdr; |
| 2501 | ip_outer->ip_len = htons(len + sizeof(pim_encap_iphdr) + |
| 2502 | sizeof(pim_encap_pimhdr)); |
| 2503 | ip_outer->ip_src = V_viftable[vifi].v_lcl_addr; |
| 2504 | ip_outer->ip_dst = rt->mfc_rp; |
| 2505 | /* |
| 2506 | * Copy the inner header TOS to the outer header, and take care of the |
| 2507 | * IP_DF bit. |
| 2508 | */ |
| 2509 | ip_outer->ip_tos = ip->ip_tos; |
| 2510 | if (ip->ip_off & htons(IP_DF)) |
| 2511 | ip_outer->ip_off |= htons(IP_DF); |
| 2512 | ip_fillid(ip_outer); |
| 2513 | pimhdr = (struct pim_encap_pimhdr *)((caddr_t)ip_outer |
| 2514 | + sizeof(pim_encap_iphdr)); |
| 2515 | *pimhdr = pim_encap_pimhdr; |
| 2516 | /* If the iif crosses a border, set the Border-bit */ |
| 2517 | if (rt->mfc_flags[vifi] & MRT_MFC_FLAGS_BORDER_VIF & V_mrt_api_config) |
| 2518 | pimhdr->flags |= htonl(PIM_BORDER_REGISTER); |
| 2519 | |
| 2520 | mb_first->m_data += sizeof(pim_encap_iphdr); |
| 2521 | pimhdr->pim.pim_cksum = in_cksum(mb_first, sizeof(pim_encap_pimhdr)); |
| 2522 | mb_first->m_data -= sizeof(pim_encap_iphdr); |
no test coverage detected