(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>
There exists the possibility that a RP exists as a anycast
pair for a lan segment. As such one side may receive
the register and properly handle the registration mechanics.
The one that does not receive the register packets will still
get S,G state and WRVIFWHOLE upcalls across the lan. In
this case notice that we have not received the Registration
packets and prevent nexthop lookups.
Ticket: CM-27466
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
There was some code missed during the upstreaming process
due to code squash. Identify and put into a commit
to keep code consistent and correct.
Signed-off-by: Satheesh Kumar K <sathk@cumulusnetworks.com>
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When the WRVIFWHOLE callback is made with a iifp of the pimreg
device we *know* that the packet is a PIM Register packet
( see net/ipv4/ipmr.c for kernel behavior ). As such
we know that we will shortly read the pim register packet
and handle it through those mechanics. There is nothing
to do here so we can move along.
Ticket: CM-27729
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Issue 1:
1. Enable pim on an interface.
2. Configure query-interval or query max response time,
which results in pimd crash.
Root cause:
1. When pim is enabled on an interface, it creates a igmp socket
with querier_timer and other_querier time as NULL.
2. When query-interval/max_response_time is configured, it call the
function igmp_sock_query_reschedule() to reshedule the query. This
function check either of querier_timer or other_querier timer should
be running. Since in this case both are NULL, it results in crash.
Issue 2:
1. Enable pim on an interface.
2. Execute no ip igmp query-interval or query max response time,
which results in pimd crash.
Root cause:
1. When pim is enabled on an interface, it creates a pim interface
with querier_timer and other_querier time as NULL.
2. When no ip igmp query-interval/max_response_time is executed, it will
check either of querier_timer or other_querier timer should be running.
Since in this case both are NULL, it results in crash.
Fix:
When pim is enabled on an interface, it creates a igmp socket with
mtrace_only as true. So add a check if mtrace_only is true, then don't
reshedule the query.
Signed-off-by: Sarita Patra <saritap@vmware.com>
Issue:
Client---LHR---RP
1. Add kernel route for RP on LHR. Client send join
2. (*,G) will be get created in LHR and RP.
3. Kill the FRR on all the nodes
4. Start FRR only on LHR node
5. In LHR, (*, G) will be created with iif as unknown.
Root cause:
In the step 4, When LHR will receive igmp join, it will call
the function pim_ecmp_fib_lookup_if_vif_index which will look
for nexthop to RP with neighbor needed as false. So RPF lookup will
be true as the route is present in the kernel. It will create a
(*, G) channel_oil with incoming interface as the RPF interface
towards RP and install the (*,G) mroute in kernel.
Along with this (*,G) upstream gets craeted, which call the function
pim_rpf_update, which will look for the nexthop to RP with neighbor
needed as true. As the frr is not running in RP, no neighbor is present
on the nexthop interface. Due to which this will fail and will update
the channel_oil incoming interface as MAXVIFS(32).
Fix:
pim_ecmp_fib_lookup_if_vif_index() call the function pim_ecmp_nexthop_lookup
with neighbor_needed as true.
Signed-off-by: Sarita Patra <saritap@vmware.com>
Issue: REGISTER-STOP Rx is always displaying 0.
Root-cause: pim_ifstat_reg_stop_recv is not getting
incremented when register stop message is received.
Fix: Increment pim_ifstat_reg_stop_recv on receiving
of pim register stop packet.
Signed-off-by: Sarita Patra <saritap@vmware.com>
It's been a year search and destroy.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
- Add extern modifier to some declarations in header file and move
qpim_all_pim_routers_addr definition to pimd/pimd.c
`GCC now defaults to -fno-common. As a result, global variable accesses
are more efficient on various targets. In C, global variables with
multiple tentative definitions now result in linker errors.`
Taken from https://gcc.gnu.org/gcc-10/changes.html
Signed-off-by: Tomas Korbar <tkorbar@redhat.com>
1. show ip pim mlag summary
provides MLAG session information and stats
2. show ip pim mlag upstream
displays the upstream entries synced across the MLAG switches
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
ipmr-lo is an internally added device used for multicast vxlan tunnel
termination. This device is not expected to be managed by the admin
however in the case it is accidentally shut we need to be able handle
it by recovering when it is "no shut" again.
Ticket: CM-24985
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
PIM MLAG DF election API was not being triggered on cost change if the
upstream neighbor remained the same.
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
In an anycast VTEP setup the peerlink_rif is added as a static OIF
to the originating mroute (bypassing the pim state machine). This is
needed to ensure both MLAG switches rx a copy of encapsulated BUM flow.
We were not handling link state changes on this static OIF resulting
in the wrong vifi being used in the OIL (because of vifi re-allocation).
This commit re-acts to oper state changes by deleting the OIF on link
down and re-adding it on link up.
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
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>
When local member is added the (*, G) entry may already be in a JOINED
state. In that case the OIL is not updated i.e. pim_channel_add_oif is
not happening for ipmr-lo. Because of this the traffic associated with
the multicast vxlan tunnel is pulled down to the VTEP but not terminated
by the kernel.
This change force updates the OIL anytime ipmr-lo is added or removed
as a local member.
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
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>
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>
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>
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>
Channel with the MLAG daemon is setup on the first VxLAN BUM MDT or
pim-mlag AA SVI.
This channel is used for -
1. rxing MLAG status status updates (peer state, role etc.)
2. for syncing active-active upstream entries with the peer MLAG
switch.
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
The vrrpd one conflicts with the standalone vrrpd package; also we're
installing daemons to /usr/lib/frr on some systems so they're not on
PATH.
Signed-off-by: David Lamparter <equinox@diac24.net>
Update zclient_lookup_nexthop_once() to create the zapi
header using the vrf_id on the pim->vrf struct.
This is the one we do a check on a couple lines before, so
we should be using it when we actually create the header as
well.
Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
Allow pimd to stop the lookup if zebra tells pimd that the
lookup failed due to a zapi error. Otherwise, it will keep
waiting for a nexthop message that will never come.
Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
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>
The channel_oil_list and hash are taking significant
cpu at scale when adding to the sorted list. Replace
with a RB_TREE.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Kernel might not hand us a bad packet, but better safe than sorry here.
Validate the IP header length field. Also adds an additional check that
the packet length is sufficient for an IGMP packet, and a check that we
actually have enough for an ip header at all.
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
We check that the IGMP message is sufficently sized for an mtrace query,
but not a response, leading to uninitialized stack read.
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Allow 'ip igmp join' to join group for any source if no source is
specified.
Disallow joining source "0.0.0.0" as it is used to define an
any-source multicast group.
Signed-off-by: Liam McBirnie <liam.mcbirnie@boeing.com>
Commit: ddbf3e6060
This commit modified the interface up handling code in
ZAPI such that the zclient handled the decoding for you.
Prior to this commit ospf assumed that it could use the
old ifp pointer to know state before reading the stream.
This lead to a situation where ospf would `smartly` track
and do the right thing in this situation. This commit
changed this assumption and in certain scenarios, say
a interface was changed after it was already up would
lead to situations where ospf would not properly handle
the new interface up.
Modify ospf to track data that is important to it in
it's interface->info pointer.
This code pattern was followed in both eigrp and pim.
In eigrp's case it was just behaving weirdly in any event
so fixing this pattern is not a big deal. In pim's
case it was not properly using this so it's a no-op
to fix.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
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>
A variety of buffer overflow reads and crashes
that could occur if you fed bad info into pim.
1) When type is setup incorrectly we were printing the first 8 bytes
of the pim_parse_addr_source, but the min encoding length is
4 bytes. As such we will read beyond end of buffer.
2) The RP(pim, grp) macro can return a NULL value
Do not automatically assume that we can deref
the data.
3) BSM parsing was not properly sanitizing data input from wire
and we could enter into situations where we would read beyond
the end of the buffer. Prevent this from happening, we are
probably left in a bad way.
4) The received bit length cannot be greater than 32 bits,
refuse to allow it to happen.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Inherited OIL is used as a part of the JoinDesired macro. And in FRR we
use the channel OIL as the inherited OIL (to reduce processing overhead
everytime JD needs to be re-evaluated). On a FHR pimreg is a part of the
channel-OIL but must not be used for JD computation.
This commit blacklists pimreg from the inherited_oil i.e. present but
ignored.
Note: This fixup is being done to address topotest failures.
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
If a register packet is received that is less than the PIM_MSG_REGISTER_LEN
in size we can have a possible situation where the data being
checksummed is just random data from the buffer we read into.
2019/11/18 21:45:46 warnings: PIM: int pim_if_add_vif(struct interface *, _Bool, _Bool): could not get address for interface fuzziface ifindex=0
==27636== Invalid read of size 4
==27636== at 0x4E6EB0D: in_cksum (checksum.c:28)
==27636== by 0x4463CC: pim_pim_packet (pim_pim.c:194)
==27636== by 0x40E2B4: main (pim_main.c:117)
==27636== Address 0x771f818 is 0 bytes after a block of size 24 alloc'd
==27636== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27636== by 0x40E261: main (pim_main.c:112)
==27636==
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When you configure interface configuration without explicitly
configuring pim on that interface, we were not creating the pimreg
interface and as such we would crash in an attempted register
since the pimreg device is non-existent.
The crash is this:
==8823== Invalid read of size 8
==8823== at 0x468614: pim_channel_add_oif (pim_oil.c:392)
==8823== by 0x46D0F1: pim_register_join (pim_register.c:61)
==8823== by 0x449AB3: pim_mroute_msg_nocache (pim_mroute.c:242)
==8823== by 0x449AB3: pim_mroute_msg (pim_mroute.c:661)
==8823== by 0x449AB3: mroute_read (pim_mroute.c:707)
==8823== by 0x4FC0676: thread_call (thread.c:1549)
==8823== by 0x4EF3A2F: frr_run (libfrr.c:1064)
==8823== by 0x40DCB5: main (pim_main.c:162)
==8823== Address 0xc8 is not stack'd, malloc'd or (recently) free'd
pim_register_join calls pim_channel_add_oif with:
pim_channel_add_oif(up->channel_oil, pim->regiface,
PIM_OIF_FLAG_PROTO_PIM);
We just need to make srue pim->regiface exists once we start configuring
pim.
Fixes: #5358
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When configuring a RP, dissallow the choice of 0.0.0.0 or
255.255.255.255 as the address as that they make no sense
what so ever.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
We were adding a newline for the source in some cases
but not others and tighten up the display of data
eva# show ip pim rp-info
RP address group/prefix-list OIF I am RP Source
10.254.0.1 224.0.0.0/4 lo yes Static
4.4.4.4 225.1.2.3/32 abcdefghijklmno yes Static
10.0.20.45 226.200.100.100/32 r1-eth0 no Static
eva#
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
SPT switchover handling is done by adding pimreg in the OIL of the (*, G)
entry on the LHR. This causes multicast data with that destination to be
sent to pimd as IGMPMSG_WHOLEPKT. These packets trigger creation of (S,G)
and also register forwarding. However register forwarding must only be done
if the router is also a FHR. That FHR check was missing causing strange
source registrations from multicast routers that were not directly
connected to the source.
Relevant logs from LHR -
PIM: pim_mroute_msg: pim kernel upcall WHOLEPKT type=3 ip_p=0 from fd=9 for (S,G)=(6.0.0.30,239.1.1.111) on pimreg vifi=0 size=98
PIM: Sending (6.0.0.30,239.1.1.111) Register Packet to 81.0.0.5
PIM: pim_register_send: Sending (6.0.0.30,239.1.1.111) Register Packet to 81.0.0.5 on swp2
And 6.0.0.30 is clearly not directly connected on that router -
root@tor-11:~# ip route |grep 6.0.0.30 -A2
6.0.0.30 proto ospf metric 20
nexthop via 6.0.0.22 dev swp1 weight 1 onlink
nexthop via 6.0.0.23 dev swp2 weight 1 onlink
root@tor-11:~#
Ticket: CM-24549
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
It was causing a Join on (S,G) who's prune state was being cleared. This
was an inactive (KAT not running; no immediate OIL) entry that was being
flushed out but because of this incorrect Join (that was being done with
out join-state checks) the source was getting populated repeatedy i.e.
never aged.
Output of "ip monitor mroute"
=============================
(27.0.0.11,239.1.1.102) Iif: lo State: resolved Table: default
Deleted (27.0.0.11,239.1.1.102) Iif: lo State: resolved Table: default
(27.0.0.11,239.1.1.102) Iif: pimreg State: resolved Table: default
(27.0.0.11,239.1.1.102) Iif: uplink-1 State: resolved Table: default
(27.0.0.11,239.1.1.102) Iif: uplink-1 State: resolved Table: default
(27.0.0.11,239.1.1.102) Iif: uplink-1 State: resolved Table: default
(27.0.0.11,239.1.1.102) Iif: lo Oifs: uplink-1 State: resolved Table: default
(27.0.0.11,239.1.1.104) Iif: lo Oifs: pimreg uplink-1 State: resolved Table: default
(27.0.0.11,239.1.1.102) Iif: lo Oifs: pimreg uplink-1 State: resolved Table: default
Deleted (27.0.0.11,239.1.1.102) Iif: lo State: resolved Table: default
(27.0.0.11,239.1.1.102) Iif: pimreg State: resolved Table: default
(27.0.0.11,239.1.1.102) Iif: uplink-1 State: resolved Table: default
(27.0.0.11,239.1.1.102) Iif: uplink-1 State: resolved Table: default
(27.0.0.11,239.1.1.102) Iif: uplink-1 State: resolved Table: default
(27.0.0.11,239.1.1.102) Iif: lo Oifs: uplink-1 State: resolved Table: default
These mroute events (on a no longer existing multicast souce) continue in
a never ending loop.
Triggered joins/prunes MUST only done via state machine transitions i.e.
via pim_upstream_update_join_desired.
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
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>
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>
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>
It is now used to evaluate and display join-desired state for
each upstream entry -
root@spine-1:~# net show pim upstream-join-desired
Source Group EvalJD
* 239.1.1.111 yes
6.0.0.28 239.1.1.111 yes
6.0.0.29 239.1.1.111 no
6.0.0.30 239.1.1.111 yes
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
This re-naming was needed because the JD state on an upstream is
not just based on channel info i.e. we can have JD=true even if there
is no downstream channel. The "show ip upstream-join-desired" command
will be changed to display that info i.e. upstream's JD state instead
of downstream channel params. The downstream channel params are now
available via "show ip pim channel"
PS: This change maybe reverted if upstream NAKs it. But there is a
pressing need for it to debug some not-so-reproduible problems.
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
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>
Dumps while in problem state -
============================
[from "show ip pim state"]
Active Source Group RPT IIF OIL
1 6.0.0.31 239.1.1.111 n swp1 swp4( J * )
[from "show ip pim join"]
Interface Address Source Group State Uptime Expire Prune
swp3 6.0.0.22 6.0.0.31 239.1.1.111 JOIN --:--:-- 03:11 --:--
You can see from the dumps that the pim downstream router has joined on
swp3 but that OIF has not been added to the OIL with flag
PIM_OIF_FLAG_PROTO_PIM. This is because the join was rxed while the
ifchannel was in a prune-pending state.
Relevant logs -
===============
[
PIM: recv_prune: prune (S,G)=(6.0.0.31,239.1.1.111) rpt=1 wc=0 upstream=6.0.0.22 holdtime=210 from 6.0.0.28 on swp3
PIM: pim_upstream_ref(pim_ifchannel_add): upstream (6.0.0.31,239.1.1.111) ref count 3 increment
PIM: pim_upstream_add(pim_ifchannel_add): (6.0.0.31,239.1.1.111), iif 6.0.0.26/0 (swp1) found: 1: ref_count: 3
PIM: pim_ifchannel_add: ifchannel (6.0.0.31,239.1.1.111) is created
PIM: pim_joinprune_recv: SGRpt flag is set, del inherit oif from up (6.0.0.31,239.1.1.111)
PIM: pim_mroute_add(pim_channel_del_oif), vrf default Added Route: (6.0.0.31,239.1.1.111) IIF: swp1, OIFS: swp4
PIM: pim_channel_del_oif(pim_joinprune_recv): (S,G)=(6.0.0.31,239.1.1.111): proto_mask=4 IIF:1 OIF=swp3 vif_index=3
PIM: recv_join: join (S,G)=(6.0.0.31,239.1.1.111) rpt=0 wc=0 upstream=6.0.0.22 holdtime=210 from 6.0.0.28 on swp3
PIM: PIM_IFCHANNEL(swp3): (6.0.0.31,239.1.1.111) is switching from SGRpt(PP) to JOIN
PIM: Sending Request for New Channel Oil Information(6.0.0.31,239.1.1.111) VIIF 1(default)
]
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
This is needed for two reasons -
1. The inherited OIL needs to be setup independent of the RPF interface
to allow correct computation of the JoinDesired macro.
2. The RPF interface is computed at the time of MFC programming so
it is not possible to permanently evict the OIF at that time oif_add
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
When a inherited OIL becomes empty join-desired can go to false. So
we need to re-run join-desired evaluation on any inherited OIL changes.
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
The macro was always returning non-empty because of comparing an
array of u8_t with an array of u32_t.
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
If an dummy upstream entry (no RPF nbr) which is already in a JOINED
state is resolved we were not triggering an immediate join via the
per-interface upstream switch list.
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
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>
Deviations -
1. Avoid using SPTbit setting. Replace that with Use_Spt macro.
2. If S is supposed to be forwarded along the RPT but has an empty OIL
prune it.
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
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>
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>
Joined state is computed based on the downstream state and cannot be
changed if the RPF link flaps.
Reference: rfc 7761, section 4.5.5
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
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>
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>
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>
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>
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>
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>
1. This avoids the needs to re-run "muting" decisions.
2. Avoids the need to restore's pim OIL after fixup and send to kernel
(this is getting harder to manage).
In the future we need to also move the PIM maintained channel OIL from
an array of MAXVIFs to a simple DLL. This will be a significant
optimization in memory usage and preformance (OIL reads, copies etc).
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
If an mroute loses DF election (with the MLAG peer) it has to stop
forwarding traffic on active-active devices such as ipmr-lo used
for vxlan traffic termination. To acheive that this commit
introduces a concept of OIF muting. That way we can let the PIM and
IGMP state machines play out and silence OIFs after the fact.
Relevant outputs:
=================
1. muted OIFs are displayed with the M flag in "pim state" -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
root@TORC12:~# net show pim state |grep "27.0.0.13"|grep 100
1 27.0.0.13 239.1.1.100 uplink-1 ipmr-lo( *M)
root@TORC12:~#
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2. And supressed altogether in the mroute output -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
root@TORC12:~# net show mroute |grep "27.0.0.13"|grep 100
27.0.0.13 239.1.1.100 none uplink-1 none 0 --:--:--
root@TORC12:~#
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
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>
1. add the Mlag ProtoBuf Lib to Zebra Compilation
2. Encode the messages with protobuf before writing to MLAG
3. Decode the MLAG Messages using protobuf and write to clients
based on their subscrption.
Signed-off-by: Satheesh Kumar K <sathk@cumulusnetworks.com>
This includes:
1. Defining message formats
2. Stream Decoding after receiving the message at PIM
3. Handling MLAG UP & Down Notifications
Signed-off-by: Satheesh Kumar K <sathk@cumulusnetworks.com>
when ever a FRR Client wants to send any data to another node
using MLAG Channel, uses below mechanisam.
1. sends a MLAG Registration to zebra with interested messages that
it is intended to receive from peer.
2. In response to this request, Zebra opens communication channel with
MLAG. and also in Rx. diretion zebra forwards only those messages which
client shown interest during registration
3. when client is no-longer interested in communicating with MLAG, client
posts De-register to Zebra
4. if this is the last client which is interested for MLAG Communication,
zebra closes the channel.
why PIM Needs MLAG Communication
================================
1. In general on LAN Networks elecetd DR will send the Join towards
Multicast RP in case of a LHR and Register in case of FHR.
2. But in case DR Goes down, traffic will be re-converged only after
the New DR is elected, but this can take time based on Hold Timer to
detect the DR down.
3. this can be optimised by using MLAG Mecganisam.
4. and also Traffic can be forwarded more efficiently by knowing the cost
towards RP using MLAG
Signed-off-by: Satheesh Kumar K <sathk@cumulusnetworks.com>
When receiving igmp packets we are spitting out a lot of
debugs. Attempt to clean this up to allow us to understand
what is going on a bit better by just being able to look
at the log file.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
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>
We are seeing situations where PIM is sending a IGMP v3 query
and immediately receiving back up the pim kernel interface the
query from itself:
from `show int brief`:
swp7 up default 192.168.202.1/24
We are also receiving these debugs:
2019-11-11T20:52:40.452307+00:00 leaf02 pimd[1592]: Send IGMPv3 query to 224.4.0.8 on swp7 for group 224.4.0.8, sources=0 msg_size=12 s_flag=0 QRV=2 QQI=125 QQIC=7d
2019-11-11T20:52:40.452430+00:00 leaf02 pimd[1592]: pim_mroute_msg(default): igmp kernel upcall on swp7(0x55eaa7dc7dc0) for 192.168.202.1 -> 224.4.11.123
2019-11-11T20:52:40.452574+00:00 leaf02 pimd[1592]: Recv IP packet from 192.168.202.1 to 224.4.11.123 on swp7: size=40 ip_header_size=24 ip_proto=2
2019-11-11T20:52:40.452699+00:00 leaf02 pimd[1592]: Recv IGMP packet from 192.168.202.1 to 224.4.11.123 on swp7: ttl=1 msg_type=17 msg_size=16
2019-11-11T20:52:40.452824+00:00 leaf02 pimd[1592]: Recv IGMP query v3 from 192.168.202.1 on swp7 for group 224.4.11.123
This query is causing us to do some weird gyrations around the IGMP state machine for handling
queries. Let's just prevent it from happening.
Ticket: CM-27247
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When adding an OIF to the OIL, if we are not the DR
there is no need to install it then remove it.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
We have a zlog_warn that is unguarded ( and really is a debug message )
as that there is nothing the end user can do and nothing to note
here other than a debug message to track refcounts. Change
to an appropriate debug and zlog_debug it instead.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When you enter:
ip pim ssm prefix-list my-custom-ssm-range
ip pim ssm prefix-list my-custom-ssm-range
The second instance would cause a failure to happen which
should not happen w/ duplicate config.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Scenarios where this code change is required:
1. BFD is un-configured from BGP at remote end.
Neighbour BFD sends ADMIN_DOWN state, but BFD on local side will send
DOWN to BGP, resulting in BGP session DOWN.
Removing BFD session administratively shouldn't bring DOWN BGP session
at local or remote.
2. BFD is un-configured from BGP or shutdown locally.
BFD will send state DOWN to BGP resulting in BGP session DOWN.
(This is akin to saying do not use BFD for BGP)
Removing BFD session administratively shouldn't bring DOWN BGP session at
local or remote.
Signed-off-by: Sayed Mohd Saquib sayed.saquib@broadcom.com
The result variable was already tested against PIM_GROUP_BAD_ADDR_MASK_COMBO
earlier in the function. No need to do the same thing twice.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
All paths leading to this point in the code have already deref'ed
the pim->global_scope.bsrp_table. No point in testing for
validness now. This was caught by Coverity.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The pim_msg_send() return code was not being checked. Make
consistent with it's usage everywhere else.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Cleanup the interface creation apis to make it more
clear what they are doing.
Make it explicit that the creation via name/ifindex will
only add it to the appropriate list.
Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
There are several places in the pim where we are mixing up
zlog_warn w/ zlog_debug and vice versa. If we are protecting
a zlog_warn w/ a debug is it really a warn? If we have an actual
error situation we should also warn about it.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When we create the up data structure we create the channel_oil
as well. As such it is impossible to get into this code
so it can be removed.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This will facilitate the Hardware to prefer control packets over
Normal Data packets while queuing, so that during congestion, the
chance of dropping control packet will be minimised.
Signed-off-by: Satheesh Kumar K <sathk@cumulusnetworks.com>
For all the places we have a zclient->interface_up convert
them to use the interface ifp_up callback instead.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Switch the zclient->interface_add functionality to have everyone
use the interface create callback in lib/if.c
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Start the conversion to allow zapi interface callbacks to be
controlled like vrf creation/destruction/change callbacks.
This will allow us to consolidate control into the interface.c
instead of having each daemon read the stream and react accordingly.
This will hopefully reduce a bunch of cut-n-paste stuff
Create 4 new callback functions that will be controlled by
lib/if.c
create -> A upper level protocol receives an interface creation event
The ifp is brand spanking newly created in the system.
up -> A upper level protocol receives a interface up event
This means the interface is up and ready to go.
down -> A upper level protocol receives a interface down
destroy -> A upper level protocol receives a destroy event
This means to delete the pointers associated with it.
At this point this is just boilerplate setup for future commits.
There is no new functionality.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The Pim RFC does not appear to state any length requirements
of pim, other than the checksum must be correct.
Certain vendors are sending extra data at the end of a pim assert
message. This while not explicitly against the rules was a bit
of surprise to pim when we threw the assert message on the floor
for being too long.
Modify the test to see if length left will allow us to read
the 8 bytes of data that we need. If it is sufficient for
that allow the packet to be used.
Fixes: #4957
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Original Idea is to display normal & detailed debugs when detailed
debug alone is configured. because of this "sh debugs" are showing
wrong Information, because same macro is used to disply the configured
debugs.
that means even if Normal debug is configured, detailed macro returns
TRUE. To avoid this ambiguity check whetehr detailed debug is configured
or not during dumping configured debugs. In all other places using
old macro.
Signed-off-by: Satheesh Kumar K <sathk@cumulusnetworks.com>
Debian packaging when run finds a bunch of spelling errors:
I: frr: spelling-error-in-binary usr/bin/vtysh occurences occurrences
I: frr: spelling-error-in-binary usr/lib/frr/bfdd Amount of times Number of times
I: frr: spelling-error-in-binary usr/lib/frr/bgpd occurences occurrences
I: frr: spelling-error-in-binary usr/lib/frr/bgpd recieved received
I: frr: spelling-error-in-binary usr/lib/frr/isisd betweeen between
I: frr: spelling-error-in-binary usr/lib/frr/ospf6d Infomation Information
I: frr: spelling-error-in-binary usr/lib/frr/ospfd missmatch mismatch
I: frr: spelling-error-in-binary usr/lib/frr/pimd bootsrap bootstrap
I: frr: spelling-error-in-binary usr/lib/frr/pimd Unknwon Unknown
I: frr: spelling-error-in-binary usr/lib/frr/zebra Requsted Requested
I: frr: spelling-error-in-binary usr/lib/frr/zebra uknown unknown
I: frr: spelling-error-in-binary usr/lib/x86_64-linux-gnu/frr/libfrr.so.0.0.0 overriden overridden
This commit fixes all of them except the bgp `recieved` issue due to
it being part of json output. That one will need to go through
a deprecation cycle.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Pim will do the nexthop registration with "ip pim rp" static configuration
with this Zebra will advertise the Route Information.
But while processing this info at PIM, if Nexthop Interfaces are not PIM
enabled, currently PIM is dropping those paths. in case all paths are not
PIM enabled, there is no valid RPF Interface at PIM.
and PIM will be stuck at this state until Next update this to route, that
can happen only if there is a Routing change at Zebra for this prefix.
until that time PIM will not have any valid outgoing Interface.
This issue was mainly seen during Node bootup scenarios.
Fix Proposed
=============
store the paths in PIM PNC Data structure though they are not enabled
with PIM, because while selecting the Interface PIM checks for multicast
enabled Interface.
Tests Performed
===============
1. Verified fail Test case
2. Disabling the PIM on selected outgoing Interface, PIM is choosing
another path when Neighbor is down on this Interface.
3. Re-configure the PIM on above un-configured Interface, PIM is staying
with old NHop since it is valid.
Signed-off-by: Satheesh Kumar K <sathk@cumulusnetworks.com>
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>
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>
Add a function that allows you to modify the channel oil's incoming
interface and to appropriately install/remove it from the kernel.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
zvni setup in zebra is controlled via bgpd i.e. advertise_all_vni
from bgpd triggers this setup. As a part of zvni creation we may need
to setup BUM mcast SG entries which are propagated to pimd for MDT setup.
Now pimd may not be present at the time of zvni creation or may restart
post zvni creation so we need a mechanism to replay (on pimd startup) and
to cleanup (on pimd stop). This is addressed via zebra_vxlan_sg_replay and
zebra_evpn_pim_cfg_clean_up.
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>