コード例 #1
0
ファイル: nhrp_route.c プロジェクト: ton31337/frr
enum nhrp_route_type nhrp_route_address(struct interface *in_ifp,
					union sockunion *addr, struct prefix *p,
					struct nhrp_peer **peer)
{
	struct interface *ifp = in_ifp;
	struct nhrp_interface *nifp;
	struct nhrp_cache *c;
	union sockunion via[4];
	uint32_t network_id = 0;
	afi_t afi = family2afi(sockunion_family(addr));
	int i;

	if (ifp) {
		nifp = ifp->info;
		network_id = nifp->afi[afi].network_id;

		c = nhrp_cache_get(ifp, addr, 0);
		if (c && c->cur.type == NHRP_CACHE_LOCAL) {
			if (p)
				memset(p, 0, sizeof(*p));
			return NHRP_ROUTE_LOCAL;
		}
	}

	for (i = 0; i < 4; i++) {
		if (!nhrp_route_get_nexthop(addr, p, &via[i], &ifp))
			return NHRP_ROUTE_BLACKHOLE;
		if (ifp) {
			/* Departing from nbma network? */
			nifp = ifp->info;
			if (network_id
			    && network_id != nifp->afi[afi].network_id)
				return NHRP_ROUTE_OFF_NBMA;
		}
		if (sockunion_family(&via[i]) == AF_UNSPEC)
			break;
		/* Resolve via node, but return the prefix of first match */
		addr = &via[i];
		p = NULL;
	}

	if (ifp) {
		c = nhrp_cache_get(ifp, addr, 0);
		if (c && c->cur.type >= NHRP_CACHE_DYNAMIC) {
			if (p)
				memset(p, 0, sizeof(*p));
			if (c->cur.type == NHRP_CACHE_LOCAL)
				return NHRP_ROUTE_LOCAL;
			if (peer)
				*peer = nhrp_peer_ref(c->cur.peer);
			return NHRP_ROUTE_NBMA_NEXTHOP;
		}
	}

	return NHRP_ROUTE_BLACKHOLE;
}
コード例 #2
0
ファイル: nhrp_interface.c プロジェクト: KaloNK/quagga
int nhrp_interface_address_add(int cmd, struct zclient *client,
			       zebra_size_t length, vrf_id_t vrf_id)
{
	struct connected *ifc;
	char buf[PREFIX_STRLEN];

	ifc = zebra_interface_address_read(cmd, client->ibuf, vrf_id);
	if (ifc == NULL)
		return 0;

	debugf(NHRP_DEBUG_IF, "if-addr-add: %s: %s",
		ifc->ifp->name,
		prefix2str(ifc->address, buf, sizeof buf));

	nhrp_interface_update_address(ifc->ifp, family2afi(PREFIX_FAMILY(ifc->address)), 0);

	return 0;
}
コード例 #3
0
ファイル: nhrp_route.c プロジェクト: ton31337/frr
static struct route_node *nhrp_route_update_get(const struct prefix *p,
						int create)
{
	struct route_node *rn;
	afi_t afi = family2afi(PREFIX_FAMILY(p));

	if (!zebra_rib[afi])
		return NULL;

	if (create) {
		rn = route_node_get(zebra_rib[afi], p);
		if (!rn->info) {
			rn->info = XCALLOC(MTYPE_NHRP_ROUTE,
					   sizeof(struct route_info));
			route_lock_node(rn);
		}
		return rn;
	} else {
		return route_node_lookup(zebra_rib[afi], p);
	}
}
コード例 #4
0
ファイル: nhrp_route.c プロジェクト: ton31337/frr
int nhrp_route_get_nexthop(const union sockunion *addr, struct prefix *p,
			   union sockunion *via, struct interface **ifp)
{
	struct route_node *rn;
	struct route_info *ri;
	struct prefix lookup;
	afi_t afi = family2afi(sockunion_family(addr));
	char buf[PREFIX_STRLEN];

	sockunion2hostprefix(addr, &lookup);

	rn = route_node_match(zebra_rib[afi], &lookup);
	if (!rn)
		return 0;

	ri = rn->info;
	if (ri->nhrp_ifp) {
		debugf(NHRP_DEBUG_ROUTE, "lookup %s: nhrp_if=%s",
		       prefix2str(&lookup, buf, sizeof buf),
		       ri->nhrp_ifp->name);

		if (via)
			sockunion_family(via) = AF_UNSPEC;
		if (ifp)
			*ifp = ri->nhrp_ifp;
	} else {
		debugf(NHRP_DEBUG_ROUTE, "lookup %s: zebra route dev %s",
		       prefix2str(&lookup, buf, sizeof buf),
		       ri->ifp ? ri->ifp->name : "(none)");

		if (via)
			*via = ri->via;
		if (ifp)
			*ifp = ri->ifp;
	}
	if (p)
		*p = rn->p;
	route_unlock_node(rn);
	return 1;
}
コード例 #5
0
ファイル: zebra_rnh.c プロジェクト: Quagga/quagga
int
zebra_evaluate_rnh_table (vrf_id_t vrfid, int family)
{
  struct route_table *ptable;
  struct route_table *ntable;
  struct route_node *prn;
  struct route_node *nrn;
  struct rnh *rnh;
  struct zserv *client;
  struct listnode *node;
  struct rib *rib;

  ntable = lookup_rnh_table(vrfid, family);
  if (!ntable)
    {
      zlog_debug("evaluate_rnh_table: rnh table not found\n");
      return -1;
    }

  ptable = zebra_vrf_table(family2afi(family), SAFI_UNICAST, vrfid);
  if (!ptable)
    {
      zlog_debug("evaluate_rnh_table: prefix table not found\n");
      return -1;
    }

  for (nrn = route_top (ntable); nrn; nrn = route_next (nrn))
    {
      if (!nrn->info)
	  continue;
      
      rnh = nrn->info;
      prn = route_node_match(ptable, &nrn->p);
      if (!prn)
	rib = NULL;
      else
	{
	  RNODE_FOREACH_RIB(prn, rib)
	    {
	      if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
		continue;
	      if (! CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
		continue;

	      if (CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
		{
		  if (rib->type == ZEBRA_ROUTE_CONNECT)
		    break;

		  if (rib->type == ZEBRA_ROUTE_NHRP)
		    {
		      struct nexthop *nexthop;
		      for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
			if (nexthop->type == NEXTHOP_TYPE_IFINDEX ||
			    nexthop->type == NEXTHOP_TYPE_IFNAME)
			  break;
		      if (nexthop)
			break;
		    }
		}
	      else
		break;
	    }
	}

      if (compare_state(rib, rnh->state))
	{
	  if (IS_ZEBRA_DEBUG_NHT)
	    {
	      char bufn[INET6_ADDRSTRLEN];
	      char bufp[INET6_ADDRSTRLEN];
	      prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN);
	      if (prn)
		prefix2str(&prn->p, bufp, INET6_ADDRSTRLEN);
	      else
		strcpy(bufp, "null");
	      zlog_debug("rnh %s resolved through route %s - sending "
			 "nexthop %s event to clients", bufn, bufp,
			 rib ? "reachable" : "unreachable");
	    }
	  copy_state(rnh, rib);
	  for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client))
	    send_client(rnh, client, vrfid);
	}
    }
  return 1;
}
コード例 #6
0
ファイル: bgp_fsm.c プロジェクト: LabNConsulting/quagga-vnc
/* This function is the first starting point of all BGP connection. It
   try to connect to remote peer with non-blocking IO. */
int
bgp_start (struct peer *peer)
{
  int status;
  int connected = 0;

  if (BGP_PEER_START_SUPPRESSED (peer))
    {
      if (BGP_DEBUG (fsm, FSM))
        plog_err (peer->log, "%s [FSM] Trying to start suppressed peer"
                  " - this is never supposed to happen!", peer->host);
      return -1;
    }

  /* Scrub some information that might be left over from a previous,
   * session
   */
  /* Connection information. */
  if (peer->su_local)
    {
      sockunion_free (peer->su_local);
      peer->su_local = NULL;
    }

  if (peer->su_remote)
    {
      sockunion_free (peer->su_remote);
      peer->su_remote = NULL;
    }

  /* Clear remote router-id. */
  peer->remote_id.s_addr = 0;

  /* Clear peer capability flag. */
  peer->cap = 0;
    
  /* If the peer is passive mode, force to move to Active mode. */
  if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE))
    {
      BGP_EVENT_ADD (peer, TCP_connection_open_failed);
      return 0;
    }

  /* Register to be notified on peer up */
  if ((peer->ttl == 1) || (peer->gtsm_hops == 1))
    connected = 1;

  bgp_find_or_add_nexthop(family2afi(peer->su.sa.sa_family), NULL, peer,
			  connected);
  status = bgp_connect (peer);

  switch (status)
    {
    case connect_error:
      if (BGP_DEBUG (fsm, FSM))
	plog_debug (peer->log, "%s [FSM] Connect error", peer->host);
      BGP_EVENT_ADD (peer, TCP_connection_open_failed);
      break;
    case connect_success:
      if (BGP_DEBUG (fsm, FSM))
	plog_debug (peer->log, "%s [FSM] Connect immediately success",
		   peer->host);
      BGP_EVENT_ADD (peer, TCP_connection_open);
      break;
    case connect_in_progress:
      /* To check nonblocking connect, we wait until socket is
         readable or writable. */
      if (BGP_DEBUG (fsm, FSM))
	plog_debug (peer->log, "%s [FSM] Non blocking connect waiting result",
		   peer->host);
      if (peer->fd < 0)
	{
	  zlog_err ("bgp_start peer's fd is negative value %d",
		    peer->fd);
	  return -1;
	}
      BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
      BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
      break;
    }
  return 0;
}