]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #12302 from louis-6wind/fix-isis_route_null-area
authorOlivier Dugeon <olivier.dugeon@orange.com>
Thu, 17 Nov 2022 11:25:43 +0000 (12:25 +0100)
committerGitHub <noreply@github.com>
Thu, 17 Nov 2022 11:25:43 +0000 (12:25 +0100)
isisd: fix area NULL pointer in isis_route_update

71 files changed:
Makefile.am
alpine/APKBUILD.in
bgpd/bgp_attr.c
bgpd/bgp_fsm.c
bgpd/bgp_io.c
bgpd/bgp_mplsvpn.c
bgpd/bgp_packet.c
bgpd/bgp_regex.h
bgpd/bgp_route.c
bgpd/bgp_routemap.c
bgpd/bgp_vty.c
bgpd/bgpd.h
configure.ac
debian/frr.install
debian/frr.logrotate [deleted file]
debian/frr.pam
doc/user/installation.rst
doc/user/pathd.rst
doc/user/zebra.rst
docker/alpine/Dockerfile
lib/frrstr.c
lib/frrstr.h
lib/ipaddr.h
lib/srv6.c
lib/srv6.h
lib/vty.c
lib/vty.h
lib/zclient.c
ospfd/ospf_lsa.c
pathd/path_cli.c
pathd/path_ted.c
pathd/path_ted.h
pathd/pathd.c
pathd/pathd.h
pimd/pim_iface.c
pimd/pim_igmp_mtrace.c
pimd/pim_nb_config.c
pimd/pim_nht.c
pimd/pim_nht.h
pimd/pim_rpf.c
redhat/frr.pam
redhat/frr.spec.in
tests/topotests/srv6_locator_usid/__init__.py [new file with mode: 0644]
tests/topotests/srv6_locator_usid/expected_chunks_1.json [new file with mode: 0644]
tests/topotests/srv6_locator_usid/expected_chunks_2.json [new file with mode: 0644]
tests/topotests/srv6_locator_usid/expected_chunks_3.json [new file with mode: 0644]
tests/topotests/srv6_locator_usid/expected_chunks_4.json [new file with mode: 0644]
tests/topotests/srv6_locator_usid/expected_chunks_5.json [new file with mode: 0644]
tests/topotests/srv6_locator_usid/expected_chunks_6.json [new file with mode: 0644]
tests/topotests/srv6_locator_usid/expected_chunks_7.json [new file with mode: 0644]
tests/topotests/srv6_locator_usid/expected_chunks_8.json [new file with mode: 0644]
tests/topotests/srv6_locator_usid/expected_locators_1.json [new file with mode: 0644]
tests/topotests/srv6_locator_usid/expected_locators_2.json [new file with mode: 0644]
tests/topotests/srv6_locator_usid/expected_locators_3.json [new file with mode: 0644]
tests/topotests/srv6_locator_usid/expected_locators_4.json [new file with mode: 0644]
tests/topotests/srv6_locator_usid/expected_locators_5.json [new file with mode: 0644]
tests/topotests/srv6_locator_usid/expected_locators_6.json [new file with mode: 0644]
tests/topotests/srv6_locator_usid/expected_locators_7.json [new file with mode: 0644]
tests/topotests/srv6_locator_usid/expected_locators_8.json [new file with mode: 0644]
tests/topotests/srv6_locator_usid/r1/setup.sh [new file with mode: 0644]
tests/topotests/srv6_locator_usid/r1/sharpd.conf [new file with mode: 0644]
tests/topotests/srv6_locator_usid/r1/zebra.conf [new file with mode: 0644]
tests/topotests/srv6_locator_usid/test_srv6_locator_usid.py [new file with mode: 0755]
tools/etc/logrotate.d/frr [new file with mode: 0644]
tools/frrcommon.sh.in
zebra/dplane_fpm_nl.c
zebra/zapi_msg.c
zebra/zebra_evpn_mh.c
zebra/zebra_srv6.c
zebra/zebra_srv6.h
zebra/zebra_srv6_vty.c

index 8c7bde9d4ce74cc2f9a285e7a1a9a353585a0e8d..44d2ab8e72b80d5533430df61f62ebb726519528 100644 (file)
@@ -231,7 +231,7 @@ EXTRA_DIST += \
        \
        python/xrefstructs.json \
        \
-       redhat/frr.logrotate \
+       tools/etc/logrotate.d/frr \
        redhat/frr.pam \
        redhat/frr.spec \
        \
index 51986de2dd2af1a92c6e94c373ef43225b77994b..3aad9549b5fb07f72c7d22b707897e73f738aa01 100644 (file)
@@ -15,8 +15,8 @@ makedepends="ncurses-dev net-snmp-dev gawk texinfo perl
     libcap-dev libcurl libedit libffi libgcc libgomp libisoburn libisofs
     libltdl libressl libssh2 libstdc++ libtool libuuid
     linux-headers lzip lzo m4 make mkinitfs mpc1 mpfr4 mtools musl-dev
-    ncurses-libs ncurses-terminfo ncurses-terminfo-base patch pax-utils pcre
-    perl pkgconf python3 python3-dev readline readline-dev sqlite-libs
+    ncurses-libs ncurses-terminfo ncurses-terminfo-base patch pax-utils pcre2
+    perl pkgconf python3 python3-dev readline readline-dev sqlite-libs pcre2-dev
     squashfs-tools sudo tar texinfo xorriso xz-libs py-pip rtrlib rtrlib-dev
     py3-sphinx elfutils elfutils-dev libyang-dev"
 checkdepends="pytest py-setuptools"
@@ -46,8 +46,9 @@ build() {
                --enable-multipath=64 \
                --enable-vty-group=frrvty \
                --enable-user=$_user \
-               --enable-group=$_user
-       make
+               --enable-group=$_user \
+               --enable-pcre2posix
+       make -j $(nproc)
 }
 
 check() {
index e9050c5aecd5facf52465b50331e63f9fb66c06c..89aed1ba699fde82b55996e6ac68ac750cb4167d 100644 (file)
@@ -4507,7 +4507,9 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
                        stream_put(s, &attr->srv6_l3vpn->sid,
                                   sizeof(attr->srv6_l3vpn->sid)); /* sid */
                        stream_putc(s, 0);      /* sid_flags */
-                       stream_putw(s, 0xffff); /* endpoint */
+                       stream_putw(s,
+                                   attr->srv6_l3vpn
+                                           ->endpoint_behavior); /* endpoint */
                        stream_putc(s, 0);      /* reserved */
                        stream_putc(
                                s,
index 01c61615a3312c2ba5eec8b75316880d386e272e..f110005e49f28d3b05c900719c8709534f3880d0 100644 (file)
@@ -634,7 +634,8 @@ const char *const peer_down_str[] = {"",
                                     "AS Set config change",
                                     "Waiting for peer OPEN",
                                     "Reached received prefix count",
-                                    "Socket Error"};
+                                    "Socket Error",
+                                    "Admin. shutdown (RTT)"};
 
 static void bgp_graceful_restart_timer_off(struct peer *peer)
 {
@@ -1832,7 +1833,9 @@ int bgp_start(struct peer *peer)
                        flog_err(EC_BGP_FSM,
                                 "%s [FSM] Trying to start suppressed peer - this is never supposed to happen!",
                                 peer->host);
-               if (CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN))
+               if (CHECK_FLAG(peer->sflags, PEER_STATUS_RTT_SHUTDOWN))
+                       peer->last_reset = PEER_DOWN_RTT_SHUTDOWN;
+               else if (CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN))
                        peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
                else if (CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHUTDOWN))
                        peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
index ce8ce96a0dd8f3ad2f3204b4b461d746f21619bb..49ae9816a32a54fc759f12c177643115be900796 100644 (file)
@@ -280,10 +280,11 @@ static void bgp_process_reads(struct thread *thread)
        case -ENOMEM:
                ibuf_full = true;
                if (!ibuf_full_logged) {
-                       flog_warn(
-                               EC_BGP_UPDATE_RCV,
-                               "%s [Warning] Peer Input-Queue is full: limit (%u)",
-                               peer->host, bm->inq_limit);
+                       if (bgp_debug_neighbor_events(peer))
+                               zlog_debug(
+                                       "%s [Event] Peer Input-Queue is full: limit (%u)",
+                                       peer->host, bm->inq_limit);
+
                        ibuf_full_logged = true;
                }
                break;
index 9a25450afa56cc263add1b3e4d68d19d45fa1874..18cb90763c038a91062982b9023bf76e3ce96d34 100644 (file)
@@ -1554,13 +1554,22 @@ void vpn_leak_from_vrf_update(struct bgp *to_bgp,            /* to */
 
        /* Set SID for SRv6 VPN */
        if (from_bgp->vpn_policy[afi].tovpn_sid_locator) {
+               struct srv6_locator_chunk *locator =
+                       from_bgp->vpn_policy[afi].tovpn_sid_locator;
                encode_label(
                        from_bgp->vpn_policy[afi].tovpn_sid_transpose_label,
                        &label);
                static_attr.srv6_l3vpn = XCALLOC(MTYPE_BGP_SRV6_L3VPN,
                                sizeof(struct bgp_attr_srv6_l3vpn));
                static_attr.srv6_l3vpn->sid_flags = 0x00;
-               static_attr.srv6_l3vpn->endpoint_behavior = 0xffff;
+               static_attr.srv6_l3vpn->endpoint_behavior =
+                       afi == AFI_IP
+                               ? (CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID)
+                                          ? SRV6_ENDPOINT_BEHAVIOR_END_DT4_USID
+                                          : SRV6_ENDPOINT_BEHAVIOR_END_DT4)
+                               : (CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID)
+                                          ? SRV6_ENDPOINT_BEHAVIOR_END_DT6_USID
+                                          : SRV6_ENDPOINT_BEHAVIOR_END_DT6);
                static_attr.srv6_l3vpn->loc_block_len =
                        from_bgp->vpn_policy[afi]
                                .tovpn_sid_locator->block_bits_length;
@@ -1587,12 +1596,17 @@ void vpn_leak_from_vrf_update(struct bgp *to_bgp,            /* to */
                                .tovpn_sid_locator->prefix.prefix,
                       sizeof(struct in6_addr));
        } else if (from_bgp->tovpn_sid_locator) {
+               struct srv6_locator_chunk *locator =
+                       from_bgp->tovpn_sid_locator;
                encode_label(from_bgp->tovpn_sid_transpose_label, &label);
                static_attr.srv6_l3vpn =
                        XCALLOC(MTYPE_BGP_SRV6_L3VPN,
                                sizeof(struct bgp_attr_srv6_l3vpn));
                static_attr.srv6_l3vpn->sid_flags = 0x00;
-               static_attr.srv6_l3vpn->endpoint_behavior = 0xffff;
+               static_attr.srv6_l3vpn->endpoint_behavior =
+                       CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID)
+                               ? SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID
+                               : SRV6_ENDPOINT_BEHAVIOR_END_DT46;
                static_attr.srv6_l3vpn->loc_block_len =
                        from_bgp->tovpn_sid_locator->block_bits_length;
                static_attr.srv6_l3vpn->loc_node_len =
index 72d6a9231756538a102fb18831fb9da2988d8ed2..f3ca3bba0a0651299f63bed039b01a011cd735e6 100644 (file)
@@ -1011,9 +1011,12 @@ static void bgp_notify_send_internal(struct peer *peer, uint8_t code,
        if (code == BGP_NOTIFY_CEASE) {
                if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
                        peer->last_reset = PEER_DOWN_USER_RESET;
-               else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
-                       peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
-               else
+               else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN) {
+                       if (CHECK_FLAG(peer->sflags, PEER_STATUS_RTT_SHUTDOWN))
+                               peer->last_reset = PEER_DOWN_RTT_SHUTDOWN;
+                       else
+                               peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
+               } else
                        peer->last_reset = PEER_DOWN_NOTIFY_SEND;
        } else
                peer->last_reset = PEER_DOWN_NOTIFY_SEND;
@@ -1749,15 +1752,24 @@ static int bgp_keepalive_receive(struct peer *peer, bgp_size_t size)
        /* If the peer's RTT is higher than expected, shutdown
         * the peer automatically.
         */
-       if (CHECK_FLAG(peer->flags, PEER_FLAG_RTT_SHUTDOWN)
-           && peer->rtt > peer->rtt_expected) {
+       if (!CHECK_FLAG(peer->flags, PEER_FLAG_RTT_SHUTDOWN))
+               return Receive_KEEPALIVE_message;
 
+       if (peer->rtt > peer->rtt_expected) {
                peer->rtt_keepalive_rcv++;
 
                if (peer->rtt_keepalive_rcv > peer->rtt_keepalive_conf) {
-                       zlog_warn(
-                               "%s shutdown due to high round-trip-time (%dms > %dms)",
-                               peer->host, peer->rtt, peer->rtt_expected);
+                       char rtt_shutdown_reason[BUFSIZ] = {};
+
+                       snprintfrr(
+                               rtt_shutdown_reason,
+                               sizeof(rtt_shutdown_reason),
+                               "shutdown due to high round-trip-time (%dms > %dms, hit %u times)",
+                               peer->rtt, peer->rtt_expected,
+                               peer->rtt_keepalive_rcv);
+                       zlog_warn("%s %s", peer->host, rtt_shutdown_reason);
+                       SET_FLAG(peer->sflags, PEER_STATUS_RTT_SHUTDOWN);
+                       peer_tx_shutdown_message_set(peer, rtt_shutdown_reason);
                        peer_flag_set(peer, PEER_FLAG_SHUTDOWN);
                }
        } else {
index 43ebb9ac918f5d65515a925aaecaeeecb67d2ef9..e07b7f911b9e09c114942b52bfad3c7c7fa29f77 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#ifndef _QUAGGA_BGP_REGEX_H
-#define _QUAGGA_BGP_REGEX_H
+#ifndef _FRR_BGP_REGEX_H
+#define _FRR_BGP_REGEX_H
 
 #include <zebra.h>
 
-#ifdef HAVE_LIBPCREPOSIX
+#ifdef HAVE_LIBPCRE2_POSIX
+#ifndef _FRR_PCRE2_POSIX
+#define _FRR_PCRE2_POSIX
+#include <pcre2posix.h>
+#endif /* _FRR_PCRE2_POSIX */
+#elif defined(HAVE_LIBPCREPOSIX)
 #include <pcreposix.h>
 #else
 #include <regex.h>
-#endif /* HAVE_LIBPCREPOSIX */
+#endif /* HAVE_LIBPCRE2_POSIX */
 
 extern void bgp_regex_free(regex_t *regex);
 extern regex_t *bgp_regcomp(const char *str);
 extern int bgp_regexec(regex_t *regex, struct aspath *aspath);
 
-#endif /* _QUAGGA_BGP_REGEX_H */
+#endif /* _FRR_BGP_REGEX_H */
index 130a0b4abd8bf8dc9e84d90337b3679451c714c1..a6a67eeaac54600e3f2f40412482e20b031c2b22 100644 (file)
@@ -4044,6 +4044,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
        int vnc_implicit_withdraw = 0;
 #endif
        int same_attr = 0;
+       const struct prefix *bgp_nht_param_prefix;
 
        /* Special case for BGP-LU - map LU safi to ordinary unicast safi */
        if (orig_safi == SAFI_LABELED_UNICAST)
@@ -4111,6 +4112,11 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
                if (aspath_get_last_as(attr->aspath) == bgp->as)
                        do_loop_check = 0;
 
+       if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
+               bgp_nht_param_prefix = NULL;
+       else
+               bgp_nht_param_prefix = p;
+
        /* AS path loop check. */
        if (do_loop_check) {
                if (aspath_loop_check(attr->aspath, bgp->as) > allowas_in ||
@@ -4621,8 +4627,8 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
 
                        if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
                                                    safi, pi, NULL, connected,
-                                                   p)
-                           || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
+                                                   bgp_nht_param_prefix) ||
+                           CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
                                bgp_path_info_set_flag(dest, pi,
                                                       BGP_PATH_VALID);
                        else {
@@ -4784,8 +4790,8 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
                nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
 
                if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
-                                           connected, p)
-                   || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
+                                           connected, bgp_nht_param_prefix) ||
+                   CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
                        bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
                else {
                        if (BGP_DEBUG(nht, NHT)) {
index aff09206e4b03842f2aa2bb0c9c2ffd05ef09d4c..b736e6c38a97dd11d9760632a157057d82af4c7f 100644 (file)
 #include "log.h"
 #include "frrlua.h"
 #include "frrscript.h"
-#ifdef HAVE_LIBPCREPOSIX
+#ifdef HAVE_LIBPCRE2_POSIX
+#ifndef _FRR_PCRE2_POSIX
+#define _FRR_PCRE2_POSIX
+#include <pcre2posix.h>
+#endif /* _FRR_PCRE2_POSIX */
+#elif defined(HAVE_LIBPCREPOSIX)
 #include <pcreposix.h>
 #else
 #include <regex.h>
-#endif /* HAVE_LIBPCREPOSIX */
+#endif /* HAVE_LIBPCRE2_POSIX */
 #include "buffer.h"
 #include "sockunion.h"
 #include "hash.h"
index 1f66080e93ba02503eb3c02ff7d09cc6a3adc044..6f0bd5ededfda591546ddc66fbaeceeb117a09ad 100644 (file)
@@ -5272,8 +5272,10 @@ static int peer_flag_modify_vty(struct vty *vty, const char *ip_str,
                return CMD_WARNING_CONFIG_FAILED;
        }
 
-       if (!set && flag == PEER_FLAG_SHUTDOWN)
+       if (!set && flag == PEER_FLAG_SHUTDOWN) {
                peer_tx_shutdown_message_unset(peer);
+               UNSET_FLAG(peer->sflags, PEER_STATUS_RTT_SHUTDOWN);
+       }
 
        if (set)
                ret = peer_flag_set(peer, flag);
@@ -14565,9 +14567,18 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
        if (use_json) {
                json_object_int_add(json_neigh, "connectRetryTimer",
                                    p->v_connect);
-               if (peer_established(p) && p->rtt)
+               if (peer_established(p)) {
                        json_object_int_add(json_neigh, "estimatedRttInMsecs",
                                            p->rtt);
+                       if (CHECK_FLAG(p->flags, PEER_FLAG_RTT_SHUTDOWN)) {
+                               json_object_int_add(json_neigh,
+                                                   "shutdownRttInMsecs",
+                                                   p->rtt_expected);
+                               json_object_int_add(json_neigh,
+                                                   "shutdownRttAfterCount",
+                                                   p->rtt_keepalive_rcv);
+                       }
+               }
                if (p->t_start)
                        json_object_int_add(
                                json_neigh, "nextStartTimerDueInMsecs",
@@ -14602,9 +14613,14 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
        } else {
                vty_out(vty, "BGP Connect Retry Timer in Seconds: %d\n",
                        p->v_connect);
-               if (peer_established(p) && p->rtt)
+               if (peer_established(p)) {
                        vty_out(vty, "Estimated round trip time: %d ms\n",
                                p->rtt);
+                       if (CHECK_FLAG(p->flags, PEER_FLAG_RTT_SHUTDOWN))
+                               vty_out(vty,
+                                       "Shutdown when RTT > %dms, count > %u\n",
+                                       p->rtt_expected, p->rtt_keepalive_rcv);
+               }
                if (p->t_start)
                        vty_out(vty, "Next start timer due in %ld seconds\n",
                                thread_timer_remain_second(p->t_start));
index b3fce07344959683a317b54db56f82a88eb132a3..8a0ec5ad2d3f1003da844979dc3ebac7037f0301 100644 (file)
@@ -1524,6 +1524,7 @@ struct peer {
 /* LLGR aware peer */
 #define PEER_STATUS_LLGR_WAIT (1U << 11)
 #define PEER_STATUS_REFRESH_PENDING (1U << 12) /* refresh request from peer */
+#define PEER_STATUS_RTT_SHUTDOWN (1U << 13) /* In shutdown state due to RTT */
 
        /* Configured timer values. */
        _Atomic uint32_t holdtime;
@@ -1737,6 +1738,7 @@ struct peer {
 #define PEER_DOWN_WAITING_OPEN          32U /* Waiting for open to succeed */
 #define PEER_DOWN_PFX_COUNT             33U /* Reached received prefix count */
 #define PEER_DOWN_SOCKET_ERROR          34U /* Some socket error happened */
+#define PEER_DOWN_RTT_SHUTDOWN          35U /* Automatically shutdown due to RTT */
        /*
         * Remember to update peer_down_str in bgp_fsm.c when you add
         * a new value to the last_reset reason
index 1a481ecd794c7c294fd43f386fde4b8208742e3d..97c8ca451b80639f88ae75ff0ddbec7ebac8387f 100644 (file)
@@ -712,6 +712,8 @@ AC_ARG_ENABLE([cpu-time],
   AS_HELP_STRING([--disable-cpu-time], [disable cpu usage data gathering]))
 AC_ARG_ENABLE([pcreposix],
   AS_HELP_STRING([--enable-pcreposix], [enable using PCRE Posix libs for regex functions]))
+AC_ARG_ENABLE([pcre2posix],
+  AS_HELP_STRING([--enable-pcre2posix], [enable using PCRE2 Posix libs for regex functions]))
 AC_ARG_ENABLE([fpm],
   AS_HELP_STRING([--enable-fpm], [enable Forwarding Plane Manager support]))
 AC_ARG_ENABLE([werror],
@@ -1659,6 +1661,16 @@ if test "$enable_pcreposix" = "yes"; then
 fi
 AC_SUBST([HAVE_LIBPCREPOSIX])
 
+dnl ---------------------------
+dnl check system has PCRE2 regexp
+dnl ---------------------------
+if test "$enable_pcre2posix" = "yes"; then
+  AC_CHECK_LIB([pcre2-posix], [regexec], [], [
+    AC_MSG_ERROR([--enable-pcre2posix given but unable to find libpcre2-posix])
+  ])
+fi
+AC_SUBST([HAVE_LIBPCRE2_POSIX])
+
 dnl ##########################################################################
 dnl test "$enable_clippy_only" != "yes"
 fi
index 48263222f82b958e19f1d7a6e181edca45fbfafb..044b48498458079cb46b7422844f7ea4229b30e6 100644 (file)
@@ -1,6 +1,7 @@
 debian/frr.conf usr/lib/tmpfiles.d
 etc/
 tools/etc/frr/frr.conf etc/frr/
+tools/etc/logrotate.d/frr etc/logrotate.d/
 tools/frr-reload usr/lib/frr/
 usr/bin/mtracebis
 usr/bin/vtysh
diff --git a/debian/frr.logrotate b/debian/frr.logrotate
deleted file mode 100644 (file)
index 735af65..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/var/log/frr/*.log {
-        size 500k
-        sharedscripts
-        missingok
-        compress
-        rotate 14
-        create 0640 frr frr
-
-        postrotate
-            pid=$(lsof -t -a -c /syslog/ /var/log/frr/* 2>/dev/null)
-            if [ -n "$pid" ]
-            then # using syslog
-                 kill -HUP $pid
-            fi
-            # in case using file logging; if switching back and forth
-            # between file and syslog, rsyslogd might still have file
-            # open, as well as the daemons, so always signal the daemons.
-            # It's safe, a NOP if (only) syslog is being used.
-            for i in babeld bgpd eigrpd isisd ldpd nhrpd ospf6d ospfd sharpd \
-                pimd pim6d ripd ripngd zebra pathd pbrd staticd bfdd fabricd vrrpd; do
-                if [ -e /var/run/frr/$i.pid ] ; then
-                    pids="$pids $(cat /var/run/frr/$i.pid)"
-                fi
-            done
-            [ -n "$pids" ] && kill -USR1 $pids || true
-        endscript
-}
index 2b106d43bc59429de22eb434f245c39b6ee5223c..737b88953b59373411b11f019ae3904d9bc176ea 100644 (file)
@@ -1,3 +1,4 @@
 # Any user may call vtysh but only those belonging to the group frrvty can
 # actually connect to the socket and use the program.
 auth   sufficient      pam_permit.so
+account        sufficient      pam_rootok.so
index ba35facf2a881393a1c7e9e87fb19e65daf7eae4..8f89c6c4f828d07755c9ac78a1d204151b631fd3 100644 (file)
@@ -368,6 +368,13 @@ options from the list below.
 
    Turn on the usage of PCRE Posix libs for regex functionality.
 
+.. option:: --enable-pcre2posix
+
+   Turn on the usage of PCRE2 Posix libs for regex functionality.
+
+   PCRE2 versions <= 10.31 work a bit differently. We suggest using at least
+   >= 10.36.
+
 .. option:: --enable-rpath
 
    Set hardcoded rpaths in the executable [default=yes].
index f0b76f10b7a1197c3925fca6c142ff12cd20a8da..ec107fbe47253356dbe7519141db441c04720fdf 100644 (file)
@@ -175,7 +175,7 @@ controller and obtain those by means of the PCEP protocol.
 .. image:: images/pathd_initiated_multi.png
 
 Starting
-=============
+========
 
 Default configuration file for *pathd* is :file:`pathd.conf`.  The typical
 location of :file:`pathd.conf` is |INSTALL_PREFIX_ETC|/pathd.conf.
@@ -480,6 +480,12 @@ Configuration Commands
 
    Specify a peer and its precedence in a PCC definition.
 
+Debugging
+---------
+
+.. clicmd:: debug pathd policy
+
+   Enable or disable Pathd policy information.
 
 Introspection Commands
 ----------------------
index 0a843b9283227aa54479d848517046d202713d4a..db43266d68bef9d861d7082d998720eca5dfb208 100644 (file)
@@ -810,6 +810,36 @@ and this section also helps that case.
       !
    ...
 
+.. clicmd:: behavior usid
+
+   Specify the SRv6 locator as a Micro-segment (uSID) locator. When a locator is
+   specified as a uSID locator, all the SRv6 SIDs allocated from the locator by the routing
+   protocols are bound to the SRv6 uSID behaviors. For example, if you configure BGP to use
+   a locator specified as a uSID locator, BGP instantiates and advertises SRv6 uSID behaviors
+   (e.g., ``uDT4`` / ``uDT6`` / ``uDT46``) instead of classic SRv6 behaviors
+   (e.g., ``End.DT4`` / ``End.DT6`` / ``End.DT46``).
+
+::
+
+   router# configure terminal
+   router(config)# segment-routinig
+   router(config-sr)# srv6
+   router(config-srv6)# locators
+   router(config-srv6-locators)# locator loc1
+   router(config-srv6-locator)# prefix fc00:0:1::/48 block-len 32 node-len 16 func-bits 16
+   router(config-srv6-locator)# behavior usid
+
+   router(config-srv6-locator)# show run
+   ...
+   segment-routing
+    srv6
+     locators
+      locator loc1
+       prefix fc00:0:1::/48
+       behavior usid
+      !
+   ...
+
 .. _multicast-rib-commands:
 
 Multicast RIB Commands
index b9278dbb880e58f64e2360be3ae5e70defd3c0fe..238a7fc4097e280d134fc9a06b791e666496e474 100644 (file)
@@ -1,7 +1,7 @@
 # syntax=docker/dockerfile:1
 
 # Create a basic stage set up to build APKs
-FROM alpine:3.15 as alpine-builder
+FROM alpine:3.16 as alpine-builder
 RUN apk add \
                --update-cache \
                abuild \
@@ -13,7 +13,7 @@ RUN apk add \
 RUN adduser -D -G abuild builder && su builder -c 'abuild-keygen -a -n'
 
 # This stage builds a dist tarball from the source
-FROM alpine:3.15 as source-builder
+FROM alpine:3.16 as source-builder
 
 RUN mkdir -p /src/alpine
 COPY alpine/APKBUILD.in /src/alpine
@@ -48,7 +48,7 @@ RUN cd /dist \
        && abuild -r -P /pkgs/apk
 
 # This stage installs frr from the apk
-FROM alpine:3.15
+FROM alpine:3.16
 RUN mkdir -p /pkgs/apk
 COPY --from=alpine-apk-builder /pkgs/apk/ /pkgs/apk/
 RUN apk add \
index 1b98b224cc9e329d0fad8adbec15d2662feac4dc..d66c6f8c16f71ba049f7e074397b478e1cf4724e 100644 (file)
 #include <string.h>
 #include <ctype.h>
 #include <sys/types.h>
-#ifdef HAVE_LIBPCREPOSIX
+#ifdef HAVE_LIBPCRE2_POSIX
+#ifndef _FRR_PCRE2_POSIX
+#define _FRR_PCRE2_POSIX
+#include <pcre2posix.h>
+#endif /* _FRR_PCRE2_POSIX */
+#elif defined(HAVE_LIBPCREPOSIX)
 #include <pcreposix.h>
 #else
 #include <regex.h>
-#endif /* HAVE_LIBPCREPOSIX */
+#endif /* HAVE_LIBPCRE2_POSIX */
 
 #include "frrstr.h"
 #include "memory.h"
index d52d6a4482293440a758ea12f3abb5deb29342e8..f0066d0fc5e8564f77e68874d4d058d955226b96 100644 (file)
 
 #include <sys/types.h>
 #include <sys/types.h>
-#ifdef HAVE_LIBPCREPOSIX
+#ifdef HAVE_LIBPCRE2_POSIX
+#ifndef _FRR_PCRE2_POSIX
+#define _FRR_PCRE2_POSIX
+#include <pcre2posix.h>
+#endif /* _FRR_PCRE2_POSIX */
+#elif defined(HAVE_LIBPCREPOSIX)
 #include <pcreposix.h>
 #else
 #include <regex.h>
-#endif /* HAVE_LIBPCREPOSIX */
+#endif /* HAVE_LIBPCRE2_POSIX */
 #include <stdbool.h>
 
 #include "vector.h"
index d7ab358afea794f45f7fd207c79386eded772df9..43b3028200c7e9c71d0a81497833b2cac61a7d61 100644 (file)
@@ -61,6 +61,8 @@ struct ipaddr {
 #define IPADDRSZ(p)                                                            \
        (IS_IPADDR_V4((p)) ? sizeof(struct in_addr) : sizeof(struct in6_addr))
 
+#define IPADDR_STRING_SIZE 46
+
 static inline int ipaddr_family(const struct ipaddr *ip)
 {
        switch (ip->ipa_type) {
index 1c2c8913d5d3a8a99980a934426624023b55b018..5cd82080f5442759d664fdbec8d4ce58f666bf31 100644 (file)
@@ -241,6 +241,10 @@ json_object *srv6_locator_json(const struct srv6_locator *loc)
        json_object_int_add(jo_root, "argumentBitsLength",
                            loc->argument_bits_length);
 
+       /* set true if the locator is a Micro-segment (uSID) locator */
+       if (CHECK_FLAG(loc->flags, SRV6_LOCATOR_USID))
+               json_object_string_add(jo_root, "behavior", "usid");
+
        /* set status_up */
        json_object_boolean_add(jo_root, "statusUp",
                                loc->status_up);
@@ -286,6 +290,10 @@ json_object *srv6_locator_detailed_json(const struct srv6_locator *loc)
        json_object_int_add(jo_root, "argumentBitsLength",
                            loc->argument_bits_length);
 
+       /* set true if the locator is a Micro-segment (uSID) locator */
+       if (CHECK_FLAG(loc->flags, SRV6_LOCATOR_USID))
+               json_object_string_add(jo_root, "behavior", "usid");
+
        /* set algonum */
        json_object_int_add(jo_root, "algoNum", loc->algonum);
 
index 18d5bdebc2e44981bf814a53c396fb721da029ae..acfb0631cc0ef2d3722423c71dc7318072ed29c0 100644 (file)
@@ -92,6 +92,9 @@ struct srv6_locator {
        bool status_up;
        struct list *chunks;
 
+       uint8_t flags;
+#define SRV6_LOCATOR_USID (1 << 0) /* The SRv6 Locator is a uSID Locator */
+
        QOBJ_FIELDS;
 };
 DECLARE_QOBJ_TYPE(srv6_locator);
@@ -116,6 +119,23 @@ struct srv6_locator_chunk {
        uint8_t proto;
        uint16_t instance;
        uint32_t session_id;
+
+       uint8_t flags;
+};
+
+/*
+ * SRv6 Endpoint Behavior codepoints, as defined by IANA in
+ * https://www.iana.org/assignments/segment-routing/segment-routing.xhtml
+ */
+enum srv6_endpoint_behavior_codepoint {
+       SRV6_ENDPOINT_BEHAVIOR_RESERVED       = 0x0000,
+       SRV6_ENDPOINT_BEHAVIOR_END_DT6        = 0x0012,
+       SRV6_ENDPOINT_BEHAVIOR_END_DT4        = 0x0013,
+       SRV6_ENDPOINT_BEHAVIOR_END_DT46       = 0x0014,
+       SRV6_ENDPOINT_BEHAVIOR_END_DT6_USID   = 0x003E,
+       SRV6_ENDPOINT_BEHAVIOR_END_DT4_USID   = 0x003F,
+       SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID  = 0x0040,
+       SRV6_ENDPOINT_BEHAVIOR_OPAQUE         = 0xFFFF,
 };
 
 struct nexthop_srv6 {
index d524ae53cba81fe90bee24424d692f01495cbb60..5fe8d82473b10a9bb18306fcde68e4d94738b4da 100644 (file)
--- a/lib/vty.c
+++ b/lib/vty.c
 #include <lib/version.h>
 #include <sys/types.h>
 #include <sys/types.h>
-#ifdef HAVE_LIBPCREPOSIX
+#ifdef HAVE_LIBPCRE2_POSIX
+#ifndef _FRR_PCRE2_POSIX
+#define _FRR_PCRE2_POSIX
+#include <pcre2posix.h>
+#endif /* _FRR_PCRE2_POSIX */
+#elif defined(HAVE_LIBPCREPOSIX)
 #include <pcreposix.h>
 #else
 #include <regex.h>
-#endif /* HAVE_LIBPCREPOSIX */
+#endif /* HAVE_LIBPCRE2_POSIX */
 #include <stdio.h>
 
 #include "linklist.h"
index 430579c5a8776caf5b541138425d9029dd2e0750..0b3fd2443f954cf14e65e169c4e2d122a594b40f 100644 (file)
--- a/lib/vty.h
+++ b/lib/vty.h
 #define _ZEBRA_VTY_H
 
 #include <sys/types.h>
-#ifdef HAVE_LIBPCREPOSIX
+#ifdef HAVE_LIBPCRE2_POSIX
+#ifndef _FRR_PCRE2_POSIX
+#define _FRR_PCRE2_POSIX
+#include <pcre2posix.h>
+#endif /* _FRR_PCRE2_POSIX */
+#elif defined(HAVE_LIBPCREPOSIX)
 #include <pcreposix.h>
 #else
 #include <regex.h>
-#endif /* HAVE_LIBPCREPOSIX */
+#endif /* HAVE_LIBPCRE2_POSIX */
 
 #include "thread.h"
 #include "log.h"
index 2517773dc436e32cb7e1121b60c7069e4e3fd5bc..fd6eb7db0d60a59c5c503a14354d6f051ed0eb44 100644 (file)
@@ -1088,6 +1088,7 @@ int zapi_srv6_locator_chunk_encode(struct stream *s,
        stream_putc(s, c->node_bits_length);
        stream_putc(s, c->function_bits_length);
        stream_putc(s, c->argument_bits_length);
+       stream_putc(s, c->flags);
        return 0;
 }
 
@@ -1109,6 +1110,7 @@ int zapi_srv6_locator_chunk_decode(struct stream *s,
        STREAM_GETC(s, c->node_bits_length);
        STREAM_GETC(s, c->function_bits_length);
        STREAM_GETC(s, c->argument_bits_length);
+       STREAM_GETC(s, c->flags);
        return 0;
 
 stream_failure:
index 4fb3a33568e218bd5d29a9b8ce37360a8fd3a5d5..a67b6c6c19586e352174f3686ea85513878df42b 100644 (file)
@@ -2205,7 +2205,7 @@ struct ospf_lsa *ospf_external_lsa_originate(struct ospf *ospf,
           */
 
        if (ospf->router_id.s_addr == INADDR_ANY) {
-               if (IS_DEBUG_OSPF_EVENT)
+               if (ei && IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
                                "LSA[Type5:%pI4]: deferring AS-external-LSA origination, router ID is zero",
                                &ei->p.prefix);
@@ -2214,7 +2214,7 @@ struct ospf_lsa *ospf_external_lsa_originate(struct ospf *ospf,
 
        /* Create new AS-external-LSA instance. */
        if ((new = ospf_external_lsa_new(ospf, ei, NULL)) == NULL) {
-               if (IS_DEBUG_OSPF_EVENT)
+               if (ei && IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
                                "LSA[Type5:%pI4]: Could not originate AS-external-LSA",
                                &ei->p.prefix);
index a6540cc84a1e2f06d6d2813ff1799f4814bc3e91..b88453c68f899697eaa2dd0bcedc38afe87ab7f9 100644 (file)
@@ -126,7 +126,7 @@ DEFPY(show_srte_policy,
        ttable_rowseps(tt, 0, BOTTOM, true, '-');
 
        RB_FOREACH (policy, srte_policy_head, &srte_policies) {
-               char endpoint[46];
+               char endpoint[ENDPOINT_STR_LENGTH];
                char binding_sid[16] = "-";
 
                ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
@@ -173,7 +173,7 @@ DEFPY(show_srte_policy_detail,
        vty_out(vty, "\n");
        RB_FOREACH (policy, srte_policy_head, &srte_policies) {
                struct srte_candidate *candidate;
-               char endpoint[46];
+               char endpoint[ENDPOINT_STR_LENGTH];
                char binding_sid[16] = "-";
                char *segment_list_info;
                static char undefined_info[] = "(undefined)";
@@ -1091,8 +1091,25 @@ DEFPY_NOSH(show_debugging_pathd, show_debugging_pathd_cmd,
           "pathd module debugging\n")
 {
 
+       vty_out(vty, "Path debugging status:\n");
+
        cmd_show_lib_debugs(vty);
        /* nothing to do here */
+       path_ted_show_debugging(vty);
+       path_policy_show_debugging(vty);
+       return CMD_SUCCESS;
+}
+
+DEFPY(debug_path_policy, debug_path_policy_cmd, "[no] debug pathd policy",
+      NO_STR DEBUG_STR
+      "path debugging\n"
+      "policy debugging\n")
+{
+       uint32_t mode = DEBUG_NODE2MODE(vty->node);
+       bool no_debug = no;
+
+       DEBUG_MODE_SET(&path_policy_debug, mode, !no);
+       DEBUG_FLAGS_SET(&path_policy_debug, PATH_POLICY_DEBUG_BASIC, !no_debug);
        return CMD_SUCCESS;
 }
 
@@ -1291,8 +1308,34 @@ int config_write_segment_routing(struct vty *vty)
        return 1;
 }
 
+static int path_policy_cli_debug_config_write(struct vty *vty)
+{
+       if (DEBUG_MODE_CHECK(&path_policy_debug, DEBUG_MODE_CONF)) {
+               if (DEBUG_FLAGS_CHECK(&path_policy_debug,
+                                     PATH_POLICY_DEBUG_BASIC))
+                       vty_out(vty, "debug pathd policy\n");
+               return 1;
+       }
+       return 0;
+}
+
+static int path_policy_cli_debug_set_all(uint32_t flags, bool set)
+{
+       DEBUG_FLAGS_SET(&path_policy_debug, flags, set);
+
+       /* If all modes have been turned off, don't preserve options. */
+       if (!DEBUG_MODE_CHECK(&path_policy_debug, DEBUG_MODE_ALL))
+               DEBUG_CLEAR(&path_policy_debug);
+
+       return 0;
+}
+
 void path_cli_init(void)
 {
+       hook_register(nb_client_debug_config_write,
+                     path_policy_cli_debug_config_write);
+       hook_register(nb_client_debug_set_all, path_policy_cli_debug_set_all);
+
        install_node(&segment_routing_node);
        install_node(&sr_traffic_eng_node);
        install_node(&srte_segment_list_node);
@@ -1308,6 +1351,9 @@ void path_cli_init(void)
        install_element(ENABLE_NODE, &show_srte_policy_cmd);
        install_element(ENABLE_NODE, &show_srte_policy_detail_cmd);
 
+       install_element(ENABLE_NODE, &debug_path_policy_cmd);
+       install_element(CONFIG_NODE, &debug_path_policy_cmd);
+
        install_element(CONFIG_NODE, &segment_routing_cmd);
        install_element(SEGMENT_ROUTING_NODE, &sr_traffic_eng_cmd);
        install_element(SR_TRAFFIC_ENG_NODE, &srte_segment_list_cmd);
index 68748af53e7a3fea432155572074c2c3deb929ab..5fc8a1f03252d765247edd4d10057ca8398cdb26 100644 (file)
@@ -488,6 +488,12 @@ int path_ted_cli_debug_config_write(struct vty *vty)
        return 0;
 }
 
+void path_ted_show_debugging(struct vty *vty)
+{
+       if (DEBUG_FLAGS_CHECK(&ted_state_g.dbg, PATH_TED_DEBUG_BASIC))
+               vty_out(vty, "  Path TED debugging is on\n");
+}
+
 int path_ted_cli_debug_set_all(uint32_t flags, bool set)
 {
        DEBUG_FLAGS_SET(&ted_state_g.dbg, flags, set);
index c6897b152032e96c3de4f34eab32c95544c1fa43..5a0c8eecd337363b2b3f0f9c8cb61e261ccffc6b 100644 (file)
@@ -101,6 +101,7 @@ int path_ted_segment_list_refresh(void);
 
 /* TED configuration functions */
 uint32_t path_ted_config_write(struct vty *vty);
+void path_ted_show_debugging(struct vty *vty);
 
 /* TED util functions */
 /* clang-format off */
index e9d7cc6fc707c7a17866198819364927c7532bb2..167c88aeab1eaba4c4cbb989211ed292eee0d24a 100644 (file)
@@ -23,6 +23,8 @@
 #include "lib_errors.h"
 #include "network.h"
 #include "libfrr.h"
+#include <debug.h>
+#include <hook.h>
 
 #include "pathd/pathd.h"
 #include "pathd/path_zebra.h"
@@ -44,6 +46,17 @@ DEFINE_HOOK(pathd_candidate_updated, (struct srte_candidate * candidate),
 DEFINE_HOOK(pathd_candidate_removed, (struct srte_candidate * candidate),
            (candidate));
 
+struct debug path_policy_debug;
+
+#define PATH_POLICY_DEBUG(fmt, ...)                                            \
+       do {                                                                   \
+               if (DEBUG_FLAGS_CHECK(&path_policy_debug,                      \
+                                     PATH_POLICY_DEBUG_BASIC))                \
+                       DEBUGD(&path_policy_debug, "policy: " fmt,             \
+                              ##__VA_ARGS__);                                 \
+       } while (0)
+
+
 static void trigger_pathd_candidate_created(struct srte_candidate *candidate);
 static void trigger_pathd_candidate_created_timer(struct thread *thread);
 static void trigger_pathd_candidate_updated(struct srte_candidate *candidate);
@@ -97,6 +110,20 @@ RB_GENERATE(srte_policy_head, srte_policy, entry, srte_policy_compare)
 
 struct srte_policy_head srte_policies = RB_INITIALIZER(&srte_policies);
 
+static void srte_policy_status_log(struct srte_policy *policy)
+{
+       char endpoint[ENDPOINT_STR_LENGTH];
+
+       ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
+       if (policy->status == SRTE_POLICY_STATUS_DOWN) {
+               PATH_POLICY_DEBUG("SR-TE(%s, %u): policy is DOWN", endpoint,
+                                 policy->color);
+       } else if (policy->status == SRTE_POLICY_STATUS_UP) {
+               PATH_POLICY_DEBUG("SR-TE(%s, %u): policy is UP", endpoint,
+                                 policy->color);
+       }
+}
+
 /**
  * Adds a segment list to pathd.
  *
@@ -531,6 +558,10 @@ void srte_apply_changes(void)
 
        RB_FOREACH_SAFE (policy, srte_policy_head, &srte_policies, safe_pol) {
                if (CHECK_FLAG(policy->flags, F_POLICY_DELETED)) {
+                       if (policy->status != SRTE_POLICY_STATUS_DOWN) {
+                               policy->status = SRTE_POLICY_STATUS_DOWN;
+                               srte_policy_status_log(policy);
+                       }
                        srte_policy_del(policy);
                        continue;
                }
@@ -565,7 +596,7 @@ void srte_policy_apply_changes(struct srte_policy *policy)
        struct srte_candidate *candidate, *safe;
        struct srte_candidate *old_best_candidate;
        struct srte_candidate *new_best_candidate;
-       char endpoint[46];
+       char endpoint[ENDPOINT_STR_LENGTH];
 
        ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
 
@@ -574,8 +605,7 @@ void srte_policy_apply_changes(struct srte_policy *policy)
        new_best_candidate = srte_policy_best_candidate(policy);
 
        if (new_best_candidate != old_best_candidate) {
-               /* TODO: add debug guard. */
-               zlog_debug(
+               PATH_POLICY_DEBUG(
                        "SR-TE(%s, %u): best candidate changed from %s to %s",
                        endpoint, policy->color,
                        old_best_candidate ? old_best_candidate->name : "none",
@@ -617,10 +647,10 @@ void srte_policy_apply_changes(struct srte_policy *policy)
                                   F_SEGMENT_LIST_MODIFIED);
 
                if (candidate_changed || segment_list_changed) {
-                       /* TODO: add debug guard. */
-                       zlog_debug("SR-TE(%s, %u): best candidate %s changed",
-                                  endpoint, policy->color,
-                                  new_best_candidate->name);
+                       PATH_POLICY_DEBUG(
+                               "SR-TE(%s, %u): best candidate %s changed",
+                               endpoint, policy->color,
+                               new_best_candidate->name);
 
                        path_zebra_add_sr_policy(
                                policy, new_best_candidate->lsp->segment_list);
@@ -722,10 +752,10 @@ void srte_candidate_set_bandwidth(struct srte_candidate *candidate,
                                  float bandwidth, bool required)
 {
        struct srte_policy *policy = candidate->policy;
-       char endpoint[46];
+       char endpoint[ENDPOINT_STR_LENGTH];
 
        ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
-       zlog_debug(
+       PATH_POLICY_DEBUG(
                "SR-TE(%s, %u): candidate %s %sconfig bandwidth set to %f B/s",
                endpoint, policy->color, candidate->name,
                required ? "required " : "", bandwidth);
@@ -750,11 +780,13 @@ void srte_lsp_set_bandwidth(struct srte_lsp *lsp, float bandwidth,
 {
        struct srte_candidate *candidate = lsp->candidate;
        struct srte_policy *policy = candidate->policy;
-       char endpoint[46];
+       char endpoint[ENDPOINT_STR_LENGTH];
+
        ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
-       zlog_debug("SR-TE(%s, %u): candidate %s %slsp bandwidth set to %f B/s",
-                  endpoint, policy->color, candidate->name,
-                  required ? "required" : "", bandwidth);
+       PATH_POLICY_DEBUG(
+               "SR-TE(%s, %u): candidate %s %slsp bandwidth set to %f B/s",
+               endpoint, policy->color, candidate->name,
+               required ? "required" : "", bandwidth);
        SET_FLAG(lsp->flags, F_CANDIDATE_HAS_BANDWIDTH);
        COND_FLAG(lsp->flags, F_CANDIDATE_REQUIRED_BANDWIDTH, required);
        lsp->bandwidth = bandwidth;
@@ -770,10 +802,11 @@ void srte_lsp_set_bandwidth(struct srte_lsp *lsp, float bandwidth,
 void srte_candidate_unset_bandwidth(struct srte_candidate *candidate)
 {
        struct srte_policy *policy = candidate->policy;
-       char endpoint[46];
+       char endpoint[ENDPOINT_STR_LENGTH];
+
        ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
-       zlog_debug("SR-TE(%s, %u): candidate %s config bandwidth unset",
-                  endpoint, policy->color, candidate->name);
+       PATH_POLICY_DEBUG("SR-TE(%s, %u): candidate %s config bandwidth unset",
+                         endpoint, policy->color, candidate->name);
        UNSET_FLAG(candidate->flags, F_CANDIDATE_HAS_BANDWIDTH);
        UNSET_FLAG(candidate->flags, F_CANDIDATE_REQUIRED_BANDWIDTH);
        candidate->bandwidth = 0;
@@ -792,10 +825,11 @@ void srte_lsp_unset_bandwidth(struct srte_lsp *lsp)
 {
        struct srte_candidate *candidate = lsp->candidate;
        struct srte_policy *policy = candidate->policy;
-       char endpoint[46];
+       char endpoint[ENDPOINT_STR_LENGTH];
+
        ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
-       zlog_debug("SR-TE(%s, %u): candidate %s lsp bandwidth unset", endpoint,
-                  policy->color, candidate->name);
+       PATH_POLICY_DEBUG("SR-TE(%s, %u): candidate %s lsp bandwidth unset",
+                         endpoint, policy->color, candidate->name);
        UNSET_FLAG(lsp->flags, F_CANDIDATE_HAS_BANDWIDTH);
        UNSET_FLAG(lsp->flags, F_CANDIDATE_REQUIRED_BANDWIDTH);
        SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);
@@ -820,9 +854,10 @@ void srte_candidate_set_metric(struct srte_candidate *candidate,
                               bool is_computed)
 {
        struct srte_policy *policy = candidate->policy;
-       char endpoint[46];
+       char endpoint[ENDPOINT_STR_LENGTH];
+
        ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
-       zlog_debug(
+       PATH_POLICY_DEBUG(
                "SR-TE(%s, %u): candidate %s %sconfig metric %s (%u) set to %f (is-bound: %s; is_computed: %s)",
                endpoint, policy->color, candidate->name,
                required ? "required " : "", srte_candidate_metric_name(type),
@@ -854,9 +889,10 @@ void srte_lsp_set_metric(struct srte_lsp *lsp,
 {
        struct srte_candidate *candidate = lsp->candidate;
        struct srte_policy *policy = candidate->policy;
-       char endpoint[46];
+       char endpoint[ENDPOINT_STR_LENGTH];
+
        ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
-       zlog_debug(
+       PATH_POLICY_DEBUG(
                "SR-TE(%s, %u): candidate %s %slsp metric %s (%u) set to %f (is-bound: %s; is_computed: %s)",
                endpoint, policy->color, candidate->name,
                required ? "required " : "", srte_candidate_metric_name(type),
@@ -889,11 +925,13 @@ void srte_candidate_unset_metric(struct srte_candidate *candidate,
                                 enum srte_candidate_metric_type type)
 {
        struct srte_policy *policy = candidate->policy;
-       char endpoint[46];
+       char endpoint[ENDPOINT_STR_LENGTH];
+
        ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
-       zlog_debug("SR-TE(%s, %u): candidate %s config metric %s (%u) unset",
-                  endpoint, policy->color, candidate->name,
-                  srte_candidate_metric_name(type), type);
+       PATH_POLICY_DEBUG(
+               "SR-TE(%s, %u): candidate %s config metric %s (%u) unset",
+               endpoint, policy->color, candidate->name,
+               srte_candidate_metric_name(type), type);
        assert((type > 0) && (type <= MAX_METRIC_TYPE));
        srte_unset_metric(&candidate->metrics[type - 1]);
        srte_lsp_unset_metric(candidate->lsp, type);
@@ -913,11 +951,13 @@ void srte_lsp_unset_metric(struct srte_lsp *lsp,
 {
        struct srte_candidate *candidate = lsp->candidate;
        struct srte_policy *policy = candidate->policy;
-       char endpoint[46];
+       char endpoint[ENDPOINT_STR_LENGTH];
+
        ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
-       zlog_debug("SR-TE(%s, %u): candidate %s lsp metric %s (%u) unset",
-                  endpoint, policy->color, candidate->name,
-                  srte_candidate_metric_name(type), type);
+       PATH_POLICY_DEBUG(
+               "SR-TE(%s, %u): candidate %s lsp metric %s (%u) unset",
+               endpoint, policy->color, candidate->name,
+               srte_candidate_metric_name(type), type);
        assert((type > 0) && (type <= MAX_METRIC_TYPE));
        srte_unset_metric(&lsp->metrics[type - 1]);
 }
@@ -941,16 +981,18 @@ void srte_candidate_set_objfun(struct srte_candidate *candidate, bool required,
                               enum objfun_type type)
 {
        struct srte_policy *policy = candidate->policy;
-       char endpoint[46];
+       char endpoint[ENDPOINT_STR_LENGTH];
+
        ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
 
        candidate->objfun = type;
        SET_FLAG(candidate->flags, F_CANDIDATE_HAS_OBJFUN);
        COND_FLAG(candidate->flags, F_CANDIDATE_REQUIRED_OBJFUN, required);
        SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);
-       zlog_debug("SR-TE(%s, %u): candidate %s %sobjective function set to %s",
-                  endpoint, policy->color, candidate->name,
-                  required ? "required " : "", objfun_type_name(type));
+       PATH_POLICY_DEBUG(
+               "SR-TE(%s, %u): candidate %s %sobjective function set to %s",
+               endpoint, policy->color, candidate->name,
+               required ? "required " : "", objfun_type_name(type));
 }
 
 /**
@@ -961,14 +1003,15 @@ void srte_candidate_set_objfun(struct srte_candidate *candidate, bool required,
 void srte_candidate_unset_objfun(struct srte_candidate *candidate)
 {
        struct srte_policy *policy = candidate->policy;
-       char endpoint[46];
+       char endpoint[ENDPOINT_STR_LENGTH];
+
        ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
 
        UNSET_FLAG(candidate->flags, F_CANDIDATE_HAS_OBJFUN);
        UNSET_FLAG(candidate->flags, F_CANDIDATE_REQUIRED_OBJFUN);
        SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);
        candidate->objfun = OBJFUN_UNDEFINED;
-       zlog_debug(
+       PATH_POLICY_DEBUG(
                "SR-TE(%s, %u): candidate %s objective functions preferences unset",
                endpoint, policy->color, candidate->name);
 }
@@ -1013,7 +1056,8 @@ void srte_candidate_set_affinity_filter(struct srte_candidate *candidate,
                                        uint32_t filter)
 {
        struct srte_policy *policy = candidate->policy;
-       char endpoint[46];
+       char endpoint[ENDPOINT_STR_LENGTH];
+
        ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
 
        assert(type > AFFINITY_FILTER_UNDEFINED);
@@ -1021,7 +1065,7 @@ void srte_candidate_set_affinity_filter(struct srte_candidate *candidate,
        SET_FLAG(candidate->flags, filter_type_to_flag(type));
        SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);
        candidate->affinity_filters[type - 1] = filter;
-       zlog_debug(
+       PATH_POLICY_DEBUG(
                "SR-TE(%s, %u): candidate %s affinity filter %s set to 0x%08x",
                endpoint, policy->color, candidate->name,
                filter_type_name(type), filter);
@@ -1038,7 +1082,8 @@ void srte_candidate_unset_affinity_filter(struct srte_candidate *candidate,
                                          enum affinity_filter_type type)
 {
        struct srte_policy *policy = candidate->policy;
-       char endpoint[46];
+       char endpoint[ENDPOINT_STR_LENGTH];
+
        ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
 
        assert(type > AFFINITY_FILTER_UNDEFINED);
@@ -1046,9 +1091,10 @@ void srte_candidate_unset_affinity_filter(struct srte_candidate *candidate,
        UNSET_FLAG(candidate->flags, filter_type_to_flag(type));
        SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);
        candidate->affinity_filters[type - 1] = 0;
-       zlog_debug("SR-TE(%s, %u): candidate %s affinity filter %s unset",
-                  endpoint, policy->color, candidate->name,
-                  filter_type_name(type));
+       PATH_POLICY_DEBUG(
+               "SR-TE(%s, %u): candidate %s affinity filter %s unset",
+               endpoint, policy->color, candidate->name,
+               filter_type_name(type));
 }
 
 /**
@@ -1093,10 +1139,11 @@ srte_segment_entry_find(struct srte_segment_list *segment_list, uint32_t index)
 void srte_candidate_status_update(struct srte_candidate *candidate, int status)
 {
        struct srte_policy *policy = candidate->policy;
-       char endpoint[46];
+       char endpoint[ENDPOINT_STR_LENGTH];
+
        ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
-       zlog_debug("SR-TE(%s, %u): zebra updated status to %d", endpoint,
-                  policy->color, status);
+       PATH_POLICY_DEBUG("SR-TE(%s, %u): zebra updated status to %d", endpoint,
+                         policy->color, status);
        switch (status) {
        case ZEBRA_SR_POLICY_DOWN:
                switch (policy->status) {
@@ -1109,9 +1156,8 @@ void srte_candidate_status_update(struct srte_candidate *candidate, int status)
                case SRTE_POLICY_STATUS_DOWN:
                        return;
                default:
-                       zlog_debug("SR-TE(%s, %u): policy is DOWN", endpoint,
-                                  policy->color);
                        policy->status = SRTE_POLICY_STATUS_DOWN;
+                       srte_policy_status_log(policy);
                        break;
                }
                break;
@@ -1120,9 +1166,8 @@ void srte_candidate_status_update(struct srte_candidate *candidate, int status)
                case SRTE_POLICY_STATUS_UP:
                        return;
                default:
-                       zlog_debug("SR-TE(%s, %u): policy is UP", endpoint,
-                                  policy->color);
                        policy->status = SRTE_POLICY_STATUS_UP;
+                       srte_policy_status_log(policy);
                        break;
                }
                break;
@@ -1148,19 +1193,20 @@ void srte_candidate_unset_segment_list(const char *originator, bool force)
                return;
        }
 
-       zlog_debug("Unset segment lists for originator %s", originator);
+       PATH_POLICY_DEBUG("Unset segment lists for originator %s", originator);
 
        /* Iterate the policies, then iterate each policy's candidate path
         * to check the candidate path's segment list originator */
        struct srte_policy *policy;
        RB_FOREACH (policy, srte_policy_head, &srte_policies) {
-               zlog_debug("Unset segment lists checking policy %s",
-                          policy->name);
+               PATH_POLICY_DEBUG("Unset segment lists checking policy %s",
+                                 policy->name);
                struct srte_candidate *candidate;
                RB_FOREACH (candidate, srte_candidate_head,
                            &policy->candidate_paths) {
-                       zlog_debug("Unset segment lists checking candidate %s",
-                                  candidate->name);
+                       PATH_POLICY_DEBUG(
+                               "Unset segment lists checking candidate %s",
+                               candidate->name);
                        if (candidate->lsp == NULL) {
                                continue;
                        }
@@ -1190,8 +1236,8 @@ void srte_candidate_unset_segment_list(const char *originator, bool force)
                                    sizeof(segment_list->originator))
                                    == 0
                            || force) {
-                               zlog_debug("Unset segment list %s",
-                                          segment_list->name);
+                               PATH_POLICY_DEBUG("Unset segment list %s",
+                                                 segment_list->name);
                                SET_FLAG(segment_list->flags,
                                         F_SEGMENT_LIST_DELETED);
                                SET_FLAG(candidate->flags,
@@ -1222,6 +1268,12 @@ const char *srte_origin2str(enum srte_protocol_origin origin)
        }
 }
 
+void path_policy_show_debugging(struct vty *vty)
+{
+       if (DEBUG_FLAGS_CHECK(&path_policy_debug, PATH_POLICY_DEBUG_BASIC))
+               vty_out(vty, "  Path policy debugging is on\n");
+}
+
 void pathd_shutdown(void)
 {
        path_ted_teardown();
@@ -1347,8 +1399,9 @@ int32_t srte_ted_do_query_type_c(struct srte_segment_entry *entry,
                zlog_warn(" %s: PATHD-TED: SL: ERROR query C : ted-sid (%d)",
                          __func__, ted_sid);
        } else {
-               zlog_debug("%s: PATHD-TED: SL: Success query C : ted-sid (%d)",
-                          __func__, ted_sid);
+               PATH_TED_DEBUG(
+                       "%s: PATHD-TED: SL: Success query C : ted-sid (%d)",
+                       __func__, ted_sid);
        }
        if (CHECK_SID(entry->segment_list->protocol_origin, ted_sid,
                      entry->sid_value)) {
@@ -1377,8 +1430,9 @@ int32_t srte_ted_do_query_type_e(struct srte_segment_entry *entry,
                zlog_warn(" %s: PATHD-TED: SL: ERROR query E : ted-sid (%d)",
                          __func__, ted_sid);
        } else {
-               zlog_debug("%s: PATHD-TED: SL: Success query E : ted-sid (%d)",
-                          __func__, ted_sid);
+               PATH_TED_DEBUG(
+                       "%s: PATHD-TED: SL: Success query E : ted-sid (%d)",
+                       __func__, ted_sid);
        }
        if (CHECK_SID(entry->segment_list->protocol_origin, ted_sid,
                      entry->sid_value)) {
@@ -1406,8 +1460,8 @@ int32_t srte_ted_do_query_type_f(struct srte_segment_entry *entry,
                zlog_warn("%s:SL:  ERROR query F : ted-sid (%d)", __func__,
                          ted_sid);
        } else {
-               zlog_debug("%s:SL: Success query F : ted-sid (%d)", __func__,
-                          ted_sid);
+               PATH_TED_DEBUG("%s:SL: Success query F : ted-sid (%d)",
+                              __func__, ted_sid);
        }
        if (CHECK_SID(entry->segment_list->protocol_origin, ted_sid,
                      entry->sid_value)) {
index 81d7aa91054adfb9769ed651f4bd84bed400c1de..bb2e63c04ba725dfa44721974e059eb248dd50f4 100644 (file)
@@ -43,6 +43,10 @@ enum srte_protocol_origin {
        SRTE_ORIGIN_LOCAL = 3,
 };
 
+extern struct debug path_policy_debug;
+
+#define PATH_POLICY_DEBUG_BASIC 0x01
+
 enum srte_policy_status {
        SRTE_POLICY_STATUS_UNKNOWN = 0,
        SRTE_POLICY_STATUS_DOWN = 1,
@@ -326,6 +330,8 @@ struct srte_candidate {
 RB_HEAD(srte_candidate_head, srte_candidate);
 RB_PROTOTYPE(srte_candidate_head, srte_candidate, entry, srte_candidate_compare)
 
+#define ENDPOINT_STR_LENGTH IPADDR_STRING_SIZE
+
 struct srte_policy {
        RB_ENTRY(srte_policy) entry;
 
@@ -444,6 +450,7 @@ void srte_candidate_status_update(struct srte_candidate *candidate, int status);
 void srte_candidate_unset_segment_list(const char *originator, bool force);
 const char *srte_origin2str(enum srte_protocol_origin origin);
 void pathd_shutdown(void);
+void path_policy_show_debugging(struct vty *vty);
 
 /* path_cli.c */
 void path_cli_init(void);
index 6f272f008519ec911a7d95192aecf0aa8c14d0aa..db9156b04b55d2517ee0b760b430b55e8131408d 100644 (file)
@@ -689,7 +689,7 @@ static void pim_if_addr_del_pim(struct connected *ifc)
 {
        struct pim_interface *pim_ifp = ifc->ifp->info;
 
-       if (ifc->address->family != AF_INET) {
+       if (ifc->address->family != PIM_AF) {
                /* non-IPv4 address */
                return;
        }
@@ -843,7 +843,7 @@ void pim_if_addr_del_all(struct interface *ifp)
        for (ALL_LIST_ELEMENTS(ifp->connected, node, nextnode, ifc)) {
                struct prefix *p = ifc->address;
 
-               if (p->family != AF_INET)
+               if (p->family != PIM_AF)
                        continue;
 
                pim_if_addr_del(ifc, 1 /* force_prim_as_any=true */);
index 1a90b46dec516c50a15eff9e2727b2f3031b65b4..259c34c819c8535eeb770b1c113af0e22f06289d 100644 (file)
@@ -365,19 +365,9 @@ static int mtrace_un_forward_packet(struct pim_instance *pim, struct ip *ip_hdr,
        if (ip_hdr->ip_ttl-- <= 1)
                return -1;
 
-       ip_hdr->ip_sum = in_cksum(ip_hdr, ip_hdr->ip_hl * 4);
-
-       fd = pim_socket_raw(IPPROTO_RAW);
-
-       if (fd < 0)
-               return -1;
-
-       pim_socket_ip_hdr(fd);
-
        if (interface == NULL) {
                memset(&nexthop, 0, sizeof(nexthop));
                if (!pim_nexthop_lookup(pim, &nexthop, ip_hdr->ip_dst, 0)) {
-                       close(fd);
                        if (PIM_DEBUG_MTRACE)
                                zlog_debug(
                                        "Dropping mtrace packet, no route to destination");
@@ -389,6 +379,15 @@ static int mtrace_un_forward_packet(struct pim_instance *pim, struct ip *ip_hdr,
                if_out = interface;
        }
 
+       ip_hdr->ip_sum = in_cksum(ip_hdr, ip_hdr->ip_hl * 4);
+
+       fd = pim_socket_raw(IPPROTO_RAW);
+
+       if (fd < 0)
+               return -1;
+
+       pim_socket_ip_hdr(fd);
+
        ret = pim_socket_bind(fd, if_out);
 
        if (ret < 0) {
index 12f8ffedfe28b344c4e2d27f6f2226312c7e530c..c4ff912cde99862c9c300e3cfb6aca85bd1d58b5 100644 (file)
@@ -24,6 +24,7 @@
 #include "lib/northbound_cli.h"
 #include "pim_igmpv3.h"
 #include "pim_neighbor.h"
+#include "pim_nht.h"
 #include "pim_pim.h"
 #include "pim_mlag.h"
 #include "pim_bfd.h"
@@ -146,6 +147,7 @@ static int pim_cmd_interface_add(struct interface *ifp)
                pim_ifp->pim_enable = true;
 
        pim_if_addr_add_all(ifp);
+       pim_upstream_nh_if_update(pim_ifp->pim, ifp);
        pim_if_membership_refresh(ifp);
 
        pim_if_create_pimreg(pim_ifp->pim);
@@ -171,6 +173,7 @@ static int pim_cmd_interface_delete(struct interface *ifp)
 
        if (!pim_ifp->gm_enable) {
                pim_if_addr_del_all(ifp);
+               pim_upstream_nh_if_update(pim_ifp->pim, ifp);
                pim_if_delete(ifp);
        }
 
index f9a9aeb1b0673665a9a43dd1541bce735a7e5bec..a33da645689ed36ed0b51f530f59e28aad122be4 100644 (file)
@@ -469,6 +469,40 @@ static int pim_update_upstream_nh(struct pim_instance *pim,
        return 0;
 }
 
+static int pim_upstream_nh_if_update_helper(struct hash_bucket *bucket,
+                                           void *arg)
+{
+       struct pim_nexthop_cache *pnc = bucket->data;
+       struct pnc_hash_walk_data *pwd = arg;
+       struct pim_instance *pim = pwd->pim;
+       struct interface *ifp = pwd->ifp;
+       struct nexthop *nh_node = NULL;
+       ifindex_t first_ifindex;
+
+       for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next) {
+               first_ifindex = nh_node->ifindex;
+               if (ifp != if_lookup_by_index(first_ifindex, pim->vrf->vrf_id))
+                       continue;
+
+               if (pnc->upstream_hash->count) {
+                       pim_update_upstream_nh(pim, pnc);
+                       break;
+               }
+       }
+
+       return HASHWALK_CONTINUE;
+}
+
+void pim_upstream_nh_if_update(struct pim_instance *pim, struct interface *ifp)
+{
+       struct pnc_hash_walk_data pwd;
+
+       pwd.pim = pim;
+       pwd.ifp = ifp;
+
+       hash_walk(pim->rpf_hash, pim_upstream_nh_if_update_helper, &pwd);
+}
+
 uint32_t pim_compute_ecmp_hash(struct prefix *src, struct prefix *grp)
 {
        uint32_t hash_val;
@@ -495,6 +529,7 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
        uint32_t hash_val = 0, mod_val = 0;
        uint8_t nh_iter = 0, found = 0;
        uint32_t i, num_nbrs = 0;
+       struct pim_interface *pim_ifp;
 
        if (!pnc || !pnc->nexthop_num || !nexthop)
                return 0;
@@ -611,10 +646,13 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
                        nh_iter++;
                        continue;
                }
-               if (!ifp->info) {
+
+               pim_ifp = ifp->info;
+
+               if (!pim_ifp || !pim_ifp->pim_enable) {
                        if (PIM_DEBUG_PIM_NHT)
                                zlog_debug(
-                                       "%s: multicast not enabled on input interface %s(%s) (ifindex=%d, RPF for source %pPA)",
+                                       "%s: pim not enabled on input interface %s(%s) (ifindex=%d, RPF for source %pPA)",
                                        __func__, ifp->name, pim->vrf->name,
                                        first_ifindex, &src);
                        if (nh_iter == mod_val)
@@ -882,6 +920,7 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
        uint8_t i = 0;
        uint32_t hash_val = 0, mod_val = 0;
        uint32_t num_nbrs = 0;
+       struct pim_interface *pim_ifp;
 
        if (PIM_DEBUG_PIM_NHT_DETAIL)
                zlog_debug("%s: Looking up: %pPA(%s), last lookup time: %lld",
@@ -964,10 +1003,12 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
                        continue;
                }
 
-               if (!ifp->info) {
+               pim_ifp = ifp->info;
+
+               if (!pim_ifp || !pim_ifp->pim_enable) {
                        if (PIM_DEBUG_PIM_NHT)
                                zlog_debug(
-                                       "%s: multicast not enabled on input interface %s(%s) (ifindex=%d, RPF for source %pPA)",
+                                       "%s: pim not enabled on input interface %s(%s) (ifindex=%d, RPF for source %pPA)",
                                        __func__, ifp->name, pim->vrf->name,
                                        first_ifindex, &src);
                        if (i == mod_val)
index 240e61d98ff9cdc85815835abaa82488a231f8f9..f487a21ba4c9683c28271b7eb831ff1a9fda1815 100644 (file)
@@ -53,6 +53,11 @@ struct pim_nexthop_cache {
        uint32_t bsr_count;
 };
 
+struct pnc_hash_walk_data {
+       struct pim_instance *pim;
+       struct interface *ifp;
+};
+
 int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS);
 int pim_find_or_track_nexthop(struct pim_instance *pim, pim_addr addr,
                              struct pim_upstream *up, struct rp_info *rp,
@@ -77,5 +82,5 @@ void pim_nht_bsr_del(struct pim_instance *pim, pim_addr bsr_addr);
 /* RPF(bsr_addr) == src_ip%src_ifp? */
 bool pim_nht_bsr_rpf_check(struct pim_instance *pim, pim_addr bsr_addr,
                           struct interface *src_ifp, pim_addr src_ip);
-
+void pim_upstream_nh_if_update(struct pim_instance *pim, struct interface *ifp);
 #endif
index f5834029a575903426645af72dd46d8b8eef747b..d237a73126308a8724c04d693ef606f7850d41e0 100644 (file)
@@ -61,6 +61,7 @@ bool pim_nexthop_lookup(struct pim_instance *pim, struct pim_nexthop *nexthop,
        ifindex_t first_ifindex = 0;
        int found = 0;
        int i = 0;
+       struct pim_interface *pim_ifp;
 
 #if PIM_IPV == 4
        /*
@@ -118,15 +119,16 @@ bool pim_nexthop_lookup(struct pim_instance *pim, struct pim_nexthop *nexthop,
                        continue;
                }
 
-               if (!ifp->info) {
+               pim_ifp = ifp->info;
+               if (!pim_ifp || !pim_ifp->pim_enable) {
                        if (PIM_DEBUG_ZEBRA)
                                zlog_debug(
-                                       "%s: multicast not enabled on input interface %s (ifindex=%d, RPF for source %pPAs)",
+                                       "%s: pim not enabled on input interface %s (ifindex=%d, RPF for source %pPAs)",
                                        __func__, ifp->name, first_ifindex,
                                        &addr);
                        i++;
-               } else if (neighbor_needed
-                          && !pim_if_connected_to_source(ifp, addr)) {
+               } else if (neighbor_needed &&
+                          !pim_if_connected_to_source(ifp, addr)) {
                        nbr = pim_neighbor_find(ifp,
                                                nexthop_tab[i].nexthop_addr);
                        if (PIM_DEBUG_PIM_TRACE_DETAIL)
index 5cef5d9d746e8ed2b4304a38f8e83a60c2b4e1dd..17a62f1999c8e7b468b80070f7998f6832dd62d8 100644 (file)
@@ -5,6 +5,7 @@
 # Only allow root (and possibly wheel) to use this because enable access
 # is unrestricted.
 auth       sufficient   pam_rootok.so
+account    sufficient   pam_rootok.so
 
 # Uncomment the following line to implicitly trust users in the "wheel" group.
 #auth       sufficient   pam_wheel.so trust use_uid
index 8f469d2a07ac3929fa84e5bc8d721036debc22ad..afe75e1f261370bfc511ad5173ff607592ab95a9 100644 (file)
@@ -469,7 +469,7 @@ ln -s %{_sbindir}/frrinit.sh %{buildroot}%{_initddir}/frr
 install %{zeb_src}/tools/etc/frr/daemons %{buildroot}%{_sysconfdir}/frr
 install %{zeb_src}/tools/etc/frr/frr.conf %{buildroot}%{_sysconfdir}/frr/frr.conf.template
 install -m644 %{zeb_rh_src}/frr.pam %{buildroot}%{_sysconfdir}/pam.d/frr
-install -m644 %{zeb_rh_src}/frr.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/frr
+install -m644 %{zeb_src}/tools/etc/logrotate.d/frr %{buildroot}%{_sysconfdir}/logrotate.d/frr
 install -d -m750 %{buildroot}%{rundir}
 
 %if 0%{?rhel} > 7 || 0%{?fedora} > 29
diff --git a/tests/topotests/srv6_locator_usid/__init__.py b/tests/topotests/srv6_locator_usid/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/srv6_locator_usid/expected_chunks_1.json b/tests/topotests/srv6_locator_usid/expected_chunks_1.json
new file mode 100644 (file)
index 0000000..fe51488
--- /dev/null
@@ -0,0 +1 @@
+[]
diff --git a/tests/topotests/srv6_locator_usid/expected_chunks_2.json b/tests/topotests/srv6_locator_usid/expected_chunks_2.json
new file mode 100644 (file)
index 0000000..304d738
--- /dev/null
@@ -0,0 +1,8 @@
+[
+  {
+    "name": "loc1",
+    "chunks": [
+      "fc00:0:1::/48"
+    ]
+  }
+]
diff --git a/tests/topotests/srv6_locator_usid/expected_chunks_3.json b/tests/topotests/srv6_locator_usid/expected_chunks_3.json
new file mode 100644 (file)
index 0000000..fe51488
--- /dev/null
@@ -0,0 +1 @@
+[]
diff --git a/tests/topotests/srv6_locator_usid/expected_chunks_4.json b/tests/topotests/srv6_locator_usid/expected_chunks_4.json
new file mode 100644 (file)
index 0000000..fe51488
--- /dev/null
@@ -0,0 +1 @@
+[]
diff --git a/tests/topotests/srv6_locator_usid/expected_chunks_5.json b/tests/topotests/srv6_locator_usid/expected_chunks_5.json
new file mode 100644 (file)
index 0000000..0d4f101
--- /dev/null
@@ -0,0 +1,2 @@
+[
+]
diff --git a/tests/topotests/srv6_locator_usid/expected_chunks_6.json b/tests/topotests/srv6_locator_usid/expected_chunks_6.json
new file mode 100644 (file)
index 0000000..0d4f101
--- /dev/null
@@ -0,0 +1,2 @@
+[
+]
diff --git a/tests/topotests/srv6_locator_usid/expected_chunks_7.json b/tests/topotests/srv6_locator_usid/expected_chunks_7.json
new file mode 100644 (file)
index 0000000..0d4f101
--- /dev/null
@@ -0,0 +1,2 @@
+[
+]
diff --git a/tests/topotests/srv6_locator_usid/expected_chunks_8.json b/tests/topotests/srv6_locator_usid/expected_chunks_8.json
new file mode 100644 (file)
index 0000000..0d4f101
--- /dev/null
@@ -0,0 +1,2 @@
+[
+]
diff --git a/tests/topotests/srv6_locator_usid/expected_locators_1.json b/tests/topotests/srv6_locator_usid/expected_locators_1.json
new file mode 100644 (file)
index 0000000..c0eeacc
--- /dev/null
@@ -0,0 +1,20 @@
+{
+  "locators":[
+    {
+      "name": "loc1",
+      "prefix": "fc00:0:1::/48",
+      "blockBitsLength": 32,
+      "nodeBitsLength": 16,
+      "functionBitsLength": 16,
+      "argumentBitsLength": 0,
+      "behavior": "usid",
+      "statusUp": true,
+      "chunks": [
+        {
+          "prefix": "fc00:0:1::/48",
+          "proto": "system"
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/srv6_locator_usid/expected_locators_2.json b/tests/topotests/srv6_locator_usid/expected_locators_2.json
new file mode 100644 (file)
index 0000000..38a6739
--- /dev/null
@@ -0,0 +1,20 @@
+{
+  "locators":[
+    {
+      "name": "loc1",
+      "prefix": "fc00:0:1::/48",
+      "blockBitsLength": 32,
+      "nodeBitsLength": 16,
+      "functionBitsLength": 16,
+      "argumentBitsLength": 0,
+      "behavior": "usid",
+      "statusUp": true,
+      "chunks": [
+        {
+          "prefix": "fc00:0:1::/48",
+          "proto": "sharp"
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/srv6_locator_usid/expected_locators_3.json b/tests/topotests/srv6_locator_usid/expected_locators_3.json
new file mode 100644 (file)
index 0000000..c0eeacc
--- /dev/null
@@ -0,0 +1,20 @@
+{
+  "locators":[
+    {
+      "name": "loc1",
+      "prefix": "fc00:0:1::/48",
+      "blockBitsLength": 32,
+      "nodeBitsLength": 16,
+      "functionBitsLength": 16,
+      "argumentBitsLength": 0,
+      "behavior": "usid",
+      "statusUp": true,
+      "chunks": [
+        {
+          "prefix": "fc00:0:1::/48",
+          "proto": "system"
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/srv6_locator_usid/expected_locators_4.json b/tests/topotests/srv6_locator_usid/expected_locators_4.json
new file mode 100644 (file)
index 0000000..b1528ff
--- /dev/null
@@ -0,0 +1,35 @@
+{
+  "locators":[
+    {
+      "name": "loc1",
+      "prefix": "fc00:0:1::/48",
+      "blockBitsLength": 32,
+      "nodeBitsLength": 16,
+      "functionBitsLength": 16,
+      "argumentBitsLength": 0,
+      "behavior": "usid",
+      "statusUp": true,
+      "chunks": [
+        {
+          "prefix": "fc00:0:1::/48",
+          "proto": "system"
+        }
+      ]
+    },
+    {
+      "name": "loc2",
+      "prefix": "fc00:0:2::/48",
+      "blockBitsLength": 32,
+      "nodeBitsLength": 16,
+      "functionBitsLength": 16,
+      "argumentBitsLength": 0,
+      "statusUp": true,
+      "chunks": [
+        {
+          "prefix": "fc00:0:2::/48",
+          "proto": "system"
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/srv6_locator_usid/expected_locators_5.json b/tests/topotests/srv6_locator_usid/expected_locators_5.json
new file mode 100644 (file)
index 0000000..b6acc23
--- /dev/null
@@ -0,0 +1,36 @@
+{
+  "locators":[
+    {
+      "name": "loc1",
+      "prefix": "fc00:0:1::/48",
+      "blockBitsLength": 32,
+      "nodeBitsLength": 16,
+      "functionBitsLength": 16,
+      "argumentBitsLength": 0,
+      "behavior": "usid",
+      "statusUp": true,
+      "chunks": [
+        {
+          "prefix": "fc00:0:1::/48",
+          "proto": "system"
+        }
+      ]
+    },
+    {
+      "name": "loc2",
+      "prefix": "fc00:0:2::/48",
+      "blockBitsLength": 32,
+      "nodeBitsLength": 16,
+      "functionBitsLength": 16,
+      "argumentBitsLength": 0,
+      "behavior": "usid",
+      "statusUp": true,
+      "chunks": [
+        {
+          "prefix": "fc00:0:2::/48",
+          "proto": "system"
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/srv6_locator_usid/expected_locators_6.json b/tests/topotests/srv6_locator_usid/expected_locators_6.json
new file mode 100644 (file)
index 0000000..b1528ff
--- /dev/null
@@ -0,0 +1,35 @@
+{
+  "locators":[
+    {
+      "name": "loc1",
+      "prefix": "fc00:0:1::/48",
+      "blockBitsLength": 32,
+      "nodeBitsLength": 16,
+      "functionBitsLength": 16,
+      "argumentBitsLength": 0,
+      "behavior": "usid",
+      "statusUp": true,
+      "chunks": [
+        {
+          "prefix": "fc00:0:1::/48",
+          "proto": "system"
+        }
+      ]
+    },
+    {
+      "name": "loc2",
+      "prefix": "fc00:0:2::/48",
+      "blockBitsLength": 32,
+      "nodeBitsLength": 16,
+      "functionBitsLength": 16,
+      "argumentBitsLength": 0,
+      "statusUp": true,
+      "chunks": [
+        {
+          "prefix": "fc00:0:2::/48",
+          "proto": "system"
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/srv6_locator_usid/expected_locators_7.json b/tests/topotests/srv6_locator_usid/expected_locators_7.json
new file mode 100644 (file)
index 0000000..e965e02
--- /dev/null
@@ -0,0 +1,19 @@
+{
+  "locators":[
+    {
+      "name": "loc2",
+      "prefix": "fc00:0:2::/48",
+      "statusUp": true,
+      "blockBitsLength": 32,
+      "nodeBitsLength": 16,
+      "functionBitsLength": 16,
+      "argumentBitsLength": 0,
+      "chunks":[
+        {
+          "prefix": "fc00:0:2::/48",
+          "proto": "system"
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/srv6_locator_usid/expected_locators_8.json b/tests/topotests/srv6_locator_usid/expected_locators_8.json
new file mode 100644 (file)
index 0000000..6e1b993
--- /dev/null
@@ -0,0 +1,4 @@
+{
+  "locators":[
+  ]
+}
diff --git a/tests/topotests/srv6_locator_usid/r1/setup.sh b/tests/topotests/srv6_locator_usid/r1/setup.sh
new file mode 100644 (file)
index 0000000..36ed713
--- /dev/null
@@ -0,0 +1,2 @@
+ip link add dummy0 type dummy
+ip link set dummy0 up
diff --git a/tests/topotests/srv6_locator_usid/r1/sharpd.conf b/tests/topotests/srv6_locator_usid/r1/sharpd.conf
new file mode 100644 (file)
index 0000000..d460859
--- /dev/null
@@ -0,0 +1,7 @@
+hostname r1
+!
+log stdout notifications
+log monitor notifications
+log commands
+log file sharpd.log debugging
+!
diff --git a/tests/topotests/srv6_locator_usid/r1/zebra.conf b/tests/topotests/srv6_locator_usid/r1/zebra.conf
new file mode 100644 (file)
index 0000000..78ef1e9
--- /dev/null
@@ -0,0 +1,20 @@
+hostname r1
+!
+! debug zebra events
+! debug zebra rib detailed
+!
+log stdout notifications
+log monitor notifications
+log commands
+log file zebra.log debugging
+!
+segment-routing
+ srv6
+  locators
+   locator loc1
+    prefix fc00:0:1::/48 func-bits 16 block-len 32 node-len 16
+    behavior usid
+   !
+  !
+ !
+!
diff --git a/tests/topotests/srv6_locator_usid/test_srv6_locator_usid.py b/tests/topotests/srv6_locator_usid/test_srv6_locator_usid.py
new file mode 100755 (executable)
index 0000000..37fd736
--- /dev/null
@@ -0,0 +1,276 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2022, University of Rome Tor Vergata
+# Authored by Carmine Scarpitta <carmine.scarpitta@uniroma2.it>
+#
+# Permission to use, copy, modify, and/or distribute this software
+# for any purpose with or without fee is hereby granted, provided
+# that the above copyright notice and this permission notice appear
+# in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+#
+
+"""
+test_srv6_locator_usid.py:
+Test for SRv6 Locator uSID on zebra
+"""
+
+import os
+import sys
+import json
+import pytest
+import functools
+
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+
+pytestmark = [pytest.mark.bgpd, pytest.mark.sharpd]
+
+
+def open_json_file(filename):
+    try:
+        with open(filename, "r") as f:
+            return json.load(f)
+    except IOError:
+        assert False, "Could not read file {}".format(filename)
+
+
+def setup_module(mod):
+    tgen = Topogen({None: "r1"}, mod.__name__)
+    tgen.start_topology()
+    for rname, router in tgen.routers().items():
+        router.run("/bin/bash {}/{}/setup.sh".format(CWD, rname))
+        router.load_config(
+            TopoRouter.RD_ZEBRA, os.path.join(
+                CWD, "{}/zebra.conf".format(rname))
+        )
+        router.load_config(
+            TopoRouter.RD_SHARP, os.path.join(
+                CWD, "{}/sharpd.conf".format(rname))
+        )
+    tgen.start_router()
+
+
+def teardown_module(mod):
+    tgen = get_topogen()
+    tgen.stop_topology()
+
+
+def _check_srv6_locator(router, expected_locator_file):
+    logger.info("checking zebra locator status")
+    output = json.loads(
+        router.vtysh_cmd("show segment-routing srv6 locator json")
+    )
+    expected = open_json_file("{}/{}".format(CWD, expected_locator_file))
+    return topotest.json_cmp(output, expected)
+
+
+def _check_sharpd_chunk(router, expected_chunk_file):
+    logger.info("checking sharpd locator chunk status")
+    output = json.loads(
+        router.vtysh_cmd("show sharp segment-routing srv6 json")
+    )
+    expected = open_json_file("{}/{}".format(CWD, expected_chunk_file))
+    return topotest.json_cmp(output, expected)
+
+
+def check_srv6_locator(router, expected_file):
+    func = functools.partial(_check_srv6_locator, router, expected_file)
+    success, result = topotest.run_and_expect(func, None, count=5, wait=3)
+    assert result is None, "Failed"
+
+
+def check_sharpd_chunk(router, expected_file):
+    func = functools.partial(_check_sharpd_chunk, router, expected_file)
+    success, result = topotest.run_and_expect(func, None, count=5, wait=3)
+    assert result is None, "Failed"
+
+
+def test_srv6_usid_locator_configuration():
+    tgen = get_topogen()
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+    router = tgen.gears["r1"]
+
+    # FOR DEVELOPER:
+    # If you want to stop some specific line and start interactive shell,
+    # please use tgen.mininet_cli() to start it.
+
+    logger.info("Verify SRv6 Locators instantiated from config file")
+    check_srv6_locator(router, "expected_locators_1.json")
+    check_sharpd_chunk(router, "expected_chunks_1.json")
+
+
+def test_srv6_usid_locator_get_chunk():
+    tgen = get_topogen()
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+    router = tgen.gears["r1"]
+
+    # FOR DEVELOPER:
+    # If you want to stop some specific line and start interactive shell,
+    # please use tgen.mininet_cli() to start it.
+
+    logger.info("Get chunk for the locator loc1")
+    router.vtysh_cmd("sharp srv6-manager get-locator-chunk loc1")
+    check_srv6_locator(router, "expected_locators_2.json")
+    check_sharpd_chunk(router, "expected_chunks_2.json")
+
+
+def test_srv6_usid_locator_release_chunk():
+    tgen = get_topogen()
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+    router = tgen.gears["r1"]
+
+    # FOR DEVELOPER:
+    # If you want to stop some specific line and start interactive shell,
+    # please use tgen.mininet_cli() to start it.
+
+    logger.info("Release chunk for the locator loc1")
+    router.vtysh_cmd("sharp srv6-manager release-locator-chunk loc1")
+    check_srv6_locator(router, "expected_locators_3.json")
+    check_sharpd_chunk(router, "expected_chunks_3.json")
+
+
+def test_srv6_usid_locator_create_locator():
+    tgen = get_topogen()
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+    router = tgen.gears["r1"]
+
+    # FOR DEVELOPER:
+    # If you want to stop some specific line and start interactive shell,
+    # please use tgen.mininet_cli() to start it.
+
+    logger.info("Create an additional SRv6 Locator")
+    router.vtysh_cmd(
+        """
+        configure terminal
+         segment-routing
+          srv6
+           locators
+            locator loc2
+             prefix fc00:0:2::/48 func-bits 16 block-len 32 node-len 16
+        """
+    )
+    check_srv6_locator(router, "expected_locators_4.json")
+    check_sharpd_chunk(router, "expected_chunks_4.json")
+
+
+def test_srv6_usid_locator_set_behavior_usid():
+    tgen = get_topogen()
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+    router = tgen.gears["r1"]
+
+    # FOR DEVELOPER:
+    # If you want to stop some specific line and start interactive shell,
+    # please use tgen.mininet_cli() to start it.
+
+    logger.info(
+        "Specify the SRv6 Locator loc2 as a Micro-segment (uSID) Locator"
+    )
+    router.vtysh_cmd(
+        """
+        configure terminal
+         segment-routing
+          srv6
+           locators
+            locator loc2
+             behavior usid
+        """
+    )
+    check_srv6_locator(router, "expected_locators_5.json")
+    check_sharpd_chunk(router, "expected_chunks_5.json")
+
+
+def test_srv6_usid_locator_unset_behavior_usid():
+    tgen = get_topogen()
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+    router = tgen.gears["r1"]
+
+    # FOR DEVELOPER:
+    # If you want to stop some specific line and start interactive shell,
+    # please use tgen.mininet_cli() to start it.
+
+    logger.info("Clear Micro-segment (uSID) Locator flag for loc2")
+    router.vtysh_cmd(
+        """
+        configure terminal
+         segment-routing
+          srv6
+           locators
+            locator loc2
+             no behavior usid
+        """
+    )
+    check_srv6_locator(router, "expected_locators_6.json")
+    check_sharpd_chunk(router, "expected_chunks_6.json")
+
+
+def test_srv6_usid_locator_delete():
+    tgen = get_topogen()
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+    router = tgen.gears["r1"]
+
+    # FOR DEVELOPER:
+    # If you want to stop some specific line and start interactive shell,
+    # please use tgen.mininet_cli() to start it.
+
+    logger.info(
+        "Delete locator loc1 and verify that the chunk is released automatically"
+    )
+    router.vtysh_cmd(
+        """
+        configure terminal
+         segment-routing
+          srv6
+           locators
+            no locator loc1
+        """
+    )
+    check_srv6_locator(router, "expected_locators_7.json")
+    check_sharpd_chunk(router, "expected_chunks_7.json")
+
+
+def test_srv6_usid_locator_delete_all():
+    tgen = get_topogen()
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+    router = tgen.gears["r1"]
+
+    # FOR DEVELOPER:
+    # If you want to stop some specific line and start interactive shell,
+    # please use tgen.mininet_cli() to start it.
+
+    logger.info("Delete all the SRv6 configuration")
+    router.vtysh_cmd(
+        """
+        configure terminal
+         segment-routing
+          no srv6
+        """
+    )
+    check_srv6_locator(router, "expected_locators_8.json")
+    check_sharpd_chunk(router, "expected_chunks_8.json")
+
+
+if __name__ == "__main__":
+    args = ["-s"] + sys.argv[1:]
+    sys.exit(pytest.main(args))
diff --git a/tools/etc/logrotate.d/frr b/tools/etc/logrotate.d/frr
new file mode 100644 (file)
index 0000000..735af65
--- /dev/null
@@ -0,0 +1,27 @@
+/var/log/frr/*.log {
+        size 500k
+        sharedscripts
+        missingok
+        compress
+        rotate 14
+        create 0640 frr frr
+
+        postrotate
+            pid=$(lsof -t -a -c /syslog/ /var/log/frr/* 2>/dev/null)
+            if [ -n "$pid" ]
+            then # using syslog
+                 kill -HUP $pid
+            fi
+            # in case using file logging; if switching back and forth
+            # between file and syslog, rsyslogd might still have file
+            # open, as well as the daemons, so always signal the daemons.
+            # It's safe, a NOP if (only) syslog is being used.
+            for i in babeld bgpd eigrpd isisd ldpd nhrpd ospf6d ospfd sharpd \
+                pimd pim6d ripd ripngd zebra pathd pbrd staticd bfdd fabricd vrrpd; do
+                if [ -e /var/run/frr/$i.pid ] ; then
+                    pids="$pids $(cat /var/run/frr/$i.pid)"
+                fi
+            done
+            [ -n "$pids" ] && kill -USR1 $pids || true
+        endscript
+}
index 61f1abb3787f660eb28b9a635c449ac8034e56d4..3c16c27c6dfa135b54f3ab7e25969b32726edc5d 100755 (executable)
@@ -335,7 +335,7 @@ if [ -z "$FRR_PATHSPACE" ]; then
        load_old_config "/etc/sysconfig/frr"
 fi
 
-if { declare -p watchfrr_options 2>/dev/null || true; } | grep -q '^declare \-a'; then
+if { declare -p watchfrr_options 2>/dev/null || true; } | grep -q '^declare -a'; then
        log_warning_msg "watchfrr_options contains a bash array value." \
                "The configured value is intentionally ignored since it is likely wrong." \
                "Please remove or fix the setting."
index d07c4c63324b9985acd4725e097cdd20677dbf96..c5e1c113cb0844e0e2bb90dbbaa599eb87e6959f 100644 (file)
@@ -98,6 +98,7 @@ struct fpm_nl_ctx {
        struct thread *t_read;
        struct thread *t_write;
        struct thread *t_event;
+       struct thread *t_nhg;
        struct thread *t_dequeue;
 
        /* zebra events. */
@@ -271,7 +272,7 @@ DEFUN(fpm_use_nhg, fpm_use_nhg_cmd,
                return CMD_SUCCESS;
 
        thread_add_event(gfnc->fthread->master, fpm_process_event, gfnc,
-                        FNE_TOGGLE_NHG, &gfnc->t_event);
+                        FNE_TOGGLE_NHG, &gfnc->t_nhg);
 
        return CMD_SUCCESS;
 }
@@ -287,7 +288,7 @@ DEFUN(no_fpm_use_nhg, no_fpm_use_nhg_cmd,
                return CMD_SUCCESS;
 
        thread_add_event(gfnc->fthread->master, fpm_process_event, gfnc,
-                        FNE_TOGGLE_NHG, &gfnc->t_event);
+                        FNE_TOGGLE_NHG, &gfnc->t_nhg);
 
        return CMD_SUCCESS;
 }
@@ -1275,7 +1276,7 @@ static void fpm_process_queue(struct thread *t)
 static void fpm_process_event(struct thread *t)
 {
        struct fpm_nl_ctx *fnc = THREAD_ARG(t);
-       int event = THREAD_VAL(t);
+       enum fpm_nl_events event = THREAD_VAL(t);
 
        switch (event) {
        case FNE_DISABLE:
@@ -1328,11 +1329,6 @@ static void fpm_process_event(struct thread *t)
                if (IS_ZEBRA_DEBUG_FPM)
                        zlog_debug("%s: LSP walk finished", __func__);
                break;
-
-       default:
-               if (IS_ZEBRA_DEBUG_FPM)
-                       zlog_debug("%s: unhandled event %d", __func__, event);
-               break;
        }
 }
 
@@ -1372,6 +1368,8 @@ static int fpm_nl_finish_early(struct fpm_nl_ctx *fnc)
        THREAD_OFF(fnc->t_ribwalk);
        THREAD_OFF(fnc->t_rmacreset);
        THREAD_OFF(fnc->t_rmacwalk);
+       THREAD_OFF(fnc->t_event);
+       THREAD_OFF(fnc->t_nhg);
        thread_cancel_async(fnc->fthread->master, &fnc->t_read, NULL);
        thread_cancel_async(fnc->fthread->master, &fnc->t_write, NULL);
        thread_cancel_async(fnc->fthread->master, &fnc->t_connect, NULL);
index a3db53f2961e185c541746da0a3f814237626cb7..85eb6b34510214a00ff71607d78649cdaf7ab5a5 100644 (file)
@@ -2710,6 +2710,7 @@ int zsend_srv6_manager_get_locator_chunk_response(struct zserv *client,
        chunk.keep = 0;
        chunk.proto = client->proto;
        chunk.instance = client->instance;
+       chunk.flags = loc->flags;
 
        zclient_create_header(s, ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK, vrf_id);
        zapi_srv6_locator_chunk_encode(s, &chunk);
index 98120accfdc2e5fa7c22afa071aae4725a9cea2e..01ea9c5b9c924d4af15dba0bd64f9247ad3cf2e6 100644 (file)
@@ -2759,6 +2759,12 @@ bool zebra_evpn_is_if_es_capable(struct zebra_if *zif)
        if (zif->zif_type == ZEBRA_IF_BOND)
                return true;
 
+       /* relax the checks to allow config to be applied in zebra
+        * before interface is rxed from the kernel
+        */
+       if (zif->ifp->ifindex == IFINDEX_INTERNAL)
+               return true;
+
        /* XXX: allow swpX i.e. a regular ethernet port to be an ES link too */
        return false;
 }
index 36506cacc7b33a406ef791d0fbb45ee55c652e25..d61e4f8045d9493f8ca2ed78f057c25cab8a4f91 100644 (file)
@@ -177,6 +177,58 @@ struct srv6_locator *zebra_srv6_locator_lookup(const char *name)
        return NULL;
 }
 
+void zebra_notify_srv6_locator_add(struct srv6_locator *locator)
+{
+       struct listnode *node;
+       struct zserv *client;
+
+       /*
+        * Notify new locator info to zclients.
+        *
+        * The srv6 locators and their prefixes are managed by zserv(zebra).
+        * And an actual configuration the srv6 sid in the srv6 locator is done
+        * by zclient(bgpd, isisd, etc). The configuration of each locator
+        * allocation and specify it by zserv and zclient should be
+        * asynchronous. For that, zclient should be received the event via
+        * ZAPI when a srv6 locator is added on zebra.
+        * Basically, in SRv6, adding/removing SRv6 locators is performed less
+        * frequently than adding rib entries, so a broad to all zclients will
+        * not degrade the overall performance of FRRouting.
+        */
+       for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client))
+               zsend_zebra_srv6_locator_add(client, locator);
+}
+
+void zebra_notify_srv6_locator_delete(struct srv6_locator *locator)
+{
+       struct listnode *n;
+       struct srv6_locator_chunk *c;
+       struct zserv *client;
+
+       /*
+        * Notify deleted locator info to zclients if needed.
+        *
+        * zclient(bgpd,isisd,etc) allocates a sid from srv6 locator chunk and
+        * uses it for its own purpose. For example, in the case of BGP L3VPN,
+        * the SID assigned to vpn unicast rib will be given.
+        * And when the locator is deleted by zserv(zebra), those SIDs need to
+        * be withdrawn. The zclient must initiate the withdrawal of the SIDs
+        * by ZEBRA_SRV6_LOCATOR_DELETE, and this notification is sent to the
+        * owner of each chunk.
+        */
+       for (ALL_LIST_ELEMENTS_RO((struct list *)locator->chunks, n, c)) {
+               if (c->proto == ZEBRA_ROUTE_SYSTEM)
+                       continue;
+               client = zserv_find_client(c->proto, c->instance);
+               if (!client) {
+                       zlog_warn("Not found zclient(proto=%u, instance=%u).",
+                                 c->proto, c->instance);
+                       continue;
+               }
+               zsend_zebra_srv6_locator_delete(client, locator);
+       }
+}
+
 struct zebra_srv6 *zebra_srv6_get_default(void)
 {
        static struct zebra_srv6 srv6;
index 84fcc305bc3264049e506f4f30ece2e2b13ce298..f320b9ca0f94e3c514b64b602ad2af028118483e 100644 (file)
@@ -61,6 +61,9 @@ extern void zebra_srv6_locator_add(struct srv6_locator *locator);
 extern void zebra_srv6_locator_delete(struct srv6_locator *locator);
 extern struct srv6_locator *zebra_srv6_locator_lookup(const char *name);
 
+void zebra_notify_srv6_locator_add(struct srv6_locator *locator);
+void zebra_notify_srv6_locator_delete(struct srv6_locator *locator);
+
 extern void zebra_srv6_init(void);
 extern struct zebra_srv6 *zebra_srv6_get_default(void);
 extern bool zebra_srv6_is_enable(void);
index e6810bdc5683517214734cb3624f7b87853f361a..1221365d4d5e5e826c3afa2afda9ca7cc97bf8cd 100644 (file)
@@ -172,6 +172,9 @@ DEFUN (show_srv6_locator_detail,
                vty_out(vty, "Argument-Bit-Len: %u\n",
                        locator->argument_bits_length);
 
+               if (CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID))
+                       vty_out(vty, "Behavior: uSID\n");
+
                vty_out(vty, "Chunks:\n");
                for (ALL_LIST_ELEMENTS_RO((struct list *)locator->chunks, node,
                                          chunk)) {
@@ -369,6 +372,38 @@ DEFPY (locator_prefix,
        return CMD_SUCCESS;
 }
 
+DEFPY (locator_behavior,
+       locator_behavior_cmd,
+       "[no] behavior usid",
+       NO_STR
+       "Configure SRv6 behavior\n"
+       "Specify SRv6 behavior uSID\n")
+{
+       VTY_DECLVAR_CONTEXT(srv6_locator, locator);
+
+       if (no && !CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID))
+               /* SRv6 locator uSID flag already unset, nothing to do */
+               return CMD_SUCCESS;
+
+       if (!no && CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID))
+               /* SRv6 locator uSID flag already set, nothing to do */
+               return CMD_SUCCESS;
+
+       /* Remove old locator from zclients */
+       zebra_notify_srv6_locator_delete(locator);
+
+       /* Set/Unset the SRV6_LOCATOR_USID */
+       if (no)
+               UNSET_FLAG(locator->flags, SRV6_LOCATOR_USID);
+       else
+               SET_FLAG(locator->flags, SRV6_LOCATOR_USID);
+
+       /* Notify the new locator to zclients */
+       zebra_notify_srv6_locator_add(locator);
+
+       return CMD_SUCCESS;
+}
+
 static int zebra_sr_config(struct vty *vty)
 {
        struct zebra_srv6 *srv6 = zebra_srv6_get_default();
@@ -399,6 +434,8 @@ static int zebra_sr_config(struct vty *vty)
                        if (locator->argument_bits_length)
                                vty_out(vty, " arg-len %u",
                                        locator->argument_bits_length);
+                       if (CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID))
+                               vty_out(vty, "    behavior usid");
                        vty_out(vty, "\n");
                        vty_out(vty, "   exit\n");
                        vty_out(vty, "   !\n");
@@ -435,6 +472,7 @@ void zebra_srv6_vty_init(void)
 
        /* Command for configuration */
        install_element(SRV6_LOC_NODE, &locator_prefix_cmd);
+       install_element(SRV6_LOC_NODE, &locator_behavior_cmd);
 
        /* Command for operation */
        install_element(VIEW_NODE, &show_srv6_locator_cmd);