]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_debug.c
bgpd: List all groups dynamically for commands with peer-group
[mirror_frr.git] / bgpd / bgp_debug.c
index a4ded57c25630d2008103bbcbb5a3e5a2bd62e43..f476b161884ad8eaf6afa02c9523cda7d1fce692 100644 (file)
@@ -42,6 +42,9 @@
 #include "bgpd/bgp_ecommunity.h"
 #include "bgpd/bgp_label.h"
 #include "bgpd/bgp_evpn.h"
+#include "bgpd/bgp_evpn_private.h"
+#include "bgpd/bgp_evpn_vty.h"
+#include "bgpd/bgp_vty.h"
 #include "bgpd/bgp_flowspec.h"
 
 unsigned long conf_bgp_debug_as4;
@@ -169,6 +172,8 @@ static const struct message bgp_notify_capability_msg[] = {
 const char *bgp_origin_str[] = {"i", "e", "?"};
 const char *bgp_origin_long_str[] = {"IGP", "EGP", "incomplete"};
 
+static int bgp_debug_print_evpn_prefix(struct vty *vty, const char *desc,
+                                      struct prefix *p);
 /* Given a string return a pointer the corresponding peer structure */
 static struct peer *bgp_find_peer(struct vty *vty, const char *peer_str)
 {
@@ -213,14 +218,16 @@ static void bgp_debug_list_free(struct list *list)
                }
 }
 
-/* Print the desc along with a list of peers/prefixes this debug is
- * enabled for */
+/*
+ * Print the desc along with a list of peers/prefixes this debug is
+ * enabled for
+ */
 static void bgp_debug_list_print(struct vty *vty, const char *desc,
                                 struct list *list)
 {
        struct bgp_debug_filter *filter;
        struct listnode *node, *nnode;
-       char buf[INET6_ADDRSTRLEN];
+       char buf[PREFIX2STR_BUFFER];
 
        vty_out(vty, "%s", desc);
 
@@ -230,19 +237,20 @@ static void bgp_debug_list_print(struct vty *vty, const char *desc,
                        if (filter->host)
                                vty_out(vty, " %s", filter->host);
 
-                       if (filter->p)
-                               vty_out(vty, " %s/%d",
-                                       inet_ntop(filter->p->family,
-                                                 &filter->p->u.prefix, buf,
-                                                 INET6_ADDRSTRLEN),
-                                       filter->p->prefixlen);
+                       if (filter->p && filter->p->family == AF_EVPN)
+                               bgp_debug_print_evpn_prefix(vty, "", filter->p);
+                       else if (filter->p) {
+                               prefix2str(filter->p, buf, sizeof(buf));
+                               vty_out(vty, " %s", buf);
+                       }
                }
        }
 
        vty_out(vty, "\n");
 }
 
-/* Print the command to enable the debug for each peer/prefix this debug is
+/*
+ * Print the command to enable the debug for each peer/prefix this debug is
  * enabled for
  */
 static int bgp_debug_list_conf_print(struct vty *vty, const char *desc,
@@ -250,7 +258,7 @@ static int bgp_debug_list_conf_print(struct vty *vty, const char *desc,
 {
        struct bgp_debug_filter *filter;
        struct listnode *node, *nnode;
-       char buf[INET6_ADDRSTRLEN];
+       char buf[PREFIX2STR_BUFFER];
        int write = 0;
 
        if (list && !list_isempty(list)) {
@@ -260,13 +268,13 @@ static int bgp_debug_list_conf_print(struct vty *vty, const char *desc,
                                write++;
                        }
 
-
-                       if (filter->p) {
-                               vty_out(vty, "%s %s/%d\n", desc,
-                                       inet_ntop(filter->p->family,
-                                                 &filter->p->u.prefix, buf,
-                                                 INET6_ADDRSTRLEN),
-                                       filter->p->prefixlen);
+                       if (filter->p && filter->p->family == AF_EVPN) {
+                               bgp_debug_print_evpn_prefix(vty, desc,
+                                                           filter->p);
+                               write++;
+                       } else if (filter->p) {
+                               prefix2str(filter->p, buf, sizeof(buf));
+                               vty_out(vty, "%s %s\n", desc, buf);
                                write++;
                        }
                }
@@ -360,6 +368,8 @@ int bgp_dump_attr(struct attr *attr, char *buf, size_t size)
        if (!attr)
                return 0;
 
+       buf[0] = '\0';
+
        if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)))
                snprintf(buf, size, "nexthop %s", inet_ntoa(attr->nexthop));
 
@@ -543,6 +553,106 @@ static void bgp_debug_clear_updgrp_update_dbg(struct bgp *bgp)
        update_group_walk(bgp, update_group_clear_update_dbg, NULL);
 }
 
+static int bgp_debug_print_evpn_prefix(struct vty *vty, const char *desc,
+                                      struct prefix *p)
+{
+       char evpn_desc[PREFIX2STR_BUFFER + INET_ADDRSTRLEN];
+       char buf[PREFIX2STR_BUFFER];
+       char buf2[ETHER_ADDR_STRLEN];
+
+       if (p->u.prefix_evpn.route_type == BGP_EVPN_MAC_IP_ROUTE) {
+               if (is_evpn_prefix_ipaddr_none((struct prefix_evpn *)p)) {
+                       sprintf(evpn_desc, "l2vpn evpn type macip mac %s",
+                                prefix_mac2str(
+                                       &p->u.prefix_evpn.macip_addr.mac,
+                                       buf2, sizeof(buf2)));
+               } else {
+                       uint8_t family = is_evpn_prefix_ipaddr_v4(
+                                               (struct prefix_evpn *)p) ?
+                                                       AF_INET : AF_INET6;
+                       sprintf(evpn_desc, "l2vpn evpn type macip mac %s ip %s",
+                                prefix_mac2str(
+                                       &p->u.prefix_evpn.macip_addr.mac,
+                                       buf2, sizeof(buf2)),
+                                inet_ntop(family,
+                                       &p->u.prefix_evpn.macip_addr.ip.ip.addr,
+                                       buf, PREFIX2STR_BUFFER));
+               }
+       } else if (p->u.prefix_evpn.route_type == BGP_EVPN_IMET_ROUTE) {
+               sprintf(evpn_desc, "l2vpn evpn type multicast ip %s",
+                       inet_ntoa(p->u.prefix_evpn.imet_addr.ip.ipaddr_v4));
+       } else if (p->u.prefix_evpn.route_type == BGP_EVPN_IP_PREFIX_ROUTE) {
+               uint8_t family = is_evpn_prefix_ipaddr_v4(
+                                       (struct prefix_evpn *)p) ? AF_INET
+                                                               : AF_INET6;
+               sprintf(evpn_desc, "l2vpn evpn type prefix ip %s/%d",
+                       inet_ntop(family,
+                                 &p->u.prefix_evpn.prefix_addr.ip.ip.addr, buf,
+                                 PREFIX2STR_BUFFER),
+                       p->u.prefix_evpn.prefix_addr.ip_prefix_length);
+       }
+
+       vty_out(vty, "%s %s\n", desc, evpn_desc);
+
+       return 0;
+}
+
+static int bgp_debug_parse_evpn_prefix(struct vty *vty, struct cmd_token **argv,
+                                      int argc, struct prefix **argv_pp)
+{
+       struct prefix *argv_p;
+       struct ethaddr mac;
+       struct ipaddr ip;
+       int evpn_type;
+       int type_idx = 0;
+       int mac_idx = 0;
+       int ip_idx = 0;
+
+       argv_p = *argv_pp;
+
+       if (argv_find(argv, argc, "macip", &type_idx))
+               evpn_type = BGP_EVPN_MAC_IP_ROUTE;
+       else if (argv_find(argv, argc, "multicast", &type_idx))
+               evpn_type = BGP_EVPN_IMET_ROUTE;
+       else if (argv_find(argv, argc, "prefix", &type_idx))
+               evpn_type = BGP_EVPN_IP_PREFIX_ROUTE;
+       else
+               evpn_type = 0;
+
+       if (evpn_type == BGP_EVPN_MAC_IP_ROUTE) {
+               memset(&ip, 0, sizeof(struct ipaddr));
+
+               argv_find(argv, argc, "mac", &mac_idx);
+               (void)prefix_str2mac(argv[mac_idx + 1]->arg, &mac);
+
+               argv_find(argv, argc, "ip", &ip_idx);
+               str2ipaddr(argv[ip_idx + 1]->arg, &ip);
+
+               build_evpn_type2_prefix((struct prefix_evpn *)argv_p,
+                                       &mac, &ip);
+       } else if (evpn_type == BGP_EVPN_IMET_ROUTE) {
+               memset(&ip, 0, sizeof(struct ipaddr));
+
+               argv_find(argv, argc, "ip", &ip_idx);
+               str2ipaddr(argv[ip_idx + 1]->arg, &ip);
+
+               build_evpn_type3_prefix((struct prefix_evpn *)argv_p,
+                                       ip.ipaddr_v4);
+       } else if (evpn_type == BGP_EVPN_IP_PREFIX_ROUTE) {
+               struct prefix ip_prefix;
+
+               memset(&ip_prefix, 0, sizeof(struct prefix));
+               if (argv_find(argv, argc, "ip", &ip_idx)) {
+                       (void)str2prefix(argv[ip_idx + 1]->arg, &ip_prefix);
+                       apply_mask(&ip_prefix);
+               }
+               build_type5_prefix_from_ip_prefix(
+                                       (struct prefix_evpn *)argv_p,
+                                       &ip_prefix);
+       }
+
+       return CMD_SUCCESS;
+}
 
 /* Debug option setting interface. */
 unsigned long bgp_debug_option = 0;
@@ -1266,6 +1376,141 @@ DEFUN (no_debug_bgp_update_direct_peer,
        return CMD_SUCCESS;
 }
 
+#ifndef VTYSH_EXTRACT_PL
+#include "bgpd/bgp_debug_clippy.c"
+#endif
+
+DEFPY (debug_bgp_update_prefix_afi_safi,
+       debug_bgp_update_prefix_afi_safi_cmd,
+       "debug bgp updates prefix l2vpn$afi evpn$safi type <macip mac <X:X:X:X:X:X|X:X:X:X:X:X/M> [ip <A.B.C.D|X:X::X:X>]|multicast ip <A.B.C.D|X:X::X:X>|prefix ip <A.B.C.D/M|X:X::X:X/M>>",
+       DEBUG_STR
+       BGP_STR
+       "BGP updates\n"
+       "Specify a prefix to debug\n"
+       L2VPN_HELP_STR
+       EVPN_HELP_STR
+       "Specify EVPN Route type\n"
+       "MAC-IP (Type-2) route\n"
+       MAC_STR MAC_STR MAC_STR
+       IP_STR
+       "IPv4 address\n"
+       "IPv6 address\n"
+       "Multicast (Type-3) route\n"
+       IP_STR
+       "IPv4 address\n"
+       "IPv6 address\n"
+       "Prefix (Type-5) route\n"
+       IP_STR
+       "IPv4 prefix\n"
+       "IPv6 prefix\n")
+{
+       struct prefix *argv_p;
+       int ret = CMD_SUCCESS;
+       char buf[PREFIX2STR_BUFFER];
+
+       argv_p = prefix_new();
+
+       ret = bgp_debug_parse_evpn_prefix(vty, argv, argc, &argv_p);
+       if (ret != CMD_SUCCESS) {
+               prefix_free(argv_p);
+               return ret;
+       }
+
+       if (!bgp_debug_update_prefixes)
+               bgp_debug_update_prefixes = list_new();
+
+       prefix2str(argv_p, buf, sizeof(buf));
+
+       if (bgp_debug_list_has_entry(bgp_debug_update_prefixes, NULL, argv_p)) {
+               vty_out(vty,
+                       "BGP updates debugging is already enabled for %s\n",
+                       buf);
+               prefix_free(argv_p);
+               return CMD_SUCCESS;
+       }
+
+       bgp_debug_list_add_entry(bgp_debug_update_prefixes, NULL, argv_p);
+
+       if (vty->node == CONFIG_NODE) {
+               DEBUG_ON(update, UPDATE_PREFIX);
+       } else {
+               TERM_DEBUG_ON(update, UPDATE_PREFIX);
+               vty_out(vty, "BGP updates debugging is on for %s\n", buf);
+       }
+
+       prefix_free(argv_p);
+
+       return CMD_SUCCESS;
+}
+
+DEFPY (no_debug_bgp_update_prefix_afi_safi,
+       no_debug_bgp_update_prefix_afi_safi_cmd,
+       "no debug bgp updates prefix l2vpn$afi evpn$safi type <macip mac <X:X:X:X:X:X|X:X:X:X:X:X/M> [ip <A.B.C.D|X:X::X:X>]|multicast ip <A.B.C.D|X:X::X:X>|prefix ip <A.B.C.D/M|X:X::X:X/M>>",
+       NO_STR
+       DEBUG_STR
+       BGP_STR
+       "BGP updates\n"
+       "Specify a prefix to debug\n"
+       L2VPN_HELP_STR
+       EVPN_HELP_STR
+       "Specify EVPN Route type\n"
+       "MAC-IP (Type-2) route\n"
+       MAC_STR MAC_STR MAC_STR
+       IP_STR
+       "IPv4 address\n"
+       "IPv6 address\n"
+       "Multicast (Type-3) route\n"
+       IP_STR
+       "IPv4 address\n"
+       "IPv6 address\n"
+       "Prefix (Type-5) route\n"
+       IP_STR
+       "IPv4 prefix\n"
+       "IPv6 prefix\n")
+{
+       struct prefix *argv_p;
+       bool found_prefix = false;
+       int ret = CMD_SUCCESS;
+       char buf[PREFIX2STR_BUFFER];
+
+       argv_p = prefix_new();
+
+       ret = bgp_debug_parse_evpn_prefix(vty, argv, argc, &argv_p);
+       if (ret != CMD_SUCCESS) {
+               prefix_free(argv_p);
+               return ret;
+       }
+
+       if (bgp_debug_update_prefixes
+           && !list_isempty(bgp_debug_update_prefixes)) {
+               found_prefix = bgp_debug_list_remove_entry(
+                       bgp_debug_update_prefixes, NULL, argv_p);
+
+               if (list_isempty(bgp_debug_update_prefixes)) {
+                       if (vty->node == CONFIG_NODE) {
+                               DEBUG_OFF(update, UPDATE_PREFIX);
+                       } else {
+                               TERM_DEBUG_OFF(update, UPDATE_PREFIX);
+                               vty_out(vty,
+                                       "BGP updates debugging (per prefix) is off\n");
+                       }
+               }
+       }
+
+       prefix2str(argv_p, buf, sizeof(buf));
+
+       if (found_prefix)
+               vty_out(vty, "BGP updates debugging is off for %s\n", buf);
+       else
+               vty_out(vty, "BGP updates debugging was not enabled for %s\n",
+                       buf);
+
+       prefix_free(argv_p);
+
+       return ret;
+}
+
+
 DEFUN (debug_bgp_update_prefix,
        debug_bgp_update_prefix_cmd,
        "debug bgp updates prefix <A.B.C.D/M|X:X::X:X/M>",
@@ -1878,67 +2123,6 @@ DEFUN_NOSH (show_debugging_bgp,
        return CMD_SUCCESS;
 }
 
-/* return count of number of debug flags set */
-int bgp_debug_count(void)
-{
-       int ret = 0;
-       if (BGP_DEBUG(as4, AS4))
-               ret++;
-
-       if (BGP_DEBUG(as4, AS4_SEGMENT))
-               ret++;
-
-       if (BGP_DEBUG(bestpath, BESTPATH))
-               ret++;
-
-       if (BGP_DEBUG(keepalive, KEEPALIVE))
-               ret++;
-
-       if (BGP_DEBUG(neighbor_events, NEIGHBOR_EVENTS))
-               ret++;
-
-       if (BGP_DEBUG(nht, NHT))
-               ret++;
-
-       if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
-               ret++;
-
-       if (BGP_DEBUG(update, UPDATE_PREFIX))
-               ret++;
-
-       if (BGP_DEBUG(update, UPDATE_IN))
-               ret++;
-
-       if (BGP_DEBUG(update, UPDATE_OUT))
-               ret++;
-
-       if (BGP_DEBUG(zebra, ZEBRA))
-               ret++;
-
-       if (BGP_DEBUG(allow_martians, ALLOW_MARTIANS))
-               ret++;
-
-       if (BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF))
-               ret++;
-       if (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF))
-               ret++;
-       if (BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT))
-               ret++;
-       if (BGP_DEBUG(vpn, VPN_LEAK_LABEL))
-               ret++;
-       if (BGP_DEBUG(flowspec, FLOWSPEC))
-               ret++;
-       if (BGP_DEBUG(labelpool, LABELPOOL))
-               ret++;
-
-       if (BGP_DEBUG(pbr, PBR))
-               ret++;
-       if (BGP_DEBUG(pbr, PBR_ERROR))
-               ret++;
-
-       return ret;
-}
-
 static int bgp_config_write_debug(struct vty *vty)
 {
        int write = 0;
@@ -2095,6 +2279,10 @@ void bgp_debug_init(void)
        install_element(CONFIG_NODE, &debug_bgp_update_prefix_cmd);
        install_element(ENABLE_NODE, &no_debug_bgp_update_prefix_cmd);
        install_element(CONFIG_NODE, &no_debug_bgp_update_prefix_cmd);
+       install_element(ENABLE_NODE, &debug_bgp_update_prefix_afi_safi_cmd);
+       install_element(CONFIG_NODE, &debug_bgp_update_prefix_afi_safi_cmd);
+       install_element(ENABLE_NODE, &no_debug_bgp_update_prefix_afi_safi_cmd);
+       install_element(CONFIG_NODE, &no_debug_bgp_update_prefix_afi_safi_cmd);
 
        /* debug bgp zebra prefix A.B.C.D/M */
        install_element(ENABLE_NODE, &debug_bgp_zebra_prefix_cmd);