Commit Graph

258 Commits

Author SHA1 Message Date
Rafael Zalamena
5920b3eb38 *: replace all random() calls
Replace all `random()` calls with a function called `frr_weak_random()`
and make it clear that it is only supposed to be used for weak random
applications.

Use the annotation described by the Coverity Scan documentation to
ignore `random()` call warnings.

Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
2020-04-17 20:57:43 -03:00
Donald Sharp
f32b16b09f
Merge pull request #6017 from sarav511/ovrride
pimd: Join not sent within prune override time when received non local prune
2020-04-14 08:32:32 -04:00
Donald Sharp
8fcca5024f
Merge pull request #6079 from sarav511/regstop_exp
pimd: Reg Suppression expiry has to account for couldreg->false while in RegPrune
2020-03-25 06:32:42 -04:00
saravanank
cf575d0975 pimd: Reg Suppression expiry has to account for couldreg->false while in prune
Problem: This happened in once in a while during testing the scenario multiple
times. When regstop timer expire and at that point if rpf interface doesn't
exist, the register state for the upstream gets struck in reg-prune state indefinitely.
This will not recover even when rpf comes back and traffic resumed because
register state is struck on prune.

RCA: Reg suppression expiry is keeping reg state unchanged when iif is absent.

Fix: When iif is absent during reg suppression expiry, treat it as couldreg
becoming false and move it NO_INFO state.

Signed-off-by: Saravanan K <saravanank@vmware.com>
2020-03-24 02:31:04 -07:00
saravanank
af9106e544 pimd: Join not sent within prune override time when received non local prune.
RCA: Periodic join is mostly sent by nbr jp timer except for few scenarios by upstream join timer

Fix: If join timer not running, we have to use nbr jp timer to calculate
remaining time for next join.

Signed-off-by: Saravanan K <saravanank@vmware.com>
2020-03-17 02:01:35 -07:00
Sarita Patra
9443810eef pimd: fix OIL not removed after IGMP prune
Issue: Client1------LHR-----(int-1)RP(int-2)------client2
Client2 send IGMP join for group G.
Client1 send IGMP join for group G.
verify show ip mroute in RP, will have 2 OIL.
Client2 send IGMP leave.
Verify show ip mroute in RP, will still have 2.

Root cause: When RP receives IGMP join from client2, it creates
a (s,g) channel oil and add the interface int-2 into oil list and
set the flag PIM_OIF_FLAG_PROTO_IGMP to int-2
Client1 send IGMP join, LHR will send a (*,G) join to RP. RP will
add the interface int-1 into the oil list of (s,g) channel_oil and
will set the flag PIM_OIF_FLAG_PROTO_IGMP and PIM_OIF_FLAG_PROTO_PIM
to the int-1 and set PIM_OIF_FLAG_PROTO_PIM to int-2 as well. It is
happening because of the pim_upstream_inherited_olist_decide() and
forward_on() get all the oil and update the flag wrongly.
So now when client 2 sends IGMP prune, RP will not remove the int-2
from oil list since both PIM_OIF_FLAG_PROTO_PIM & PIM_OIF_FLAG_PROTO_IGMP
are set, it just unset the flag PIM_OIF_FLAG_PROTO_IGMP.

Fix: Introduced new flags in if_channel, PIM_IF_FLAG_MASK_PROTO_PIM
& PIM_IF_FLAG_MASK_PROTO_IGMP. If a if_channel is created because of
pim join or pim (s,g,rpt) prune received, then set the flag
PIM_IF_FLAG_MASK_PROTO_PIM. If a if_channel is created becuase of IGMP
join received, then set the flag PIM_IF_FLAG_MASK_PROTO_IGMP.
When an interface needs to be added into the oil list check if
PIM_IF_FLAG_MASK_PROTO_PIM or PIM_IF_FLAG_MASK_PROTO_IGMP is set, then
update oil flag accordingly.

Signed-off-by: Sarita Patra <saritap@vmware.com>
2020-03-16 21:54:34 -07:00
Anuradha Karuppiah
ea6d91c86b pimd: re-eval flow activity on kat expiry
When the (S,G) KAT expires we need to poll for activity before dropping the
entry as traffic may have been forwarded by the dataplane since the last
periodic poll cycle.

This only works if traffic is being forwarded by the kernel i.e. if the
entries were HW accelerated via an ASIC we may still miss out on last
minute activity on the mroute in the HW.

Ticket: CM-26871

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2020-03-06 16:18:44 -05:00
Satheesh Kumar K
22c35834ea pimd: Use PIM EVPN MLAG Infra for syncing PIM MLAG Entries
Initially, MLAG Sync is happened at pim_ifchannel, this is mainly to
support even config mismatches(missing configuration of dual active).
But this causes more syncs for each entry.

and also it is not In-line with PIM EVPN. to avoid that moving to
pm_upstream based syncing.

Signed-off-by: Satheesh Kumar K <sathk@cumulusnetworks.com>
2020-03-06 16:03:36 -05:00
Anuradha Karuppiah
ec85b101e6 pimd: run DF election only on (*, G) termination mroutes
(S,G) entries that inherit ipmr-lo into the OIL also inherit
the DF role from the parent (*, G) entry.

This change is done primarily to simplify the sync process and
to prevent the MLAG peers from having to track (S, G) activity etc.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2020-03-06 16:03:28 -05:00
Donald Sharp
5e81f5dd1a *: Finish off the __PRETTY_FUNCTION__ to __func__
FINISH IT

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2020-03-06 09:23:22 -05:00
Donatas Abraitis
15569c58f8 *: Replace __PRETTY_FUNCTION__/__FUNCTION__ to __func__
Just keep the code cool.

Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
2020-03-05 20:23:23 +02:00
Donatas Abraitis
286bbbecb0 pimd: Convert pim_upstream_evaluate_join_desired type to bool
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
2020-03-04 17:13:01 +02:00
Anuradha Karuppiah
448139e704 pimd: stop overloading SRC_IGMP upstream for vxlan local membership
A local membership is created on the vxlan termination device ipmr-lo. This
is done to -
1. Pull multicast vxlan tunnel traffic to the VTEP for termination by
triggering JoinDesired on the BUM multicast group.
2. Include the OIF in the mroute to signal to the dataplane component
that flow needs to be vxlan terminated.

Earlier we were overloading the PIM_UPSTREAM_FLAG_MASK_SRC_IGMP for
this local membership creation but that is creating confusion both in
the state machine and in the show outputs. To avoid that we use the
more apparent PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM. With this change -
1. We get LHR functionality for VXLAN_TERM mroutes
2. OIF is populated with PIM_OIF_FLAG_PROTO_PIM only

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2020-02-14 09:18:30 -08:00
Anuradha Karuppiah
73db824993 pimd: skip syncing and running DF election on orig mroutes
This is not causing functional problems but has become a source
of confusion. DF status is only relevant to multicast tunnel decaps.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2020-02-14 09:18:30 -08:00
Anuradha Karuppiah
f03999caa6 pimd: increase RPF metric via the peerlink_rif by plus-10
The RPF cost is incremented by 10 if the RPF interface is the peerlink-rif.
This is used to force the MLAG switch with the lowest cost to the RPF
to become the MLAG DF. If a switch has to go via the peerlink-rif to get
to the RP or source it simplly cannot be the designated forwarder.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2020-02-14 09:18:30 -08:00
Anuradha Karuppiah
95586137e6 pimd: inherit MLAG DF role from the parent (*, G) entry
DF election is only run for (*,G) entries i.e. election is skipped
for (S,G) entries that are setup as a result of SPT switchover. (S,G)
entries inherit the DF role from the parent (*,G) entry. So the DF is
responsible for terminating all sources associated with a group.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2020-02-14 09:18:30 -08:00
Anuradha Karuppiah
05ca004b80 pim: DF election for tunnel termination mroutes in an anycast-VTEP setup
1. Upstream entries associated with tunnel termination mroutes are
synced to the MLAG peer via the local MLAG daemon.
2. These entries are installed in the peer switch (via an upstream
ref flag).
3. DF (Designated Forwarder) election is run per-upstream entry by both
the MLAG switches -
a. The switch with the lowest RPF cost is the DF winner
b. If both switches have the same RPF cost the MLAG role is
used as a tie breaker with the MLAG primary becoming the DF
winner.
4. The DF winner terminates the multicast traffic by adding the tunnel
termination device to the OIL. The non-DF suppresses the termination
device from the OIL.

Note: Before the PIM-MLAG interface was available hidden config was
used to test the EVPN-PIM functionality with MLAG. I have removed the
code to persist that config to avoid confusion. The hidden commands are
still available.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2020-02-14 09:18:30 -08:00
Donatas Abraitis
752022670a *: Remove break after return
Just a deadcode.

Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
2020-02-13 15:39:54 +02:00
Donald Sharp
dd3364cb1a pimd: Convert the upstream_list and hash to a rb tree
Convert the upstream_list and hash to a rb tree, Significant
time was being spent in the listnode_add_sort.  This reduces
this time greatly.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2020-01-03 08:39:55 -05:00
Mark Stapp
174d3891ab pimd: clear SA warning in pimd
Remove a dead store in pim_upstream.c to clear up an SA
warning.

Signed-off-by: Mark Stapp <mjs@voltanet.io>
2019-12-10 12:10:44 -05:00
Anuradha Karuppiah
35d6862d60 pimd: eval use_rpt on new upstream post IIF setup but before MFC programming
use_rpt macro depends on JoinDesired macro and is mostly independent of the
actual RPF interface i.e. doesn't change when the RPF interface changes.

There is however one exception to this handling and that is on the
first hop router (DR or non-DR). On the DR the FHR flag is set so the
RPF interface stays irrelevant to use_rpt eval. But on the non-DR the
IIF is the only way to know we are directly connected to the SG i.e.
to know that we must NOT switch the source to RPT.

This commit fixes up the order of use_rpt eval -
1. it is done before mroute programming
2. but after IIF setup, for SRC_NOCACHE and STATIC_IIF upstream entries

Note: drop an unnecessary check to verify that the RPF interface is
pim enabled. This is just to make the code consistent.

Ticket: CM-27446

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-11-22 09:48:15 -08:00
Anuradha Karuppiah
075a475e0c pimd: fixup whitespace errors reported by CI
No functional changes.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-11-20 13:32:08 -08:00
Anuradha Karuppiah
a1be09396c pimd: drop redundant checks for RPF interface
pim_upstream_kat_start_ok was checking if RPF interface was present,
twice!

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-11-20 10:20:09 -08:00
Anuradha Karuppiah
41a115e4f0 pimd: fixup JD macro to use "peer-msdp-sa" check instead of I_am_RP check
JD macro is defined by the RFC as -
bool JoinDesired(S,G) {
    return (immediate_olist(S,G) != NULL
        OR (KeepaliveTimer(S,G) is running
        AND inherited_olist(S,G) != NULL))
}

However for MSDP synced SA the KAT will not be running so an exception is
needed. Earlier I had done this by relaxing KAT_run requirements entirely
on the RP. However as that prevents the source from being aged out in some
cases I have made the check more narrow i.e. has to an MSDP peer added
entry.

Ticket: CM-24398

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-11-15 14:16:08 -08:00
Anuradha Karuppiah
c5cdf06960 pimd: jp-agg list update debug logs
Added event logs around add/del of upstream entries into the nbr's
jp-agg list. This is to help debug a problem with stale (deleted)
upstream entries being present in the list causing pimd to crash on
the periodic processing.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-11-15 14:16:08 -08:00
Anuradha Karuppiah
c692bd2ad4 pimd: send an immediate XG JP message when switching from SPT to RPT
Today we are only pruning the SPT when (S,G) upstream entry
switches from Joined toNotJoined. This leaves the source still
pruned along the RPT till the next periodic XG join-prune is sent
to the RPF(RP). Traffic from the source will be blackholed for this
duration. To prevent that we need send a new JP message
to RPF(RP) immediately.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-11-15 14:16:08 -08:00
Anuradha Karuppiah
b36576e44c pimd: RPF change to unreachable was leaving a stale entry in the jp-agg list
This was causing pimd to crash later; call-stack -
(gdb) bt
    context=<optimized out>) at lib/sigevent.c:254
    group=group@entry=0x7ffffa9797e0) at pimd/pim_rp.c:207
    grp=grp@entry=0x7ffffa9799fe, sgs=sgs@entry=0x560ac069edb0, size=52)
    at pimd/pim_msg.c:200
    groups=<optimized out>) at pimd/pim_join.c:562
    at pimd/pim_neighbor.c:288
    at lib/thread.c:1599
    at lib/libfrr.c:1024
    envp=<optimized out>) at pimd/pim_main.c:162
(gdb) fr 4
    group=group@entry=0x7ffffa9797e0) at pimd/pim_rp.c:207
207     pimd/pim_rp.c: No such file or directory.
(gdb) fr 6
    grp=grp@entry=0x7ffffa9799fe, sgs=sgs@entry=0x560ac069edb0, size=52)
    at pimd/pim_msg.c:200
200     pimd/pim_msg.c: No such file or directory.
(gdb) p source->up->sg_str
$1 = '\000' <repeats 31 times>, <incomplete sequence \361>
(gdb)

This problem can manifest in the following event sequence -
1. upstream RPF neighbor is resolved
2. upstream RPF neighbor becomes unresolved (but upstream entry
   stays on the jp-agg list)
3. upstream entry is removed
on the next old-neighbor jp-agg-list processing the stale entry is
accessed resulting in the crash.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-11-15 14:16:08 -08:00
Anuradha Karuppiah
7ef66af956 pimd: insert upstream entry into nbr's jp-agg list when a new nbr is added
A dummy pim upstream entry can be in a JOINED state before its RPF nbr is
added. Handle that case by triggering an immediate join.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-11-15 14:16:08 -08:00
Anuradha Karuppiah
8c55c1325a pimd: add caller string prefix to pim_rpf_update logs
No functional change; log enhancements only.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-11-15 14:16:08 -08:00
Anuradha Karuppiah
cfa8f7eb05 pimd: fixup kat restart to conform to the RFC
1. KAT should be re-started only if traffic rxed along the SPT i.e.
IIF == RPF_Interface(S).
Only exception to the rule is if you are LHR.
2. KAT should be started on all routers (not just FHR, RP, LHR).

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-11-15 12:00:29 -08:00
Anuradha Karuppiah
2ef4ed70c9 pimd: re-name SwitchToSptDesired to SwitchToSptDesiredonRp
Criteria for switching to SPT is different on RP and LHR. Re-name
the functions to make that apparent.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-11-15 12:00:29 -08:00
Anuradha Karuppiah
ec83653333 pimd: replace direct accesses to t_ka_timer with a kat_running macro
No functional change, simple cleanup to improve readability

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-11-15 12:00:29 -08:00
Anuradha Karuppiah
a53a9b3e6b pimd: fixup join desired handling to match the RFC defined macro
This commit includes the following changes -
1. kat needs to be included when evaluting join desired on a (S,G)
   entry.
2. there were cases where we were adding OIF based on joindesired
   being true for unrelated reasons (on other OIFs). cleaned up those
   cases.
3. make all calls to pim_upstream_switch conditional on the JoinDesired
   macro.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-11-15 12:00:29 -08:00
Anuradha Karuppiah
a749b90041 pimd: on some triggers use_rpt re-evaluated for all groups
RP config change is a big hammer and use_rpt/spt needs to be
re-evaluated on all existing (S,G) entries.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-11-15 12:00:29 -08:00
Anuradha Karuppiah
70c86421c9 pimd: update (S,G,rpt)'s IIF when the parent (*,G)'s IIF changes
If a source is being forwarded along the RPT it uses the parent (*,G)'s
IIF. When the parent's IIF changes all the children need to be updated

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-11-15 12:00:29 -08:00
Anuradha Karuppiah
7984af1840 pimd: set mfcc_parent at the time of MFCC programming
mfcc_parent for an (S, G) entry was being updated on any upstream RPF
change. With the change to use RPT for (S,G) in some cases we can no
longer do that. Instead the upstream entry's RPF neigbor is managed
separately form the channel_oil's mfcc_parent i.e. via NHT. And the
mfcc_parent is evaluated at the time of mroute programming.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-11-15 12:00:29 -08:00
Anuradha Karuppiah
69e3538cd8 pimd: decide between SPT based and RPT based forwarding
An (S,G) mroute can be created as a result of rpt prune. However that
entry needs to stay on the parent (*,G)'s tree (IIF) till a decision is
made to switch the source to the SPT.

The decision to stay on the RPT is made based on the SPTbit setting
according to - RFC7761, Section 4.2 “Data Packet Forwarding Rules”

However those rules are hard to achieve when hw acceleration i.e.
control and data planes are separate. So instead of relying on data
we make the decision of using SPT if we have decided to join the SPT -
Use_RPT(S,G) {
    if (Joined(S,G) == TRUE          // we have decided to join the SPT
            OR Directly_Connected(S) == TRUE // source is directly connected
            OR I_am_RP(G) == TRUE)   // RP
        //use_spt
        return FALSE;
    //use_rpt
    return TRUE;
}

To make that change some re-org was needed -
1. pim static mroutes and dynamic (upstream mroutes) top level APIs
have been separated. This is to limit the state machine to dynamic
mroutes.
2. c_oil->oil.mfcc_parent is re-evaluated based on if we decided
to use the SPT or stay on the RPT.
3. upstream mroute re-eval is done when any of the criteria involved
in Use_RPT changes.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-11-15 12:00:29 -08:00
Anuradha Karuppiah
a155fed53c pimd: re-eval c_oil mute flags on upstream attach/detach
Theoretically there should be no case where the channel-oil hangs
around after the upstream entry is removed. But currently there are
cases where it does. This is a precautionary fixup till we are
rid off all of those cases.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-11-15 10:05:06 -08:00
Anuradha Karuppiah
1b249e7097 pimd: update add_oif and del_oif debugs to print caller
These logs were printing file name which has little value (is always
pim_oil.c). Instead print the caller.

add_oif/del_oif are being called directly from one too many. Instead OIF
setup needs to be consolidated via the PIM state machine. These
debugs are expected to help in understanding what needs to be cleaned up.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-11-15 08:47:33 -08:00
Donald Sharp
23fc858a5e pimd: debug igmp trace turns on non igmp debugs
When you turn on `debug igmp trace` we are seeing a bunch
of debugs associated with pim processing.  This is because we were
using PIM_DEBUG_TRACE which is both `debug igmp trace` and `debug pim trace`
when tracing igmp code it would be nice to only see igmp work.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-11-12 09:38:04 -05:00
Donald Sharp
02434c43a5 pimd: Always create upstream reference when adding channel oil
Modify the code to create an upstream reference whenever the code
creates an channel_oil via the pim_mroute.c code.  This code also
starts a keep alive timer to clean up the reference if we do
nothing with it after the normal time.

I've left alone the source->channel_oil creation because these
are kept and tracked independently already.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-07-18 07:56:37 -04:00
Donald Sharp
46dd6edb06 pimd: pim_upstream *always* creates a channel_oil
Modify code base so that pim_upstream *always* creates a channel_oil
and as such we do not need to create it later or play other games.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-07-18 07:56:37 -04:00
Quentin Young
2951a7a4c2 *: s/TRUE/true/, s/FALSE/false/
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
2019-07-01 17:26:05 +00:00
Donald Sharp
9e132a491a pimd: Ensure channel_oil_add is created through all paths
If we create a channel_oil ensure that all paths that
we can go down will create one.  Future commits
can remove the (up->channel_oil) tests.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-06-19 19:13:10 -04:00
Donald Sharp
8a3e7e9ed9 pimd: Add debugs for channel_oil creation and deletion
Add some debugs so we can see channel oil creation and deletion
events.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-06-14 19:22:43 -04:00
Donald Sharp
ae14da4860 pimd: Remove unnecessary boolean to pim_rpf_update
We already log whether or not we add nht tracking, having
an additional boolean to say to log another line is
a bit over the top.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-06-07 13:27:29 -04:00
Quentin Young
c35b7e6bea pimd: strcpy -> strlcpy
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
2019-05-29 18:03:26 +00:00
Jafar Al-Gharaibeh
bda0241599
Merge pull request #4239 from sarav511/rp
pimd: PIM Bootstrap Message Processing
2019-05-28 10:26:28 -05:00
saravanank
4533b847ec pimd: PIM nexthop tracking changes for tracking nexthop path of BSR.
Signed-off-by: Saravanan K <saravanank@vmware.com>
2019-05-14 20:23:15 -07:00
Quentin Young
d8b87afe7c lib: hashing functions should take const arguments
It doesn't make much sense for a hash function to modify its argument,
so const the hash input.

BGP does it in a couple places, those cast away the const. Not great but
not any worse than it was.

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
2019-05-14 21:23:08 +00:00