Esempio n. 1
0
/* Inteface addition message from zebra. */
static int
bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length,
    vrf_id_t vrf_id)
{
  struct interface *ifp;

  ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);

  if (BGP_DEBUG(zebra, ZEBRA) && ifp)
    zlog_debug("Zebra rcvd: interface add %s", ifp->name);

  return 0;
}
Esempio n. 2
0
/* 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;

  status = bgp_connect (peer);

  switch (status)
    {
    case connect_error:
      if (BGP_DEBUG (fsm, FSM))
	plog_info (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_info (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_info (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;
}
Esempio n. 3
0
/* BGP try to connect to the peer.  */
int
bgp_connect (struct peer *peer)
{
  ifindex_t ifindex = 0;

  /* Make socket for the peer. */
  peer->fd = sockunion_socket (&peer->su);
  if (peer->fd < 0)
    return -1;

  set_nonblocking (peer->fd);

  /* Set socket send buffer size */
  bgp_update_sock_send_buffer_size(peer->fd);

  bgp_set_socket_ttl (peer, peer->fd);

  sockopt_reuseaddr (peer->fd);
  sockopt_reuseport (peer->fd);
  
#ifdef IPTOS_PREC_INTERNETCONTROL
  if (bgpd_privs.change (ZPRIVS_RAISE))
    zlog_err ("%s: could not raise privs", __func__);
  if (sockunion_family (&peer->su) == AF_INET)
    setsockopt_ipv4_tos (peer->fd, IPTOS_PREC_INTERNETCONTROL);
  else if (sockunion_family (&peer->su) == AF_INET6)
    setsockopt_ipv6_tclass (peer->fd, IPTOS_PREC_INTERNETCONTROL);
  if (bgpd_privs.change (ZPRIVS_LOWER))
    zlog_err ("%s: could not lower privs", __func__);
#endif

  if (peer->password)
    bgp_md5_set_connect (peer->fd, &peer->su, peer->password);

  /* Bind socket. */
  bgp_bind (peer);

  /* Update source bind. */
  bgp_update_source (peer);

  if (peer->ifname)
    ifindex = ifname2ifindex (peer->ifname);

  if (BGP_DEBUG (events, EVENTS))
    plog_debug (peer->log, "%s [Event] Connect start to %s fd %d",
	       peer->host, peer->host, peer->fd);

  /* Connect to the remote peer. */
  return sockunion_connect (peer->fd, &peer->su, htons (peer->port), ifindex);
}
Esempio n. 4
0
static int
bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length)
{
  struct stream *s;
  struct interface *ifp;
  struct connected *c;
  struct listnode *node, *nnode;

  s = zclient->ibuf;
  ifp = zebra_interface_state_read (s);
  if (! ifp)
    return 0;

  if (BGP_DEBUG(zebra, ZEBRA))
    zlog_debug("Zebra rcvd: interface %s down", ifp->name);

  for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
    bgp_connected_delete (c);

  /* Fast external-failover (Currently IPv4 only) */
  {
    struct listnode *mnode;
    struct bgp *bgp;
    struct peer *peer;
    struct interface *peer_if;

    for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
      {
	if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
	  continue;

	for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
	  {
	    if (peer->ttl != 1)
	      continue;

	    if (peer->su.sa.sa_family == AF_INET)
	      peer_if = if_lookup_by_ipv4 (&peer->su.sin.sin_addr);
	    else
	      continue;

	    if (ifp == peer_if)
	      BGP_EVENT_ADD (peer, BGP_Stop);
	  }
      }
  }

  return 0;
}
/* Called after event occured, this function change status and reset
   read/write and timer thread. */
void
bgp_fsm_change_status (struct peer *peer, int status)
{
  bgp_dump_state (peer, peer->status, status);

  /* Preserve old status and change into new status. */
  peer->ostatus = peer->status;
  peer->status = status;

  if (BGP_DEBUG (normal, NORMAL))
    zlog_debug ("%s went from %s to %s",
		peer->host,
		LOOKUP (bgp_status_msg, peer->ostatus),
		LOOKUP (bgp_status_msg, peer->status));
}
Esempio n. 6
0
/* Called after event occured, this function change status and reset
   read/write and timer thread. */
void
bgp_fsm_change_status (struct peer *peer, int status)
{
  bgp_dump_state (peer, peer->status, status);

  /* Preserve old status and change into new status. */
  peer->ostatus = peer->status;
  peer->status = status;

  if (BGP_DEBUG (normal, NORMAL))
    if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
      zlog_info ("%s went from %s to %s", peer->host,
		 LOOKUP (bgp_status_msg, peer->ostatus),
		 LOOKUP (bgp_status_msg, peer->status));
}
Esempio n. 7
0
/* dump notify packet */
void
bgp_notify_print(struct peer *peer, struct bgp_notify *bgp_notify, 
                 const char *direct)
{
  const char *subcode_str;

  subcode_str = "";

  switch (bgp_notify->code) 
    {
    case BGP_NOTIFY_HEADER_ERR:
      subcode_str = LOOKUP (bgp_notify_head_msg, bgp_notify->subcode);
      break;
    case BGP_NOTIFY_OPEN_ERR:
      subcode_str = LOOKUP (bgp_notify_open_msg, bgp_notify->subcode);
      break;
    case BGP_NOTIFY_UPDATE_ERR:
      subcode_str = LOOKUP (bgp_notify_update_msg, bgp_notify->subcode);
      break;
    case BGP_NOTIFY_HOLD_ERR:
      subcode_str = "";
      break;
    case BGP_NOTIFY_FSM_ERR:
      subcode_str = "";
      break;
    case BGP_NOTIFY_CEASE:
      subcode_str = LOOKUP (bgp_notify_cease_msg, bgp_notify->subcode);
      break;
    case BGP_NOTIFY_CAPABILITY_ERR:
      subcode_str = LOOKUP (bgp_notify_capability_msg, bgp_notify->subcode);
      break;
    }

  if (bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
    zlog_info ("%%NOTIFICATION: %s neighbor %s %d/%d (%s%s) %d bytes %s",
              strcmp (direct, "received") == 0 ? "received from" : "sent to",
              peer->host, bgp_notify->code, bgp_notify->subcode,
               LOOKUP (bgp_notify_msg, bgp_notify->code),
              subcode_str, bgp_notify->length,
              bgp_notify->data ? bgp_notify->data : "");
  else if (BGP_DEBUG (normal, NORMAL))
    plog_debug (peer->log, "%s %s NOTIFICATION %d/%d (%s%s) %d bytes %s",
	       peer ? peer->host : "",
	       direct, bgp_notify->code, bgp_notify->subcode,
	       LOOKUP (bgp_notify_msg, bgp_notify->code),
	       subcode_str, bgp_notify->length,
	       bgp_notify->data ? bgp_notify->data : "");
}
Esempio n. 8
0
static int
bgp_interface_delete (int command, struct zclient *zclient,
		      zebra_size_t length)
{
  struct stream *s;
  struct interface *ifp;

  s = zclient->ibuf;
  ifp = zebra_interface_state_read (s);
  ifp->ifindex = IFINDEX_INTERNAL;

  if (BGP_DEBUG(zebra, ZEBRA))
    zlog_debug("Zebra rcvd: interface delete %s", ifp->name);

  return 0;
}
Esempio n. 9
0
/* BGP scan thread.  This thread check nexthop reachability. */
static int
bgp_scan_timer (struct thread *t)
{
  bgp_scan_thread =
    thread_add_timer (master, bgp_scan_timer, NULL, bgp_scan_interval);

  if (BGP_DEBUG (events, EVENTS))
    zlog_debug ("Performing BGP general scanning");

  bgp_scan (AFI_IP, SAFI_UNICAST);

#ifdef HAVE_IPV6
  bgp_scan (AFI_IP6, SAFI_UNICAST);
#endif /* HAVE_IPV6 */

  return 0;
}
Esempio n. 10
0
/* BGP connect retry timer. */
static int
bgp_connect_timer (struct thread *thread)
{
  struct peer *peer;

  peer = THREAD_ARG (thread);
  peer->t_connect = NULL;

  if (BGP_DEBUG (fsm, FSM))
    zlog (peer->log, LOG_DEBUG, "%s [FSM] Timer (connect timer expire)",
	  peer->host);

  THREAD_VAL (thread) = ConnectRetry_timer_expired;
  bgp_event (thread); /* bgp_event unlocks peer */

  return 0;
}
Esempio n. 11
0
/* BGP try to connect to the peer.  */
int
bgp_connect (struct peer *peer)
{
  unsigned int ifindex = 0;

  /* Make socket for the peer. */
  peer->fd = sockunion_socket (&peer->su);
  if (peer->fd < 0)
    return -1;

  /* If we can get socket for the peer, adjest TTL and make connection. */
  if (peer_sort (peer) == BGP_PEER_EBGP) {
    sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
    if (peer->gtsm_hops)
      sockopt_minttl (peer->su.sa.sa_family, peer->fd, MAXTTL + 1 - peer->gtsm_hops);
  }

  sockopt_reuseaddr (peer->fd);
  sockopt_reuseport (peer->fd);
  
#ifdef IPTOS_PREC_INTERNETCONTROL
  if (sockunion_family (&peer->su) == AF_INET)
    setsockopt_ipv4_tos (peer->fd, IPTOS_PREC_INTERNETCONTROL);
#endif

  if (peer->password)
    bgp_md5_set_connect (peer->fd, &peer->su, peer->password);

  /* Bind socket. */
  bgp_bind (peer);

  /* Update source bind. */
  bgp_update_source (peer);

#ifdef HAVE_IPV6
  if (peer->ifname)
    ifindex = if_nametoindex (peer->ifname);
#endif /* HAVE_IPV6 */

  if (BGP_DEBUG (events, EVENTS))
    plog_debug (peer->log, "%s [Event] Connect start to %s fd %d",
	       peer->host, peer->host, peer->fd);

  /* Connect to the remote peer. */
  return sockunion_connect (peer->fd, &peer->su, htons (peer->port), ifindex);
}
Esempio n. 12
0
/* BGP start timer.  This function set BGP_Start event to thread value
   and process event. */
static int
bgp_start_timer (struct thread *thread)
{
  struct peer *peer;

  peer = THREAD_ARG (thread);
  peer->t_start = NULL;

  if (BGP_DEBUG (fsm, FSM))
    zlog (peer->log, LOG_DEBUG,
	  "%s [FSM] Timer (start timer expire).", peer->host);

  THREAD_VAL (thread) = BGP_Start;
  bgp_event (thread);  /* bgp_event unlocks peer */

  return 0;
}
Esempio n. 13
0
/* BGP holdtime timer. */
static int
bgp_holdtime_timer (struct thread *thread)
{
  struct peer *peer;

  peer = THREAD_ARG (thread);
  peer->t_holdtime = NULL;

  if (BGP_DEBUG (fsm, FSM))
    zlog (peer->log, LOG_DEBUG,
	  "%s [FSM] Timer (holdtime timer expire)",
	  peer->host);

  THREAD_VAL (thread) = Hold_Timer_expired;
  bgp_event (thread);

  return 0;
}
Esempio n. 14
0
/* BGP keepalive fire ! */
static int
bgp_keepalive_timer (struct thread *thread)
{
  struct peer *peer;

  peer = THREAD_ARG (thread);
  peer->t_keepalive = NULL;

  if (BGP_DEBUG (fsm, FSM))
    zlog (peer->log, LOG_DEBUG,
	  "%s [FSM] Timer (keepalive timer expire)",
	  peer->host);

  THREAD_VAL (thread) = KeepAlive_timer_expired;
  bgp_event (thread); /* bgp_event unlocks peer */

  return 0;
}
Esempio n. 15
0
/* BGP start timer.  This function set BGP_Start event to thread value
   and process event. */
static int
bgp_start_timer (struct thread *thread)
{
  struct peer *peer;

  peer = THREAD_ARG (thread);
  peer->t_start = NULL;

  UNSET_FLAG (peer->sflags, PEER_STATUS_CREATE_INIT);

  if (BGP_DEBUG (fsm, FSM))
    zlog (peer->log, LOG_DEBUG,
	  "%s [FSM] Timer (start timer expire).", peer->host);

  THREAD_VAL (thread) = BGP_Start;
  bgp_event (thread);

  return 0;
}
/* Hold timer expire.  This is error of BGP connection. So cut the
   peer and change to Idle status. */
static int
bgp_fsm_holdtime_expire (struct peer *peer)
{
  if (BGP_DEBUG (fsm, FSM))
    zlog (peer->log, LOG_DEBUG, "%s [FSM] Hold timer expire", peer->host);

  /* Send notify to remote peer. */
  bgp_notify_send (peer, BGP_NOTIFY_HOLD_ERR, 0);

  /* Sweep if it is temporary peer. */
  if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
    {
      zlog_info ("%s [Event] Accepting BGP peer is deleted", peer->host);
      peer_delete (peer);
      return -1;
    }

  return 0;
}
Esempio n. 17
0
static as_t
bgp_capability_as4 (struct peer *peer, struct capability_header *hdr)
{
  SET_FLAG (peer->cap, PEER_CAP_AS4_RCV);
  
  if (hdr->length != CAPABILITY_CODE_AS4_LEN)
    {
      zlog_err ("%s AS4 capability has incorrect data length %d",
                peer->host, hdr->length);
      return 0;
    }
  
  as_t as4 = stream_getl (BGP_INPUT(peer));
  
  if (BGP_DEBUG (as4, AS4))
    zlog_debug ("%s [AS4] about to set cap PEER_CAP_AS4_RCV, got as4 %u",
                peer->host, as4);
  return as4;
}
/* Execute event process. */
int
bgp_event (struct thread *thread)
{
  int ret = 0;
  int event;
  int next;
  struct peer *peer;

  peer = THREAD_ARG (thread);
  event = THREAD_VAL (thread);

  /* Logging this event. */
  next = FSM [peer->status -1][event - 1].next_state;

  if (BGP_DEBUG (fsm, FSM) && peer->status != next)
    plog_debug (peer->log, "%s [FSM] %s (%s->%s)", peer->host, 
	       bgp_event_str[event],
	       LOOKUP (bgp_status_msg, peer->status),
	       LOOKUP (bgp_status_msg, next));

  /* Call function. */
  if (FSM [peer->status -1][event - 1].func)
    ret = (*(FSM [peer->status - 1][event - 1].func))(peer);

  /* When function do not want proceed next job return -1. */
  if (ret >= 0)
    {
      /* If status is changed. */
      if (next != peer->status)
        {
          /* Transition into Clearing must /always/ clear all routes.. */
          if (next == Clearing)
            bgp_clear_route_all (peer);
          
          bgp_fsm_change_status (peer, next);
        }
      
      /* Make sure timer is set. */
      bgp_timer_set (peer);
    }
  
  return ret;
}
Esempio n. 19
0
static int
bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length)
{
  struct stream *s;
  struct interface *ifp;
  struct connected *c;
  struct listnode *node, *nnode;

  s = zclient->ibuf;
  ifp = zebra_interface_state_read (s);
  if (! ifp)
    return 0;

  if (BGP_DEBUG(zebra, ZEBRA))
    zlog_debug("Zebra rcvd: interface %s down", ifp->name);

  for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
    bgp_connected_delete (c);

  /* Fast external-failover */
  {
    struct listnode *mnode;
    struct bgp *bgp;
    struct peer *peer;

    for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
      {
	if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
	  continue;

	for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
	  {
	    if ((peer->ttl != 1) && (peer->gtsm_hops != 1))
	      continue;

	    if (ifp == peer->nexthop.ifp)
	      BGP_EVENT_ADD (peer, BGP_Stop);
	  }
      }
  }

  return 0;
}
Esempio n. 20
0
/* Router-id update message from zebra. */
static int
bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length,
    vrf_id_t vrf_id)
{
  struct prefix router_id;

  zebra_router_id_update_read(zclient->ibuf,&router_id);

  if (BGP_DEBUG(zebra, ZEBRA))
    {
      char buf[128];
      prefix2str(&router_id, buf, sizeof(buf));
      zlog_debug("Zebra rcvd: router id update %s", buf);
    }

  router_id_zebra = router_id.u.prefix4;

  bgp_router_id_zebra_bump ();
  return 0;
}
Esempio n. 21
0
int
bgp_routeadv_timer_vpnv4_unicast (struct thread *thread)
{
  struct peer *peer;

  peer = THREAD_ARG (thread);
  peer->t_routeadv[AFI_IP][SAFI_MPLS_VPN] = NULL;

  if (BGP_DEBUG (events, EVENTS))
    zlog_info ("%s routeadv timer expired for VPNv4 unicast", peer->host);

  peer->synctime[AFI_IP][SAFI_MPLS_VPN] = time (NULL);

  BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);

  BGP_TIMER_ON (peer->t_routeadv[AFI_IP][SAFI_MPLS_VPN], bgp_routeadv_timer_vpnv4_unicast,
		peer->v_routeadv);

  return 0;
}
Esempio n. 22
0
/* Called after event occured, this function change status and reset
   read/write and timer thread. */
void
bgp_fsm_change_status (struct peer *peer, int status)
{
  bgp_dump_state (peer, peer->status, status);

  /* Transition into Clearing or Deleted must /always/ clear all routes.. 
   * (and must do so before actually changing into Deleted..
   */
  if (status >= Clearing)
    bgp_clear_route_all (peer);
  
  /* Preserve old status and change into new status. */
  peer->ostatus = peer->status;
  peer->status = status;
  
  if (BGP_DEBUG (normal, NORMAL))
    zlog_debug ("%s went from %s to %s",
		peer->host,
		LOOKUP (bgp_status_msg, peer->ostatus),
		LOOKUP (bgp_status_msg, peer->status));
}
Esempio n. 23
0
static int
bgp_graceful_stale_timer_expire (struct thread *thread)
{
  struct peer *peer;
  afi_t afi;
  safi_t safi;

  peer = THREAD_ARG (thread);
  peer->t_gr_stale = NULL;

  if (BGP_DEBUG (events, EVENTS))
    zlog_debug ("%s graceful restart stalepath timer expired", peer->host);

  /* NSF delete stale route */
  for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
    for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
      if (peer->nsf[afi][safi])
	bgp_clear_stale_route (peer, afi, safi);

  return 0;
}
Esempio n. 24
0
/* BGP try to connect to the peer.  */
int
bgp_connect (struct peer *peer)
{
  unsigned int ifindex = 0;

  /* Make socket for the peer. */
  peer->fd = sockunion_socket (&peer->su);
  if (peer->fd < 0)
    return -1;

  /* If we can get socket for the peer, adjest TTL and make connection. */
  if (peer_sort (peer) == BGP_PEER_EBGP)
    sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);

  sockopt_reuseaddr (peer->fd);
  sockopt_reuseport (peer->fd);

  /* Bind socket. */
  bgp_bind (peer);

  /* Update source bind. */
  bgp_update_source (peer);

#ifdef HAVE_IPV6
  if (peer->ifname)
    ifindex = if_nametoindex (peer->ifname);
#endif /* HAVE_IPV6 */

  if (BGP_DEBUG (events, EVENTS))
    plog_info (peer->log, "%s [Event] Connect start to %s fd %d",
	       peer->host, peer->host, peer->fd);

#ifdef HAVE_TCP_SIGNATURE
  if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD))
    bgp_tcpsig_set (peer->fd, peer);
#endif /* HAVE_TCP_SIGNATURE */

  /* Connect to the remote peer. */
  return sockunion_connect (peer->fd, &peer->su, htons (peer->port), ifindex);
}
Esempio n. 25
0
static int
bgp_routeadv_timer (struct thread *thread)
{
  struct peer *peer;

  peer = THREAD_ARG (thread);
  peer->t_routeadv = NULL;

  if (BGP_DEBUG (fsm, FSM))
    zlog (peer->log, LOG_DEBUG,
	  "%s [FSM] Timer (routeadv timer expire)",
	  peer->host);

  peer->synctime = bgp_clock ();

  BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);

  BGP_TIMER_ON (peer->t_routeadv, bgp_routeadv_timer,
		peer->v_routeadv);

  return 0;
}
Esempio n. 26
0
/* BGP Network Routes Scan */
s_int32_t
bnh_network_scan (struct thread *t_network_scan)
{
  struct lib_globals *blg;
  struct bgp *bgp;
  s_int32_t ret;

  ret = 0;
  bgp = THREAD_ARG (t_network_scan);
  blg = THREAD_GLOB (t_network_scan);

  if (! blg || &BLG != blg || ! bgp)
    {
      ret = -1;
      goto EXIT;
    }

  bgp->t_network_scan = NULL;

  BGP_SET_VR_CONTEXT (&BLG, bgp->owning_bvr);

  if (BGP_DEBUG (normal, NORMAL))
    zlog_info (&BLG, "[RIB] Scanning BGP Network Routes...");

  bnh_network_scan_afi (bgp, AFI_IP);

#ifdef HAVE_IPV6
  IF_BGP_CAP_HAVE_IPV6
    bnh_network_scan_afi (bgp, AFI_IP6);
#endif /* HAVE_IPV6 */

  if (bgp->network_scan_interval)
    BGP_TIMER_ON (&BLG, bgp->t_network_scan, bgp, bnh_network_scan,
                  bgp->network_scan_interval);

EXIT:

  return ret;
}
Esempio n. 27
0
static int
bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length)
{
  struct stream *s;
  struct interface *ifp;
  struct connected *c;
  struct listnode *node, *nnode;

  s = zclient->ibuf;
  ifp = zebra_interface_state_read (s);

  if (! ifp)
    return 0;

  if (BGP_DEBUG(zebra, ZEBRA))
    zlog_debug("Zebra rcvd: interface %s up", ifp->name);

  for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
    bgp_connected_add (c);

  return 0;
}
Esempio n. 28
0
/* Unset redistribution.  */
int
bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type)
{
  /* Unset flag from BGP instance. */
  bgp->redist[afi][type] = 0;

  /* Unset route-map. */
  if (bgp->rmap[afi][type].name)
    free (bgp->rmap[afi][type].name);
  bgp->rmap[afi][type].name = NULL;
  bgp->rmap[afi][type].map = NULL;

  /* Unset metric. */
  bgp->redist_metric_flag[afi][type] = 0;
  bgp->redist_metric[afi][type] = 0;

  /* Return if zebra connection is disabled. */
  if (! vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
    return CMD_WARNING;
  vrf_bitmap_unset (zclient->redist[type], VRF_DEFAULT);

  if (bgp->redist[AFI_IP][type] == 0 
      && bgp->redist[AFI_IP6][type] == 0 
      && zclient->sock >= 0)
    {
      /* Send distribute delete message to zebra. */
      if (BGP_DEBUG(zebra, ZEBRA))
	zlog_debug("Zebra send: redistribute delete %s",
		   zebra_route_string(type));
      zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type,
                               VRF_DEFAULT);
    }
  
  /* Withdraw redistributed routes from current BGP's routing table. */
  bgp_redistribute_withdraw (bgp, afi, type);

  return CMD_SUCCESS;
}
Esempio n. 29
0
/* Called after event occured, this function change status and reset
   read/write and timer thread. */
void
bgp_fsm_change_status (struct peer *peer, int status)
{
  bgp_dump_state (peer, peer->status, status);

  /* Transition into Clearing or Deleted must /always/ clear all routes.. 
   * (and must do so before actually changing into Deleted..
   */
  if (status >= Clearing)
    {
      bgp_clear_route_all (peer);

      /* If no route was queued for the clear-node processing, generate the
       * completion event here. This is needed because if there are no routes
       * to trigger the background clear-node thread, the event won't get
       * generated and the peer would be stuck in Clearing. Note that this
       * event is for the peer and helps the peer transition out of Clearing
       * state; it should not be generated per (AFI,SAFI). The event is
       * directly posted here without calling clear_node_complete() as we
       * shouldn't do an extra unlock. This event will get processed after
       * the state change that happens below, so peer will be in Clearing
       * (or Deleted).
       */
      if (!work_queue_is_scheduled (peer->clear_node_queue))
        BGP_EVENT_ADD (peer, Clearing_Completed);
    }
  
  /* Preserve old status and change into new status. */
  peer->ostatus = peer->status;
  peer->status = status;
  
  if (BGP_DEBUG (normal, NORMAL))
    zlog_debug ("%s went from %s to %s",
		peer->host,
		LOOKUP (bgp_status_msg, peer->ostatus),
		LOOKUP (bgp_status_msg, peer->status));
}
Esempio n. 30
0
/* Other routes redistribution into BGP. */
int
bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
{
  /* Set flag to BGP instance. */
  bgp->redist[afi][type] = 1;

  /* Return if already redistribute flag is set. */
  if (zclient->redist[type])
    return CMD_WARNING;

  zclient->redist[type] = 1;

  /* Return if zebra connection is not established. */
  if (zclient->sock < 0)
    return CMD_WARNING;

  if (BGP_DEBUG(zebra, ZEBRA))
    zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
    
  /* Send distribute add message to zebra. */
  zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);

  return CMD_SUCCESS;
}