* Packet forwarding routine once entry in the cache is made */
| 1486 | * Packet forwarding routine once entry in the cache is made |
| 1487 | */ |
| 1488 | static int |
| 1489 | ip_mdq(struct mbuf *m, struct ifnet *ifp, struct mfc *rt, vifi_t xmt_vif) |
| 1490 | { |
| 1491 | struct ip *ip = mtod(m, struct ip *); |
| 1492 | vifi_t vifi; |
| 1493 | int plen = ntohs(ip->ip_len); |
| 1494 | |
| 1495 | VIF_LOCK_ASSERT(); |
| 1496 | |
| 1497 | /* |
| 1498 | * If xmt_vif is not -1, send on only the requested vif. |
| 1499 | * |
| 1500 | * (since vifi_t is u_short, -1 becomes MAXUSHORT, which > numvifs.) |
| 1501 | */ |
| 1502 | if (xmt_vif < V_numvifs) { |
| 1503 | if (V_viftable[xmt_vif].v_flags & VIFF_REGISTER) |
| 1504 | pim_register_send(ip, V_viftable + xmt_vif, m, rt); |
| 1505 | else |
| 1506 | phyint_send(ip, V_viftable + xmt_vif, m); |
| 1507 | return 1; |
| 1508 | } |
| 1509 | |
| 1510 | /* |
| 1511 | * Don't forward if it didn't arrive from the parent vif for its origin. |
| 1512 | */ |
| 1513 | vifi = rt->mfc_parent; |
| 1514 | if ((vifi >= V_numvifs) || (V_viftable[vifi].v_ifp != ifp)) { |
| 1515 | CTR4(KTR_IPMF, "%s: rx on wrong ifp %p (vifi %d, v_ifp %p)", |
| 1516 | __func__, ifp, (int)vifi, V_viftable[vifi].v_ifp); |
| 1517 | MRTSTAT_INC(mrts_wrong_if); |
| 1518 | ++rt->mfc_wrong_if; |
| 1519 | /* |
| 1520 | * If we are doing PIM assert processing, send a message |
| 1521 | * to the routing daemon. |
| 1522 | * |
| 1523 | * XXX: A PIM-SM router needs the WRONGVIF detection so it |
| 1524 | * can complete the SPT switch, regardless of the type |
| 1525 | * of the iif (broadcast media, GRE tunnel, etc). |
| 1526 | */ |
| 1527 | if (V_pim_assert_enabled && (vifi < V_numvifs) && |
| 1528 | V_viftable[vifi].v_ifp) { |
| 1529 | if (ifp == &V_multicast_register_if) |
| 1530 | PIMSTAT_INC(pims_rcv_registers_wrongiif); |
| 1531 | |
| 1532 | /* Get vifi for the incoming packet */ |
| 1533 | for (vifi = 0; vifi < V_numvifs && V_viftable[vifi].v_ifp != ifp; |
| 1534 | vifi++) |
| 1535 | ; |
| 1536 | if (vifi >= V_numvifs) |
| 1537 | return 0; /* The iif is not found: ignore the packet. */ |
| 1538 | |
| 1539 | if (rt->mfc_flags[vifi] & MRT_MFC_FLAGS_DISABLE_WRONGVIF) |
| 1540 | return 0; /* WRONGVIF disabled: ignore the packet */ |
| 1541 | |
| 1542 | if (ratecheck(&rt->mfc_last_assert, &pim_assert_interval)) { |
| 1543 | struct sockaddr_in k_igmpsrc = { sizeof k_igmpsrc, AF_INET }; |
| 1544 | struct igmpmsg *im; |
| 1545 | int hlen = ip->ip_hl << 2; |
no test coverage detected