zebra sends (S, G) and (*, G) entries for BUM mcast groups to pimd. This
commit includes the changes to handle the notifications and trigger the
creation of (S, G) base cache in pimd.
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
These entries will be used over the subsequent commits for
1. vxlan-tunnel-termination handling - setup MDT to rx VxLAN encapsulated
BUM traffic.
2. vxlan-tunnel-origination handling - register local-vtep-ip as a
multicast source.
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
Add a bit of code to allow us to look at specified S,G for
the upstream available to us.
If one item is listed we assume Group, if both we assume Source
then Group.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Add a bit of code to allow us to look at specified S,G for
the upstreams available to us.
If one item is listed we assume Group, if both we assume Source then
Group.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Replace cli 'debug static' with 'debug pim static', to make
the 'debug static' node available for staticd (eventually).
Signed-off-by: Mark Stapp <mjs@voltanet.io>
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>
When we receive a S,G join and the ifchannel is in S,G RPT Prune state,
pim should transition the ifchannel state to JOIN and transition the
pim_upstream state for the S,G stream.
Ticket: CM-24513
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
pim was sending a triggered response on every S,G RPT prune information
read. Suppose we had this in a *,G message:
*,G
S1, G RPT Prune
S2, G RPT Prune
We would send two triggered *,G messages upstream. This leads to over
processing and quickly changing state if S1 or S2 were in different
states.
Modify the code to send just one Triggered *,G upstream after looking
at all S,G state for a *,G.
Ticket: CM-24531
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
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>
Track whether or not we have received an answer from
our query to do nexthop tracking. This allows us to
go straight to doing a synchronous query for our
RPF.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Start the separation of tracking a Destination from the act
of looking it up. The cojoining of these two concepts led
to a bunch of code that had to think about both problems leading
to weird situations and code paths. Simplify the code by making
pim_ecmp_nexthop_search a static function and we only ever
call pim_ecmp_nexthop_lookup when we need to do a RPF().
pim_ecmp_nexthop_lookup will now attempt to find a stored pnc
and if it finds one it will report on the answer from it.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When creating new RP information from a `ip pim rp A.B.C.D/M A.B.C.D`
we should determine if we are the RP even if we can or cannot
determine if we have a path to the RP via RPF.
This is because we should determine if we are the RP based upon a
connected ip address match not whether or not we have a path to
the RPF. We would normally think this is not important but
RPF is inherently asynchronous and we can have a state where
we have registered for nht but have not received the actual
path back yet from zebra.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The current reverse logic led to this code construct
if (!pim_nexthop_lookup(...)) {
//Do something successfull
}
This is backwards and will cause logic errors when people
use this code. Fix to use true/false for success/failure.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When a new pim neighbor comes up, we need to go through and
mark nexthops that we have received from zebra for reachability
tracking so we can refigure stuff. If we pass in the new neighbor
we can limit the search to those nexthops out the interface that
the new neighbor has come up.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The pim_resolve_upstream_nh function call is no longer being used
let's remove it from the code base.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Issue: (*,G) mroute uptime is not updated in mroute table,
after deleting and adding the RP
Root cause: When RP gets deleted or becomes not reachable, then
we un-install the entry from the kernel, but still maintains the
entry in the stack. When RP gets re-configured or becomes reachable,
"show ip mroute" shows the uptime, when the channel_oil gets created.
Fix: Introduce a new time mroute_creation in the channel_oil, gets
updated when mroute gets installed in the kernel.
Signed-off-by: Sarita Patra <saritap@vmware.com>
When we delete an interface, we need to set the interface
ifindex to an internal value so that we don't end up in
a state where the re-addition of the same ifindex, due to
a rename operation, causes an infinite loop.
Fixes:#4007
Fix-Suggested-by: Saravanan K
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
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>
The pim_rp_check_is_my_ip_address function was checking to see
if we were the actual RP as well as the pim_register code
was doing the same thing. Remove the reduncancy a bit and
just make this function check for that we are the actual receiver
of this data.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The code as written will scan the entirety of all pim upstreams
on a rpf change, this is not necessary because we know that when
we get a nexthop change we already scan the upstreams reliant
on that and do this work. There is no need to do this again a
short time later.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The interface column in pim was limited to 8 or 9 columns
all over the place in pim, fix the code up to allow interface
length to be up to 16 columns.
Ticket: CM-23083
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When we are shutting down, delay the zlookup free to as
late as possible since we may need it still
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Suppose we have 2 routers A and B. Both Router A and B have
the same priority of 1000. Router A is the elected DR.
Now suppose B lowers his priority to 1. He still looses the
DR election and we are not sending a hello with the new priority.
Immediately after this A's priority is also lowered to 1, it
looses the election and sends the hello. B receives this hello
and elects A as the DR( since it has the better ip address)
At this point A believes B is the DR, and B believes A is the
DR until such time that the normal hello from B is sent to A,
which if timed correctly can be a significant amount of time).
This code just causes a hello to be sent if the priority is
changed. Now both sides will be able to converge quickly
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
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>
When a RP gets deleted, find all the (*, G) upstream whose
group belongs to the deleted RP.
case 1: if the group belongs to any other rp, then call
pim_upstream_update() to update the upstream addr and rpf
information.
case 2: If no RP found for the group, then clear the pim
upstream address and rpf information.
Signed-off-by: Sarita Patra <saritap@vmware.com>
When a new RP is configured, find all the (*, G) upstream whose
group belongs to the new RP and then update the upstream structure
with the below fields.
1. De-register for the old RP.
2. Set the upstream address as new RP
3. Register for the new RP.
4. Update the upstream rpf information and kernel multicast forwarding
cache(MFC), if the new RP is reachable.
Signed-off-by: Sarita Patra <saritap@vmware.com>
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>
When route to RP gets modified, FRR receives a notification from
zebra, and call the function pim_update_rp_nh() to compute the
new nexthop and will update the source_nexthop information of
rp_info. This is not working for the case when RP becomes not
reachable.
Fix: When FRR receives a notification from zebra saying RP becomes
not reachable, then delete the source_nexthop informatio of rp_info.
Signed-off-by: Sarita Patra <saritap@vmware.com>
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>
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>
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.
Added some null checks for the incoming interface, while displaying
the pim upstream information in the cli command "show ip pim upstream".
Signed-off-by: Sarita Patra <saritap@vmware.com>
Added comments which explains the new values for existing fields
and new fields in the upstream and channel_oil data structure.
Following are the summary of the behaviour change in PIM code.
Scenario 1 : RP doesn’t exist/RP not reachable
Event: Join received
Current behaviour:
No upstream gets created
Changed behaviour:
Upstream data structure created with below info
upstream_addr: INADDR_ANY
channel_oil iif: MAXVIF
channel_oil is_valid: FALSE (flag introduced to indicate if this entry is valid to get installed in hardware)
RPF details: Not valid
Join state: NOT_JOINED
Kernal installed: FALSE
Scenario 2: Dummy upstream exists
Event: RP configured
Current Behaviour:
upstream address updated for the dummy upstream created.
Changed Behaviour:
upstream_addr: RP address
channel_oil iif: MAXVIF
channel_oil is_valid: FALSE
RPF details: only RP address updated
Join state: NOT_JOINED
Kernel installed: FALSE
Scenario 3: Dummy upstream exists
Event: RP becomes reachable
Current Behaviour:
Update channel oil, rpf details in the upstream and install in hardware
Changed Behaviour:
upstream_addr: RP Adress
channel_oil iif: MAXVIF
channel_oil is_valid: FALSE
RPF details: RPF details updated via NHT callback
Join state: JOINED
Kernel installed: TRUE
Scenario 4: MRoute exists
Event: RP gets deleted
Current behaviour:
Nothing got updated in him upstream and channel oil,
join timer still runs. Mroute still exists in kernel.
Changed behaviour:
upstream_addr: INADDR_ANY
channel_oil iif: MAXVIF
channel_oil is_valid: FALSE
RPF details: Not valid
Join state: NOT_JOINED (also sent prune towards deleted RPF nbr)
Kernel installed: FALSE
Scenario 5: MRoute Exists
Event: RP unreachable
Current behaviour:
Nothing got updated in him upstream and channel oil,
join timer still runs. Mroute sdeleted from kernel.
Changed behaviour:
upstream_addr: RP address
channel_oil iif: MAXVIF
channel_oil is_valid: FALSE
RPF details: only RP address updated
Join state: NOT_JOINED (also sent prune towards deleted RPF nbr)
Kernel installed: FALSE
Scenario 6: Mroute exists
Event: Better RP configured with precise group range & reachable.
Current behaviour:
No effect on existing route.
Changed behaviour:
Upstream address: Better RP
RPF interface: towards the better RP
Join state: JOINED (Send a prune towards the old RP and send a join
towards the better RP)
Scenario 7: Mroute exists
Event: RP deleted and another RP with broad group range fits this group & reachable
Current behaviour:
No effect on current behaviour
Changed behaviour:
Upstream address: next available RP
RPF interface: towards the next available RP
Join state: JOINED (Send a prune towards the old RP and send a join
towards the better RP)
Signed-off-by: Sarita Patra <saritap@vmware.com>
Add a test command to pim that allows you to reset the keepalive timer
for an upstream to it's max value. This is to allow purposeful testing
of cleanup code in pim, by forcing the keeaplive timer to expire later.
robot# show ip pim upstream
Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt
enp3s0 192.168.201.136 225.1.0.0 NotJ,RegP 00:00:10 00:00:52 00:00:25 00:02:54 1
robot# show ip pim upstream
Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt
enp3s0 192.168.201.136 225.1.0.0 NotJ,RegP 00:00:11 00:00:51 00:00:24 00:02:53 1
robot# test pim keep 192.168.201.136 225.1.0.0
Setting (192.168.201.136,225.1.0.0) to current keep alive time: 210
robot# show ip pim upstream
Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt
enp3s0 192.168.201.136 225.1.0.0 NotJ,RegP 00:00:27 00:00:35 00:00:08 00:03:27 1
robot#
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Issue: Configure "ip pim rp x.x.x.x 225.0.0.0/4".
Show running config shows "ip pim rp x.x.x.x 224.0.0.0/4"
This is mis-leading.
Root-cause: Internally 225.0.0.0/4 is getting converted to
224.0.0.0/4 group mask, since the prefix length is 4.
Fix: Restrict the user to configure inconsistent group address
mask by throughing a cli error "Inconsistent address and mask".
Signed-off-by: Sarita Patra <saritap@vmware.com>
Issue: Shut the RP interface in the router RP. LHR will get to know
RP becomes not-reachable, so it send a prune towards the RP. On
receiving the prune, RP clear the (*, G) entry, but (S, G) should
not get removed if present.
Now no-shut the RP interface in the router RP. LHR will send a (*, G)
join towards the RP. On receiving join FRR create the (*, G) entry.
Along with this, it also add the interface(join received) in the OIL
of (S, G) and also refresh the (S, G) timer.
Fix: Dont refresh the timer for S, G or (*, G), if the flag for the
channel OIL is PIM_OIF_FLAG_PROTO_ANY.
Signed-off-by: Sarita Patra <saritap@vmware.com>
Add a command to track if an interface should be in active-active
mode or not. This command is hidden at this time because it
is not finished fully.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
- some target_CFLAGS that needed to include AM_CFLAGS didn't do so
- libyang/sysrepo/sqlite3/confd CFLAGS + LIBS weren't used at all
- consistently use $(FOO_CFLAGS) instead of @FOO_CFLAGS@
- 2 dependencies were missing for clippy
Signed-off-by: David Lamparter <equinox@diac24.net>
If you have an interface being added to a static mroute
and that interface has been configured w/ pim but does
not have a valid ip address yet, we do not create a
VIF for that device yet. As such when we attempt
to assign the vif array in the pim static data structure
we attempt to write into -1 of that array.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The pimg data structure is only used in one spot to send the default
vrf id to zebra upon startup. Add the default vrf id to the struct pim_router
data structure and remove the pimg pointer.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Create a `struct pim_router` and move the thread master into it.
Future commits will further move global varaibles into the pim_router
structure.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Just add the ability to notice the capabilities on startup,
but don't do anything with it yet.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When we receive a igmp report and attempt to initiate
a pim ifchannel for it and that fails to work then
let's back out the work done setting stuff up to this
point.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When we fail to add a local membership add some additional debugs
so that we can have a bit more information on when something goes
bad.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
It's been a year since we added the new optional parameters
to instantiation. Let's switch over to the new name.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When sending a sockoption for MRT_INIT, *bsd requires that
the data passed in must be 1. While linux does not, the
code was sending in a positive value that was causing issues
on *bsd of protocol not supported.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When trying to run PIM on *bsd, the kernel expects to only
allow the pim kernel socket to work if we elevate priviledges.
So do so.
This commit gets us further in the startup of PIM on *bsd
but is not sufficient to get it fully started yet.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Introduce frr-interface.yang, which defines a model for managing FRR
interfaces.
Update the 'frr_yang_module_info' array of all daemons that will
implement this module.
Add automatically generated stub callbacks in if.c. These callbacks will
be implemented in the following commit.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
FRR_DAEMON_INFO should now contain an array of 'frr_yang_module_info'
structures describing the YANG modules implemented by the daemon.
This array will be used by frr_init() function to load all YANG modules
and initialize the northbound callbacks during the daemon initialization.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Resolves issue with exit-vrf being placed at the end of zebra's portion
of a vrf block, but before other daemons' portions of the same config
block.
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
The ->hash_cmp and linked list ->cmp functions were sometimes
being used interchangeably and this really is not a good
thing. So let's modify the hash_cmp function pointer to return
a boolean and convert everything to use the new syntax.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit fixes two issues during pim shutdown.
1) The rp_info structure was being freed before the
outgoing notifications that depended on it's information
was sent out as part of shutdown.
2) The pim->upstream_list shutdown involved iterating
over the list via ALL_LIST_ELEMENTS. This typically
is enough but pim will auto delete child nodes as well
as itself when it goes away and they depend on it. As such
the node and nnode could possibly already have been freed.
So change the way we look at all the data in the upstream_list
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Suppose we have a bridge with a host and two routers attached
to it.
r1 r2
| |
--------
|
host
host is sending traffic.
r1 and r2 are pim neighbors and r2 is the DR.
Both r1 and r2 will receive data from the stream up the pim
kernel socket. r1 will notice that it is not the DR and
stop processing in pim. This code adds a bit more code to blackhole
the route when r1 detects it is not the DR in this scenario.
This is being done because the kernel is both keeping state and
sending data to the pim process to continue processing this.
Additionally if we happen to be running this on a asic, then
blackholing the route in the asic can save a significant amount
of cpu time handling this situation.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When we decide we are not the right pim process to add upstream state
for the igmp state received, notice this in a debug to make life
easier to debug.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The tracking of who have drpriority on an interface
in pim was not displayed anywhere. Add to the show
command for future reference.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
In pim_if_new use bool instead of an int to pass
true/false values for what we should create the
pim interface type for.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The startup of a non-integrated config was not properly
allowing for startup to create the vif when we have
not learned about the interface we are trying to configure
at this point in time. Actually notice when we are
trying to create a pimreg device or not to properly
notice when to attempt to create the vif or not.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>