There exists a chain of events where calling pim_mlag_up_peer_deref
can free the up pointer. Prevent a use after free by returning
the up pointer as needed and checking to make sure we are
ok.
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>