David Lamparter [Wed, 22 Mar 2017 09:45:51 +0000 (10:45 +0100)]
lib: sandbox: print vtysh daemon targets
This is very useful to check whether a command disappeared from a
specific daemon (by comparing against an earlier output of
"grammar find-ambiguous printall nodescan")
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
David Lamparter [Wed, 22 Mar 2017 09:22:14 +0000 (10:22 +0100)]
vtysh: parsing fixes on distribute-list
The vtysh preprocessing stuff doesn't like the first argument to
install_element() being something other than a _NODE constant, and the
comment hack wasn't cutting it... just expand this.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
David Lamparter [Wed, 22 Mar 2017 09:38:22 +0000 (10:38 +0100)]
*: apply DEFUN_NOSH for node-switch CLI commands
These have copies in vtysh that do the node-switch locally and are
listed in extract.pl's ignore list. The ignore list however is
redundant since DEFUN_NOSH does the same thing...
ldpd is a bit hacky, but Renato is reworking this anyway.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Renato Westphal [Tue, 28 Mar 2017 00:39:27 +0000 (21:39 -0300)]
doc: minor tweaks in the build instructions
* ldpd is built by default in all platforms, it's not necessary to
provide --enable-ldpd anymore;
* Remove comment about ldpd not being tested on OpenBSD, it works very
well on this platform;
* Provide instructions to enable MPLS forwarding in OpenBSD.
Renato Westphal [Mon, 27 Mar 2017 23:14:09 +0000 (20:14 -0300)]
ldpd: replace all occurrences of '\n' with VTY_NEWLINE
The format of the terse output of several ldpd's show commands was copied
from the OpenBSD's ldpctl(8) control program. In the process of doing
that I forgot to replace the occurrences of '\n' with VTY_NEWLINE.
Renato Westphal [Sat, 25 Mar 2017 23:57:03 +0000 (20:57 -0300)]
ldpd: fix pseudowire merge algorithm
The previous algorithm wasn't failsafe for full configuration reloads
where several pseudowires can be inserted or removed at the same
time. This patch introduces a much simpler logic that solves the problem
in a better way.
Renato Westphal [Sat, 25 Mar 2017 23:52:42 +0000 (20:52 -0300)]
ldpd: remove a few unnecessary functions
The original ldpd(8) daemon in OpenBSD doesn't allow the user to put
non-existing interfaces in the configuration file. For this reason,
the l2vpn_if_find() and l2vpn_pw_find() functions take an ifindex as
an argument. In FRR's ldpd we can put non-existing interfaces in the
configuration, and they are activated as soon as they are available. For
this reason, we can't lookup interfaces by their ifindex in this port.
The l2vpn_if_find_name() and l2vpn_pw_find_name() functions were
introduced to address this issue. However, since the "find-by-ifindex"
functions are not being used anymore, we can just remove them and rename
the *_find_name() functions removing the "_name" suffix.
Renato Westphal [Wed, 22 Mar 2017 15:53:36 +0000 (12:53 -0300)]
ldpd: do a full configuration reload upon receiving a SIGHUP
The rationale here is to do something very similar to what the original
OpenBSD's ldpd(8) does to reload configuration files:
* create a new empty base configuration (vty_conf);
* parse the configuration file and store the result in vty_conf;
* merge the new configuration into the current configuration.
To do this, introduce a new global variable called "sighup" so that ldpd
doesn't attempt to merge vty_conf into ldpd_conf for each command in
the configuration file, which would be very disruptive. vty_conf should
be merged only after the whole configuration file is parsed in order to
avoid taking actions like shutting down neighbors when not necessary.
Renato Westphal [Sun, 26 Mar 2017 00:28:13 +0000 (21:28 -0300)]
ldpd: ignore the SIGHUP signal in the child processes
Only the parent process should handle the SIGHUP signal, but we need
to make sure that this signal is ignored in the child processes so a
command like "killall -SIGHUP ldpd" won't kill ldpd.
Renato Westphal [Thu, 23 Mar 2017 17:49:28 +0000 (14:49 -0300)]
ldpd: simplify handling of configuration commands
The logic to make configuration changes in ldpd is as follows:
1 - duplicate the current configuration;
2 - modify the duplicated configuration (delta);
3 - merge the duplicated configuration into the current configuration.
We can however change things a little bit in order to simplify the code.
If we provide a global vty_conf variable and make sure that it's
always an up-to-date duplicate of ldpd_conf, then we don't need to call
ldp_dup_config() in the callback of each configuration command. Instead
of that, we just need to duplicate ldpd_conf in the startup of the daemon
and in the end of the ldp_reload() function. Doing this is safe because,
due to the single-threaded nature of the parent process, it's impossible
to have multiple requests to change the configuration at the same time.
Also, we can remove the *_ref() functions and do something much simpler
instead. The problem we have to deal with here is that VTY_GET_CONTEXT()
returns a pointer to an element of ldpd_conf, and what we want is a
pointer to an element of vty_conf (e.g. an l2vpn). To solve this,
we just need to look for the equivalent element inside vty_conf using
standard functions from ldpd like l2vpn_find() and others.
Renato Westphal [Wed, 22 Mar 2017 19:23:46 +0000 (16:23 -0300)]
ldpd: drop privileges earlier in the parent process
This solves a bug where log files created with "log file" were being
created root-owned. So, inserting the "log file" command multiple times
with the same path would fail giving a permission denied error.
Also, rearrange the main() function to call start_child() as soon as
possible to avoid a bunch of unnecessary initializations in the forked
processes.
anuradhak [Tue, 21 Mar 2017 17:12:30 +0000 (10:12 -0700)]
pimd: Remove interface type SSM.
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.
anuradhak [Fri, 17 Mar 2017 18:51:13 +0000 (11:51 -0700)]
pimd: Allow SSM groups to co-exist with ASM groups.
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.
Renato Westphal [Sat, 18 Mar 2017 20:05:35 +0000 (17:05 -0300)]
ldpd: change the sorting algorithm of adjacencies
Now the "show mpls ldp discovery" command will display all LDP
adjancencies sorted by address family, neighbor ID and then type (link
or targeted).
Example:
vtysh# show mpls ldp discovery
AF ID Type Source Holdtime
ipv4 3.3.3.3 Link rt2-eth1 15
ipv4 3.3.3.3 Link rt2-eth2 15
ipv4 4.4.4.4 Link rt2-eth1 15
ipv6 1.1.1.1 Link rt2-eth0 15
ipv6 3.3.3.3 Link rt2-eth1 15
ipv6 3.3.3.3 Link rt2-eth2 15
ipv6 4.4.4.4 Link rt2-eth1 15
ßingen [Mon, 20 Mar 2017 14:34:49 +0000 (15:34 +0100)]
Implement generic label manager
Label Manager allows to share MPLS label space among different
daemons. Each daemon can request a chunk of consecutive labels and
release it if it doesn't need them anymore. Label Manager stores the
daemon protocol and instance to identify the owner client. It uses them
to perform garbage collection, releasing all label chunks from a client
when it gets disconnected or reconnected.
Additionally, every client can request that the chunk is never garbage
collected. In that case client has the responsibility to release
non-used labels.
Zebra can host the label manager itself (if no -l param is provided) or
connect to an external one using zserv/zclient (providing its address
with -l param).
Client code is in lib/zclient.c, but currently only LDP is using it.
TODO: Allow for custom ranges requests, i.e., specify the start label
besides the chunk.
TODO: Release labels from LDP.
Renato Westphal [Fri, 17 Mar 2017 18:41:04 +0000 (15:41 -0300)]
ldpd: remove pseudowire LSP check
In order to bring a pseudowire up, we must make sure that there's at
least one LSP available to its remote end (otherwise the labeled frames
from the CEs wouldn't reach their destination). We were doing this
check in ldpd, but doing so is very limiting because it doesn't consider
other types of LSPs that might be available (static LSPs, RSVP-TE, SR,
etc). Thus remove this check from the l2vpn_pw_ok() function. Later
on we'll implement a pseudowire manager in zebra which will solve this
problem in a much better way (including notifying ldpd about failures
to install a pseudowire in the kernel/hardware).
Donald Sharp [Thu, 16 Mar 2017 15:15:32 +0000 (11:15 -0400)]
pimd: Consider interface change a RPF_CHANGED event
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>
Donald Sharp [Fri, 10 Mar 2017 15:26:00 +0000 (10:26 -0500)]
pimd: Carefully Reconstruct FHR state when interface bounces
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>
Chirag Shah [Wed, 22 Feb 2017 15:28:36 +0000 (07:28 -0800)]
pimd: Nexthop tracking support
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>
anuradhak [Thu, 9 Mar 2017 19:42:55 +0000 (11:42 -0800)]
pimd: display reg-state and join-state info in the pim_upstream output
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#
anuradhak [Thu, 9 Mar 2017 18:47:50 +0000 (10:47 -0800)]
pimd: simplify pim upstream state transitions
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.
anuradhak [Thu, 9 Mar 2017 17:52:59 +0000 (09:52 -0800)]
pimd: add new/distinct enumeration for pim register state
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
anuradhak [Wed, 8 Mar 2017 17:29:40 +0000 (09:29 -0800)]
pimd: Separate the register and upstream join states on the FHR
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.
Donald Sharp [Fri, 10 Mar 2017 00:37:23 +0000 (19:37 -0500)]
zebra: Fix specific prefix handling
Suppose we are handling the process_workq and either a new static
route is installed or a Routing Protocol installs a new route.
We will call evaluate_rnh with a specific prefix. We might
have a situation where we clear the NHC flag prematurely.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>