* Send an upcall with the data packet to the user-level process. */
| 2411 | * Send an upcall with the data packet to the user-level process. |
| 2412 | */ |
| 2413 | static int |
| 2414 | pim_register_send_upcall(struct ip *ip, struct vif *vifp, |
| 2415 | struct mbuf *mb_copy, struct mfc *rt) |
| 2416 | { |
| 2417 | struct mbuf *mb_first; |
| 2418 | int len = ntohs(ip->ip_len); |
| 2419 | struct igmpmsg *im; |
| 2420 | struct sockaddr_in k_igmpsrc = { sizeof k_igmpsrc, AF_INET }; |
| 2421 | |
| 2422 | VIF_LOCK_ASSERT(); |
| 2423 | |
| 2424 | /* |
| 2425 | * Add a new mbuf with an upcall header |
| 2426 | */ |
| 2427 | mb_first = m_gethdr(M_NOWAIT, MT_DATA); |
| 2428 | if (mb_first == NULL) { |
| 2429 | m_freem(mb_copy); |
| 2430 | return ENOBUFS; |
| 2431 | } |
| 2432 | mb_first->m_data += max_linkhdr; |
| 2433 | mb_first->m_pkthdr.len = len + sizeof(struct igmpmsg); |
| 2434 | mb_first->m_len = sizeof(struct igmpmsg); |
| 2435 | mb_first->m_next = mb_copy; |
| 2436 | |
| 2437 | /* Send message to routing daemon */ |
| 2438 | im = mtod(mb_first, struct igmpmsg *); |
| 2439 | im->im_msgtype = IGMPMSG_WHOLEPKT; |
| 2440 | im->im_mbz = 0; |
| 2441 | im->im_vif = vifp - V_viftable; |
| 2442 | im->im_src = ip->ip_src; |
| 2443 | im->im_dst = ip->ip_dst; |
| 2444 | |
| 2445 | k_igmpsrc.sin_addr = ip->ip_src; |
| 2446 | |
| 2447 | MRTSTAT_INC(mrts_upcalls); |
| 2448 | |
| 2449 | if (socket_send(V_ip_mrouter, mb_first, &k_igmpsrc) < 0) { |
| 2450 | CTR1(KTR_IPMF, "%s: socket queue full", __func__); |
| 2451 | MRTSTAT_INC(mrts_upq_sockfull); |
| 2452 | return ENOBUFS; |
| 2453 | } |
| 2454 | |
| 2455 | /* Keep statistics */ |
| 2456 | PIMSTAT_INC(pims_snd_registers_msgs); |
| 2457 | PIMSTAT_ADD(pims_snd_registers_bytes, len); |
| 2458 | |
| 2459 | return 0; |
| 2460 | } |
| 2461 | |
| 2462 | /* |
| 2463 | * Encapsulate the data packet in PIM Register message and send it to the RP. |
no test coverage detected