diff options
60 files changed, 448 insertions, 139 deletions
diff --git a/babeld/babeld.c b/babeld/babeld.c index f61eac000f..0104620cd5 100644 --- a/babeld/babeld.c +++ b/babeld/babeld.c @@ -716,7 +716,7 @@ DEFUN (babel_set_smoothing_half_life, DEFUN (babel_distribute_list, babel_distribute_list_cmd, - "distribute-list [prefix] WORD <in|out> [WORD]", + "distribute-list [prefix] ACCESSLIST4_NAME <in|out> [WORD]", "Filter networks in routing updates\n" "Specify a prefix\n" "Access-list name\n" @@ -736,7 +736,7 @@ DEFUN (babel_distribute_list, DEFUN (babel_no_distribute_list, babel_no_distribute_list_cmd, - "no distribute-list [prefix] WORD <in|out> [WORD]", + "no distribute-list [prefix] ACCESSLIST4_NAME <in|out> [WORD]", NO_STR "Filter networks in routing updates\n" "Specify a prefix\n" @@ -758,7 +758,7 @@ DEFUN (babel_no_distribute_list, DEFUN (babel_ipv6_distribute_list, babel_ipv6_distribute_list_cmd, - "ipv6 distribute-list [prefix] WORD <in|out> [WORD]", + "ipv6 distribute-list [prefix] ACCESSLIST6_NAME <in|out> [WORD]", "IPv6\n" "Filter networks in routing updates\n" "Specify a prefix\n" @@ -779,7 +779,7 @@ DEFUN (babel_ipv6_distribute_list, DEFUN (babel_no_ipv6_distribute_list, babel_no_ipv6_distribute_list_cmd, - "no ipv6 distribute-list [prefix] WORD <in|out> [WORD]", + "no ipv6 distribute-list [prefix] ACCESSLIST6_NAME <in|out> [WORD]", NO_STR "IPv6\n" "Filter networks in routing updates\n" diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c index 3c67017dc7..d3424b2957 100644 --- a/bgpd/bgp_aspath.c +++ b/bgpd/bgp_aspath.c @@ -1002,8 +1002,6 @@ uint8_t *aspath_snmp_pathseg(struct aspath *as, size_t *varlen) return stream_pnt(snmp_stream); } -#define min(A,B) ((A) < (B) ? (A) : (B)) - static struct assegment *aspath_aggregate_as_set_add(struct aspath *aspath, struct assegment *asset, as_t as) @@ -1060,7 +1058,7 @@ struct aspath *aspath_aggregate(struct aspath *as1, struct aspath *as2) break; /* Minimum segment length. */ - minlen = min(seg1->length, seg2->length); + minlen = MIN(seg1->length, seg2->length); for (match = 0; match < minlen; match++) if (seg1->as[match] != seg2->as[match]) diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 28dd19d842..a33e9800e6 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -1298,12 +1298,11 @@ static void bgp_l3nhg_zebra_init(void) } -#define min(A, B) ((A) < (B) ? (A) : (B)) void bgp_l3nhg_init(void) { uint32_t id_max; - id_max = min(ZEBRA_NHG_PROTO_SPACING - 1, 16 * 1024); + id_max = MIN(ZEBRA_NHG_PROTO_SPACING - 1, 16 * 1024); bf_init(bgp_nh_id_bitmap, id_max); bf_assign_zero_index(bgp_nh_id_bitmap); diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 3fc478bc97..aa59499b04 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -4004,7 +4004,7 @@ static void bgp_route_map_event(const char *rmap_name) DEFUN_YANG (match_mac_address, match_mac_address_cmd, - "match mac address WORD", + "match mac address ACCESSLIST_MAC_NAME", MATCH_STR "mac address\n" "Match address of route\n" @@ -4024,7 +4024,7 @@ DEFUN_YANG (match_mac_address, DEFUN_YANG (no_match_mac_address, no_match_mac_address_cmd, - "no match mac address WORD", + "no match mac address ACCESSLIST_MAC_NAME", NO_STR MATCH_STR "mac\n" @@ -4576,7 +4576,7 @@ DEFUN_YANG (no_match_probability, DEFPY_YANG (match_ip_route_source, match_ip_route_source_cmd, - "match ip route-source WORD", + "match ip route-source ACCESSLIST4_NAME", MATCH_STR IP_STR "Match advertising source address of route\n" @@ -4600,7 +4600,7 @@ DEFPY_YANG (match_ip_route_source, DEFUN_YANG (no_match_ip_route_source, no_match_ip_route_source_cmd, - "no match ip route-source [WORD]", + "no match ip route-source [ACCESSLIST4_NAME]", NO_STR MATCH_STR IP_STR diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c index 96febcd5df..e43ae5c13f 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -553,7 +553,7 @@ void bgp_adj_out_set_subgroup(struct bgp_dest *dest, bgp_adv_fifo_add_tail(&subgrp->sync->update, adv); - subgrp->version = max(subgrp->version, dest->version); + subgrp->version = MAX(subgrp->version, dest->version); } /* The only time 'withdraw' will be false is if we are sending @@ -609,7 +609,7 @@ void bgp_adj_out_unset_subgroup(struct bgp_dest *dest, } } - subgrp->version = max(subgrp->version, dest->version); + subgrp->version = MAX(subgrp->version, dest->version); } void bgp_adj_out_remove_subgroup(struct bgp_dest *dest, struct bgp_adj_out *adj, @@ -721,7 +721,7 @@ void subgroup_announce_table(struct update_subgroup *subgrp, * covers the pathological case where all routes in the table have * now been deleted. */ - subgrp->version = max(subgrp->version, table->version); + subgrp->version = MAX(subgrp->version, table->version); /* * Start a task to merge the subgroup if necessary. diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 65806bb5f4..3725f242e1 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -7048,7 +7048,7 @@ DEFUN (no_neighbor_interface, DEFUN (neighbor_distribute_list, neighbor_distribute_list_cmd, - "neighbor <A.B.C.D|X:X::X:X|WORD> distribute-list WORD <in|out>", + "neighbor <A.B.C.D|X:X::X:X|WORD> distribute-list ACCESSLIST_NAME <in|out>", NEIGHBOR_STR NEIGHBOR_ADDR_STR2 "Filter updates to/from this neighbor\n" @@ -7079,7 +7079,7 @@ DEFUN (neighbor_distribute_list, ALIAS_HIDDEN( neighbor_distribute_list, neighbor_distribute_list_hidden_cmd, - "neighbor <A.B.C.D|X:X::X:X|WORD> distribute-list WORD <in|out>", + "neighbor <A.B.C.D|X:X::X:X|WORD> distribute-list ACCESSLIST_NAME <in|out>", NEIGHBOR_STR NEIGHBOR_ADDR_STR2 "Filter updates to/from this neighbor\n" "IP Access-list name\n" @@ -7088,7 +7088,7 @@ ALIAS_HIDDEN( DEFUN (no_neighbor_distribute_list, no_neighbor_distribute_list_cmd, - "no neighbor <A.B.C.D|X:X::X:X|WORD> distribute-list WORD <in|out>", + "no neighbor <A.B.C.D|X:X::X:X|WORD> distribute-list ACCESSLIST_NAME <in|out>", NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2 @@ -7118,7 +7118,7 @@ DEFUN (no_neighbor_distribute_list, ALIAS_HIDDEN( no_neighbor_distribute_list, no_neighbor_distribute_list_hidden_cmd, - "no neighbor <A.B.C.D|X:X::X:X|WORD> distribute-list WORD <in|out>", + "no neighbor <A.B.C.D|X:X::X:X|WORD> distribute-list ACCESSLIST_NAME <in|out>", NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2 "Filter updates to/from this neighbor\n" "IP Access-list name\n" diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index e60acecfae..29775bccce 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -81,13 +81,6 @@ typedef uint32_t as_t; typedef uint16_t as16_t; /* we may still encounter 16 Bit asnums */ typedef uint16_t bgp_size_t; -#define max(a, b) \ - ({ \ - __typeof__(a) _a = (a); \ - __typeof__(b) _b = (b); \ - _a > _b ? _a : _b; \ - }) - enum bgp_af_index { BGP_AF_START, BGP_AF_IPV4_UNICAST = BGP_AF_START, diff --git a/doc/developer/building-frr-for-archlinux.rst b/doc/developer/building-frr-for-archlinux.rst index af1677e89e..406d22d618 100644 --- a/doc/developer/building-frr-for-archlinux.rst +++ b/doc/developer/building-frr-for-archlinux.rst @@ -11,7 +11,9 @@ Installing Dependencies git autoconf automake libtool make cmake pcre readline texinfo \ pkg-config pam json-c bison flex python-pytest \ c-ares python python2-ipaddress python-sphinx \ - net-snmp perl libcap libelf + net-snmp perl libcap libelf libunwind + +.. include:: building-libunwind-note.rst .. include:: building-libyang.rst diff --git a/doc/developer/building-frr-for-centos7.rst b/doc/developer/building-frr-for-centos7.rst index ce11126f70..c40b5de594 100644 --- a/doc/developer/building-frr-for-centos7.rst +++ b/doc/developer/building-frr-for-centos7.rst @@ -22,7 +22,9 @@ Add packages: readline-devel texinfo net-snmp-devel groff pkgconfig \ json-c-devel pam-devel bison flex pytest c-ares-devel \ python-devel python-sphinx libcap-devel \ - elfutils-libelf-devel + elfutils-libelf-devel libunwind-devel + +.. include:: building-libunwind-note.rst .. include:: building-libyang.rst diff --git a/doc/developer/building-frr-for-centos8.rst b/doc/developer/building-frr-for-centos8.rst index 109a7866d9..659752f6df 100644 --- a/doc/developer/building-frr-for-centos8.rst +++ b/doc/developer/building-frr-for-centos8.rst @@ -15,7 +15,9 @@ Add packages: automake libtool make readline-devel texinfo net-snmp-devel pkgconfig \ groff pkgconfig json-c-devel pam-devel bison flex python2-pytest \ c-ares-devel python2-devel libcap-devel \ - elfutils-libelf-devel + elfutils-libelf-devel libunwind-devel + +.. include:: building-libunwind-note.rst .. include:: building-libyang.rst diff --git a/doc/developer/building-frr-for-debian9.rst b/doc/developer/building-frr-for-debian9.rst index f8d8025f62..b2fdef9990 100644 --- a/doc/developer/building-frr-for-debian9.rst +++ b/doc/developer/building-frr-for-debian9.rst @@ -11,7 +11,9 @@ Add packages: sudo apt-get install git autoconf automake libtool make \ libreadline-dev texinfo libjson-c-dev pkg-config bison flex \ libc-ares-dev python3-dev python3-pytest python3-sphinx build-essential \ - libsnmp-dev libcap-dev libelf-dev + libsnmp-dev libcap-dev libelf-dev libunwind-dev + +.. include:: building-libunwind-note.rst .. include:: building-libyang.rst diff --git a/doc/developer/building-frr-for-fedora.rst b/doc/developer/building-frr-for-fedora.rst index 6ce76ba158..dc869ece10 100644 --- a/doc/developer/building-frr-for-fedora.rst +++ b/doc/developer/building-frr-for-fedora.rst @@ -15,7 +15,9 @@ Installing Dependencies readline-devel texinfo net-snmp-devel groff pkgconfig json-c-devel \ pam-devel python3-pytest bison flex c-ares-devel python3-devel \ python3-sphinx perl-core patch libcap-devel \ - elfutils-libelf-devel + elfutils-libelf-devel libunwind-devel + +.. include:: building-libunwind-note.rst .. include:: building-libyang.rst diff --git a/doc/developer/building-frr-for-freebsd10.rst b/doc/developer/building-frr-for-freebsd10.rst index e85cb80053..5e70b81d43 100644 --- a/doc/developer/building-frr-for-freebsd10.rst +++ b/doc/developer/building-frr-for-freebsd10.rst @@ -17,7 +17,9 @@ is first package install and asked) :: pkg install git autoconf automake libtool gmake json-c pkgconf \ - bison flex py36-pytest c-ares python3.6 py36-sphinx + bison flex py36-pytest c-ares python3.6 py36-sphinx libunwind + +.. include:: building-libunwind-note.rst Make sure there is no /usr/bin/flex preinstalled (and use the newly installed in /usr/local/bin): (FreeBSD frequently provides a older flex diff --git a/doc/developer/building-frr-for-freebsd11.rst b/doc/developer/building-frr-for-freebsd11.rst index b97538b763..808207b831 100644 --- a/doc/developer/building-frr-for-freebsd11.rst +++ b/doc/developer/building-frr-for-freebsd11.rst @@ -17,7 +17,9 @@ is first package install and asked) .. code-block:: shell pkg install git autoconf automake libtool gmake json-c pkgconf \ - bison flex py36-pytest c-ares python3.6 py36-sphinx texinfo + bison flex py36-pytest c-ares python3.6 py36-sphinx texinfo libunwind + +.. include:: building-libunwind-note.rst Make sure there is no /usr/bin/flex preinstalled (and use the newly installed in /usr/local/bin): (FreeBSD frequently provides a older flex diff --git a/doc/developer/building-frr-for-opensuse.rst b/doc/developer/building-frr-for-opensuse.rst index ee6a36a14b..d9800a1638 100644 --- a/doc/developer/building-frr-for-opensuse.rst +++ b/doc/developer/building-frr-for-opensuse.rst @@ -14,7 +14,9 @@ Installing Dependencies readline-devel texinfo net-snmp-devel groff pkgconfig libjson-c-devel\ pam-devel python3-pytest bison flex c-ares-devel python3-devel\ python3-Sphinx perl patch libcap-devel libyang-devel \ - libelf-devel + libelf-devel libunwind-devel + +.. include:: building-libunwind-note.rst Building & Installing FRR ------------------------- diff --git a/doc/developer/building-frr-for-ubuntu1804.rst b/doc/developer/building-frr-for-ubuntu1804.rst index 3e8c6c0d0b..fcfd94ec2c 100644 --- a/doc/developer/building-frr-for-ubuntu1804.rst +++ b/doc/developer/building-frr-for-ubuntu1804.rst @@ -15,7 +15,9 @@ Installing Dependencies pkg-config libpam0g-dev libjson-c-dev bison flex \ libc-ares-dev python3-dev python3-sphinx \ install-info build-essential libsnmp-dev perl libcap-dev \ - libelf-dev + libelf-dev libunwind-dev + +.. include:: building-libunwind-note.rst .. include:: building-libyang.rst diff --git a/doc/developer/building-frr-for-ubuntu2004.rst b/doc/developer/building-frr-for-ubuntu2004.rst index 28e7ca6518..fdfc25da9d 100644 --- a/doc/developer/building-frr-for-ubuntu2004.rst +++ b/doc/developer/building-frr-for-ubuntu2004.rst @@ -15,7 +15,9 @@ Installing Dependencies pkg-config libpam0g-dev libjson-c-dev bison flex \ libc-ares-dev python3-dev python3-sphinx \ install-info build-essential libsnmp-dev perl \ - libcap-dev python2 libelf-dev + libcap-dev python2 libelf-dev libunwind-dev + +.. include:: building-libunwind-note.rst Note that Ubuntu 20 no longer installs python 2.x, so it must be installed explicitly. Ensure that your system has a symlink named diff --git a/doc/developer/building-libunwind-note.rst b/doc/developer/building-libunwind-note.rst new file mode 100644 index 0000000000..0beb1f8d37 --- /dev/null +++ b/doc/developer/building-libunwind-note.rst @@ -0,0 +1,6 @@ +.. note:: + + The ``libunwind`` library is optional but highly recommended, as it improves + backtraces printed for crashes and debugging. However, if it is not + available for some reason, it can simply be left out without any loss of + functionality. diff --git a/doc/developer/conf.py b/doc/developer/conf.py index 61df6e0e60..79f8233978 100644 --- a/doc/developer/conf.py +++ b/doc/developer/conf.py @@ -136,6 +136,7 @@ language = None # directories to ignore when looking for source files. exclude_patterns = [ "_build", + "building-libunwind-note.rst", "building-libyang.rst", "topotests-snippets.rst", "topotests-markers.rst", diff --git a/doc/developer/subdir.am b/doc/developer/subdir.am index d16420c7e7..c8654d6725 100644 --- a/doc/developer/subdir.am +++ b/doc/developer/subdir.am @@ -23,6 +23,7 @@ dev_RSTFILES = \ doc/developer/building-frr-for-ubuntu1604.rst \ doc/developer/building-frr-for-ubuntu1804.rst \ doc/developer/building-frr-for-ubuntu2004.rst \ + doc/developer/building-libunwind-note.rst \ doc/developer/building-libyang.rst \ doc/developer/building.rst \ doc/developer/cli.rst \ diff --git a/doc/user/basic.rst b/doc/user/basic.rst index 16708adb50..69f276d551 100644 --- a/doc/user/basic.rst +++ b/doc/user/basic.rst @@ -244,6 +244,42 @@ Basic Config Commands Use unbuffered output for log and debug messages; normally there is some internal buffering. +.. clicmd:: log unique-id + + Include ``[XXXXX-XXXXX]`` log message unique identifier in the textual part + of log messages. This is enabled by default, but can be disabled with + ``no log unique-id``. Please make sure the IDs are enabled when including + logs for FRR bug reports. + + The unique identifiers are automatically generated based on source code + file name, format string (before filling out) and severity. They do not + change "randomly", but some cleanup work may cause large chunks of ID + changes between releases. The IDs always start with a letter, consist of + letters and numbers (and a dash for readability), are case insensitive, and + ``I``, ``L``, ``O`` & ``U`` are excluded. + + This option will not affect future logging targets which allow putting the + unique identifier in auxiliary metadata outside the log message text + content. (No such logging target exists currently, but RFC5424 syslog and + systemd's journald both support it.) + +.. clicmd:: debug unique-id XXXXX-XXXXX backtrace + + Print backtraces (call stack) for specific log messages, identified by + their unique ID (see above.) Includes source code location and current + event handler being executed. On some systems you may need to install a + `debug symbols` package to get proper function names rather than raw code + pointers. + + This command can be issued inside and outside configuration mode, and is + saved to configuration only if it was given in configuration mode. + + .. warning:: + + Printing backtraces can significantly slow down logging calls and cause + log files to quickly balloon in size. Remember to disable backtraces + when they're no longer needed. + .. clicmd:: service password-encryption Encrypt password. diff --git a/eigrpd/eigrp_routemap.c b/eigrpd/eigrp_routemap.c index 65fa95b652..d9b500a8fd 100644 --- a/eigrpd/eigrp_routemap.c +++ b/eigrpd/eigrp_routemap.c @@ -858,7 +858,7 @@ ALIAS(no_match_interface, no_match_interface_val_cmd, "no match interface WORD", DEFUN (match_ip_next_hop, match_ip_next_hop_cmd, - "match ip next-hop WORD", + "match ip next-hop ACCESSLIST4_NAME", MATCH_STR IP_STR "Match next-hop address of route\n" @@ -884,7 +884,7 @@ DEFUN (no_match_ip_next_hop, } ALIAS(no_match_ip_next_hop, no_match_ip_next_hop_val_cmd, - "no match ip next-hop WORD", NO_STR MATCH_STR IP_STR + "no match ip next-hop ACCESSLIST4_NAME", NO_STR MATCH_STR IP_STR "Match next-hop address of route\n" "IP Access-list name\n") @@ -927,7 +927,7 @@ ALIAS(no_match_ip_next_hop_prefix_list, DEFUN (match_ip_address, match_ip_address_cmd, - "match ip address WORD", + "match ip address ACCESSLIST4_NAME", MATCH_STR IP_STR "Match address of route\n" @@ -952,7 +952,7 @@ DEFUN (no_match_ip_address, } ALIAS(no_match_ip_address, no_match_ip_address_val_cmd, - "no match ip address WORD", NO_STR MATCH_STR IP_STR + "no match ip address ACCESSLIST4_NAME", NO_STR MATCH_STR IP_STR "Match address of route\n" "IP Access-list name\n") @@ -1124,7 +1124,7 @@ ALIAS(no_set_tag, no_set_tag_val_cmd, "no set tag (0-65535)", NO_STR SET_STR DEFUN (eigrp_distribute_list, eigrp_distribute_list_cmd, - "distribute-list [prefix] WORD <in|out> [WORD]", + "distribute-list [prefix] ACCESSLIST_NAME <in|out> [WORD]", "Filter networks in routing updates\n" "Specify a prefix\n" "Access-list name\n" @@ -1144,7 +1144,7 @@ DEFUN (eigrp_distribute_list, DEFUN (eigrp_no_distribute_list, eigrp_no_distribute_list_cmd, - "no distribute-list [prefix] WORD <in|out> [WORD]", + "no distribute-list [prefix] ACCESSLIST_NAME <in|out> [WORD]", NO_STR "Filter networks in routing updates\n" "Specify a prefix\n" diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c index b543c2d3ec..bf03d0a050 100644 --- a/isisd/isis_cli.c +++ b/isisd/isis_cli.c @@ -1011,7 +1011,7 @@ void cli_show_isis_spf_ietf_backoff(struct vty *vty, * XPath: /frr-isisd:isis/instance/spf/prefix-priorities/medium/access-list-name */ DEFPY_YANG(spf_prefix_priority, spf_prefix_priority_cmd, - "spf prefix-priority <critical|high|medium>$priority WORD$acl_name", + "spf prefix-priority <critical|high|medium>$priority ACCESSLIST_NAME$acl_name", "SPF configuration\n" "Configure a prefix priority list\n" "Specify critical priority prefixes\n" @@ -1029,7 +1029,7 @@ DEFPY_YANG(spf_prefix_priority, spf_prefix_priority_cmd, } DEFPY_YANG(no_spf_prefix_priority, no_spf_prefix_priority_cmd, - "no spf prefix-priority <critical|high|medium>$priority [WORD]", + "no spf prefix-priority <critical|high|medium>$priority [ACCESSLIST_NAME]", NO_STR "SPF configuration\n" "Configure a prefix priority list\n" diff --git a/ldpd/hello.c b/ldpd/hello.c index 5aa14ed067..629fe46e70 100644 --- a/ldpd/hello.c +++ b/ldpd/hello.c @@ -415,13 +415,13 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af, if (holdtime == 0) holdtime = LINK_DFLT_HOLDTIME; - adj->holdtime = min(if_get_hello_holdtime(ia), holdtime); + adj->holdtime = MIN(if_get_hello_holdtime(ia), holdtime); break; case HELLO_TARGETED: if (holdtime == 0) holdtime = TARGETED_DFLT_HOLDTIME; - adj->holdtime = min(tnbr_get_hello_holdtime(tnbr), holdtime); + adj->holdtime = MIN(tnbr_get_hello_holdtime(tnbr), holdtime); } if (adj->holdtime != INFINITE_HOLDTIME) adj_start_itimer(adj); diff --git a/ldpd/init.c b/ldpd/init.c index d394fb08ea..0ee64c16fa 100644 --- a/ldpd/init.c +++ b/ldpd/init.c @@ -197,7 +197,7 @@ recv_init(struct nbr *nbr, char *buf, uint16_t len) len -= tlv_len; } - nbr->keepalive = min(nbr_get_keepalive(nbr->af, nbr->id), + nbr->keepalive = MIN(nbr_get_keepalive(nbr->af, nbr->id), ntohs(sess.keepalive_time)); max_pdu_len = ntohs(sess.max_pdu_len); @@ -208,7 +208,7 @@ recv_init(struct nbr *nbr, char *buf, uint16_t len) */ if (max_pdu_len <= 255) max_pdu_len = LDP_MAX_LEN; - nbr->max_pdu_len = min(max_pdu_len, LDP_MAX_LEN); + nbr->max_pdu_len = MIN(max_pdu_len, LDP_MAX_LEN); nbr_fsm(nbr, NBR_EVT_INIT_RCVD); diff --git a/ldpd/ldp_vty_cmds.c b/ldpd/ldp_vty_cmds.c index 9d3d1a606e..11d6930f06 100644 --- a/ldpd/ldp_vty_cmds.c +++ b/ldpd/ldp_vty_cmds.c @@ -253,7 +253,7 @@ DEFPY (ldp_allow_broken_lsps, DEFPY (ldp_discovery_targeted_hello_accept, ldp_discovery_targeted_hello_accept_cmd, - "[no] discovery targeted-hello accept [from WORD$from_acl]", + "[no] discovery targeted-hello accept [from ACCESSLIST_NAME$from_acl]", NO_STR "Configure discovery parameters\n" "LDP Targeted Hellos\n" @@ -288,7 +288,7 @@ DEFPY (ldp_discovery_transport_address_ipv6, DEFPY (ldp_label_local_advertise, ldp_label_local_advertise_cmd, - "[no] label local advertise [{to WORD$to_acl|for WORD$for_acl}]", + "[no] label local advertise [{to ACCESSLIST_NAME$to_acl|for ACCESSLIST_NAME$for_acl}]", NO_STR "Configure label control and policies\n" "Configure local label control and policies\n" @@ -303,7 +303,7 @@ DEFPY (ldp_label_local_advertise, DEFPY (ldp_label_local_advertise_explicit_null, ldp_label_local_advertise_explicit_null_cmd, - "[no] label local advertise explicit-null [for WORD$for_acl]", + "[no] label local advertise explicit-null [for ACCESSLIST_NAME$for_acl]", NO_STR "Configure label control and policies\n" "Configure local label control and policies\n" @@ -317,7 +317,7 @@ DEFPY (ldp_label_local_advertise_explicit_null, DEFPY (ldp_label_local_allocate, ldp_label_local_allocate_cmd, - "[no] label local allocate <host-routes$host_routes|for WORD$for_acl>", + "[no] label local allocate <host-routes$host_routes|for ACCESSLIST_NAME$for_acl>", NO_STR "Configure label control and policies\n" "Configure local label control and policies\n" @@ -331,7 +331,7 @@ DEFPY (ldp_label_local_allocate, DEFPY (ldp_label_remote_accept, ldp_label_remote_accept_cmd, - "[no] label remote accept {from WORD$from_acl|for WORD$for_acl}", + "[no] label remote accept {from ACCESSLIST_NAME$from_acl|for ACCESSLIST_NAME$for_acl}", NO_STR "Configure label control and policies\n" "Configure remote/peer label control and policies\n" diff --git a/ldpd/ldpe.h b/ldpd/ldpe.h index 880722424e..0f650a86d3 100644 --- a/ldpd/ldpe.h +++ b/ldpd/ldpe.h @@ -30,9 +30,6 @@ #include "ldpd.h" #include "lib/ldp_sync.h" -#define min(x,y) ((x) <= (y) ? (x) : (y)) -#define max(x,y) ((x) > (y) ? (x) : (y)) - /* forward declarations */ TAILQ_HEAD(mapping_head, mapping_entry); diff --git a/lib/atomlist.c b/lib/atomlist.c index 3668b083d0..b7c9516a00 100644 --- a/lib/atomlist.c +++ b/lib/atomlist.c @@ -18,6 +18,8 @@ #include "config.h" #endif +#include <assert.h> + #include "atomlist.h" void atomlist_add_head(struct atomlist_head *h, struct atomlist_item *item) diff --git a/lib/elf_py.c b/lib/elf_py.c index 1c306893ad..f230add695 100644 --- a/lib/elf_py.c +++ b/lib/elf_py.c @@ -636,6 +636,9 @@ static Elf_Scn *elf_find_addr(struct elffile *ef, uint64_t addr, size_t *idx) Elf_Scn *scn = elf_getscn(ef->elf, i); GElf_Shdr _shdr, *shdr = gelf_getshdr(scn, &_shdr); + /* virtual address is kinda meaningless for TLS sections */ + if (shdr->sh_flags & SHF_TLS) + continue; if (addr < shdr->sh_addr || addr >= shdr->sh_addr + shdr->sh_size) continue; diff --git a/lib/filter.c b/lib/filter.c index 3a86fbce93..9c80808fe8 100644 --- a/lib/filter.c +++ b/lib/filter.c @@ -612,7 +612,7 @@ DEFUN (show_mac_access_list, DEFUN (show_mac_access_list_name, show_mac_access_list_name_cmd, - "show mac access-list WORD", + "show mac access-list ACCESSLIST_MAC_NAME", SHOW_STR "mac access lists\n" "List mac access lists\n" @@ -635,7 +635,7 @@ DEFUN (show_ip_access_list, DEFUN (show_ip_access_list_name, show_ip_access_list_name_cmd, - "show ip access-list WORD [json]", + "show ip access-list ACCESSLIST4_NAME [json]", SHOW_STR IP_STR "List IP access lists\n" @@ -661,7 +661,7 @@ DEFUN (show_ipv6_access_list, DEFUN (show_ipv6_access_list_name, show_ipv6_access_list_name_cmd, - "show ipv6 access-list WORD [json]", + "show ipv6 access-list ACCESSLIST6_NAME [json]", SHOW_STR IPV6_STR "List IPv6 access lists\n" @@ -839,12 +839,62 @@ static void access_list_init_ipv4(void) install_element(ENABLE_NODE, &show_ip_access_list_name_cmd); } +static void access_list_autocomplete_afi(afi_t afi, vector comps, + struct cmd_token *token) +{ + struct access_list *access; + struct access_list *next; + struct access_master *master; + + master = access_master_get(afi); + if (master == NULL) + return; + + for (access = master->str.head; access; access = next) { + next = access->next; + vector_set(comps, XSTRDUP(MTYPE_COMPLETION, access->name)); + } +} + static struct cmd_node access_ipv6_node = { .name = "ipv6 access list", .node = ACCESS_IPV6_NODE, .prompt = "", }; +static void access_list_autocomplete(vector comps, struct cmd_token *token) +{ + access_list_autocomplete_afi(AFI_IP, comps, token); + access_list_autocomplete_afi(AFI_IP6, comps, token); + access_list_autocomplete_afi(AFI_L2VPN, comps, token); +} + +static void access_list4_autocomplete(vector comps, struct cmd_token *token) +{ + access_list_autocomplete_afi(AFI_IP, comps, token); +} + +static void access_list6_autocomplete(vector comps, struct cmd_token *token) +{ + access_list_autocomplete_afi(AFI_IP6, comps, token); +} + +static void access_list_mac_autocomplete(vector comps, struct cmd_token *token) +{ + access_list_autocomplete_afi(AFI_L2VPN, comps, token); +} + +static const struct cmd_variable_handler access_list_handlers[] = { + {.tokenname = "ACCESSLIST_NAME", + .completions = access_list_autocomplete}, + {.tokenname = "ACCESSLIST4_NAME", + .completions = access_list4_autocomplete}, + {.tokenname = "ACCESSLIST6_NAME", + .completions = access_list6_autocomplete}, + {.tokenname = "ACCESSLIST_MAC_NAME", + .completions = access_list_mac_autocomplete}, + {.completions = NULL}}; + static void access_list_reset_ipv6(void) { struct access_list *access; @@ -874,6 +924,8 @@ static void access_list_init_ipv6(void) void access_list_init(void) { + cmd_variable_handler_register(access_list_handlers); + access_list_init_ipv4(); access_list_init_ipv6(); access_list_init_mac(); diff --git a/lib/filter_cli.c b/lib/filter_cli.c index 43618094ac..fb40c527dd 100644 --- a/lib/filter_cli.c +++ b/lib/filter_cli.c @@ -822,7 +822,7 @@ DEFPY_YANG( ALIAS( no_ipv6_access_list_remark, no_ipv6_access_list_remark_line_cmd, - "no ipv6 access-list WORD$name remark LINE...", + "no ipv6 access-list ACCESSLIST6_NAME$name remark LINE...", NO_STR IPV6_STR ACCESS_LIST_STR @@ -832,7 +832,7 @@ ALIAS( DEFPY_YANG( mac_access_list, mac_access_list_cmd, - "mac access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <X:X:X:X:X:X$mac|any>", + "mac access-list ACCESSLIST_MAC_NAME$name [seq (1-4294967295)$seq] <deny|permit>$action <X:X:X:X:X:X$mac|any>", MAC_STR ACCESS_LIST_STR ACCESS_LIST_ZEBRA_STR @@ -898,7 +898,7 @@ DEFPY_YANG( DEFPY_YANG( no_mac_access_list, no_mac_access_list_cmd, - "no mac access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <X:X:X:X:X:X$mac|any>", + "no mac access-list ACCESSLIST_MAC_NAME$name [seq (1-4294967295)$seq] <deny|permit>$action <X:X:X:X:X:X$mac|any>", NO_STR MAC_STR ACCESS_LIST_STR @@ -938,7 +938,7 @@ DEFPY_YANG( DEFPY_YANG( no_mac_access_list_all, no_mac_access_list_all_cmd, - "no mac access-list WORD$name", + "no mac access-list ACCESSLIST_MAC_NAME$name", NO_STR MAC_STR ACCESS_LIST_STR @@ -955,7 +955,7 @@ DEFPY_YANG( DEFPY_YANG( mac_access_list_remark, mac_access_list_remark_cmd, - "mac access-list WORD$name remark LINE...", + "mac access-list ACCESSLIST_MAC_NAME$name remark LINE...", MAC_STR ACCESS_LIST_STR ACCESS_LIST_ZEBRA_STR @@ -980,7 +980,7 @@ DEFPY_YANG( DEFPY_YANG( no_mac_access_list_remark, no_mac_access_list_remark_cmd, - "no mac access-list WORD$name remark", + "no mac access-list ACCESSLIST_MAC_NAME$name remark", NO_STR MAC_STR ACCESS_LIST_STR @@ -1004,7 +1004,7 @@ DEFPY_YANG( ALIAS( no_mac_access_list_remark, no_mac_access_list_remark_line_cmd, - "no mac access-list WORD$name remark LINE...", + "no mac access-list ACCESSLIST_MAC_NAME$name remark LINE...", NO_STR MAC_STR ACCESS_LIST_STR diff --git a/lib/frrcu.h b/lib/frrcu.h index 3808259040..ae840926b5 100644 --- a/lib/frrcu.h +++ b/lib/frrcu.h @@ -17,6 +17,8 @@ #ifndef _FRRCU_H #define _FRRCU_H +#include <assert.h> + #include "memory.h" #include "atomlist.h" @@ -303,9 +303,6 @@ void if_delete(struct interface **ifp) if (ptr->ifindex != IFINDEX_INTERNAL) IFINDEX_RB_REMOVE(vrf, ptr); - if (!vrf_is_enabled(vrf)) - vrf_delete(vrf); - if_delete_retain(ptr); list_delete(&ptr->connected); @@ -1420,7 +1417,7 @@ static int lib_interface_create(struct nb_cb_create_args *args) static int lib_interface_destroy(struct nb_cb_destroy_args *args) { struct interface *ifp; - + struct vrf *vrf; switch (args->event) { case NB_EV_VALIDATE: @@ -1436,9 +1433,13 @@ static int lib_interface_destroy(struct nb_cb_destroy_args *args) break; case NB_EV_APPLY: ifp = nb_running_unset_entry(args->dnode); + vrf = ifp->vrf; ifp->configured = false; if_delete(&ifp); + + if (!vrf_is_enabled(vrf)) + vrf_delete(vrf); break; } diff --git a/lib/log_vty.c b/lib/log_vty.c index cbb8de8976..9911323553 100644 --- a/lib/log_vty.c +++ b/lib/log_vty.c @@ -36,6 +36,8 @@ DEFINE_HOOK(zlog_rotate, (), ()); DEFINE_HOOK(zlog_cli_show, (struct vty * vty), (vty)); +static unsigned logmsgs_with_persist_bt; + static const int log_default_lvl = LOG_DEBUG; static int log_config_stdout_lvl = ZLOG_DISABLED; @@ -267,6 +269,44 @@ DEFUN_HIDDEN (no_config_log_monitor, return CMD_SUCCESS; } +DEFPY (debug_uid_backtrace, + debug_uid_backtrace_cmd, + "[no] debug unique-id UID backtrace", + NO_STR + DEBUG_STR + "Options per individual log message, by unique ID\n" + "Log message unique ID (XXXXX-XXXXX)\n" + "Add backtrace to log when message is printed\n") +{ + struct xrefdata search, *xrd; + struct xrefdata_logmsg *xrdl; + uint8_t flag; + + strlcpy(search.uid, uid, sizeof(search.uid)); + xrd = xrefdata_uid_find(&xrefdata_uid, &search); + + if (!xrd) { + vty_out(vty, "%% no log message with ID \"%s\" found\n", uid); + return CMD_WARNING; + } + if (xrd->xref->type != XREFT_LOGMSG) { + vty_out(vty, "%% ID \"%s\" is not a log message\n", uid); + return CMD_WARNING; + } + xrdl = container_of(xrd, struct xrefdata_logmsg, xrefdata); + + flag = (vty->node == CONFIG_NODE) ? LOGMSG_FLAG_PERSISTENT + : LOGMSG_FLAG_EPHEMERAL; + + if ((xrdl->fl_print_bt & flag) == (no ? 0 : flag)) + return CMD_SUCCESS; + if (flag == LOGMSG_FLAG_PERSISTENT) + logmsgs_with_persist_bt += no ? -1 : 1; + + xrdl->fl_print_bt ^= flag; + return CMD_SUCCESS; +} + static int set_log_file(struct zlog_cfg_file *target, struct vty *vty, const char *fname, int loglevel) { @@ -751,6 +791,24 @@ void log_config_write(struct vty *vty) vty_out(vty, "no log error-category\n"); if (!zlog_get_prefix_xid()) vty_out(vty, "no log unique-id\n"); + + if (logmsgs_with_persist_bt) { + struct xrefdata *xrd; + struct xrefdata_logmsg *xrdl; + + vty_out(vty, "!\n"); + + frr_each (xrefdata_uid, &xrefdata_uid, xrd) { + if (xrd->xref->type != XREFT_LOGMSG) + continue; + + xrdl = container_of(xrd, struct xrefdata_logmsg, + xrefdata); + if (xrdl->fl_print_bt & LOGMSG_FLAG_PERSISTENT) + vty_out(vty, "debug unique-id %s backtrace\n", + xrd->uid); + } + } } static int log_vty_init(const char *progname, const char *protoname, @@ -801,4 +859,7 @@ void log_cmd_init(void) install_element(CONFIG_NODE, &config_log_filterfile_cmd); install_element(CONFIG_NODE, &no_config_log_filterfile_cmd); install_element(CONFIG_NODE, &log_immediate_mode_cmd); + + install_element(ENABLE_NODE, &debug_uid_backtrace_cmd); + install_element(CONFIG_NODE, &debug_uid_backtrace_cmd); } diff --git a/lib/routemap_cli.c b/lib/routemap_cli.c index 918a2ebdcb..d7d4a9a81f 100644 --- a/lib/routemap_cli.c +++ b/lib/routemap_cli.c @@ -166,7 +166,7 @@ DEFPY_YANG( DEFPY_YANG( match_ip_address, match_ip_address_cmd, - "match ip address WORD$name", + "match ip address ACCESSLIST4_NAME$name", MATCH_STR IP_STR "Match address of route\n" @@ -186,7 +186,7 @@ DEFPY_YANG( DEFPY_YANG( no_match_ip_address, no_match_ip_address_cmd, - "no match ip address [WORD]", + "no match ip address [ACCESSLIST4_NAME]", NO_STR MATCH_STR IP_STR @@ -243,7 +243,7 @@ DEFPY_YANG( DEFPY_YANG( match_ip_next_hop, match_ip_next_hop_cmd, - "match ip next-hop WORD$name", + "match ip next-hop ACCESSLIST4_NAME$name", MATCH_STR IP_STR "Match next-hop address of route\n" @@ -263,7 +263,7 @@ DEFPY_YANG( DEFPY_YANG( no_match_ip_next_hop, no_match_ip_next_hop_cmd, - "no match ip next-hop [WORD]", + "no match ip next-hop [ACCESSLIST4_NAME]", NO_STR MATCH_STR IP_STR @@ -358,7 +358,7 @@ DEFPY_YANG( DEFPY_YANG( match_ipv6_address, match_ipv6_address_cmd, - "match ipv6 address WORD$name", + "match ipv6 address ACCESSLIST6_NAME$name", MATCH_STR IPV6_STR "Match IPv6 address of route\n" @@ -378,7 +378,7 @@ DEFPY_YANG( DEFPY_YANG( no_match_ipv6_address, no_match_ipv6_address_cmd, - "no match ipv6 address [WORD]", + "no match ipv6 address [ACCESSLIST6_NAME]", NO_STR MATCH_STR IPV6_STR diff --git a/lib/snmp.c b/lib/snmp.c index 23d3f38b31..8d8b3c950c 100644 --- a/lib/snmp.c +++ b/lib/snmp.c @@ -25,13 +25,11 @@ #include "smux.h" -#define min(A,B) ((A) < (B) ? (A) : (B)) - int oid_compare(const oid *o1, int o1_len, const oid *o2, int o2_len) { int i; - for (i = 0; i < min(o1_len, o2_len); i++) { + for (i = 0; i < MIN(o1_len, o2_len); i++) { if (o1[i] < o2[i]) return -1; else if (o1[i] > o2[i]) diff --git a/lib/typerb.h b/lib/typerb.h index d22d864aae..75a1de77b3 100644 --- a/lib/typerb.h +++ b/lib/typerb.h @@ -20,6 +20,7 @@ #ifndef _FRR_TYPERB_H #define _FRR_TYPERB_H +#include <string.h> #include "typesafe.h" #ifdef __cplusplus diff --git a/lib/typesafe.c b/lib/typesafe.c index f90b59daf0..3b65a2d02a 100644 --- a/lib/typesafe.c +++ b/lib/typesafe.c @@ -20,6 +20,7 @@ #include <stdlib.h> #include <string.h> +#include <assert.h> #include "typesafe.h" #include "memory.h" diff --git a/lib/typesafe.h b/lib/typesafe.h index 44c42ffbca..b284397d98 100644 --- a/lib/typesafe.h +++ b/lib/typesafe.h @@ -20,7 +20,6 @@ #include <stddef.h> #include <stdint.h> #include <stdbool.h> -#include <assert.h> #include "compiler.h" #ifdef __cplusplus @@ -539,13 +539,10 @@ void vrf_init(int (*create)(struct vrf *), int (*enable)(struct vrf *), static void vrf_terminate_single(struct vrf *vrf) { - int enabled = vrf_is_enabled(vrf); - /* Clear configured flag and invoke delete. */ UNSET_FLAG(vrf->status, VRF_CONFIGURED); if_terminate(vrf); - if (enabled) - vrf_delete(vrf); + vrf_delete(vrf); } /* Terminate VRF module. */ diff --git a/lib/xref.c b/lib/xref.c index a41f91a228..0d3549d062 100644 --- a/lib/xref.c +++ b/lib/xref.c @@ -35,6 +35,8 @@ struct xref_block *xref_blocks; static struct xref_block **xref_block_last = &xref_blocks; +struct xrefdata_uid_head xrefdata_uid = INIT_RBTREE_UNIQ(xrefdata_uid); + static void base32(uint8_t **inpos, int *bitpos, char *out, size_t n_chars) { @@ -109,6 +111,8 @@ static void xref_add_one(const struct xref *xref) base32(&h, &bitpos, &xrefdata->uid[0], 5); xrefdata->uid[5] = '-'; base32(&h, &bitpos, &xrefdata->uid[6], 5); + + xrefdata_uid_add(&xrefdata_uid, xrefdata); } void xref_gcc_workaround(const struct xref *xref) diff --git a/lib/xref.h b/lib/xref.h index 6cff1a3769..0e3f00f690 100644 --- a/lib/xref.h +++ b/lib/xref.h @@ -22,6 +22,7 @@ #include <limits.h> #include <errno.h> #include "compiler.h" +#include "typesafe.h" #ifdef __cplusplus extern "C" { @@ -63,6 +64,8 @@ struct xref { /* type-specific bits appended by embedding this struct */ }; +PREDECL_RBTREE_UNIQ(xrefdata_uid); + struct xrefdata { /* pointer back to the const part; this will be initialized at * program startup by xref_block_add(). (Creating structs with @@ -88,8 +91,18 @@ struct xrefdata { uint32_t hashu32[2]; /* -- 32 bytes (on 64bit) -- */ + struct xrefdata_uid_item xui; }; +static inline int xrefdata_uid_cmp(const struct xrefdata *a, + const struct xrefdata *b) +{ + return strcmp(a->uid, b->uid); +} + +DECLARE_RBTREE_UNIQ(xrefdata_uid, struct xrefdata, xui, xrefdata_uid_cmp); +extern struct xrefdata_uid_head xrefdata_uid; + /* linker "magic" is used to create an array of pointers to struct xref. * the result is a contiguous block of pointers, each pointing to an xref * somewhere in the code. The linker gives us start and end pointers, we diff --git a/lib/zlog.c b/lib/zlog.c index 6fd52cae62..1b0751559d 100644 --- a/lib/zlog.c +++ b/lib/zlog.c @@ -47,12 +47,19 @@ #include <mach/mach_traps.h> #endif +#ifdef HAVE_LIBUNWIND +#define UNW_LOCAL_ONLY +#include <libunwind.h> +#include <dlfcn.h> +#endif + #include "memory.h" #include "atomlist.h" #include "printfrr.h" #include "frrcu.h" #include "zlog.h" #include "libfrr_trace.h" +#include "thread.h" DEFINE_MTYPE_STATIC(LIB, LOG_MESSAGE, "log message"); DEFINE_MTYPE_STATIC(LIB, LOG_TLSBUF, "log thread-local buffer"); @@ -508,6 +515,87 @@ static void vzlog_tls(struct zlog_tls *zlog_tls, const struct xref_logmsg *xref, XFREE(MTYPE_LOG_MESSAGE, msg->text); } +static void zlog_backtrace_msg(const struct xref_logmsg *xref, int prio) +{ + struct thread *tc = pthread_getspecific(thread_current); + const char *uid = xref->xref.xrefdata->uid; + bool found_thread = false; + + zlog(prio, "| (%s) message in thread %jd, at %s(), %s:%d", uid, + zlog_gettid(), xref->xref.func, xref->xref.file, xref->xref.line); + +#ifdef HAVE_LIBUNWIND + const char *threadfunc = tc ? tc->xref->funcname : NULL; + bool found_caller = false; + unw_cursor_t cursor; + unw_context_t uc; + unw_word_t ip, off, sp; + Dl_info dlinfo; + + unw_getcontext(&uc); + + unw_init_local(&cursor, &uc); + while (unw_step(&cursor) > 0) { + char buf[96], name[128] = "?"; + bool is_thread = false; + + unw_get_reg(&cursor, UNW_REG_IP, &ip); + unw_get_reg(&cursor, UNW_REG_SP, &sp); + + if (unw_is_signal_frame(&cursor)) + zlog(prio, "| (%s) ---- signal ----", uid); + + if (!unw_get_proc_name(&cursor, buf, sizeof(buf), &off)) { + if (!strcmp(buf, xref->xref.func)) + found_caller = true; + if (threadfunc && !strcmp(buf, threadfunc)) + found_thread = is_thread = true; + + snprintf(name, sizeof(name), "%s+%#lx", buf, (long)off); + } + + if (!found_caller) + continue; + + if (dladdr((void *)ip, &dlinfo)) + zlog(prio, "| (%s) %-36s %16lx+%08lx %16lx %s", uid, + name, (long)dlinfo.dli_fbase, + (long)ip - (long)dlinfo.dli_fbase, (long)sp, + dlinfo.dli_fname); + else + zlog(prio, "| (%s) %-36s %16lx %16lx", uid, name, + (long)ip, (long)sp); + + if (is_thread) + zlog(prio, "| (%s) ^- scheduled from %s(), %s:%u", uid, + tc->xref->xref.func, tc->xref->xref.file, + tc->xref->xref.line); + } +#elif defined(HAVE_GLIBC_BACKTRACE) + void *frames[64]; + char **names = NULL; + int n_frames, i; + + n_frames = backtrace(frames, array_size(frames)); + if (n_frames < 0) + n_frames = 0; + if (n_frames) + names = backtrace_symbols(frames, n_frames); + + for (i = 0; i < n_frames; i++) { + void *retaddr = frames[i]; + char *loc = names[i]; + + zlog(prio, "| (%s) %16lx %-36s", uid, (long)retaddr, loc); + } + free(names); +#endif + if (!found_thread && tc) + zlog(prio, "| (%s) scheduled from %s(), %s:%u", uid, + tc->xref->xref.func, tc->xref->xref.file, + tc->xref->xref.line); +} + void vzlogx(const struct xref_logmsg *xref, int prio, const char *fmt, va_list ap) { @@ -545,6 +633,15 @@ void vzlogx(const struct xref_logmsg *xref, int prio, vzlog_tls(zlog_tls, xref, prio, fmt, ap); else vzlog_notls(xref, prio, fmt, ap); + + if (xref) { + struct xrefdata_logmsg *xrdl; + + xrdl = container_of(xref->xref.xrefdata, struct xrefdata_logmsg, + xrefdata); + if (xrdl->fl_print_bt) + zlog_backtrace_msg(xref, prio); + } } void zlog_sigsafe(const char *text, size_t len) diff --git a/lib/zlog.h b/lib/zlog.h index d9c8952ac5..6e84fe8923 100644 --- a/lib/zlog.h +++ b/lib/zlog.h @@ -54,10 +54,14 @@ struct xref_logmsg { const char *args; }; +/* whether flag was added in config mode or enable mode */ +#define LOGMSG_FLAG_EPHEMERAL (1 << 0) +#define LOGMSG_FLAG_PERSISTENT (1 << 1) + struct xrefdata_logmsg { struct xrefdata xrefdata; - /* nothing more here right now */ + uint8_t fl_print_bt; }; /* These functions are set up to write to stdout/stderr without explicit @@ -94,15 +98,19 @@ static inline void zlog_ref(const struct xref_logmsg *xref, #define _zlog_ecref(ec_, prio, msg, ...) \ do { \ - static struct xrefdata _xrefdata = { \ - .xref = NULL, \ - .uid = {}, \ - .hashstr = (msg), \ - .hashu32 = {(prio), (ec_)}, \ + static struct xrefdata_logmsg _xrefdata = { \ + .xrefdata = \ + { \ + .xref = NULL, \ + .uid = {}, \ + .hashstr = (msg), \ + .hashu32 = {(prio), (ec_)}, \ + }, \ }; \ static const struct xref_logmsg _xref __attribute__( \ (used)) = { \ - .xref = XREF_INIT(XREFT_LOGMSG, &_xrefdata, __func__), \ + .xref = XREF_INIT(XREFT_LOGMSG, &_xrefdata.xrefdata, \ + __func__), \ .fmtstring = (msg), \ .priority = (prio), \ .ec = (ec_), \ diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index 6caee259b6..f35971ba8c 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -879,12 +879,12 @@ void ospf6_plist_update(struct prefix_list *plist) DEFUN (area_import_list, area_import_list_cmd, - "area <A.B.C.D|(0-4294967295)> import-list NAME", + "area <A.B.C.D|(0-4294967295)> import-list ACCESSLIST6_NAME", "OSPF6 area parameters\n" "OSPF6 area ID in IP address format\n" "OSPF6 area ID as a decimal value\n" "Set the filter for networks from other areas announced to the specified one\n" - "Name of the acess-list\n") + "Name of the access-list\n") { int idx_ipv4 = 1; int idx_name = 3; @@ -911,7 +911,7 @@ DEFUN (area_import_list, DEFUN (no_area_import_list, no_area_import_list_cmd, - "no area <A.B.C.D|(0-4294967295)> import-list NAME", + "no area <A.B.C.D|(0-4294967295)> import-list ACCESSLIST6_NAME", NO_STR "OSPF6 area parameters\n" "OSPF6 area ID in IP address format\n" @@ -940,12 +940,12 @@ DEFUN (no_area_import_list, DEFUN (area_export_list, area_export_list_cmd, - "area <A.B.C.D|(0-4294967295)> export-list NAME", + "area <A.B.C.D|(0-4294967295)> export-list ACCESSLIST6_NAME", "OSPF6 area parameters\n" "OSPF6 area ID in IP address format\n" "OSPF6 area ID as a decimal value\n" "Set the filter for networks announced to other areas\n" - "Name of the acess-list\n") + "Name of the access-list\n") { int idx_ipv4 = 1; int idx_name = 3; @@ -974,7 +974,7 @@ DEFUN (area_export_list, DEFUN (no_area_export_list, no_area_export_list_cmd, - "no area <A.B.C.D|(0-4294967295)> export-list NAME", + "no area <A.B.C.D|(0-4294967295)> export-list ACCESSLIST6_NAME", NO_STR "OSPF6 area parameters\n" "OSPF6 area ID in IP address format\n" diff --git a/ospf6d/ospf6_gr.h b/ospf6d/ospf6_gr.h index 6406e8efee..28798d8717 100644 --- a/ospf6d/ospf6_gr.h +++ b/ospf6d/ospf6_gr.h @@ -93,7 +93,7 @@ struct tlv_header { #define TLV_BODY_SIZE(tlvh) (ROUNDUP(ntohs((tlvh)->length), sizeof(uint32_t))) -#define TLV_SIZE(tlvh) (TLV_HDR_SIZE + TLV_BODY_SIZE(tlvh)) +#define TLV_SIZE(tlvh) (uint32_t)(TLV_HDR_SIZE + TLV_BODY_SIZE(tlvh)) #define TLV_HDR_TOP(lsah) \ (struct tlv_header *)((char *)(lsah) + OSPF6_LSA_HEADER_SIZE) diff --git a/ospf6d/ospf6_gr_helper.c b/ospf6d/ospf6_gr_helper.c index 78f842db6c..4dc2d8af83 100644 --- a/ospf6d/ospf6_gr_helper.c +++ b/ospf6d/ospf6_gr_helper.c @@ -157,8 +157,18 @@ static int ospf6_extract_grace_lsa_fields(struct ospf6_lsa *lsa, length = ntohs(lsah->length) - OSPF6_LSA_HEADER_SIZE; - for (tlvh = TLV_HDR_TOP(lsah); sum < length; + for (tlvh = TLV_HDR_TOP(lsah); sum < length && tlvh; tlvh = TLV_HDR_NEXT(tlvh)) { + + /* Check TLV len against overall LSA */ + if (sum + TLV_SIZE(tlvh) > length) { + if (IS_DEBUG_OSPF6_GR) + zlog_debug( + "%s: Malformed packet: Invalid TLV len:%d", + __func__, TLV_SIZE(tlvh)); + return OSPF6_FAILURE; + } + switch (ntohs(tlvh->type)) { case GRACE_PERIOD_TYPE: gracePeriod = (struct grace_tlv_graceperiod *)tlvh; @@ -1235,8 +1245,20 @@ static int ospf6_grace_lsa_show_info(struct vty *vty, struct ospf6_lsa *lsa, zlog_debug(" TLV info:"); } - for (tlvh = TLV_HDR_TOP(lsah); sum < length; + for (tlvh = TLV_HDR_TOP(lsah); sum < length && tlvh; tlvh = TLV_HDR_NEXT(tlvh)) { + + /* Check TLV len */ + if (sum + TLV_SIZE(tlvh) > length) { + if (vty) + vty_out(vty, "%% Invalid TLV length: %d\n", + TLV_SIZE(tlvh)); + else if (IS_DEBUG_OSPF6_GR) + zlog_debug("%% Invalid TLV length: %d", + TLV_SIZE(tlvh)); + return OSPF6_FAILURE; + } + switch (ntohs(tlvh->type)) { case GRACE_PERIOD_TYPE: gracePeriod = (struct grace_tlv_graceperiod *)tlvh; diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index 60e109ea80..42d31414f5 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -705,11 +705,11 @@ static int ospf_if_delete_hook(struct interface *ifp) */ ospf_del_if_params(ifp, IF_DEF_PARAMS(ifp)); - route_table_finish(IF_OIFS(ifp)); - for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn)) if (rn->info) ospf_del_if_params(ifp, rn->info); + + route_table_finish(IF_OIFS(ifp)); route_table_finish(IF_OIFS_PARAMS(ifp)); XFREE(MTYPE_OSPF_IF_INFO, ifp->info); @@ -971,11 +971,14 @@ struct ospf_interface *ospf_vl_new(struct ospf *ospf, static void ospf_vl_if_delete(struct ospf_vl_data *vl_data) { struct interface *ifp = vl_data->vl_oi->ifp; + struct vrf *vrf = ifp->vrf; vl_data->vl_oi->address->u.prefix4.s_addr = INADDR_ANY; vl_data->vl_oi->address->prefixlen = 0; ospf_if_free(vl_data->vl_oi); if_delete(&ifp); + if (!vrf_is_enabled(vrf)) + vrf_delete(vrf); vlink_count--; } diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index fcfc645a23..e7f18ae79c 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -1775,7 +1775,7 @@ DEFUN (no_ospf_area_default_cost, DEFUN (ospf_area_export_list, ospf_area_export_list_cmd, - "area <A.B.C.D|(0-4294967295)> export-list NAME", + "area <A.B.C.D|(0-4294967295)> export-list ACCESSLIST4_NAME", "OSPF area parameters\n" "OSPF area ID in IP address format\n" "OSPF area ID as a decimal value\n" @@ -1799,7 +1799,7 @@ DEFUN (ospf_area_export_list, DEFUN (no_ospf_area_export_list, no_ospf_area_export_list_cmd, - "no area <A.B.C.D|(0-4294967295)> export-list NAME", + "no area <A.B.C.D|(0-4294967295)> export-list ACCESSLIST4_NAME", NO_STR "OSPF area parameters\n" "OSPF area ID in IP address format\n" @@ -1827,7 +1827,7 @@ DEFUN (no_ospf_area_export_list, DEFUN (ospf_area_import_list, ospf_area_import_list_cmd, - "area <A.B.C.D|(0-4294967295)> import-list NAME", + "area <A.B.C.D|(0-4294967295)> import-list ACCESSLIST4_NAME", "OSPF area parameters\n" "OSPF area ID in IP address format\n" "OSPF area ID as a decimal value\n" @@ -1851,7 +1851,7 @@ DEFUN (ospf_area_import_list, DEFUN (no_ospf_area_import_list, no_ospf_area_import_list_cmd, - "no area <A.B.C.D|(0-4294967295)> import-list NAME", + "no area <A.B.C.D|(0-4294967295)> import-list ACCESSLIST4_NAME", NO_STR "OSPF area parameters\n" "OSPF area ID in IP address format\n" @@ -9347,7 +9347,7 @@ DEFUN (no_ospf_redistribute_instance_source, DEFUN (ospf_distribute_list_out, ospf_distribute_list_out_cmd, - "distribute-list WORD out " FRR_REDIST_STR_OSPFD, + "distribute-list ACCESSLIST4_NAME out " FRR_REDIST_STR_OSPFD, "Filter networks in routing updates\n" "Access-list name\n" OUT_STR @@ -9369,7 +9369,7 @@ DEFUN (ospf_distribute_list_out, DEFUN (no_ospf_distribute_list_out, no_ospf_distribute_list_out_cmd, - "no distribute-list WORD out " FRR_REDIST_STR_OSPFD, + "no distribute-list ACCESSLIST4_NAME out " FRR_REDIST_STR_OSPFD, NO_STR "Filter networks in routing updates\n" "Access-list name\n" diff --git a/pathd/path_pcep_controller.c b/pathd/path_pcep_controller.c index 449c40c16c..162c53590f 100644 --- a/pathd/path_pcep_controller.c +++ b/pathd/path_pcep_controller.c @@ -38,14 +38,6 @@ #define MAX_RECONNECT_DELAY 120 -#define min(a, b) \ - ({ \ - __typeof__(a) _a = (a); \ - __typeof__(b) _b = (b); \ - _a <= _b ? _a : _b; \ - }) - - /* Event handling data structures */ enum pcep_ctrl_event_type { EV_UPDATE_PCC_OPTS = 1, @@ -1078,7 +1070,7 @@ void remove_pcc_state(struct ctrl_state *ctrl_state, uint32_t backoff_delay(uint32_t max, uint32_t base, uint32_t retry_count) { - uint32_t a = min(max, base * (1 << retry_count)); + uint32_t a = MIN(max, base * (1 << retry_count)); uint64_t r = frr_weak_random(), m = RAND_MAX; uint32_t b = (a / 2) + (r * (a / 2)) / m; return b; diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 4cd94e0df9..e5ee7a82ad 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -2446,8 +2446,6 @@ static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state, case PIM_REG_PRUNE: strlcpy(state_str, "RegP", state_str_len); break; - default: - strlcpy(state_str, "Unk", state_str_len); } return state_str; } diff --git a/pimd/pim_msdp_packet.h b/pimd/pim_msdp_packet.h index f5af8d1140..10b7ca4198 100644 --- a/pimd/pim_msdp_packet.h +++ b/pimd/pim_msdp_packet.h @@ -58,7 +58,8 @@ * fragmentation */ #define PIM_MSDP_SA_MAX_ENTRY_CNT 120 -#define PIM_MSDP_MAX_PACKET_SIZE max(PIM_MSDP_SA_TLV_MAX_SIZE, PIM_MSDP_KA_TLV_MAX_SIZE) +#define PIM_MSDP_MAX_PACKET_SIZE \ + MAX(PIM_MSDP_SA_TLV_MAX_SIZE, PIM_MSDP_KA_TLV_MAX_SIZE) #define PIM_MSDP_PKT_TYPE_STRLEN 16 diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index d21c7b4008..d0d120523d 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -1720,8 +1720,6 @@ const char *pim_reg_state2str(enum pim_reg_state reg_state, char *state_str, case PIM_REG_PRUNE: strlcpy(state_str, "RegPrune", state_str_len); break; - default: - strlcpy(state_str, "RegUnknown", state_str_len); } return state_str; } @@ -1785,7 +1783,7 @@ static int pim_upstream_register_stop_timer(struct thread *t) } pim_null_register_send(up); break; - default: + case PIM_REG_NOINFO: break; } diff --git a/pimd/pimd.h b/pimd/pimd.h index 4cb860a6b7..675c0ebc6b 100644 --- a/pimd/pimd.h +++ b/pimd/pimd.h @@ -85,8 +85,6 @@ #define PIM_INADDR_IS_ANY(addr) (addr).s_addr == PIM_NET_INADDR_ANY #define PIM_INADDR_ISNOT_ANY(addr) ((addr).s_addr != PIM_NET_INADDR_ANY) /* struct in_addr addr */ -#define max(x,y) ((x) > (y) ? (x) : (y)) - #define PIM_MASK_PIM_EVENTS (1 << 0) #define PIM_MASK_PIM_EVENTS_DETAIL (1 << 1) #define PIM_MASK_PIM_PACKETS (1 << 2) diff --git a/ripd/rip_cli.c b/ripd/rip_cli.c index 5590b1833d..58c28e54c0 100644 --- a/ripd/rip_cli.c +++ b/ripd/rip_cli.c @@ -327,7 +327,7 @@ void cli_show_rip_network_interface(struct vty *vty, */ DEFPY_YANG (rip_offset_list, rip_offset_list_cmd, - "[no] offset-list WORD$acl <in|out>$direction (0-16)$metric [IFNAME]", + "[no] offset-list ACCESSLIST4_NAME$acl <in|out>$direction (0-16)$metric [IFNAME]", NO_STR "Modify RIP metric\n" "Access-list name\n" @@ -1026,7 +1026,7 @@ DEFPY_YANG (clear_ip_rip, DEFUN (rip_distribute_list, rip_distribute_list_cmd, - "distribute-list [prefix] WORD <in|out> [WORD]", + "distribute-list [prefix] ACCESSLIST4_NAME <in|out> [WORD]", "Filter networks in routing updates\n" "Specify a prefix\n" "Access-list name\n" @@ -1046,7 +1046,7 @@ DEFUN (rip_distribute_list, DEFUN (rip_no_distribute_list, rip_no_distribute_list_cmd, - "no distribute-list [prefix] WORD <in|out> [WORD]", + "no distribute-list [prefix] ACCESSLIST4_NAME <in|out> [WORD]", NO_STR "Filter networks in routing updates\n" "Specify a prefix\n" diff --git a/ripngd/ripng_cli.c b/ripngd/ripng_cli.c index 63b75e723d..5bf3103a78 100644 --- a/ripngd/ripng_cli.c +++ b/ripngd/ripng_cli.c @@ -233,7 +233,7 @@ void cli_show_ripng_network_interface(struct vty *vty, */ DEFPY_YANG (ripng_offset_list, ripng_offset_list_cmd, - "[no] offset-list WORD$acl <in|out>$direction (0-16)$metric [IFNAME]", + "[no] offset-list ACCESSLIST6_NAME$acl <in|out>$direction (0-16)$metric [IFNAME]", NO_STR "Modify RIPng metric\n" "Access-list name\n" @@ -511,7 +511,7 @@ DEFPY_YANG (clear_ipv6_rip, DEFUN (ripng_ipv6_distribute_list, ripng_ipv6_distribute_list_cmd, - "ipv6 distribute-list [prefix] WORD <in|out> [WORD]", + "ipv6 distribute-list [prefix] ACCESSLIST6_NAME <in|out> [WORD]", "IPv6\n" "Filter networks in routing updates\n" "Specify a prefix\n" @@ -532,7 +532,7 @@ DEFUN (ripng_ipv6_distribute_list, DEFUN (ripng_no_ipv6_distribute_list, ripng_no_ipv6_distribute_list_cmd, - "no ipv6 distribute-list [prefix] WORD <in|out> [WORD]", + "no ipv6 distribute-list [prefix] ACCESSLIST6_NAME <in|out> [WORD]", NO_STR "IPv6\n" "Filter networks in routing updates\n" diff --git a/ripngd/ripng_nexthop.c b/ripngd/ripng_nexthop.c index 3e9fa90938..50972feffc 100644 --- a/ripngd/ripng_nexthop.c +++ b/ripngd/ripng_nexthop.c @@ -43,8 +43,6 @@ DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_RTE_DATA, "RIPng rte data"); #define DEBUG 1 -#define min(a, b) ((a) < (b) ? (a) : (b)) - struct ripng_rte_data { struct prefix_ipv6 *p; struct ripng_info *rinfo; @@ -151,7 +149,7 @@ void ripng_rte_send(struct list *ripng_rte_list, struct interface *ifp, if (mtu < 0) mtu = IFMINMTU; - rtemax = (min(mtu, RIPNG_MAX_PACKET_SIZE) - IPV6_HDRLEN + rtemax = (MIN(mtu, RIPNG_MAX_PACKET_SIZE) - IPV6_HDRLEN - sizeof(struct udphdr) - sizeof(struct ripng_packet) + sizeof(struct rte)) / sizeof(struct rte); diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 9610f71d09..ab3e55d100 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -493,8 +493,8 @@ static int rtadv_timer(struct thread *thread) RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) FOR_ALL_INTERFACES (vrf, ifp) { - if (if_is_loopback_or_vrf(ifp) - || !if_is_operative(ifp)) + if (if_is_loopback_or_vrf(ifp) || !if_is_operative(ifp) + || (vrf_is_backend_netns() && ifp->vrf_id != zvrf->vrf->vrf_id)) continue; zif = ifp->info; diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index 66d6d4b4f2..1cc7e8932b 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -184,8 +184,6 @@ static int zebra_vrf_disable(struct vrf *vrf) zlog_debug("VRF %s id %u is now inactive", zvrf_name(zvrf), zvrf_id(zvrf)); - table_manager_disable(zvrf); - /* Stop any VxLAN-EVPN processing. */ zebra_vxlan_vrf_disable(zvrf); @@ -274,6 +272,8 @@ static int zebra_vrf_delete(struct vrf *vrf) zlog_debug("VRF %s id %u deleted", zvrf_name(zvrf), zvrf_id(zvrf)); + table_manager_disable(zvrf); + /* clean-up work queues */ for (i = 0; i < MQ_SIZE; i++) { struct listnode *lnode, *nnode; diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index bb46a1e62e..2d2c0a0bee 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -4645,6 +4645,11 @@ int zebra_vxlan_svi_down(struct interface *ifp, struct interface *link_if) zevpn = zebra_evpn_from_svi(ifp, link_if); if (zevpn) { + /* remove from l3-vni list */ + zl3vni = zl3vni_from_vrf(zevpn->vrf_id); + if (zl3vni) + listnode_delete(zl3vni->l2vnis, zevpn); + zevpn->svi_if = NULL; zevpn->vrf_id = VRF_DEFAULT; @@ -4704,6 +4709,10 @@ int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if) zevpn->svi_if = ifp; zevpn->vrf_id = ifp->vrf_id; + zl3vni = zl3vni_from_vrf(zevpn->vrf_id); + if (zl3vni) + listnode_add_sort_nodup(zl3vni->l2vnis, zevpn); + if (if_is_operative(zevpn->vxlan_if)) zebra_evpn_send_add_to_client(zevpn); |
