From: Daniel Walton <[email protected]>
Signed-off-by: Daniel Walton <[email protected]>
---
bgpd/bgp_route.c | 5 ++-
bgpd/bgp_table.h | 1 +
bgpd/bgp_vty.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 127 insertions(+), 1 deletion(-)
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index dcce000..9240497 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -1654,7 +1654,7 @@ bgp_process_main (struct work_queue *wq, void *data)
new_select = old_and_new.new;
/* Nothing to do. */
- if (old_select && old_select == new_select)
+ if (old_select && old_select == new_select && !CHECK_FLAG(rn->flags,
BGP_NODE_USER_CLEAR))
{
if (! CHECK_FLAG (old_select->flags, BGP_INFO_ATTR_CHANGED))
{
@@ -1668,6 +1668,9 @@ bgp_process_main (struct work_queue *wq, void *data)
}
}
+ /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set */
+ UNSET_FLAG(rn->flags, BGP_NODE_USER_CLEAR);
+
if (old_select)
bgp_info_unset_flag (rn, old_select, BGP_INFO_SELECTED);
if (new_select)
diff --git a/bgpd/bgp_table.h b/bgpd/bgp_table.h
index 209a18c..0c9e50d 100644
--- a/bgpd/bgp_table.h
+++ b/bgpd/bgp_table.h
@@ -65,6 +65,7 @@ struct bgp_node
u_char flags;
#define BGP_NODE_PROCESS_SCHEDULED (1 << 0)
+#define BGP_NODE_USER_CLEAR (1 << 1)
};
/*
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index b0cf819..c04e8c2 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -4859,6 +4859,87 @@ bgp_clear (struct vty *vty, struct bgp *bgp, afi_t afi,
safi_t safi,
return CMD_SUCCESS;
}
+/* Recalculate bestpath and re-advertise a prefix */
+static int
+bgp_clear_prefix (struct vty *vty, char *view_name, const char *ip_str,
+ afi_t afi, safi_t safi, struct prefix_rd *prd)
+{
+ int ret;
+ struct prefix match;
+ struct bgp_node *rn;
+ struct bgp_node *rm;
+ struct bgp *bgp;
+ struct bgp_table *table;
+ struct bgp_table *rib;
+
+ /* BGP structure lookup. */
+ if (view_name)
+ {
+ bgp = bgp_lookup_by_name (view_name);
+ if (bgp == NULL)
+ {
+ vty_out (vty, "%% Can't find BGP view %s%s", view_name, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ else
+ {
+ bgp = bgp_get_default ();
+ if (bgp == NULL)
+ {
+ vty_out (vty, "%% No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
+ /* Check IP address argument. */
+ ret = str2prefix (ip_str, &match);
+ if (! ret)
+ {
+ vty_out (vty, "%% address is malformed%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ match.family = afi2family (afi);
+ rib = bgp->rib[afi][safi];
+
+ if (safi == SAFI_MPLS_VPN)
+ {
+ for (rn = bgp_table_top (rib); rn; rn = bgp_route_next (rn))
+ {
+ if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
+ continue;
+
+ if ((table = rn->info) != NULL)
+ {
+ if ((rm = bgp_node_match (table, &match)) != NULL)
+ {
+ if (rm->p.prefixlen == match.prefixlen)
+ {
+ SET_FLAG (rn->flags, BGP_NODE_USER_CLEAR);
+ bgp_process (bgp, rm, afi, safi);
+ }
+ bgp_unlock_node (rm);
+ }
+ }
+ }
+ }
+ else
+ {
+ if ((rn = bgp_node_match (rib, &match)) != NULL)
+ {
+ if (rn->p.prefixlen == match.prefixlen)
+ {
+ SET_FLAG (rn->flags, BGP_NODE_USER_CLEAR);
+ bgp_process (bgp, rn, afi, safi);
+ }
+ bgp_unlock_node (rn);
+ }
+ }
+
+ return CMD_SUCCESS;
+}
+
static int
bgp_clear_vty (struct vty *vty, const char *name, afi_t afi, safi_t safi,
enum clear_sort sort, enum bgp_clear_type stype,
@@ -5024,6 +5105,27 @@ ALIAS (clear_ip_bgp_external,
"Address family\n"
"Clear all external peers\n")
+DEFUN (clear_ip_bgp_prefix,
+ clear_ip_bgp_prefix_cmd,
+ "clear ip bgp prefix A.B.C.D/M",
+ CLEAR_STR
+ IP_STR
+ BGP_STR
+ "Clear bestpath and re-advertise\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+{
+ return bgp_clear_prefix (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST, NULL);
+}
+
+ALIAS (clear_ip_bgp_prefix,
+ clear_bgp_prefix_cmd,
+ "clear bgp prefix A.B.C.D/M",
+ CLEAR_STR
+ BGP_STR
+ "Clear bestpath and re-advertise\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+
+
DEFUN (clear_ip_bgp_as,
clear_ip_bgp_as_cmd,
"clear ip bgp " CMD_AS_RANGE,
@@ -5227,6 +5329,22 @@ ALIAS (clear_bgp_all_soft_out,
"Clear all peers\n"
"Soft reconfig outbound update\n")
+DEFUN (clear_bgp_ipv6_safi_prefix,
+ clear_bgp_ipv6_safi_prefix_cmd,
+ "clear bgp ipv6 (unicast|multicast) prefix X:X::X:X/M",
+ CLEAR_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family Modifier\n"
+ "Clear bestpath and re-advertise\n"
+ "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
+{
+ if (strncmp (argv[0], "m", 1) == 0)
+ return bgp_clear_prefix (vty, NULL, argv[1], AFI_IP6, SAFI_MULTICAST,
NULL);
+ else
+ return bgp_clear_prefix (vty, NULL, argv[1], AFI_IP6, SAFI_UNICAST, NULL);
+}
+
DEFUN (clear_ip_bgp_peer_soft_out,
clear_ip_bgp_peer_soft_out_cmd,
"clear ip bgp A.B.C.D soft out",
@@ -10405,6 +10523,10 @@ bgp_vty_init (void)
install_element (ENABLE_NODE, &clear_bgp_ipv6_as_in_prefix_filter_cmd);
#endif /* HAVE_IPV6 */
+ /* clear ip bgp prefix */
+ install_element (ENABLE_NODE, &clear_ip_bgp_prefix_cmd);
+ install_element (ENABLE_NODE, &clear_bgp_ipv6_safi_prefix_cmd);
+
/* "clear ip bgp neighbor soft out" */
install_element (ENABLE_NODE, &clear_ip_bgp_all_soft_out_cmd);
install_element (ENABLE_NODE, &clear_ip_bgp_instance_all_soft_out_cmd);
--
1.9.1
_______________________________________________
Quagga-dev mailing list
[email protected]
https://lists.quagga.net/mailman/listinfo/quagga-dev