in_mcast.c (9b7501e7977c1f4a0a4a798cdf0af64846009df8) | in_mcast.c (c8ee75f2315e8267ad814dc5b4645ef205f0e0e1) |
---|---|
1/*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 2007-2009 Bruce Simpson. 5 * Copyright (c) 2005 Robert N. M. Watson. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 30 unchanged lines hidden (view full) --- 39 40#include <sys/param.h> 41#include <sys/systm.h> 42#include <sys/kernel.h> 43#include <sys/lock.h> 44#include <sys/malloc.h> 45#include <sys/mbuf.h> 46#include <sys/protosw.h> | 1/*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 2007-2009 Bruce Simpson. 5 * Copyright (c) 2005 Robert N. M. Watson. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 30 unchanged lines hidden (view full) --- 39 40#include <sys/param.h> 41#include <sys/systm.h> 42#include <sys/kernel.h> 43#include <sys/lock.h> 44#include <sys/malloc.h> 45#include <sys/mbuf.h> 46#include <sys/protosw.h> |
47#include <sys/rmlock.h> | |
48#include <sys/socket.h> 49#include <sys/socketvar.h> 50#include <sys/protosw.h> 51#include <sys/sysctl.h> 52#include <sys/ktr.h> 53#include <sys/taskqueue.h> 54#include <sys/tree.h> 55 --- 1317 unchanged lines hidden (view full) --- 1373 * SMPng: NOTE: Must take Giant as a join may create a new ifma. 1374 * 1375 * Return 0 if successful, otherwise return an appropriate error code. 1376 */ 1377static int 1378inp_block_unblock_source(struct inpcb *inp, struct sockopt *sopt) 1379{ 1380 struct group_source_req gsr; | 47#include <sys/socket.h> 48#include <sys/socketvar.h> 49#include <sys/protosw.h> 50#include <sys/sysctl.h> 51#include <sys/ktr.h> 52#include <sys/taskqueue.h> 53#include <sys/tree.h> 54 --- 1317 unchanged lines hidden (view full) --- 1372 * SMPng: NOTE: Must take Giant as a join may create a new ifma. 1373 * 1374 * Return 0 if successful, otherwise return an appropriate error code. 1375 */ 1376static int 1377inp_block_unblock_source(struct inpcb *inp, struct sockopt *sopt) 1378{ 1379 struct group_source_req gsr; |
1381 struct rm_priotracker in_ifa_tracker; | |
1382 sockunion_t *gsa, *ssa; 1383 struct ifnet *ifp; 1384 struct in_mfilter *imf; 1385 struct ip_moptions *imo; 1386 struct in_msource *ims; 1387 struct in_multi *inm; 1388 uint16_t fmode; 1389 int error, doblock; --- 21 unchanged lines hidden (view full) --- 1411 gsa->sin.sin_len = sizeof(struct sockaddr_in); 1412 gsa->sin.sin_addr = mreqs.imr_multiaddr; 1413 1414 ssa->sin.sin_family = AF_INET; 1415 ssa->sin.sin_len = sizeof(struct sockaddr_in); 1416 ssa->sin.sin_addr = mreqs.imr_sourceaddr; 1417 1418 if (!in_nullhost(mreqs.imr_interface)) { | 1380 sockunion_t *gsa, *ssa; 1381 struct ifnet *ifp; 1382 struct in_mfilter *imf; 1383 struct ip_moptions *imo; 1384 struct in_msource *ims; 1385 struct in_multi *inm; 1386 uint16_t fmode; 1387 int error, doblock; --- 21 unchanged lines hidden (view full) --- 1409 gsa->sin.sin_len = sizeof(struct sockaddr_in); 1410 gsa->sin.sin_addr = mreqs.imr_multiaddr; 1411 1412 ssa->sin.sin_family = AF_INET; 1413 ssa->sin.sin_len = sizeof(struct sockaddr_in); 1414 ssa->sin.sin_addr = mreqs.imr_sourceaddr; 1415 1416 if (!in_nullhost(mreqs.imr_interface)) { |
1419 IN_IFADDR_RLOCK(&in_ifa_tracker); | 1417 struct epoch_tracker et; 1418 1419 NET_EPOCH_ENTER(et); |
1420 INADDR_TO_IFP(mreqs.imr_interface, ifp); | 1420 INADDR_TO_IFP(mreqs.imr_interface, ifp); |
1421 IN_IFADDR_RUNLOCK(&in_ifa_tracker); | 1421 /* XXXGL: ifref? */ 1422 NET_EPOCH_EXIT(et); |
1422 } 1423 if (sopt->sopt_name == IP_BLOCK_SOURCE) 1424 doblock = 1; 1425 1426 CTR3(KTR_IGMPV3, "%s: imr_interface = 0x%08x, ifp = %p", 1427 __func__, ntohl(mreqs.imr_interface.s_addr), ifp); 1428 break; 1429 } --- 436 unchanged lines hidden (view full) --- 1866 * Returns NULL if no ifp could be found, otherwise return referenced ifp. 1867 * 1868 * FUTURE: Implement IPv4 source-address selection. 1869 */ 1870static struct ifnet * 1871inp_lookup_mcast_ifp(const struct inpcb *inp, 1872 const struct sockaddr_in *gsin, const struct in_addr ina) 1873{ | 1423 } 1424 if (sopt->sopt_name == IP_BLOCK_SOURCE) 1425 doblock = 1; 1426 1427 CTR3(KTR_IGMPV3, "%s: imr_interface = 0x%08x, ifp = %p", 1428 __func__, ntohl(mreqs.imr_interface.s_addr), ifp); 1429 break; 1430 } --- 436 unchanged lines hidden (view full) --- 1867 * Returns NULL if no ifp could be found, otherwise return referenced ifp. 1868 * 1869 * FUTURE: Implement IPv4 source-address selection. 1870 */ 1871static struct ifnet * 1872inp_lookup_mcast_ifp(const struct inpcb *inp, 1873 const struct sockaddr_in *gsin, const struct in_addr ina) 1874{ |
1874 struct rm_priotracker in_ifa_tracker; | |
1875 struct ifnet *ifp; 1876 struct nhop_object *nh; 1877 1878 NET_EPOCH_ASSERT(); 1879 KASSERT(inp != NULL, ("%s: inp must not be NULL", __func__)); 1880 KASSERT(gsin->sin_family == AF_INET, ("%s: not AF_INET", __func__)); 1881 KASSERT(IN_MULTICAST(ntohl(gsin->sin_addr.s_addr)), 1882 ("%s: not multicast", __func__)); 1883 1884 ifp = NULL; 1885 if (!in_nullhost(ina)) { | 1875 struct ifnet *ifp; 1876 struct nhop_object *nh; 1877 1878 NET_EPOCH_ASSERT(); 1879 KASSERT(inp != NULL, ("%s: inp must not be NULL", __func__)); 1880 KASSERT(gsin->sin_family == AF_INET, ("%s: not AF_INET", __func__)); 1881 KASSERT(IN_MULTICAST(ntohl(gsin->sin_addr.s_addr)), 1882 ("%s: not multicast", __func__)); 1883 1884 ifp = NULL; 1885 if (!in_nullhost(ina)) { |
1886 IN_IFADDR_RLOCK(&in_ifa_tracker); | |
1887 INADDR_TO_IFP(ina, ifp); 1888 if (ifp != NULL) 1889 if_ref(ifp); | 1886 INADDR_TO_IFP(ina, ifp); 1887 if (ifp != NULL) 1888 if_ref(ifp); |
1890 IN_IFADDR_RUNLOCK(&in_ifa_tracker); | |
1891 } else { 1892 nh = fib4_lookup(inp->inp_inc.inc_fibnum, gsin->sin_addr, 0, NHR_NONE, 0); 1893 if (nh != NULL) { 1894 ifp = nh->nh_ifp; 1895 if_ref(ifp); 1896 } else { 1897 struct in_ifaddr *ia; 1898 struct ifnet *mifp; --- 343 unchanged lines hidden (view full) --- 2242/* 2243 * Leave an IPv4 multicast group on an inpcb, possibly with a source. 2244 */ 2245static int 2246inp_leave_group(struct inpcb *inp, struct sockopt *sopt) 2247{ 2248 struct group_source_req gsr; 2249 struct ip_mreq_source mreqs; | 1889 } else { 1890 nh = fib4_lookup(inp->inp_inc.inc_fibnum, gsin->sin_addr, 0, NHR_NONE, 0); 1891 if (nh != NULL) { 1892 ifp = nh->nh_ifp; 1893 if_ref(ifp); 1894 } else { 1895 struct in_ifaddr *ia; 1896 struct ifnet *mifp; --- 343 unchanged lines hidden (view full) --- 2240/* 2241 * Leave an IPv4 multicast group on an inpcb, possibly with a source. 2242 */ 2243static int 2244inp_leave_group(struct inpcb *inp, struct sockopt *sopt) 2245{ 2246 struct group_source_req gsr; 2247 struct ip_mreq_source mreqs; |
2250 struct rm_priotracker in_ifa_tracker; | |
2251 sockunion_t *gsa, *ssa; 2252 struct ifnet *ifp; 2253 struct in_mfilter *imf; 2254 struct ip_moptions *imo; 2255 struct in_msource *ims; 2256 struct in_multi *inm; 2257 int error; 2258 bool is_final; --- 43 unchanged lines hidden (view full) --- 2302 /* 2303 * Attempt to look up hinted ifp from interface address. 2304 * Fallthrough with null ifp iff lookup fails, to 2305 * preserve 4.4BSD mcast API idempotence. 2306 * XXX NOTE WELL: The RFC 3678 API is preferred because 2307 * using an IPv4 address as a key is racy. 2308 */ 2309 if (!in_nullhost(mreqs.imr_interface)) { | 2248 sockunion_t *gsa, *ssa; 2249 struct ifnet *ifp; 2250 struct in_mfilter *imf; 2251 struct ip_moptions *imo; 2252 struct in_msource *ims; 2253 struct in_multi *inm; 2254 int error; 2255 bool is_final; --- 43 unchanged lines hidden (view full) --- 2299 /* 2300 * Attempt to look up hinted ifp from interface address. 2301 * Fallthrough with null ifp iff lookup fails, to 2302 * preserve 4.4BSD mcast API idempotence. 2303 * XXX NOTE WELL: The RFC 3678 API is preferred because 2304 * using an IPv4 address as a key is racy. 2305 */ 2306 if (!in_nullhost(mreqs.imr_interface)) { |
2310 IN_IFADDR_RLOCK(&in_ifa_tracker); | 2307 struct epoch_tracker et; 2308 2309 NET_EPOCH_ENTER(et); |
2311 INADDR_TO_IFP(mreqs.imr_interface, ifp); | 2310 INADDR_TO_IFP(mreqs.imr_interface, ifp); |
2312 IN_IFADDR_RUNLOCK(&in_ifa_tracker); | 2311 /* XXXGL ifref? */ 2312 NET_EPOCH_EXIT(et); |
2313 } 2314 CTR3(KTR_IGMPV3, "%s: imr_interface = 0x%08x, ifp = %p", 2315 __func__, ntohl(mreqs.imr_interface.s_addr), ifp); 2316 2317 break; 2318 2319 case MCAST_LEAVE_GROUP: 2320 case MCAST_LEAVE_SOURCE_GROUP: --- 139 unchanged lines hidden (view full) --- 2460 * Either an instance of struct in_addr or an instance of struct ip_mreqn 2461 * may be passed to this socket option. An address of INADDR_ANY or an 2462 * interface index of 0 is used to remove a previous selection. 2463 * When no interface is selected, one is chosen for every send. 2464 */ 2465static int 2466inp_set_multicast_if(struct inpcb *inp, struct sockopt *sopt) 2467{ | 2313 } 2314 CTR3(KTR_IGMPV3, "%s: imr_interface = 0x%08x, ifp = %p", 2315 __func__, ntohl(mreqs.imr_interface.s_addr), ifp); 2316 2317 break; 2318 2319 case MCAST_LEAVE_GROUP: 2320 case MCAST_LEAVE_SOURCE_GROUP: --- 139 unchanged lines hidden (view full) --- 2460 * Either an instance of struct in_addr or an instance of struct ip_mreqn 2461 * may be passed to this socket option. An address of INADDR_ANY or an 2462 * interface index of 0 is used to remove a previous selection. 2463 * When no interface is selected, one is chosen for every send. 2464 */ 2465static int 2466inp_set_multicast_if(struct inpcb *inp, struct sockopt *sopt) 2467{ |
2468 struct rm_priotracker in_ifa_tracker; | |
2469 struct in_addr addr; 2470 struct ip_mreqn mreqn; 2471 struct ifnet *ifp; 2472 struct ip_moptions *imo; 2473 int error; 2474 2475 if (sopt->sopt_valsize == sizeof(struct ip_mreqn)) { 2476 /* --- 22 unchanged lines hidden (view full) --- 2499 */ 2500 error = sooptcopyin(sopt, &addr, sizeof(struct in_addr), 2501 sizeof(struct in_addr)); 2502 if (error) 2503 return (error); 2504 if (in_nullhost(addr)) { 2505 ifp = NULL; 2506 } else { | 2468 struct in_addr addr; 2469 struct ip_mreqn mreqn; 2470 struct ifnet *ifp; 2471 struct ip_moptions *imo; 2472 int error; 2473 2474 if (sopt->sopt_valsize == sizeof(struct ip_mreqn)) { 2475 /* --- 22 unchanged lines hidden (view full) --- 2498 */ 2499 error = sooptcopyin(sopt, &addr, sizeof(struct in_addr), 2500 sizeof(struct in_addr)); 2501 if (error) 2502 return (error); 2503 if (in_nullhost(addr)) { 2504 ifp = NULL; 2505 } else { |
2507 IN_IFADDR_RLOCK(&in_ifa_tracker); | 2506 struct epoch_tracker et; 2507 2508 NET_EPOCH_ENTER(et); |
2508 INADDR_TO_IFP(addr, ifp); | 2509 INADDR_TO_IFP(addr, ifp); |
2509 IN_IFADDR_RUNLOCK(&in_ifa_tracker); | 2510 /* XXXGL ifref? */ 2511 NET_EPOCH_EXIT(et); |
2510 if (ifp == NULL) 2511 return (EADDRNOTAVAIL); 2512 } 2513 CTR3(KTR_IGMPV3, "%s: ifp = %p, addr = 0x%08x", __func__, ifp, 2514 ntohl(addr.s_addr)); 2515 } 2516 2517 /* Reject interfaces which do not support multicast. */ --- 526 unchanged lines hidden --- | 2512 if (ifp == NULL) 2513 return (EADDRNOTAVAIL); 2514 } 2515 CTR3(KTR_IGMPV3, "%s: ifp = %p, addr = 0x%08x", __func__, ifp, 2516 ntohl(addr.s_addr)); 2517 } 2518 2519 /* Reject interfaces which do not support multicast. */ --- 526 unchanged lines hidden --- |