Pat Ruddy [Fri, 18 Sep 2020 09:12:08 +0000 (10:12 +0100)]
bgpd: add utility to check if a vrf is active
From RFC4382:
A VRF is
up(1) when there is at least one interface associated
with the VRF whose ifOperStatus is up(1). A VRF is
down(2) when:
a. There does not exist at least one interface whose
ifOperStatus is up(1).
b. There are no interfaces associated with the VRF.
Run through interfaces associated with a vrf and return
true if there is one in the up state.
Stephen Worley [Wed, 27 Jan 2021 21:20:22 +0000 (16:20 -0500)]
zebra: disallow resolution to duplicate nexthops
Disallow the resolution to nexthops that are marked duplicate.
When we are resolving to an ecmp group, it's possible this
group has duplicates.
I found this when I hit a bug where we can have groups resolving
to each other and cause the resolved->next->next pointer to increase
exponentially. Sufficiently large ecmp and zebra will grind to a hault.
Like so:
```
D> 4.4.4.14/32 [150/0] via 1.1.1.1 (recursive), weight 1, 00:00:02
* via 1.1.1.1, dummy1 onlink, weight 1, 00:00:02
via 4.4.4.1 (recursive), weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 4.4.4.2 (recursive), weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 4.4.4.3 (recursive), weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 4.4.4.4 (recursive), weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 4.4.4.5 (recursive), weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 4.4.4.6 (recursive), weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 4.4.4.7 (recursive), weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 4.4.4.8 (recursive), weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 4.4.4.9 (recursive), weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 4.4.4.10 (recursive), weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 4.4.4.11 (recursive), weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 4.4.4.12 (recursive), weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 4.4.4.13 (recursive), weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 4.4.4.15 (recursive), weight 1, 00:00:02
via 1.1.1.1, dummy1 onlink, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1 onlink, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 4.4.4.16 (recursive), weight 1, 00:00:02
via 1.1.1.1, dummy1 onlink, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
via 1.1.1.1, dummy1, weight 1, 00:00:02
D> 4.4.4.15/32 [150/0] via 1.1.1.1 (recursive), weight 1, 00:00:09
* via 1.1.1.1, dummy1 onlink, weight 1, 00:00:09
via 4.4.4.1 (recursive), weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 4.4.4.2 (recursive), weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 4.4.4.3 (recursive), weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 4.4.4.4 (recursive), weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 4.4.4.5 (recursive), weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 4.4.4.6 (recursive), weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 4.4.4.7 (recursive), weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 4.4.4.8 (recursive), weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 4.4.4.9 (recursive), weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 4.4.4.10 (recursive), weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 4.4.4.11 (recursive), weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 4.4.4.12 (recursive), weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 4.4.4.13 (recursive), weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 4.4.4.14 (recursive), weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 4.4.4.16 (recursive), weight 1, 00:00:09
via 1.1.1.1, dummy1 onlink, weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
via 1.1.1.1, dummy1, weight 1, 00:00:09
D> 4.4.4.16/32 [150/0] via 1.1.1.1 (recursive), weight 1, 00:00:19
* via 1.1.1.1, dummy1 onlink, weight 1, 00:00:19
via 4.4.4.1 (recursive), weight 1, 00:00:19
via 1.1.1.1, dummy1, weight 1, 00:00:19
via 4.4.4.2 (recursive), weight 1, 00:00:19
Then use sharpd to install 4.4.4.16 -> 4.4.4.1 pointing to that nexthop
group in decending order.
```
With these changes it prevents the growing ecmp above by disallowing
duplicates to be in the resolution decision. These nexthops are not
installed anyways so why should we be resolving to them?
Signed-off-by: Stephen Worley <sworley@nvidia.com>
David Lamparter [Mon, 1 Feb 2021 16:50:01 +0000 (17:50 +0100)]
lib/printf: disable `%n` specifier
We don't use `%n` anywhere, so the only purpose it serves is enabling
exploits.
(I thought about this initially when adding printfrr, but I wasn't sure
we don't use `%n` anywhere, and thought I'll check later, and then just
forgot it...)
Signed-off-by: David Lamparter <equinox@diac24.net>
Donald Sharp [Mon, 1 Feb 2021 15:14:38 +0000 (10:14 -0500)]
bgpd: Centralize the dest unlocking for adj_out data structure
When FRR creates a adj_out data structure we lock the `struct
bgp_dest` node associated with it. On freeing of this data
structure and removing the lock it was not associated with
the actual free of the adjacency structure. Let's clean up
the lock/unlock to be centralized to the alloc/free of the adj_out.
Donald Sharp [Thu, 28 Jan 2021 16:25:51 +0000 (11:25 -0500)]
lib: Line up `show thread cpu` output appropriately
The output from `show thread cpu` was not lined up appropriately
for the header line. As well as the function name we were
calling in the output. Fix it.
Donatas Abraitis [Sun, 31 Jan 2021 14:20:36 +0000 (16:20 +0200)]
bgpd: Initialize bgp_notify.raw_data before passing to bgp_notify_receive()
``` 2523558-==2523558== 2523558-==2523558== Conditional jump or move depends on uninitialised value(s) 2523558:==2523558== at 0x47F242: bgp_notify_admin_message (bgp_debug.c:505) 2523558-==2523558== by 0x47F242: bgp_notify_print (bgp_debug.c:534) 2523558-==2523558== by 0x4BA9BC: bgp_notify_receive (bgp_packet.c:1905) 2523558-==2523558== by 0x4BA9BC: bgp_process_packet (bgp_packet.c:2602) 2523558-==2523558== by 0x4904B7E: thread_call (thread.c:1681) 2523558-==2523558== by 0x48CAA27: frr_run (libfrr.c:1126) 2523558-==2523558== by 0x474B1A: main (bgp_main.c:540) 2523558-==2523558== Uninitialised value was created by a stack allocation 2523558:==2523558== at 0x4BA33D: bgp_process_packet (bgp_packet.c:2529)
```
Donald Sharp [Sat, 30 Jan 2021 19:31:47 +0000 (14:31 -0500)]
bfdd: Prevent unininited data transmittal
Valgrind reports:
2052866-==2052866== 2052866-==2052866== Syscall param sendmsg(msg.msg_name) points to uninitialised byte(s) 2052866:==2052866== at 0x49C8E13: sendmsg (sendmsg.c:28) 2052866-==2052866== by 0x11DC08: bp_udp_send (bfd_packet.c:823) 2052866-==2052866== by 0x11DD76: ptm_bfd_echo_snd (bfd_packet.c:179) 2052866-==2052866== by 0x114C2D: ptm_bfd_echo_xmt_TO (bfd.c:469) 2052866-==2052866== by 0x114C2D: ptm_bfd_echo_start (bfd.c:498) 2052866-==2052866== by 0x114C2D: bs_echo_timer_handler (bfd.c:1199) 2052866-==2052866== by 0x11E478: bfd_recv_cb (bfd_packet.c:702) 2052866-==2052866== by 0x4904846: thread_call (thread.c:1681) 2052866-==2052866== by 0x48CB4DF: frr_run (libfrr.c:1126) 2052866-==2052866== by 0x113044: main (bfdd.c:403) 2052866-==2052866== Address 0x1ffefff3e8 is on thread 1's stack
In ptm_bfd_echo_snd, for the v4 case we were memsetting the v6 memory
then setting the v4 memory. Just fix it.
Donald Sharp [Sat, 30 Jan 2021 19:13:34 +0000 (14:13 -0500)]
ospfd: Prevent sending of uninited data to zebra
Valgrind reports: 2174600-==2174600== 2174600-==2174600== Syscall param write(buf) points to uninitialised byte(s) 2174600:==2174600== at 0x49C7FB3: write (write.c:26) 2174600-==2174600== by 0x48A4EA0: buffer_write (buffer.c:475) 2174600-==2174600== by 0x4915AD9: zclient_send_message (zclient.c:298) 2174600-==2174600== by 0x12DB97: ospf_ldp_sync_state_req_msg (ospf_ldp_sync.c:114) 2174600-==2174600== by 0x12E4F0: ospf_ldp_sync_if_start (ospf_ldp_sync.c:160) 2174600-==2174600== by 0x12E4F0: ospf_ldp_sync_ism_change (ospf_ldp_sync.c:339) 2174600-==2174600== by 0x12E4F0: ospf_ldp_sync_ism_change (ospf_ldp_sync.c:332) 2174600-==2174600== by 0x12C6A2: hook_call_ospf_ism_change (ospf_ism.c:46) 2174600-==2174600== by 0x12C6A2: ism_change_state (ospf_ism.c:540) 2174600-==2174600== by 0x12C6A2: ospf_ism_event (ospf_ism.c:600) 2174600-==2174600== by 0x4904846: thread_call (thread.c:1681)
When we send the request structure we are sending the whole thing and the
interface name string has junk at the end. Not a big deal, but cleans
up valgrind going wumple on us.
Donald Sharp [Sat, 30 Jan 2021 18:38:32 +0000 (13:38 -0500)]
eigrpd: Prevent uninitialized value from being used
valgrind is finding:
2141982-==2141982== Conditional jump or move depends on uninitialised value(s) 2141982:==2141982== at 0x11A7A6: eigrp_metrics_is_same (eigrp_metric.c:134) 2141982-==2141982== by 0x120360: eigrp_topology_update_distance (eigrp_topology.c:374) 2141982-==2141982== by 0x124F01: eigrp_get_fsm_event (eigrp_fsm.c:284) 2141982-==2141982== by 0x12519E: eigrp_fsm_event (eigrp_fsm.c:419) 2141982-==2141982== by 0x1206A1: eigrp_topology_neighbor_down (eigrp_topology.c:518) 2141982-==2141982== by 0x11AB3A: eigrp_nbr_delete (eigrp_neighbor.c:178) 2141982-==2141982== by 0x124494: eigrp_finish_final (eigrpd.c:271) 2141982-==2141982== by 0x1245A8: eigrp_finish (eigrpd.c:247) 2141982-==2141982== by 0x124630: eigrp_terminate (eigrpd.c:240) 2141982-==2141982== by 0x11344B: sigint (eigrp_main.c:112) 2141982-==2141982== by 0x48F5F32: quagga_sigevent_process (sigevent.c:130)
Donald Sharp [Sat, 30 Jan 2021 02:27:49 +0000 (21:27 -0500)]
bgpd: Remove hidden `neighbor X route-map Y <in|out>` command
This command was put in place to allow upgrades for the
neighbor command from the BGP_NODE and have it put
into the ipv4 uni node instead. Since this
utterly kills the yang conversion. I believe we need
to remove this. Since people upgrading will just loose
the route-map applicatoin( if they are using such an old
config ) and RFC 8212 will come into play. They'll figure
it out pretty fast.
Fixes: #7983 Signed-off-by: Donald Sharp <sharpd@nvidia.com>
The calling function of ospf_nbr_nbma_lookup_next calls
this function and then immediately returns when it
gets the NULL. Just cleanup a bit more code.
Donald Sharp [Thu, 28 Jan 2021 19:04:59 +0000 (14:04 -0500)]
pbrd: Remove #if 0 code
I am not even sure what the goal of this code was in any
way shape fashion or form. But since it's pbr_nht.c
I as the original author should know... But I don't.
Donald Sharp [Thu, 28 Jan 2021 18:21:12 +0000 (13:21 -0500)]
ospfd: Remove #if 0 code
The #if 0 code in ospfd, has not been compiled since at least
2012. If we are at least 9 years old at this point with no effort
to use or save, we should just get rid of it.
Pat Ruddy [Thu, 21 Jan 2021 14:16:26 +0000 (14:16 +0000)]
bgpd: make sure nh is valid for MPLS vpn routes
If we are using a nexthop for a MPLS VPN route make sure the
nexthop is over a labeled path. This new check mirrors the one
in validate_paths (where routes are enabled when a nexthop
becomes reachable). The check is introduced to the code path
where routes are added and the nexthop is looked up.
Duncan Eastoe [Tue, 26 Jan 2021 16:59:48 +0000 (16:59 +0000)]
tests: more robust show route header stripping
In test_converge_protocols() use sed to match the "show ip(v6) route"
header and strip it, rather than using tail which requires hardcoding
the expected length of the header (which is subject to change).
Yash Ranjan [Wed, 28 Oct 2020 10:51:39 +0000 (03:51 -0700)]
ospf6d: Json support added for command "show ipv6 ospf6 route [json]"
Modify code to add JSON format output in show command
"show ipv6 ospf6 route [<intra-area|inter-area|external-1|
external-2|X:X::X:X|X:X::X:X/M|detail|summary>]"
with proper formating
Rafael Zalamena [Tue, 26 Jan 2021 16:58:34 +0000 (13:58 -0300)]
watchfrr: fix SA warning
`valid_command` now causes static analyzer complaints since it no
longer assumes `optarg` is non-NULL. If this was the case then
`valid_command` would return `false` (or 0) because it would mean the
string is empty and doesn't contain the '%s' it expects.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Donald Sharp [Tue, 26 Jan 2021 13:10:49 +0000 (08:10 -0500)]
ospf6d: Track wait_timer and disable when needed
When removing ospfv3 from an interface that has been previously
put into wait state, there is a possible use after free of the
oi because the wait_timer could have been started for the interface.
This is because the wait_timer was not tracked by the interface
and we just created a thread for it without storing the thread
pointer.
Issue: #7932 Signed-off-by: Donald Sharp <sharpd@nvidia.com>
Donald Sharp [Tue, 26 Jan 2021 12:48:40 +0000 (07:48 -0500)]
pimd: Prevent use after free
Valgrind is reporting this:
==22220== Invalid read of size 4
==22220== at 0x11DC2B: pim_if_delete (pim_iface.c:215)
==22220== by 0x11DD71: pim_if_terminate (pim_iface.c:76)
==22220== by 0x128E03: pim_instance_terminate (pim_instance.c:66)
==22220== by 0x128E03: pim_vrf_delete (pim_instance.c:159)
==22220== by 0x48E0010: vrf_delete (vrf.c:251)
==22220== by 0x48E0010: vrf_delete (vrf.c:225)
==22220== by 0x48E02FE: vrf_terminate (vrf.c:551)
==22220== by 0x149495: pim_terminate (pimd.c:142)
==22220== by 0x13C61B: pim_sigint (pim_signals.c:44)
==22220== by 0x48CF862: quagga_sigevent_process (sigevent.c:103)
==22220== by 0x48DD324: thread_fetch (thread.c:1404)
==22220== by 0x48A926A: frr_run (libfrr.c:1122)
==22220== by 0x11B85E: main (pim_main.c:167)
==22220== Address 0x5912160 is 1,200 bytes inside a block of size 1,624 free'd
==22220== at 0x48369AB: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==22220== by 0x128E52: pim_instance_terminate (pim_instance.c:74)
==22220== by 0x128E52: pim_vrf_delete (pim_instance.c:159)
==22220== by 0x48E0010: vrf_delete (vrf.c:251)
==22220== by 0x48E0010: vrf_delete (vrf.c:225)
==22220== by 0x48F1353: zclient_vrf_delete (zclient.c:1896)
==22220== by 0x48F1353: zclient_read (zclient.c:3511)
==22220== by 0x48DD826: thread_call (thread.c:1585)
==22220== by 0x48A925F: frr_run (libfrr.c:1123)
==22220== by 0x11B85E: main (pim_main.c:167)
==22220== Block was alloc'd at
==22220== at 0x4837B65: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==22220== by 0x48ADA4F: qcalloc (memory.c:110)
==22220== by 0x128B9B: pim_instance_init (pim_instance.c:82)
==22220== by 0x128B9B: pim_vrf_new (pim_instance.c:142)
==22220== by 0x48E0C5A: vrf_get (vrf.c:217)
==22220== by 0x48F13C9: zclient_vrf_add (zclient.c:1863)
==22220== by 0x48F13C9: zclient_read (zclient.c:3508)
==22220== by 0x48DD826: thread_call (thread.c:1585)
==22220== by 0x48A925F: frr_run (libfrr.c:1123)
==22220== by 0x11B85E: main (pim_main.c:167)
On pim vrf deletion, ensure that the vrf->info pointers are NULL as well
as the free'd pim pointer for ->vrf is NULL as well.
Donald Sharp [Sun, 24 Jan 2021 12:52:55 +0000 (07:52 -0500)]
lib: Prevent possible memory overwrite
fname is MAXPATHLEN and scriptdir and fs->name are less then
MAXPATHLEN but the combination of those two + the `.lua` are
greater than the MAXPATHLEN. Just give us more room to prevent
a coding boo boo.
Mark Stapp [Thu, 21 Jan 2021 15:12:05 +0000 (10:12 -0500)]
zebra: send async nhg update results
Send the results of daemons' nhg updates asynchronously,
after the update has actually completed. Capture additional
info about the source daemon in order to locate the correct
zapi session. Simplify the result types considered by the
zebra_nhg module.