Esempio n. 1
0
void
ospf_if_set_multicast(struct ospf_interface *oi)
{
  if ((oi->state > ISM_Loopback) &&
      (oi->type != OSPF_IFTYPE_LOOPBACK) &&
      (oi->type != OSPF_IFTYPE_VIRTUALLINK) &&
      (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_ACTIVE))
    {
      /* The interface should belong to the OSPF-all-routers group. */
      if (!OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS) &&
	  (ospf_if_add_allspfrouters(oi->ospf, oi->address,
				     oi->ifp->ifindex) >= 0))
	  /* Set the flag only if the system call to join succeeded. */
	  OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
    }
  else
    {
      /* The interface should NOT belong to the OSPF-all-routers group. */
      if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS))
        {
          /* Only actually drop if this is the last reference */
          if (OI_MEMBER_COUNT(oi, MEMBER_ALLROUTERS) == 1)
	    ospf_if_drop_allspfrouters (oi->ospf, oi->address,
	                                oi->ifp->ifindex);
	  /* Unset the flag regardless of whether the system call to leave
	     the group succeeded, since it's much safer to assume that
	     we are not a member. */
          OI_MEMBER_LEFT(oi,MEMBER_ALLROUTERS);
        }
    }

  if (((oi->type == OSPF_IFTYPE_BROADCAST) ||
       (oi->type == OSPF_IFTYPE_POINTOPOINT)) &&
      ((oi->state == ISM_DR) || (oi->state == ISM_Backup)) &&
      (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_ACTIVE))
    {
      /* The interface should belong to the OSPF-designated-routers group. */
      if (!OI_MEMBER_CHECK(oi, MEMBER_DROUTERS) &&
	  (ospf_if_add_alldrouters(oi->ospf, oi->address,
	  			   oi->ifp->ifindex) >= 0))
	/* Set the flag only if the system call to join succeeded. */
	OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
    }
  else
    {
      /* The interface should NOT belong to the OSPF-designated-routers group */
      if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS))
        {
          /* drop only if last reference */
          if (OI_MEMBER_COUNT(oi, MEMBER_DROUTERS) == 1)
	    ospf_if_drop_alldrouters(oi->ospf, oi->address, oi->ifp->ifindex);
          
	  /* Unset the flag regardless of whether the system call to leave
	     the group succeeded, since it's much safer to assume that
	     we are not a member. */
          OI_MEMBER_LEFT(oi, MEMBER_DROUTERS);
        }
    }
}
Esempio n. 2
0
int
ospf_dr_election (struct ospf_interface *oi)
{
  struct in_addr old_dr, old_bdr;
  int old_state, new_state;
  struct list *el_list;
  struct ospf_neighbor *dr, *bdr;

  /* backup current values. */
  old_dr = DR (oi);
  old_bdr = BDR (oi);
  old_state = oi->state;

  el_list = list_new ();

  /* List eligible routers. */
  ospf_dr_eligible_routers (oi->nbrs, el_list);

  /* First election of DR and BDR. */
  bdr = ospf_elect_bdr (oi, el_list);
  dr = ospf_elect_dr (oi, el_list);

  new_state = ospf_ism_state (oi);

  zlog_info ("DR-Election[1st]: Backup %s", inet_ntoa (BDR (oi)));
  zlog_info ("DR-Election[1st]: DR     %s", inet_ntoa (DR (oi)));

  if (new_state != old_state &&
      !(new_state == ISM_DROther && old_state < ISM_DROther))
    {
      ospf_elect_bdr (oi, el_list);
      ospf_elect_dr (oi, el_list); 

      new_state = ospf_ism_state (oi);

      zlog_info ("DR-Election[2nd]: Backup %s", inet_ntoa (BDR (oi)));
      zlog_info ("DR-Election[2nd]: DR     %s", inet_ntoa (DR (oi)));
    }

  list_delete (el_list);

  /* if DR or BDR changes, cause AdjOK? neighbor event. */
  if (!IPV4_ADDR_SAME (&old_dr, &DR (oi)) ||
      !IPV4_ADDR_SAME (&old_bdr, &BDR (oi)))
    ospf_dr_change (oi->ospf, oi->nbrs);

  if (oi->type == OSPF_IFTYPE_BROADCAST || oi->type == OSPF_IFTYPE_POINTOPOINT)
    {
      /* Multicast group change. */
      if ((old_state != ISM_DR && old_state != ISM_Backup) &&
	  (new_state == ISM_DR || new_state == ISM_Backup))
	ospf_if_add_alldrouters (oi->ospf, oi->address, oi->ifp->ifindex);
      else if ((old_state == ISM_DR || old_state == ISM_Backup) &&
	       (new_state != ISM_DR && new_state != ISM_Backup))
	ospf_if_drop_alldrouters (oi->ospf, oi->address, oi->ifp->ifindex);
    }

  return new_state;
}