* Process a received MLDv2 general, group-specific or * group-and-source-specific query. * * Assumes that mld points to a struct mldv2_query which is stored in * contiguous memory. * * Return 0 if successful, otherwise an appropriate error code is returned. */
| 811 | * Return 0 if successful, otherwise an appropriate error code is returned. |
| 812 | */ |
| 813 | static int |
| 814 | mld_v2_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6, |
| 815 | struct mbuf *m, struct mldv2_query *mld, const int off, const int icmp6len) |
| 816 | { |
| 817 | struct mld_ifsoftc *mli; |
| 818 | struct in6_multi *inm; |
| 819 | uint32_t maxdelay, nsrc, qqi; |
| 820 | int is_general_query; |
| 821 | uint16_t timer; |
| 822 | uint8_t qrv; |
| 823 | #ifdef KTR |
| 824 | char ip6tbuf[INET6_ADDRSTRLEN]; |
| 825 | #endif |
| 826 | |
| 827 | NET_EPOCH_ASSERT(); |
| 828 | |
| 829 | if (!mld_v2enable) { |
| 830 | CTR3(KTR_MLD, "ignore v2 query src %s on ifp %p(%s)", |
| 831 | ip6_sprintf(ip6tbuf, &ip6->ip6_src), |
| 832 | ifp, if_name(ifp)); |
| 833 | return (0); |
| 834 | } |
| 835 | |
| 836 | /* |
| 837 | * RFC3810 Section 6.2: MLD queries must originate from |
| 838 | * a router's link-local address. |
| 839 | */ |
| 840 | if (!IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) { |
| 841 | CTR3(KTR_MLD, "ignore v1 query src %s on ifp %p(%s)", |
| 842 | ip6_sprintf(ip6tbuf, &ip6->ip6_src), |
| 843 | ifp, if_name(ifp)); |
| 844 | return (0); |
| 845 | } |
| 846 | |
| 847 | is_general_query = 0; |
| 848 | |
| 849 | CTR2(KTR_MLD, "input v2 query on ifp %p(%s)", ifp, if_name(ifp)); |
| 850 | |
| 851 | maxdelay = ntohs(mld->mld_maxdelay); /* in 1/10ths of a second */ |
| 852 | if (maxdelay >= 32768) { |
| 853 | maxdelay = (MLD_MRC_MANT(maxdelay) | 0x1000) << |
| 854 | (MLD_MRC_EXP(maxdelay) + 3); |
| 855 | } |
| 856 | timer = (maxdelay * PR_FASTHZ) / MLD_TIMER_SCALE; |
| 857 | if (timer == 0) |
| 858 | timer = 1; |
| 859 | |
| 860 | qrv = MLD_QRV(mld->mld_misc); |
| 861 | if (qrv < 2) { |
| 862 | CTR3(KTR_MLD, "%s: clamping qrv %d to %d", __func__, |
| 863 | qrv, MLD_RV_INIT); |
| 864 | qrv = MLD_RV_INIT; |
| 865 | } |
| 866 | |
| 867 | qqi = mld->mld_qqi; |
| 868 | if (qqi >= 128) { |
| 869 | qqi = MLD_QQIC_MANT(mld->mld_qqi) << |
| 870 | (MLD_QQIC_EXP(mld->mld_qqi) + 3); |
no test coverage detected