mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-29 12:18:12 +00:00
bgpd-nht-connected-route.patch
BGP: Use next hop tracking for connected routes too And cleanup obsolete code in bgp_scan and bgp_import.
This commit is contained in:
parent
9f0ea7d4f2
commit
fc9a856f70
@ -1185,6 +1185,7 @@ int
|
||||
bgp_start (struct peer *peer)
|
||||
{
|
||||
int status;
|
||||
int connected = 0;
|
||||
|
||||
bgp_peer_conf_if_to_su_update(peer);
|
||||
|
||||
@ -1225,6 +1226,12 @@ bgp_start (struct peer *peer)
|
||||
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)
|
||||
@ -1492,6 +1499,45 @@ bgp_ignore (struct peer *peer)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
bgp_fsm_nht_update(struct peer *peer, int valid)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!peer)
|
||||
return;
|
||||
|
||||
switch (peer->status)
|
||||
{
|
||||
case Idle:
|
||||
if (valid)
|
||||
BGP_EVENT_ADD(peer, BGP_Start);
|
||||
break;
|
||||
case Connect:
|
||||
ret = bgp_connect_check(peer, 0);
|
||||
if (!ret && valid)
|
||||
{
|
||||
BGP_TIMER_OFF(peer->t_connect);
|
||||
BGP_EVENT_ADD(peer, ConnectRetry_timer_expired);
|
||||
}
|
||||
break;
|
||||
case Active:
|
||||
if (valid)
|
||||
{
|
||||
BGP_TIMER_OFF(peer->t_connect);
|
||||
BGP_EVENT_ADD(peer, ConnectRetry_timer_expired);
|
||||
}
|
||||
case OpenSent:
|
||||
case OpenConfirm:
|
||||
case Established:
|
||||
case Clearing:
|
||||
case Deleted:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Finite State Machine structure */
|
||||
static const struct {
|
||||
int (*func) (struct peer *);
|
||||
|
@ -74,6 +74,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#define BGP_MSEC_JITTER 10
|
||||
|
||||
/* Prototypes. */
|
||||
extern void bgp_fsm_nht_update(struct peer *, int valid);
|
||||
extern int bgp_event (struct thread *);
|
||||
extern int bgp_event_update (struct peer *, int event);
|
||||
extern int bgp_stop (struct peer *peer);
|
||||
|
@ -227,7 +227,6 @@ bgp_exit (int status)
|
||||
int *socket;
|
||||
struct interface *ifp;
|
||||
extern struct zclient *zclient;
|
||||
extern struct zclient *zlookup;
|
||||
|
||||
/* it only makes sense for this to be called on a clean exit */
|
||||
assert (status == 0);
|
||||
@ -266,9 +265,6 @@ bgp_exit (int status)
|
||||
/* cleanup route maps */
|
||||
bgp_route_map_terminate();
|
||||
|
||||
/* reverse bgp_scan_init */
|
||||
bgp_scan_finish ();
|
||||
|
||||
/* reverse access_list_init */
|
||||
access_list_add_hook (NULL);
|
||||
access_list_delete_hook (NULL);
|
||||
@ -291,13 +287,14 @@ bgp_exit (int status)
|
||||
vty_terminate ();
|
||||
if (zclient)
|
||||
zclient_free (zclient);
|
||||
if (zlookup)
|
||||
zclient_free (zlookup);
|
||||
if (bgp_nexthop_buf)
|
||||
stream_free (bgp_nexthop_buf);
|
||||
if (bgp_ifindices_buf)
|
||||
stream_free (bgp_ifindices_buf);
|
||||
|
||||
/* reverse bgp_scan_init */
|
||||
bgp_scan_finish ();
|
||||
|
||||
/* reverse bgp_master_init */
|
||||
if (master)
|
||||
thread_master_free (master);
|
||||
|
1057
bgpd/bgp_nexthop.c
1057
bgpd/bgp_nexthop.c
File diff suppressed because it is too large
Load Diff
@ -25,21 +25,9 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "queue.h"
|
||||
#include "prefix.h"
|
||||
|
||||
#define BGP_SCAN_INTERVAL_DEFAULT 60
|
||||
#define BGP_IMPORT_INTERVAL_DEFAULT 15
|
||||
|
||||
/* BGP nexthop cache value structure. */
|
||||
struct bgp_nexthop_cache
|
||||
{
|
||||
/* This nexthop exists in IGP. */
|
||||
u_char valid;
|
||||
|
||||
/* Nexthop is changed. */
|
||||
u_char changed;
|
||||
|
||||
/* Nexthop is changed. */
|
||||
u_char metricchanged;
|
||||
|
||||
/* IGP route's metric. */
|
||||
u_int32_t metric;
|
||||
|
||||
@ -51,24 +39,26 @@ struct bgp_nexthop_cache
|
||||
|
||||
#define BGP_NEXTHOP_VALID (1 << 0)
|
||||
#define BGP_NEXTHOP_REGISTERED (1 << 1)
|
||||
#define BGP_NEXTHOP_CONNECTED (1 << 2)
|
||||
#define BGP_NEXTHOP_PEER_NOTIFIED (1 << 3)
|
||||
|
||||
u_int16_t change_flags;
|
||||
|
||||
#define BGP_NEXTHOP_CHANGED (1 << 0)
|
||||
#define BGP_NEXTHOP_METRIC_CHANGED (1 << 1)
|
||||
#define BGP_NEXTHOP_CONNECTED_CHANGED (1 << 2)
|
||||
|
||||
struct bgp_node *node;
|
||||
void *nht_info; /* In BGP, peer session */
|
||||
LIST_HEAD(path_list, bgp_info) paths;
|
||||
unsigned int path_count;
|
||||
};
|
||||
|
||||
extern void bgp_scan_init (void);
|
||||
extern void bgp_scan_finish (void);
|
||||
extern int bgp_nexthop_lookup (afi_t, struct peer *peer, struct bgp_info *,
|
||||
int *, int *);
|
||||
extern void bgp_connected_add (struct connected *c);
|
||||
extern void bgp_connected_delete (struct connected *c);
|
||||
extern int bgp_multiaccess_check_v4 (struct in_addr, char *);
|
||||
extern int bgp_multiaccess_check_v4 (struct in_addr, struct peer *);
|
||||
extern int bgp_config_write_scan_time (struct vty *);
|
||||
extern int bgp_nexthop_onlink (afi_t, struct attr *);
|
||||
extern int bgp_nexthop_self (struct attr *);
|
||||
|
@ -50,19 +50,15 @@ static void path_nh_map(struct bgp_info *path, struct bgp_nexthop_cache *bnc,
|
||||
int keep);
|
||||
|
||||
int
|
||||
bgp_find_nexthop (struct bgp_info *path, int *changed, int *metricchanged)
|
||||
bgp_find_nexthop (struct bgp_info *path, int connected)
|
||||
{
|
||||
struct bgp_nexthop_cache *bnc = path->nexthop;
|
||||
|
||||
if (!bnc)
|
||||
return 0;
|
||||
|
||||
if (changed)
|
||||
*changed = CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED);
|
||||
|
||||
if (metricchanged)
|
||||
*metricchanged = CHECK_FLAG(bnc->change_flags,
|
||||
BGP_NEXTHOP_METRIC_CHANGED);
|
||||
if (connected && !(CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED)))
|
||||
return 0;
|
||||
|
||||
return (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID));
|
||||
}
|
||||
@ -77,7 +73,7 @@ bgp_unlink_nexthop (struct bgp_info *path)
|
||||
|
||||
path_nh_map(path, NULL, 0);
|
||||
|
||||
if (LIST_EMPTY(&(bnc->paths)))
|
||||
if (LIST_EMPTY(&(bnc->paths)) && !bnc->nht_info)
|
||||
{
|
||||
if (BGP_DEBUG(nht, NHT))
|
||||
{
|
||||
@ -93,15 +89,34 @@ bgp_unlink_nexthop (struct bgp_info *path)
|
||||
}
|
||||
|
||||
int
|
||||
bgp_find_or_add_nexthop (afi_t afi, struct bgp_info *ri, int *changed,
|
||||
int *metricchanged)
|
||||
bgp_find_or_add_nexthop (afi_t afi, struct bgp_info *ri, struct peer *peer,
|
||||
int connected)
|
||||
{
|
||||
struct bgp_node *rn;
|
||||
struct bgp_nexthop_cache *bnc;
|
||||
struct prefix p;
|
||||
|
||||
if (ri)
|
||||
{
|
||||
if (make_prefix(afi, ri, &p) < 0)
|
||||
return 1;
|
||||
}
|
||||
else if (peer)
|
||||
{
|
||||
if (afi == AFI_IP)
|
||||
{
|
||||
p.family = AF_INET;
|
||||
p.prefixlen = IPV4_MAX_BITLEN;
|
||||
p.u.prefix4 = peer->su.sin.sin_addr;
|
||||
}
|
||||
else if (afi == AFI_IP6)
|
||||
{
|
||||
p.family = AF_INET6;
|
||||
p.prefixlen = IPV6_MAX_BITLEN;
|
||||
p.u.prefix6 = peer->su.sin6.sin6_addr;
|
||||
}
|
||||
}
|
||||
|
||||
rn = bgp_node_get (bgp_nexthop_cache_table[afi], &p);
|
||||
|
||||
if (!rn->info)
|
||||
@ -110,23 +125,27 @@ bgp_find_or_add_nexthop (afi_t afi, struct bgp_info *ri, int *changed,
|
||||
rn->info = bnc;
|
||||
bnc->node = rn;
|
||||
bgp_lock_node(rn);
|
||||
register_nexthop(bnc);
|
||||
if (connected)
|
||||
SET_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED);
|
||||
}
|
||||
|
||||
bnc = rn->info;
|
||||
bgp_unlock_node (rn);
|
||||
|
||||
if (!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
|
||||
register_nexthop(bnc);
|
||||
|
||||
if (ri)
|
||||
{
|
||||
path_nh_map(ri, bnc, 1);
|
||||
|
||||
if (changed)
|
||||
*changed = CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED);
|
||||
|
||||
if (metricchanged)
|
||||
*metricchanged = CHECK_FLAG(bnc->change_flags,
|
||||
BGP_NEXTHOP_METRIC_CHANGED);
|
||||
|
||||
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID) && bnc->metric)
|
||||
(bgp_info_extra_get(ri))->igpmetric = bnc->metric;
|
||||
else if (ri->extra)
|
||||
ri->extra->igpmetric = 0;
|
||||
}
|
||||
else if (peer)
|
||||
bnc->nht_info = (void *)peer;
|
||||
|
||||
return (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID));
|
||||
}
|
||||
@ -265,6 +284,7 @@ bgp_parse_nexthop_update (void)
|
||||
else
|
||||
{
|
||||
bnc->flags &= ~BGP_NEXTHOP_VALID;
|
||||
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED);
|
||||
bnc_nexthop_free(bnc);
|
||||
bnc->nexthop = NULL;
|
||||
}
|
||||
@ -322,12 +342,21 @@ sendmsg_nexthop (struct bgp_nexthop_cache *bnc, int command)
|
||||
|
||||
/* Check socket. */
|
||||
if (!zclient || zclient->sock < 0)
|
||||
{
|
||||
zlog_debug("%s: Can't send NH register, Zebra client not established",
|
||||
__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
p = &(bnc->node->p);
|
||||
s = zclient->obuf;
|
||||
stream_reset (s);
|
||||
zclient_create_header (s, command);
|
||||
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED))
|
||||
stream_putc(s, 1);
|
||||
else
|
||||
stream_putc(s, 0);
|
||||
|
||||
stream_putw(s, PREFIX_FAMILY(p));
|
||||
stream_putc(s, p->prefixlen);
|
||||
switch (PREFIX_FAMILY(p))
|
||||
@ -349,6 +378,11 @@ sendmsg_nexthop (struct bgp_nexthop_cache *bnc, int command)
|
||||
/* TBD: handle the failure */
|
||||
if (ret < 0)
|
||||
zlog_warn("sendmsg_nexthop: zclient_send_message() failed");
|
||||
|
||||
if (command == ZEBRA_NEXTHOP_REGISTER)
|
||||
SET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
|
||||
else if (command == ZEBRA_NEXTHOP_UNREGISTER)
|
||||
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -367,7 +401,6 @@ register_nexthop (struct bgp_nexthop_cache *bnc)
|
||||
if (bnc->flags & BGP_NEXTHOP_REGISTERED)
|
||||
return;
|
||||
sendmsg_nexthop(bnc, ZEBRA_NEXTHOP_REGISTER);
|
||||
SET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -385,7 +418,6 @@ unregister_nexthop (struct bgp_nexthop_cache *bnc)
|
||||
return;
|
||||
|
||||
sendmsg_nexthop(bnc, ZEBRA_NEXTHOP_UNREGISTER);
|
||||
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -402,6 +434,7 @@ evaluate_paths (struct bgp_nexthop_cache *bnc)
|
||||
struct bgp_info *path;
|
||||
struct bgp *bgp = bgp_get_default();
|
||||
int afi;
|
||||
struct peer *peer = (struct peer *)bnc->nht_info;
|
||||
|
||||
LIST_FOREACH(path, &(bnc->paths), nh_thread)
|
||||
{
|
||||
@ -444,6 +477,15 @@ evaluate_paths (struct bgp_nexthop_cache *bnc)
|
||||
|
||||
bgp_process(bgp, rn, afi, SAFI_UNICAST);
|
||||
}
|
||||
|
||||
if (peer && !CHECK_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED))
|
||||
{
|
||||
if (BGP_DEBUG(nht, NHT))
|
||||
zlog_debug("%s: Updating peer (%s) status with NHT", __FUNCTION__, peer->host);
|
||||
bgp_fsm_nht_update(peer, CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID));
|
||||
SET_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED);
|
||||
}
|
||||
|
||||
RESET_FLAG(bnc->change_flags);
|
||||
}
|
||||
|
||||
|
@ -31,12 +31,9 @@ extern void bgp_parse_nexthop_update();
|
||||
* bgp_find_nexthop() - lookup the nexthop cache table for the bnc object
|
||||
* ARGUMENTS:
|
||||
* p - path for which the nexthop object is being looked up
|
||||
* c - output variable that stores whether the nexthop object has changed
|
||||
* since last time.
|
||||
* m - output variable that stores whether the nexthop metric has changed
|
||||
* since last time.
|
||||
* connected - True if NH MUST be a connected route
|
||||
*/
|
||||
extern int bgp_find_nexthop(struct bgp_info *p, int *c, int *m);
|
||||
extern int bgp_find_nexthop(struct bgp_info *p, int connected);
|
||||
|
||||
/**
|
||||
* bgp_find_or_add_nexthop() - lookup the nexthop cache table for the bnc
|
||||
@ -45,12 +42,11 @@ extern int bgp_find_nexthop(struct bgp_info *p, int *c, int *m);
|
||||
* ARGUMENTS:
|
||||
* a - afi: AFI_IP or AF_IP6
|
||||
* p - path for which the nexthop object is being looked up
|
||||
* c - output variable that stores whether the nexthop object has changed
|
||||
* since last time.
|
||||
* m - output variable that stores whether the nexthop metric has changed
|
||||
* since last time.
|
||||
* peer - The BGP peer associated with this NHT
|
||||
* connected - True if NH MUST be a connected route
|
||||
*/
|
||||
extern int bgp_find_or_add_nexthop(afi_t a, struct bgp_info *p, int *c, int *m);
|
||||
extern int bgp_find_or_add_nexthop(afi_t a, struct bgp_info *p,
|
||||
struct peer *peer, int connected);
|
||||
|
||||
/**
|
||||
* bgp_unlink_nexthop() - Unlink the nexthop object from the path structure.
|
||||
|
@ -100,8 +100,8 @@ bgp_packet_delete (struct peer *peer)
|
||||
}
|
||||
|
||||
/* Check file descriptor whether connect is established. */
|
||||
static void
|
||||
bgp_connect_check (struct peer *peer)
|
||||
int
|
||||
bgp_connect_check (struct peer *peer, int change_state)
|
||||
{
|
||||
int status;
|
||||
socklen_t slen;
|
||||
@ -120,20 +120,23 @@ bgp_connect_check (struct peer *peer)
|
||||
{
|
||||
zlog (peer->log, LOG_INFO, "can't get sockopt for nonblocking connect");
|
||||
BGP_EVENT_ADD (peer, TCP_fatal_error);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* When status is 0 then TCP connection is established. */
|
||||
if (status == 0)
|
||||
{
|
||||
BGP_EVENT_ADD (peer, TCP_connection_open);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BGP_DEBUG (events, EVENTS))
|
||||
plog_debug (peer->log, "%s [Event] Connect failed (%s)",
|
||||
peer->host, safe_strerror (errno));
|
||||
if (change_state)
|
||||
BGP_EVENT_ADD (peer, TCP_connection_open_failed);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -698,7 +701,7 @@ bgp_write (struct thread *thread)
|
||||
/* For non-blocking IO check. */
|
||||
if (peer->status == Connect)
|
||||
{
|
||||
bgp_connect_check (peer);
|
||||
bgp_connect_check (peer, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2541,7 +2544,7 @@ bgp_read (struct thread *thread)
|
||||
/* For non-blocking IO check. */
|
||||
if (peer->status == Connect)
|
||||
{
|
||||
bgp_connect_check (peer);
|
||||
bgp_connect_check (peer, 1);
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
|
@ -40,6 +40,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
/* Packet send and receive function prototypes. */
|
||||
extern int bgp_read (struct thread *);
|
||||
extern int bgp_write (struct thread *);
|
||||
extern int bgp_connect_check (struct peer *, int change_state);
|
||||
|
||||
extern void bgp_keepalive_send (struct peer *);
|
||||
extern void bgp_open_send (struct peer *);
|
||||
|
143
bgpd/bgp_route.c
143
bgpd/bgp_route.c
@ -55,7 +55,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "bgpd/bgp_zebra.h"
|
||||
#include "bgpd/bgp_vty.h"
|
||||
#include "bgpd/bgp_mpath.h"
|
||||
#include "bgpd/bgp_nht.c"
|
||||
#include "bgpd/bgp_nht.h"
|
||||
|
||||
/* Extern from bgp_dump.c */
|
||||
extern const char *bgp_origin_str[];
|
||||
@ -1064,7 +1064,7 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
|
||||
IN6_IS_ADDR_UNSPECIFIED(&attr->extra->mp_nexthop_global))
|
||||
#endif /* HAVE_IPV6 */
|
||||
|| (peer->sort == BGP_PEER_EBGP
|
||||
&& bgp_multiaccess_check_v4 (attr->nexthop, peer->host) == 0))
|
||||
&& (bgp_multiaccess_check_v4 (attr->nexthop, peer) == 0)))
|
||||
{
|
||||
/* Set IPv4 nexthop. */
|
||||
if (p->family == AF_INET)
|
||||
@ -2229,6 +2229,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
|
||||
struct bgp_info *new;
|
||||
const char *reason;
|
||||
char buf[SU_ADDRSTRLEN];
|
||||
int connected = 0;
|
||||
|
||||
bgp = peer->bgp;
|
||||
rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
|
||||
@ -2306,17 +2307,6 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
|
||||
/* IPv4 unicast next hop check. */
|
||||
if (afi == AFI_IP && safi == SAFI_UNICAST)
|
||||
{
|
||||
/* If the peer is EBGP and nexthop is not on connected route,
|
||||
discard it. */
|
||||
if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1
|
||||
&& ! bgp_nexthop_onlink (afi, &new_attr)
|
||||
&& ! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
|
||||
{
|
||||
reason = "non-connected next-hop;";
|
||||
bgp_attr_flush (&new_attr);
|
||||
goto filtered;
|
||||
}
|
||||
|
||||
/* Next hop must not be 0.0.0.0 nor Class D/E address. Next hop
|
||||
must not be my own address. */
|
||||
if (new_attr.nexthop.s_addr == 0
|
||||
@ -2443,18 +2433,27 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
|
||||
}
|
||||
|
||||
/* Nexthop reachability check. */
|
||||
if ((afi == AFI_IP || afi == AFI_IP6)
|
||||
&& safi == SAFI_UNICAST
|
||||
&& (peer->sort == BGP_PEER_IBGP
|
||||
|| peer->sort == BGP_PEER_CONFED
|
||||
|| (peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
|
||||
|| CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)))
|
||||
if ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST)
|
||||
{
|
||||
if (bgp_find_or_add_nexthop (afi, ri, NULL, NULL))
|
||||
if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1 &&
|
||||
! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
|
||||
connected = 1;
|
||||
else
|
||||
connected = 0;
|
||||
|
||||
if (bgp_find_or_add_nexthop (afi, ri, NULL, connected))
|
||||
bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
|
||||
else
|
||||
{
|
||||
if (BGP_DEBUG(nht, NHT))
|
||||
{
|
||||
char buf1[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, (const void *)&attr_new->nexthop, buf1, INET6_ADDRSTRLEN);
|
||||
zlog_debug("%s(%s): NH unresolved", __FUNCTION__, buf1);
|
||||
}
|
||||
bgp_info_unset_flag (rn, ri, BGP_INFO_VALID);
|
||||
}
|
||||
}
|
||||
else
|
||||
bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
|
||||
|
||||
@ -2484,18 +2483,27 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
|
||||
memcpy ((bgp_info_extra_get (new))->tag, tag, 3);
|
||||
|
||||
/* Nexthop reachability check. */
|
||||
if ((afi == AFI_IP || afi == AFI_IP6)
|
||||
&& safi == SAFI_UNICAST
|
||||
&& (peer->sort == BGP_PEER_IBGP
|
||||
|| peer->sort == BGP_PEER_CONFED
|
||||
|| (peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
|
||||
|| CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)))
|
||||
if ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST)
|
||||
{
|
||||
if (bgp_find_or_add_nexthop (afi, new, NULL, NULL))
|
||||
if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1 &&
|
||||
! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
|
||||
connected = 1;
|
||||
else
|
||||
connected = 0;
|
||||
|
||||
if (bgp_find_or_add_nexthop (afi, new, NULL, connected))
|
||||
bgp_info_set_flag (rn, new, BGP_INFO_VALID);
|
||||
else
|
||||
{
|
||||
if (BGP_DEBUG(nht, NHT))
|
||||
{
|
||||
char buf1[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, (const void *)&attr_new->nexthop, buf1, INET6_ADDRSTRLEN);
|
||||
zlog_debug("%s(%s): NH unresolved", __FUNCTION__, buf1);
|
||||
}
|
||||
bgp_info_unset_flag (rn, new, BGP_INFO_VALID);
|
||||
}
|
||||
}
|
||||
else
|
||||
bgp_info_set_flag (rn, new, BGP_INFO_VALID);
|
||||
|
||||
@ -3558,6 +3566,23 @@ bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p,
|
||||
ri->attr = attr_new;
|
||||
ri->uptime = bgp_clock ();
|
||||
|
||||
/* Nexthop reachability check. */
|
||||
if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
|
||||
{
|
||||
if (bgp_find_or_add_nexthop (afi, ri, NULL, 0))
|
||||
bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
|
||||
else
|
||||
{
|
||||
if (BGP_DEBUG(nht, NHT))
|
||||
{
|
||||
char buf1[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, (const void *)&attr_new->nexthop,
|
||||
buf1, INET6_ADDRSTRLEN);
|
||||
zlog_debug("%s(%s): NH unresolved", __FUNCTION__, buf1);
|
||||
}
|
||||
bgp_info_unset_flag (rn, ri, BGP_INFO_VALID);
|
||||
}
|
||||
}
|
||||
/* Process change. */
|
||||
bgp_process (bgp, rn, afi, safi);
|
||||
bgp_unlock_node (rn);
|
||||
@ -3570,7 +3595,25 @@ bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p,
|
||||
/* Make new BGP info. */
|
||||
new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, bgp->peer_self,
|
||||
attr_new, rn);
|
||||
SET_FLAG (new->flags, BGP_INFO_VALID);
|
||||
/* Nexthop reachability check. */
|
||||
if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
|
||||
{
|
||||
if (bgp_find_or_add_nexthop (afi, new, NULL, 0))
|
||||
bgp_info_set_flag (rn, new, BGP_INFO_VALID);
|
||||
else
|
||||
{
|
||||
if (BGP_DEBUG(nht, NHT))
|
||||
{
|
||||
char buf1[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, (const void *)&attr_new->nexthop,
|
||||
buf1, INET6_ADDRSTRLEN);
|
||||
zlog_debug("%s(%s): NH unresolved", __FUNCTION__, buf1);
|
||||
}
|
||||
bgp_info_unset_flag (rn, new, BGP_INFO_VALID);
|
||||
}
|
||||
}
|
||||
else
|
||||
bgp_info_set_flag (rn, new, BGP_INFO_VALID);
|
||||
|
||||
/* Register new BGP information. */
|
||||
bgp_info_add (rn, new);
|
||||
@ -3672,6 +3715,23 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p,
|
||||
ri->attr = attr_new;
|
||||
ri->uptime = bgp_clock ();
|
||||
|
||||
/* Nexthop reachability check. */
|
||||
if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
|
||||
{
|
||||
if (bgp_find_or_add_nexthop (afi, ri, NULL, 0))
|
||||
bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
|
||||
else
|
||||
{
|
||||
if (BGP_DEBUG(nht, NHT))
|
||||
{
|
||||
char buf1[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, (const void *)&attr_new->nexthop,
|
||||
buf1, INET6_ADDRSTRLEN);
|
||||
zlog_debug("%s(%s): NH unresolved", __FUNCTION__, buf1);
|
||||
}
|
||||
bgp_info_unset_flag (rn, ri, BGP_INFO_VALID);
|
||||
}
|
||||
}
|
||||
/* Process change. */
|
||||
bgp_aggregate_increment (bgp, p, ri, afi, safi);
|
||||
bgp_process (bgp, rn, afi, safi);
|
||||
@ -3685,7 +3745,25 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p,
|
||||
/* Make new BGP info. */
|
||||
new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, bgp->peer_self, attr_new,
|
||||
rn);
|
||||
SET_FLAG (new->flags, BGP_INFO_VALID);
|
||||
/* Nexthop reachability check. */
|
||||
if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
|
||||
{
|
||||
if (bgp_find_or_add_nexthop (afi, new, NULL, 0))
|
||||
bgp_info_set_flag (rn, new, BGP_INFO_VALID);
|
||||
else
|
||||
{
|
||||
if (BGP_DEBUG(nht, NHT))
|
||||
{
|
||||
char buf1[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, (const void *)&attr_new->nexthop, buf1,
|
||||
INET6_ADDRSTRLEN);
|
||||
zlog_debug("%s(%s): NH unresolved", __FUNCTION__, buf1);
|
||||
}
|
||||
bgp_info_unset_flag (rn, new, BGP_INFO_VALID);
|
||||
}
|
||||
}
|
||||
else
|
||||
bgp_info_set_flag (rn, new, BGP_INFO_VALID);
|
||||
|
||||
/* Aggregate address increment. */
|
||||
bgp_aggregate_increment (bgp, p, new, afi, safi);
|
||||
@ -3770,6 +3848,7 @@ bgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi,
|
||||
if (ri)
|
||||
{
|
||||
bgp_aggregate_decrement (bgp, p, ri, afi, safi);
|
||||
bgp_unlink_nexthop(ri);
|
||||
bgp_info_delete (rn, ri);
|
||||
bgp_process (bgp, rn, afi, safi);
|
||||
}
|
||||
@ -3906,17 +3985,12 @@ bgp_static_set (struct vty *vty, struct bgp *bgp, const char *ip_str,
|
||||
rn->info = bgp_static;
|
||||
}
|
||||
|
||||
/* If BGP scan is not enabled, we should install this route here. */
|
||||
if (! bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
|
||||
{
|
||||
bgp_static->valid = 1;
|
||||
|
||||
if (need_update)
|
||||
bgp_static_withdraw (bgp, &p, afi, safi);
|
||||
|
||||
if (! bgp_static->backdoor)
|
||||
bgp_static_update (bgp, &p, bgp_static, afi, safi);
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
@ -3964,6 +4038,7 @@ bgp_static_unset (struct vty *vty, struct bgp *bgp, const char *ip_str,
|
||||
bgp_static_withdraw (bgp, &p, afi, safi);
|
||||
|
||||
/* Clear configuration. */
|
||||
bgp_unlink_nexthop(bgp_static);
|
||||
bgp_static_free (bgp_static);
|
||||
rn->info = NULL;
|
||||
bgp_unlock_node (rn);
|
||||
|
29
bgpd/bgpd.c
29
bgpd/bgpd.c
@ -58,6 +58,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "bgpd/bgp_network.h"
|
||||
#include "bgpd/bgp_vty.h"
|
||||
#include "bgpd/bgp_mpath.h"
|
||||
#include "bgpd/bgp_nht.h"
|
||||
#ifdef HAVE_SNMP
|
||||
#include "bgpd/bgp_snmp.h"
|
||||
#endif /* HAVE_SNMP */
|
||||
@ -4733,9 +4734,8 @@ peer_maximum_prefix_set (struct peer *peer, afi_t afi, safi_t safi,
|
||||
else
|
||||
UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
|
||||
|
||||
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
|
||||
return 0;
|
||||
|
||||
if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
|
||||
{
|
||||
group = peer->group;
|
||||
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
|
||||
{
|
||||
@ -4750,7 +4750,17 @@ peer_maximum_prefix_set (struct peer *peer, afi_t afi, safi_t safi,
|
||||
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
|
||||
else
|
||||
UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
|
||||
|
||||
if ((peer->status == Established) && (peer->afc[afi][safi]))
|
||||
bgp_maximum_prefix_overflow (peer, afi, safi, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((peer->status == Established) && (peer->afc[afi][safi]))
|
||||
bgp_maximum_prefix_overflow (peer, afi, safi, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -5767,9 +5777,6 @@ bgp_config_write (struct vty *vty)
|
||||
if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
|
||||
vty_out (vty, " bgp network import-check%s", VTY_NEWLINE);
|
||||
|
||||
/* BGP scan interval. */
|
||||
bgp_config_write_scan_time (vty);
|
||||
|
||||
/* BGP flag dampening. */
|
||||
if (CHECK_FLAG (bgp->af_flags[AFI_IP][SAFI_UNICAST],
|
||||
BGP_CONFIG_DAMPENING))
|
||||
@ -5849,12 +5856,16 @@ bgp_master_init (void)
|
||||
void
|
||||
bgp_init (void)
|
||||
{
|
||||
/* BGP VTY commands installation. */
|
||||
bgp_vty_init ();
|
||||
|
||||
/* allocates some vital data structures used by peer commands in vty_init */
|
||||
bgp_scan_init ();
|
||||
|
||||
/* Init zebra. */
|
||||
bgp_zebra_init ();
|
||||
|
||||
/* BGP VTY commands installation. */
|
||||
bgp_vty_init ();
|
||||
|
||||
/* BGP inits. */
|
||||
bgp_attr_init ();
|
||||
bgp_debug_init ();
|
||||
@ -5862,7 +5873,7 @@ bgp_init (void)
|
||||
bgp_route_init ();
|
||||
bgp_route_map_init ();
|
||||
bgp_address_init ();
|
||||
bgp_scan_init ();
|
||||
bgp_scan_vty_init();
|
||||
bgp_mplsvpn_init ();
|
||||
|
||||
/* Access list initialize. */
|
||||
|
@ -233,8 +233,16 @@ zebra_evaluate_rnh_table (int vrfid, int family, int force)
|
||||
if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
|
||||
continue;
|
||||
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
|
||||
{
|
||||
if (CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
|
||||
{
|
||||
if (rib->type == ZEBRA_ROUTE_CONNECT)
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state_changed = 0;
|
||||
@ -649,7 +657,9 @@ print_rnh (struct route_node *rn, struct vty *vty)
|
||||
print_nh(nexthop, vty);
|
||||
}
|
||||
else
|
||||
vty_out(vty, " unresolved%s", VTY_NEWLINE);
|
||||
vty_out(vty, " unresolved%s%s",
|
||||
CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED) ? "(Connected)" : "",
|
||||
VTY_NEWLINE);
|
||||
|
||||
vty_out(vty, " Client list:");
|
||||
for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client))
|
||||
|
@ -30,6 +30,7 @@
|
||||
struct rnh
|
||||
{
|
||||
u_char flags;
|
||||
#define ZEBRA_NHT_CONNECTED 0x1
|
||||
struct rib *state;
|
||||
struct list *client_list;
|
||||
struct route_node *node;
|
||||
|
@ -755,6 +755,7 @@ zserv_nexthop_register (struct zserv *client, int sock, u_short length)
|
||||
struct stream *s;
|
||||
struct prefix p;
|
||||
u_short l = 0;
|
||||
u_char connected;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_NHT)
|
||||
zlog_debug("nexthop_register msg from client %s: length=%d\n",
|
||||
@ -764,12 +765,16 @@ zserv_nexthop_register (struct zserv *client, int sock, u_short length)
|
||||
|
||||
while (l < length)
|
||||
{
|
||||
connected = stream_getc(s);
|
||||
p.family = stream_getw(s);
|
||||
p.prefixlen = stream_getc(s);
|
||||
l += 3;
|
||||
l += 4;
|
||||
stream_get(&p.u.prefix, s, PSIZE(p.prefixlen));
|
||||
l += PSIZE(p.prefixlen);
|
||||
rnh = zebra_add_rnh(&p, 0);
|
||||
if (connected)
|
||||
SET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED);
|
||||
|
||||
zebra_add_rnh_client(rnh, client);
|
||||
}
|
||||
zebra_evaluate_rnh_table(0, AF_INET, 0);
|
||||
@ -785,6 +790,7 @@ zserv_nexthop_unregister (struct zserv *client, int sock, u_short length)
|
||||
struct stream *s;
|
||||
struct prefix p;
|
||||
u_short l = 0;
|
||||
u_char connected;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_NHT)
|
||||
zlog_debug("nexthop_unregister msg from client %s: length=%d\n",
|
||||
@ -794,9 +800,10 @@ zserv_nexthop_unregister (struct zserv *client, int sock, u_short length)
|
||||
|
||||
while (l < length)
|
||||
{
|
||||
connected = stream_getc(s);
|
||||
p.family = stream_getw(s);
|
||||
p.prefixlen = stream_getc(s);
|
||||
l += 3;
|
||||
l += 4;
|
||||
stream_get(&p.u.prefix, s, PSIZE(p.prefixlen));
|
||||
l += PSIZE(p.prefixlen);
|
||||
rnh = zebra_lookup_rnh(&p, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user