MCPcopy Create free account
hub / github.com/F-Stack/f-stack / mld_input

Function mld_input

freebsd/netinet6/mld6.c:1251–1323  ·  view source on GitHub ↗

* MLD input path. * * Assume query messages which fit in a single ICMPv6 message header * have been pulled up. * Assume that userland will want to see the message, even if it * otherwise fails kernel input validation; do not free it. * Pullup may however free the mbuf chain m if it fails. * * Return IPPROTO_DONE if we freed m. Otherwise, return 0. */

Source from the content-addressed store, hash-verified

1249 * Return IPPROTO_DONE if we freed m. Otherwise, return 0.
1250 */
1251int
1252mld_input(struct mbuf **mp, int off, int icmp6len)
1253{
1254 struct ifnet *ifp;
1255 struct ip6_hdr *ip6;
1256 struct mbuf *m;
1257 struct mld_hdr *mld;
1258 int mldlen;
1259
1260 m = *mp;
1261 CTR3(KTR_MLD, "%s: called w/mbuf (%p,%d)", __func__, m, off);
1262
1263 ifp = m->m_pkthdr.rcvif;
1264
1265 /* Pullup to appropriate size. */
1266 if (m->m_len < off + sizeof(*mld)) {
1267 m = m_pullup(m, off + sizeof(*mld));
1268 if (m == NULL) {
1269 ICMP6STAT_INC(icp6s_badlen);
1270 return (IPPROTO_DONE);
1271 }
1272 }
1273 mld = (struct mld_hdr *)(mtod(m, uint8_t *) + off);
1274 if (mld->mld_type == MLD_LISTENER_QUERY &&
1275 icmp6len >= sizeof(struct mldv2_query)) {
1276 mldlen = sizeof(struct mldv2_query);
1277 } else {
1278 mldlen = sizeof(struct mld_hdr);
1279 }
1280 if (m->m_len < off + mldlen) {
1281 m = m_pullup(m, off + mldlen);
1282 if (m == NULL) {
1283 ICMP6STAT_INC(icp6s_badlen);
1284 return (IPPROTO_DONE);
1285 }
1286 }
1287 *mp = m;
1288 ip6 = mtod(m, struct ip6_hdr *);
1289 mld = (struct mld_hdr *)(mtod(m, uint8_t *) + off);
1290
1291 /*
1292 * Userland needs to see all of this traffic for implementing
1293 * the endpoint discovery portion of multicast routing.
1294 */
1295 switch (mld->mld_type) {
1296 case MLD_LISTENER_QUERY:
1297 icmp6_ifstat_inc(ifp, ifs6_in_mldquery);
1298 if (icmp6len == sizeof(struct mld_hdr)) {
1299 if (mld_v1_input_query(ifp, ip6, mld) != 0)
1300 return (0);
1301 } else if (icmp6len >= sizeof(struct mldv2_query)) {
1302 if (mld_v2_input_query(ifp, ip6, m,
1303 (struct mldv2_query *)mld, off, icmp6len) != 0)
1304 return (0);
1305 }
1306 break;
1307 case MLD_LISTENER_REPORT:
1308 icmp6_ifstat_inc(ifp, ifs6_in_mldreport);

Callers 1

icmp6_inputFunction · 0.85

Calls 4

m_pullupFunction · 0.85
mld_v1_input_queryFunction · 0.85
mld_v2_input_queryFunction · 0.85
mld_v1_input_reportFunction · 0.85

Tested by

no test coverage detected