summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rwxr-xr-xtools/checkpatch.pl5
-rwxr-xr-xtools/checkpatch.sh3
-rw-r--r--tools/etc/frr/support_bundle_commands.conf10
-rw-r--r--tools/frr-llvm-cg.c2
-rwxr-xr-xtools/frr-reload.py99
-rwxr-xr-xtools/frr.in10
-rw-r--r--tools/frr.service.in8
-rw-r--r--tools/frr@.service.in8
-rwxr-xr-xtools/frr_babeltrace.py70
-rwxr-xr-xtools/frrcommon.sh.in12
-rw-r--r--tools/frrinit.sh.in2
-rw-r--r--tools/gen_northbound_callbacks.c217
-rw-r--r--tools/gen_yang_deviations.c2
-rw-r--r--tools/valgrind.supp9
-rw-r--r--tools/watchfrr.sh.in4
15 files changed, 338 insertions, 123 deletions
diff --git a/tools/checkpatch.pl b/tools/checkpatch.pl
index d007c1d..ecae0e9 100755
--- a/tools/checkpatch.pl
+++ b/tools/checkpatch.pl
@@ -547,7 +547,7 @@ our $Operators = qr{
our $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
our $Iterators = qr{
- frr_each|frr_each_safe|frr_each_from|
+ darr_foreach_p|darr_foreach_i|frr_each|frr_each_safe|frr_each_from|
frr_with_mutex|frr_with_privs|
LIST_FOREACH|LIST_FOREACH_SAFE|
SLIST_FOREACH|SLIST_FOREACH_SAFE|SLIST_FOREACH_PREVPTR|
@@ -555,7 +555,7 @@ our $Iterators = qr{
TAILQ_FOREACH|TAILQ_FOREACH_SAFE|TAILQ_FOREACH_REVERSE|TAILQ_FOREACH_REVERSE_SAFE|
RB_FOREACH|RB_FOREACH_SAFE|RB_FOREACH_REVERSE|RB_FOREACH_REVERSE_SAFE|
SPLAY_FOREACH|
- FOR_ALL_INTERFACES|FOR_ALL_INTERFACES_ADDRESSES|JSON_FOREACH|
+ FOR_ALL_INTERFACES|JSON_FOREACH|
LY_FOR_KEYS|LY_LIST_FOR|LY_TREE_FOR|LY_TREE_DFS_BEGIN|LYD_TREE_DFS_BEGIN|
RE_DEST_FOREACH_ROUTE|RE_DEST_FOREACH_ROUTE_SAFE|
RNODE_FOREACH_RE|RNODE_FOREACH_RE_SAFE|
@@ -563,6 +563,7 @@ our $Iterators = qr{
SUBGRP_FOREACH_PEER|SUBGRP_FOREACH_PEER_SAFE|
SUBGRP_FOREACH_ADJ|SUBGRP_FOREACH_ADJ_SAFE|
AF_FOREACH|FOREACH_AFI_SAFI|FOREACH_SAFI|
+ FOREACH_BE_CLIENT_BITS|FOREACH_MGMTD_BE_CLIENT_ID|
LSDB_LOOP
}x;
diff --git a/tools/checkpatch.sh b/tools/checkpatch.sh
index 6071f48..bf63057 100755
--- a/tools/checkpatch.sh
+++ b/tools/checkpatch.sh
@@ -3,7 +3,8 @@
usage="./checkpatch.sh <patch> <tree>"
patch=$1
tree=$2
-checkpatch="$tree/tools/checkpatch.pl --no-tree -f"
+scriptdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)"
+checkpatch="$scriptdir/checkpatch.pl --no-tree -f"
ignore="ldpd\|babeld"
cwd=${PWD##*/}
dirty=0
diff --git a/tools/etc/frr/support_bundle_commands.conf b/tools/etc/frr/support_bundle_commands.conf
index b7a1708..b3889e8 100644
--- a/tools/etc/frr/support_bundle_commands.conf
+++ b/tools/etc/frr/support_bundle_commands.conf
@@ -34,6 +34,8 @@ show bgp nexthop
show bgp vrf all summary
show bgp vrf all ipv4
show bgp vrf all ipv6
+show bgp vrf all ipv4 vpn
+show bgp vrf all ipv6 vpn
show bgp vrf all neighbors
show bgp evpn route
@@ -78,9 +80,9 @@ show vrf
show work-queues
show debugging hashtable
show running-config
-show thread cpu
-show thread poll
-show thread timers
+show event cpu
+show event poll
+show event timers
show daemons
show version
CMD_LIST_END
@@ -175,7 +177,7 @@ CMD_LIST_END
PROC_NAME:ospf6
CMD_LIST_START
show ipv6 ospf6 vrf all
-show ipv6 ospf6 vrfs
+show ipv6 ospf6 vrfs
show ipv6 ospf6 vrf all border-routers
show ipv6 ospf6 vrf all border-routers detail
show ipv6 ospf6 vrf all database
diff --git a/tools/frr-llvm-cg.c b/tools/frr-llvm-cg.c
index 3a7222e..f366ba6 100644
--- a/tools/frr-llvm-cg.c
+++ b/tools/frr-llvm-cg.c
@@ -231,7 +231,7 @@ static void walk_const_fptrs(struct json_object *js_call, LLVMValueRef value,
"%s: calls function pointer from unhandled const GEP\n",
prefix);
*hdr_written = true;
- /* fallthru */
+ fallthrough;
default:
/* to help the user / development */
if (!*hdr_written) {
diff --git a/tools/frr-reload.py b/tools/frr-reload.py
index 3a478f6..73479c6 100755
--- a/tools/frr-reload.py
+++ b/tools/frr-reload.py
@@ -25,6 +25,7 @@ from collections import OrderedDict
from ipaddress import IPv6Address, ip_network
from pprint import pformat
+
# Python 3
def iteritems(d):
return iter(d.items())
@@ -362,7 +363,7 @@ class Config(object):
"""
Return the parsed context as strings for display, log etc.
"""
- for (_, ctx) in sorted(iteritems(self.contexts)):
+ for _, ctx in sorted(iteritems(self.contexts)):
print(str(ctx))
def save_contexts(self, key, lines):
@@ -546,7 +547,6 @@ class Config(object):
cur_ctx_lines = []
for line in self.lines:
-
if not line:
continue
@@ -647,7 +647,7 @@ def lines_to_config(ctx_keys, line, delete):
ctx_keys = []
if line:
- for (i, ctx_key) in enumerate(ctx_keys):
+ for i, ctx_key in enumerate(ctx_keys):
cmd.append(" " * i + ctx_key)
line = line.lstrip()
@@ -725,7 +725,7 @@ def get_normalized_ipv6_line(line):
def line_exist(lines, target_ctx_keys, target_line, exact_match=True):
- for (ctx_keys, line) in lines:
+ for ctx_keys, line in lines:
if ctx_keys == target_ctx_keys:
if exact_match:
if line == target_line:
@@ -744,7 +744,7 @@ def bgp_delete_inst_move_line(lines_to_del):
bgp_defult_inst = False
bgp_vrf_inst = False
- for (ctx_keys, line) in lines_to_del:
+ for ctx_keys, line in lines_to_del:
# Find bgp default inst
if (
ctx_keys[0].startswith("router bgp")
@@ -757,7 +757,7 @@ def bgp_delete_inst_move_line(lines_to_del):
bgp_vrf_inst = True
if bgp_defult_inst and bgp_vrf_inst:
- for (ctx_keys, line) in lines_to_del:
+ for ctx_keys, line in lines_to_del:
# move bgp default inst to end
if (
ctx_keys[0].startswith("router bgp")
@@ -853,7 +853,6 @@ def bgp_delete_nbr_remote_as_line(lines_to_add):
def bgp_remove_neighbor_cfg(lines_to_del, del_nbr_dict):
-
# This method handles deletion of bgp neighbor configs,
# if there is neighbor to peer-group cmd is in delete list.
# As 'no neighbor .* peer-group' deletes the neighbor,
@@ -861,7 +860,7 @@ def bgp_remove_neighbor_cfg(lines_to_del, del_nbr_dict):
# in error.
lines_to_del_to_del = []
- for (ctx_keys, line) in lines_to_del:
+ for ctx_keys, line in lines_to_del:
if (
ctx_keys[0].startswith("router bgp")
and line
@@ -876,7 +875,7 @@ def bgp_remove_neighbor_cfg(lines_to_del, del_nbr_dict):
if re_nb:
lines_to_del_to_del.append((ctx_keys, line))
- for (ctx_keys, line) in lines_to_del_to_del:
+ for ctx_keys, line in lines_to_del_to_del:
lines_to_del.remove((ctx_keys, line))
@@ -942,7 +941,7 @@ def bgp_delete_move_lines(lines_to_add, lines_to_del):
# "router bgp 200 no neighbor uplink1 interface remote-as internal"
# "router bgp 200 no neighbor underlay peer-group"
- for (ctx_keys, line) in lines_to_del:
+ for ctx_keys, line in lines_to_del:
if (
ctx_keys[0].startswith("router bgp")
and line
@@ -999,13 +998,13 @@ def bgp_delete_move_lines(lines_to_add, lines_to_del):
bgp_remove_neighbor_cfg(lines_to_del, del_nbr_dict)
return (lines_to_add, lines_to_del)
- for (ctx_keys, line) in lines_to_del_to_app:
+ for ctx_keys, line in lines_to_del_to_app:
lines_to_del.remove((ctx_keys, line))
lines_to_del.append((ctx_keys, line))
# {'router bgp 65001': {'PG': ['10.1.1.2'], 'PG1': ['10.1.1.21']},
# 'router bgp 65001 vrf vrf1': {'PG': ['10.1.1.2'], 'PG1': ['10.1.1.21']}}
- for (ctx_keys, line) in lines_to_del:
+ for ctx_keys, line in lines_to_del:
if (
ctx_keys[0].startswith("router bgp")
and line
@@ -1023,7 +1022,7 @@ def bgp_delete_move_lines(lines_to_add, lines_to_del):
del_dict[ctx_keys[0]][pg_key].append(re_nbr_pg.group(1))
lines_to_del_to_app = []
- for (ctx_keys, line) in lines_to_del:
+ for ctx_keys, line in lines_to_del:
if (
ctx_keys[0].startswith("router bgp")
and line
@@ -1043,10 +1042,10 @@ def bgp_delete_move_lines(lines_to_add, lines_to_del):
if re_pg:
lines_to_del_to_app.append((ctx_keys, line))
- for (ctx_keys, line) in lines_to_del_to_del:
+ for ctx_keys, line in lines_to_del_to_del:
lines_to_del.remove((ctx_keys, line))
- for (ctx_keys, line) in lines_to_del_to_app:
+ for ctx_keys, line in lines_to_del_to_app:
lines_to_del.remove((ctx_keys, line))
lines_to_del.append((ctx_keys, line))
@@ -1056,7 +1055,6 @@ def bgp_delete_move_lines(lines_to_add, lines_to_del):
def pim_delete_move_lines(lines_to_add, lines_to_del):
-
# Under interface context, if 'no ip pim' is present
# remove subsequent 'no ip pim <blah>' options as it
# they are implicitly deleted by 'no ip pim'.
@@ -1064,12 +1062,12 @@ def pim_delete_move_lines(lines_to_add, lines_to_del):
# pending list.
pim_disable = False
- for (ctx_keys, line) in lines_to_del:
+ for ctx_keys, line in lines_to_del:
if ctx_keys[0].startswith("interface") and line and line == "ip pim":
pim_disable = True
if pim_disable:
- for (ctx_keys, line) in lines_to_del:
+ for ctx_keys, line in lines_to_del:
if (
ctx_keys[0].startswith("interface")
and line
@@ -1081,7 +1079,6 @@ def pim_delete_move_lines(lines_to_add, lines_to_del):
def delete_move_lines(lines_to_add, lines_to_del):
-
lines_to_add, lines_to_del = bgp_delete_move_lines(lines_to_add, lines_to_del)
lines_to_add, lines_to_del = pim_delete_move_lines(lines_to_add, lines_to_del)
@@ -1089,13 +1086,12 @@ def delete_move_lines(lines_to_add, lines_to_del):
def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
-
# Quite possibly the most confusing (while accurate) variable names in history
lines_to_add_to_del = []
lines_to_del_to_del = []
- index = 0
- for (ctx_keys, line) in lines_to_del:
+ index = -1
+ for ctx_keys, line in lines_to_del:
deleted = False
# no form of route-map description command only
@@ -1110,10 +1106,21 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
lines_to_del.remove((ctx_keys, line))
lines_to_del.insert(index, (ctx_keys, "description"))
+ # interface x ; description blah
+ # no form of description does not accept any argument,
+ # strip arg before rendering
+ if (
+ ctx_keys[0].startswith("interface ")
+ and line
+ and line.startswith("description ")
+ ):
+ lines_to_del.remove((ctx_keys, line))
+ lines_to_del.insert(index, (ctx_keys, "description"))
+
# If there is a change in the segment routing block ranges, do it
# in-place, to avoid requesting spurious label chunks which might fail
if line and "segment-routing global-block" in line:
- for (add_key, add_line) in lines_to_add:
+ for add_key, add_line in lines_to_add:
if (
ctx_keys[0] == add_key[0]
and add_line
@@ -1124,7 +1131,6 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
continue
if ctx_keys[0].startswith("router bgp") and line:
-
if line.startswith("neighbor "):
# BGP changed how it displays swpX peers that are part of peer-group. Older
# versions of frr would display these on separate lines:
@@ -1206,7 +1212,7 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
bfd_nbr = "neighbor %s" % nbr
bfd_search_string = bfd_nbr + r" bfd (\S+) (\S+) (\S+)"
- for (ctx_keys, add_line) in lines_to_add:
+ for ctx_keys, add_line in lines_to_add:
if ctx_keys[0].startswith("router bgp"):
re_add_nbr_bfd_timers = re.search(
bfd_search_string, add_line
@@ -1236,7 +1242,7 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
dir = re_nbr_rm.group(3)
search = "neighbor%sroute-map(.*)%s" % (neighbor_name, dir)
save_line = "EMPTY"
- for (ctx_keys_al, add_line) in lines_to_add:
+ for ctx_keys_al, add_line in lines_to_add:
if ctx_keys_al[0].startswith("router bgp"):
if add_line:
rm_match = re.search(search, add_line)
@@ -1256,7 +1262,7 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
lines_to_del_to_del.append((ctx_keys_al, line))
if adjust_for_bgp_node == 1:
- for (ctx_keys_dl, dl_line) in lines_to_del:
+ for ctx_keys_dl, dl_line in lines_to_del:
if (
ctx_keys_dl[0].startswith("router bgp")
and len(ctx_keys_dl) > 1
@@ -1438,7 +1444,6 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
and ctx_keys[1] == "address-family l2vpn evpn"
and ctx_keys[2].startswith("vni")
):
-
re_route_target = (
re.search("^route-target import (.*)$", line)
if line is not None
@@ -1514,19 +1519,18 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
lines_to_del_to_del.append((ctx_keys, line))
lines_to_add_to_del.append((tmp_ctx_keys, line))
- for (ctx_keys, line) in lines_to_del_to_del:
+ for ctx_keys, line in lines_to_del_to_del:
try:
lines_to_del.remove((ctx_keys, line))
except ValueError:
pass
- for (ctx_keys, line) in lines_to_add_to_del:
+ for ctx_keys, line in lines_to_add_to_del:
try:
lines_to_add.remove((ctx_keys, line))
except ValueError:
pass
-
return (lines_to_add, lines_to_del)
@@ -1537,8 +1541,7 @@ def ignore_unconfigurable_lines(lines_to_add, lines_to_del):
"""
lines_to_del_to_del = []
- for (ctx_keys, line) in lines_to_del:
-
+ for ctx_keys, line in lines_to_del:
# The integrated-vtysh-config one is technically "no"able but if we did
# so frr-reload would stop working so do not let the user shoot
# themselves in the foot by removing this.
@@ -1559,7 +1562,7 @@ def ignore_unconfigurable_lines(lines_to_add, lines_to_del):
log.info('"%s" cannot be removed' % (ctx_keys[-1],))
lines_to_del_to_del.append((ctx_keys, line))
- for (ctx_keys, line) in lines_to_del_to_del:
+ for ctx_keys, line in lines_to_del_to_del:
lines_to_del.remove((ctx_keys, line))
return (lines_to_add, lines_to_del)
@@ -1584,8 +1587,7 @@ def compare_context_objects(newconf, running):
# Find contexts that are in newconf but not in running
# Find contexts that are in running but not in newconf
- for (running_ctx_keys, running_ctx) in iteritems(running.contexts):
-
+ for running_ctx_keys, running_ctx in iteritems(running.contexts):
if running_ctx_keys in newconf.contexts:
newconf_ctx = newconf.contexts[running_ctx_keys]
@@ -1606,7 +1608,6 @@ def compare_context_objects(newconf, running):
lines_to_del.append((running_ctx_keys, new_del_line))
if running_ctx_keys not in newconf.contexts:
-
# We check that the len is 1 here so that we only look at ('router bgp 10')
# and not ('router bgp 10', 'address-family ipv4 unicast'). The
# latter could cause a false delete_bgpd positive if ipv4 unicast is in
@@ -1777,14 +1778,12 @@ def compare_context_objects(newconf, running):
# Find the lines within each context to add
# Find the lines within each context to del
- for (newconf_ctx_keys, newconf_ctx) in iteritems(newconf.contexts):
-
+ for newconf_ctx_keys, newconf_ctx in iteritems(newconf.contexts):
if newconf_ctx_keys in running.contexts:
running_ctx = running.contexts[newconf_ctx_keys]
for line in newconf_ctx.lines:
if line not in running_ctx.dlines:
-
# candidate paths can only be added after the policy and segment list,
# so add them to a separate array that is going to be appended at the end
if (
@@ -1802,10 +1801,8 @@ def compare_context_objects(newconf, running):
if line not in newconf_ctx.dlines:
lines_to_del.append((newconf_ctx_keys, line))
- for (newconf_ctx_keys, newconf_ctx) in iteritems(newconf.contexts):
-
+ for newconf_ctx_keys, newconf_ctx in iteritems(newconf.contexts):
if newconf_ctx_keys not in running.contexts:
-
# candidate paths can only be added after the policy and segment list,
# so add them to a separate array that is going to be appended at the end
if (
@@ -2040,7 +2037,6 @@ if __name__ == "__main__":
reload_ok = False
if args.test:
-
# Create a Config object from the running config
running = Config(vtysh)
@@ -2056,8 +2052,7 @@ if __name__ == "__main__":
print("\nLines To Delete")
print("===============")
- for (ctx_keys, line) in lines_to_del:
-
+ for ctx_keys, line in lines_to_del:
if line == "!":
continue
@@ -2083,8 +2078,7 @@ if __name__ == "__main__":
print("\nLines To Add")
print("============")
- for (ctx_keys, line) in lines_to_add:
-
+ for ctx_keys, line in lines_to_add:
if line == "!":
continue
@@ -2172,8 +2166,7 @@ if __name__ == "__main__":
# apply to other scenarios as well where configuring FOO adds BAR
# to the config.
if lines_to_del and x == 0:
- for (ctx_keys, line) in lines_to_del:
-
+ for ctx_keys, line in lines_to_del:
if line == "!":
continue
@@ -2203,12 +2196,11 @@ if __name__ == "__main__":
vtysh(["configure"] + cmd, stdouts)
except VtyshException:
-
# - Pull the last entry from cmd (this would be
# 'no ip ospf authentication message-digest 1.1.1.1' in
# our example above
# - Split that last entry by whitespace and drop the last word
- log.info("Failed to execute %s", " ".join(cmd))
+ log.error("Failed to execute %s", " ".join(cmd))
last_arg = cmd[-1].split(" ")
if len(last_arg) <= 2:
@@ -2231,8 +2223,7 @@ if __name__ == "__main__":
if lines_to_add:
lines_to_configure = []
- for (ctx_keys, line) in lines_to_add:
-
+ for ctx_keys, line in lines_to_add:
if line == "!":
continue
diff --git a/tools/frr.in b/tools/frr.in
index cd24a96..94c15d5 100755
--- a/tools/frr.in
+++ b/tools/frr.in
@@ -14,11 +14,11 @@
#
PATH=/bin:/usr/bin:/sbin:/usr/sbin
-D_PATH="@CFG_SBIN@" # /usr/lib/frr
-C_PATH="@CFG_SYSCONF@" # /etc/frr
-V_PATH="@CFG_STATE@" # /var/run/frr
-B_PATH="@CFG_BIN@"
-VTYSH="@vtysh_bin@" # /usr/bin/vtysh
+D_PATH="@e_sbindir@" # /usr/lib/frr
+C_PATH="@e_frr_sysconfdir@" # /etc/frr
+V_PATH="@e_frr_runstatedir@" # /var/run/frr
+B_PATH="@e_bindir@"
+VTYSH="@e_vtysh_bin@" # /usr/bin/vtysh
FRR_USER="@enable_user@" # frr
FRR_GROUP="@enable_group@" # frr
FRR_VTY_GROUP="@enable_vty_group@" # frrvty
diff --git a/tools/frr.service.in b/tools/frr.service.in
index 1e958dd..b52ee3f 100644
--- a/tools/frr.service.in
+++ b/tools/frr.service.in
@@ -17,10 +17,10 @@ WatchdogSec=60s
RestartSec=5
Restart=always
LimitNOFILE=1024
-PIDFile=@CFG_STATE@/watchfrr.pid
-ExecStart=@CFG_SBIN@/frrinit.sh start
-ExecStop=@CFG_SBIN@/frrinit.sh stop
-ExecReload=@CFG_SBIN@/frrinit.sh reload
+PIDFile=@e_frr_runstatedir@/watchfrr.pid
+ExecStart=@e_sbindir@/frrinit.sh start
+ExecStop=@e_sbindir@/frrinit.sh stop
+ExecReload=@e_sbindir@/frrinit.sh reload
[Install]
WantedBy=multi-user.target
diff --git a/tools/frr@.service.in b/tools/frr@.service.in
index 85408a0..c8a2d3b 100644
--- a/tools/frr@.service.in
+++ b/tools/frr@.service.in
@@ -17,10 +17,10 @@ WatchdogSec=60s
RestartSec=5
Restart=always
LimitNOFILE=1024
-PIDFile=@CFG_STATE@/%I/watchfrr.pid
-ExecStart=@CFG_SBIN@/frrinit.sh start %I
-ExecStop=@CFG_SBIN@/frrinit.sh stop %I
-ExecReload=@CFG_SBIN@/frrinit.sh reload %I
+PIDFile=@e_frr_runstatedir@/%I/watchfrr.pid
+ExecStart=@e_sbindir@/frrinit.sh start %I
+ExecStop=@e_sbindir@/frrinit.sh stop %I
+ExecReload=@e_sbindir@/frrinit.sh reload %I
[Install]
WantedBy=multi-user.target
diff --git a/tools/frr_babeltrace.py b/tools/frr_babeltrace.py
index 4d974ad..9832568 100755
--- a/tools/frr_babeltrace.py
+++ b/tools/frr_babeltrace.py
@@ -157,6 +157,46 @@ def parse_frr_bgp_evpn_mh_local_es_evi_del_zrecv(event):
parse_event(event, field_parsers)
+def parse_frr_bgp_evpn_mh_es_evi_vtep_add(event):
+ """
+ bgp evpn remote ead evi remote vtep add; raw format -
+ ctf_array(unsigned char, esi, esi, sizeof(esi_t))
+ """
+ field_parsers = {"esi": print_esi,
+ "vtep": print_net_ipv4_addr}
+
+ parse_event(event, field_parsers)
+
+def parse_frr_bgp_evpn_mh_es_evi_vtep_del(event):
+ """
+ bgp evpn remote ead evi remote vtep del; raw format -
+ ctf_array(unsigned char, esi, esi, sizeof(esi_t))
+ """
+ field_parsers = {"esi": print_esi,
+ "vtep": print_net_ipv4_addr}
+
+ parse_event(event, field_parsers)
+
+def parse_frr_bgp_evpn_mh_local_ead_es_evi_route_upd(event):
+ """
+ bgp evpn local ead evi vtep; raw format -
+ ctf_array(unsigned char, esi, esi, sizeof(esi_t))
+ """
+ field_parsers = {"esi": print_esi,
+ "vtep": print_net_ipv4_addr}
+
+ parse_event(event, field_parsers)
+
+def parse_frr_bgp_evpn_mh_local_ead_es_evi_route_del(event):
+ """
+ bgp evpn local ead evi vtep del; raw format -
+ ctf_array(unsigned char, esi, esi, sizeof(esi_t))
+ """
+ field_parsers = {"esi": print_esi,
+ "vtep": print_net_ipv4_addr}
+
+ parse_event(event, field_parsers)
+
def parse_frr_bgp_evpn_local_vni_add_zrecv(event):
"""
bgp evpn local-vni parser; raw format -
@@ -205,6 +245,24 @@ def parse_frr_bgp_evpn_local_macip_del_zrecv(event):
parse_event(event, field_parsers)
+def parse_frr_bgp_evpn_advertise_type5(event):
+ """
+ local originated type-5 route
+ """
+ field_parsers = {"ip": print_ip_addr,
+ "rmac": print_mac,
+ "vtep": print_net_ipv4_addr}
+
+ parse_event(event, field_parsers)
+
+def parse_frr_bgp_evpn_withdraw_type5(event):
+ """
+ local originated type-5 route withdraw
+ """
+ field_parsers = {"ip": print_ip_addr}
+
+ parse_event(event, field_parsers)
+
############################ evpn parsers - end *#############################
def main():
@@ -225,6 +283,14 @@ def main():
parse_frr_bgp_evpn_mh_local_es_evi_add_zrecv,
"frr_bgp:evpn_mh_local_es_evi_del_zrecv":
parse_frr_bgp_evpn_mh_local_es_evi_del_zrecv,
+ "frr_bgp:evpn_mh_es_evi_vtep_add":
+ parse_frr_bgp_evpn_mh_es_evi_vtep_add,
+ "frr_bgp:evpn_mh_es_evi_vtep_del":
+ parse_frr_bgp_evpn_mh_es_evi_vtep_del,
+ "frr_bgp:evpn_mh_local_ead_es_evi_route_upd":
+ parse_frr_bgp_evpn_mh_local_ead_es_evi_route_upd,
+ "frr_bgp:evpn_mh_local_ead_es_evi_route_del":
+ parse_frr_bgp_evpn_mh_local_ead_es_evi_route_del,
"frr_bgp:evpn_local_vni_add_zrecv":
parse_frr_bgp_evpn_local_vni_add_zrecv,
"frr_bgp:evpn_local_l3vni_add_zrecv":
@@ -233,6 +299,10 @@ def main():
parse_frr_bgp_evpn_local_macip_add_zrecv,
"frr_bgp:evpn_local_macip_del_zrecv":
parse_frr_bgp_evpn_local_macip_del_zrecv,
+ "frr_bgp:evpn_advertise_type5":
+ parse_frr_bgp_evpn_advertise_type5,
+ "frr_bgp:evpn_withdraw_type5":
+ parse_frr_bgp_evpn_withdraw_type5,
}
# get the trace path from the first command line argument
diff --git a/tools/frrcommon.sh.in b/tools/frrcommon.sh.in
index 00b63a7..44d4195 100755
--- a/tools/frrcommon.sh.in
+++ b/tools/frrcommon.sh.in
@@ -14,18 +14,18 @@
# not perform any action. Note there is an "exit 1" if the main config
# file does not exist.
#
-# This script should be installed in @CFG_SBIN@/frrcommon.sh
+# This script should be installed in @e_sbindir@/frrcommon.sh
# FRR_PATHSPACE is passed in from watchfrr
suffix="${FRR_PATHSPACE:+/${FRR_PATHSPACE}}"
nsopt="${FRR_PATHSPACE:+-N ${FRR_PATHSPACE}}"
PATH=/bin:/usr/bin:/sbin:/usr/sbin
-D_PATH="@CFG_SBIN@" # /usr/lib/frr
-C_PATH="@CFG_SYSCONF@${suffix}" # /etc/frr
-V_PATH="@CFG_STATE@${suffix}" # /var/run/frr
-B_PATH="@CFG_BIN@"
-VTYSH="@vtysh_bin@" # /usr/bin/vtysh
+D_PATH="@e_sbindir@" # /usr/lib/frr
+C_PATH="@e_frr_sysconfdir@${suffix}" # /etc/frr
+V_PATH="@e_frr_runstatedir@${suffix}" # /var/run/frr
+B_PATH="@e_bindir@"
+VTYSH="@e_vtysh_bin@" # /usr/bin/vtysh
FRR_USER="@enable_user@" # frr
FRR_GROUP="@enable_group@" # frr
FRR_VTY_GROUP="@enable_vty_group@" # frrvty
diff --git a/tools/frrinit.sh.in b/tools/frrinit.sh.in
index 428d57c..178d18d 100644
--- a/tools/frrinit.sh.in
+++ b/tools/frrinit.sh.in
@@ -37,7 +37,7 @@ self="`dirname $0`"
if [ -r "$self/frrcommon.sh" ]; then
. "$self/frrcommon.sh"
else
- . "@CFG_SBIN@/frrcommon.sh"
+ . "@e_sbindir@/frrcommon.sh"
fi
case "$1" in
diff --git a/tools/gen_northbound_callbacks.c b/tools/gen_northbound_callbacks.c
index 5b778a1..a879811 100644
--- a/tools/gen_northbound_callbacks.c
+++ b/tools/gen_northbound_callbacks.c
@@ -7,6 +7,7 @@
#define REALLY_NEED_PLAIN_GETOPT 1
#include <zebra.h>
+#include <sys/stat.h>
#include <unistd.h>
@@ -25,67 +26,70 @@ static void __attribute__((noreturn)) usage(int status)
static struct nb_callback_info {
int operation;
bool optional;
+ bool need_config_write;
char return_type[32];
char return_value[32];
char arguments[128];
} nb_callbacks[] = {
{
- .operation = NB_OP_CREATE,
+ .operation = NB_CB_CREATE,
+ .need_config_write = true,
.return_type = "int ",
.return_value = "NB_OK",
.arguments = "struct nb_cb_create_args *args",
},
{
- .operation = NB_OP_MODIFY,
+ .operation = NB_CB_MODIFY,
+ .need_config_write = true,
.return_type = "int ",
.return_value = "NB_OK",
.arguments = "struct nb_cb_modify_args *args",
},
{
- .operation = NB_OP_DESTROY,
+ .operation = NB_CB_DESTROY,
.return_type = "int ",
.return_value = "NB_OK",
.arguments = "struct nb_cb_destroy_args *args",
},
{
- .operation = NB_OP_MOVE,
+ .operation = NB_CB_MOVE,
.return_type = "int ",
.return_value = "NB_OK",
.arguments = "struct nb_cb_move_args *args",
},
{
- .operation = NB_OP_APPLY_FINISH,
+ .operation = NB_CB_APPLY_FINISH,
.optional = true,
.return_type = "void ",
.return_value = "",
.arguments = "struct nb_cb_apply_finish_args *args",
},
{
- .operation = NB_OP_GET_ELEM,
+ .operation = NB_CB_GET_ELEM,
.return_type = "struct yang_data *",
.return_value = "NULL",
.arguments = "struct nb_cb_get_elem_args *args",
},
{
- .operation = NB_OP_GET_NEXT,
+ .operation = NB_CB_GET_NEXT,
.return_type = "const void *",
.return_value = "NULL",
.arguments = "struct nb_cb_get_next_args *args",
},
{
- .operation = NB_OP_GET_KEYS,
+ .operation = NB_CB_GET_KEYS,
.return_type = "int ",
.return_value = "NB_OK",
.arguments = "struct nb_cb_get_keys_args *args",
},
{
- .operation = NB_OP_LOOKUP_ENTRY,
+ .operation = NB_CB_LOOKUP_ENTRY,
.return_type = "const void *",
.return_value = "NULL",
.arguments = "struct nb_cb_lookup_entry_args *args",
},
{
- .operation = NB_OP_RPC,
+ .operation = NB_CB_RPC,
.return_type = "int ",
.return_value = "NB_OK",
.arguments = "struct nb_cb_rpc_args *args",
@@ -96,6 +100,16 @@ static struct nb_callback_info {
},
};
+/*
+ * Special-purpose info block for the cli-config-write callback. This
+ * is different enough from the config-oriented callbacks that it doesn't
+ * really fit in the array above.
+ */
+static struct nb_callback_info nb_config_write = {
+ .return_type = "void ",
+ .arguments = "struct vty *vty, const struct lyd_node *dnode, bool show_defaults",
+};
+
static void replace_hyphens_by_underscores(char *str)
{
char *p;
@@ -106,7 +120,7 @@ static void replace_hyphens_by_underscores(char *str)
}
static void generate_callback_name(const struct lysc_node *snode,
- enum nb_operation operation, char *buffer,
+ enum nb_cb_operation operation, char *buffer,
size_t size)
{
struct list *snodes;
@@ -128,7 +142,38 @@ static void generate_callback_name(const struct lysc_node *snode,
strlcat(buffer, snode->name, size);
strlcat(buffer, "_", size);
}
- strlcat(buffer, nb_operation_name(operation), size);
+ strlcat(buffer, nb_cb_operation_name(operation), size);
+ list_delete(&snodes);
+
+ replace_hyphens_by_underscores(buffer);
+}
+
+static void generate_config_write_cb_name(const struct lysc_node *snode,
+ char *buffer, size_t size)
+{
+ struct list *snodes;
+ struct listnode *ln;
+
+ buffer[0] = '\0';
+
+ snodes = list_new();
+ for (; snode; snode = snode->parent) {
+ /* Skip schema-only snodes. */
+ if (CHECK_FLAG(snode->nodetype, LYS_USES | LYS_CHOICE | LYS_CASE
+ | LYS_INPUT
+ | LYS_OUTPUT))
+ continue;
+
+ listnode_add_head(snodes, (void *)snode);
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(snodes, ln, snode)) {
+ strlcat(buffer, snode->name, size);
+ strlcat(buffer, "_", size);
+ }
+
+ strlcat(buffer, "cli_write", size);
+
list_delete(&snodes);
replace_hyphens_by_underscores(buffer);
@@ -140,8 +185,16 @@ static void generate_prototype(const struct nb_callback_info *ncinfo,
printf("%s%s(%s);\n", ncinfo->return_type, cb_name, ncinfo->arguments);
}
+static void generate_config_write_prototype(const struct nb_callback_info *ncinfo,
+ const char *cb_name)
+{
+ printf("%s%s(%s);\n", ncinfo->return_type, cb_name, ncinfo->arguments);
+}
+
static int generate_prototypes(const struct lysc_node *snode, void *arg)
{
+ bool need_config_write = true;
+
switch (snode->nodetype) {
case LYS_CONTAINER:
case LYS_LEAF:
@@ -159,12 +212,21 @@ static int generate_prototypes(const struct lysc_node *snode, void *arg)
char cb_name[BUFSIZ];
if (cb->optional
- || !nb_operation_is_valid(cb->operation, snode))
+ || !nb_cb_operation_is_valid(cb->operation, snode))
continue;
generate_callback_name(snode, cb->operation, cb_name,
sizeof(cb_name));
generate_prototype(cb, cb_name);
+
+ if (cb->need_config_write && need_config_write) {
+ generate_config_write_cb_name(snode, cb_name,
+ sizeof(cb_name));
+ generate_config_write_prototype(&nb_config_write,
+ cb_name);
+
+ need_config_write = false;
+ }
}
return YANG_ITER_CONTINUE;
@@ -177,10 +239,10 @@ static void generate_callback(const struct nb_callback_info *ncinfo,
ncinfo->return_type, cb_name, ncinfo->arguments);
switch (ncinfo->operation) {
- case NB_OP_CREATE:
- case NB_OP_MODIFY:
- case NB_OP_DESTROY:
- case NB_OP_MOVE:
+ case NB_CB_CREATE:
+ case NB_CB_MODIFY:
+ case NB_CB_DESTROY:
+ case NB_CB_MOVE:
printf("\tswitch (args->event) {\n"
"\tcase NB_EV_VALIDATE:\n"
"\tcase NB_EV_PREPARE:\n"
@@ -200,9 +262,22 @@ static void generate_callback(const struct nb_callback_info *ncinfo,
printf("\treturn %s;\n}\n\n", ncinfo->return_value);
}
+static void generate_config_write_callback(const struct nb_callback_info *ncinfo,
+ const char *cb_name)
+{
+ printf("%s%s%s(%s)\n{\n", static_cbs ? "static " : "",
+ ncinfo->return_type, cb_name, ncinfo->arguments);
+
+ /* Add a comment, since these callbacks may not all be needed. */
+ printf("\t/* TODO: this cli callback is optional; the cli output may not need to be done at each node. */\n");
+
+ printf("}\n\n");
+}
+
static int generate_callbacks(const struct lysc_node *snode, void *arg)
{
bool first = true;
+ bool need_config_write = true;
switch (snode->nodetype) {
case LYS_CONTAINER:
@@ -221,7 +296,7 @@ static int generate_callbacks(const struct lysc_node *snode, void *arg)
char cb_name[BUFSIZ];
if (cb->optional
- || !nb_operation_is_valid(cb->operation, snode))
+ || !nb_cb_operation_is_valid(cb->operation, snode))
continue;
if (first) {
@@ -240,6 +315,15 @@ static int generate_callbacks(const struct lysc_node *snode, void *arg)
generate_callback_name(snode, cb->operation, cb_name,
sizeof(cb_name));
generate_callback(cb, cb_name);
+
+ if (cb->need_config_write && need_config_write) {
+ generate_config_write_cb_name(snode, cb_name,
+ sizeof(cb_name));
+ generate_config_write_callback(&nb_config_write,
+ cb_name);
+
+ need_config_write = false;
+ }
}
return YANG_ITER_CONTINUE;
@@ -248,6 +332,10 @@ static int generate_callbacks(const struct lysc_node *snode, void *arg)
static int generate_nb_nodes(const struct lysc_node *snode, void *arg)
{
bool first = true;
+ char cb_name[BUFSIZ];
+ char xpath[XPATH_MAXLEN];
+ bool config_pass = *(bool *)arg;
+ bool need_config_write = true;
switch (snode->nodetype) {
case LYS_CONTAINER:
@@ -261,31 +349,53 @@ static int generate_nb_nodes(const struct lysc_node *snode, void *arg)
return YANG_ITER_CONTINUE;
}
+ /* We generate two types of structs currently; behavior is a little
+ * different between the types.
+ */
for (struct nb_callback_info *cb = &nb_callbacks[0];
cb->operation != -1; cb++) {
- char cb_name[BUFSIZ];
if (cb->optional
- || !nb_operation_is_valid(cb->operation, snode))
+ || !nb_cb_operation_is_valid(cb->operation, snode))
continue;
- if (first) {
- char xpath[XPATH_MAXLEN];
+ if (config_pass) {
+ if (first) {
+ yang_snode_get_path(snode, YANG_PATH_DATA, xpath,
+ sizeof(xpath));
- yang_snode_get_path(snode, YANG_PATH_DATA, xpath,
- sizeof(xpath));
+ printf("\t\t{\n"
+ "\t\t\t.xpath = \"%s\",\n",
+ xpath);
+ printf("\t\t\t.cbs = {\n");
+ first = false;
+ }
- printf("\t\t{\n"
- "\t\t\t.xpath = \"%s\",\n",
- xpath);
- printf("\t\t\t.cbs = {\n");
- first = false;
- }
+ generate_callback_name(snode, cb->operation, cb_name,
+ sizeof(cb_name));
+ printf("\t\t\t\t.%s = %s,\n",
+ nb_cb_operation_name(cb->operation),
+ cb_name);
+ } else if (cb->need_config_write && need_config_write) {
+ if (first) {
+ yang_snode_get_path(snode,
+ YANG_PATH_DATA,
+ xpath,
+ sizeof(xpath));
+
+ printf("\t\t{\n"
+ "\t\t\t.xpath = \"%s\",\n",
+ xpath);
+ printf("\t\t\t.cbs = {\n");
+ first = false;
+ }
- generate_callback_name(snode, cb->operation, cb_name,
- sizeof(cb_name));
- printf("\t\t\t\t.%s = %s,\n", nb_operation_name(cb->operation),
- cb_name);
+ generate_config_write_cb_name(snode, cb_name,
+ sizeof(cb_name));
+ printf("\t\t\t\t.cli_show = %s,\n", cb_name);
+
+ need_config_write = false;
+ }
}
if (!first) {
@@ -303,6 +413,7 @@ int main(int argc, char *argv[])
char module_name_underscores[64];
struct stat st;
int opt;
+ bool config_pass;
while ((opt = getopt(argc, argv, "hp:s")) != -1) {
switch (opt) {
@@ -348,13 +459,18 @@ int main(int argc, char *argv[])
module = yang_module_find(argv[0]);
if (!module)
/* Non-native FRR module (e.g. modules from unit tests). */
- module = yang_module_load(argv[0]);
+ module = yang_module_load(argv[0], NULL);
yang_init_loading_complete();
/* Create a nb_node for all YANG schema nodes. */
nb_nodes_create();
+ /* Emit bare-bones license line (and fool the checkpatch regex
+ * that triggers a warning).
+ */
+ printf("// SPDX-" "License-Identifier: GPL-2.0-or-later\n\n");
+
/* Generate callback prototypes. */
if (!static_cbs) {
printf("/* prototypes */\n");
@@ -369,13 +485,38 @@ int main(int argc, char *argv[])
sizeof(module_name_underscores));
replace_hyphens_by_underscores(module_name_underscores);
- /* Generate frr_yang_module_info array. */
+ /*
+ * We're going to generate two structs here, two arrays of callbacks:
+ * first one with config-handling callbacks, then a second struct with
+ * config-output-oriented callbacks.
+ */
+
+ /* Generate frr_yang_module_info array, with config-handling callbacks */
+ config_pass = true;
printf("/* clang-format off */\n"
- "const struct frr_yang_module_info %s_info = {\n"
+ "const struct frr_yang_module_info %s_nb_info = {\n"
"\t.name = \"%s\",\n"
"\t.nodes = {\n",
module_name_underscores, module->name);
- yang_snodes_iterate(module->info, generate_nb_nodes, 0, NULL);
+ yang_snodes_iterate(module->info, generate_nb_nodes, 0, &config_pass);
+
+ /* Emit terminator element */
+ printf("\t\t{\n"
+ "\t\t\t.xpath = NULL,\n"
+ "\t\t},\n");
+ printf("\t}\n"
+ "};\n");
+
+ /* Generate second array, with output-oriented callbacks. */
+ config_pass = false;
+ printf("\n/* clang-format off */\n"
+ "const struct frr_yang_module_info %s_cli_info = {\n"
+ "\t.name = \"%s\",\n"
+ "\t.nodes = {\n",
+ module_name_underscores, module->name);
+ yang_snodes_iterate(module->info, generate_nb_nodes, 0, &config_pass);
+
+ /* Emit terminator element */
printf("\t\t{\n"
"\t\t\t.xpath = NULL,\n"
"\t\t},\n");
diff --git a/tools/gen_yang_deviations.c b/tools/gen_yang_deviations.c
index fc9f55b..251643c 100644
--- a/tools/gen_yang_deviations.c
+++ b/tools/gen_yang_deviations.c
@@ -55,7 +55,7 @@ int main(int argc, char *argv[])
yang_init(false, false);
/* Load YANG module. */
- module = yang_module_load(argv[0]);
+ module = yang_module_load(argv[0], NULL);
/* Generate deviations. */
yang_snodes_iterate(module->info, generate_yang_deviation, 0, NULL);
diff --git a/tools/valgrind.supp b/tools/valgrind.supp
index da3d4a8..d2cb411 100644
--- a/tools/valgrind.supp
+++ b/tools/valgrind.supp
@@ -24,6 +24,15 @@
fun:zprivs_caps_init
}
{
+ <zprivs_init leak in library code we do not control>
+ Memcheck:Leak
+ match-leak-kinds: reachable
+ ...
+ fun:getgrouplist
+ fun:zprivs_init
+ fun:frr_init
+}
+{
<sqlite3 leak in a function we do not control>
Memcheck:Leak
fun:malloc
diff --git a/tools/watchfrr.sh.in b/tools/watchfrr.sh.in
index 712f962..31279f6 100644
--- a/tools/watchfrr.sh.in
+++ b/tools/watchfrr.sh.in
@@ -5,7 +5,7 @@
# internally by watchfrr to start the protocol daemons with the appropriate
# options.
#
-# This script should be installed in @CFG_SBIN@/watchfrr.sh
+# This script should be installed in @e_sbindir@/watchfrr.sh
log_success_msg() {
:
@@ -27,7 +27,7 @@ self="`dirname $0`"
if [ -r "$self/frrcommon.sh" ]; then
. "$self/frrcommon.sh"
else
- . "@CFG_SBIN@/frrcommon.sh"
+ . "@e_sbindir@/frrcommon.sh"
fi
frrcommon_main "$@"