When sending a PIM join upwards on the RP-based tree, it may get dropped on
the last hop before the RP if the RP is reachable via a connected route
(i.e. there's no associated nexthop). pimd needs to put the nexthop IP
address into the PIM join payload and fails to do that if that route has a
nexthop of 0.0.0.0. So whenever we look up a route to determine the nexthop
or we receive a nexthop tracking update from Zebra, use the destination
address as the nexthop address for connected routes.
Fixes#2326.
Signed-off-by: Martin Buck <mb-tmp-tvguho.pbz@gromit.dyndns.org>
The assignment of sa with the usage of hash_get and hash_alloc_intern
can never fail. No need to look for a failure case.
Found by Coverity SA.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Cleanup the pim->rpf_hash after upstream cleanup is done
since upstream cleanup uses the rpf_hash to cleanup itself.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The pim_upstream_free command was leaving slag by
not deleting data associated with the upstream
data structure. Modify the code to explicitly free
all data associated with an upstream on a pim instance
deletion event. Additionally the end result is that
the pim_upstream_free command is not needed anymore
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When the underlying networking subsystem is fundamentally
changed via some system controls. If we have msdp running
there exists a possibility that we need to stop some running
timers to prevent a crash.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The interface itself knows if it is a vrf device or
not, so let's just use a check for that in the decision
if a interface is a loopback or not.
Additionally modify function to return a bool.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Adding to mtracebis querying with group address. Same change
to vtysh mtrace command. Support for querying (S,G) and (*,G)
state in mtrace router code. Further improvments to mtrace router
code with closer complience to IETF draft. More references in
comments to the draft. Man page has been updated accordingly.
Signed-off-by: Mladen Sablic <mladen.sablic@gmail.com>
The following types are nonstandard:
- u_char
- u_short
- u_int
- u_long
- u_int8_t
- u_int16_t
- u_int32_t
Replace them with the C99 standard types:
- uint8_t
- unsigned short
- unsigned int
- unsigned long
- uint8_t
- uint16_t
- uint32_t
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Mtrace router code has been fixed for the case where no PIM
interface exists towards the source and next-hop is returned.
fwd_ttl is set to one, for correct reporting of mcast ttl.
Also, NO_MULTICAST error is returned when there is no PIM.
And prev_hop is set to source, for case when connected to source,
to help termination of hop-by-hop queries.
Dependency of logging on PIM, when sending mtrace packet, has been
removed.
Signed-off-by: Mladen Sablic <mladen.sablic@gmail.com>
Can't take the address of members of packed structures due to potential for
alignment faults on some platforms.
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
When the pim_nexthop_lookup fails, close the opened fd
as part of the failure condition.
Additionally pim_nexthop_lookup assumes that we've
actually already looked up a nexthop in the past.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
There is no need to look at all VRF's when we need to
reevaluate the source forward since the calling function
knows the vrf.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
We know the vrf that we are in when we need to initiate a
rescan of the rpf cache. So pass it in and use that information.
This should help the rescan at scale with several vrf's cutting
out a lot of unnecessary work.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Vty commands that link netns context to a vrf is requiring some
privileges. The change consists in retrieving the privileges at the
vrf_cmd_init() called by the relevant daemon. Then use it.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Feature of mtrace only IGMP sockets on pim sm and pim
ssm interfaces. Modifed IGMP socket creation and show
igmp interface command output.
Signed-off-by: Mladen Sablic <mladen.sablic@gmail.com>
The TODO file had become a dumping ground of changes made
to the protocol. That when we modified the underlying code
we would need to update the TODO file again due to it's nature.
There is no point in keeping the list of items that we've done
as that commit messages will indicate the new features. So
pull out all the Finished work and rework the Todo numbers
used.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The ZEBRA_FLAG_INTERNAL flag is used to signal to zebra that
the route being added, the nexthops for it can be recursively
resolved. This name keeps throwing me off when I read it
so let's rename to something that allows the developer to
understand what is going on.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is the implementation of weak multicast traceroute.
It consists of IGMP module dealing with mtrace type IGMP messages
and client program mtrace/mtracebis for initiating mtrace queries.
Signed-off-by: Mladen Sablic <mladen.sablic@gmail.com>
Create a zapi_nexthop_update_decode function that both
pim and bgp use to decode the message from zebra.
There probably could be further optimizations but I opted
to keep the code as similiar as is possible between the
originals because they both make some assumptions about
code flow that I do not fully understand yet.
The real goal here is that I want to create a new
user of the nexthop tracking code from a higher level
daemon and I see no need to re-implement this damn
code again for a 3rd time.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The PIM_NODE command is only being used to display
default vrf configuration. Move this into the
vrf display and remove PIM_NODE.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Abstract the code that sends the zapi message into zebra
for the turn on/off of nexthop tracking for a prefix.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
zclient_init sets the redist_default to the appropriate
value, testing it with an assert doesn't really provide
us with much of anything useful.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The 'ip pim use-source ...' command returns a hard
success/failure. Allow it to return a soft-failure
for when we re-enter the same line.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When PIM handles some MSDP commands, a repeated command
was causing a CMD_WARNING_CONFIG_FAILED. This should
be a CMD_WARNING. Fix the code to allow vtysh to handle
this appropriately.
Ticket: CM-19053
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When creating the pim_ifp, and we run out of memory there
existed a chance that we would dereference the failed memory
pointer.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When we receive a S,G rpt prune message for a mroute,
really, absolutely, guarantee the send upstream immediately.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Some of the deprecated stream.h macros see such little use that we may
as well just remove them and use the non-deprecated macros.
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Allow the higher level protocol to specify if it would
like to receive notifications about it's routes that
it has installed.
I've purposely made it part of zclient_new_notify because
we need to track the routes on a per daemon basis only.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Certain interface flapping events can cause a lookup
that does not find any ifp pointer. This is only causing
a crash in the `debug pim zebra` command due to only needing
to lookup the interface for it's name.
Modify code to ensure we have a valid pointer. Follow other
debug statements lead in the same function for what to display
when an interface does not currently exist.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When we ask PIM to do a CLI search of a random (S,G) if the
(S,G) has no RPF due to no route, let the user know about
the issue instead of crashing.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
A recent commit has shown that we were not consistent with
handling of the vrf lookup. Adjust pim to do the right
thing with vrf lookup to be consistent and to make SA
happier.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This improves code readability and also future-proofs our codebase
against new changes in the data structure used to store interfaces.
The FOR_ALL_INTERFACES_ADDRESSES macro was also moved to lib/ but
for now only babeld is using it.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This is an important optimization for users running FRR on systems with
a large number of interfaces (e.g. thousands of tunnels). Red-black
trees scale much better than sorted linked-lists and also store the
elements in an ordered way (contrary to hash tables).
This is a big patch but the interesting bits are all in lib/if.[ch].
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Make use of strnlen() and strlcpy() so we can get rid of these
convoluted if_*_by_name_len() functions.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
When displaying the 'show ip pim upstream' command.
Display proper information about the RPF address
choosen.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Convert the list_delete(struct list *) function to use
struct list **. This is to allow the list pointer to be nulled.
I keep running into uses of this list_delete function where we
forget to set the returned pointer to NULL and attempt to use
it and then experience a crash, usually after the developer
has long since left the building.
Let's make the api explicit in it setting the list pointer
to null.
Cynical Prediction: This code will expose a attempt
to use the NULL'ed list pointer in some obscure bit
of code.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Current cleanup is for unset values or variables that are not used anymore.
Regarding ospfd/ospf_vty.c: argv_find()
we'll never get it NULL, so get coststr = argv[idx]->arg;
When displaying the mroute table, add ability to fill
in all the missing data that for human eyes can be assumed.
This will allow people using grep over the command
can get more information.
sharpd@robot ~> sudo vtysh -c "show ip mroute fill"
Source Group Proto Input Output TTL Uptime
* 229.1.1.1 STATIC dum0 enp3s0 1 00:11:07 Default-IP-Routing-Table
* 229.1.1.1 STATIC dum0 virbr0 1 00:01:47 Default-IP-Routing-Table
sharpd@robot ~>
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Adds the ability to filter PIM Joins & IGMP reports on an interface.
Enabling a multicast boundary on an interface for a particular group
will prevent the interface from appearing in the group's OIL.
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
If pim/igmp is not enabled on an interface, the ->info pointer will be
null. Need to check that before dereferencing it.
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
If you cut-n-paste an existing "ip igmp join 233.200.0.0 0.0.0.0"
command under an interface we should not return an error.
This fixes the broken indentation of several foreach loops throughout
the code.
From clang's documentation[1]:
ForEachMacros: A vector of macros that should be interpreted as foreach
loops instead of as function calls.
[1] http://clang.llvm.org/docs/ClangFormatStyleOptions.html
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Start the conversion of pim configuration commands to use
the ferr side channel to allow more detailed information
to be returned to cli commands.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
All the rp debugs were a mish-mash of TRACE or ZEBRA,
but the reality they were all focused on handling NHT
issues associated with the RP's. So let's create
a new debug 'debug pim nht rp' if you are having
issues with RP's.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
If you read the extra fine print of the PIM RFC
it asks you to stop the PP Timer and the
Expiry Timer when you are certain S,G RPT states.
This commit puts this into practice and it also
deletes the S,G ifchannel if necessary.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com.
The changes introduced in PR #1044 caused pim to notice
when a setsockopt call failed. The kicker here is that
this used to just work because we ignored the issue
pre. So VRF's need to BINDTODEVICE to get igmp callbacks
but the default vrf does not need to do so.
With the fix we now see IGMP group join:
root@dell-s6000-02 ~/frr# vtysh -c "show ip igmp group"
Interface Address Group Mode Timer Srcs V Uptime
br1 20.0.11.1 232.2.3.4 EXCL 00:04:14 1 3 00:00:05
Fixes: #1121
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This feature does this:
Add the ability to store the non-prefix static RP
entries into a table. Then to lookup the G to
find the RP in that table, finding the longest
prefix match across both prefix-lists and
static RP's.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When we are searching for a RP to use, amongst
many RP's and separate prefix-lists, Match on
the longest prefix specified to choose the
correct RP.
Example:
ip pim rp 4.3.2.1 prefix-list A
ip pim rp 4.3.2.2 prefix-list B
ip pim rp 4.3.2.3 prefix-list C
ip prefix-list A seq 5 permit 225.0.0.0/8
ip prefix-list B seq 5 permit 225.1.0.0/16
ip prefix-list C seq 5 permit 225.1.1.0/24
Old behavior: Group 225.1.1.14 comes in and
we need to find the RP to use, we would match
on the first prefix-list A( since we are searching
based on a sorted link list of RP address ) and
select 4.3.2.1 as our RP
New behavior: Group 225.1.1.14 comes in and
we need to find theRP to use, we now will
match on C( longest prefix match ) and select
4.3.2.3 as our RP.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
There exists cases where we have not properly configured
a RP yet, but we are getting callbacks for nocache.
This is generating allot of spam messages in the log.
In the case where we attempt to lookup INADDR_NONE
just say it fails without need to talk to anyone
since we'll never get a real answer from zebra
anyways.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The commit '19b807c pimd: Allow the keepalive time to be per vrf.'
is missing some data. Probably as a result of the indentation
and I accidently dropped it.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
pim is vrf aware and the interface based line for vrf's was
not being started with a vrf_frame as the non interface
based line was.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Using the previously-added vty_frame() support, this gets rid of all the
pointless empty "interface XYZ" blocks that get added for any interface
that shows up in the system (e.g. dummys, tunnels, etc.)
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Specifically, gcc 4.2.1 on OpenBSD 6.0 warns about these; they're bogus
(gcc 4.2, being rather old, isn't quite as "intelligent" as newer
versions; the newer ones apply more logic and less warnings.)
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
1) Error check return from setsockopt and sockets
2) Check return codes for str2prefix
3) Clean up some potential NULL References
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
1) Clean up display of S,GRPt prune state to be more meaningful
2) Upon receipt of a S,GRPt prune make sure we transition to
the correct state
3) Upon loss of a S,GRPt prune make sure we transition to
the correct state as well as immediately send a *,G
join upstream to propagate the loss of the prune.
4) Removal of a weird S,G state being installed upon
loss of a S,G RPt prune.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
This could happen if routing isn't up yet but the command did take so we
should exit 0 here. Testing:
root@cel-redxp-10[frr-dwalton76]# vtysh -c 'conf t' -c' ip pim rp
11.11.11.11'
% No Path to RP address specified: 11.11.11.11
root@cel-redxp-10[frr-dwalton76]# echo $?
0
root@cel-redxp-10[frr-dwalton76]#
There exists a path for ifchannel creation that if a S,G
fails to create and a corresponding *,G ifchannel is there,
the S,G will be deleted but we were leaving the S,G in the
*,G ifchannel sources list. Remove from the list in this case
Ticket: CM-17605
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
BFD replay for all interfaces was only considering VRF_DEFAULT interface
list.
The change will walk all VRFs, interface list per VRF to register pim
neighbor with BFD.
Signed-off-by: Chirag shah <chirag@cumulusnetworks.com>
Upon frr restart vtysh replays pim bfd configuration
cli before pim sm command, this results in failure
of pim bfd config on the VIF as it is not pim enabled yet.
Inside pim bfd configuration, call to create PIM vif
handler if it is not created yet.
no ip pim bfd, if pim is not enabled display warning and return.
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
This does three things:
1) When we get a RPF_FAILURE, remove the mroute associated
with it.
-> This way when the RPF comes back we can just add the
mroute in as part of the normal scanning process.
2) When we do a ecmp_nexthop_search return 1 when we found
something we can use.
3) Ignore output from pim_update_rp_nh
-> When we do a ecmp_nexthop_search ignore the return
code and do not attempt to gather it up to return
to the calling function. It is just ignored
and we were not taking into account the what of
multiple RP's we were looking at.
Ticket: CM-17218
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
If a single S,G is being deleted because the keepalive
timer has timed out, Send a *,G join upstream to clear
the S,G RPT prune bit.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The secondary address list was being added/removed as
we went. I see no reason to have special bookkeeping
for this list. Just add it on interface startup and
then remove it on deletion. Removes some
very specialized coding that was saving a very small
amount of space.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
There are situations where we receive a *,G with
a S,G,RPT Prune embedded where we do not actually
have any S,G yet(MSDP with multiple RP's with the
same address). As such since we only need to
lookup the S,G ifchannel once, do it after
the recv_prune.
Ticket: CM-17230
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When a interface is flapped we were leaking some memory
associated with link lists. Especially in the jp_agg
code. If your network was/is stable and you are not
running at any scale you probably would not see this
as impactful at all.
Ticket: CM-16392
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The channel_oil has a back pointer(up) to the upstream data structure.
If we are planning on keeping the channel oil (due to ref count issues)
longer than keeping the upstream, when we delete the upstream we were
not clearing the back pointer to up. This would result in a situation
where if that memory has started to be used again it will cause a
crash and other fun things.
Ticket: CM-17092
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This patch does two things:
1) Converts the pim_ifp->ifchannel_list to a pim_ifp->ifchannel_rb
2) Removes the hashing to use the RB RB_FIND instead.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Remove the redundant information in pim_ifp->pim_ifchannel_list
just call it pim_ifp->ifchannel_list
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The pim->ifchannel_list can be duplicated by iterating
over each vrf and then over each pim_ifp->pim_ifchannel_list
Since list handling is taking allot of time at scale
convert over to using this value.
Additionally clean up pim_cmd.c to have helper functions
to handle the actual encoding of data for output.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The NHT upstream list at scale is horribly inefficient due to keeping
a sorted list of upstream entries. The attempting to find
the upstream and the insertion of it into the upstream_list
was consuming a large amount of cpu cycles.
Convert to a hash, allow add/deletions to effectively become
O(1) events.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When we receive a new ecmp path and the old nexthop is still
valid. There existed some cases where we would continue looking
for a nexthop( and thus loose the fact that we had found it )
after found.
Ticket: CM-16983
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Don Slice <dslice@cumulusnetworks.com>
When we receive a S,G,RPT prune as part of a *,G tree, install
the NULL oil S,G mroute. This will cause the traffic to stop
flowing for this particular S,G as we expect.
Ticket: CM-16978
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
'show ip mroute vrf all count' crashes currently
This commit fixes that issue
Ticket: CM-17052
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
During normal course of operations, zebra sends the ZEBRA_INTERFACE_VRF_UPDATE
call up into all connected zclients. In the case of PIM the
zlookup was expecting a min length of 10, but ZEBRA_INTERFACE_VRF_UPDATE
was sending of size 6. This min length check makes no sense,
so just remove.
Ticket: CM-16976
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
When we receive a SGRPT Prune we were switching the upstream
to JOINED and immediately sending a join. This was not
the right thing to do.
This was happening because we were making decisions about the
new ifchannel before it was fully formed.
Rework ifchannel startup to provide enough information to
the pim upstream data structure to make the right decisions
Ticket: CM-16425
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
In show ip pim interface and show ip pim interface <intf>
display State "down" pim enabled interfaces.
Ticket:CM-16809
Reviewed By:CCR-6398
Testing Done:
show ip pim interface
Interface State Address PIM Nbrs PIM DR FHR IfChannels
br1 up 2.0.1.1 0 local 0 0
lo up 6.0.0.1 0 local 0 0
pimreg up 0.0.0.0 0 local 0 0
swp1 down 6.0.1.1 0 local 0 0
swp2 up 6.0.2.1 1 local 0 0
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
When we receive a register message for an existing S,G
and the SPT bit is not set, then do a quick check against
the S,G to see if we have counters updated. This is added
because the existing S,G wheel_timer only updates every
31 seconds and it is possible for a Null Register to
have come in before that first 30 second timer pops.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Ensure that displayed (S,G) output in logs is
consistent for all debugs. This will make it
easier to grep for interesting data.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When the secondary addresses got expanded to allow
v6 on the list, we needed to limit the igmp sockets
to just v4 currently.
Ticket: CM-16858
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Quentin Young <qlyoung@cumulusnetworks.com>
Be aware that we may not have pim configured on all interfaces when
we have a failure situation.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When we have vrf config that we have not fully setup yet,
(ie zebra knows nothing about it yet), when attempting to
do a nexthop_lookup, zebra will just drop the request
if it doesn't know about the vrf.
In this case, we need to safely not ask for the information
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When we do not really have the vrf up, wisely do not attempt
to dereference the ifp looked up.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
It is possible that the incoming interface lookup
will fail because we are in transition from one vrf
to another.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Under vrf's pim needs to have a socket listening for pim packets on the vrf
device so that we can actually get the packets. As such when we configure
up a vrf interface, configure just enough to allow it to listen on the
device and to do the right thing.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When we are initializing a pim socket for vrf or loopback
interfaces do not schedule a hello to go out at all.
I'm currently leaving the check on is a vrf / loopback
device on the actual send as that we have several paths
to get there.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
pim was the only routing daemon to have any knowledge
of how zebra connects to each daemon. There is no
need for this.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
In a vrf configuration, when we receive a pim packet we lookup
the correct incoming interface. There exists a chance that
the correct incoming interface has not been configured to use
pim yet. gracefully bow out and do nothing with the packet.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The pimregX devices when created by the kernel are put into
the default vrf. When pim gets the callback that the device
exists, check to see if it is a pimregX device and if so
move it into the appropriate vrf.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When shutting down the vrf don't kill the default vrf
when attempting to cleanup something else.
Also move the terminate to the right spot.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The vrf interface is receiving the pim packet
instead of the slave interface that is bound.
Lookup the ifindex ifp pointer from that.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Bind the pim kernel fd to the appropriate vrf, modify
the callback up into pim with the IGMP report to
retrieve the incoming interface and use that to
lookup the correct interface to use.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Fix the instance startup to allow separation between the data structure
setup for pim instances from actual attempt to use. More than
likely there will be other issues that need to be fixed but
this gets us 'working' again.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
pim_msdp_pkt_sa_gen is intentionally passed mp as NULL
in some cases, so we need to pass through the pim instance
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The vrf loopback ip address should be associated with the
vrf device for vrf's, else use the loopback.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Move the upstream_list, hash and wheel into 'struct pim_instance'
Remove all pimg to pim in pim_upstream
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
A bunch of functions had return values that were never
checked for ( and not needed ) and opposite return values
for proper calling function boolean logic.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
1) Create pim_instance.[ch] to allow us to handle the instance information there
2) Refactor some pim_rpf_ and some pim_rp commands into appropriate files and
appropriate includes.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
As a transitory mechanism, if c_oil->pim is set, use that particular
pim instance, else use the default pimg.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The pimreg device name should be based upon the
tableid we create( as that this is what the kernel does )
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Storing the pim instance off of the pim interface will allow
us to easily keep track of vrf information. This is because
pretty much is everything is interface based.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When we are handling the thread read/writes for
a pim mroute socket, make it so that it can
be appropriately handled by the 'struct pim_instance'
instead of defaulting to the default VRF's
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit does these things:
1) Saves the pim instance created on the vrf pointer
2) Moves some initialization to the proper spot.
3) Remove vrf_id from 'struct pim_ssm' it is not needed
4) Removes some checks to prevent non-default vrf's from
being created.
5) When creating the pim instance, save default vrf in pimg to allow backwards compatibility
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This change allows other non-linux platforms to be a bit
more forgiving if we ask for a very very large size.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Convert the socket fd to be owned by the pimg pointer as
well as the counters associated with the fd. This will
allow us to future proof our code.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This reverts commit c14777c6bf.
clang 5 is not widely available enough for people to indent with. This
is particularly problematic when rebasing/adjusting branches.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
This allows frr-reload.py (or anything else that scripts via vtysh)
to know if the vtysh command worked or hit an error.
During running config, all IFPs are traversed, bfd interface config write
need to check for ifp->info null in case pim info is missing and skip the interface.
bfd update for address change need to check if particular pim neighbor's address matches
with bfd address update
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
In prep for switching over to having PIM understand VRF
remove the qpim_inaddr_any global variable and just
use INADDR_ANY directly.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The secondary address comparison done to determine if we are
an RP for a specified address was comparing A.B.C.D/32 to A.B.C.D/0
because when we created the rp_info we were not setting the prefixlen
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
-Upon Rx (*,G) Join w/o SGRpt at RP, trigger (S,G) Join
towards FHR, unset SGRpt flag from channel,
add (*,G) oif to (S,G) entry.
-Add I am not RP check to triger SGRpt on *,G path otherwise,
send S,G Prune on SPT path from RP to FHR upon receving *,G Prune.
-Upon Rx SGRpt receive, remove OIF(downstream where Prune received) from specific S,G.
Testing Done:
pim-smoke
Ran 95 tests in 11790.552s
FAILED (SKIP=10, failures=4)
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
The indentation of ifjoin_to_noinfo was not consistent with
the rest of the function and caused clang to loose it's mind
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The indentation of ifjoin_to_noinfo was not consistent with
the rest of the function and caused clang to loose it's mind
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
All PIM Neighbors for a given pim interface is registered with
BFD.
Upon receiving BFD status down event, PIM Neighbor with BFD info is deleted.
Add pim bfd configuraiton (CLI) per interface, '[no] ip pim bfd'
Testing Done:
Configure BFD under PIM interface on all neighbor routers,
check bfd sessions up, remote end unconfigure BFD, results in BFD session down.
Previous state was UP to New state DOWN, results in PIM neighbor delete behind
that particular pim interface.
Pim-smoke Results:
Ran 94 tests in 7409.680s
FAILED (SKIP=8, failures=2)
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
When we add a thread pointer to thread_add_XXX functions
when the specified function is called, thread.c is setting
the thread pointer to NULL. This was causing pim to
liberally pull it's zassert grenade pin's.
Additionally clean up code to not set the NULL pointer.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
pim register_recv api returns 1 instead of 0 upon succesfully processing REG message
Testing Done:
Verified At RP via receiving PIM (Data/Null) Register messages
and checked show ip pim interface < > Received errors under Hello
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
If frr.conf file has pim hello option setup prior to pim sm under an interface, upon frr start/restart hello option cli replayed prior to sm command
from vtysh. Added a code in pim hello option cli handler to create pim vif if it does not exist.
Testing Done:
configure pim hello options before pim sm in frr.conf file and restart frr
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
Send IGMP General Query and Get Gen. Query timer,
once Other Querier timer expired.
Ticket:CM-13152
Reviewed By:CCR-6189
Testing Done:
tor-4# show ip igmp interface
Interface State Address V Querier Query Timer Uptime
swp2 up 70.1.1.2 3 other --:--:-- 00:06:45
swp3 up 80.1.1.2 3 local 00:00:35 00:22:52
Upon disabling IGMP on remote igmp interface, after other querier expiry
sends a query and elects as Querier
tor-4# show ip igmp interface
Interface State Address V Querier Query Timer Uptime
swp2 up 70.1.1.2 3 local 00:01:29 00:10:16
swp3 up 80.1.1.2 3 local 00:01:14 00:26:23
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
-Upon Receving SGRpt Prune message, transitioning from Prune Pending state
to NOINFO state, ifchannel entry was getting deleted in prune pending timer
expiry. This can result in SGRpt ifhchannel deleted and recreated upon receving
triggered or periodic SGRpt received from downstream.
The automation test failed as it expected (check) SGRpt entry at RP after it triggers
SPT switchover.
- While transitioning from Prune-Pending state to NOINFO(Pruned) state, Trigger
SGRpt message towards RP.
- Add/del some of the debug traces
Ticket:CM-16057
Reviewed By:CCR-6198
Testing Done:
Rerun test08 multiple times and observed passing it.
Pim-smoke with hardnode
Ran 95 tests in 11219.420s
FAILED (SKIP=10, failures=4)
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
When we have no normal mroutes and only static mroutes
there exists a code path where we attempted to dereference
c_oil when we were showing static mroutes. Looks like
a cut-n-paste error, we should be using s_route->c_oil there
Ticket: CM-15013
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
We only needed to add/change the vrf callbacks when we initialize
the vrf subsystem. As such it is not necessary to handle the callbacks
in any other way than through the init function.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
vrf_iflist_create -> By the time this is called in enable, the vrf's iflist
is already created. Additionally this code should be a properly of the vrf
to init/destroy not someone else.
vrf_iflist_terminate -> This function should be a property of vrf deletion
and does not need to be exposed.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The FSF's address changed, and we had a mixture of comment styles for
the GPL file header. (The style with * at the beginning won out with
580 to 141 in existing files.)
Note: I've intentionally left intact other "variations" of the copyright
header, e.g. whether it says "Zebra", "Quagga", "FRR", or nothing.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Pass pointer to pointer instead of assigning by return value. See
previous commit message.
To ensure that the behavior stays functionally correct, any assignments
with the result of a thread_add* function have been transformed to set
the pointer to null before passing it. These can be removed wherever the
pointer is known to already be null.
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
The way thread.c is written, a caller who wishes to be able to cancel a
thread or avoid scheduling it twice must keep a reference to the thread.
Typically this is done with a long lived pointer whose value is checked
for null in order to know if the thread is currently scheduled. The
check-and-schedule idiom is so common that several wrapper macros in
thread.h existed solely to provide it.
This patch removes those macros and adds a new parameter to all
thread_add_* functions which is a pointer to the struct thread * to
store the result of a scheduling call. If the value passed is non-null,
the thread will only be scheduled if the value is null. This helps with
consistency.
A Coccinelle spatch has been used to transform code of the form:
if (t == NULL)
t = thread_add_* (...)
to the form
thread_add_* (..., &t)
The THREAD_ON macros have also been transformed to the underlying
thread.c calls.
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
During processing of Join/Prune,
for a S,G entry, current state is SGRpt, when only *,G is
received, need to clear SGRpt and add/inherit the *,G OIF to S,G so
it can forward traffic to downstream where *,G is received.
Upon receiving SGRpt prune remove the inherited *,G OIF.
From, downstream router received *,G Prune along with SGRpt
prune. Avoid sending *,G and SGRpt Prune together.
Reset upstream_del reset ifchannel to NULL.
Testing Done:
Run failed smoke test of sending data packets, trigger SPT switchover,
*,G path received SGRpt later data traffic stopped S,G ages out from LHR, sends only
*,G join to upstream, verified S,G entry inherit the OIF.
Upon receiving SGRpt deletes inherited oif and retains in SGRpt state.
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
Upon static IGMP configured port down igmp source info is destroyed.
Upon port up or quagga restart (if addr add) register IGMP sock with
port, source, group.
Testing Done:
Configure IGMPv3 Report on Host swpx, ifdown/ifup swpx,
verify ip mroute containng IGMP mroute
tor-1# show ip mroute
Source Group Proto Input Output TTL Uptime
30.1.1.1 225.1.1.21 IGMP swp2 swp3 1 00:00:05
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
Upon pim enabled disabled, current upstreams entries rpf update callback,
needs to check if old rpf is still pim enabled otherwise do not trigger
prune towards old rpf.
Testing Done:
Verified by disabling pim enabled rpf interface and
crash is not observed upon disabling pim on rpf interface.
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
ip pim ecmp and ip pim ecmp rebalance configuration CLIs were
not adding to Quagga.confg or running configuration.
Added both the configuration write in Config write handler.
Testing Done: Execute configuration cli and verified running config
and Quagga.conf file containing both configuration.
03# show running-config
Building configuration...
Current configuration:
!
ip multicast-routing
ip pim rp 6.0.0.9 230.0.0.0/16
ip pim join-prune-interval 61
ip pim ecmp
ip pim ecmp rebalance
!
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
During PIM Neighbor change/UP event, pim_scan_oil api
scans all channel oil to see any rpf impacted. Instead of
passing current upstream's RPF it passes current RPF as 0 and
does query to rib for nexhtop (without ECMP/Rebalance). This creates
inconsist RPF between Upstream and Channel oil.
In Channel Oil keep backward pointer to upstream DB and fetch up's
RPF and passed to channel_oil scan.
Decrement channel_oil ref_count in upstream_del when decrementing
up ref_count and it is not the last.
Created ECMP based FIB lookup API.
Testing Done:
Performed following testing on tester setup:
5 x LHR, 4 x MSDP Spines, 6 Sources each sending to 1023 groups from one of the spines.
Total send rate 8Mpps.
Test that caused problems was to reboot every device at the same time.
After fix performed 5 iterations of reboot devices and show no sign of the problem.
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
When we have a S,G being created, that it might
also be a FHR router as well. This happens
when the FHR is in the path of the RP->LHR
for when it builds it's SPT tree for the S,G.
Ticket: CM-16056, CM-15836
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Now that pim has the ability to use ecmp, the Group
path to the RP, may be different than what is choosen
for the *,G IIF. As such when we are making the
spt switchover decision, compare the S,G IIF to the
*,G IIF.
Ticket: CM-15870
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When we uplifted the cli from old -> new, I did not properly
handle the switch from <1-3> to (1-3) for number ranges.
Also fix some minor variable renaming that happened?
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This was causing a crash when no group address was passed
because a garbage pointer valuse was used. It also was ignoring
the group address when passing one.
Signed-off-by: Jafar Al-Gharaibeh <jafar@atcorp.com>
During neighbor down event, all upstream entries rpf lookup may result
into nhop address with 0.0.0.0 and rpf interface info being NULL.
Put preventin check where rpf interface info is accessed.
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
During processing of Join/Prune,
for a S,G entry, current state is SGRpt, when only *,G is
received, need to clear SGRpt and add/inherit the *,G OIF to S,G so
it can forward traffic to downstream where *,G is received.
Upon receiving SGRpt prune remove the inherited *,G OIF.
Testing Done:
Trigger SPT switchover, *,G path received SGRpt later data
traffic stopped S,G ages out from LHR, sends only
*,G join to upstream, verified S,G entry inherit the OIF.
Upon receiving SGRpt deletes inherited oif and retains in SGRpt state.
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
Execute ip igmp version 3 under swp interface,
verified show running displayed 'ip igmp' configuration.
Continuous sending group membership, performed 'no ip igmp'
and verified, group membership flushed. Performed
'ip igmp version 3', verified 'show ip igmp groups'
displaying igmp membership re-populated.
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
In this patch, PIM nexthop tracking uses locally populated nexthop cached list
to determine ECMP based nexthop (w/ ECMP knob enabled), otherwise picks
the first nexthop as RPF.
Introduced '[no] ip pim ecmp' command to enable/disable PIM ECMP knob.
By default, PIM ECMP is disabled.
Intorudced '[no] ip pim ecmp rebalance' command to provide existing mcache
entry to switch new path based on hash chosen path.
Introduced, show command to display pim registered addresses and respective nexthops.
Introuduce, show command to find nexthop and out interface for (S,G) or (RP,G).
Re-Register an address with nexthop when Interface UP event received,
to ensure the PIM nexthop cache is updated (being PIM enabled).
During PIM neighbor UP, traverse all RPs and Upstreams nexthop and determine, if
any of nexthop's IPv4 address changes/resolves due to neigbor UP event.
Testing Done: Run various LHR, RP and FHR related cases to resolve RPF using
nexthop cache with ECMP knob disabled, performed interface/PIM neighbor flap events.
Executed pim-smoke with knob disabled.
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
(cherry picked from commit cba4448178)
We have a bunch of places where we iterate over
the pim_ifchannel_list to find those ifchannels
that match a certain upstream. Since we already
know in the upstream the list of ifchannels
associated with it, just look at those instead.
Functions changed:
forward_on
forward_off
pim_upstream_rpf_interface_changed
pim_upstream_update_could_assert
pim_upstream_update_my_assert_metric
pim_upstream_update_assert_tracking_desired
pim_upstream_is_sg_rpt
Ticket: CM-15629
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Add a list structure to track the ifchannels associated
with a particular upstream.
We are not doing anything with this particular knowledge
yet but it will be come useful in the near future.
Ticket: CM-15629
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When we are determining an inherited_olist, let's be allot
smarter about what we look at. Before this code change
we are looping over the entirety of all ifchannels in
the system to find the relevant ones. Convert the
code to *find*(hash table lookup) the specific ifchannels we
are interested in.
Ticket: CM-15629
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When we have a S,G that was created due to the *,G IGMP
report going away, safely remove the S,G as well.
Ticket: CM-15838
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
To the 'ip pim spt-switchover infinity-and-beyond' command
add 'prefix-list <PLIST>'. To the command.
Use this as the basis to deny (Not immediate switchover)
or permit (Immediate switchover), based upon matching
the group address and the prefix-list.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
In this patch, PIM nexthop tracking uses locally populated nexthop cached list
to determine ECMP based nexthop (w/ ECMP knob enabled), otherwise picks
the first nexthop as RPF.
Introduced '[no] ip pim ecmp' command to enable/disable PIM ECMP knob.
By default, PIM ECMP is disabled.
Intorudced '[no] ip pim ecmp rebalance' command to provide existing mcache
entry to switch new path based on hash chosen path.
Introduced, show command to display pim registered addresses and respective nexthops.
Introuduce, show command to find nexthop and out interface for (S,G) or (RP,G).
Re-Register an address with nexthop when Interface UP event received,
to ensure the PIM nexthop cache is updated (being PIM enabled).
During PIM neighbor UP, traverse all RPs and Upstreams nexthop and determine, if
any of nexthop's IPv4 address changes/resolves due to neigbor UP event.
Testing Done: Run various LHR, RP and FHR related cases to resolve RPF using
nexthop cache with ECMP knob disabled, performed interface/PIM neighbor flap events.
Executed pim-smoke with knob disabled.
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
When we have a *,G mroute that starts receiving any particular
S,G, we will get wholepkt callbacks due to the pimreg in the
OIL for the *,G.
So we need to do SPT switchover, but this can fail if we
do not have a path to the S( but we do to the RP!).
In this case fail gracefully.
Ticket: CM-15621
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This allows SPT switchover for S,G upon receipt of packets
on the LHR.
1) When we create a *,G from a IGMP Group Report, install
the *,G route with the pimreg device on the OIL.
2) When a packet hits the LHR that matches the *,G, we will
get a WHOLEPKT callback from the kernel and if we cannot
find the S,G, that means we have matched it on the LHR via
the *,G mroute. Create the S,G start the KAT and run
inherited_olist.
3) When the S,G times out, safely remove the S,G via
the KAT expiry
4) When the *,G is removed, remove any S,G associated
with it via the LHR flag.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When terminating pim, there existed( albeit small ) the chance
to cause a crash. Cleanup the termination to not have
that chance.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
It is impossible for the list->cmp function to
ever be handed NULL values as the arguments.
Clean up this in the code.
Additionally consolidate the exact same two functions
into 1 function.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
There is no need for a function that calls another function.
Additionally, nexthop_updates from zebra can be either
ZEBRA_NEXTHOP_UPDATE -or-
ZEBRA_IMPORT_CHECK_UPDATE
If we were to receive a IMPORT_CHECK_UPDATE the code
would cause a immediate crash. Fix this
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
There exists a common pattern in pim where we were setting
a variable to a value in the error case when we would no
longer need it.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Add code to properly receive v6 addresses up from zebra and to
properly place them into our interface secondary address list.
Additionally cleanup some code in pim_cmd.c that was broken
by these changes.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Send v6 secondary addresses to our neighbor in hello's.
Additionally allow the disabling it via the cli introduced
earlier.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Add ability to encode/decode the v6 secondary addresses
if they are passed to us.
This also fixes the issue where if we are passed
a v6 secondary address list we will not refuse
to form neighbors.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
With RFC 5549 we need a methodology to find
a neighbor based upon a nexthop that is
v6 based. This commit sets us up for that
by allowing you to find the neigbor by
the secondary list. In a future commit
we will add code to pass the v6 secondary
addresses.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When we are checking RP addresses and looking at the secondary
address. With the addition of the ability to handle v6 addresses
in the secondary list. Assuming that the secondary address
is a v4 address is a no go.
Convert to prefix_same.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This code change adds the ability to specify that
we should be able to work with older versions
of PIM.
In future commits we will actually use this data.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
In certain conditions when we are deleting the interface
from an OIL do not delete the mroute. That decision
should be made by the state machine.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Interface type has been replaced with the SSM range config. And SSM
groups can now co-exists with ASM groups. I have left the pim ssm
per-interface cli control hidden. It now enables pim-sm with a warning.
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Ticket: CM-15344
Testing Done: pim-smoke
SSM groups (232/8 or user configured SSM range) can exist in the same
multicast network as ASM groups. For such groups all RPT related state
machine operations have to be skipped as defined by section 4.8 of
RFC4601 -
1. Source registration is skipped for SSM groups. For SSM groups mroute
is setup on the FHR when a new multicast flow is rxed; however source
registration (i.e. pimreg join) is skipped. This will let the ASIC black
hole the traffic till a valid OIL is added to the mroute.
2. (*,G) IGMP registrations are ignored for SSM groups.
Sample output:
=============
fhr# sh ip pim group-type
SSM group range : 232.0.0.0/8
fhr# sh ip pim group-type 232.1.1.1
Group type: SSM
fhr# sh ip pim group-type 239.1.1.1
Group type: ASM
fhr#
Sample config:
=============
fhr(config)# ip pim ssm prefix-list ssm-ranges
fhr(config)#
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Ticket: CM-15344
Testing Done:
1. SSM/ASM source-registration/igmp-joins.
2. On the fly multicast group type changes.
3. pim-smoke.
When we get a SGrpt Prune embedded in the *,G Join,
Display the created ifchannel as being SGRpt state.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
pim_jp_agg list should not ref count pim_upstream as that
the deletion of pim_upstream deletion should remove
the pim_upstream from the j/p agg list.
Cleanup a memory leag of jag
Make comparison of js cleaner in add_group
Move THREAD_OFF to before the neighbor find.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Suppose you have a unnumbered ecmp connections between
two switches:
st1-l3# show ip pim neighbor
Interface Neighbor Uptime Holdtime DR Pri
swp52 6.0.0.10 00:00:01 00:00:29 1
swp53 6.0.0.10 00:00:06 00:00:26 1
And for a given (S,G) the RPF goes:
st1-l3# show ip nht
99.1.1.1
resolved via bgp
fe80::4e76:25ff:fee7:42d1, via swp52
fe80::4e76:25ff:fee7:42d5, via swp53
Client list: pim(fd 14)
Now suppose, 52 is the choosen RPF( since we can only pick one )
and the interface goes down. As such we will choose to use
swp53.
The problem was that the pim_rpf_update call is made
it will change the rpf interface to 53, but not tell
the calling function that the RPF_CHANGED because
it is only looking at the rpf_addr(the nexthop)
to see if it is changed and if we are in an unnumbered
dual ecmp to the same box it was not detecting and
notifying.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The J/P Aggregation + the NHT tracking code was not
playing nicely together
1) Clean up pim_upstream ref counting to keep a bit better
track of it.
2) When we delete pim_upstream zero it out to hopefully
catch issues faster in the future
3) Clean up J/P Agg source list a bit better to keep order
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When creating the pim upstream data structure, if we fail
to create remove the reference we saved to it on the side
in the pnc code.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When an interface bounces and we receive a packet before
pim has a chance to fully bring the 'struct pim_usptream'
back up correctly, first check to see if we already have
an associated data structure before creating it again.
This removes a case where both the c_oil and up ref counts
were being incremented and never removed properly.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Add pim Nexthop tracking feature 1st part where, specific RP or Source address (unicast address)
register with Zebra. Once nexthop update received from Zebra for a given address, scan RP or upstream
entries impacted by the change in nexthop.
Reviewed By: CCR-5761, Donald Sharp <sharpd@cumulusnetworks.com>
Testing Done: Tested with multiple RPs and multiple *,G entries at LHR.
Add new Nexthop or remove one of the link towards RP and verify RP and upstream nexthop update.
similar test done at RP with multiple S,G entries to reach source.
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
Changed the state field in the "sh ip pim upstream" output to include
register and join state info as a comma separated value. Register info
is supressed if reg-state=NoInfo.
Sample output:
=============
root@fhr:/home/cumulus# net show pim upstream
Iif Source Group State Uptime JoinTimer
RSTimer KATimer RefCnt
swp1 33.1.1.1 239.1.1.2 J,RegP 00:00:18 --:--:--
00:00:44 00:03:24 2
root@fhr:/home/cumulus#
root@rp:/home/cumulus# net show pim upstream
Iif Source Group State Uptime JoinTimer
RSTimer KATimer RefCnt
lo * 239.1.1.2 J 00:02:08 00:00:52
--:--:-- --:--:-- 1
swp1 33.1.1.1 239.1.1.2 J 00:00:16 00:00:11
--:--:-- 00:03:26 1
root@rp:/home/cumulus#
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Ticket: CM-14700
Testing Done: pim-smoke
This is another follow-up change to the reg-state and up-join-state
separation. The upstream join state machine can now respond to
JoinDesired macro changes independent of router role.
I have also dropped the PRUNE state from the upstream-join-state
enumeration. RFC4601 only defines JOINED and NOTJOINED states. And PRUNE
can really be replace by NOTJOINED.
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Ticket: CM-14700
Testing Done: Register state machine in FHR only, combined FHR-RP and
FHR-RP-LHR/all-in-one setups. Also ran pim-smoke.
With the separation of register-state and upstream-join-state we no
longer need an enumeration that covers both states. This commit includes
the following -
1. Defined new enumeration for reg state (this 1:1 with RFC4601).
2. Dropped JOIN_PENDING enum value from upstream join state. RFC4601
only define two values NOT_JOINED and JOINED for this state.
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Ticket: CM-14700
Testing Done: Verified register setup manually and ran pim-smoke
On the FHR upstream-join-state is not particularly relevant as we
don't need to send upstream JPs for the SG. So that field was being
overloaded with the register-state. However some of the events that
triggered changes to the JoinDesired macro were accidentally overwriting
the state with join info (instead of treating it as register info)
confusing the register state machine.
To make the PIM RFC macros' implemention simple I have separated out
the register-state. And upstream->state now solely describes the
upstream-join-state independent of the role of the PIM router.
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Ticket: CM-14700
Testing Done: verified pim-register state-machine with separate and
combined FHR/RP routers. Also ran pim-smoke.
pimd/pim_sock.c:178:13: error: implicit conversion from
'int' to 'char' changes value from 148 to -108
[-Werror,-Wconstant-conversion]
ra[0] = 148;
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
(Note: the allow_delete thing is called "zebra" on the commandline
because that's the clearest context there, while it is called "FRR" in
the CLI because that's considerably less confusing in a vtysh env.)
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
There exists situations where we may have cleaned not
properly cleaned up the various J/P aggregation lists.
This commit fixes those issues.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Contains the fetch-and-run-thread logic, and vty startup (which is the
last thing happening before entering the main loop).
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Centralise read_config/daemonize/dryrun/pidfile/vty_serv into libfrr.
This also makes multi-instance pid/config handling available as part of
the library. It's only wired up in ospfd, but the code is in lib/.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Start centralising startup & option parsing into the library.
FRR_DAEMON_INFO is a bit weird, but it will become useful later (e.g.
for killing the ZLOG_* enum, and having the daemon name available)
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
The 'show ip pim state' command was not
working quite correctly from when
we moved over to the new vtysh-grammar.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Automatically turn on pim if the daemon is turned on.
Hide the 'ip multicast-routing' command
Disable the 'no ip multicast-routing' command
Do not display the 'ip multicast-routing' command.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When you enter these commands, under an interface:
ip igmp version ...
ip igmp query-interval ...
ip igmp query-max-response-time ...
ip igmp query-max-response-time-dsec ...
These commands will now just turn on igmp for the
interface.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Add the ability for PIM to send Join/Prunes as an
aggregated message instead of individual messages
for each S,G.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The static mroutes were making the assumption that the vif index
and the ifindex were the same. This is not necessarily the case.
Additionally if we are displaying a *,G route only display
the G.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When we receive a group in a IGMP report
let's look it up based upon a hash
instead of a list.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Suppose we have this
(*,G) IIF = swp1 OIL: swp3
(S,G) IIF = swp2 OIL: swp3 swp4
There exists situations where we can receive the mcast
packet for (S,G) on both swp1 and swp2. In this case
the packet received on swp1 will be sent from the kernel
to us as a WRVIF and WRVIFWHOLE.
As per normal, WRVIF packet processing handles the assert
case so we know we have not received the packet on a downstream
interface, so no assert.
The WRVIFWHOLE packet processing can then check to see if
it received the packet as a result of the (*,G) mroute
from upstream. If we have then we can safely drop
the packet.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When we are at scale, it is possible that
we have a very large number of ifchannels
per interface. So make lookup for
that situation to be a hash lookup.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When we are only looking at one ifchannel, for inheritance, narrow
the search down to only the interface/ifchannel we are interested in
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When we receive a igmp packet, there is no need
to ensure that it is a igmp packet, as that is
what we have asked for.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When we get a packet from the network for pim, we do not
need to check to see that it is a pim packet, since that
is what we've asked to receive.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When receiving a J/P packet, only check to see if we should
log when the J/P packet is not for us.
Very slight performance improvement additionally
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
pim_upstream_join_timer_decrease_to_t_override passed in
a `struct in_addr` that in all cases was part of the
upstream data structure that was passed in already.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Switch pim over to using packed data structures for building
Join/Prune messages to be sent.
This is a pre-cursor to the ability to handle the ability
to aggregate Join/Prune messages together.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
For:
pim_msg_build_header
pim_msg_addr_encode_ipv4_ucast
pim_msg_addr_encode_ipv4_group
pim_msg_addr_encode_ipv4_source
Assume that the buffer size passed in is of sufficient size
already. This is assured already because buffer sizes
are checked for minimum lengths for the entire packet
ahead of time. So we are double checking.
Additionally at scale we will be calling these functions
a very very large number of times.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Add the 'struct pim_msg_header' and convert
all places that encoded/decoded the message header
to use it.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Document the J/P packet format and ensure
that the smallest size packet that we
may send will actually fit.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Convert the const int size of the encoded
types to #defines so that they can be
used elsewhere.
Return Null instead of 0.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Ticket: CM-14652
Testing Done: Tested via sending IGMP report and flap port and verified pim upstream and mroute, the entry is deleted. Run pim-smoke
Even after Report received port down event, IGMP entry alawys exists in upstream, mroute, kernel.
The entry exist because it was recreated after delete due missing check if group has no more source list,
mode is exclude, last source address was * means (*, G) so do not trigger to create entry.
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Ticket:CM-14056
Reviewed By:sharpd, CCR-5603
Testing Done: verified multiple ifdown/ifup event on submitter setup and dev setup with 2k s,g entries, ran pim-smoke.
1. during ifdown event, pim vif for bridge was not resetting vif_index to -1 due to errno received from
kernel during vif del sequence. It could be timing issue where kernel may have delete prior to pimd sending request.
For vif_del even kernel returns error, reset vif_index to -1 in pimd DB so next if up event VIF receives new vif_index
and reprograms in kernel.
2. during mroute del sequence reset mfcc_parent to MAXVIF.
3. during mroute add check if parent mfcc_parent is MAXVIF then do not download to kernel such mroute entry.
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
Ticket:CM-12924
Reviewed By:shapd
Testing Done: configure PIM neighbor, verify PIM hello packet dump for ttl to be 1.
Set TTL to 1 for outgoing multicast control packets destine to ALL-PIM-ROUTERS as oppose to unicast mcast packets.
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
Ticket: CM-12041
Reviewed By: sharpd, CCR-5556
Testing Done: Tested on Local setup generating PIM Register (Data/Null) and processing both Tx/Rx with correct checksum.
Provided quagga debian to submitter and checksum cases passed on submitter setup.
1. PIM Register msg checksum only accounts for 8 bytes (4 bytes for PIM header and next 4 byetes before data payload).
In PIM header checksum calculation checked PIM packet type (in this case REGISTER type) then only pass 8 bytes as length
rather than full packet length.
2. PIM Register Rx path also handled with 8 byte and full pim lenth checksum.
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
Ticket: CM-13771
Reviewed By: CCR-5537
Testing Done: yes
Fix to CM-13771 where DBG message was out of order.
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
Cleanup the in_ifname and out_ifname buffers
to be large enough to hold the actual interface
names.
Additionally move the common variables to be defined
once, instead of inside of multiple for loops
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
In all cases pim_sock_open was called, we just passed
in the pim_ifp->primary_address, which is accessible
from the interface pointer. So just pass that in.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This fixes the issue a crash when we have configured an interface
inside of a vrf, and apply pim commands to it.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The library libzebra that is installed with FRR will
conflict with Quagga. So let's rename it to libfrr.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Fix broken switch statement that would
allow the case statement to fall through.
Fix possible buffer overwrite.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When on the RP we received a prune *,G for an established S,G
If join_desired is no longer true we need to prune and
reset some timers, in addition to removing the inherited
interface from the olist.
This was not happening because we were just removing
the inherited oif from the *,G.
Ticket: CM-14561
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Valgrind noticed that we have a read of uninitialized memory:
Conditional jump or move depends on uninitialised value(s)
==13749== at 0x428067: pim_ifassert_winner_set (pim_assert.c:57)
==13749== by 0x4266F0: pim_ifchannel_add (pim_ifchannel.c:535)
==13749== by 0x426CC1: pim_ifchannel_join_add (pim_ifchannel.c:730)
==13749== by 0x427B5B: recv_join (pim_join.c:95)
==13749== by 0x427B5B: pim_joinprune_recv (pim_join.c:270)
==13749== by 0x42354F: pim_pim_packet (pim_pim.c:249)
==13749== by 0x4236C0: pim_sock_read (pim_pim.c:349)
==13749== by 0x4E60587: thread_call (thread.c:1462)
==13749== by 0x40C75E: main (pim_main.c:266)
==13749==
This commit fixes that issue.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
We were creating the pimreg device with a
created ifindex of 255. This was causing
issues when a interface was assigned a ifindex
of 255 by the kernel. Subsuquently pim
would stay in a hosed up state.
Modify the ifindex used for the pimreg device
to be 0.
Ticket: CM-14625
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When we are creating the igmp ifchannel we were creating
it with both a P and a I flag. This was causing
it to not be cleaned up properly when the interface
was shut down. Subsuquently when the interface
came back up we would attempt to add it back in
but it would fail.
Ticket: CM-14586
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
PIM was handling vif creation deletion poorly
for interface down and up events. Fix this
issue by keeping track of which vif index'es
we have issued and allow the wholes to be
filled in.
Ticket: CM-14556
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit does these three things:
1) Add code to 'show ip pim state' to show where OIF's got their
decision to include that interface
2) Add code in pim_mroute_[add|del] to display what we think we are
adding to the kernel
3) Add code to properly track where we got the incoming request from and
to appropriately not remove a OIL if we have state still
Ticket: CM-14034
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Don Slice <dslice@cumulusnetworks.com>
Reviewed-by: Chirag Shah <chirag@cumulusnetworks.com>
Rename the qpim_zclient_update variable to zclient.
This is to follow the naming conventions in the rest
of the code.
Additionally move the struct zclient * pointer into pim_zebra.c
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Start the abstraction of the zclient data structure out from a
global variable for the entire program to a global variable
to the pim_zebra.c file.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>