if (bpc->bpc_has_localif) {
STREAM_GET(bpc->bpc_localif, msg, ifnamelen);
bpc->bpc_localif[ifnamelen] = 0;
+
+ /*
+ * IPv6 link-local addresses must use scope id,
+ * otherwise the session lookup will always fail
+ * and we'll have multiple sessions showing up.
+ *
+ * This problem only happens with single hop
+ * since it is not possible to have link-local
+ * address for multi hop sessions.
+ */
+ if (bpc->bpc_ipv4 == false
+ && IN6_IS_ADDR_LINKLOCAL(
+ &bpc->bpc_peer.sa_sin6.sin6_addr))
+ bpc->bpc_peer.sa_sin6.sin6_scope_id =
+ ptm_bfd_fetch_ifindex(bpc->bpc_localif);
}
}
Note: please check the `libyang build requirements
<https://github.com/CESNET/libyang/blob/master/README.md#build-requirements>`_
first.
-
-Libyang uses loadable libraries an YANG modules. It supports
-environment variables to allow overriding the load paths for each of
-these. With FRR, this override currently must be done at the time of
-running FRR's configure command using new options. The new options are:
-
-.. code-block:: shell
-
- --with-yangmodelsdir=DIR
- yang models directory (${datarootdir}/yang)
- --with-libyang-pluginsdir=DIR
- yangmodule plugins directory
- (${libdir}/frr/libyang_plugins)
-
-an example which uses the compile directory is:
-
-.. code-block:: shell
-
- ./configure --with-libyang-pluginsdir="`pwd`/yang/libyang_plugins/.libs" \
- --with-yangmodelsdir="`pwd`/yang"
Configure zebra to use `dir` for local state files, such as pid files and
unix sockets.
+.. option:: --with-yangmodelsdir <dir>
+
+ Look for YANG modules in `dir` [`prefix`/share/yang]. Note that the FRR
+ YANG modules will be installed here.
+
+.. option:: --with-libyang-pluginsdir <dir>
+
+ Look for libyang plugins in `dir` [`prefix`/lib/frr/libyang_plugins].
+ Note that the FRR libyang plugins will be installed here.
+
+When it's desired to run FRR without installing it in the system, it's possible
+to configure it as follows to look for YANG modules and libyang plugins in the
+compile directory:
+.. code-block:: shell
+
+ ./configure --with-libyang-pluginsdir="`pwd`/yang/libyang_plugins/.libs" \
+ --with-yangmodelsdir="`pwd`/yang"
+
.. _least-privilege-support:
Least-Privilege Support
void lsp_build_list_nonzero_ht(uint8_t *start_id, uint8_t *stop_id,
struct list *list, dict_t *lspdb)
{
- dnode_t *first, *last, *curr;
+ for (dnode_t *curr = dict_lower_bound(lspdb, start_id);
+ curr; curr = dict_next(lspdb, curr)) {
+ struct isis_lsp *lsp = curr->dict_data;
- first = dict_lower_bound(lspdb, start_id);
- if (!first)
- return;
-
- last = dict_upper_bound(lspdb, stop_id);
-
- curr = first;
-
- if (((struct isis_lsp *)(curr->dict_data))->hdr.rem_lifetime)
- listnode_add(list, first->dict_data);
-
- while (curr) {
- curr = dict_next(lspdb, curr);
- if (curr
- && ((struct isis_lsp *)(curr->dict_data))->hdr.rem_lifetime)
- listnode_add(list, curr->dict_data);
- if (curr == last)
+ if (memcmp(lsp->hdr.lsp_id, stop_id,
+ ISIS_SYS_ID_LEN + 2) > 0)
break;
- }
- return;
+ if (lsp->hdr.rem_lifetime)
+ listnode_add(list, lsp);
+ }
}
static void lsp_set_time(struct isis_lsp *lsp)
if ((area->is_type & level) == 0)
return ISIS_ERROR;
- if (monotime_since(&area->last_lsp_refresh_event[level - 1], NULL) < 50000L) {
+ if (monotime_since(&area->last_lsp_refresh_event[level - 1], NULL) < 100000L) {
sched_debug("ISIS (%s): Still unstable, postpone LSP L%d refresh",
area->area_tag, level);
_lsp_regenerate_schedule(area, level, 0, false,
void lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit)
{
- if (!fabricd) {
+ if (!fabricd)
lsp_set_all_srmflags(lsp, true);
- if (circuit)
- isis_tx_queue_del(circuit->tx_queue, lsp);
- } else {
+ else
fabricd_lsp_flood(lsp);
- }
+
+ if (circuit)
+ isis_tx_queue_del(circuit->tx_queue, lsp);
}
static int lsp_handle_adj_state_change(struct isis_adjacency *adj)
/bgpd/test_peer_attr
/isisd/test_fuzz_isis_tlv
/isisd/test_fuzz_isis_tlv_tests.h
+/isisd/test_isis_lspdb
/isisd/test_isis_vertex_queue
/lib/cli/test_cli
/lib/cli/test_cli_clippy.c
--- /dev/null
+#include <zebra.h>
+
+#include "isisd/isis_lsp.c"
+
+struct thread_master *master;
+
+int isis_sock_init(struct isis_circuit *circuit);
+int isis_sock_init(struct isis_circuit *circuit)
+{
+ return 0;
+}
+
+struct zebra_privs_t isisd_privs;
+
+static void test_lsp_build_list_nonzero_ht(void)
+{
+ uint8_t lsp_id1[8] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00
+ };
+ uint8_t lsp_id_end[8] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x5f, 0x00
+ };
+ uint8_t lsp_id2[8] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00
+ };
+
+ struct isis_area *area = calloc(sizeof(*area), 1);
+
+ area->lsp_mtu = 1500;
+
+ dict_t *lspdb = lsp_db_init();
+
+ struct isis_lsp *lsp1 = lsp_new(area, lsp_id1, 6000, 0, 0, 0, NULL,
+ ISIS_LEVEL2);
+
+ lsp_insert(lsp1, lspdb);
+
+ struct isis_lsp *lsp2 = lsp_new(area, lsp_id2, 6000, 0, 0, 0, NULL,
+ ISIS_LEVEL2);
+
+ lsp_insert(lsp2, lspdb);
+
+ struct list *list = list_new();
+
+ lsp_build_list_nonzero_ht(lsp_id1, lsp_id_end, list, lspdb);
+ assert(list->count == 1);
+ assert(listgetdata(listhead(list)) == lsp1);
+ list_delete_all_node(list);
+
+ lsp_id_end[5] = 0x03;
+ lsp_id_end[6] = 0x00;
+
+ lsp_build_list_nonzero_ht(lsp_id1, lsp_id_end, list, lspdb);
+ assert(list->count == 2);
+ assert(listgetdata(listhead(list)) == lsp1);
+ assert(listgetdata(listtail(list)) == lsp2);
+ list_delete_all_node(list);
+
+ memcpy(lsp_id1, lsp_id2, sizeof(lsp_id1));
+
+ lsp_build_list_nonzero_ht(lsp_id1, lsp_id_end, list, lspdb);
+ assert(list->count == 1);
+ assert(listgetdata(listhead(list)) == lsp2);
+ list_delete_all_node(list);
+
+ lsp_id1[5] = 0x03;
+ lsp_id_end[5] = 0x04;
+
+ lsp_build_list_nonzero_ht(lsp_id1, lsp_id_end, list, lspdb);
+ assert(list->count == 0);
+ list_delete_all_node(list);
+
+ lsp_id1[5] = 0x00;
+
+ lsp_build_list_nonzero_ht(lsp_id1, lsp_id_end, list, lspdb);
+ assert(list->count == 2);
+ assert(listgetdata(listhead(list)) == lsp1);
+ assert(listgetdata(listtail(list)) == lsp2);
+ list_delete_all_node(list);
+}
+
+int main(int argc, char **argv)
+{
+ isis = calloc(sizeof(*isis), 1);
+ test_lsp_build_list_nonzero_ht();
+ return 0;
+}
--- /dev/null
+import frrtest
+
+class TestIsisLSPDB(frrtest.TestMultiOut):
+ program = './test_isis_lspdb'
+
+TestIsisLSPDB.exit_cleanly()
else
TESTS_ISISD = \
tests/isisd/test_fuzz_isis_tlv \
+ tests/isisd/test_isis_lspdb \
tests/isisd/test_isis_vertex_queue \
# end
endif
tests_isisd_test_fuzz_isis_tlv_LDADD = $(ISISD_TEST_LDADD)
tests_isisd_test_fuzz_isis_tlv_SOURCES = tests/isisd/test_fuzz_isis_tlv.c
nodist_tests_isisd_test_fuzz_isis_tlv_SOURCES = tests/isisd/test_fuzz_isis_tlv_tests.h
+tests_isisd_test_isis_lspdb_CFLAGS = $(TESTS_CFLAGS)
+tests_isisd_test_isis_lspdb_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_isisd_test_isis_lspdb_LDADD = $(ISISD_TEST_LDADD)
+tests_isisd_test_isis_lspdb_SOURCES = tests/isisd/test_isis_lspdb.c
tests_isisd_test_isis_vertex_queue_CFLAGS = $(TESTS_CFLAGS)
tests_isisd_test_isis_vertex_queue_CPPFLAGS = $(TESTS_CPPFLAGS)
tests_isisd_test_isis_vertex_queue_LDADD = $(ISISD_TEST_LDADD)
tests/helpers/python/frrtest.py \
tests/isisd/test_fuzz_isis_tlv.py \
tests/isisd/test_fuzz_isis_tlv_tests.h.gz \
+ tests/isisd/test_isis_lspdb.py \
tests/isisd/test_isis_vertex_queue.py \
tests/lib/cli/test_commands.in \
tests/lib/cli/test_commands.py \
# The list of daemons to watch is automatically generated by the init script.
watchfrr_enable=yes
-watchfrr_options=(-d -r /usr/sbin/servicebBfrrbBrestartbB%s -s /usr/sbin/servicebBfrrbBstartbB%s -k /usr/sbin/servicebBfrrbBstopbB%s -b bB)
+
+watchfrr_options=(-d -r /usr/lib/frr/frrbBrestartbB%s -s /usr/lib/frr/frrbBstartbB%s -k /usr/lib/frr/frrbBstopbB%s -b bB)
# If valgrind_enable is 'yes' the frr daemons will be started via valgrind.
# The use case for doing so is tracking down memory leaks, etc in frr.
echo -n " $1"
fi
+
${SSD} \
--start \
--pidfile=`pidfile $1` \
-- \
`eval echo "$""$1""_options"` -n "$2"
else
- echo -n " $1"
if ! check_daemon $1; then
echo -n " (binary does not exist)"
return;
# Now we have to wait until $DAEMON has _really_ stopped.
#
if test -n "$PID" && kill -0 $PID 2>/dev/null; then
- echo -n " (waiting) ."
cnt=0
while kill -0 $PID 2>/dev/null; do
cnt=`expr $cnt + 1`
break
fi
sleep 2
- echo -n "."
done
fi
- echo -n " $inst"
rm -f `pidfile $inst`
rm -f `vtyfile $inst`
# Start if at least one daemon is activated.
if [ $found_one -eq 1 ]; then
- echo -n "Starting Frr monitor daemon:"
start watchfrr
echo "."
fi
wanted_prio=$1
daemon_list=${daemon:-$DAEMONS}
- echo -n "Starting Frr daemons (prio:$wanted_prio):"
-
for prio_i in `seq 1 $wanted_prio`; do
for daemon_name in $daemon_list; do
eval daemon_prio=\$${daemon_name}
eval "file_list_suffix="$V_PATH"/"$daemon_name-*""
for pidfile in $file_list_suffix.pid; do
${SSD} --stop --quiet --oknodo --pidfile "$pidfile"
- echo -n "."
rm -rf "$pidfile"
done
for vtyfile in $file_list_suffix.vty; do
fi
done
done
- echo "."
}
check_status()