GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / emf / igs / igsc_sdb.c
blob0b23f1b64ae25d0005fe92885c01154127dd62d2
1 /*
2 * This file contains the common code routines to access/update the
3 * IGMP Snooping database.
5 * Copyright (C) 2012, Broadcom Corporation
6 * All Rights Reserved.
7 *
8 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
9 * the contents of this file may not be disclosed to third parties, copied
10 * or duplicated in any form, in whole or in part, without the prior
11 * written permission of Broadcom Corporation.
13 * $Id: igsc_sdb.c 360693 2012-10-04 02:29:26Z $
15 #include <typedefs.h>
16 #include <bcmdefs.h>
17 #include <bcmendian.h>
18 #include <bcmutils.h>
19 #include <proto/ethernet.h>
20 #include <proto/bcmip.h>
21 #include <osl.h>
22 #include <clist.h>
23 #if defined(linux)
24 #include <osl_linux.h>
25 #elif defined(__ECOS)
26 #include <osl_ecos.h>
27 #else /* defined(osl_xx) */
28 #error "Unsupported osl"
29 #endif /* defined(osl_xx) */
30 #include "emfc_export.h"
31 #include "igs_cfg.h"
32 #include "igsc_export.h"
33 #include "igsc.h"
34 #include "igsc_sdb.h"
37 * Description: This function initializes the IGSDB. IGSDB group
38 * entries are organized as a hash table with chaining
39 * for collision resolution. Each IGSDB group entry
40 * points to the chain of IGSDB host entries that are
41 * members of the group.
43 * Input: igsc_info - IGSL Common code global data handle
45 void
46 igsc_sdb_init(igsc_info_t *igsc_info)
48 int32 i;
50 for (i = 0; i < IGSDB_HASHT_SIZE; i++)
52 clist_init_head(&igsc_info->mgrp_sdb[i]);
55 return;
59 * Description: This function deletes the host entry of IGSDB. It also
60 * deletes the corresponding interfaces and group entries
61 * if this is the last member of the group.
63 * Input: igsc_info - IGSL Common code global data handle
64 * mh - Pointer to Multicast host entry of IGSDB
66 static void
67 igsc_sdb_mh_delete(igsc_info_t *igsc_info, igsc_mh_t *mh)
69 /* Delete the interface entry if no stream is going on it */
70 if (--mh->mh_mi->mi_ref == 0)
72 IGS_DEBUG("Deleting interface entry %p\n", mh->mh_mi);
74 /* Delete the MFDB entry if no more members of the group
75 * are present on the interface.
77 if (emfc_mfdb_membership_del(igsc_info->emf_handle,
78 mh->mh_mgrp->mgrp_ip,
79 mh->mh_mi->mi_ifp) != SUCCESS)
81 IGS_ERROR("Membership entry %x %p delete failed\n",
82 mh->mh_mgrp->mgrp_ip, mh->mh_mi->mi_ifp);
83 return;
86 clist_delete(&mh->mh_mi->mi_list);
87 MFREE(igsc_info->osh, mh->mh_mi, sizeof(igsc_mi_t));
90 /* Delete the host entry */
91 clist_delete(&mh->mh_list);
92 IGSC_STATS_DECR(igsc_info, igmp_mcast_members);
94 /* If the member being deleted is last node in the host list,
95 * delete the group entry also.
97 if (clist_empty(&mh->mh_mgrp->mh_head))
99 IGS_IGSDB("Deleting group entry of %d.%d.%d.%d too\n",
100 (mh->mh_mgrp->mgrp_ip >> 24),
101 ((mh->mh_mgrp->mgrp_ip >> 16) & 0xff),
102 ((mh->mh_mgrp->mgrp_ip >> 8) & 0xff),
103 (mh->mh_mgrp->mgrp_ip & 0xff));
105 clist_delete(&mh->mh_mgrp->mgrp_hlist);
106 MFREE(igsc_info->osh, mh->mh_mgrp, sizeof(igsc_mgrp_t));
107 IGSC_STATS_DECR(igsc_info, igmp_mcast_groups);
110 MFREE(igsc_info->osh, mh, sizeof(igsc_mh_t));
112 return;
116 * Description: This function is called when no reports are received
117 * from any of the participating group members with in
118 * multicast group membership interval time. It deletes
119 * all the group member information from IGSDB so that
120 * the multicast stream forwarding is stopped.
122 * Input: mh - Pointer to multicast host entry that timed out.
124 static void
125 igsc_sdb_timer(igsc_mh_t *mh)
127 igsc_info_t *igsc_info;
129 igsc_info = mh->mh_mgrp->igsc_info;
131 IGSC_STATS_INCR(igsc_info, igmp_mem_timeouts);
133 IGS_IGSDB("Multicast host entry %d.%d.%d.%d timed out\n",
134 (mh->mh_ip >> 24), ((mh->mh_ip >> 16) & 0xff),
135 ((mh->mh_ip >> 8) & 0xff), (mh->mh_ip & 0xff));
137 /* Timer expiry indicates that no report is seen from the
138 * member. First check the interface entry before deleting
139 * the host entry.
141 igsc_sdb_mh_delete(igsc_info, mh);
143 return;
147 * Description: This function does the IGSDB lookup to locate a multicast
148 * group entry.
150 * Input: mgrp_ip - Multicast group address of the entry.
152 * Return: Returns NULL is no group entry is found. Otherwise
153 * returns pointer to the IGSDB group entry.
155 static igsc_mgrp_t *
156 igsc_sdb_group_find(igsc_info_t *igsc_info, uint32 mgrp_ip)
158 uint32 hash;
159 igsc_mgrp_t *mgrp;
160 clist_head_t *ptr;
162 ASSERT(IP_ISMULTI(mgrp_ip));
164 hash = IGSDB_MGRP_HASH(mgrp_ip);
166 for (ptr = igsc_info->mgrp_sdb[hash].next;
167 ptr != &igsc_info->mgrp_sdb[hash]; ptr = ptr->next)
169 mgrp = clist_entry(ptr, igsc_mgrp_t, mgrp_hlist);
171 /* Compare group address */
172 if (mgrp_ip == mgrp->mgrp_ip)
174 IGS_IGSDB("Multicast Group entry %d.%d.%d.%d found\n",
175 (mgrp_ip >> 24), ((mgrp_ip >> 16) & 0xff),
176 ((mgrp_ip >> 8) & 0xff), (mgrp_ip & 0xff));
178 return (mgrp);
182 return (NULL);
186 * Description: This fnction does the MFDB lookup to locate host entry
187 * of the specified group.
189 * Input: igsc_info - IGMP Snooper instance handle.
190 * mgrp - Pointer to multicast group entry of IGSDB
191 * mh_ip - Member IP Address to find
192 * ifp - Pointer to the member interface.
194 * Return: Returns pointer to host entry or NULL.
196 static igsc_mh_t *
197 igsc_sdb_mh_entry_find(igsc_info_t *igsc_info, igsc_mgrp_t *mgrp,
198 uint32 mh_ip, void *ifp)
200 igsc_mh_t *mh;
201 clist_head_t *ptr;
203 for (ptr = mgrp->mh_head.next;
204 ptr != &mgrp->mh_head; ptr = ptr->next)
206 mh = clist_entry(ptr, igsc_mh_t, mh_list);
207 if ((mh_ip == mh->mh_ip) && (ifp == mh->mh_mi->mi_ifp))
209 return (mh);
213 return (NULL);
216 static igsc_mi_t *
217 igsc_sdb_mi_entry_find(igsc_info_t *igsc_info, igsc_mgrp_t *mgrp, void *ifp)
219 igsc_mi_t *mi;
220 clist_head_t *ptr;
222 for (ptr = mgrp->mi_head.next;
223 ptr != &mgrp->mi_head; ptr = ptr->next)
225 mi = clist_entry(ptr, igsc_mi_t, mi_list);
226 if (ifp == mi->mi_ifp)
228 return (mi);
232 return (NULL);
236 * Description: This function does the IGSDB lookup to locate a host
237 * entry of the specified multicast group.
239 * Input: igsc_info - IGMP Snooper instance handle.
240 * mgrp_ip - Multicast group IP address of the entry.
241 * mh_ip - Multicast host address.
242 * ifp - Pointer to the interface on which the member
243 * is present.
245 * Return: Returns NULL is no host entry is found. Otherwise
246 * returns pointer to the IGSDB host entry.
248 static igsc_mh_t *
249 igsc_sdb_member_find(igsc_info_t *igsc_info, uint32 mgrp_ip,
250 uint32 mh_ip, void *ifp)
252 uint32 hash;
253 igsc_mgrp_t *mgrp;
254 igsc_mh_t *mh;
256 ASSERT(IP_ISMULTI(mgrp_ip));
258 hash = IGSDB_MGRP_HASH(mgrp_ip);
260 /* Find group entry */
261 mgrp = igsc_sdb_group_find(igsc_info, mgrp_ip);
263 if (mgrp != NULL)
265 /* Find host entry */
266 mh = igsc_sdb_mh_entry_find(igsc_info, mgrp, mh_ip, ifp);
268 if (mh != NULL)
270 IGS_IGSDB("Host entry of %d.%d.%d.%d:%d.%d.%d.%d:%p found\n",
271 (mgrp_ip >> 24), ((mgrp_ip >> 16) & 0xff),
272 ((mgrp_ip >> 8) & 0xff), (mgrp_ip & 0xff),
273 (mh_ip >> 24), ((mh_ip >> 16) & 0xff),
274 ((mh_ip >> 8) & 0xff), (mh_ip & 0xff), (uint32)ifp);
275 return (mh);
279 IGS_IGSDB("Host entry %x %x %p not found\n", mgrp_ip, mh_ip, ifp);
281 return (NULL);
283 #ifdef MEDIAROOM_IGMP_WAR
284 /* MSFT MediaRoom clients are aware of the entire group. If one client sends out a membership
285 * report and the other clients see it, the other clients will not send out separate membership
286 * reports. This causes us to age out perfectly good streaming clients and causes packet loss.
287 * WAR this by updating the timer for entire group
289 static void
290 update_all_timers_in_group(igsc_info_t *igsc_info, igsc_mgrp_t *mgrp,
291 uint32 mh_ip, void *ifp)
293 igsc_mh_t *mh;
294 clist_head_t *ptr;
296 for (ptr = mgrp->mh_head.next;
297 ptr != &mgrp->mh_head; ptr = ptr->next)
299 mh = clist_entry(ptr, igsc_mh_t, mh_list);
300 IGS_IGSDB("Refreshing timer for group %x and host %x\n",
301 mh->mh_mgrp->mgrp_ip, mh->mh_ip);
302 osl_timer_update(mh->mgrp_timer, igsc_info->grp_mem_intv, FALSE);
305 return;
307 #endif /* MEDIAROOM_IGMP_WAR */
310 * Description: This function is called by IGMP Snooper when it wants
311 * to add IGSDB entry or refresh the entry. This function
312 * is also called by the management application to add a
313 * static IGSDB entry.
315 * If the IGSDB entry is not present, it allocates group
316 * entry, host entry, interface entry and links them
317 * together. Othewise it just updates the timer for the
318 * matched host entry.
320 * Input: mgrp_ip - Multicast group IP address of the entry.
321 * mh_ip - Multicast host address. When adding static
322 * entry this parameter is zero.
323 * ifp - Pointer to the interface on which the member
324 * is present.
326 * Return: SUCCESS or FAILURE
328 int32
329 igsc_sdb_member_add(igsc_info_t *igsc_info, void *ifp, uint32 mgrp_ip,
330 uint32 mh_ip)
332 int32 hash, ret;
333 igsc_mgrp_t *mgrp;
334 igsc_mh_t *mh;
335 igsc_mi_t *mi;
337 ASSERT(IP_ISMULTI(mgrp_ip));
338 ASSERT(!IP_ISMULTI(mh_ip));
340 OSL_LOCK(igsc_info->sdb_lock);
342 /* If the group entry doesn't exist, add a new entry and update
343 * the member/host information.
345 mgrp = igsc_sdb_group_find(igsc_info, mgrp_ip);
347 if (mgrp == NULL)
349 /* Allocate and initialize multicast group entry */
350 mgrp = MALLOC(igsc_info->osh, sizeof(igsc_mgrp_t));
351 if (mgrp == NULL)
353 IGS_ERROR("Failed to alloc size %d for IGSDB group entry\n",
354 sizeof(igsc_mgrp_t));
355 goto sdb_add_exit0;
358 mgrp->mgrp_ip = mgrp_ip;
359 clist_init_head(&mgrp->mh_head);
360 clist_init_head(&mgrp->mi_head);
361 mgrp->igsc_info = igsc_info;
363 IGS_IGSDB("Adding group entry %d.%d.%d.%d\n",
364 (mgrp_ip >> 24), ((mgrp_ip >> 16) & 0xff),
365 ((mgrp_ip >> 8) & 0xff), (mgrp_ip & 0xff));
367 /* Add the group entry to hash table */
368 hash = IGSDB_MGRP_HASH(mgrp_ip);
369 clist_add_head(&igsc_info->mgrp_sdb[hash], &mgrp->mgrp_hlist);
371 IGSC_STATS_INCR(igsc_info, igmp_mcast_groups);
373 else
375 IGS_IGSDB("Refreshing FDB entry for group %d.%d.%d.%d:%d.%d.%d.%d\n",
376 (mgrp_ip >> 24), ((mgrp_ip >> 16) & 0xff),
377 ((mgrp_ip >> 8) & 0xff), (mgrp_ip & 0xff),
378 (mh_ip >> 24), ((mh_ip >> 16) & 0xff),
379 ((mh_ip >> 8) & 0xff), (mh_ip & 0xff));
381 /* Avoid adding duplicate entries */
382 mh = igsc_sdb_mh_entry_find(igsc_info, mgrp, mh_ip, ifp);
383 if (mh != NULL)
385 OSL_UNLOCK(igsc_info->sdb_lock);
386 #ifdef MEDIAROOM_IGMP_WAR
387 /* Refresh the group interval timer for all group members */
388 update_all_timers_in_group(igsc_info, mgrp, mh_ip, ifp);
389 #else
390 /* Refresh the group interval timer for this group */
391 osl_timer_update(mh->mgrp_timer, igsc_info->grp_mem_intv, FALSE);
392 #endif
393 return (SUCCESS);
397 /* Allocate and initialize multicast host entry */
398 mh = MALLOC(igsc_info->osh, sizeof(igsc_mh_t));
399 if (mh == NULL)
401 IGS_ERROR("Failed to allocated memory size %d for IGSDB host entry\n",
402 sizeof(igsc_mh_t));
403 goto sdb_add_exit1;
406 /* Initialize the host entry */
407 mh->mh_ip = mh_ip;
408 mh->mh_mgrp = mgrp;
410 IGS_IGSDB("Adding host entry %d.%d.%d.%d on interface %p\n",
411 (mh_ip >> 24), ((mh_ip >> 16) & 0xff),
412 ((mh_ip >> 8) & 0xff), (mh_ip & 0xff), ifp);
414 IGSC_STATS_INCR(igsc_info, igmp_mcast_members);
416 /* Set the group interval timer */
417 mh->mgrp_timer = osl_timer_init("IGMPV2_GRP_MEM_INTV",
418 (void (*)(void *))igsc_sdb_timer,
419 (void *)mh);
420 if (mh->mgrp_timer == NULL)
422 IGS_ERROR("Failed to allocate memory size %d for IGSDB timer\n",
423 sizeof(osl_timer_t));
424 goto sdb_add_exit2;
427 osl_timer_add(mh->mgrp_timer, igsc_info->grp_mem_intv, FALSE);
429 /* Add the host entry to the group */
430 clist_add_head(&mgrp->mh_head, &mh->mh_list);
432 /* Avoid adding duplicate interface list entries */
433 mi = igsc_sdb_mi_entry_find(igsc_info, mgrp, ifp);
434 if (mi != NULL)
436 /* Link the interface list entry */
437 mh->mh_mi = mi;
439 /* Increment ref count indicating a new reference from
440 * host entry.
442 ASSERT(mi->mi_ref > 0);
443 mi->mi_ref++;
445 OSL_UNLOCK(igsc_info->sdb_lock);
446 return (SUCCESS);
449 ret = emfc_mfdb_membership_add(igsc_info->emf_handle,
450 mgrp->mgrp_ip, ifp);
451 if (ret != SUCCESS)
453 IGS_ERROR("Failed to add MFDB entry for %x %p\n",
454 mgrp_ip, ifp);
455 goto sdb_add_exit3;
458 /* Allocate and initialize multicast interface entry */
459 mi = MALLOC(igsc_info->osh, sizeof(igsc_mi_t));
460 if (mi == NULL)
462 IGS_ERROR("Failed to allocated memory size %d for interface entry\n",
463 sizeof(igsc_mi_t));
464 goto sdb_add_exit4;
467 /* Initialize the multicast interface list entry */
468 mi->mi_ifp = ifp;
469 mi->mi_ref = 1;
471 IGS_IGSDB("Adding interface entry for interface %p\n", mi->mi_ifp);
473 /* Add the multicast interface entry */
474 clist_add_head(&mgrp->mi_head, &mi->mi_list);
476 /* Link the interface list entry to host entry */
477 mh->mh_mi = mi;
479 OSL_UNLOCK(igsc_info->sdb_lock);
481 return (SUCCESS);
483 sdb_add_exit4:
484 emfc_mfdb_membership_del(igsc_info->emf_handle, mgrp->mgrp_ip, ifp);
485 sdb_add_exit3:
486 osl_timer_del(mh->mgrp_timer);
487 clist_delete(&mh->mh_list);
488 sdb_add_exit2:
489 MFREE(igsc_info->osh, mh, sizeof(igsc_mh_t));
490 sdb_add_exit1:
491 if (clist_empty(&mgrp->mh_head))
493 clist_delete(&mgrp->mgrp_hlist);
494 MFREE(igsc_info->osh, mgrp, sizeof(igsc_mgrp_t));
496 sdb_add_exit0:
497 OSL_UNLOCK(igsc_info->sdb_lock);
498 return (FAILURE);
502 * Description: This function is called by the IGMP snooper layer
503 * to delete the IGSDB host entry. It deletes the group
504 * entry also if the host entry is last in the group.
506 * Input: Same as above function.
508 * Return: SUCCESS or FAILURE
510 int32
511 igsc_sdb_member_del(igsc_info_t *igsc_info, void *ifp, uint32 mgrp_ip,
512 uint32 mh_ip)
514 igsc_mh_t *mh;
516 OSL_LOCK(igsc_info->sdb_lock);
518 mh = igsc_sdb_member_find(igsc_info, mgrp_ip, mh_ip, ifp);
520 if (mh != NULL)
522 /* Delete the timer */
523 osl_timer_del(mh->mgrp_timer);
525 IGS_IGSDB("Deleting host entry %d.%d.%d.%d\n",
526 (mh_ip >> 24), ((mh_ip >> 16) & 0xff),
527 ((mh_ip >> 8) & 0xff), (mh_ip & 0xff));
529 igsc_sdb_mh_delete(igsc_info, mh);
531 OSL_UNLOCK(igsc_info->sdb_lock);
533 return (SUCCESS);
536 OSL_UNLOCK(igsc_info->sdb_lock);
538 return (FAILURE);
542 * Description: This function clears the group interval timers and
543 * deletes the group, host and interface entries of the
544 * IGSDB.
546 void
547 igsc_sdb_clear(igsc_info_t *igsc_info)
549 uint32 i;
550 igsc_mgrp_t *mgrp;
551 igsc_mh_t *mh;
552 clist_head_t *ptr1, *ptr2, *tmp1, *tmp2;
554 OSL_LOCK(igsc_info->sdb_lock);
556 /* Delete all the group entries */
557 for (i = 0; i < IGSDB_HASHT_SIZE; i++)
559 for (ptr1 = igsc_info->mgrp_sdb[i].next;
560 ptr1 != &igsc_info->mgrp_sdb[i]; ptr1 = tmp1)
562 mgrp = clist_entry(ptr1, igsc_mgrp_t, mgrp_hlist);
564 /* Delete all host entries */
565 for (ptr2 = mgrp->mh_head.next; ptr2 != &mgrp->mh_head; ptr2 = tmp2)
567 mh = clist_entry(ptr2, igsc_mh_t, mh_list);
569 /* Delete the interface entry if no stream is going on it */
570 if (--mh->mh_mi->mi_ref == 0)
572 IGS_IGSDB("Deleting interface entry %p\n", mh->mh_mi);
574 /* Delete the MFDB entry if no more members of the group
575 * are present on the interface.
577 emfc_mfdb_membership_del(igsc_info->emf_handle,
578 mh->mh_mgrp->mgrp_ip,
579 mh->mh_mi->mi_ifp);
580 clist_delete(&mh->mh_mi->mi_list);
581 MFREE(igsc_info->osh, mh->mh_mi, sizeof(igsc_mi_t));
584 osl_timer_del(mh->mgrp_timer);
585 tmp2 = ptr2->next;
586 clist_delete(ptr2);
587 MFREE(igsc_info->osh, mh, sizeof(igsc_mh_t));
590 tmp1 = ptr1->next;
591 clist_delete(ptr1);
592 MFREE(igsc_info->osh, mgrp, sizeof(igsc_mgrp_t));
596 OSL_UNLOCK(igsc_info->sdb_lock);
598 return;
602 * IGSDB Listing Function
604 int32
605 igsc_sdb_list(igsc_info_t *igsc_info, igs_cfg_sdb_list_t *list, uint32 size)
607 clist_head_t *ptr1, *ptr2;
608 igsc_mh_t *mh;
609 igsc_mgrp_t *mgrp;
610 int32 i, index = 0;
612 if (igsc_info == NULL)
614 IGS_ERROR("Invalid IGSC handle passed\n");
615 return (FAILURE);
618 if (list == NULL)
620 IGS_ERROR("Invalid buffer input\n");
621 return (FAILURE);
624 for (i = 0; i < IGSDB_HASHT_SIZE; i++)
626 for (ptr1 = igsc_info->mgrp_sdb[i].next;
627 ptr1 != &igsc_info->mgrp_sdb[i];
628 ptr1 = ptr1->next)
630 mgrp = clist_entry(ptr1, igsc_mgrp_t, mgrp_hlist);
631 for (ptr2 = mgrp->mh_head.next;
632 ptr2 != &mgrp->mh_head; ptr2 = ptr2->next)
634 mh = clist_entry(ptr2, igsc_mh_t, mh_list);
636 list->sdb_entry[index].mgrp_ip = mgrp->mgrp_ip;
637 list->sdb_entry[index].mh_ip = mh->mh_ip;
638 strncpy(list->sdb_entry[index].if_name,
639 DEV_IFNAME(mh->mh_mi->mi_ifp), 16);
640 index++;
645 list->num_entries = index;
647 return (SUCCESS);
651 * Description: This function is called to delete the IGSDB
652 * an interface
654 * Input: igsc_info - igsc info pointer
655 * ifp - interface pointer
657 * Return: SUCCESS or FAILURE
659 int32
660 igsc_sdb_interface_del(igsc_info_t *igsc_info, void *ifp)
662 uint32 i;
663 igsc_mgrp_t *mgrp;
664 igsc_mh_t *mh;
665 clist_head_t *ptr1, *ptr2, *tmp1, *tmp2;
667 if (igsc_info == NULL)
669 IGS_ERROR("Invalid IGSC handle passed\n");
670 return (FAILURE);
673 if (ifp == NULL)
675 IGS_ERROR("Invalid interface input\n");
676 return (FAILURE);
680 OSL_LOCK(igsc_info->sdb_lock);
682 /* Delete all the group entries */
683 for (i = 0; i < IGSDB_HASHT_SIZE; i++)
685 for (ptr1 = igsc_info->mgrp_sdb[i].next;
686 ptr1 != &igsc_info->mgrp_sdb[i]; ptr1 = tmp1)
688 mgrp = clist_entry(ptr1, igsc_mgrp_t, mgrp_hlist);
690 /* Delete the host and interface entries */
691 for (ptr2 = mgrp->mh_head.next; ptr2 != &mgrp->mh_head; ptr2 = tmp2)
693 mh = clist_entry(ptr2, igsc_mh_t, mh_list);
695 if (mh->mh_mi->mi_ifp != ifp) {
696 tmp2 = ptr2->next;
697 continue;
700 /* Delete the interface entry if no stream is going on it */
701 if (--mh->mh_mi->mi_ref == 0)
703 IGS_IGSDB("Deleting interface entry %p\n", mh->mh_mi);
705 /* Delete the MFDB entry if no more members of the group
706 * are present on the interface.
708 emfc_mfdb_membership_del(igsc_info->emf_handle,
709 mh->mh_mgrp->mgrp_ip,
710 mh->mh_mi->mi_ifp);
711 clist_delete(&mh->mh_mi->mi_list);
712 MFREE(igsc_info->osh, mh->mh_mi, sizeof(igsc_mi_t));
715 osl_timer_del(mh->mgrp_timer);
716 tmp2 = ptr2->next;
717 clist_delete(ptr2);
718 MFREE(igsc_info->osh, mh, sizeof(igsc_mh_t));
721 /* If the member being deleted is last node in the host list,
722 * delete the group entry also.
724 tmp1 = ptr1->next;
725 if (clist_empty(&mgrp->mh_head))
727 IGS_IGSDB("Deleting group entry of %d.%d.%d.%d too\n",
728 (mgrp->mgrp_ip >> 24),
729 ((mgrp->mgrp_ip >> 16) & 0xff),
730 ((mgrp->mgrp_ip >> 8) & 0xff),
731 (mgrp->mgrp_ip & 0xff));
733 clist_delete(ptr1);
734 MFREE(igsc_info->osh, mgrp, sizeof(igsc_mgrp_t));
739 OSL_UNLOCK(igsc_info->sdb_lock);
741 return (SUCCESS);