Add if_vrf_lookup_by_index_next to get the next ifindex in a vrf
given the previous ifindex or 0 for the first.
Signed-off-by: Pat Ruddy <pat@voltanet.io>
Add SNMP support for L3vpn Vrf table as defined in [RFC4382]
Keep track of vrf status for the table and for future traps.
Signed-off-by: Pat Ruddy <pat@voltanet.io>
If a vrf is exporting to a vpn table and/or importing to a vpn
table then it is assumed t be a MPLS VPN vrf.
Signed-off-by: Pat Ruddy <pat@voltanet.io>
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.
Signed-off-by: Pat Ruddy <pat@voltanet.io>
Run through the vrf's interface list and return a count, skipping
the l3mdev which has a name which matches the vrf name.
Signed-off-by: Pat Ruddy <pat@voltanet.io>
When adjacencies change state the attached-bits in LSPs in other areas
on the router may need to be modified.
1. If a router no longer has a L2 adjacency to another area the
attached-bit must no longer be sent in the LSP
2. If a new L2 adjacency comes up in a different area then the
attached-bit should be sent in the LSP
Signed-off-by: Lynne Morrison <lynne@voltanet.io>
Move the pbr hash creation to be after the update release
and dplane install. Now that rules are installed in a separate
dplane pthread, we can have scenarios where we have an interface
flapping and we install/remove rules sufficiently fast enough we
could issue what we think is an update for an identical rule and
end up releasing the rule right after we created it and sent it to
the dplane. This solves the problem of recving duplicate rules
during interface flapping.
Signed-off-by: Stephen Worley <sworley@nvidia.com>
Only handle an interface update in the nexthop tracking code
if the nexthop in question was set with an interface to point
out of. If the nexthop is GW only, the interface update could
be unrelated but have overlapping address space. Let that be
handled elsewhere.
Ex)
```
5.5.5.0/30 dev dummyDoof proto kernel scope link src 5.5.5.1
5.5.5.0/24 dev goofDummy proto kernel scope link src 5.5.5.1
[root@alfred frr-2]# ip ro show table 10000
default via 5.5.5.2 dev dummyDoof proto pbr metric 20
[root@alfred frr-2]# ip link set goofDummy down
[root@alfred frr-2]# ip ro show table 10000
[root@alfred frr-2]# ip link set goofDummy up
[root@alfred frr-2]# ip ro show table 10000
```
Signed-off-by: Stephen Worley <sworley@nvidia.com>
Add a test for the infinite recursion case fixed
with 0c4dbb5f8fe8fb188fa0e0aa8ce04764e893b79b
See that commit for details of the problem. This test uses a simpler
version of the repro found there as the test.
Signed-off-by: Stephen Worley <sworley@nvidia.com>
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
...............
................
and on...
```
You can repro the above via:
```
kernel routes:
1.1.1.1 dev dummy1 scope link
4.4.4.0/24 via 1.1.1.1 dev dummy1
==============================
config:
nexthop-group doof
nexthop 1.1.1.1
nexthop 4.4.4.1
nexthop 4.4.4.10
nexthop 4.4.4.11
nexthop 4.4.4.12
nexthop 4.4.4.13
nexthop 4.4.4.14
nexthop 4.4.4.15
nexthop 4.4.4.16
nexthop 4.4.4.2
nexthop 4.4.4.3
nexthop 4.4.4.4
nexthop 4.4.4.5
nexthop 4.4.4.6
nexthop 4.4.4.7
nexthop 4.4.4.8
nexthop 4.4.4.9
!
===========================
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>
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>
Description: When we get a new vrf add and vrf with same name, but different vrf-id already
exists in the database, we should treat vrf add as update.
This happens mostly when there are lots of vrf and other configuration being replayed.
There may be a stale vrf delete followed by new vrf add. This
can cause timing race condition where vrf delete could be missed and
further same vrf add would get rejected instead of treating last arrived
vrf add as update.
Treat vrf add for existing vrf as update.
Implicitly disable this VRF to cleanup routes and other functions as part of vrf disable.
Update vrf_id for the vrf and update vrf_id tree.
Re-enable VRF so that all routes are freshly installed.
Above 3 steps are mandatory since it can happen that with config reload
stale routes which are installed in vrf-1 table might contain routes from
older vrf-0 table which might have got deleted due to missing vrf-0 in new configuration.
Signed-off-by: sudhanshukumar22 <sudhanshu.kumar@broadcom.com>
This is the best I can make the asm blocks in lib/xref.h look, so just
mute the warning. (It shouldn't come in relevant for other code.)
Signed-off-by: David Lamparter <equinox@diac24.net>
This allows grabbing a list of all DEFUNs and their help texts through
the xref extraction mechanics.
Signed-off-by: David Lamparter <equinox@diac24.net>
This allows extracting a list of all log messages including their ECs
and autogenerated unique IDs for them.
Signed-off-by: David Lamparter <equinox@diac24.net>
Our "true" libraries (i.e. not modules) don't invoke neither
FRR_DAEMON_INFO nor FRR_MODULE_SETUP, hence XREF_SETUP isn't invoked
either. Invoke it directly to get things working.
Signed-off-by: David Lamparter <equinox@diac24.net>
This adds the machinery for cross reference points (hence "xref") for
things to be annotated with source code location or other metadata
and/or to be uniquely identified and found at runtime or by dissecting
executable files.
The extraction tool to walk down an ELF file is done and working but
needs some more cleanup and will be added in a separate commit.
Signed-off-by: David Lamparter <equinox@diac24.net>
Makes more sense to have this as a static inline. Also I don't want to
be forced to link network.o into clippy ;)
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
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.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
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.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
valgrind is reporting:
2448137-==2448137== Thread 5 zebra_apic:
2448137-==2448137== Syscall param writev(vector[...]) points to uninitialised byte(s)
2448137:==2448137== at 0x4D6FDDD: __writev (writev.c:26)
2448137-==2448137== by 0x4D6FDDD: writev (writev.c:24)
2448137-==2448137== by 0x48A35F5: buffer_flush_available (buffer.c:431)
2448137-==2448137== by 0x48A3504: buffer_flush_all (buffer.c:237)
2448137-==2448137== by 0x495948: zserv_write (zserv.c:263)
2448137-==2448137== by 0x4904B7E: thread_call (thread.c:1681)
2448137-==2448137== by 0x48BD3E5: fpt_run (frr_pthread.c:308)
2448137-==2448137== by 0x4C61EA6: start_thread (pthread_create.c:477)
2448137-==2448137== by 0x4D78DEE: clone (clone.S:95)
2448137-==2448137== Address 0x720c3ce is 62 bytes inside a block of size 4,120 alloc'd
2448137:==2448137== at 0x483877F: malloc (vg_replace_malloc.c:307)
2448137-==2448137== by 0x48D2977: qmalloc (memory.c:110)
2448137-==2448137== by 0x48A30E3: buffer_add (buffer.c:135)
2448137-==2448137== by 0x48A30E3: buffer_put (buffer.c:161)
2448137-==2448137== by 0x49591B: zserv_write (zserv.c:256)
2448137-==2448137== by 0x4904B7E: thread_call (thread.c:1681)
2448137-==2448137== by 0x48BD3E5: fpt_run (frr_pthread.c:308)
2448137-==2448137== by 0x4C61EA6: start_thread (pthread_create.c:477)
2448137-==2448137== by 0x4D78DEE: clone (clone.S:95)
2448137-==2448137== Uninitialised value was created by a stack allocation
2448137:==2448137== at 0x43E490: zserv_encode_vrf (zapi_msg.c:103)
Effectively we are sending `struct vrf_data` without ensuring
data has been properly initialized.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
Valgrind reports:
2437395-==2437395== Invalid read of size 8
2437395:==2437395== at 0x40B610: ospf6_asbr_update_route_ecmp_path (ospf6_asbr.c:327)
2437395-==2437395== by 0x40BC7C: ospf6_asbr_lsa_add (ospf6_asbr.c:544)
2437395-==2437395== by 0x40C5DF: ospf6_asbr_lsentry_add (ospf6_asbr.c:829)
2437395-==2437395== by 0x42D88D: ospf6_top_brouter_hook_add (ospf6_top.c:185)
2437395-==2437395== by 0x4188E3: ospf6_intra_brouter_calculation (ospf6_intra.c:2320)
2437395-==2437395== by 0x42C624: ospf6_spf_calculation_thread (ospf6_spf.c:638)
2437395-==2437395== by 0x4904B7E: thread_call (thread.c:1681)
2437395-==2437395== by 0x48CAA27: frr_run (libfrr.c:1126)
2437395-==2437395== by 0x40AF43: main (ospf6_main.c:232)
2437395-==2437395== Address 0x5c668a8 is 24 bytes inside a block of size 256 free'd
2437395:==2437395== at 0x48399AB: free (vg_replace_malloc.c:538)
2437395-==2437395== by 0x429027: ospf6_route_delete (ospf6_route.c:419)
2437395-==2437395== by 0x429027: ospf6_route_unlock (ospf6_route.c:460)
2437395-==2437395== by 0x429027: ospf6_route_remove (ospf6_route.c:887)
2437395-==2437395== by 0x40B343: ospf6_asbr_update_route_ecmp_path (ospf6_asbr.c:318)
2437395-==2437395== by 0x40BC7C: ospf6_asbr_lsa_add (ospf6_asbr.c:544)
2437395-==2437395== by 0x40C5DF: ospf6_asbr_lsentry_add (ospf6_asbr.c:829)
2437395-==2437395== by 0x42D88D: ospf6_top_brouter_hook_add (ospf6_top.c:185)
2437395-==2437395== by 0x4188E3: ospf6_intra_brouter_calculation (ospf6_intra.c:2320)
2437395-==2437395== by 0x42C624: ospf6_spf_calculation_thread (ospf6_spf.c:638)
2437395-==2437395== by 0x4904B7E: thread_call (thread.c:1681)
2437395-==2437395== by 0x48CAA27: frr_run (libfrr.c:1126)
2437395-==2437395== by 0x40AF43: main (ospf6_main.c:232)
2437395-==2437395== Block was alloc'd at
2437395:==2437395== at 0x483AB65: calloc (vg_replace_malloc.c:760)
2437395-==2437395== by 0x48D2A32: qcalloc (memory.c:115)
2437395-==2437395== by 0x427CE4: ospf6_route_create (ospf6_route.c:402)
2437395-==2437395== by 0x40BA8A: ospf6_asbr_lsa_add (ospf6_asbr.c:490)
2437395-==2437395== by 0x40C5DF: ospf6_asbr_lsentry_add (ospf6_asbr.c:829)
2437395-==2437395== by 0x42D88D: ospf6_top_brouter_hook_add (ospf6_top.c:185)
2437395-==2437395== by 0x4188E3: ospf6_intra_brouter_calculation (ospf6_intra.c:2320)
2437395-==2437395== by 0x42C624: ospf6_spf_calculation_thread (ospf6_spf.c:638)
2437395-==2437395== by 0x4904B7E: thread_call (thread.c:1681)
2437395-==2437395== by 0x48CAA27: frr_run (libfrr.c:1126)
2437395-==2437395== by 0x40AF43: main (ospf6_main.c:232)
ospfv3 loops through the ecmp routes to decide what to clean up. In some
situations the code free's up an existing route at the head of the list.
Cleaning the pointers in the list but never touching the original pointer.
In that case notice and update the old pointer.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
```
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)
```
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
This version of eigrp pre-calculated the eigrp metric
to be a default of 1500 bytes, but unfortunately it
had entered the byte order wrong.
Modify the code to properly set the byte order
according to the eigrp rfc as well as actually
read in and transmit the mtu of the interface
instead of hard coding it to 1500 bytes.
Fixes: #7986
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
On shutdown, interfaces are deleted but if the bfd session
is down we retain the interface pointer. Remove the retained
pointer.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>