Commit Graph

240 Commits

Author SHA1 Message Date
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
rgirada
e3e532dd16 Pimd : S,G Mroute entries are not expiring even after KAT expiry,
become stale entries.

Topology:
--------
Source
|
FHR
|
RP ------ LHR --- Recv1
|
Recv2

Root case :
-----------
When RP acts as a LHR i.e RP has a local receiver and registed for
the same group where LHR connected receiver also registered for the
same multicast group.When RP receives a (s,g) join form LHR , it
increments upstream ref count to two to track the Local membership
as well.But at the time of KAT expiry in RP , upstream reference
is not being removed Which is added to track local membership which
is causing to make these entries as stale in RP and FHR.

Fix : Made the change such that it removes the upstream reference
if it is added to track the local memberships.

Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2019-05-09 02:53:11 -07:00
Donald Sharp
b077f57162 pimd: When creating new upstream state, figure out what we should join
Always when creating a new S,G state look at all possible ifchannels
to decide what the mroute should be.

The bug that this is fixing is this:

Suppose two incoming `*,G` joins on swp1, and swp2.
Now suppose that one of those ifchannel `*,G` sends a `*,G S,G RPT Prune`.
We were creating the S,G upstream state as we should but we were
only looking at the S,G ifchannel to decide the S,G mroute we would
be creating.  As such what we need to do is to look over the associated
*,G ifchannels and allow us to associate correct oil needed.

Ticket: CM-24732
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-04-22 17:45:04 -04:00
Anuradha Karuppiah
b9f3a51c07 pimd: register local VTEP-IP for each BUM MDT via NULL registers
For multicast vxlan tunnels we register the local VTEP-IP independent
of the prescence of BUM traffic i.e. we prime the pump. This
is acheived via NULL registers.

VxLAN orig entries with upstream in a PIM_REG_JOIN state are linked to
a work list for periodic NULL register transmission. Once the SPT setup
is complete the upstream-entry moves to a PIM_REG_PRUNE state and is
remved from the VxLAN work list.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-04-20 08:33:22 -07:00
Anuradha Karuppiah
aea1f84551 pimd: extern pim_null_register_send
pim_vxlan will use this for registering the local-VTEP-IP wth the RP
independent of the presence of BUM traffic.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-04-20 08:33:22 -07:00
Anuradha Karuppiah
8eeaef9b06 pimd: per-SG control to allow any router to register itself as source
In a VxLAN-AA setup both the anycast VTEPS can send VxLAN encapsulated
traffic. This is despite the fact that the it is not-DR on the IIF
associated with the originating mroute.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-04-20 08:33:21 -07:00
Anuradha Karuppiah
6a5de0ad48 pimd: provide a mechanism to pin the IIF for an SG entry
In the case of vxlan origination entries IIF is set to -
1. lo for single VTEPs
2. MLAG-ISL for VTEPs multihomed via MLAG.

This commit creates the necessary infrastructure by -
1. allowing the IIF to be set statically (without RPF lookup)
2. and by preventing next-hop-tracking registration

PS: Note that I have skipped additional checks in pim_upstream_del
intentionally i.e. an attempt will be made to remove nexthop-tracking
for the upstream entry (with STATIC_IIF) which will fail because of the
up-entry not being in the nh's hash table. Ideally we should maintain
a nh pointer in the up-entry to prevent this unnecessary processing.
In the abscence of that I wanted to avoid spraying STATIC_IIF checks
all over.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-04-20 08:33:21 -07:00
Anuradha Karuppiah
ff459c36af pimd: provide an api to force stop kat on an upstream entry
In the case of pim vxlan we create and keep upstream entries alive
in the abscence of traffic. So we need a mechanism to purge entries
abruptly on vxlan SG delete without having to wait for the entry
to age out.

These are again just the infrastructure changes needed for it.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-04-20 08:33:21 -07:00
Anuradha Karuppiah
820b4a40a1 pimd: provide an upstream control to prevent KAT expiry
For vxlan BUM MDTs we prime the pump and register the local-VTEP-ip
as source even before the first BUM packet is rxed. This commit provides
the infrastructure changes needed for that.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-04-20 08:33:21 -07:00
Russ White
0697abef9d
Merge pull request #4096 from donaldsharp/pim_nht_cleanup
Pim nht cleanup
2019-04-16 10:27:35 -04:00
Donald Sharp
6f0f014f08 pimd: Add JoinDesired(S,G) to deciding to set spt bit
The decision for Update_SPTbit(S,G, iif) includes a test
for JoinDesired(S,G) in section 4.2.2.  When we were deciding
to update the spt bit we were not taking this into account.

This commit fixes this issue.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-04-09 13:20:32 -04:00
Donald Sharp
2de05c606e pimd: Initiate *,G S,G RPT Prune in some cases
On the LHR after we decide that traffic is flowing and
we set the SPT bit for the S,G *and* the incoming IIF
of the S,G is different than the incoming IIF of the *,G
we should immediately send the *,G S,G RPT Prune as
a triggered response instead of waiting for the next
cycle.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-04-05 11:12:59 -04:00
Donald Sharp
4171408128 pimd: Cleanup extra paranthesis around S,G printout
When we are displaying S,G string data we already auto
display the string as (S,G) no need to have ((S,G)).
Cleanup some that were found during log look through.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-03-28 15:51:49 -04:00
Sarita Patra
47e3ce59c4 pimd: Addressing the review comments
Signed-off-by: Sarita Patra <saritap@vmware.com>
2019-03-18 20:22:04 -07:00
Sarita Patra
246445a372 pimd: Handling delete nexthop track for PIM upstream address
When RP gets deleted, find all the (*, G) upstream whose group belongs to
the deleted RP, release the upstream from pnc->upstream_hash in the function
pim_delete_tracked_nexthop().

Signed-off-by: Sarita Patra <saritap@vmware.com>
2019-02-24 23:27:16 -08:00
Sarita Patra
1250cb5df2 pimd: clear upstream rpf information when RP becomes not reachable
When route to RP gets modified, FRR receives a notification from
zebra, and call the function pim_resolve_upstream_nh() to compute the
nexthop and update upstream->rpf structure.
Issue: In case when RP becomes not reachable, FRR only uninstall
the mroute from the kernal, but not update the upstream->rpf structure.

Fix: When FRR receives a notification from zebra saying RP becomes
not reachable, then update the following fields.
1. update channel_oil incoming interface as MAXVIFS
2. Un-install the mroute from the kernel.
3. Switch upstream state from JOINED to NOTJOINED.
4. Clear the nexthop information of the upstream.

Signed-off-by: Sarita Patra <saritap@vmware.com>
2019-02-24 23:27:08 -08:00
Sarita Patra
732c209c98 pimd: create dummy (*,G) upstream when RP not configured/reachable
In this commit, we are creating a dummy upstream & dummy channel_oil
for (*, G) when RP is not configured or not reachable.
Dummy upstream: <upstream_addr = INADDR_ANY, rpf = Unknown>
Dummy channel oil: <iif = MAXVIFS>

Signed-off-by: Sarita Patra <saritap@vmware.com>
2019-02-24 21:30:06 -08:00
Sarita Patra
957d93eaf2 pimd: Handling Null incoming interface of dummy upstream
When FRR receives IGMP/PIM (*, G) join and RP is not configured or not
reachable, then we are creating a dummy upstream with incoming interface
as NULL and upstream address as INADDR_ANY.

Added upstream address and incoming interface validation where it is necessary,
before doing any operation on the upstream.

Signed-off-by: Sarita Patra <saritap@vmware.com>
2019-02-24 21:26:58 -08:00
Donald Sharp
d17612dd6a pimd: Move the infinite_assert_metric global to pim_router
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-01-04 12:23:39 -05:00