Deleted Added
full compact
igmp.c (128019) igmp.c (130333)
1/*
2 * Copyright (c) 1988 Stephen Deering.
3 * Copyright (c) 1992, 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Stephen Deering of Stanford University.
8 *

--- 17 unchanged lines hidden (view full) ---

26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)igmp.c 8.1 (Berkeley) 7/19/93
1/*
2 * Copyright (c) 1988 Stephen Deering.
3 * Copyright (c) 1992, 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Stephen Deering of Stanford University.
8 *

--- 17 unchanged lines hidden (view full) ---

26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)igmp.c 8.1 (Berkeley) 7/19/93
34 * $FreeBSD: head/sys/netinet/igmp.c 128019 2004-04-07 20:46:16Z imp $
34 * $FreeBSD: head/sys/netinet/igmp.c 130333 2004-06-11 03:42:37Z rwatson $
35 */
36
37/*
38 * Internet Group Management Protocol (IGMP) routines.
39 *
40 * Written by Steve Deering, Stanford, May 1988.
41 * Modified by Rosen Sharma, Stanford, Aug 1994.
42 * Modified by Bill Fenner, Xerox PARC, Feb 1995.

--- 32 unchanged lines hidden (view full) ---

75static struct router_info *find_rti(struct ifnet *ifp);
76static void igmp_sendpkt(struct in_multi *, int, unsigned long);
77
78static struct igmpstat igmpstat;
79
80SYSCTL_STRUCT(_net_inet_igmp, IGMPCTL_STATS, stats, CTLFLAG_RW, &igmpstat,
81 igmpstat, "");
82
35 */
36
37/*
38 * Internet Group Management Protocol (IGMP) routines.
39 *
40 * Written by Steve Deering, Stanford, May 1988.
41 * Modified by Rosen Sharma, Stanford, Aug 1994.
42 * Modified by Bill Fenner, Xerox PARC, Feb 1995.

--- 32 unchanged lines hidden (view full) ---

75static struct router_info *find_rti(struct ifnet *ifp);
76static void igmp_sendpkt(struct in_multi *, int, unsigned long);
77
78static struct igmpstat igmpstat;
79
80SYSCTL_STRUCT(_net_inet_igmp, IGMPCTL_STATS, stats, CTLFLAG_RW, &igmpstat,
81 igmpstat, "");
82
83/*
84 * igmp_mtx protects all mutable global variables in igmp.c, as well as
85 * the data fields in struct router_info. In general, a router_info
86 * structure will be valid as long as the referencing struct in_multi is
87 * valid, so no reference counting is used. We allow unlocked reads of
88 * router_info data when accessed via an in_multi read-only.
89 */
90static struct mtx igmp_mtx;
83static SLIST_HEAD(, router_info) router_info_head;
84static int igmp_timers_are_running;
91static SLIST_HEAD(, router_info) router_info_head;
92static int igmp_timers_are_running;
93
94/*
95 * XXXRW: can we define these such that these can be made const? In any
96 * case, these shouldn't be changed after igmp_init() and therefore don't
97 * need locking.
98 */
85static u_long igmp_all_hosts_group;
86static u_long igmp_all_rtrs_group;
99static u_long igmp_all_hosts_group;
100static u_long igmp_all_rtrs_group;
101
87static struct mbuf *router_alert;
88static struct route igmprt;
89
90#ifdef IGMP_DEBUG
91#define IGMP_PRINTF(x) printf(x)
92#else
93#define IGMP_PRINTF(x)
94#endif

--- 18 unchanged lines hidden (view full) ---

113 ra = mtod(router_alert, struct ipoption *);
114 ra->ipopt_dst.s_addr = 0;
115 ra->ipopt_list[0] = IPOPT_RA; /* Router Alert Option */
116 ra->ipopt_list[1] = 0x04; /* 4 bytes long */
117 ra->ipopt_list[2] = 0x00;
118 ra->ipopt_list[3] = 0x00;
119 router_alert->m_len = sizeof(ra->ipopt_dst) + ra->ipopt_list[1];
120
102static struct mbuf *router_alert;
103static struct route igmprt;
104
105#ifdef IGMP_DEBUG
106#define IGMP_PRINTF(x) printf(x)
107#else
108#define IGMP_PRINTF(x)
109#endif

--- 18 unchanged lines hidden (view full) ---

128 ra = mtod(router_alert, struct ipoption *);
129 ra->ipopt_dst.s_addr = 0;
130 ra->ipopt_list[0] = IPOPT_RA; /* Router Alert Option */
131 ra->ipopt_list[1] = 0x04; /* 4 bytes long */
132 ra->ipopt_list[2] = 0x00;
133 ra->ipopt_list[3] = 0x00;
134 router_alert->m_len = sizeof(ra->ipopt_dst) + ra->ipopt_list[1];
135
136 mtx_init(&igmp_mtx, "igmp_mtx", NULL, MTX_DEF);
121 SLIST_INIT(&router_info_head);
122}
123
124static struct router_info *
125find_rti(struct ifnet *ifp)
126{
127 struct router_info *rti;
128
137 SLIST_INIT(&router_info_head);
138}
139
140static struct router_info *
141find_rti(struct ifnet *ifp)
142{
143 struct router_info *rti;
144
145 mtx_assert(&igmp_mtx, MA_OWNED);
129 IGMP_PRINTF("[igmp.c, _find_rti] --> entering \n");
130 SLIST_FOREACH(rti, &router_info_head, rti_list) {
131 if (rti->rti_ifp == ifp) {
132 IGMP_PRINTF(
133 "[igmp.c, _find_rti] --> found old entry \n");
134 return rti;
135 }
136 }
146 IGMP_PRINTF("[igmp.c, _find_rti] --> entering \n");
147 SLIST_FOREACH(rti, &router_info_head, rti_list) {
148 if (rti->rti_ifp == ifp) {
149 IGMP_PRINTF(
150 "[igmp.c, _find_rti] --> found old entry \n");
151 return rti;
152 }
153 }
154 /*
155 * XXXRW: return value of malloc not checked, despite M_NOWAIT.
156 */
137 MALLOC(rti, struct router_info *, sizeof *rti, M_IGMP, M_NOWAIT);
138 rti->rti_ifp = ifp;
139 rti->rti_type = IGMP_V2_ROUTER;
140 rti->rti_time = 0;
141 SLIST_INSERT_HEAD(&router_info_head, rti, rti_list);
142
143 IGMP_PRINTF("[igmp.c, _find_rti] --> created an entry \n");
144 return rti;

--- 47 unchanged lines hidden (view full) ---

192 }
193 m->m_data -= iphlen;
194 m->m_len += iphlen;
195
196 ip = mtod(m, struct ip *);
197 timer = igmp->igmp_code * PR_FASTHZ / IGMP_TIMER_SCALE;
198 if (timer == 0)
199 timer = 1;
157 MALLOC(rti, struct router_info *, sizeof *rti, M_IGMP, M_NOWAIT);
158 rti->rti_ifp = ifp;
159 rti->rti_type = IGMP_V2_ROUTER;
160 rti->rti_time = 0;
161 SLIST_INSERT_HEAD(&router_info_head, rti, rti_list);
162
163 IGMP_PRINTF("[igmp.c, _find_rti] --> created an entry \n");
164 return rti;

--- 47 unchanged lines hidden (view full) ---

212 }
213 m->m_data -= iphlen;
214 m->m_len += iphlen;
215
216 ip = mtod(m, struct ip *);
217 timer = igmp->igmp_code * PR_FASTHZ / IGMP_TIMER_SCALE;
218 if (timer == 0)
219 timer = 1;
200 rti = find_rti(ifp);
201
202 /*
203 * In the IGMPv2 specification, there are 3 states and a flag.
204 *
205 * In Non-Member state, we simply don't have a membership record.
206 * In Delaying Member state, our timer is running (inm->inm_timer)
207 * In Idle Member state, our timer is not running (inm->inm_timer==0)
208 *

--- 10 unchanged lines hidden (view full) ---

219
220 if (igmp->igmp_code == 0) {
221 /*
222 * Old router. Remember that the querier on this
223 * interface is old, and set the timer to the
224 * value in RFC 1112.
225 */
226
220
221 /*
222 * In the IGMPv2 specification, there are 3 states and a flag.
223 *
224 * In Non-Member state, we simply don't have a membership record.
225 * In Delaying Member state, our timer is running (inm->inm_timer)
226 * In Idle Member state, our timer is not running (inm->inm_timer==0)
227 *

--- 10 unchanged lines hidden (view full) ---

238
239 if (igmp->igmp_code == 0) {
240 /*
241 * Old router. Remember that the querier on this
242 * interface is old, and set the timer to the
243 * value in RFC 1112.
244 */
245
246 mtx_lock(&igmp_mtx);
247 rti = find_rti(ifp);
227 rti->rti_type = IGMP_V1_ROUTER;
228 rti->rti_time = 0;
248 rti->rti_type = IGMP_V1_ROUTER;
249 rti->rti_time = 0;
250 mtx_unlock(&igmp_mtx);
229
230 timer = IGMP_MAX_HOST_REPORT_DELAY * PR_FASTHZ;
231
232 if (ip->ip_dst.s_addr != igmp_all_hosts_group ||
233 igmp->igmp_group.s_addr != 0) {
234 ++igmpstat.igps_rcv_badqueries;
235 m_freem(m);
236 return;

--- 102 unchanged lines hidden (view full) ---

339{
340 int s = splnet();
341
342 if (inm->inm_addr.s_addr == igmp_all_hosts_group
343 || inm->inm_ifp->if_flags & IFF_LOOPBACK) {
344 inm->inm_timer = 0;
345 inm->inm_state = IGMP_OTHERMEMBER;
346 } else {
251
252 timer = IGMP_MAX_HOST_REPORT_DELAY * PR_FASTHZ;
253
254 if (ip->ip_dst.s_addr != igmp_all_hosts_group ||
255 igmp->igmp_group.s_addr != 0) {
256 ++igmpstat.igps_rcv_badqueries;
257 m_freem(m);
258 return;

--- 102 unchanged lines hidden (view full) ---

361{
362 int s = splnet();
363
364 if (inm->inm_addr.s_addr == igmp_all_hosts_group
365 || inm->inm_ifp->if_flags & IFF_LOOPBACK) {
366 inm->inm_timer = 0;
367 inm->inm_state = IGMP_OTHERMEMBER;
368 } else {
369 mtx_lock(&igmp_mtx);
347 inm->inm_rti = find_rti(inm->inm_ifp);
370 inm->inm_rti = find_rti(inm->inm_ifp);
371 mtx_unlock(&igmp_mtx);
348 igmp_sendpkt(inm, inm->inm_rti->rti_type, 0);
349 inm->inm_timer = IGMP_RANDOM_DELAY(
350 IGMP_MAX_HOST_REPORT_DELAY*PR_FASTHZ);
351 inm->inm_state = IGMP_IREPORTEDLAST;
352 igmp_timers_are_running = 1;
353 }
354 splx(s);
355}

--- 43 unchanged lines hidden (view full) ---

399
400void
401igmp_slowtimo(void)
402{
403 int s = splnet();
404 struct router_info *rti;
405
406 IGMP_PRINTF("[igmp.c,_slowtimo] -- > entering \n");
372 igmp_sendpkt(inm, inm->inm_rti->rti_type, 0);
373 inm->inm_timer = IGMP_RANDOM_DELAY(
374 IGMP_MAX_HOST_REPORT_DELAY*PR_FASTHZ);
375 inm->inm_state = IGMP_IREPORTEDLAST;
376 igmp_timers_are_running = 1;
377 }
378 splx(s);
379}

--- 43 unchanged lines hidden (view full) ---

423
424void
425igmp_slowtimo(void)
426{
427 int s = splnet();
428 struct router_info *rti;
429
430 IGMP_PRINTF("[igmp.c,_slowtimo] -- > entering \n");
431 mtx_lock(&igmp_mtx);
407 SLIST_FOREACH(rti, &router_info_head, rti_list) {
408 if (rti->rti_type == IGMP_V1_ROUTER) {
409 rti->rti_time++;
410 if (rti->rti_time >= IGMP_AGE_THRESHOLD)
411 rti->rti_type = IGMP_V2_ROUTER;
412 }
413 }
432 SLIST_FOREACH(rti, &router_info_head, rti_list) {
433 if (rti->rti_type == IGMP_V1_ROUTER) {
434 rti->rti_time++;
435 if (rti->rti_time >= IGMP_AGE_THRESHOLD)
436 rti->rti_type = IGMP_V2_ROUTER;
437 }
438 }
439 mtx_unlock(&igmp_mtx);
414 IGMP_PRINTF("[igmp.c,_slowtimo] -- > exiting \n");
415 splx(s);
416}
417
418static void
419igmp_sendpkt(struct in_multi *inm, int type, unsigned long addr)
420{
421 struct mbuf *m;

--- 50 unchanged lines hidden ---
440 IGMP_PRINTF("[igmp.c,_slowtimo] -- > exiting \n");
441 splx(s);
442}
443
444static void
445igmp_sendpkt(struct in_multi *inm, int type, unsigned long addr)
446{
447 struct mbuf *m;

--- 50 unchanged lines hidden ---