static void pim_if_addr_del_pim(struct connected *ifc)
{
  struct pim_interface *pim_ifp = ifc->ifp->info;

  if (ifc->address->family != AF_INET) {
    /* non-IPv4 address */
    return;
  }

  if (!pim_ifp) {
    /* PIM not enabled on interface */
    return;
  }

  if (PIM_INADDR_ISNOT_ANY(pim_ifp->primary_address)) {
    /* Interface keeps a valid primary address */
    return;
  }

  if (pim_ifp->pim_sock_fd < 0) {
    /* Interface does not hold a valid socket any longer */
    return;
  }

  /*
    pim_sock_delete() closes the socket, stops read and timer threads,
    and kills all neighbors.
   */
  pim_sock_delete(ifc->ifp, "last address has been removed from interface");
}
Exemple #2
0
static void pim_msdp_sa_peer_ip_set(struct pim_msdp_sa *sa,
				    struct pim_msdp_peer *mp, struct in_addr rp)
{
	struct pim_msdp_peer *old_mp;

	/* optimize the "no change" case as it will happen
	 * frequently/periodically */
	if (mp && (sa->peer.s_addr == mp->peer.s_addr)) {
		return;
	}

	/* any time the peer ip changes also update the rp address */
	if (PIM_INADDR_ISNOT_ANY(sa->peer)) {
		old_mp = pim_msdp_peer_find(sa->pim, sa->peer);
		if (old_mp && old_mp->sa_cnt) {
			--old_mp->sa_cnt;
		}
	}

	if (mp) {
		++mp->sa_cnt;
		sa->peer = mp->peer;
	} else {
		sa->peer.s_addr = PIM_NET_INADDR_ANY;
	}
	sa->rp = rp;
}
void pim_if_addr_add(struct connected *ifc)
{
  struct pim_interface *pim_ifp;
  struct interface *ifp;
  struct in_addr ifaddr;

  zassert(ifc);

  ifp = ifc->ifp;
  zassert(ifp);
  pim_ifp = ifp->info;
  if (!pim_ifp)
    return;

  if (!if_is_operative(ifp))
    return;

  /* if (PIM_DEBUG_ZEBRA) */ {
    char buf[BUFSIZ];
    prefix2str(ifc->address, buf, BUFSIZ);
    zlog_debug("%s: %s ifindex=%d connected IP address %s %s",
	       __PRETTY_FUNCTION__,
	       ifp->name, ifp->ifindex, buf,
	       CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) ?
	       "secondary" : "primary");
  }

  ifaddr = ifc->address->u.prefix4;

  detect_address_change(ifp, 0, __PRETTY_FUNCTION__);

  if (PIM_IF_TEST_IGMP(pim_ifp->options)) {
    struct igmp_sock *igmp;

    /* lookup IGMP socket */
    igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->igmp_socket_list,
				       ifaddr);
    if (!igmp) {
      /* if addr new, add IGMP socket */
      pim_igmp_sock_add(pim_ifp->igmp_socket_list, ifaddr, ifp);
    }
  } /* igmp */

  if (PIM_IF_TEST_PIM(pim_ifp->options)) {

    /* Interface has a valid primary address ? */
    if (PIM_INADDR_ISNOT_ANY(pim_ifp->primary_address)) {

      /* Interface has a valid socket ? */
      if (pim_ifp->pim_sock_fd < 0) {
	if (pim_sock_add(ifp)) {
	  zlog_warn("Failure creating PIM socket for interface %s",
		    ifp->name);
	}
      }

    }
  } /* pim */

  if (PIM_MROUTE_IS_ENABLED) {
    /*
      PIM or IGMP is enabled on interface, and there is at least one
      address assigned, then try to create a vif_index.
    */
    if (pim_ifp->mroute_vif_index < 0) {
      pim_if_add_vif(ifp);
    }
  }
}