BGP: VRF registration and cleanup

Various changes and fixes related to VRF registration, deletion,
BGP exit etc.

- Define instance type
- Ensure proper handling upon instance create, delete and
  VRF add/delete from zebra
- Cleanup upon bgp_exit()
- Ensure messages are not sent to zebra for unknown VRFs

Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Reviewed-by:   Donald Sharp <sharpd@cumulusnetworks.com>

Ticket: CM-9128, CM-7203
Reviewed By: CCR-4098
Testing Done: Manual
This commit is contained in:
vivek 2016-02-12 12:18:28 -08:00
parent 0e5223e7a0
commit ad4cbda1a3
11 changed files with 450 additions and 303 deletions

View File

@ -207,11 +207,6 @@ peer_xfer_conn(struct peer *from_peer)
return(peer);
}
/* Check if suppress start/restart of sessions to peer. */
#define BGP_PEER_START_SUPPRESSED(P) \
(CHECK_FLAG ((P)->flags, PEER_FLAG_SHUTDOWN) \
|| CHECK_FLAG ((P)->sflags, PEER_STATUS_PREFIX_OVERFLOW))
/* Hook function called after bgp event is occered. And vty's
neighbor command invoke this function after making neighbor
structure. */

View File

@ -236,20 +236,11 @@ bgp_exit (int status)
bgp_delete (bgp);
list_free (bm->bgp);
/* reverse bgp_zebra_init/if_init */
if (retain_mode)
if_add_hook (IF_DELETE_HOOK, NULL);
/*Pending: Must-Do, this needs to be moved in a loop for all the instances..
Do the iflist lookup for vrf associated with the instance
for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
{
struct listnode *c_node, *c_nnode;
struct connected *c;
for (ALL_LIST_ELEMENTS (ifp->connected, c_node, c_nnode, c))
bgp_connected_delete (c);
}
*/
/* free interface and connected route information. */
bgp_if_finish ();
/* reverse bgp_attr_init */
bgp_attr_finish ();

View File

@ -539,15 +539,11 @@ sendmsg_zebra_rnh (struct bgp_nexthop_cache *bnc, int command)
/* Check socket. */
if (!zclient || zclient->sock < 0)
{
/* Hiding this error now, because bgp_nht_register_all() is implemented.
which tries it after zclient_connect()
zlog_debug("%s: Can't send NH register, Zebra client not established",
__FUNCTION__);
Pending: remove this comment after reviewing to see if no message is needed in this case
*/
return;
}
return;
/* Don't try to register if Zebra doesn't know of this instance. */
if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bnc->bgp))
return;
p = &(bnc->node->p);
s = zclient->obuf;
@ -702,48 +698,6 @@ evaluate_paths (struct bgp_nexthop_cache *bnc)
RESET_FLAG(bnc->change_flags);
}
void
bgp_nht_register_all (vrf_id_t vrf_id)
{
struct bgp_node *rn;
struct bgp_nexthop_cache *bnc;
struct bgp *bgp;
bgp = bgp_lookup_by_vrf_id (vrf_id);
if (!bgp)
{
zlog_err("bgp_nht_register_all: instance not found for vrf_id %d", vrf_id);
return;
}
for (rn = bgp_table_top (bgp->nexthop_cache_table[AFI_IP]); rn; rn = bgp_route_next (rn))
if ((bnc = rn->info) != NULL &&
!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
{
register_zebra_rnh(bnc, 0);
}
for (rn = bgp_table_top (bgp->nexthop_cache_table[AFI_IP6]); rn; rn = bgp_route_next (rn))
if ((bnc = rn->info) != NULL &&
!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
{
register_zebra_rnh(bnc, 0);
}
for (rn = bgp_table_top (bgp->import_check_table[AFI_IP]); rn; rn = bgp_route_next (rn))
if ((bnc = rn->info) != NULL &&
!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
{
register_zebra_rnh(bnc, 1);
}
for (rn = bgp_table_top (bgp->import_check_table[AFI_IP6]); rn; rn = bgp_route_next (rn))
if ((bnc = rn->info) != NULL &&
!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
{
register_zebra_rnh(bnc, 1);
}
}
/**
* path_nh_map - make or break path-to-nexthop association.
* ARGUMENTS:

View File

@ -22,8 +22,6 @@
#ifndef _BGP_NHT_H
#define _BGP_NHT_H
extern void bgp_nht_register_all (vrf_id_t);
/**
* bgp_parse_nexthop_update() - parse a nexthop update message from Zebra.
*/

View File

@ -1828,8 +1828,9 @@ bgp_process_main (struct work_queue *wq, void *data)
group_announce_route(bgp, afi, safi, rn, new_select);
/* FIB update. */
if ((safi == SAFI_UNICAST || safi == SAFI_MULTICAST) && (! bgp_flag_check(bgp, BGP_FLAG_INSTANCE_TYPE_VIEW) &&
! bgp_option_check (BGP_OPT_NO_FIB)))
if ((safi == SAFI_UNICAST || safi == SAFI_MULTICAST) &&
(bgp->inst_type != BGP_INSTANCE_TYPE_VIEW) &&
!bgp_option_check (BGP_OPT_NO_FIB))
{
if (new_select
&& new_select->type == ZEBRA_ROUTE_BGP
@ -3784,6 +3785,48 @@ bgp_static_redo_import_check (struct bgp *bgp)
bgp_flag_unset(bgp, BGP_FLAG_FORCE_STATIC_PROCESS);
}
static void
bgp_purge_af_static_redist_routes (struct bgp *bgp, afi_t afi, safi_t safi)
{
struct bgp_table *table;
struct bgp_node *rn;
struct bgp_info *ri;
table = bgp->rib[afi][safi];
for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
{
for (ri = rn->info; ri; ri = ri->next)
{
if (ri->peer == bgp->peer_self &&
((ri->type == ZEBRA_ROUTE_BGP &&
ri->sub_type == BGP_ROUTE_STATIC) ||
(ri->type != ZEBRA_ROUTE_BGP &&
ri->sub_type == BGP_ROUTE_REDISTRIBUTE)))
{
bgp_aggregate_decrement (bgp, &rn->p, ri, afi, safi);
bgp_unlink_nexthop(ri);
bgp_info_delete (rn, ri);
bgp_process (bgp, rn, afi, safi);
}
}
}
}
/*
* Purge all networks and redistributed routes from routing table.
* Invoked upon the instance going down.
*/
void
bgp_purge_static_redist_routes (struct bgp *bgp)
{
afi_t afi;
safi_t safi;
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
bgp_purge_af_static_redist_routes (bgp, afi, safi);
}
int
bgp_static_set_vpnv4 (struct vty *vty, const char *ip_str, const char *rd_str,
const char *tag_str)

View File

@ -248,6 +248,7 @@ extern void bgp_redistribute_withdraw (struct bgp *, afi_t, int, u_short);
extern void bgp_static_add (struct bgp *);
extern void bgp_static_delete (struct bgp *);
extern void bgp_static_redo_import_check (struct bgp *);
extern void bgp_purge_static_redist_routes (struct bgp *bgp);
extern void bgp_static_update (struct bgp *, struct prefix *, struct bgp_static *,
afi_t, safi_t);
extern void bgp_static_withdraw (struct bgp *, struct prefix *, afi_t, safi_t);

View File

@ -607,6 +607,7 @@ DEFUN (router_bgp,
as_t as;
struct bgp *bgp;
const char *name = NULL;
enum bgp_instance_type inst_type;
// "router bgp" without an ASN
if (argc < 1)
@ -632,10 +633,17 @@ DEFUN (router_bgp,
{
VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
inst_type = BGP_INSTANCE_TYPE_DEFAULT;
if (argc == 3)
name = argv[2];
{
name = argv[2];
if (!strcmp(argv[1], "vrf"))
inst_type = BGP_INSTANCE_TYPE_VRF;
else if (!strcmp(argv[1], "view"))
inst_type = BGP_INSTANCE_TYPE_VIEW;
}
ret = bgp_get (&bgp, &as, name);
ret = bgp_get (&bgp, &as, name, inst_type);
switch (ret)
{
case BGP_ERR_MULTIPLE_INSTANCE_NOT_SET:
@ -653,10 +661,6 @@ DEFUN (router_bgp,
}
/* Pending: handle when user tries to change a view to vrf n vv. */
if (argc == 3 && !strcmp(argv[1], "vrf"))
bgp_flag_set (bgp, BGP_FLAG_INSTANCE_TYPE_VRF);
if (argc == 3 && !strcmp(argv[1], "view"))
bgp_flag_set (bgp, BGP_FLAG_INSTANCE_TYPE_VIEW);
}
vty->node = BGP_NODE;

View File

@ -89,6 +89,20 @@ do { \
bgp_attr_deep_free(info->attr); \
} while (0)
/* Can we install into zebra? */
static inline int
bgp_install_info_to_zebra (struct bgp *bgp)
{
if (zclient->sock <= 0)
return 0;
if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
return 0;
return 1;
}
/* Router-id update message from zebra. */
static int
bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length,
@ -104,15 +118,15 @@ bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length,
{
char buf[PREFIX2STR_BUFFER];
prefix2str(&router_id, buf, sizeof(buf));
zlog_debug("Zebra rcvd: router id update %s vrf %u", buf, vrf_id);
zlog_debug("Rx Router Id update VRF %u Id %s", vrf_id, buf);
}
if (!vrf_id)
if (vrf_id == VRF_DEFAULT)
{
/* This is to cover all the views */
/* Router-id change for default VRF has to also update all views. */
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
{
if (bgp_flag_check(bgp, BGP_FLAG_INSTANCE_TYPE_VRF))
if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
continue;
bgp->router_id_zebra = router_id.u.prefix4;
@ -220,7 +234,7 @@ bgp_nbr_connected_delete (struct bgp *bgp, struct nbr_connected *ifc, int del)
}
}
/* Inteface addition message from zebra. */
/* VRF learnt from Zebra. */
static int
bgp_vrf_add (int command, struct zclient *zclient, zebra_size_t length,
vrf_id_t vrf_id)
@ -229,46 +243,24 @@ bgp_vrf_add (int command, struct zclient *zclient, zebra_size_t length,
struct bgp *bgp;
vrf = zebra_vrf_add_read (zclient->ibuf, vrf_id);
if (!vrf) // unexpected
return -1;
if (BGP_DEBUG (zebra, ZEBRA) && vrf)
zlog_debug("Zebra rcvd: vrf add %s", vrf->name);
if (BGP_DEBUG (zebra, ZEBRA))
zlog_debug("Rx VRF add %s id %d", vrf->name, vrf_id);
bgp = bgp_lookup_by_name(vrf->name);
if (bgp)
{
/* We have instance configured, make it "up". */
bgp->vrf_id = vrf_id;
if (BGP_DEBUG (zebra, ZEBRA) && vrf)
zlog_debug("zclient_send_reg_requests %u", vrf_id);
zclient_send_reg_requests (zclient, vrf_id);
bgp_instance_up (bgp);
//Pending: See if the following can be moved inside bgp_instance_up ()
bgp_nht_register_all(vrf_id);
}
return 0;
}
void
bgp_vrf_update (struct bgp *bgp)
{
struct vrf *vrf;
if (bgp->name)
{
vrf = vrf_lookup_by_name(bgp->name);
if (vrf)
bgp->vrf_id = vrf->vrf_id;
}
zclient_send_reg_requests (zclient, bgp->vrf_id);
bgp_nht_register_all (bgp->vrf_id);
}
/* Inteface deletion message from zebra. */
/* VRF deleted by Zebra. */
static int
bgp_vrf_delete (int command, struct zclient *zclient, zebra_size_t length,
vrf_id_t vrf_id)
@ -276,18 +268,25 @@ bgp_vrf_delete (int command, struct zclient *zclient, zebra_size_t length,
struct vrf *vrf;
struct bgp *bgp;
vrf = zebra_vrf_state_read (zclient->ibuf, vrf_id);
/* Default VRF cannot be deleted. */
assert (vrf_id != VRF_DEFAULT);
if (BGP_DEBUG (zebra, ZEBRA) && vrf)
zlog_debug("Zebra rcvd: vrf delete %s", vrf->name);
vrf = zebra_vrf_state_read (zclient->ibuf, vrf_id);
if (!vrf) // unexpected
return -1;
if (BGP_DEBUG (zebra, ZEBRA))
zlog_debug("Rx VRF del %s id %d", vrf->name, vrf_id);
bgp = bgp_lookup_by_name(vrf->name);
if (bgp)
{
/* We have instance configured, make it "down". */
bgp->vrf_id = VRF_DEFAULT;
bgp_instance_down (bgp);
bgp->vrf_id = 0;
}
/* Note: This is a callback, the VRF will be deleted by the caller. */
return 0;
}
@ -303,7 +302,7 @@ bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length,
ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);
if (BGP_DEBUG (zebra, ZEBRA) && ifp)
zlog_debug("Zebra rcvd: interface add %s", ifp->name);
zlog_debug("Rx Intf add VRF %u IF %s", vrf_id, ifp->name);
return 0;
}
@ -320,7 +319,7 @@ bgp_interface_delete (int command, struct zclient *zclient,
ifp->ifindex = IFINDEX_INTERNAL;
if (BGP_DEBUG (zebra, ZEBRA))
zlog_debug("Zebra rcvd: interface delete %s", ifp->name);
zlog_debug("Rx Intf del VRF %u IF %s", vrf_id, ifp->name);
return 0;
}
@ -336,10 +335,6 @@ bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length,
struct listnode *node, *nnode;
struct bgp *bgp;
bgp = bgp_lookup_by_vrf_id (vrf_id);
if (!bgp)
return 0;
s = zclient->ibuf;
ifp = zebra_interface_state_read (s, vrf_id);
@ -347,7 +342,11 @@ bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length,
return 0;
if (BGP_DEBUG (zebra, ZEBRA))
zlog_debug("Zebra rcvd: interface %s up", ifp->name);
zlog_debug("Rx Intf up VRF %u IF %s", vrf_id, ifp->name);
bgp = bgp_lookup_by_vrf_id (vrf_id);
if (!bgp)
return 0;
for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
bgp_connected_add (bgp, c);
@ -369,17 +368,17 @@ bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length,
struct listnode *node, *nnode;
struct bgp *bgp;
bgp = bgp_lookup_by_vrf_id (vrf_id);
if (!bgp)
return 0;
s = zclient->ibuf;
ifp = zebra_interface_state_read (s, vrf_id);
if (! ifp)
return 0;
if (BGP_DEBUG (zebra, ZEBRA))
zlog_debug("Zebra rcvd: interface %s down", ifp->name);
zlog_debug("Rx Intf down VRF %u IF %s", vrf_id, ifp->name);
bgp = bgp_lookup_by_vrf_id (vrf_id);
if (!bgp)
return 0;
for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
bgp_connected_delete (bgp, c);
@ -389,23 +388,18 @@ bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length,
/* 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))
return 0;
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
{
if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
continue;
if ((peer->ttl != 1) && (peer->gtsm_hops != 1))
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);
}
if (ifp == peer->nexthop.ifp)
BGP_EVENT_ADD (peer, BGP_Stop);
}
}
@ -427,8 +421,8 @@ bgp_interface_address_add (int command, struct zclient *zclient,
{
char buf[PREFIX2STR_BUFFER];
prefix2str(ifc->address, buf, sizeof(buf));
zlog_debug("Zebra rcvd: interface %s address add %s",
ifc->ifp->name, buf);
zlog_debug("Rx Intf address add VRF %u IF %s addr %s",
vrf_id, ifc->ifp->name, buf);
}
if (if_is_operative (ifc->ifp))
@ -437,10 +431,7 @@ bgp_interface_address_add (int command, struct zclient *zclient,
bgp = bgp_lookup_by_vrf_id (vrf_id);
if (!bgp)
{
zlog_err("instance not found\n");
return 0;
}
return 0;
bgp_connected_add (bgp, ifc);
/* If we have learnt of any neighbors on this interface,
@ -462,10 +453,6 @@ bgp_interface_address_delete (int command, struct zclient *zclient,
struct connected *ifc;
struct bgp *bgp;
bgp = bgp_lookup_by_vrf_id (vrf_id);
if (!bgp)
return 0;
ifc = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
if (ifc == NULL)
@ -475,12 +462,16 @@ bgp_interface_address_delete (int command, struct zclient *zclient,
{
char buf[PREFIX2STR_BUFFER];
prefix2str(ifc->address, buf, sizeof(buf));
zlog_debug("Zebra rcvd: interface %s address delete %s",
ifc->ifp->name, buf);
zlog_debug("Rx Intf address del VRF %u IF %s addr %s",
vrf_id, ifc->ifp->name, buf);
}
if (if_is_operative (ifc->ifp))
bgp_connected_delete (bgp, ifc);
{
bgp = bgp_lookup_by_vrf_id (vrf_id);
if (bgp)
bgp_connected_delete (bgp, ifc);
}
connected_free (ifc);
@ -494,10 +485,6 @@ bgp_interface_nbr_address_add (int command, struct zclient *zclient,
struct nbr_connected *ifc = NULL;
struct bgp *bgp;
bgp = bgp_lookup_by_vrf_id (vrf_id);
if (!bgp)
return 0;
ifc = zebra_interface_nbr_address_read (command, zclient->ibuf, vrf_id);
if (ifc == NULL)
@ -507,12 +494,16 @@ bgp_interface_nbr_address_add (int command, struct zclient *zclient,
{
char buf[PREFIX2STR_BUFFER];
prefix2str(ifc->address, buf, sizeof(buf));
zlog_debug("Zebra rcvd: interface %s nbr address add %s",
ifc->ifp->name, buf);
zlog_debug("Rx Intf neighbor add VRF %u IF %s addr %s",
vrf_id, ifc->ifp->name, buf);
}
if (if_is_operative (ifc->ifp))
bgp_nbr_connected_add (bgp, ifc);
{
bgp = bgp_lookup_by_vrf_id (vrf_id);
if (bgp)
bgp_nbr_connected_add (bgp, ifc);
}
return 0;
}
@ -524,10 +515,6 @@ bgp_interface_nbr_address_delete (int command, struct zclient *zclient,
struct nbr_connected *ifc = NULL;
struct bgp *bgp;
bgp = bgp_lookup_by_vrf_id (vrf_id);
if (!bgp)
return 0;
ifc = zebra_interface_nbr_address_read (command, zclient->ibuf, vrf_id);
if (ifc == NULL)
@ -537,12 +524,16 @@ bgp_interface_nbr_address_delete (int command, struct zclient *zclient,
{
char buf[PREFIX2STR_BUFFER];
prefix2str(ifc->address, buf, sizeof(buf));
zlog_debug("Zebra rcvd: interface %s nbr address delete %s",
ifc->ifp->name, buf);
zlog_debug("Rx Intf neighbor del VRF %u IF %s addr %s",
vrf_id, ifc->ifp->name, buf);
}
if (if_is_operative (ifc->ifp))
bgp_nbr_connected_delete (bgp, ifc, 0);
{
bgp = bgp_lookup_by_vrf_id (vrf_id);
if (bgp)
bgp_nbr_connected_delete (bgp, ifc, 0);
}
nbr_connected_free (ifc);
@ -616,7 +607,8 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length,
if (bgp_debug_zebra((struct prefix *)&p))
{
char buf[2][INET_ADDRSTRLEN];
zlog_debug("Zebra rcvd: IPv4 route add %s[%d] %s/%d nexthop %s metric %u tag %d",
zlog_debug("Rx IPv4 route add VRF %u %s[%d] %s/%d nexthop %s metric %u tag %d",
vrf_id,
zebra_route_string(api.type), api.instance,
inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
p.prefixlen,
@ -646,8 +638,9 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length,
if (bgp_debug_zebra((struct prefix *)&p))
{
char buf[2][INET_ADDRSTRLEN];
zlog_debug("Zebra rcvd: IPv4 route delete %s[%d] %s/%d "
zlog_debug("Rx IPv4 route delete VRF %u %s[%d] %s/%d "
"nexthop %s metric %u tag %d",
vrf_id,
zebra_route_string(api.type), api.instance,
inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
p.prefixlen,
@ -735,7 +728,8 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
if (bgp_debug_zebra((struct prefix *)&p))
{
char buf[2][INET6_ADDRSTRLEN];
zlog_debug("Zebra rcvd: IPv6 route add %s[%d] %s/%d nexthop %s metric %u tag %d",
zlog_debug("Rx IPv6 route add VRF %u %s[%d] %s/%d nexthop %s metric %u tag %d",
vrf_id,
zebra_route_string(api.type), api.instance,
inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
p.prefixlen,
@ -764,8 +758,9 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
if (bgp_debug_zebra((struct prefix *)&p))
{
char buf[2][INET6_ADDRSTRLEN];
zlog_debug("Zebra rcvd: IPv6 route delete %s[%d] %s/%d "
zlog_debug("Rx IPv6 route delete VRF %u %s[%d] %s/%d "
"nexthop %s metric %u tag %d",
vrf_id,
zebra_route_string(api.type), api.instance,
inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
p.prefixlen,
@ -1170,7 +1165,10 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
struct bgp_info *info_cp = &local_info;
u_short tag;
if (zclient->sock < 0)
/* Don't try to install if we're not connected to Zebra or Zebra doesn't
* know of this instance.
*/
if (!bgp_install_info_to_zebra (bgp))
return;
if ((p->family == AF_INET &&
@ -1329,8 +1327,9 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
if (bgp_debug_zebra(p))
{
int i;
zlog_debug("Zebra send: IPv4 route %s %s/%d metric %u tag %d"
zlog_debug("Tx IPv4 route %s VRF %u %s/%d metric %u tag %d"
" count %d", (valid_nh_count ? "add":"delete"),
bgp->vrf_id,
inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
p->prefixlen, api.metric, api.tag, api.nexthop_num);
for (i = 0; i < api.nexthop_num; i++)
@ -1508,8 +1507,8 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
if (bgp_debug_zebra(p))
{
int i;
zlog_debug("Zebra send: IPv4 route %s %s/%d metric %u tag %d",
valid_nh_count ? "add" : "delete",
zlog_debug("Tx IPv4 route %s VRF %u %s/%d metric %u tag %d",
valid_nh_count ? "add" : "delete", bgp->vrf_id,
inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
p->prefixlen, api.metric, api.tag);
for (i = 0; i < api.nexthop_num; i++)
@ -1530,8 +1529,8 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
if (bgp_debug_zebra(p))
{
int i;
zlog_debug("Zebra send: IPv6 route %s %s/%d metric %u tag %d",
valid_nh_count ? "add" : "delete",
zlog_debug("Tx IPv6 route %s VRF %u %s/%d metric %u tag %d",
valid_nh_count ? "add" : "delete", bgp->vrf_id,
inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
p->prefixlen, api.metric, api.tag);
for (i = 0; i < api.nexthop_num; i++)
@ -1555,6 +1554,12 @@ bgp_zebra_announce_table (struct bgp *bgp, afi_t afi, safi_t safi)
struct bgp_table *table;
struct bgp_info *ri;
/* Don't try to install if we're not connected to Zebra or Zebra doesn't
* know of this instance.
*/
if (!bgp_install_info_to_zebra (bgp))
return;
table = bgp->rib[afi][safi];
if (!table) return;
@ -1572,10 +1577,14 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
int flags;
struct peer *peer;
if (zclient->sock < 0)
return;
peer = info->peer;
assert(peer);
/* Don't try to install if we're not connected to Zebra or Zebra doesn't
* know of this instance.
*/
if (!bgp_install_info_to_zebra (peer->bgp))
return;
if ((p->family == AF_INET &&
!vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_BGP], peer->bgp->vrf_id))
@ -1623,7 +1632,8 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
if (bgp_debug_zebra(p))
{
char buf[2][INET_ADDRSTRLEN];
zlog_debug("Zebra send: IPv4 route delete %s/%d metric %u tag %d",
zlog_debug("Tx IPv4 route delete VRF %u %s/%d metric %u tag %d",
peer->bgp->vrf_id,
inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
p->prefixlen, api.metric, api.tag);
}
@ -1661,7 +1671,8 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
if (bgp_debug_zebra(p))
{
char buf[2][INET6_ADDRSTRLEN];
zlog_debug("Zebra send: IPv6 route delete %s/%d metric %u tag %d",
zlog_debug("Tx IPv6 route delete VRF %u %s/%d metric %u tag %d",
peer->bgp->vrf_id,
inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
p->prefixlen, api.metric, api.tag);
}
@ -1750,12 +1761,15 @@ bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type, u_short instance)
vrf_bitmap_set (zclient->redist[afi][type], bgp->vrf_id);
}
/* Return if zebra connection is not established. */
if (zclient->sock < 0)
/* Don't try to register if we're not connected to Zebra or Zebra doesn't
* know of this instance.
*/
if (!bgp_install_info_to_zebra (bgp))
return CMD_WARNING;
if (BGP_DEBUG (zebra, ZEBRA))
zlog_debug("Zebra send: redistribute add afi %d %s %d", afi,
zlog_debug("Tx redistribute add VRF %u afi %d %s %d",
bgp->vrf_id, afi,
zebra_route_string(type), instance);
/* Send distribute add message to zebra. */
@ -1768,12 +1782,15 @@ bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type, u_short instance)
int
bgp_redistribute_resend (struct bgp *bgp, afi_t afi, int type, u_short instance)
{
/* Return if zebra connection is not established. */
if (zclient->sock < 0)
/* Don't try to send if we're not connected to Zebra or Zebra doesn't
* know of this instance.
*/
if (!bgp_install_info_to_zebra (bgp))
return -1;
if (BGP_DEBUG (zebra, ZEBRA))
zlog_debug("Zebra send: redistribute delete/add afi %d %s %d", afi,
zlog_debug("Tx redistribute del/add VRF %u afi %d %s %d",
bgp->vrf_id, afi,
zebra_route_string(type), instance);
/* Send distribute add message to zebra. */
@ -1854,12 +1871,12 @@ bgp_redistribute_unreg (struct bgp *bgp, afi_t afi, int type, u_short instance)
vrf_bitmap_unset (zclient->redist[afi][type], bgp->vrf_id);
}
if (zclient->sock >= 0)
if (bgp_install_info_to_zebra (bgp))
{
/* Send distribute delete message to zebra. */
if (BGP_DEBUG (zebra, ZEBRA))
zlog_debug("Zebra send: redistribute delete afi %d %s %d",
afi, zebra_route_string(type), instance);
zlog_debug("Tx redistribute del VRF %u afi %d %s %d",
bgp->vrf_id, afi, zebra_route_string(type), instance);
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, type, instance,
bgp->vrf_id);
}
@ -1903,14 +1920,60 @@ bgp_zclient_reset (void)
zclient_reset (zclient);
}
/* Register this instance with Zebra. Invoked upon connect (for
* default instance) and when other VRFs are learnt (or created and
* already learnt).
*/
void
bgp_zebra_instance_register (struct bgp *bgp)
{
/* Don't try to register if we're not connected to Zebra */
if (zclient->sock < 0)
return;
if (BGP_DEBUG (zebra, ZEBRA))
zlog_debug("Registering VRF %u", bgp->vrf_id);
/* Register for router-id, interfaces, redistributed routes. */
zclient_send_reg_requests (zclient, bgp->vrf_id);
}
/* Deregister this instance with Zebra. Invoked upon the instance
* being deleted (default or VRF) and it is already registered.
*/
void
bgp_zebra_instance_deregister (struct bgp *bgp)
{
/* Don't try to deregister if we're not connected to Zebra */
if (zclient->sock < 0)
return;
if (BGP_DEBUG (zebra, ZEBRA))
zlog_debug("Deregistering VRF %u", bgp->vrf_id);
/* Deregister for router-id, interfaces, redistributed routes. */
zclient_send_dereg_requests (zclient, bgp->vrf_id);
}
/* BGP has established connection with Zebra. */
static void
bgp_zebra_connected (struct zclient *zclient)
{
struct listnode *node, *nnode;
struct bgp *bgp;
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
bgp_vrf_update (bgp);
/* At this point, we may or may not have BGP instances configured, but
* we're only interested in the default VRF (others wouldn't have learnt
* the VRF from Zebra yet.)
*/
bgp = bgp_get_default();
if (!bgp)
return;
bgp_zebra_instance_register (bgp);
/* TODO - What if we have peers and networks configured, do we have to
* kick-start them?
*/
}

View File

@ -29,7 +29,6 @@ extern struct stream *bgp_ifindices_buf;
extern void bgp_zebra_init(struct thread_master *master);
extern int bgp_if_update_all (void);
extern void bgp_vrf_update (struct bgp *);
extern int bgp_config_write_maxpaths (struct vty *, struct bgp *, afi_t,
safi_t, int *);
extern int bgp_config_write_redistribute (struct vty *, struct bgp *, afi_t, safi_t,
@ -39,6 +38,9 @@ extern void bgp_zebra_announce (struct prefix *, struct bgp_info *, struct bgp *
extern void bgp_zebra_announce_table (struct bgp *, afi_t, safi_t);
extern void bgp_zebra_withdraw (struct prefix *, struct bgp_info *, safi_t);
extern void bgp_zebra_instance_register (struct bgp *);
extern void bgp_zebra_instance_deregister (struct bgp *);
extern struct bgp_redist *bgp_redist_lookup (struct bgp *, afi_t, u_char, u_short);
extern struct bgp_redist *bgp_redist_add (struct bgp *, afi_t, u_char, u_short);
extern int bgp_redistribute_set (struct bgp *, afi_t, int, u_short);

View File

@ -80,6 +80,7 @@ struct bgp_master *bm;
/* BGP community-list. */
struct community_list_handler *bgp_clist;
extern struct zclient *zclient;
void
bgp_session_reset(struct peer *peer)
@ -2698,10 +2699,9 @@ bgp_startup_timer_expire (struct thread *thread)
return 0;
}
/* BGP instance creation by `router bgp' commands. */
static struct bgp *
bgp_create (as_t *as, const char *name)
bgp_create (as_t *as, const char *name, enum bgp_instance_type inst_type)
{
struct bgp *bgp;
afi_t afi;
@ -2710,7 +2710,19 @@ bgp_create (as_t *as, const char *name)
if ( (bgp = XCALLOC (MTYPE_BGP, sizeof (struct bgp))) == NULL)
return NULL;
if (BGP_DEBUG (zebra, ZEBRA))
{
if (inst_type == BGP_INSTANCE_TYPE_DEFAULT)
zlog_debug("Creating Default VRF, AS %u", *as);
else
zlog_debug("Creating %s %s, AS %u",
(inst_type == BGP_INSTANCE_TYPE_VRF) ? "VRF" : "VIEW",
name, *as);
}
bgp_lock (bgp);
bgp->inst_type = inst_type;
bgp->vrf_id = VRF_DEFAULT; /* initialization. */
bgp->peer_self = peer_new (bgp);
if (bgp->peer_self->host)
XFREE(MTYPE_BGP_PEER_HOST, bgp->peer_self->host);
@ -2757,7 +2769,7 @@ bgp_create (as_t *as, const char *name)
}
else
{
//Pending: See if calling bgp_instance_up() makes more sense.
/* TODO - The startup timer needs to be run for the whole of BGP */
THREAD_TIMER_ON (bm->master, bgp->t_startup, bgp_startup_timer_expire,
bgp, bgp->restart_time);
}
@ -2769,38 +2781,16 @@ bgp_create (as_t *as, const char *name)
return bgp;
}
void
bgp_instance_up (struct bgp *bgp)
{
struct peer *peer;
struct listnode *node, *next;
afi_t afi;
int i;
THREAD_TIMER_ON (bm->master, bgp->t_startup, bgp_startup_timer_expire,
bgp, bgp->restart_time);
/* Delete static route. */
bgp_static_add (bgp);
/* Set redistribution. */
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
if (i != ZEBRA_ROUTE_BGP && bgp_redist_lookup(bgp, afi, i, 0))
bgp_redistribute_set (bgp, afi, i, 0);
for (ALL_LIST_ELEMENTS (bgp->peer, node, next, peer))
{
BGP_EVENT_ADD (peer, BGP_Start);
}
}
/* Return first entry of BGP. */
/* Return the "default VRF" instance of BGP. */
struct bgp *
bgp_get_default (void)
{
if (bm->bgp->head)
return (listgetdata (listhead (bm->bgp)));
struct bgp *bgp;
struct listnode *node, *nnode;
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
return bgp;
return NULL;
}
@ -2833,8 +2823,7 @@ bgp_lookup_by_name (const char *name)
return NULL;
}
/* Lookup BGP structure by view name. */
//Pending: move this based on the vrf_hash lookup and find the linked bgp instance.
/* Lookup BGP instance based on VRF id */
struct bgp *
bgp_lookup_by_vrf_id (vrf_id_t vrf_id)
{
@ -2847,9 +2836,34 @@ bgp_lookup_by_vrf_id (vrf_id_t vrf_id)
return NULL;
}
/* Link BGP instance to VRF, if present. */
static void
bgp_vrf_link (struct bgp *bgp)
{
struct vrf *vrf;
vrf = vrf_lookup_by_name(bgp->name);
if (!vrf)
return;
bgp->vrf_id = vrf->vrf_id;
}
/* Unlink BGP instance from VRF, if present. */
static void
bgp_vrf_unlink (struct bgp *bgp)
{
struct vrf *vrf;
vrf = vrf_lookup (bgp->vrf_id);
if (!vrf)
return;
bgp->vrf_id = VRF_DEFAULT;
}
/* Called from VTY commands. */
int
bgp_get (struct bgp **bgp_val, as_t *as, const char *name)
bgp_get (struct bgp **bgp_val, as_t *as, const char *name,
enum bgp_instance_type inst_type)
{
struct bgp *bgp;
@ -2869,6 +2883,8 @@ bgp_get (struct bgp **bgp_val, as_t *as, const char *name)
*as = bgp->as;
return BGP_ERR_INSTANCE_MISMATCH;
}
if (bgp->inst_type != inst_type)
return BGP_ERR_INSTANCE_MISMATCH;
*bgp_val = bgp;
return 0;
}
@ -2894,7 +2910,7 @@ bgp_get (struct bgp **bgp_val, as_t *as, const char *name)
}
}
bgp = bgp_create (as, name);
bgp = bgp_create (as, name, inst_type);
bgp_router_id_set(bgp, &bgp->router_id_zebra);
bgp_address_init (bgp);
bgp_scan_init (bgp);
@ -2914,74 +2930,73 @@ bgp_get (struct bgp **bgp_val, as_t *as, const char *name)
listnode_add (bm->bgp, bgp);
bgp_vrf_update (bgp);
/* If VRF, link to the VRF structure, if present. */
if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
bgp_vrf_link (bgp);
/* Register with Zebra, if needed */
if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
bgp_zebra_instance_register (bgp);
return 0;
}
/* Delete BGP instance. */
/*
* Make BGP instance "up". Applies only to VRFs (non-default) and
* implies the VRF has been learnt from Zebra.
*/
void
bgp_instance_up (struct bgp *bgp)
{
struct peer *peer;
struct listnode *node, *next;
/* Register with zebra. */
bgp_zebra_instance_register (bgp);
/* Kick off any peers that may have been configured. */
for (ALL_LIST_ELEMENTS (bgp->peer, node, next, peer))
{
if (!BGP_PEER_START_SUPPRESSED (peer))
BGP_EVENT_ADD (peer, BGP_Start);
}
/* Process any networks that have been configured. */
bgp_static_add (bgp);
}
/*
* Make BGP instance "down". Applies only to VRFs (non-default) and
* implies the VRF has been deleted by Zebra.
*/
void
bgp_instance_down (struct bgp *bgp)
{
struct peer *peer;
struct peer_group *group;
struct listnode *node, *pnode;
struct listnode *next, *pnext;
afi_t afi;
int i;
THREAD_OFF (bgp->t_startup);
for (ALL_LIST_ELEMENTS (bgp->peer, node, next, peer))
{
if (peer->status == Established ||
peer->status == OpenSent ||
peer->status == OpenConfirm)
{
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_PEER_UNCONFIG);
}
}
struct listnode *node;
struct listnode *next;
/* Stop timers. */
if (bgp->t_rmap_update)
BGP_TIMER_OFF(bgp->t_rmap_update);
/* Delete static route. */
bgp_static_delete (bgp);
/* Unset redistribution. */
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
if (i != ZEBRA_ROUTE_BGP)
bgp_redistribute_unreg (bgp, afi, i, 0);
for (ALL_LIST_ELEMENTS (bgp->group, node, next, group))
{
for (ALL_LIST_ELEMENTS (group->peer, pnode, pnext, peer))
{
if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
{
/* Send notify to remote peer. */
bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
}
}
}
for (ALL_LIST_ELEMENTS (bgp->peer, node, next, peer))
{
if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
{
/* Send notify to remote peer. */
bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
}
}
if (bgp->t_rmap_def_originate_eval)
{
BGP_TIMER_OFF(bgp->t_rmap_def_originate_eval);
bgp_unlock(bgp); /* TODO - This timer is started with a lock - why? */
}
return;
/* Bring down peers, so corresponding routes are purged. */
for (ALL_LIST_ELEMENTS (bgp->peer, node, next, peer))
{
if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
else
bgp_session_reset(peer);
}
/* Purge network and redistributed routes. */
bgp_purge_static_redist_routes (bgp);
}
/* Delete BGP instance. */
@ -2996,10 +3011,33 @@ bgp_delete (struct bgp *bgp)
THREAD_OFF (bgp->t_startup);
if (BGP_DEBUG (zebra, ZEBRA))
{
if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
zlog_debug("Deleting Default VRF");
else
zlog_debug("Deleting %s %s",
(bgp->inst_type == BGP_INSTANCE_TYPE_VRF) ? "VRF" : "VIEW",
bgp->name);
}
/* Stop timers. */
if (bgp->t_rmap_update)
BGP_TIMER_OFF(bgp->t_rmap_update);
if (bgp->t_rmap_def_originate_eval)
{
BGP_TIMER_OFF(bgp->t_rmap_def_originate_eval);
bgp_unlock(bgp); /* TODO - This timer is started with a lock - why? */
}
/* Delete static route. */
/* Inform peers we're going down. */
for (ALL_LIST_ELEMENTS (bgp->peer, node, next, peer))
{
if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
}
/* Delete static routes (networks). */
bgp_static_delete (bgp);
/* Unset redistribution. */
@ -3008,28 +3046,22 @@ bgp_delete (struct bgp *bgp)
if (i != ZEBRA_ROUTE_BGP)
bgp_redistribute_unset (bgp, afi, i, 0);
/* Free peers and peer-groups. */
for (ALL_LIST_ELEMENTS (bgp->group, node, next, group))
{
peer_group_delete (group);
}
peer_group_delete (group);
for (ALL_LIST_ELEMENTS (bgp->peer, node, next, peer))
{
peer_delete (peer);
}
peer_delete (peer);
if (bgp->peer_self) {
peer_delete(bgp->peer_self);
bgp->peer_self = NULL;
}
if (bgp->t_rmap_def_originate_eval)
{
BGP_TIMER_OFF(bgp->t_rmap_def_originate_eval);
bgp_unlock(bgp);
}
update_bgp_group_free (bgp);
/* TODO - Other memory may need to be freed - e.g., NHT */
/* Remove visibility via the master list - there may however still be
* routes to be processed still referencing the struct bgp.
*/
@ -3037,6 +3069,14 @@ bgp_delete (struct bgp *bgp)
if (list_isempty(bm->bgp))
bgp_close ();
/* Deregister from Zebra, if needed */
if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
bgp_zebra_instance_deregister (bgp);
/* If VRF, unlink from the VRF structure. */
if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
bgp_vrf_unlink (bgp);
thread_master_free_unused(bm->master);
bgp_unlock(bgp); /* initial reference */
@ -3174,10 +3214,10 @@ peer_lookup (struct bgp *bgp, union sockunion *su)
for (ALL_LIST_ELEMENTS (bm->bgp, bgpnode, nbgpnode, bgp))
{
/*
* Don't have to cross the instance boundaries for VRFs.
/* Skip VRFs, this function will not be invoked without an instance
* when examining VRFs.
*/
if (bgp_flag_check(bgp, BGP_FLAG_INSTANCE_TYPE_VRF))
if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
continue;
peer = hash_lookup(bgp->peerhash, &tmp_peer);
@ -6904,8 +6944,9 @@ bgp_config_write (struct vty *vty)
if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE))
{
if (bgp->name)
vty_out (vty, " %s %s", (bgp_flag_check(bgp, BGP_FLAG_INSTANCE_TYPE_VIEW) ?
"view" : "vrf"), bgp->name);
vty_out (vty, " %s %s",
(bgp->inst_type == BGP_INSTANCE_TYPE_VIEW) ?
"view" : "vrf", bgp->name);
}
vty_out (vty, "%s", VTY_NEWLINE);
@ -7130,6 +7171,36 @@ bgp_master_init (void)
bgp_process_queue_init();
}
/*
* Free up connected routes and interfaces; invoked upon bgp_exit()
*/
void
bgp_if_finish (void)
{
struct bgp *bgp;
struct listnode *node, *nnode;
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
{
struct listnode *ifnode;
struct interface *ifp;
if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
continue;
for (ALL_LIST_ELEMENTS_RO (vrf_iflist(bgp->vrf_id), ifnode, ifp))
{
struct listnode *c_node, *c_nnode;
struct connected *c;
for (ALL_LIST_ELEMENTS (ifp->connected, c_node, c_nnode, c))
bgp_connected_delete (bgp, c);
if_delete (ifp);
}
list_free (vrf_iflist(bgp->vrf_id));
}
}
void
bgp_init (void)

View File

@ -129,6 +129,21 @@ struct bgp_redist
struct bgp_rmap rmap;
};
/*
* Type of 'struct bgp'.
* - Default: The default instance
* - VRF: A specific (non-default) VRF
* - View: An instance used for route exchange
* The "default" instance is treated separately to simplify the code. Note
* that if deployed in a Multi-VRF environment, it may not exist.
*/
enum bgp_instance_type
{
BGP_INSTANCE_TYPE_DEFAULT,
BGP_INSTANCE_TYPE_VRF,
BGP_INSTANCE_TYPE_VIEW
};
/* BGP instance structure. */
struct bgp
{
@ -138,6 +153,8 @@ struct bgp
/* Name of this BGP instance. */
char *name;
/* Type of instance and VRF id. */
enum bgp_instance_type inst_type;
vrf_id_t vrf_id;
/* Reference count to allow peer_delete to finish after bgp_delete */
@ -256,8 +273,6 @@ struct bgp
#define BGP_FLAG_MULTIPATH_RELAX_AS_SET (1 << 17)
#define BGP_FLAG_FORCE_STATIC_PROCESS (1 << 18)
#define BGP_FLAG_SHOW_HOSTNAME (1 << 19)
#define BGP_FLAG_INSTANCE_TYPE_VIEW (1 << 20)
#define BGP_FLAG_INSTANCE_TYPE_VRF (1 << 21)
/* BGP Per AF flags */
u_int16_t af_flags[AFI_MAX][SAFI_MAX];
@ -333,6 +348,10 @@ struct bgp
#define BGP_ROUTE_ADV_HOLD(bgp) (bgp->main_peers_update_hold)
#define IS_BGP_INST_KNOWN_TO_ZEBRA(bgp) \
(bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT || \
(bgp->inst_type == BGP_INSTANCE_TYPE_VRF && bgp->vrf_id != VRF_DEFAULT))
/* BGP peer-group support. */
struct peer_group
{
@ -837,6 +856,11 @@ u_char last_reset_cause[BGP_MAX_PACKET_SIZE];
char *domainname;
};
/* Check if suppress start/restart of sessions to peer. */
#define BGP_PEER_START_SUPPRESSED(P) \
(CHECK_FLAG ((P)->flags, PEER_FLAG_SHUTDOWN) \
|| CHECK_FLAG ((P)->sflags, PEER_STATUS_PREFIX_OVERFLOW))
#define PEER_PASSWORD_MINLEN (1)
#define PEER_PASSWORD_MAXLEN (80)
@ -1150,6 +1174,7 @@ extern char *peer_uptime (time_t, char *, size_t, u_char, json_object *);
extern int bgp_config_write (struct vty *);
extern void bgp_config_write_family_header (struct vty *, afi_t, safi_t, int *);
extern void bgp_if_finish (void);
extern void bgp_master_init (void);
extern void bgp_init (void);
@ -1160,7 +1185,7 @@ extern int bgp_option_set (int);
extern int bgp_option_unset (int);
extern int bgp_option_check (int);
extern int bgp_get (struct bgp **, as_t *, const char *);
extern int bgp_get (struct bgp **, as_t *, const char *, enum bgp_instance_type);
extern void bgp_instance_up (struct bgp *);
extern void bgp_instance_down (struct bgp *);
extern int bgp_delete (struct bgp *);