[frr] [PATCH 04/11] bgpd: VRF RIB log updates enhancement
Philippe Guibert
philippe.guibert at 6wind.com
Wed Dec 21 09:13:49 EST 2016
On adding/removing/updating NLRI entries into VRF RIB tables, a BGP
event is fired. Note that only selected entries, and entries that are
part of multipath entries, and where one of the multipath entry is
selected.
Signed-off-by: Philippe Guibert <philippe.guibert at 6wind.com>
---
bgpd/bgp_route.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++--
bgpd/bgp_route.h | 2 ++
bgpd/bgp_vrf.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
bgpd/bgp_vrf.h | 4 ++++
4 files changed, 109 insertions(+), 2 deletions(-)
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 81d33df024fa..f9454d371ff1 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -2033,9 +2033,13 @@ bgp_process_vrf_main (struct work_queue *wq, void *data)
struct bgp *bgp = pq->bgp;
afi_t afi = pq->afi;
safi_t safi = pq->safi;
- struct bgp_info *new_select;
+ struct bgp_info *new_select, *ri;
struct bgp_info *old_select;
struct bgp_info_pair old_and_new;
+ struct bgp_vrf *vrf = NULL;
+
+ if(rn)
+ vrf = bgp_vrf_lookup_per_rn(bgp, afi, rn);
/* Best path selection. */
bgp_best_selection (bgp, rn, &bgp->maxpaths[afi][safi], &old_and_new);
@@ -2052,6 +2056,13 @@ bgp_process_vrf_main (struct work_queue *wq, void *data)
{
UNSET_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG);
SET_FLAG (old_select->flags, BGP_INFO_MULTIPATH);
+ for(ri = rn->info; ri; ri = ri->next)
+ {
+ if(ri == old_select)
+ continue;
+ if(!bgp_is_mpath_entry(ri, new_select))
+ bgp_vrf_update(vrf, afi, rn, ri, false);
+ }
}
/* no zebra announce */
UNSET_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG);
@@ -2073,18 +2084,53 @@ bgp_process_vrf_main (struct work_queue *wq, void *data)
{
if( CHECK_FLAG (old_select->flags, BGP_INFO_SELECTED))
{
- if(bgp_is_mpath_entry(old_select, new_select))
+ if(!bgp_is_mpath_entry(old_select, new_select))
+ {
+ bgp_vrf_update(vrf, afi, rn, old_select, false);
+ }
+ else
{
UNSET_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG);
SET_FLAG (old_select->flags, BGP_INFO_MULTIPATH);
}
}
+ /* withdraw mp entries which could have been removed
+ * and that a update has previously been sent
+ */
+ for(ri = rn->info; ri; ri = ri->next)
+ {
+ if(ri == old_select || (ri == new_select) )
+ continue;
+ if(!bgp_is_mpath_entry(ri, new_select))
+ {
+ bgp_vrf_update(vrf, afi, rn, ri, false);
+ }
+ }
+ bgp_info_unset_flag (rn, old_select, BGP_INFO_SELECTED);
}
if (new_select)
{
+ if(!CHECK_FLAG (new_select->flags, BGP_INFO_SELECTED) ||
+ CHECK_FLAG (new_select->flags, BGP_INFO_MULTIPATH) ||
+ CHECK_FLAG (new_select->flags, BGP_INFO_MULTIPATH_CHG))
+ {
+ bgp_vrf_update(vrf, afi, rn, new_select, true);
+ }
bgp_info_set_flag (rn, new_select, BGP_INFO_SELECTED);
bgp_info_unset_flag (rn, new_select, BGP_INFO_ATTR_CHANGED);
UNSET_FLAG (new_select->flags, BGP_INFO_MULTIPATH_CHG);
+ /* append mp entries which could have been added
+ * and that a update has not been sent
+ */
+ for(ri = rn->info; ri; ri = ri->next)
+ {
+ if( (ri == new_select) || ( ri == old_select))
+ continue;
+ if(bgp_is_mpath_entry(ri, new_select))
+ {
+ bgp_vrf_update(vrf, afi, rn, ri, true);
+ }
+ }
}
/* Reap old select bgp_info, if it has been removed */
@@ -2321,6 +2367,7 @@ bgp_rib_remove (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
bgp_process (peer->bgp, rn, afi, safi);
}
+
static void
bgp_rib_withdraw (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
afi_t afi, safi_t safi, struct prefix_rd *prd)
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index 1bbd9cc99745..57ab7e8ec8d0 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -147,6 +147,8 @@ struct bgp_info
#define BGP_INFO_COUNTED (1 << 10)
#define BGP_INFO_MULTIPATH (1 << 11)
#define BGP_INFO_MULTIPATH_CHG (1 << 12)
+#define BGP_INFO_UPDATE_SENT (1 << 13)
+#define BGP_INFO_WITHDRAW_SENT (1 << 14)
/* BGP route type. This can be static, RIP, OSPF, BGP etc. */
u_char type;
diff --git a/bgpd/bgp_vrf.c b/bgpd/bgp_vrf.c
index d1883a5c95bd..dbd9bc9d32f4 100644
--- a/bgpd/bgp_vrf.c
+++ b/bgpd/bgp_vrf.c
@@ -369,6 +369,60 @@ static bool rd_same (const struct prefix_rd *a, const struct prefix_rd *b)
return !memcmp(&a->val, &b->val, sizeof(a->val));
}
+/* messages sent to ODL to signify that an entry
+ * has been selected, or unselected
+ */
+void
+bgp_vrf_update (struct bgp_vrf *vrf, afi_t afi, struct bgp_node *rn,
+ struct bgp_info *selected, uint8_t announce)
+{
+ if(!vrf || (rn && bgp_node_table (rn)->type != BGP_TABLE_VRF))
+ return;
+ if (announce == true)
+ {
+ if(CHECK_FLAG (selected->flags, BGP_INFO_UPDATE_SENT))
+ return;
+ SET_FLAG (selected->flags, BGP_INFO_UPDATE_SENT);
+ UNSET_FLAG (selected->flags, BGP_INFO_WITHDRAW_SENT);
+ }
+ else
+ {
+ /* if not already sent, do nothing */
+ if(!CHECK_FLAG (selected->flags, BGP_INFO_UPDATE_SENT))
+ return;
+ if(CHECK_FLAG (selected->flags, BGP_INFO_WITHDRAW_SENT))
+ return;
+ SET_FLAG (selected->flags, BGP_INFO_WITHDRAW_SENT);
+ UNSET_FLAG (selected->flags, BGP_INFO_UPDATE_SENT);
+ }
+ if (BGP_DEBUG (bgp_vrf, BGPVRF))
+ {
+ char vrf_rd_str[RD_ADDRSTRLEN], rd_str[RD_ADDRSTRLEN], pfx_str[INET6_BUFSIZ];
+ char nh_str[BUFSIZ] = "<?>";
+ uint32_t label;
+
+ prefix_rd2str(&vrf->outbound_rd, vrf_rd_str, sizeof(vrf_rd_str));
+ prefix_rd2str(&selected->extra->vrf_rd, rd_str, sizeof(rd_str));
+ prefix2str(&rn->p, pfx_str, sizeof(pfx_str));
+ label = decode_label (selected->extra->tag);
+
+ if (selected->attr && selected->attr->extra)
+ {
+ if (afi == AFI_IP)
+ strcpy (nh_str, inet_ntoa (selected->attr->extra->mp_nexthop_global_in));
+ else if (afi == AFI_IP6)
+ inet_ntop (AF_INET6, &selected->attr->extra->mp_nexthop_global, nh_str, BUFSIZ);
+ }
+
+ if (announce)
+ zlog_info ("vrf[%s] %s: prefix updated, best RD %s label %u nexthop %s",
+ vrf_rd_str, pfx_str, rd_str, label, nh_str);
+ else
+ zlog_info ("vrf[%s] %s: prefix withdrawn nh %s label %u",
+ vrf_rd_str, pfx_str, nh_str, label);
+ }
+}
+
/* VRF import processing */
/* updates selected bgp_info structure to bgp vrf rib table
* most of the cases, processing consists in adding or removing entries in RIB tables
diff --git a/bgpd/bgp_vrf.h b/bgpd/bgp_vrf.h
index 40f885b46a00..3cae3e1cbc3e 100644
--- a/bgpd/bgp_vrf.h
+++ b/bgpd/bgp_vrf.h
@@ -101,5 +101,9 @@ bgp_vrf_process_imports (struct bgp *bgp, afi_t afi, safi_t safi,
struct bgp_info *old_select,
struct bgp_info *new_select);
+extern void
+bgp_vrf_update (struct bgp_vrf *vrf, afi_t afi, struct bgp_node *rn,
+ struct bgp_info *selected, uint8_t announce);
+
#endif /* _QUAGGA_BGP_VRF */
--
2.1.4
More information about the dev
mailing list