bgpd: Add the ability to use a VRF to bgp

Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2016-02-02 04:36:20 -08:00
parent e9d94ea773
commit 6aeb9e7846
13 changed files with 972 additions and 628 deletions

View File

@ -223,7 +223,6 @@ bgp_exit (int status)
{ {
struct bgp *bgp; struct bgp *bgp;
struct listnode *node, *nnode; struct listnode *node, *nnode;
struct interface *ifp;
extern struct zclient *zclient; extern struct zclient *zclient;
/* it only makes sense for this to be called on a clean exit */ /* it only makes sense for this to be called on a clean exit */
@ -239,6 +238,8 @@ bgp_exit (int status)
/* reverse bgp_zebra_init/if_init */ /* reverse bgp_zebra_init/if_init */
if (retain_mode) if (retain_mode)
if_add_hook (IF_DELETE_HOOK, NULL); 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)) for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
{ {
struct listnode *c_node, *c_nnode; struct listnode *c_node, *c_nnode;
@ -247,6 +248,7 @@ bgp_exit (int status)
for (ALL_LIST_ELEMENTS (ifp->connected, c_node, c_nnode, c)) for (ALL_LIST_ELEMENTS (ifp->connected, c_node, c_nnode, c))
bgp_connected_delete (c); bgp_connected_delete (c);
} }
*/
/* reverse bgp_attr_init */ /* reverse bgp_attr_init */
bgp_attr_finish (); bgp_attr_finish ();
@ -288,9 +290,6 @@ bgp_exit (int status)
if (bgp_ifindices_buf) if (bgp_ifindices_buf)
stream_free (bgp_ifindices_buf); stream_free (bgp_ifindices_buf);
/* reverse bgp_scan_init */
bgp_scan_finish ();
/* reverse bgp_master_init */ /* reverse bgp_master_init */
if (bm->master) if (bm->master)
thread_master_free (bm->master); thread_master_free (bm->master);

View File

@ -228,6 +228,10 @@ bgp_accept (struct thread *thread)
struct peer *peer; struct peer *peer;
struct peer *peer1; struct peer *peer1;
char buf[SU_ADDRSTRLEN]; char buf[SU_ADDRSTRLEN];
struct bgp *bgp;
char name[VRF_NAMSIZ + 1];
int rc;
socklen_t name_len = VRF_NAMSIZ;
sockunion_init (&su); sockunion_init (&su);
@ -249,15 +253,48 @@ bgp_accept (struct thread *thread)
} }
set_nonblocking (bgp_sock); set_nonblocking (bgp_sock);
name[0] = '\0';
rc = getsockopt(bgp_sock, SOL_SOCKET, SO_BINDTODEVICE, name, &name_len);
if (rc != 0)
{
zlog_err ("[Error] BGP SO_BINDTODEVICE get failed (%s)", safe_strerror (errno));
return -1;
}
else if (name[0] != '\0')
{
/* Pending:
- Cleanup/add proper debugs in this area.
- Test/find a way to implement interface config within a VRF.
*/
zlog_debug ("BGP accept vrf/interface %s, %u", name, name_len);
bgp = bgp_lookup_by_name (name);
if (bgp)
{
if (bgp->vrf_id)
zlog_debug ("BGP SO_BINDTODEVICE vrf-id in BGP %u", bgp->vrf_id);
else
{
zlog_debug ("BGP vrf not active!");
return -1;
}
}
/* if socket is interface bound, control may reach here, because name
may be equal to the interface name */
}
else
{
bgp = NULL;
}
/* Set socket send buffer size */ /* Set socket send buffer size */
bgp_update_sock_send_buffer_size(bgp_sock); bgp_update_sock_send_buffer_size(bgp_sock);
/* Check remote IP address */ /* Check remote IP address */
peer1 = peer_lookup (NULL, &su); peer1 = peer_lookup (bgp, &su);
if (! peer1) if (! peer1)
{ {
peer1 = peer_lookup_dynamic_neighbor (NULL, &su); peer1 = peer_lookup_dynamic_neighbor (bgp, &su);
if (peer1) if (peer1)
{ {
/* Dynamic neighbor has been created, let it proceed */ /* Dynamic neighbor has been created, let it proceed */
@ -382,10 +419,12 @@ bgp_bind (struct peer *peer)
int ret; int ret;
char *name; char *name;
if (! peer->ifname && !peer->conf_if) if (!peer->bgp->vrf_id && ! peer->ifname && !peer->conf_if)
return 0; return 0;
name = (peer->conf_if ? peer->conf_if : peer->ifname); name = (peer->conf_if ? peer->conf_if : (peer->ifname ? peer->ifname : peer->bgp->name));
zlog_debug ("Binding to interface %s\n", name);
if ( bgpd_privs.change (ZPRIVS_RAISE) ) if ( bgpd_privs.change (ZPRIVS_RAISE) )
zlog_err ("bgp_bind: could not raise privs"); zlog_err ("bgp_bind: could not raise privs");

View File

@ -47,15 +47,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
/* Route table for next-hop lookup cache. */
struct bgp_table *bgp_nexthop_cache_table[AFI_MAX];
/* Route table for connected route. */
static struct bgp_table *bgp_connected_table[AFI_MAX];
/* Route table for import-check */
struct bgp_table *bgp_import_check_table[AFI_MAX];
char * char *
bnc_str (struct bgp_nexthop_cache *bnc, char *buf, int size) bnc_str (struct bgp_nexthop_cache *bnc, char *buf, int size)
{ {
@ -116,8 +107,6 @@ struct bgp_addr
int refcnt; int refcnt;
}; };
static struct hash *bgp_address_hash;
static void * static void *
bgp_address_hash_alloc (void *p) bgp_address_hash_alloc (void *p)
{ {
@ -149,21 +138,21 @@ bgp_address_hash_cmp (const void *p1, const void *p2)
} }
void void
bgp_address_init (void) bgp_address_init (struct bgp *bgp)
{ {
bgp_address_hash = hash_create (bgp_address_hash_key_make, bgp->address_hash = hash_create (bgp_address_hash_key_make,
bgp_address_hash_cmp); bgp_address_hash_cmp);
} }
static void static void
bgp_address_add (struct prefix *p) bgp_address_add (struct bgp *bgp, struct prefix *p)
{ {
struct bgp_addr tmp; struct bgp_addr tmp;
struct bgp_addr *addr; struct bgp_addr *addr;
tmp.addr = p->u.prefix4; tmp.addr = p->u.prefix4;
addr = hash_get (bgp_address_hash, &tmp, bgp_address_hash_alloc); addr = hash_get (bgp->address_hash, &tmp, bgp_address_hash_alloc);
if (!addr) if (!addr)
return; return;
@ -171,14 +160,14 @@ bgp_address_add (struct prefix *p)
} }
static void static void
bgp_address_del (struct prefix *p) bgp_address_del (struct bgp *bgp, struct prefix *p)
{ {
struct bgp_addr tmp; struct bgp_addr tmp;
struct bgp_addr *addr; struct bgp_addr *addr;
tmp.addr = p->u.prefix4; tmp.addr = p->u.prefix4;
addr = hash_lookup (bgp_address_hash, &tmp); addr = hash_lookup (bgp->address_hash, &tmp);
/* may have been deleted earlier by bgp_interface_down() */ /* may have been deleted earlier by bgp_interface_down() */
if (addr == NULL) if (addr == NULL)
return; return;
@ -187,7 +176,7 @@ bgp_address_del (struct prefix *p)
if (addr->refcnt == 0) if (addr->refcnt == 0)
{ {
hash_release (bgp_address_hash, addr); hash_release (bgp->address_hash, addr);
XFREE (MTYPE_BGP_ADDR, addr); XFREE (MTYPE_BGP_ADDR, addr);
} }
} }
@ -199,14 +188,13 @@ struct bgp_connected_ref
}; };
void void
bgp_connected_add (struct connected *ifc) bgp_connected_add (struct bgp *bgp, struct connected *ifc)
{ {
struct prefix p; struct prefix p;
struct prefix *addr; struct prefix *addr;
struct bgp_node *rn; struct bgp_node *rn;
struct bgp_connected_ref *bc; struct bgp_connected_ref *bc;
struct listnode *node, *nnode, *mnode; struct listnode *node, *nnode;
struct bgp *bgp;
struct peer *peer; struct peer *peer;
addr = ifc->address; addr = ifc->address;
@ -219,9 +207,9 @@ bgp_connected_add (struct connected *ifc)
if (prefix_ipv4_any ((struct prefix_ipv4 *) &p)) if (prefix_ipv4_any ((struct prefix_ipv4 *) &p))
return; return;
bgp_address_add (addr); bgp_address_add (bgp, addr);
rn = bgp_node_get (bgp_connected_table[AFI_IP], (struct prefix *) &p); rn = bgp_node_get (bgp->connected_table[AFI_IP], (struct prefix *) &p);
if (rn->info) if (rn->info)
{ {
bc = rn->info; bc = rn->info;
@ -234,19 +222,16 @@ bgp_connected_add (struct connected *ifc)
rn->info = bc; rn->info = bc;
} }
for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp)) for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
{ {
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer)) if (peer->conf_if && (strcmp (peer->conf_if, ifc->ifp->name) == 0) &&
{ !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY))
if (peer->conf_if && (strcmp (peer->conf_if, ifc->ifp->name) == 0) && {
!CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)) if (peer_active(peer))
{ BGP_EVENT_ADD (peer, BGP_Stop);
if (peer_active(peer)) BGP_EVENT_ADD (peer, BGP_Start);
BGP_EVENT_ADD (peer, BGP_Stop); }
BGP_EVENT_ADD (peer, BGP_Start); }
}
}
}
} }
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
else if (addr->family == AF_INET6) else if (addr->family == AF_INET6)
@ -259,7 +244,7 @@ bgp_connected_add (struct connected *ifc)
if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6)) if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
return; return;
rn = bgp_node_get (bgp_connected_table[AFI_IP6], (struct prefix *) &p); rn = bgp_node_get (bgp->connected_table[AFI_IP6], (struct prefix *) &p);
if (rn->info) if (rn->info)
{ {
bc = rn->info; bc = rn->info;
@ -276,7 +261,7 @@ bgp_connected_add (struct connected *ifc)
} }
void void
bgp_connected_delete (struct connected *ifc) bgp_connected_delete (struct bgp *bgp, struct connected *ifc)
{ {
struct prefix p; struct prefix p;
struct prefix *addr; struct prefix *addr;
@ -293,9 +278,9 @@ bgp_connected_delete (struct connected *ifc)
if (prefix_ipv4_any ((struct prefix_ipv4 *) &p)) if (prefix_ipv4_any ((struct prefix_ipv4 *) &p))
return; return;
bgp_address_del (addr); bgp_address_del (bgp, addr);
rn = bgp_node_lookup (bgp_connected_table[AFI_IP], &p); rn = bgp_node_lookup (bgp->connected_table[AFI_IP], &p);
if (! rn) if (! rn)
return; return;
@ -320,7 +305,7 @@ bgp_connected_delete (struct connected *ifc)
if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6)) if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
return; return;
rn = bgp_node_lookup (bgp_connected_table[AFI_IP6], (struct prefix *) &p); rn = bgp_node_lookup (bgp->connected_table[AFI_IP6], (struct prefix *) &p);
if (! rn) if (! rn)
return; return;
@ -338,13 +323,13 @@ bgp_connected_delete (struct connected *ifc)
} }
int int
bgp_nexthop_self (struct attr *attr) bgp_nexthop_self (struct bgp *bgp, struct attr *attr)
{ {
struct bgp_addr tmp, *addr; struct bgp_addr tmp, *addr;
tmp.addr = attr->nexthop; tmp.addr = attr->nexthop;
addr = hash_lookup (bgp_address_hash, &tmp); addr = hash_lookup (bgp->address_hash, &tmp);
if (addr) if (addr)
return 1; return 1;
@ -363,7 +348,7 @@ bgp_multiaccess_check_v4 (struct in_addr nexthop, struct peer *peer)
p.prefixlen = IPV4_MAX_BITLEN; p.prefixlen = IPV4_MAX_BITLEN;
p.u.prefix4 = nexthop; p.u.prefix4 = nexthop;
rn1 = bgp_node_match (bgp_connected_table[AFI_IP], &p); rn1 = bgp_node_match (peer->bgp->connected_table[AFI_IP], &p);
if (!rn1) if (!rn1)
return 0; return 0;
@ -371,7 +356,7 @@ bgp_multiaccess_check_v4 (struct in_addr nexthop, struct peer *peer)
p.prefixlen = IPV4_MAX_BITLEN; p.prefixlen = IPV4_MAX_BITLEN;
p.u.prefix4 = peer->su.sin.sin_addr; p.u.prefix4 = peer->su.sin.sin_addr;
rn2 = bgp_node_match (bgp_connected_table[AFI_IP], &p); rn2 = bgp_node_match (peer->bgp->connected_table[AFI_IP], &p);
if (!rn2) if (!rn2)
{ {
bgp_unlock_node(rn1); bgp_unlock_node(rn1);
@ -387,7 +372,7 @@ bgp_multiaccess_check_v4 (struct in_addr nexthop, struct peer *peer)
} }
static int static int
show_ip_bgp_nexthop_table (struct vty *vty, int detail) show_ip_bgp_nexthop_table (struct vty *vty, const char *name, int detail)
{ {
struct bgp_node *rn; struct bgp_node *rn;
struct bgp_nexthop_cache *bnc; struct bgp_nexthop_cache *bnc;
@ -395,11 +380,22 @@ show_ip_bgp_nexthop_table (struct vty *vty, int detail)
struct nexthop *nexthop; struct nexthop *nexthop;
time_t tbuf; time_t tbuf;
afi_t afi; afi_t afi;
struct bgp *bgp;
if (name)
bgp = bgp_lookup_by_name (name);
else
bgp = bgp_get_default ();
if (!bgp)
{
vty_out (vty, "%% No such BGP instance exist%s", VTY_NEWLINE);
return CMD_WARNING;
}
vty_out (vty, "Current BGP nexthop cache:%s", VTY_NEWLINE); vty_out (vty, "Current BGP nexthop cache:%s", VTY_NEWLINE);
for (afi = AFI_IP ; afi < AFI_MAX ; afi++) for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
{ {
for (rn = bgp_table_top (bgp_nexthop_cache_table[afi]); rn; rn = bgp_route_next (rn)) for (rn = bgp_table_top (bgp->nexthop_cache_table[afi]); rn; rn = bgp_route_next (rn))
{ {
if ((bnc = rn->info) != NULL) if ((bnc = rn->info) != NULL)
{ {
@ -473,7 +469,7 @@ DEFUN (show_ip_bgp_nexthop,
BGP_STR BGP_STR
"BGP nexthop table\n") "BGP nexthop table\n")
{ {
return show_ip_bgp_nexthop_table (vty, 0); return show_ip_bgp_nexthop_table (vty, NULL, 0);
} }
DEFUN (show_ip_bgp_nexthop_detail, DEFUN (show_ip_bgp_nexthop_detail,
@ -484,20 +480,20 @@ DEFUN (show_ip_bgp_nexthop_detail,
BGP_STR BGP_STR
"BGP nexthop table\n") "BGP nexthop table\n")
{ {
return show_ip_bgp_nexthop_table (vty, 1); return show_ip_bgp_nexthop_table (vty, NULL, 1);
} }
void void
bgp_scan_init (void) bgp_scan_init (struct bgp *bgp)
{ {
bgp_nexthop_cache_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST); bgp->nexthop_cache_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST);
bgp_connected_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST); bgp->connected_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST);
bgp_import_check_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST); bgp->import_check_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST);
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
bgp_nexthop_cache_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST); bgp->nexthop_cache_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST);
bgp_connected_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST); bgp->connected_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST);
bgp_import_check_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST); bgp->import_check_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST);
#endif /* HAVE_IPV6 */ #endif /* HAVE_IPV6 */
} }
@ -512,31 +508,31 @@ bgp_scan_vty_init (void)
} }
void void
bgp_scan_finish (void) bgp_scan_finish (struct bgp *bgp)
{ {
/* Only the current one needs to be reset. */ /* Only the current one needs to be reset. */
bgp_nexthop_cache_reset (bgp_nexthop_cache_table[AFI_IP]); bgp_nexthop_cache_reset (bgp->nexthop_cache_table[AFI_IP]);
bgp_table_unlock (bgp_nexthop_cache_table[AFI_IP]); bgp_table_unlock (bgp->nexthop_cache_table[AFI_IP]);
bgp_nexthop_cache_table[AFI_IP] = NULL; bgp->nexthop_cache_table[AFI_IP] = NULL;
bgp_table_unlock (bgp_connected_table[AFI_IP]); bgp_table_unlock (bgp->connected_table[AFI_IP]);
bgp_connected_table[AFI_IP] = NULL; bgp->connected_table[AFI_IP] = NULL;
bgp_table_unlock (bgp_import_check_table[AFI_IP]); bgp_table_unlock (bgp->import_check_table[AFI_IP]);
bgp_import_check_table[AFI_IP] = NULL; bgp->import_check_table[AFI_IP] = NULL;
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
/* Only the current one needs to be reset. */ /* Only the current one needs to be reset. */
bgp_nexthop_cache_reset (bgp_nexthop_cache_table[AFI_IP6]); bgp_nexthop_cache_reset (bgp->nexthop_cache_table[AFI_IP6]);
bgp_table_unlock (bgp_nexthop_cache_table[AFI_IP6]); bgp_table_unlock (bgp->nexthop_cache_table[AFI_IP6]);
bgp_nexthop_cache_table[AFI_IP6] = NULL; bgp->nexthop_cache_table[AFI_IP6] = NULL;
bgp_table_unlock (bgp_connected_table[AFI_IP6]); bgp_table_unlock (bgp->connected_table[AFI_IP6]);
bgp_connected_table[AFI_IP6] = NULL; bgp->connected_table[AFI_IP6] = NULL;
bgp_table_unlock (bgp_import_check_table[AFI_IP6]); bgp_table_unlock (bgp->import_check_table[AFI_IP6]);
bgp_import_check_table[AFI_IP6] = NULL; bgp->import_check_table[AFI_IP6] = NULL;
#endif /* HAVE_IPV6 */ #endif /* HAVE_IPV6 */
} }

View File

@ -59,17 +59,18 @@ struct bgp_nexthop_cache
extern int bgp_nexthop_lookup (afi_t, struct peer *peer, struct bgp_info *, extern int bgp_nexthop_lookup (afi_t, struct peer *peer, struct bgp_info *,
int *, int *); int *, int *);
extern void bgp_connected_add (struct connected *c); extern void bgp_connected_add (struct bgp *bgp, struct connected *c);
extern void bgp_connected_delete (struct connected *c); extern void bgp_connected_delete (struct bgp *bgp, struct connected *c);
extern int bgp_multiaccess_check_v4 (struct in_addr, struct peer *); extern int bgp_multiaccess_check_v4 (struct in_addr, struct peer *);
extern int bgp_config_write_scan_time (struct vty *); extern int bgp_config_write_scan_time (struct vty *);
extern int bgp_nexthop_self (struct attr *); extern int bgp_nexthop_self (struct bgp *, struct attr *);
extern void bgp_address_init (void); extern void bgp_address_init (struct bgp *);
extern struct bgp_nexthop_cache *bnc_new(void); extern struct bgp_nexthop_cache *bnc_new(void);
extern void bnc_free(struct bgp_nexthop_cache *bnc); extern void bnc_free(struct bgp_nexthop_cache *bnc);
extern void bnc_nexthop_free(struct bgp_nexthop_cache *bnc); extern void bnc_nexthop_free(struct bgp_nexthop_cache *bnc);
extern char *bnc_str(struct bgp_nexthop_cache *bnc, char *buf, int size); extern char *bnc_str(struct bgp_nexthop_cache *bnc, char *buf, int size);
extern void bgp_scan_init(void); extern void bgp_scan_init(struct bgp *bgp);
extern void bgp_scan_finish(struct bgp *bgp);
extern void bgp_scan_vty_init(void); extern void bgp_scan_vty_init(void);
#endif /* _QUAGGA_BGP_NEXTHOP_H */ #endif /* _QUAGGA_BGP_NEXTHOP_H */

View File

@ -42,8 +42,6 @@
#include "bgpd/bgp_fsm.h" #include "bgpd/bgp_fsm.h"
extern struct zclient *zclient; extern struct zclient *zclient;
extern struct bgp_table *bgp_nexthop_cache_table[AFI_MAX];
extern struct bgp_table *bgp_import_check_table[AFI_MAX];
static void register_zebra_rnh(struct bgp_nexthop_cache *bnc, static void register_zebra_rnh(struct bgp_nexthop_cache *bnc,
int is_bgp_static_route); int is_bgp_static_route);
@ -148,9 +146,9 @@ bgp_find_or_add_nexthop (struct bgp *bgp, afi_t afi, struct bgp_info *ri,
return 0; return 0;
if (is_bgp_static_route) if (is_bgp_static_route)
rn = bgp_node_get (bgp_import_check_table[afi], &p); rn = bgp_node_get (bgp->import_check_table[afi], &p);
else else
rn = bgp_node_get (bgp_nexthop_cache_table[afi], &p); rn = bgp_node_get (bgp->nexthop_cache_table[afi], &p);
if (!rn->info) if (!rn->info)
{ {
@ -267,7 +265,7 @@ bgp_delete_connected_nexthop (afi_t afi, struct peer *peer)
else else
return; return;
rn = bgp_node_lookup(bgp_nexthop_cache_table[family2afi(p.family)], &p); rn = bgp_node_lookup(peer->bgp->nexthop_cache_table[family2afi(p.family)], &p);
if (!rn || !rn->info) if (!rn || !rn->info)
{ {
if (BGP_DEBUG(nht, NHT)) if (BGP_DEBUG(nht, NHT))
@ -316,6 +314,14 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
u_char nexthop_num; u_char nexthop_num;
struct prefix p; struct prefix p;
int i; int i;
struct bgp *bgp;
bgp = bgp_lookup_by_vrf_id (vrf_id);
if (!bgp)
{
zlog_err("parse nexthop update: instance not found for vrf_id %d", vrf_id);
return;
}
s = zclient->ibuf; s = zclient->ibuf;
@ -335,9 +341,9 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
} }
if (command == ZEBRA_NEXTHOP_UPDATE) if (command == ZEBRA_NEXTHOP_UPDATE)
rn = bgp_node_lookup(bgp_nexthop_cache_table[family2afi(p.family)], &p); rn = bgp_node_lookup(bgp->nexthop_cache_table[family2afi(p.family)], &p);
else if (command == ZEBRA_IMPORT_CHECK_UPDATE) else if (command == ZEBRA_IMPORT_CHECK_UPDATE)
rn = bgp_node_lookup(bgp_import_check_table[family2afi(p.family)], &p); rn = bgp_node_lookup(bgp->import_check_table[family2afi(p.family)], &p);
if (!rn || !rn->info) if (!rn || !rn->info)
{ {
@ -534,10 +540,11 @@ sendmsg_zebra_rnh (struct bgp_nexthop_cache *bnc, int command)
/* Check socket. */ /* Check socket. */
if (!zclient || zclient->sock < 0) if (!zclient || zclient->sock < 0)
{ {
/* Pending: hiding this error now, because bgp_nht_register_all() is implemented. /* Hiding this error now, because bgp_nht_register_all() is implemented.
which tries it after zclient_connect() which tries it after zclient_connect()
zlog_debug("%s: Can't send NH register, Zebra client not established", zlog_debug("%s: Can't send NH register, Zebra client not established",
__FUNCTION__); __FUNCTION__);
Pending: remove this comment after reviewing to see if no message is needed in this case
*/ */
return; return;
} }
@ -545,7 +552,7 @@ sendmsg_zebra_rnh (struct bgp_nexthop_cache *bnc, int command)
p = &(bnc->node->p); p = &(bnc->node->p);
s = zclient->obuf; s = zclient->obuf;
stream_reset (s); stream_reset (s);
zclient_create_header (s, command, VRF_DEFAULT); zclient_create_header (s, command, bnc->bgp->vrf_id);
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED) || if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED) ||
CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH)) CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH))
stream_putc(s, 1); stream_putc(s, 1);
@ -696,31 +703,39 @@ evaluate_paths (struct bgp_nexthop_cache *bnc)
} }
void void
bgp_nht_register_all (void) bgp_nht_register_all (vrf_id_t vrf_id)
{ {
struct bgp_node *rn; struct bgp_node *rn;
struct bgp_nexthop_cache *bnc; struct bgp_nexthop_cache *bnc;
struct bgp *bgp;
for (rn = bgp_table_top (bgp_nexthop_cache_table[AFI_IP]); rn; rn = bgp_route_next (rn)) 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 && if ((bnc = rn->info) != NULL &&
!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED)) !CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
{ {
register_zebra_rnh(bnc, 0); register_zebra_rnh(bnc, 0);
} }
for (rn = bgp_table_top (bgp_nexthop_cache_table[AFI_IP6]); rn; rn = bgp_route_next (rn)) for (rn = bgp_table_top (bgp->nexthop_cache_table[AFI_IP6]); rn; rn = bgp_route_next (rn))
if ((bnc = rn->info) != NULL && if ((bnc = rn->info) != NULL &&
!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED)) !CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
{ {
register_zebra_rnh(bnc, 0); register_zebra_rnh(bnc, 0);
} }
for (rn = bgp_table_top (bgp_import_check_table[AFI_IP]); rn; rn = bgp_route_next (rn)) for (rn = bgp_table_top (bgp->import_check_table[AFI_IP]); rn; rn = bgp_route_next (rn))
if ((bnc = rn->info) != NULL && if ((bnc = rn->info) != NULL &&
!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED)) !CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
{ {
register_zebra_rnh(bnc, 1); register_zebra_rnh(bnc, 1);
} }
for (rn = bgp_table_top (bgp_import_check_table[AFI_IP6]); rn; rn = bgp_route_next (rn)) for (rn = bgp_table_top (bgp->import_check_table[AFI_IP6]); rn; rn = bgp_route_next (rn))
if ((bnc = rn->info) != NULL && if ((bnc = rn->info) != NULL &&
!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED)) !CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
{ {

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -239,12 +239,13 @@ extern int bgp_nlri_parse (struct peer *, struct attr *, struct bgp_nlri *);
extern int bgp_maximum_prefix_overflow (struct peer *, afi_t, safi_t, int); extern int bgp_maximum_prefix_overflow (struct peer *, afi_t, safi_t, int);
extern void bgp_redistribute_add (struct prefix *, const struct in_addr *, extern void bgp_redistribute_add (struct bgp *, struct prefix *, const struct in_addr *,
const struct in6_addr *, unsigned int ifindex, const struct in6_addr *, unsigned int ifindex,
u_int32_t, u_char, u_short, u_short); u_int32_t, u_char, u_short, u_short);
extern void bgp_redistribute_delete (struct prefix *, u_char, u_short); extern void bgp_redistribute_delete (struct bgp *, struct prefix *, u_char, u_short);
extern void bgp_redistribute_withdraw (struct bgp *, afi_t, int, u_short); 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_delete (struct bgp *);
extern void bgp_static_redo_import_check (struct bgp *); extern void bgp_static_redo_import_check (struct bgp *);
extern void bgp_static_update (struct bgp *, struct prefix *, struct bgp_static *, extern void bgp_static_update (struct bgp *, struct prefix *, struct bgp_static *,

View File

@ -55,8 +55,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_updgrp.h" #include "bgpd/bgp_updgrp.h"
#include "bgpd/bgp_bfd.h" #include "bgpd/bgp_bfd.h"
extern struct in_addr router_id_zebra;
static struct peer_group * static struct peer_group *
listen_range_exists (struct bgp *bgp, struct prefix *range, int exact); listen_range_exists (struct bgp *bgp, struct prefix *range, int exact);
@ -82,16 +80,16 @@ bgp_node_safi (struct vty *vty)
} }
static int static int
peer_address_self_check (union sockunion *su) peer_address_self_check (struct bgp *bgp, union sockunion *su)
{ {
struct interface *ifp = NULL; struct interface *ifp = NULL;
if (su->sa.sa_family == AF_INET) if (su->sa.sa_family == AF_INET)
ifp = if_lookup_by_ipv4_exact (&su->sin.sin_addr); ifp = if_lookup_by_ipv4_exact (&su->sin.sin_addr, bgp->vrf_id);
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
else if (su->sa.sa_family == AF_INET6) else if (su->sa.sa_family == AF_INET6)
ifp = if_lookup_by_ipv6_exact (&su->sin6.sin6_addr, ifp = if_lookup_by_ipv6_exact (&su->sin6.sin6_addr,
su->sin6.sin6_scope_id); su->sin6.sin6_scope_id, bgp->vrf_id);
#endif /* HAVE IPV6 */ #endif /* HAVE IPV6 */
if (ifp) if (ifp)
@ -471,7 +469,7 @@ bgp_clear_vty (struct vty *vty, const char *name, afi_t afi, safi_t safi,
bgp = bgp_lookup_by_name (name); bgp = bgp_lookup_by_name (name);
if (bgp == NULL) if (bgp == NULL)
{ {
vty_out (vty, "Can't find BGP view %s%s", name, VTY_NEWLINE); vty_out (vty, "Can't find BGP instance %s%s", name, VTY_NEWLINE);
return CMD_WARNING; return CMD_WARNING;
} }
} }
@ -613,6 +611,7 @@ DEFUN (router_bgp,
// "router bgp" without an ASN // "router bgp" without an ASN
if (argc < 1) if (argc < 1)
{ {
//Pending: Make VRF option available for ASN less config
bgp = bgp_get_default(); bgp = bgp_get_default();
if (bgp == NULL) if (bgp == NULL)
@ -633,8 +632,8 @@ DEFUN (router_bgp,
{ {
VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX); VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
if (argc == 2) if (argc == 3)
name = argv[1]; name = argv[2];
ret = bgp_get (&bgp, &as, name); ret = bgp_get (&bgp, &as, name);
switch (ret) switch (ret)
@ -647,11 +646,17 @@ DEFUN (router_bgp,
vty_out (vty, "BGP is already running; AS is %u%s", as, VTY_NEWLINE); vty_out (vty, "BGP is already running; AS is %u%s", as, VTY_NEWLINE);
return CMD_WARNING; return CMD_WARNING;
case BGP_ERR_INSTANCE_MISMATCH: case BGP_ERR_INSTANCE_MISMATCH:
vty_out (vty, "BGP view name and AS number mismatch%s", VTY_NEWLINE); vty_out (vty, "BGP instance name and AS number mismatch%s", VTY_NEWLINE);
vty_out (vty, "BGP instance is already running; AS is %u%s", vty_out (vty, "BGP instance is already running; AS is %u%s",
as, VTY_NEWLINE); as, VTY_NEWLINE);
return CMD_WARNING; return CMD_WARNING;
} }
/* 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; vty->node = BGP_NODE;
@ -661,12 +666,12 @@ DEFUN (router_bgp,
} }
ALIAS (router_bgp, ALIAS (router_bgp,
router_bgp_view_cmd, router_bgp_instance_cmd,
"router bgp " CMD_AS_RANGE " view WORD", "router bgp " CMD_AS_RANGE " (view|vrf) WORD",
ROUTER_STR ROUTER_STR
BGP_STR BGP_STR
AS_STR AS_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"view name\n") "view name\n")
ALIAS (router_bgp, ALIAS (router_bgp,
@ -690,8 +695,8 @@ DEFUN (no_router_bgp,
VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX); VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
if (argc == 2) if (argc == 3)
name = argv[1]; name = argv[2];
/* Lookup bgp structure. */ /* Lookup bgp structure. */
bgp = bgp_lookup (as, name); bgp = bgp_lookup (as, name);
@ -707,13 +712,13 @@ DEFUN (no_router_bgp,
} }
ALIAS (no_router_bgp, ALIAS (no_router_bgp,
no_router_bgp_view_cmd, no_router_bgp_instance_cmd,
"no router bgp " CMD_AS_RANGE " view WORD", "no router bgp " CMD_AS_RANGE " (view|vrf) WORD",
NO_STR NO_STR
ROUTER_STR ROUTER_STR
BGP_STR BGP_STR
AS_STR AS_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"view name\n") "view name\n")
/* BGP router-id. */ /* BGP router-id. */
@ -777,7 +782,7 @@ DEFUN (no_bgp_router_id,
} }
bgp->router_id_static.s_addr = 0; bgp->router_id_static.s_addr = 0;
bgp_router_id_set (bgp, &router_id_zebra); bgp_router_id_set (bgp, &bgp->router_id_zebra);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -2639,7 +2644,7 @@ peer_remote_as_vty (struct vty *vty, const char *peer_str,
} }
else else
{ {
if (peer_address_self_check (&su)) if (peer_address_self_check (bgp, &su))
{ {
vty_out (vty, "%% Can not configure the local system as neighbor%s", vty_out (vty, "%% Can not configure the local system as neighbor%s",
VTY_NEWLINE); VTY_NEWLINE);
@ -3252,7 +3257,7 @@ DEFUN (neighbor_set_peer_group,
} }
else else
{ {
if (peer_address_self_check (&su)) if (peer_address_self_check (bgp, &su))
{ {
vty_out (vty, "%% Can not configure the local system as neighbor%s", vty_out (vty, "%% Can not configure the local system as neighbor%s",
VTY_NEWLINE); VTY_NEWLINE);
@ -5870,7 +5875,7 @@ bgp_clear_prefix (struct vty *vty, char *view_name, const char *ip_str,
bgp = bgp_lookup_by_name (view_name); bgp = bgp_lookup_by_name (view_name);
if (bgp == NULL) if (bgp == NULL)
{ {
vty_out (vty, "%% Can't find BGP view %s%s", view_name, VTY_NEWLINE); vty_out (vty, "%% Can't find BGP instance %s%s", view_name, VTY_NEWLINE);
return CMD_WARNING; return CMD_WARNING;
} }
} }
@ -5940,8 +5945,8 @@ DEFUN (clear_ip_bgp_all,
BGP_STR BGP_STR
"Clear all peers\n") "Clear all peers\n")
{ {
if (argc == 1) if (argc == 2)
return bgp_clear_vty (vty, argv[0], 0, 0, clear_all, BGP_CLEAR_SOFT_NONE, NULL); return bgp_clear_vty (vty, argv[1], 0, 0, clear_all, BGP_CLEAR_SOFT_NONE, NULL);
return bgp_clear_vty (vty, NULL, 0, 0, clear_all, BGP_CLEAR_SOFT_NONE, NULL); return bgp_clear_vty (vty, NULL, 0, 0, clear_all, BGP_CLEAR_SOFT_NONE, NULL);
} }
@ -5963,20 +5968,20 @@ ALIAS (clear_ip_bgp_all,
ALIAS (clear_ip_bgp_all, ALIAS (clear_ip_bgp_all,
clear_ip_bgp_instance_all_cmd, clear_ip_bgp_instance_all_cmd,
"clear ip bgp view WORD *", "clear ip bgp (view|vrf) WORD *",
CLEAR_STR CLEAR_STR
IP_STR IP_STR
BGP_STR BGP_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"view name\n" "view name\n"
"Clear all peers\n") "Clear all peers\n")
ALIAS (clear_ip_bgp_all, ALIAS (clear_ip_bgp_all,
clear_bgp_instance_all_cmd, clear_bgp_instance_all_cmd,
"clear bgp view WORD *", "clear bgp (view|vrf) WORD *",
CLEAR_STR CLEAR_STR
BGP_STR BGP_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"view name\n" "view name\n"
"Clear all peers\n") "Clear all peers\n")
@ -6125,8 +6130,8 @@ DEFUN (clear_ip_bgp_all_soft_out,
BGP_SOFT_STR BGP_SOFT_STR
BGP_SOFT_OUT_STR) BGP_SOFT_OUT_STR)
{ {
if (argc == 1) if (argc == 2)
return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_UNICAST, clear_all, return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_UNICAST, clear_all,
BGP_CLEAR_SOFT_OUT, NULL); BGP_CLEAR_SOFT_OUT, NULL);
return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all, return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all,
@ -6144,12 +6149,12 @@ ALIAS (clear_ip_bgp_all_soft_out,
ALIAS (clear_ip_bgp_all_soft_out, ALIAS (clear_ip_bgp_all_soft_out,
clear_ip_bgp_instance_all_soft_out_cmd, clear_ip_bgp_instance_all_soft_out_cmd,
"clear ip bgp view WORD * soft out", "clear ip bgp (view|vrf) WORD * soft out",
CLEAR_STR CLEAR_STR
IP_STR IP_STR
BGP_STR BGP_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"view name\n" "View/VRF name\n"
"Clear all peers\n" "Clear all peers\n"
BGP_SOFT_STR BGP_SOFT_STR
BGP_SOFT_OUT_STR) BGP_SOFT_OUT_STR)
@ -6189,11 +6194,11 @@ ALIAS (clear_ip_bgp_all_ipv4_soft_out,
DEFUN (clear_ip_bgp_instance_all_ipv4_soft_out, DEFUN (clear_ip_bgp_instance_all_ipv4_soft_out,
clear_ip_bgp_instance_all_ipv4_soft_out_cmd, clear_ip_bgp_instance_all_ipv4_soft_out_cmd,
"clear ip bgp view WORD * ipv4 (unicast|multicast) soft out", "clear ip bgp (view|vrf) WORD * ipv4 (unicast|multicast) soft out",
CLEAR_STR CLEAR_STR
IP_STR IP_STR
BGP_STR BGP_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"view name\n" "view name\n"
"Clear all peers\n" "Clear all peers\n"
"Address family\n" "Address family\n"
@ -6201,8 +6206,8 @@ DEFUN (clear_ip_bgp_instance_all_ipv4_soft_out,
"Address Family modifier\n" "Address Family modifier\n"
BGP_SOFT_OUT_STR) BGP_SOFT_OUT_STR)
{ {
if (strncmp (argv[1], "m", 1) == 0) if (strncmp (argv[2], "m", 1) == 0)
return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_MULTICAST, clear_all, return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_MULTICAST, clear_all,
BGP_CLEAR_SOFT_OUT, NULL); BGP_CLEAR_SOFT_OUT, NULL);
return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_UNICAST, clear_all, return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_UNICAST, clear_all,
@ -6245,8 +6250,8 @@ DEFUN (clear_bgp_all_soft_out,
BGP_SOFT_STR BGP_SOFT_STR
BGP_SOFT_OUT_STR) BGP_SOFT_OUT_STR)
{ {
if (argc == 1) if (argc == 2)
return bgp_clear_vty (vty, argv[0], AFI_IP6, SAFI_UNICAST, clear_all, return bgp_clear_vty (vty, argv[1], AFI_IP6, SAFI_UNICAST, clear_all,
BGP_CLEAR_SOFT_OUT, NULL); BGP_CLEAR_SOFT_OUT, NULL);
return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_all, return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_all,
@ -6255,10 +6260,10 @@ DEFUN (clear_bgp_all_soft_out,
ALIAS (clear_bgp_all_soft_out, ALIAS (clear_bgp_all_soft_out,
clear_bgp_instance_all_soft_out_cmd, clear_bgp_instance_all_soft_out_cmd,
"clear bgp view WORD * soft out", "clear bgp (view|vrf) WORD * soft out",
CLEAR_STR CLEAR_STR
BGP_STR BGP_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"view name\n" "view name\n"
"Clear all peers\n" "Clear all peers\n"
BGP_SOFT_STR BGP_SOFT_STR
@ -6779,8 +6784,8 @@ DEFUN (clear_ip_bgp_all_soft_in,
BGP_SOFT_STR BGP_SOFT_STR
BGP_SOFT_IN_STR) BGP_SOFT_IN_STR)
{ {
if (argc == 1) if (argc == 2)
return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_UNICAST, clear_all, return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_UNICAST, clear_all,
BGP_CLEAR_SOFT_IN, NULL); BGP_CLEAR_SOFT_IN, NULL);
return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all, return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all,
@ -6789,11 +6794,11 @@ DEFUN (clear_ip_bgp_all_soft_in,
ALIAS (clear_ip_bgp_all_soft_in, ALIAS (clear_ip_bgp_all_soft_in,
clear_ip_bgp_instance_all_soft_in_cmd, clear_ip_bgp_instance_all_soft_in_cmd,
"clear ip bgp view WORD * soft in", "clear ip bgp (view|vrf) WORD * soft in",
CLEAR_STR CLEAR_STR
IP_STR IP_STR
BGP_STR BGP_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"view name\n" "view name\n"
"Clear all peers\n" "Clear all peers\n"
BGP_SOFT_STR BGP_SOFT_STR
@ -6818,8 +6823,8 @@ DEFUN (clear_ip_bgp_all_in_prefix_filter,
BGP_SOFT_IN_STR BGP_SOFT_IN_STR
"Push out prefix-list ORF and do inbound soft reconfig\n") "Push out prefix-list ORF and do inbound soft reconfig\n")
{ {
if (argc== 1) if (argc== 2)
return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_UNICAST, clear_all, return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_UNICAST, clear_all,
BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL); BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL);
return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all, return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all,
@ -6828,11 +6833,11 @@ DEFUN (clear_ip_bgp_all_in_prefix_filter,
ALIAS (clear_ip_bgp_all_in_prefix_filter, ALIAS (clear_ip_bgp_all_in_prefix_filter,
clear_ip_bgp_instance_all_in_prefix_filter_cmd, clear_ip_bgp_instance_all_in_prefix_filter_cmd,
"clear ip bgp view WORD * in prefix-filter", "clear ip bgp (view|vrf) WORD * in prefix-filter",
CLEAR_STR CLEAR_STR
IP_STR IP_STR
BGP_STR BGP_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"view name\n" "view name\n"
"Clear all peers\n" "Clear all peers\n"
BGP_SOFT_IN_STR BGP_SOFT_IN_STR
@ -6874,11 +6879,11 @@ ALIAS (clear_ip_bgp_all_ipv4_soft_in,
DEFUN (clear_ip_bgp_instance_all_ipv4_soft_in, DEFUN (clear_ip_bgp_instance_all_ipv4_soft_in,
clear_ip_bgp_instance_all_ipv4_soft_in_cmd, clear_ip_bgp_instance_all_ipv4_soft_in_cmd,
"clear ip bgp view WORD * ipv4 (unicast|multicast) soft in", "clear ip bgp (view|vrf) WORD * ipv4 (unicast|multicast) soft in",
CLEAR_STR CLEAR_STR
IP_STR IP_STR
BGP_STR BGP_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"view name\n" "view name\n"
"Clear all peers\n" "Clear all peers\n"
"Address family\n" "Address family\n"
@ -6887,11 +6892,11 @@ DEFUN (clear_ip_bgp_instance_all_ipv4_soft_in,
BGP_SOFT_STR BGP_SOFT_STR
BGP_SOFT_IN_STR) BGP_SOFT_IN_STR)
{ {
if (strncmp (argv[1], "m", 1) == 0) if (strncmp (argv[2], "m", 1) == 0)
return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_MULTICAST, clear_all, return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_MULTICAST, clear_all,
BGP_CLEAR_SOFT_IN, NULL); BGP_CLEAR_SOFT_IN, NULL);
return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_UNICAST, clear_all, return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_UNICAST, clear_all,
BGP_CLEAR_SOFT_IN, NULL); BGP_CLEAR_SOFT_IN, NULL);
} }
@ -6918,7 +6923,7 @@ DEFUN (clear_ip_bgp_all_ipv4_in_prefix_filter,
DEFUN (clear_ip_bgp_instance_all_ipv4_in_prefix_filter, DEFUN (clear_ip_bgp_instance_all_ipv4_in_prefix_filter,
clear_ip_bgp_instance_all_ipv4_in_prefix_filter_cmd, clear_ip_bgp_instance_all_ipv4_in_prefix_filter_cmd,
"clear ip bgp view WORD * ipv4 (unicast|multicast) in prefix-filter", "clear ip bgp (view|vrf) WORD * ipv4 (unicast|multicast) in prefix-filter",
CLEAR_STR CLEAR_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -6929,8 +6934,8 @@ DEFUN (clear_ip_bgp_instance_all_ipv4_in_prefix_filter,
BGP_SOFT_IN_STR BGP_SOFT_IN_STR
"Push out prefix-list ORF and do inbound soft reconfig\n") "Push out prefix-list ORF and do inbound soft reconfig\n")
{ {
if (strncmp (argv[1], "m", 1) == 0) if (strncmp (argv[2], "m", 1) == 0)
return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_MULTICAST, clear_all, return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_MULTICAST, clear_all,
BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL); BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL);
return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_UNICAST, clear_all, return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_UNICAST, clear_all,
@ -6973,8 +6978,8 @@ DEFUN (clear_bgp_all_soft_in,
BGP_SOFT_STR BGP_SOFT_STR
BGP_SOFT_IN_STR) BGP_SOFT_IN_STR)
{ {
if (argc == 1) if (argc == 2)
return bgp_clear_vty (vty, argv[0], AFI_IP6, SAFI_UNICAST, clear_all, return bgp_clear_vty (vty, argv[1], AFI_IP6, SAFI_UNICAST, clear_all,
BGP_CLEAR_SOFT_IN, NULL); BGP_CLEAR_SOFT_IN, NULL);
return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_all, return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_all,
@ -6983,10 +6988,10 @@ DEFUN (clear_bgp_all_soft_in,
ALIAS (clear_bgp_all_soft_in, ALIAS (clear_bgp_all_soft_in,
clear_bgp_instance_all_soft_in_cmd, clear_bgp_instance_all_soft_in_cmd,
"clear bgp view WORD * soft in", "clear bgp (view|vrf) WORD * soft in",
CLEAR_STR CLEAR_STR
BGP_STR BGP_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"view name\n" "view name\n"
"Clear all peers\n" "Clear all peers\n"
BGP_SOFT_STR BGP_SOFT_STR
@ -7754,8 +7759,8 @@ DEFUN (clear_ip_bgp_all_soft,
"Clear all peers\n" "Clear all peers\n"
BGP_SOFT_STR) BGP_SOFT_STR)
{ {
if (argc == 1) if (argc == 2)
return bgp_clear_vty (vty, argv[0], AFI_IP, SAFI_UNICAST, clear_all, return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_UNICAST, clear_all,
BGP_CLEAR_SOFT_BOTH, NULL); BGP_CLEAR_SOFT_BOTH, NULL);
return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all, return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all,
@ -7764,11 +7769,11 @@ DEFUN (clear_ip_bgp_all_soft,
ALIAS (clear_ip_bgp_all_soft, ALIAS (clear_ip_bgp_all_soft,
clear_ip_bgp_instance_all_soft_cmd, clear_ip_bgp_instance_all_soft_cmd,
"clear ip bgp view WORD * soft", "clear ip bgp (view|vrf) WORD * soft",
CLEAR_STR CLEAR_STR
IP_STR IP_STR
BGP_STR BGP_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"view name\n" "view name\n"
"Clear all peers\n" "Clear all peers\n"
BGP_SOFT_STR) BGP_SOFT_STR)
@ -7796,11 +7801,11 @@ DEFUN (clear_ip_bgp_all_ipv4_soft,
DEFUN (clear_ip_bgp_instance_all_ipv4_soft, DEFUN (clear_ip_bgp_instance_all_ipv4_soft,
clear_ip_bgp_instance_all_ipv4_soft_cmd, clear_ip_bgp_instance_all_ipv4_soft_cmd,
"clear ip bgp view WORD * ipv4 (unicast|multicast) soft", "clear ip bgp (view|vrf) WORD * ipv4 (unicast|multicast) soft",
CLEAR_STR CLEAR_STR
IP_STR IP_STR
BGP_STR BGP_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"view name\n" "view name\n"
"Clear all peers\n" "Clear all peers\n"
"Address family\n" "Address family\n"
@ -7808,8 +7813,8 @@ DEFUN (clear_ip_bgp_instance_all_ipv4_soft,
"Address Family Modifier\n" "Address Family Modifier\n"
BGP_SOFT_STR) BGP_SOFT_STR)
{ {
if (strncmp (argv[1], "m", 1) == 0) if (strncmp (argv[2], "m", 1) == 0)
return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_MULTICAST, clear_all, return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_MULTICAST, clear_all,
BGP_CLEAR_SOFT_BOTH, NULL); BGP_CLEAR_SOFT_BOTH, NULL);
return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all, return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all,
@ -7839,8 +7844,8 @@ DEFUN (clear_bgp_all_soft,
"Clear all peers\n" "Clear all peers\n"
BGP_SOFT_STR) BGP_SOFT_STR)
{ {
if (argc == 1) if (argc == 2)
return bgp_clear_vty (vty, argv[0], AFI_IP6, SAFI_UNICAST, clear_all, return bgp_clear_vty (vty, argv[1], AFI_IP6, SAFI_UNICAST, clear_all,
BGP_CLEAR_SOFT_BOTH, argv[0]); BGP_CLEAR_SOFT_BOTH, argv[0]);
return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_all, return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_all,
@ -7849,10 +7854,10 @@ DEFUN (clear_bgp_all_soft,
ALIAS (clear_bgp_all_soft, ALIAS (clear_bgp_all_soft,
clear_bgp_instance_all_soft_cmd, clear_bgp_instance_all_soft_cmd,
"clear bgp view WORD * soft", "clear bgp (view|vrf) WORD * soft",
CLEAR_STR CLEAR_STR
BGP_STR BGP_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"view name\n" "view name\n"
"Clear all peers\n" "Clear all peers\n"
BGP_SOFT_STR) BGP_SOFT_STR)
@ -8348,12 +8353,21 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi,
{ {
json_object_string_add(json, "routerId", inet_ntoa (bgp->router_id)); json_object_string_add(json, "routerId", inet_ntoa (bgp->router_id));
json_object_int_add(json, "as", bgp->as); json_object_int_add(json, "as", bgp->as);
if (bgp->vrf_id)
json_object_int_add(json, "vrf-id", bgp->vrf_id);
} }
else else
{ {
vty_out (vty, vty_out (vty,
"BGP router identifier %s, local AS number %u%s", "BGP router identifier %s, local AS number %u",
inet_ntoa (bgp->router_id), bgp->as, VTY_NEWLINE); inet_ntoa (bgp->router_id), bgp->as);
if (bgp->vrf_id)
vty_out (vty, " vrf-id %u", bgp->vrf_id);
vty_out (vty, "%s", VTY_NEWLINE);
} }
if (bgp_update_delay_configured(bgp)) if (bgp_update_delay_configured(bgp))
@ -8657,17 +8671,17 @@ DEFUN (show_ip_bgp_summary,
DEFUN (show_ip_bgp_instance_summary, DEFUN (show_ip_bgp_instance_summary,
show_ip_bgp_instance_summary_cmd, show_ip_bgp_instance_summary_cmd,
"show ip bgp view WORD summary {json}", "show ip bgp (view|vrf) WORD summary {json}",
SHOW_STR SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"View name\n" "View/VRF name\n"
"Summary of BGP neighbor status\n" "Summary of BGP neighbor status\n"
"JavaScript Object Notation\n") "JavaScript Object Notation\n")
{ {
u_char uj = use_json(argc, argv); u_char uj = use_json(argc, argv);
return bgp_show_summary_vty (vty, argv[0], AFI_IP, SAFI_UNICAST, uj); return bgp_show_summary_vty (vty, argv[1], AFI_IP, SAFI_UNICAST, uj);
} }
DEFUN (show_ip_bgp_ipv4_summary, DEFUN (show_ip_bgp_ipv4_summary,
@ -8787,15 +8801,15 @@ DEFUN (show_bgp_summary,
DEFUN (show_bgp_instance_summary, DEFUN (show_bgp_instance_summary,
show_bgp_instance_summary_cmd, show_bgp_instance_summary_cmd,
"show bgp view WORD summary {json}", "show bgp (view|vrf) WORD summary {json}",
SHOW_STR SHOW_STR
BGP_STR BGP_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"View name\n" "View/VRF name\n"
"Summary of BGP neighbor status\n" "Summary of BGP neighbor status\n"
"JavaScript Object Notation\n") "JavaScript Object Notation\n")
{ {
return bgp_show_summary_vty (vty, argv[0], AFI_IP6, SAFI_UNICAST, use_json(argc, argv)); return bgp_show_summary_vty (vty, argv[1], AFI_IP6, SAFI_UNICAST, use_json(argc, argv));
} }
ALIAS (show_bgp_summary, ALIAS (show_bgp_summary,
@ -8808,11 +8822,11 @@ ALIAS (show_bgp_summary,
ALIAS (show_bgp_instance_summary, ALIAS (show_bgp_instance_summary,
show_bgp_instance_ipv6_summary_cmd, show_bgp_instance_ipv6_summary_cmd,
"show bgp view WORD ipv6 summary {json}", "show bgp (view|vrf) WORD ipv6 summary {json}",
SHOW_STR SHOW_STR
BGP_STR BGP_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"View name\n" "View/VRF name\n"
"Address family\n" "Address family\n"
"Summary of BGP neighbor status\n") "Summary of BGP neighbor status\n")
@ -8836,11 +8850,11 @@ DEFUN (show_bgp_ipv6_safi_summary,
DEFUN (show_bgp_instance_ipv6_safi_summary, DEFUN (show_bgp_instance_ipv6_safi_summary,
show_bgp_instance_ipv6_safi_summary_cmd, show_bgp_instance_ipv6_safi_summary_cmd,
"show bgp view WORD ipv6 (unicast|multicast) summary {json}", "show bgp (view|vrf) WORD ipv6 (unicast|multicast) summary {json}",
SHOW_STR SHOW_STR
BGP_STR BGP_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"View name\n" "View/VRF name\n"
"Address family\n" "Address family\n"
"Address Family modifier\n" "Address Family modifier\n"
"Address Family modifier\n" "Address Family modifier\n"
@ -8848,10 +8862,10 @@ DEFUN (show_bgp_instance_ipv6_safi_summary,
"JavaScript Object Notation\n") "JavaScript Object Notation\n")
{ {
u_char uj = use_json(argc, argv); u_char uj = use_json(argc, argv);
if (strncmp (argv[1], "m", 1) == 0) if (strncmp (argv[2], "m", 1) == 0)
return bgp_show_summary_vty (vty, argv[0], AFI_IP6, SAFI_MULTICAST, uj); return bgp_show_summary_vty (vty, argv[1], AFI_IP6, SAFI_MULTICAST, uj);
return bgp_show_summary_vty (vty, argv[0], AFI_IP6, SAFI_UNICAST, uj); return bgp_show_summary_vty (vty, argv[1], AFI_IP6, SAFI_UNICAST, uj);
} }
/* old command */ /* old command */
@ -10770,49 +10784,49 @@ ALIAS (show_ip_bgp_neighbors_peer,
DEFUN (show_ip_bgp_instance_neighbors, DEFUN (show_ip_bgp_instance_neighbors,
show_ip_bgp_instance_neighbors_cmd, show_ip_bgp_instance_neighbors_cmd,
"show ip bgp view WORD neighbors {json}", "show ip bgp (view|vrf) WORD neighbors {json}",
SHOW_STR SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"View name\n" "View/VRF name\n"
"Detailed information on TCP and BGP neighbor connections\n" "Detailed information on TCP and BGP neighbor connections\n"
"JavaScript Object Notation\n") "JavaScript Object Notation\n")
{ {
u_char uj = use_json(argc, argv); u_char uj = use_json(argc, argv);
return bgp_show_neighbor_vty (vty, argv[0], show_all, NULL, uj); return bgp_show_neighbor_vty (vty, argv[1], show_all, NULL, uj);
} }
ALIAS (show_ip_bgp_instance_neighbors, ALIAS (show_ip_bgp_instance_neighbors,
show_bgp_instance_neighbors_cmd, show_bgp_instance_neighbors_cmd,
"show bgp view WORD neighbors {json}", "show bgp (view|vrf) WORD neighbors {json}",
SHOW_STR SHOW_STR
BGP_STR BGP_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"View name\n" "View/VRF name\n"
"Detailed information on TCP and BGP neighbor connections\n" "Detailed information on TCP and BGP neighbor connections\n"
"JavaScript Object Notation\n") "JavaScript Object Notation\n")
ALIAS (show_ip_bgp_instance_neighbors, ALIAS (show_ip_bgp_instance_neighbors,
show_bgp_instance_ipv6_neighbors_cmd, show_bgp_instance_ipv6_neighbors_cmd,
"show bgp view WORD ipv6 neighbors {json}", "show bgp (view|vrf) WORD ipv6 neighbors {json}",
SHOW_STR SHOW_STR
BGP_STR BGP_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"View name\n" "View/VRF name\n"
"Address family\n" "Address family\n"
"Detailed information on TCP and BGP neighbor connections\n" "Detailed information on TCP and BGP neighbor connections\n"
"JavaScript Object Notation\n") "JavaScript Object Notation\n")
DEFUN (show_ip_bgp_instance_neighbors_peer, DEFUN (show_ip_bgp_instance_neighbors_peer,
show_ip_bgp_instance_neighbors_peer_cmd, show_ip_bgp_instance_neighbors_peer_cmd,
"show ip bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) {json}", "show ip bgp (view|vrf) WORD neighbors (A.B.C.D|X:X::X:X|WORD) {json}",
SHOW_STR SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"View name\n" "View/VRF name\n"
"Detailed information on TCP and BGP neighbor connections\n" "Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n" "Neighbor to display information about\n"
"Neighbor to display information about\n" "Neighbor to display information about\n"
@ -10821,16 +10835,16 @@ DEFUN (show_ip_bgp_instance_neighbors_peer,
{ {
u_char uj = use_json(argc, argv); u_char uj = use_json(argc, argv);
return bgp_show_neighbor_vty (vty, argv[0], show_peer, argv[1], uj); return bgp_show_neighbor_vty (vty, argv[1], show_peer, argv[2], uj);
} }
ALIAS (show_ip_bgp_instance_neighbors_peer, ALIAS (show_ip_bgp_instance_neighbors_peer,
show_bgp_instance_neighbors_peer_cmd, show_bgp_instance_neighbors_peer_cmd,
"show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) {json}", "show bgp (view|vrf) WORD neighbors (A.B.C.D|X:X::X:X|WORD) {json}",
SHOW_STR SHOW_STR
BGP_STR BGP_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"View name\n" "View/VRF name\n"
"Detailed information on TCP and BGP neighbor connections\n" "Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n" "Neighbor to display information about\n"
"Neighbor to display information about\n" "Neighbor to display information about\n"
@ -10839,11 +10853,11 @@ ALIAS (show_ip_bgp_instance_neighbors_peer,
ALIAS (show_ip_bgp_instance_neighbors_peer, ALIAS (show_ip_bgp_instance_neighbors_peer,
show_bgp_instance_ipv6_neighbors_peer_cmd, show_bgp_instance_ipv6_neighbors_peer_cmd,
"show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) {json}", "show bgp (view|vrf) WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) {json}",
SHOW_STR SHOW_STR
BGP_STR BGP_STR
"BGP view\n" "BGP view\nBGP VRF\n"
"View name\n" "View/VRF name\n"
"Address family\n" "Address family\n"
"Detailed information on TCP and BGP neighbor connections\n" "Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n" "Neighbor to display information about\n"
@ -11362,7 +11376,7 @@ DEFUN (show_ip_bgp_peer_groups,
DEFUN (show_ip_bgp_instance_peer_groups, DEFUN (show_ip_bgp_instance_peer_groups,
show_ip_bgp_instance_peer_groups_cmd, show_ip_bgp_instance_peer_groups_cmd,
"show ip bgp view WORD peer-group", "show ip bgp (view|vrf) WORD peer-group",
SHOW_STR SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -11386,7 +11400,7 @@ DEFUN (show_ip_bgp_peer_group,
DEFUN (show_ip_bgp_instance_peer_group, DEFUN (show_ip_bgp_instance_peer_group,
show_ip_bgp_instance_peer_group_cmd, show_ip_bgp_instance_peer_group_cmd,
"show ip bgp view WORD peer-group WORD", "show ip bgp (view|vrf) WORD peer-group WORD",
SHOW_STR SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -11414,7 +11428,7 @@ DEFUN (bgp_redistribute_ipv4,
return CMD_WARNING; return CMD_WARNING;
} }
bgp_redist_add(vty->index, AFI_IP, type, 0); bgp_redist_add(vty->index, AFI_IP, type, 0);
return bgp_redistribute_set (AFI_IP, type, 0); return bgp_redistribute_set (vty->index, AFI_IP, type, 0);
} }
DEFUN (bgp_redistribute_ipv4_rmap, DEFUN (bgp_redistribute_ipv4_rmap,
@ -11437,7 +11451,7 @@ DEFUN (bgp_redistribute_ipv4_rmap,
red = bgp_redist_add(vty->index, AFI_IP, type, 0); red = bgp_redist_add(vty->index, AFI_IP, type, 0);
bgp_redistribute_rmap_set (red, argv[1]); bgp_redistribute_rmap_set (red, argv[1]);
return bgp_redistribute_set (AFI_IP, type, 0); return bgp_redistribute_set (vty->index, AFI_IP, type, 0);
} }
DEFUN (bgp_redistribute_ipv4_metric, DEFUN (bgp_redistribute_ipv4_metric,
@ -11462,7 +11476,7 @@ DEFUN (bgp_redistribute_ipv4_metric,
red = bgp_redist_add(vty->index, AFI_IP, type, 0); red = bgp_redist_add(vty->index, AFI_IP, type, 0);
bgp_redistribute_metric_set(vty->index, red, AFI_IP, type, metric); bgp_redistribute_metric_set(vty->index, red, AFI_IP, type, metric);
return bgp_redistribute_set (AFI_IP, type, 0); return bgp_redistribute_set (vty->index, AFI_IP, type, 0);
} }
DEFUN (bgp_redistribute_ipv4_rmap_metric, DEFUN (bgp_redistribute_ipv4_rmap_metric,
@ -11490,7 +11504,7 @@ DEFUN (bgp_redistribute_ipv4_rmap_metric,
red = bgp_redist_add(vty->index, AFI_IP, type, 0); red = bgp_redist_add(vty->index, AFI_IP, type, 0);
bgp_redistribute_rmap_set (red, argv[1]); bgp_redistribute_rmap_set (red, argv[1]);
bgp_redistribute_metric_set(vty->index, red, AFI_IP, type, metric); bgp_redistribute_metric_set(vty->index, red, AFI_IP, type, metric);
return bgp_redistribute_set (AFI_IP, type, 0); return bgp_redistribute_set (vty->index, AFI_IP, type, 0);
} }
DEFUN (bgp_redistribute_ipv4_metric_rmap, DEFUN (bgp_redistribute_ipv4_metric_rmap,
@ -11518,7 +11532,7 @@ DEFUN (bgp_redistribute_ipv4_metric_rmap,
red = bgp_redist_add(vty->index, AFI_IP, type, 0); red = bgp_redist_add(vty->index, AFI_IP, type, 0);
bgp_redistribute_metric_set(vty->index, red, AFI_IP, type, metric); bgp_redistribute_metric_set(vty->index, red, AFI_IP, type, metric);
bgp_redistribute_rmap_set (red, argv[2]); bgp_redistribute_rmap_set (red, argv[2]);
return bgp_redistribute_set (AFI_IP, type, 0); return bgp_redistribute_set (vty->index, AFI_IP, type, 0);
} }
DEFUN (bgp_redistribute_ipv4_ospf, DEFUN (bgp_redistribute_ipv4_ospf,
@ -11540,7 +11554,7 @@ DEFUN (bgp_redistribute_ipv4_ospf,
protocol = ZEBRA_ROUTE_TABLE; protocol = ZEBRA_ROUTE_TABLE;
bgp_redist_add(vty->index, AFI_IP, protocol, instance); bgp_redist_add(vty->index, AFI_IP, protocol, instance);
return bgp_redistribute_set (AFI_IP, protocol, instance); return bgp_redistribute_set (vty->index, AFI_IP, protocol, instance);
} }
DEFUN (bgp_redistribute_ipv4_ospf_rmap, DEFUN (bgp_redistribute_ipv4_ospf_rmap,
@ -11565,7 +11579,7 @@ DEFUN (bgp_redistribute_ipv4_ospf_rmap,
VTY_GET_INTEGER ("Instance ID", instance, argv[1]); VTY_GET_INTEGER ("Instance ID", instance, argv[1]);
red = bgp_redist_add(vty->index, AFI_IP, protocol, instance); red = bgp_redist_add(vty->index, AFI_IP, protocol, instance);
bgp_redistribute_rmap_set (red, argv[2]); bgp_redistribute_rmap_set (red, argv[2]);
return bgp_redistribute_set (AFI_IP, protocol, instance); return bgp_redistribute_set (vty->index, AFI_IP, protocol, instance);
} }
DEFUN (bgp_redistribute_ipv4_ospf_metric, DEFUN (bgp_redistribute_ipv4_ospf_metric,
@ -11593,7 +11607,7 @@ DEFUN (bgp_redistribute_ipv4_ospf_metric,
red = bgp_redist_add(vty->index, AFI_IP, protocol, instance); red = bgp_redist_add(vty->index, AFI_IP, protocol, instance);
bgp_redistribute_metric_set(vty->index, red, AFI_IP, protocol, metric); bgp_redistribute_metric_set(vty->index, red, AFI_IP, protocol, metric);
return bgp_redistribute_set (AFI_IP, protocol, instance); return bgp_redistribute_set (vty->index, AFI_IP, protocol, instance);
} }
DEFUN (bgp_redistribute_ipv4_ospf_rmap_metric, DEFUN (bgp_redistribute_ipv4_ospf_rmap_metric,
@ -11624,7 +11638,7 @@ DEFUN (bgp_redistribute_ipv4_ospf_rmap_metric,
red = bgp_redist_add(vty->index, AFI_IP, protocol, instance); red = bgp_redist_add(vty->index, AFI_IP, protocol, instance);
bgp_redistribute_rmap_set (red, argv[2]); bgp_redistribute_rmap_set (red, argv[2]);
bgp_redistribute_metric_set(vty->index, red, AFI_IP, protocol, metric); bgp_redistribute_metric_set(vty->index, red, AFI_IP, protocol, metric);
return bgp_redistribute_set (AFI_IP, protocol, instance); return bgp_redistribute_set (vty->index, AFI_IP, protocol, instance);
} }
DEFUN (bgp_redistribute_ipv4_ospf_metric_rmap, DEFUN (bgp_redistribute_ipv4_ospf_metric_rmap,
@ -11655,7 +11669,7 @@ DEFUN (bgp_redistribute_ipv4_ospf_metric_rmap,
red = bgp_redist_add(vty->index, AFI_IP, protocol, instance); red = bgp_redist_add(vty->index, AFI_IP, protocol, instance);
bgp_redistribute_metric_set(vty->index, red, AFI_IP, protocol, metric); bgp_redistribute_metric_set(vty->index, red, AFI_IP, protocol, metric);
bgp_redistribute_rmap_set (red, argv[3]); bgp_redistribute_rmap_set (red, argv[3]);
return bgp_redistribute_set (AFI_IP, protocol, instance); return bgp_redistribute_set (vty->index, AFI_IP, protocol, instance);
} }
DEFUN (no_bgp_redistribute_ipv4_ospf, DEFUN (no_bgp_redistribute_ipv4_ospf,
@ -11802,7 +11816,7 @@ DEFUN (bgp_redistribute_ipv6,
} }
bgp_redist_add(vty->index, AFI_IP6, type, 0); bgp_redist_add(vty->index, AFI_IP6, type, 0);
return bgp_redistribute_set (AFI_IP6, type, 0); return bgp_redistribute_set (vty->index, AFI_IP6, type, 0);
} }
DEFUN (bgp_redistribute_ipv6_rmap, DEFUN (bgp_redistribute_ipv6_rmap,
@ -11825,7 +11839,7 @@ DEFUN (bgp_redistribute_ipv6_rmap,
red = bgp_redist_add(vty->index, AFI_IP6, type, 0); red = bgp_redist_add(vty->index, AFI_IP6, type, 0);
bgp_redistribute_rmap_set (red, argv[1]); bgp_redistribute_rmap_set (red, argv[1]);
return bgp_redistribute_set (AFI_IP6, type, 0); return bgp_redistribute_set (vty->index, AFI_IP6, type, 0);
} }
DEFUN (bgp_redistribute_ipv6_metric, DEFUN (bgp_redistribute_ipv6_metric,
@ -11850,7 +11864,7 @@ DEFUN (bgp_redistribute_ipv6_metric,
red = bgp_redist_add(vty->index, AFI_IP6, type, 0); red = bgp_redist_add(vty->index, AFI_IP6, type, 0);
bgp_redistribute_metric_set(vty->index, red, AFI_IP6, type, metric); bgp_redistribute_metric_set(vty->index, red, AFI_IP6, type, metric);
return bgp_redistribute_set (AFI_IP6, type, 0); return bgp_redistribute_set (vty->index, AFI_IP6, type, 0);
} }
DEFUN (bgp_redistribute_ipv6_rmap_metric, DEFUN (bgp_redistribute_ipv6_rmap_metric,
@ -11878,7 +11892,7 @@ DEFUN (bgp_redistribute_ipv6_rmap_metric,
red = bgp_redist_add(vty->index, AFI_IP6, type, 0); red = bgp_redist_add(vty->index, AFI_IP6, type, 0);
bgp_redistribute_rmap_set (red, argv[1]); bgp_redistribute_rmap_set (red, argv[1]);
bgp_redistribute_metric_set(vty->index, red, AFI_IP6, type, metric); bgp_redistribute_metric_set(vty->index, red, AFI_IP6, type, metric);
return bgp_redistribute_set (AFI_IP6, type, 0); return bgp_redistribute_set (vty->index, AFI_IP6, type, 0);
} }
DEFUN (bgp_redistribute_ipv6_metric_rmap, DEFUN (bgp_redistribute_ipv6_metric_rmap,
@ -11906,7 +11920,7 @@ DEFUN (bgp_redistribute_ipv6_metric_rmap,
red = bgp_redist_add(vty->index, AFI_IP6, type, 0); red = bgp_redist_add(vty->index, AFI_IP6, type, 0);
bgp_redistribute_metric_set(vty->index, red, AFI_IP6, SAFI_UNICAST, metric); bgp_redistribute_metric_set(vty->index, red, AFI_IP6, SAFI_UNICAST, metric);
bgp_redistribute_rmap_set (red, argv[2]); bgp_redistribute_rmap_set (red, argv[2]);
return bgp_redistribute_set (AFI_IP6, type, 0); return bgp_redistribute_set (vty->index, AFI_IP6, type, 0);
} }
DEFUN (no_bgp_redistribute_ipv6, DEFUN (no_bgp_redistribute_ipv6,
@ -12090,12 +12104,12 @@ bgp_vty_init (void)
/* "router bgp" commands. */ /* "router bgp" commands. */
install_element (CONFIG_NODE, &router_bgp_cmd); install_element (CONFIG_NODE, &router_bgp_cmd);
install_element (CONFIG_NODE, &router_bgp_view_cmd); install_element (CONFIG_NODE, &router_bgp_instance_cmd);
install_element (CONFIG_NODE, &router_bgp_noasn_cmd); install_element (CONFIG_NODE, &router_bgp_noasn_cmd);
/* "no router bgp" commands. */ /* "no router bgp" commands. */
install_element (CONFIG_NODE, &no_router_bgp_cmd); install_element (CONFIG_NODE, &no_router_bgp_cmd);
install_element (CONFIG_NODE, &no_router_bgp_view_cmd); install_element (CONFIG_NODE, &no_router_bgp_instance_cmd);
/* "bgp router-id" commands. */ /* "bgp router-id" commands. */
install_element (BGP_NODE, &bgp_router_id_cmd); install_element (BGP_NODE, &bgp_router_id_cmd);

View File

@ -47,7 +47,6 @@ Boston, MA 02111-1307, USA. */
/* All information about zebra. */ /* All information about zebra. */
struct zclient *zclient = NULL; struct zclient *zclient = NULL;
struct in_addr router_id_zebra;
/* Growable buffer for nexthops sent to zebra */ /* Growable buffer for nexthops sent to zebra */
struct stream *bgp_nexthop_buf = NULL; struct stream *bgp_nexthop_buf = NULL;
@ -105,15 +104,33 @@ bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length,
{ {
char buf[PREFIX2STR_BUFFER]; char buf[PREFIX2STR_BUFFER];
prefix2str(&router_id, buf, sizeof(buf)); prefix2str(&router_id, buf, sizeof(buf));
zlog_debug("Zebra rcvd: router id update %s", buf); zlog_debug("Zebra rcvd: router id update %s vrf %u", buf, vrf_id);
} }
router_id_zebra = router_id.u.prefix4; if (!vrf_id)
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
{ {
if (!bgp->router_id_static.s_addr) /* This is to cover all the views */
bgp_router_id_set (bgp, &router_id.u.prefix4); for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
{
if (bgp_flag_check(bgp, BGP_FLAG_INSTANCE_TYPE_VRF))
continue;
bgp->router_id_zebra = router_id.u.prefix4;
if (!bgp->router_id_static.s_addr)
bgp_router_id_set (bgp, &router_id.u.prefix4);
}
}
else
{
bgp = bgp_lookup_by_vrf_id (vrf_id);
if (bgp)
{
bgp->router_id_zebra = router_id.u.prefix4;
if (!bgp->router_id_static.s_addr)
bgp_router_id_set (bgp, &router_id.u.prefix4);
}
} }
return 0; return 0;
@ -137,30 +154,26 @@ bgp_read_import_check_update(int command, struct zclient *zclient,
} }
static void static void
bgp_start_interface_nbrs (struct interface *ifp) bgp_start_interface_nbrs (struct bgp *bgp, struct interface *ifp)
{ {
struct listnode *node, *nnode, *mnode; struct listnode *node, *nnode;
struct bgp *bgp;
struct peer *peer; struct peer *peer;
for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp)) for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
{ {
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer)) if (peer->conf_if &&
(strcmp (peer->conf_if, ifp->name) == 0) &&
peer->status != Established)
{ {
if (peer->conf_if && if (peer_active(peer))
(strcmp (peer->conf_if, ifp->name) == 0) && BGP_EVENT_ADD (peer, BGP_Stop);
peer->status != Established) BGP_EVENT_ADD (peer, BGP_Start);
{
if (peer_active(peer))
BGP_EVENT_ADD (peer, BGP_Stop);
BGP_EVENT_ADD (peer, BGP_Start);
}
} }
} }
} }
static void static void
bgp_nbr_connected_add (struct nbr_connected *ifc) bgp_nbr_connected_add (struct bgp *bgp, struct nbr_connected *ifc)
{ {
struct listnode *node; struct listnode *node;
struct connected *connected; struct connected *connected;
@ -181,25 +194,21 @@ bgp_nbr_connected_add (struct nbr_connected *ifc)
if (!connected) if (!connected)
return; return;
bgp_start_interface_nbrs (ifp); bgp_start_interface_nbrs (bgp, ifp);
} }
static void static void
bgp_nbr_connected_delete (struct nbr_connected *ifc, int del) bgp_nbr_connected_delete (struct bgp *bgp, struct nbr_connected *ifc, int del)
{ {
struct listnode *node, *nnode, *mnode; struct listnode *node, *nnode;
struct bgp *bgp;
struct peer *peer; struct peer *peer;
struct interface *ifp; struct interface *ifp;
for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp)) for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
{ {
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer)) if (peer->conf_if && (strcmp (peer->conf_if, ifc->ifp->name) == 0))
{ {
if (peer->conf_if && (strcmp (peer->conf_if, ifc->ifp->name) == 0)) BGP_EVENT_ADD (peer, BGP_Stop);
{
BGP_EVENT_ADD (peer, BGP_Stop);
}
} }
} }
/* Free neighbor also, if we're asked to. */ /* Free neighbor also, if we're asked to. */
@ -211,6 +220,79 @@ bgp_nbr_connected_delete (struct nbr_connected *ifc, int del)
} }
} }
/* Inteface addition message from zebra. */
static int
bgp_vrf_add (int command, struct zclient *zclient, zebra_size_t length,
vrf_id_t vrf_id)
{
struct vrf *vrf;
struct bgp *bgp;
vrf = zebra_vrf_add_read (zclient->ibuf, vrf_id);
if (BGP_DEBUG (zebra, ZEBRA) && vrf)
zlog_debug("Zebra rcvd: vrf add %s", vrf->name);
bgp = bgp_lookup_by_name(vrf->name);
if (bgp)
{
bgp->vrf_id = vrf_id;
if (BGP_DEBUG (zebra, ZEBRA) && vrf)
zlog_debug("zclient_send_requests %u", vrf_id);
zclient_send_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_requests (zclient, bgp->vrf_id);
bgp_nht_register_all (bgp->vrf_id);
}
/* Inteface deletion message from zebra. */
static int
bgp_vrf_delete (int command, struct zclient *zclient, zebra_size_t length,
vrf_id_t vrf_id)
{
struct vrf *vrf;
struct bgp *bgp;
vrf = zebra_vrf_state_read (zclient->ibuf, vrf_id);
if (BGP_DEBUG (zebra, ZEBRA) && vrf)
zlog_debug("Zebra rcvd: vrf delete %s", vrf->name);
bgp = bgp_lookup_by_name(vrf->name);
if (bgp)
{
bgp_instance_down (bgp);
bgp->vrf_id = 0;
}
return 0;
}
/* Inteface addition message from zebra. */ /* Inteface addition message from zebra. */
static int static int
bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length, bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length,
@ -252,6 +334,11 @@ bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length,
struct connected *c; struct connected *c;
struct nbr_connected *nc; struct nbr_connected *nc;
struct listnode *node, *nnode; struct listnode *node, *nnode;
struct bgp *bgp;
bgp = bgp_lookup_by_vrf_id (vrf_id);
if (!bgp)
return 0;
s = zclient->ibuf; s = zclient->ibuf;
ifp = zebra_interface_state_read (s, vrf_id); ifp = zebra_interface_state_read (s, vrf_id);
@ -263,10 +350,10 @@ bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length,
zlog_debug("Zebra rcvd: interface %s up", ifp->name); zlog_debug("Zebra rcvd: interface %s up", ifp->name);
for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c)) for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
bgp_connected_add (c); bgp_connected_add (bgp, c);
for (ALL_LIST_ELEMENTS (ifp->nbr_connected, node, nnode, nc)) for (ALL_LIST_ELEMENTS (ifp->nbr_connected, node, nnode, nc))
bgp_nbr_connected_add (nc); bgp_nbr_connected_add (bgp, nc);
return 0; return 0;
} }
@ -280,6 +367,11 @@ bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length,
struct connected *c; struct connected *c;
struct nbr_connected *nc; struct nbr_connected *nc;
struct listnode *node, *nnode; struct listnode *node, *nnode;
struct bgp *bgp;
bgp = bgp_lookup_by_vrf_id (vrf_id);
if (!bgp)
return 0;
s = zclient->ibuf; s = zclient->ibuf;
ifp = zebra_interface_state_read (s, vrf_id); ifp = zebra_interface_state_read (s, vrf_id);
@ -290,10 +382,10 @@ bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length,
zlog_debug("Zebra rcvd: interface %s down", ifp->name); zlog_debug("Zebra rcvd: interface %s down", ifp->name);
for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c)) for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
bgp_connected_delete (c); bgp_connected_delete (bgp, c);
for (ALL_LIST_ELEMENTS (ifp->nbr_connected, node, nnode, nc)) for (ALL_LIST_ELEMENTS (ifp->nbr_connected, node, nnode, nc))
bgp_nbr_connected_delete (nc, 1); bgp_nbr_connected_delete (bgp, nc, 1);
/* Fast external-failover */ /* Fast external-failover */
{ {
@ -341,14 +433,23 @@ bgp_interface_address_add (int command, struct zclient *zclient,
if (if_is_operative (ifc->ifp)) if (if_is_operative (ifc->ifp))
{ {
bgp_connected_add (ifc); struct bgp *bgp;
bgp = bgp_lookup_by_vrf_id (vrf_id);
if (!bgp)
{
zlog_err("instance not found\n");
return 0;
}
bgp_connected_add (bgp, ifc);
/* If we have learnt of any neighbors on this interface, /* If we have learnt of any neighbors on this interface,
* check to kick off any BGP interface-based neighbors, * check to kick off any BGP interface-based neighbors,
* but only if this is a link-local address. * but only if this is a link-local address.
*/ */
if (IN6_IS_ADDR_LINKLOCAL(&ifc->address->u.prefix6) && if (IN6_IS_ADDR_LINKLOCAL(&ifc->address->u.prefix6) &&
!list_isempty(ifc->ifp->nbr_connected)) !list_isempty(ifc->ifp->nbr_connected))
bgp_start_interface_nbrs (ifc->ifp); bgp_start_interface_nbrs (bgp, ifc->ifp);
} }
return 0; return 0;
@ -359,6 +460,11 @@ bgp_interface_address_delete (int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id) zebra_size_t length, vrf_id_t vrf_id)
{ {
struct connected *ifc; 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); ifc = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
@ -374,7 +480,7 @@ bgp_interface_address_delete (int command, struct zclient *zclient,
} }
if (if_is_operative (ifc->ifp)) if (if_is_operative (ifc->ifp))
bgp_connected_delete (ifc); bgp_connected_delete (bgp, ifc);
connected_free (ifc); connected_free (ifc);
@ -386,6 +492,11 @@ bgp_interface_nbr_address_add (int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id) zebra_size_t length, vrf_id_t vrf_id)
{ {
struct nbr_connected *ifc = NULL; 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); ifc = zebra_interface_nbr_address_read (command, zclient->ibuf, vrf_id);
@ -401,7 +512,7 @@ bgp_interface_nbr_address_add (int command, struct zclient *zclient,
} }
if (if_is_operative (ifc->ifp)) if (if_is_operative (ifc->ifp))
bgp_nbr_connected_add (ifc); bgp_nbr_connected_add (bgp, ifc);
return 0; return 0;
} }
@ -411,6 +522,11 @@ bgp_interface_nbr_address_delete (int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id) zebra_size_t length, vrf_id_t vrf_id)
{ {
struct nbr_connected *ifc = NULL; 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); ifc = zebra_interface_nbr_address_read (command, zclient->ibuf, vrf_id);
@ -426,7 +542,7 @@ bgp_interface_nbr_address_delete (int command, struct zclient *zclient,
} }
if (if_is_operative (ifc->ifp)) if (if_is_operative (ifc->ifp))
bgp_nbr_connected_delete (ifc, 0); bgp_nbr_connected_delete (bgp, ifc, 0);
nbr_connected_free (ifc); nbr_connected_free (ifc);
@ -444,6 +560,11 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length,
struct prefix_ipv4 p; struct prefix_ipv4 p;
unsigned int ifindex; unsigned int ifindex;
int i; int i;
struct bgp *bgp;
bgp = bgp_lookup_by_vrf_id (vrf_id);
if (!bgp)
return 0;
s = zclient->ibuf; s = zclient->ibuf;
nexthop.s_addr = 0; nexthop.s_addr = 0;
@ -513,11 +634,11 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length,
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
{ {
if (i != api.type) if (i != api.type)
bgp_redistribute_delete((struct prefix *)&p, i, api.instance); bgp_redistribute_delete(bgp, (struct prefix *)&p, i, api.instance);
} }
/* Now perform the add/update. */ /* Now perform the add/update. */
bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL, ifindex, bgp_redistribute_add(bgp, (struct prefix *)&p, &nexthop, NULL, ifindex,
api.metric, api.type, api.instance, api.tag); api.metric, api.type, api.instance, api.tag);
} }
else if (command == ZEBRA_REDISTRIBUTE_IPV4_DEL) else if (command == ZEBRA_REDISTRIBUTE_IPV4_DEL)
@ -534,7 +655,7 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length,
api.metric, api.metric,
api.tag); api.tag);
} }
bgp_redistribute_delete((struct prefix *)&p, api.type, api.instance); bgp_redistribute_delete(bgp, (struct prefix *)&p, api.type, api.instance);
} }
return 0; return 0;
@ -552,6 +673,11 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
struct prefix_ipv6 p; struct prefix_ipv6 p;
unsigned int ifindex; unsigned int ifindex;
int i; int i;
struct bgp *bgp;
bgp = bgp_lookup_by_vrf_id (vrf_id);
if (!bgp)
return 0;
s = zclient->ibuf; s = zclient->ibuf;
memset (&nexthop, 0, sizeof (struct in6_addr)); memset (&nexthop, 0, sizeof (struct in6_addr));
@ -627,10 +753,10 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
{ {
if (i != api.type) if (i != api.type)
bgp_redistribute_delete((struct prefix *)&p, i, api.instance); bgp_redistribute_delete(bgp, (struct prefix *)&p, i, api.instance);
} }
bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop, ifindex, bgp_redistribute_add (bgp, (struct prefix *)&p, NULL, &nexthop, ifindex,
api.metric, api.type, api.instance, api.tag); api.metric, api.type, api.instance, api.tag);
} }
else if (command == ZEBRA_REDISTRIBUTE_IPV6_DEL) else if (command == ZEBRA_REDISTRIBUTE_IPV6_DEL)
@ -647,7 +773,7 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
api.metric, api.metric,
api.tag); api.tag);
} }
bgp_redistribute_delete ((struct prefix *) &p, api.type, api.instance); bgp_redistribute_delete (bgp, (struct prefix *) &p, api.type, api.instance);
} }
return 0; return 0;
@ -655,7 +781,7 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
#endif /* HAVE_IPV6 */ #endif /* HAVE_IPV6 */
struct interface * struct interface *
if_lookup_by_ipv4 (struct in_addr *addr) if_lookup_by_ipv4 (struct in_addr *addr, vrf_id_t vrf_id)
{ {
struct listnode *ifnode; struct listnode *ifnode;
struct listnode *cnode; struct listnode *cnode;
@ -668,7 +794,7 @@ if_lookup_by_ipv4 (struct in_addr *addr)
p.prefix = *addr; p.prefix = *addr;
p.prefixlen = IPV4_MAX_BITLEN; p.prefixlen = IPV4_MAX_BITLEN;
for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp)) for (ALL_LIST_ELEMENTS_RO (vrf_iflist(vrf_id), ifnode, ifp))
{ {
for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected)) for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
{ {
@ -683,7 +809,7 @@ if_lookup_by_ipv4 (struct in_addr *addr)
} }
struct interface * struct interface *
if_lookup_by_ipv4_exact (struct in_addr *addr) if_lookup_by_ipv4_exact (struct in_addr *addr, vrf_id_t vrf_id)
{ {
struct listnode *ifnode; struct listnode *ifnode;
struct listnode *cnode; struct listnode *cnode;
@ -691,7 +817,7 @@ if_lookup_by_ipv4_exact (struct in_addr *addr)
struct connected *connected; struct connected *connected;
struct prefix *cp; struct prefix *cp;
for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp)) for (ALL_LIST_ELEMENTS_RO (vrf_iflist(vrf_id), ifnode, ifp))
{ {
for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected)) for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
{ {
@ -707,7 +833,7 @@ if_lookup_by_ipv4_exact (struct in_addr *addr)
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
struct interface * struct interface *
if_lookup_by_ipv6 (struct in6_addr *addr, unsigned int ifindex) if_lookup_by_ipv6 (struct in6_addr *addr, unsigned int ifindex, vrf_id_t vrf_id)
{ {
struct listnode *ifnode; struct listnode *ifnode;
struct listnode *cnode; struct listnode *cnode;
@ -720,7 +846,7 @@ if_lookup_by_ipv6 (struct in6_addr *addr, unsigned int ifindex)
p.prefix = *addr; p.prefix = *addr;
p.prefixlen = IPV6_MAX_BITLEN; p.prefixlen = IPV6_MAX_BITLEN;
for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp)) for (ALL_LIST_ELEMENTS_RO (vrf_iflist(vrf_id), ifnode, ifp))
{ {
for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected)) for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
{ {
@ -743,7 +869,7 @@ if_lookup_by_ipv6 (struct in6_addr *addr, unsigned int ifindex)
} }
struct interface * struct interface *
if_lookup_by_ipv6_exact (struct in6_addr *addr, unsigned int ifindex) if_lookup_by_ipv6_exact (struct in6_addr *addr, unsigned int ifindex, vrf_id_t vrf_id)
{ {
struct listnode *ifnode; struct listnode *ifnode;
struct listnode *cnode; struct listnode *cnode;
@ -751,7 +877,7 @@ if_lookup_by_ipv6_exact (struct in6_addr *addr, unsigned int ifindex)
struct connected *connected; struct connected *connected;
struct prefix *cp; struct prefix *cp;
for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp)) for (ALL_LIST_ELEMENTS_RO (vrf_iflist(vrf_id), ifnode, ifp))
{ {
for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected)) for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
{ {
@ -853,9 +979,9 @@ bgp_nexthop_set (union sockunion *local, union sockunion *remote,
{ {
nexthop->v4 = local->sin.sin_addr; nexthop->v4 = local->sin.sin_addr;
if (peer->update_if) if (peer->update_if)
ifp = if_lookup_by_name (peer->update_if); ifp = if_lookup_by_name_vrf (peer->update_if, peer->bgp->vrf_id);
else else
ifp = if_lookup_by_ipv4_exact (&local->sin.sin_addr); ifp = if_lookup_by_ipv4_exact (&local->sin.sin_addr, peer->bgp->vrf_id);
} }
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
if (local->sa.sa_family == AF_INET6) if (local->sa.sa_family == AF_INET6)
@ -863,13 +989,14 @@ bgp_nexthop_set (union sockunion *local, union sockunion *remote,
if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr)) if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
{ {
if (peer->conf_if || peer->ifname) if (peer->conf_if || peer->ifname)
ifp = if_lookup_by_index (if_nametoindex (peer->conf_if ? peer->conf_if : peer->ifname)); ifp = if_lookup_by_index_vrf (if_nametoindex (peer->conf_if ? peer->conf_if : peer->ifname), peer->bgp->vrf_id);
} }
else if (peer->update_if) else if (peer->update_if)
ifp = if_lookup_by_name (peer->update_if); ifp = if_lookup_by_name_vrf (peer->update_if, peer->bgp->vrf_id);
else else
ifp = if_lookup_by_ipv6_exact (&local->sin6.sin6_addr, ifp = if_lookup_by_ipv6_exact (&local->sin6.sin6_addr,
local->sin6.sin6_scope_id); local->sin6.sin6_scope_id,
peer->bgp->vrf_id);
} }
#endif /* HAVE_IPV6 */ #endif /* HAVE_IPV6 */
@ -899,7 +1026,7 @@ bgp_nexthop_set (union sockunion *local, union sockunion *remote,
else else
if_get_ipv6_local (ifp, &nexthop->v6_local); if_get_ipv6_local (ifp, &nexthop->v6_local);
if (if_lookup_by_ipv4 (&remote->sin.sin_addr)) if (if_lookup_by_ipv4 (&remote->sin.sin_addr, peer->bgp->vrf_id))
peer->shared_network = 1; peer->shared_network = 1;
else else
peer->shared_network = 0; peer->shared_network = 0;
@ -925,7 +1052,7 @@ bgp_nexthop_set (union sockunion *local, union sockunion *remote,
/* If directory connected set link-local address. */ /* If directory connected set link-local address. */
direct = if_lookup_by_ipv6 (&remote->sin6.sin6_addr, direct = if_lookup_by_ipv6 (&remote->sin6.sin6_addr,
remote->sin6.sin6_scope_id); remote->sin6.sin6_scope_id, peer->bgp->vrf_id);
if (direct) if (direct)
if_get_ipv6_local (ifp, &nexthop->v6_local); if_get_ipv6_local (ifp, &nexthop->v6_local);
} }
@ -949,7 +1076,8 @@ bgp_nexthop_set (union sockunion *local, union sockunion *remote,
} }
if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr) || if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr) ||
if_lookup_by_ipv6 (&remote->sin6.sin6_addr, remote->sin6.sin6_scope_id)) if_lookup_by_ipv6 (&remote->sin6.sin6_addr, remote->sin6.sin6_scope_id,
peer->bgp->vrf_id))
peer->shared_network = 1; peer->shared_network = 1;
else else
peer->shared_network = 0; peer->shared_network = 0;
@ -1046,9 +1174,9 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
return; return;
if ((p->family == AF_INET && if ((p->family == AF_INET &&
!vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_BGP], VRF_DEFAULT)) !vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_BGP], bgp->vrf_id))
|| (p->family == AF_INET6 && || (p->family == AF_INET6 &&
!vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_BGP], VRF_DEFAULT))) !vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_BGP], bgp->vrf_id)))
return; return;
if (bgp->main_zebra_update_hold) if (bgp->main_zebra_update_hold)
@ -1161,7 +1289,7 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
valid_nh_count++; valid_nh_count++;
} }
api.vrf_id = VRF_DEFAULT; api.vrf_id = bgp->vrf_id;
api.flags = flags; api.flags = flags;
api.type = ZEBRA_ROUTE_BGP; api.type = ZEBRA_ROUTE_BGP;
api.instance = 0; api.instance = 0;
@ -1344,7 +1472,7 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
} }
/* Make Zebra API structure. */ /* Make Zebra API structure. */
api.vrf_id = VRF_DEFAULT; api.vrf_id = bgp->vrf_id;
api.flags = flags; api.flags = flags;
api.type = ZEBRA_ROUTE_BGP; api.type = ZEBRA_ROUTE_BGP;
api.instance = 0; api.instance = 0;
@ -1447,14 +1575,14 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
if (zclient->sock < 0) if (zclient->sock < 0)
return; return;
if ((p->family == AF_INET &&
!vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_BGP], VRF_DEFAULT))
|| (p->family == AF_INET6 &&
!vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_BGP], VRF_DEFAULT)))
return;
peer = info->peer; peer = info->peer;
if ((p->family == AF_INET &&
!vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_BGP], peer->bgp->vrf_id))
|| (p->family == AF_INET6 &&
!vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_BGP], peer->bgp->vrf_id)))
return;
flags = 0; flags = 0;
if (peer->sort == BGP_PEER_IBGP) if (peer->sort == BGP_PEER_IBGP)
@ -1472,7 +1600,7 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
{ {
struct zapi_ipv4 api; struct zapi_ipv4 api;
api.vrf_id = VRF_DEFAULT; api.vrf_id = peer->bgp->vrf_id;
api.flags = flags; api.flags = flags;
api.type = ZEBRA_ROUTE_BGP; api.type = ZEBRA_ROUTE_BGP;
@ -1511,7 +1639,7 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
assert (info->attr->extra); assert (info->attr->extra);
api.vrf_id = VRF_DEFAULT; api.vrf_id = peer->bgp->vrf_id;
api.flags = flags; api.flags = flags;
api.type = ZEBRA_ROUTE_BGP; api.type = ZEBRA_ROUTE_BGP;
api.instance = 0; api.instance = 0;
@ -1603,7 +1731,7 @@ bgp_redist_del (struct bgp *bgp, afi_t afi, u_char type, u_short instance)
/* Other routes redistribution into BGP. */ /* Other routes redistribution into BGP. */
int int
bgp_redistribute_set (afi_t afi, int type, u_short instance) bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type, u_short instance)
{ {
/* Return if already redistribute flag is set. */ /* Return if already redistribute flag is set. */
@ -1616,10 +1744,10 @@ bgp_redistribute_set (afi_t afi, int type, u_short instance)
} }
else else
{ {
if (vrf_bitmap_check (zclient->redist[afi][type], VRF_DEFAULT)) if (vrf_bitmap_check (zclient->redist[afi][type], bgp->vrf_id))
return CMD_WARNING; return CMD_WARNING;
vrf_bitmap_set (zclient->redist[afi][type], VRF_DEFAULT); vrf_bitmap_set (zclient->redist[afi][type], bgp->vrf_id);
} }
/* Return if zebra connection is not established. */ /* Return if zebra connection is not established. */
@ -1632,7 +1760,7 @@ bgp_redistribute_set (afi_t afi, int type, u_short instance)
/* Send distribute add message to zebra. */ /* Send distribute add message to zebra. */
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type, zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type,
instance, VRF_DEFAULT); instance, bgp->vrf_id);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -1702,6 +1830,46 @@ bgp_redistribute_metric_set (struct bgp *bgp, struct bgp_redist *red, afi_t afi,
return 1; return 1;
} }
/* Unset redistribution. */
int
bgp_redistribute_unreg (struct bgp *bgp, afi_t afi, int type, u_short instance)
{
struct bgp_redist *red;
red = bgp_redist_lookup(bgp, afi, type, instance);
if (!red)
return CMD_SUCCESS;
/* Return if zebra connection is disabled. */
if (instance)
{
if (!redist_check_instance(&zclient->mi_redist[afi][type], instance))
return CMD_WARNING;
redist_del_instance(&zclient->mi_redist[afi][type], instance);
}
else
{
if (! vrf_bitmap_check (zclient->redist[afi][type], bgp->vrf_id))
return CMD_WARNING;
vrf_bitmap_unset (zclient->redist[afi][type], bgp->vrf_id);
}
if (zclient->sock >= 0)
{
/* 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);
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, type, instance,
bgp->vrf_id);
}
/* Withdraw redistributed routes from current BGP's routing table. */
bgp_redistribute_withdraw (bgp, afi, type, instance);
return CMD_SUCCESS;
}
/* Unset redistribution. */ /* Unset redistribution. */
int int
bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type, u_short instance) bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type, u_short instance)
@ -1712,6 +1880,8 @@ bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type, u_short instance)
if (!red) if (!red)
return CMD_SUCCESS; return CMD_SUCCESS;
bgp_redistribute_unreg(bgp, afi, type, instance);
/* Unset route-map. */ /* Unset route-map. */
if (red->rmap.name) if (red->rmap.name)
XFREE(MTYPE_ROUTE_MAP_NAME, red->rmap.name); XFREE(MTYPE_ROUTE_MAP_NAME, red->rmap.name);
@ -1724,33 +1894,6 @@ bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type, u_short instance)
bgp_redist_del(bgp, afi, type, instance); bgp_redist_del(bgp, afi, type, instance);
/* Return if zebra connection is disabled. */
if (instance)
{
if (!redist_check_instance(&zclient->mi_redist[afi][type], instance))
return CMD_WARNING;
redist_del_instance(&zclient->mi_redist[afi][type], instance);
}
else
{
if (! vrf_bitmap_check (zclient->redist[afi][type], VRF_DEFAULT))
return CMD_WARNING;
vrf_bitmap_unset (zclient->redist[afi][type], VRF_DEFAULT);
}
if (zclient->sock >= 0)
{
/* 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);
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, type, instance,
VRF_DEFAULT);
}
/* Withdraw redistributed routes from current BGP's routing table. */
bgp_redistribute_withdraw (bgp, afi, type, instance);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -1763,11 +1906,14 @@ bgp_zclient_reset (void)
static void static void
bgp_zebra_connected (struct zclient *zclient) bgp_zebra_connected (struct zclient *zclient)
{ {
zclient_send_requests (zclient, VRF_DEFAULT); struct listnode *node, *nnode;
struct bgp *bgp;
bgp_nht_register_all(); for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
bgp_vrf_update (bgp);
} }
void void
bgp_zebra_init (struct thread_master *master) bgp_zebra_init (struct thread_master *master)
{ {
@ -1776,6 +1922,8 @@ bgp_zebra_init (struct thread_master *master)
zclient_init (zclient, ZEBRA_ROUTE_BGP, 0); zclient_init (zclient, ZEBRA_ROUTE_BGP, 0);
zclient->zebra_connected = bgp_zebra_connected; zclient->zebra_connected = bgp_zebra_connected;
zclient->router_id_update = bgp_router_id_update; zclient->router_id_update = bgp_router_id_update;
zclient->vrf_add = bgp_vrf_add;
zclient->vrf_delete = bgp_vrf_delete;
zclient->interface_add = bgp_interface_add; zclient->interface_add = bgp_interface_add;
zclient->interface_delete = bgp_interface_delete; zclient->interface_delete = bgp_interface_delete;
zclient->interface_address_add = bgp_interface_address_add; zclient->interface_address_add = bgp_interface_address_add;

View File

@ -29,6 +29,7 @@ extern struct stream *bgp_ifindices_buf;
extern void bgp_zebra_init(struct thread_master *master); extern void bgp_zebra_init(struct thread_master *master);
extern int bgp_if_update_all (void); 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, extern int bgp_config_write_maxpaths (struct vty *, struct bgp *, afi_t,
safi_t, int *); safi_t, int *);
extern int bgp_config_write_redistribute (struct vty *, struct bgp *, afi_t, safi_t, extern int bgp_config_write_redistribute (struct vty *, struct bgp *, afi_t, safi_t,
@ -40,18 +41,19 @@ extern void bgp_zebra_withdraw (struct prefix *, struct bgp_info *, safi_t);
extern struct bgp_redist *bgp_redist_lookup (struct bgp *, afi_t, u_char, u_short); 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 struct bgp_redist *bgp_redist_add (struct bgp *, afi_t, u_char, u_short);
extern int bgp_redistribute_set (afi_t, int, u_short); extern int bgp_redistribute_set (struct bgp *, afi_t, int, u_short);
extern int bgp_redistribute_resend (struct bgp *, afi_t, int, u_short); extern int bgp_redistribute_resend (struct bgp *, afi_t, int, u_short);
extern int bgp_redistribute_rmap_set (struct bgp_redist *, const char *); extern int bgp_redistribute_rmap_set (struct bgp_redist *, const char *);
extern int bgp_redistribute_metric_set(struct bgp *, struct bgp_redist *, extern int bgp_redistribute_metric_set(struct bgp *, struct bgp_redist *,
afi_t, int, u_int32_t); afi_t, int, u_int32_t);
extern int bgp_redistribute_unset (struct bgp *, afi_t, int, u_short); extern int bgp_redistribute_unset (struct bgp *, afi_t, int, u_short);
extern int bgp_redistribute_unreg (struct bgp *, afi_t, int, u_short);
extern struct interface *if_lookup_by_ipv4 (struct in_addr *); extern struct interface *if_lookup_by_ipv4 (struct in_addr *, vrf_id_t);
extern struct interface *if_lookup_by_ipv4_exact (struct in_addr *); extern struct interface *if_lookup_by_ipv4_exact (struct in_addr *, vrf_id_t);
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
extern struct interface *if_lookup_by_ipv6 (struct in6_addr *, unsigned int ifindex); extern struct interface *if_lookup_by_ipv6 (struct in6_addr *, unsigned int, vrf_id_t);
extern struct interface *if_lookup_by_ipv6_exact (struct in6_addr *, unsigned int ifindex); extern struct interface *if_lookup_by_ipv6_exact (struct in6_addr *, unsigned int, vrf_id_t);
#endif /* HAVE_IPV6 */ #endif /* HAVE_IPV6 */
#endif /* _QUAGGA_BGP_ZEBRA_H */ #endif /* _QUAGGA_BGP_ZEBRA_H */

View File

@ -74,8 +74,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
/* BGP process wide configuration. */ /* BGP process wide configuration. */
static struct bgp_master bgp_master; static struct bgp_master bgp_master;
extern struct in_addr router_id_zebra;
/* BGP process wide configuration pointer to export. */ /* BGP process wide configuration pointer to export. */
struct bgp_master *bm; struct bgp_master *bm;
@ -2754,16 +2752,47 @@ bgp_create (as_t *as, const char *name)
bgp->as = *as; bgp->as = *as;
if (name) if (name)
bgp->name = XSTRDUP(MTYPE_BGP, name); {
bgp->name = XSTRDUP(MTYPE_BGP, name);
}
else
{
//Pending: See if calling bgp_instance_up() makes more sense.
THREAD_TIMER_ON (bm->master, bgp->t_startup, bgp_startup_timer_expire,
bgp, bgp->restart_time);
}
bgp->wpkt_quanta = BGP_WRITE_PACKET_MAX; bgp->wpkt_quanta = BGP_WRITE_PACKET_MAX;
bgp->coalesce_time = BGP_DEFAULT_SUBGROUP_COALESCE_TIME; bgp->coalesce_time = BGP_DEFAULT_SUBGROUP_COALESCE_TIME;
update_bgp_group_init(bgp);
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, THREAD_TIMER_ON (bm->master, bgp->t_startup, bgp_startup_timer_expire,
bgp, bgp->restart_time); bgp, bgp->restart_time);
update_bgp_group_init(bgp); /* Delete static route. */
return bgp; 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 first entry of BGP. */
@ -2804,6 +2833,20 @@ bgp_lookup_by_name (const char *name)
return NULL; return NULL;
} }
/* Lookup BGP structure by view name. */
//Pending: move this based on the vrf_hash lookup and find the linked bgp instance.
struct bgp *
bgp_lookup_by_vrf_id (vrf_id_t vrf_id)
{
struct bgp *bgp;
struct listnode *node, *nnode;
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
if (bgp->vrf_id == vrf_id)
return bgp;
return NULL;
}
/* Called from VTY commands. */ /* Called from VTY commands. */
int 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)
@ -2852,7 +2895,9 @@ bgp_get (struct bgp **bgp_val, as_t *as, const char *name)
} }
bgp = bgp_create (as, name); bgp = bgp_create (as, name);
bgp_router_id_set(bgp, &router_id_zebra); bgp_router_id_set(bgp, &bgp->router_id_zebra);
bgp_address_init (bgp);
bgp_scan_init (bgp);
*bgp_val = bgp; *bgp_val = bgp;
bgp->t_rmap_def_originate_eval = NULL; bgp->t_rmap_def_originate_eval = NULL;
@ -2869,12 +2914,14 @@ bgp_get (struct bgp **bgp_val, as_t *as, const char *name)
listnode_add (bm->bgp, bgp); listnode_add (bm->bgp, bgp);
bgp_vrf_update (bgp);
return 0; return 0;
} }
/* Delete BGP instance. */ /* Delete BGP instance. */
int void
bgp_delete (struct bgp *bgp) bgp_instance_down (struct bgp *bgp)
{ {
struct peer *peer; struct peer *peer;
struct peer_group *group; struct peer_group *group;
@ -2906,7 +2953,7 @@ bgp_delete (struct bgp *bgp)
for (afi = AFI_IP; afi < AFI_MAX; afi++) for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
if (i != ZEBRA_ROUTE_BGP) if (i != ZEBRA_ROUTE_BGP)
bgp_redistribute_unset (bgp, afi, i, 0); bgp_redistribute_unreg (bgp, afi, i, 0);
for (ALL_LIST_ELEMENTS (bgp->group, node, next, group)) for (ALL_LIST_ELEMENTS (bgp->group, node, next, group))
{ {
@ -2918,7 +2965,6 @@ bgp_delete (struct bgp *bgp)
bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN); bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
} }
} }
peer_group_delete (group);
} }
for (ALL_LIST_ELEMENTS (bgp->peer, node, next, peer)) for (ALL_LIST_ELEMENTS (bgp->peer, node, next, peer))
@ -2928,7 +2974,42 @@ bgp_delete (struct bgp *bgp)
/* Send notify to remote peer. */ /* Send notify to remote peer. */
bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN); 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);
}
return;
}
/* Delete BGP instance. */
int
bgp_delete (struct bgp *bgp)
{
struct peer *peer;
struct peer_group *group;
struct listnode *node, *next;
afi_t afi;
int i;
/* 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_unset (bgp, afi, i, 0);
for (ALL_LIST_ELEMENTS (bgp->group, node, next, group))
{
peer_group_delete (group);
}
for (ALL_LIST_ELEMENTS (bgp->peer, node, next, peer))
{
peer_delete (peer); peer_delete (peer);
} }
@ -2939,7 +3020,6 @@ bgp_delete (struct bgp *bgp)
if (bgp->t_rmap_def_originate_eval) if (bgp->t_rmap_def_originate_eval)
{ {
BGP_TIMER_OFF(bgp->t_rmap_def_originate_eval);
bgp_unlock(bgp); bgp_unlock(bgp);
} }
@ -3088,6 +3168,12 @@ peer_lookup (struct bgp *bgp, union sockunion *su)
for (ALL_LIST_ELEMENTS (bm->bgp, bgpnode, nbgpnode, bgp)) for (ALL_LIST_ELEMENTS (bm->bgp, bgpnode, nbgpnode, bgp))
{ {
/*
* Don't have to cross the instance boundaries for VRFs.
*/
if (bgp_flag_check(bgp, BGP_FLAG_INSTANCE_TYPE_VRF))
continue;
peer = hash_lookup(bgp->peerhash, &tmp_peer); peer = hash_lookup(bgp->peerhash, &tmp_peer);
if (peer) if (peer)
@ -6812,7 +6898,8 @@ bgp_config_write (struct vty *vty)
if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE)) if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE))
{ {
if (bgp->name) if (bgp->name)
vty_out (vty, " view %s", bgp->name); vty_out (vty, " %s %s", (bgp_flag_check(bgp, BGP_FLAG_INSTANCE_TYPE_VIEW) ?
"view" : "vrf"), bgp->name);
} }
vty_out (vty, "%s", VTY_NEWLINE); vty_out (vty, "%s", VTY_NEWLINE);
@ -7043,7 +7130,6 @@ bgp_init (void)
{ {
/* allocates some vital data structures used by peer commands in vty_init */ /* allocates some vital data structures used by peer commands in vty_init */
bgp_scan_init ();
/* Init zebra. */ /* Init zebra. */
bgp_zebra_init(bm->master); bgp_zebra_init(bm->master);
@ -7057,7 +7143,6 @@ bgp_init (void)
bgp_dump_init (); bgp_dump_init ();
bgp_route_init (); bgp_route_init ();
bgp_route_map_init (); bgp_route_map_init ();
bgp_address_init ();
bgp_scan_vty_init(); bgp_scan_vty_init();
bgp_mplsvpn_init (); bgp_mplsvpn_init ();

View File

@ -22,6 +22,8 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#define _QUAGGA_BGPD_H #define _QUAGGA_BGPD_H
#include "lib/json.h" #include "lib/json.h"
#include "vrf.h"
/* For union sockunion. */ /* For union sockunion. */
#include "queue.h" #include "queue.h"
#include "sockunion.h" #include "sockunion.h"
@ -136,6 +138,8 @@ struct bgp
/* Name of this BGP instance. */ /* Name of this BGP instance. */
char *name; char *name;
vrf_id_t vrf_id;
/* Reference count to allow peer_delete to finish after bgp_delete */ /* Reference count to allow peer_delete to finish after bgp_delete */
int lock; int lock;
@ -184,6 +188,7 @@ struct bgp
/* BGP router identifier. */ /* BGP router identifier. */
struct in_addr router_id; struct in_addr router_id;
struct in_addr router_id_static; struct in_addr router_id_static;
struct in_addr router_id_zebra;
/* BGP route reflector cluster ID. */ /* BGP route reflector cluster ID. */
struct in_addr cluster_id; struct in_addr cluster_id;
@ -251,11 +256,23 @@ struct bgp
#define BGP_FLAG_MULTIPATH_RELAX_AS_SET (1 << 17) #define BGP_FLAG_MULTIPATH_RELAX_AS_SET (1 << 17)
#define BGP_FLAG_FORCE_STATIC_PROCESS (1 << 18) #define BGP_FLAG_FORCE_STATIC_PROCESS (1 << 18)
#define BGP_FLAG_SHOW_HOSTNAME (1 << 19) #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 */ /* BGP Per AF flags */
u_int16_t af_flags[AFI_MAX][SAFI_MAX]; u_int16_t af_flags[AFI_MAX][SAFI_MAX];
#define BGP_CONFIG_DAMPENING (1 << 0) #define BGP_CONFIG_DAMPENING (1 << 0)
/* Route table for next-hop lookup cache. */
struct bgp_table *nexthop_cache_table[AFI_MAX];
/* Route table for import-check */
struct bgp_table *import_check_table[AFI_MAX];
struct bgp_table *connected_table[AFI_MAX];
struct hash *address_hash;
/* Static route configuration. */ /* Static route configuration. */
struct bgp_table *route[AFI_MAX][SAFI_MAX]; struct bgp_table *route[AFI_MAX][SAFI_MAX];
@ -1092,6 +1109,7 @@ extern int bgp_nexthop_set (union sockunion *, union sockunion *,
extern struct bgp *bgp_get_default (void); extern struct bgp *bgp_get_default (void);
extern struct bgp *bgp_lookup (as_t, const char *); extern struct bgp *bgp_lookup (as_t, const char *);
extern struct bgp *bgp_lookup_by_name (const char *); extern struct bgp *bgp_lookup_by_name (const char *);
extern struct bgp *bgp_lookup_by_vrf_id (vrf_id_t);
extern struct peer *peer_lookup (struct bgp *, union sockunion *); extern struct peer *peer_lookup (struct bgp *, union sockunion *);
extern struct peer *peer_lookup_by_conf_if (struct bgp *, const char *); extern struct peer *peer_lookup_by_conf_if (struct bgp *, const char *);
extern struct peer *peer_lookup_by_hostname(struct bgp *, const char *); extern struct peer *peer_lookup_by_hostname(struct bgp *, const char *);
@ -1143,6 +1161,8 @@ extern int bgp_option_unset (int);
extern int bgp_option_check (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 *);
extern void bgp_instance_up (struct bgp *);
extern void bgp_instance_down (struct bgp *);
extern int bgp_delete (struct bgp *); extern int bgp_delete (struct bgp *);
extern int bgp_flag_set (struct bgp *, int); extern int bgp_flag_set (struct bgp *, int);
@ -1276,7 +1296,6 @@ extern struct peer_af * peer_af_create (struct peer *, afi_t, safi_t);
extern struct peer_af * peer_af_find (struct peer *, afi_t, safi_t); extern struct peer_af * peer_af_find (struct peer *, afi_t, safi_t);
extern int peer_af_delete (struct peer *, afi_t, safi_t); extern int peer_af_delete (struct peer *, afi_t, safi_t);
extern void bgp_scan_finish(void);
extern void bgp_close(void); extern void bgp_close(void);
static inline int static inline int