2015-02-04 07:01:14 +01:00
|
|
|
/*
|
2017-05-13 10:25:29 +02:00
|
|
|
* PIM for Quagga
|
|
|
|
* Copyright (C) 2008 Everton da Silva Marques
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; see the file COPYING; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
2015-02-04 07:01:14 +01:00
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
2016-09-14 17:12:13 +02:00
|
|
|
#include "lib/json.h"
|
2015-02-04 07:01:14 +01:00
|
|
|
#include "command.h"
|
|
|
|
#include "if.h"
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "zclient.h"
|
2016-09-13 21:41:33 +02:00
|
|
|
#include "plist.h"
|
pimd: Pim Nexthop Tracking support with ECMP
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>
2017-04-05 22:14:12 +02:00
|
|
|
#include "hash.h"
|
|
|
|
#include "nexthop.h"
|
2017-05-23 00:14:43 +02:00
|
|
|
#include "vrf.h"
|
2015-02-04 07:01:14 +01:00
|
|
|
|
|
|
|
#include "pimd.h"
|
2016-07-12 21:09:25 +02:00
|
|
|
#include "pim_mroute.h"
|
2015-02-04 07:01:14 +01:00
|
|
|
#include "pim_cmd.h"
|
|
|
|
#include "pim_iface.h"
|
|
|
|
#include "pim_vty.h"
|
|
|
|
#include "pim_mroute.h"
|
|
|
|
#include "pim_str.h"
|
|
|
|
#include "pim_igmp.h"
|
|
|
|
#include "pim_igmpv3.h"
|
|
|
|
#include "pim_sock.h"
|
|
|
|
#include "pim_time.h"
|
|
|
|
#include "pim_util.h"
|
|
|
|
#include "pim_oil.h"
|
|
|
|
#include "pim_neighbor.h"
|
|
|
|
#include "pim_pim.h"
|
|
|
|
#include "pim_ifchannel.h"
|
|
|
|
#include "pim_hello.h"
|
|
|
|
#include "pim_msg.h"
|
|
|
|
#include "pim_upstream.h"
|
|
|
|
#include "pim_rpf.h"
|
|
|
|
#include "pim_macro.h"
|
|
|
|
#include "pim_ssmpingd.h"
|
|
|
|
#include "pim_zebra.h"
|
2015-06-12 01:29:02 +02:00
|
|
|
#include "pim_static.h"
|
2016-06-22 22:39:31 +02:00
|
|
|
#include "pim_rp.h"
|
2016-08-09 21:04:23 +02:00
|
|
|
#include "pim_zlookup.h"
|
2016-10-25 19:59:48 +02:00
|
|
|
#include "pim_msdp.h"
|
2017-03-17 19:51:13 +01:00
|
|
|
#include "pim_ssm.h"
|
pimd: Pim Nexthop Tracking support with ECMP
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>
2017-04-05 22:14:12 +02:00
|
|
|
#include "pim_nht.h"
|
2017-04-11 03:01:53 +02:00
|
|
|
#include "pim_bfd.h"
|
|
|
|
#include "bfd.h"
|
2015-02-04 07:01:14 +01:00
|
|
|
|
|
|
|
static struct cmd_node pim_global_node = {
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_NODE, "", 1 /* vtysh ? yes */
|
2015-02-04 07:01:14 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
static struct cmd_node interface_node = {
|
2017-07-17 14:03:14 +02:00
|
|
|
INTERFACE_NODE, "%s(config-if)# ", 1 /* vtysh ? yes */
|
2015-02-04 07:01:14 +01:00
|
|
|
};
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
static struct cmd_node debug_node = {DEBUG_NODE, "", 1};
|
2016-10-18 02:10:12 +02:00
|
|
|
|
2017-05-23 00:14:43 +02:00
|
|
|
static struct vrf *pim_cmd_lookup_vrf(struct vty *vty, struct cmd_token *argv[],
|
|
|
|
const int argc, int *idx)
|
|
|
|
{
|
|
|
|
struct vrf *vrf;
|
|
|
|
|
|
|
|
if (argv_find(argv, argc, "NAME", idx))
|
|
|
|
vrf = vrf_lookup_by_name(argv[*idx]->arg);
|
|
|
|
else
|
|
|
|
vrf = vrf_lookup_by_id(VRF_DEFAULT);
|
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
vty_out(vty, "Specified VRF: %s does not exist\n",
|
|
|
|
argv[*idx]->arg);
|
|
|
|
|
|
|
|
return vrf;
|
|
|
|
}
|
|
|
|
|
2015-02-04 07:01:14 +01:00
|
|
|
static void pim_if_membership_clear(struct interface *ifp)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct pim_interface *pim_ifp;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_ifp = ifp->info;
|
|
|
|
zassert(pim_ifp);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (PIM_IF_TEST_PIM(pim_ifp->options)
|
|
|
|
&& PIM_IF_TEST_IGMP(pim_ifp->options)) {
|
|
|
|
return;
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_ifchannel_membership_clear(ifp);
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
When PIM is disabled on interface, IGMPv3 local membership
|
|
|
|
information is not injected into PIM interface state.
|
|
|
|
|
|
|
|
The function pim_if_membership_refresh() fetches all IGMPv3 local
|
|
|
|
membership information into PIM. It is intented to be called
|
|
|
|
whenever PIM is enabled on the interface in order to collect missed
|
|
|
|
local membership information.
|
|
|
|
*/
|
|
|
|
static void pim_if_membership_refresh(struct interface *ifp)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
struct listnode *sock_node;
|
|
|
|
struct igmp_sock *igmp;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_ifp = ifp->info;
|
|
|
|
zassert(pim_ifp);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!PIM_IF_TEST_PIM(pim_ifp->options))
|
|
|
|
return;
|
|
|
|
if (!PIM_IF_TEST_IGMP(pim_ifp->options))
|
|
|
|
return;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
/*
|
|
|
|
First clear off membership from all PIM (S,G) entries on the
|
|
|
|
interface
|
|
|
|
*/
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_ifchannel_membership_clear(ifp);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
/*
|
|
|
|
Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
|
|
|
|
the interface
|
|
|
|
*/
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
/* scan igmp sockets */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
|
|
|
|
struct listnode *grpnode;
|
|
|
|
struct igmp_group *grp;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
/* scan igmp groups */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode,
|
|
|
|
grp)) {
|
|
|
|
struct listnode *srcnode;
|
|
|
|
struct igmp_source *src;
|
2016-07-23 05:42:11 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
/* scan group sources */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
|
|
|
|
srcnode, src)) {
|
|
|
|
|
|
|
|
if (IGMP_SOURCE_TEST_FORWARDING(
|
|
|
|
src->source_flags)) {
|
|
|
|
struct prefix_sg sg;
|
|
|
|
|
|
|
|
memset(&sg, 0,
|
|
|
|
sizeof(struct prefix_sg));
|
|
|
|
sg.src = src->source_addr;
|
|
|
|
sg.grp = grp->group_addr;
|
|
|
|
pim_ifchannel_local_membership_add(ifp,
|
|
|
|
&sg);
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
} /* scan group sources */
|
|
|
|
} /* scan igmp groups */
|
|
|
|
} /* scan igmp sockets */
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
/*
|
|
|
|
Finally delete every PIM (S,G) entry lacking all state info
|
|
|
|
*/
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_ifchannel_delete_on_noinfo(ifp);
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void pim_show_assert(struct vty *vty, struct pim_instance *pim)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
struct pim_ifchannel *ch;
|
|
|
|
struct listnode *ch_node;
|
|
|
|
struct in_addr ifaddr;
|
|
|
|
time_t now;
|
|
|
|
|
|
|
|
now = pim_time_monotonic_sec();
|
|
|
|
|
|
|
|
vty_out(vty,
|
|
|
|
"Interface Address Source Group State Winner Uptime Timer\n");
|
|
|
|
|
2017-05-20 20:17:48 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->ifchannel_list, ch_node, ch)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
char ch_src_str[INET_ADDRSTRLEN];
|
|
|
|
char ch_grp_str[INET_ADDRSTRLEN];
|
|
|
|
char winner_str[INET_ADDRSTRLEN];
|
|
|
|
char uptime[10];
|
|
|
|
char timer[10];
|
|
|
|
|
|
|
|
pim_ifp = ch->interface->info;
|
|
|
|
|
|
|
|
if (!pim_ifp)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
ifaddr = pim_ifp->primary_address;
|
|
|
|
|
|
|
|
pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str,
|
|
|
|
sizeof(ch_src_str));
|
|
|
|
pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str,
|
|
|
|
sizeof(ch_grp_str));
|
|
|
|
pim_inet4_dump("<assrt_win?>", ch->ifassert_winner, winner_str,
|
|
|
|
sizeof(winner_str));
|
|
|
|
|
|
|
|
pim_time_uptime(uptime, sizeof(uptime),
|
|
|
|
now - ch->ifassert_creation);
|
|
|
|
pim_time_timer_to_mmss(timer, sizeof(timer),
|
|
|
|
ch->t_ifassert_timer);
|
|
|
|
|
|
|
|
vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
|
|
|
|
ch->interface->name, inet_ntoa(ifaddr), ch_src_str,
|
|
|
|
ch_grp_str,
|
|
|
|
pim_ifchannel_ifassert_name(ch->ifassert_state),
|
|
|
|
winner_str, uptime, timer);
|
|
|
|
} /* scan interface channels */
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void pim_show_assert_internal(struct vty *vty, struct pim_instance *pim)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
struct listnode *ch_node;
|
|
|
|
struct pim_ifchannel *ch;
|
|
|
|
struct in_addr ifaddr;
|
|
|
|
|
|
|
|
vty_out(vty,
|
|
|
|
"CA: CouldAssert\n"
|
|
|
|
"ECA: Evaluate CouldAssert\n"
|
|
|
|
"ATD: AssertTrackingDesired\n"
|
|
|
|
"eATD: Evaluate AssertTrackingDesired\n\n");
|
|
|
|
|
|
|
|
vty_out(vty,
|
|
|
|
"Interface Address Source Group CA eCA ATD eATD\n");
|
|
|
|
|
2017-05-20 20:17:48 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->ifchannel_list, ch_node, ch)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_ifp = ch->interface->info;
|
|
|
|
|
|
|
|
if (!pim_ifp)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
ifaddr = pim_ifp->primary_address;
|
|
|
|
|
|
|
|
char ch_src_str[INET_ADDRSTRLEN];
|
|
|
|
char ch_grp_str[INET_ADDRSTRLEN];
|
|
|
|
|
|
|
|
pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str,
|
|
|
|
sizeof(ch_src_str));
|
|
|
|
pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str,
|
|
|
|
sizeof(ch_grp_str));
|
|
|
|
vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
|
|
|
|
ch->interface->name, inet_ntoa(ifaddr), ch_src_str,
|
|
|
|
ch_grp_str,
|
|
|
|
PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
|
|
|
|
pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
|
|
|
|
PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags)
|
|
|
|
? "yes"
|
|
|
|
: "no",
|
|
|
|
pim_macro_assert_tracking_desired_eval(ch) ? "yes"
|
|
|
|
: "no");
|
|
|
|
} /* scan interface channels */
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void pim_show_assert_metric(struct vty *vty, struct pim_instance *pim)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
struct listnode *ch_node;
|
|
|
|
struct pim_ifchannel *ch;
|
|
|
|
struct in_addr ifaddr;
|
2016-11-07 18:34:44 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty,
|
|
|
|
"Interface Address Source Group RPT Pref Metric Address \n");
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-05-20 20:17:48 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->ifchannel_list, ch_node, ch)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_ifp = ch->interface->info;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!pim_ifp)
|
|
|
|
continue;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
ifaddr = pim_ifp->primary_address;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
char ch_src_str[INET_ADDRSTRLEN];
|
|
|
|
char ch_grp_str[INET_ADDRSTRLEN];
|
|
|
|
char addr_str[INET_ADDRSTRLEN];
|
|
|
|
struct pim_assert_metric am;
|
2016-11-07 18:34:44 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
am = pim_macro_spt_assert_metric(&ch->upstream->rpf,
|
|
|
|
pim_ifp->primary_address);
|
2016-11-07 18:34:44 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str,
|
|
|
|
sizeof(ch_src_str));
|
|
|
|
pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str,
|
|
|
|
sizeof(ch_grp_str));
|
|
|
|
pim_inet4_dump("<addr?>", am.ip_address, addr_str,
|
|
|
|
sizeof(addr_str));
|
2016-11-07 18:34:44 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
|
|
|
|
ch->interface->name, inet_ntoa(ifaddr), ch_src_str,
|
|
|
|
ch_grp_str, am.rpt_bit_flag ? "yes" : "no",
|
|
|
|
am.metric_preference, am.route_metric, addr_str);
|
|
|
|
} /* scan interface channels */
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void pim_show_assert_winner_metric(struct vty *vty,
|
|
|
|
struct pim_instance *pim)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
struct listnode *ch_node;
|
|
|
|
struct pim_ifchannel *ch;
|
|
|
|
struct in_addr ifaddr;
|
|
|
|
|
|
|
|
vty_out(vty,
|
|
|
|
"Interface Address Source Group RPT Pref Metric Address \n");
|
|
|
|
|
2017-05-20 20:17:48 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->ifchannel_list, ch_node, ch)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_ifp = ch->interface->info;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!pim_ifp)
|
|
|
|
continue;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
ifaddr = pim_ifp->primary_address;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
char ch_src_str[INET_ADDRSTRLEN];
|
|
|
|
char ch_grp_str[INET_ADDRSTRLEN];
|
|
|
|
char addr_str[INET_ADDRSTRLEN];
|
|
|
|
struct pim_assert_metric *am;
|
|
|
|
char pref_str[5];
|
|
|
|
char metr_str[7];
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
am = &ch->ifassert_winner_metric;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str,
|
|
|
|
sizeof(ch_src_str));
|
|
|
|
pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str,
|
|
|
|
sizeof(ch_grp_str));
|
|
|
|
pim_inet4_dump("<addr?>", am->ip_address, addr_str,
|
|
|
|
sizeof(addr_str));
|
2016-11-07 18:34:44 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (am->metric_preference == PIM_ASSERT_METRIC_PREFERENCE_MAX)
|
|
|
|
snprintf(pref_str, sizeof(pref_str), "INFI");
|
|
|
|
else
|
|
|
|
snprintf(pref_str, sizeof(pref_str), "%4u",
|
|
|
|
am->metric_preference);
|
2016-11-07 18:34:44 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (am->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX)
|
|
|
|
snprintf(metr_str, sizeof(metr_str), "INFI");
|
|
|
|
else
|
|
|
|
snprintf(metr_str, sizeof(metr_str), "%6u",
|
|
|
|
am->route_metric);
|
2016-11-07 18:34:44 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
|
|
|
|
ch->interface->name, inet_ntoa(ifaddr), ch_src_str,
|
|
|
|
ch_grp_str, am->rpt_bit_flag ? "yes" : "no", pref_str,
|
|
|
|
metr_str, addr_str);
|
|
|
|
} /* scan interface channels */
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
static void json_object_pim_ifp_add(struct json_object *json,
|
|
|
|
struct interface *ifp)
|
2016-09-17 04:22:02 +02:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct pim_interface *pim_ifp;
|
2016-09-17 04:22:02 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_ifp = ifp->info;
|
|
|
|
json_object_string_add(json, "name", ifp->name);
|
|
|
|
json_object_string_add(json, "state", if_is_up(ifp) ? "up" : "down");
|
|
|
|
json_object_string_add(json, "address",
|
|
|
|
inet_ntoa(pim_ifp->primary_address));
|
|
|
|
json_object_int_add(json, "index", ifp->ifindex);
|
2016-09-17 04:22:02 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (if_is_multicast(ifp))
|
|
|
|
json_object_boolean_true_add(json, "flagMulticast");
|
2016-09-17 04:22:02 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (if_is_broadcast(ifp))
|
|
|
|
json_object_boolean_true_add(json, "flagBroadcast");
|
2016-09-17 04:22:02 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (ifp->flags & IFF_ALLMULTI)
|
|
|
|
json_object_boolean_true_add(json, "flagAllMulticast");
|
2016-09-17 04:22:02 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (ifp->flags & IFF_PROMISC)
|
|
|
|
json_object_boolean_true_add(json, "flagPromiscuous");
|
2016-09-17 04:22:02 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (PIM_IF_IS_DELETED(ifp))
|
|
|
|
json_object_boolean_true_add(json, "flagDeleted");
|
2016-09-17 04:22:02 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (pim_if_lan_delay_enabled(ifp))
|
|
|
|
json_object_boolean_true_add(json, "lanDelayEnabled");
|
2016-09-17 04:22:02 +02:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void pim_show_membership(struct vty *vty, struct pim_instance *pim,
|
2017-05-20 20:17:48 +02:00
|
|
|
u_char uj)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
struct listnode *ch_node;
|
|
|
|
struct pim_ifchannel *ch;
|
|
|
|
enum json_type type;
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_iface = NULL;
|
|
|
|
json_object *json_row = NULL;
|
|
|
|
json_object *json_tmp = NULL;
|
|
|
|
|
|
|
|
json = json_object_new_object();
|
|
|
|
|
2017-05-20 20:17:48 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->ifchannel_list, ch_node, ch)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
pim_ifp = ch->interface->info;
|
|
|
|
|
|
|
|
if (!pim_ifp)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
char ch_src_str[INET_ADDRSTRLEN];
|
|
|
|
char ch_grp_str[INET_ADDRSTRLEN];
|
|
|
|
|
|
|
|
pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str,
|
|
|
|
sizeof(ch_src_str));
|
|
|
|
pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str,
|
|
|
|
sizeof(ch_grp_str));
|
|
|
|
|
|
|
|
json_object_object_get_ex(json, ch->interface->name,
|
|
|
|
&json_iface);
|
|
|
|
|
|
|
|
if (!json_iface) {
|
|
|
|
json_iface = json_object_new_object();
|
|
|
|
json_object_pim_ifp_add(json_iface, ch->interface);
|
|
|
|
json_object_object_add(json, ch->interface->name,
|
|
|
|
json_iface);
|
|
|
|
}
|
|
|
|
|
|
|
|
json_row = json_object_new_object();
|
|
|
|
json_object_string_add(json_row, "source", ch_src_str);
|
|
|
|
json_object_string_add(json_row, "group", ch_grp_str);
|
|
|
|
json_object_string_add(
|
|
|
|
json_row, "localMembership",
|
|
|
|
ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO
|
|
|
|
? "NOINFO"
|
|
|
|
: "INCLUDE");
|
|
|
|
json_object_object_add(json_iface, ch_grp_str, json_row);
|
|
|
|
} /* scan interface channels */
|
|
|
|
|
|
|
|
if (uj) {
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
} else {
|
|
|
|
vty_out(vty,
|
|
|
|
"Interface Address Source Group Membership\n");
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Example of the json data we are traversing
|
|
|
|
*
|
|
|
|
* {
|
|
|
|
* "swp3":{
|
|
|
|
* "name":"swp3",
|
|
|
|
* "state":"up",
|
|
|
|
* "address":"10.1.20.1",
|
|
|
|
* "index":5,
|
|
|
|
* "flagMulticast":true,
|
|
|
|
* "flagBroadcast":true,
|
|
|
|
* "lanDelayEnabled":true,
|
|
|
|
* "226.10.10.10":{
|
|
|
|
* "source":"*",
|
|
|
|
* "group":"226.10.10.10",
|
|
|
|
* "localMembership":"INCLUDE"
|
|
|
|
* }
|
|
|
|
* }
|
|
|
|
* }
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* foreach interface */
|
|
|
|
json_object_object_foreach(json, key, val)
|
|
|
|
{
|
|
|
|
|
|
|
|
/* Find all of the keys where the val is an object. In
|
|
|
|
* the example
|
|
|
|
* above the only one is 226.10.10.10
|
|
|
|
*/
|
|
|
|
json_object_object_foreach(val, if_field_key,
|
|
|
|
if_field_val)
|
|
|
|
{
|
|
|
|
type = json_object_get_type(if_field_val);
|
|
|
|
|
|
|
|
if (type == json_type_object) {
|
|
|
|
vty_out(vty, "%-9s ", key);
|
|
|
|
|
|
|
|
json_object_object_get_ex(
|
|
|
|
val, "address", &json_tmp);
|
|
|
|
vty_out(vty, "%-15s ",
|
|
|
|
json_object_get_string(
|
|
|
|
json_tmp));
|
|
|
|
|
|
|
|
json_object_object_get_ex(if_field_val,
|
|
|
|
"source",
|
|
|
|
&json_tmp);
|
|
|
|
vty_out(vty, "%-15s ",
|
|
|
|
json_object_get_string(
|
|
|
|
json_tmp));
|
|
|
|
|
|
|
|
/* Group */
|
|
|
|
vty_out(vty, "%-15s ", if_field_key);
|
|
|
|
|
|
|
|
json_object_object_get_ex(
|
|
|
|
if_field_val, "localMembership",
|
|
|
|
&json_tmp);
|
|
|
|
vty_out(vty, "%-10s\n",
|
|
|
|
json_object_get_string(
|
|
|
|
json_tmp));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
json_object_free(json);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void pim_print_ifp_flags(struct vty *vty, struct interface *ifp,
|
|
|
|
int mloop)
|
|
|
|
{
|
|
|
|
vty_out(vty, "Flags\n");
|
|
|
|
vty_out(vty, "-----\n");
|
|
|
|
vty_out(vty, "All Multicast : %s\n",
|
|
|
|
(ifp->flags & IFF_ALLMULTI) ? "yes" : "no");
|
|
|
|
vty_out(vty, "Broadcast : %s\n",
|
|
|
|
if_is_broadcast(ifp) ? "yes" : "no");
|
|
|
|
vty_out(vty, "Deleted : %s\n",
|
|
|
|
PIM_IF_IS_DELETED(ifp) ? "yes" : "no");
|
|
|
|
vty_out(vty, "Interface Index : %d\n", ifp->ifindex);
|
|
|
|
vty_out(vty, "Multicast : %s\n",
|
|
|
|
if_is_multicast(ifp) ? "yes" : "no");
|
|
|
|
vty_out(vty, "Multicast Loop : %d\n", mloop);
|
|
|
|
vty_out(vty, "Promiscuous : %s\n",
|
|
|
|
(ifp->flags & IFF_PROMISC) ? "yes" : "no");
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
vty_out(vty, "\n");
|
2016-09-15 19:16:36 +02:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void igmp_show_interfaces(struct vty *vty, struct pim_instance *pim,
|
|
|
|
u_char uj)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *node;
|
|
|
|
struct interface *ifp;
|
|
|
|
time_t now;
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_row = NULL;
|
|
|
|
|
|
|
|
now = pim_time_monotonic_sec();
|
|
|
|
|
|
|
|
if (uj)
|
|
|
|
json = json_object_new_object();
|
|
|
|
else
|
|
|
|
vty_out(vty,
|
|
|
|
"Interface State Address V Querier Query Timer Uptime\n");
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
struct listnode *sock_node;
|
|
|
|
struct igmp_sock *igmp;
|
|
|
|
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
|
|
|
|
if (!pim_ifp)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
|
|
|
|
igmp)) {
|
|
|
|
char uptime[10];
|
|
|
|
char query_hhmmss[10];
|
|
|
|
|
|
|
|
pim_time_uptime(uptime, sizeof(uptime),
|
|
|
|
now - igmp->sock_creation);
|
|
|
|
pim_time_timer_to_hhmmss(query_hhmmss,
|
|
|
|
sizeof(query_hhmmss),
|
|
|
|
igmp->t_igmp_query_timer);
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json_row = json_object_new_object();
|
|
|
|
json_object_pim_ifp_add(json_row, ifp);
|
|
|
|
json_object_string_add(json_row, "upTime",
|
|
|
|
uptime);
|
|
|
|
json_object_int_add(json_row, "version",
|
|
|
|
pim_ifp->igmp_version);
|
|
|
|
|
|
|
|
if (igmp->t_igmp_query_timer) {
|
|
|
|
json_object_boolean_true_add(json_row,
|
|
|
|
"querier");
|
|
|
|
json_object_string_add(json_row,
|
|
|
|
"queryTimer",
|
|
|
|
query_hhmmss);
|
|
|
|
}
|
|
|
|
|
|
|
|
json_object_object_add(json, ifp->name,
|
|
|
|
json_row);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
vty_out(vty,
|
|
|
|
"%-9s %5s %15s %d %7s %11s %8s\n",
|
|
|
|
ifp->name,
|
|
|
|
if_is_up(ifp) ? "up" : "down",
|
|
|
|
inet_ntoa(igmp->ifaddr),
|
|
|
|
pim_ifp->igmp_version,
|
|
|
|
igmp->t_igmp_query_timer ? "local"
|
|
|
|
: "other",
|
|
|
|
query_hhmmss, uptime);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uj) {
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void igmp_show_interfaces_single(struct vty *vty,
|
|
|
|
struct pim_instance *pim,
|
|
|
|
const char *ifname, u_char uj)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
|
|
|
struct igmp_sock *igmp;
|
|
|
|
struct interface *ifp;
|
|
|
|
struct listnode *node;
|
|
|
|
struct listnode *sock_node;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
char uptime[10];
|
|
|
|
char query_hhmmss[10];
|
|
|
|
char other_hhmmss[10];
|
|
|
|
int found_ifname = 0;
|
|
|
|
int sqi;
|
2017-06-22 21:09:02 +02:00
|
|
|
int mloop = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
long gmi_msec; /* Group Membership Interval */
|
|
|
|
long lmqt_msec;
|
|
|
|
long ohpi_msec;
|
|
|
|
long oqpi_msec; /* Other Querier Present Interval */
|
|
|
|
long qri_msec;
|
|
|
|
time_t now;
|
|
|
|
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_row = NULL;
|
|
|
|
|
|
|
|
if (uj)
|
|
|
|
json = json_object_new_object();
|
|
|
|
|
|
|
|
now = pim_time_monotonic_sec();
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_ifp = ifp->info;
|
|
|
|
|
|
|
|
if (!pim_ifp)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
|
|
|
|
igmp)) {
|
|
|
|
found_ifname = 1;
|
|
|
|
pim_time_uptime(uptime, sizeof(uptime),
|
|
|
|
now - igmp->sock_creation);
|
|
|
|
pim_time_timer_to_hhmmss(query_hhmmss,
|
|
|
|
sizeof(query_hhmmss),
|
|
|
|
igmp->t_igmp_query_timer);
|
|
|
|
pim_time_timer_to_hhmmss(other_hhmmss,
|
|
|
|
sizeof(other_hhmmss),
|
|
|
|
igmp->t_other_querier_timer);
|
|
|
|
|
|
|
|
gmi_msec = PIM_IGMP_GMI_MSEC(
|
|
|
|
igmp->querier_robustness_variable,
|
|
|
|
igmp->querier_query_interval,
|
|
|
|
pim_ifp->igmp_query_max_response_time_dsec);
|
|
|
|
|
|
|
|
sqi = PIM_IGMP_SQI(
|
|
|
|
pim_ifp->igmp_default_query_interval);
|
|
|
|
|
|
|
|
oqpi_msec = PIM_IGMP_OQPI_MSEC(
|
|
|
|
igmp->querier_robustness_variable,
|
|
|
|
igmp->querier_query_interval,
|
|
|
|
pim_ifp->igmp_query_max_response_time_dsec);
|
|
|
|
|
|
|
|
lmqt_msec = PIM_IGMP_LMQT_MSEC(
|
|
|
|
pim_ifp->igmp_query_max_response_time_dsec,
|
|
|
|
igmp->querier_robustness_variable);
|
|
|
|
|
|
|
|
ohpi_msec =
|
|
|
|
PIM_IGMP_OHPI_DSEC(
|
|
|
|
igmp->querier_robustness_variable,
|
|
|
|
igmp->querier_query_interval,
|
|
|
|
pim_ifp->igmp_query_max_response_time_dsec)
|
|
|
|
* 100;
|
|
|
|
|
|
|
|
qri_msec = pim_ifp->igmp_query_max_response_time_dsec
|
|
|
|
* 100;
|
2017-06-22 21:09:02 +02:00
|
|
|
if (pim_ifp->pim_sock_fd >= 0)
|
|
|
|
mloop = pim_socket_mcastloop_get(
|
|
|
|
pim_ifp->pim_sock_fd);
|
|
|
|
else
|
|
|
|
mloop = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json_row = json_object_new_object();
|
|
|
|
json_object_pim_ifp_add(json_row, ifp);
|
|
|
|
json_object_string_add(json_row, "upTime",
|
|
|
|
uptime);
|
|
|
|
json_object_string_add(json_row, "querier",
|
|
|
|
igmp->t_igmp_query_timer
|
|
|
|
? "local"
|
|
|
|
: "other");
|
|
|
|
json_object_int_add(json_row, "queryStartCount",
|
|
|
|
igmp->startup_query_count);
|
|
|
|
json_object_string_add(json_row,
|
|
|
|
"queryQueryTimer",
|
|
|
|
query_hhmmss);
|
|
|
|
json_object_string_add(json_row,
|
|
|
|
"queryOtherTimer",
|
|
|
|
other_hhmmss);
|
|
|
|
json_object_int_add(json_row, "version",
|
|
|
|
pim_ifp->igmp_version);
|
|
|
|
json_object_int_add(
|
|
|
|
json_row,
|
|
|
|
"timerGroupMembershipIntervalMsec",
|
|
|
|
gmi_msec);
|
|
|
|
json_object_int_add(json_row,
|
|
|
|
"timerLastMemberQueryMsec",
|
|
|
|
lmqt_msec);
|
|
|
|
json_object_int_add(
|
|
|
|
json_row,
|
|
|
|
"timerOlderHostPresentIntervalMsec",
|
|
|
|
ohpi_msec);
|
|
|
|
json_object_int_add(
|
|
|
|
json_row,
|
|
|
|
"timerOtherQuerierPresentIntervalMsec",
|
|
|
|
oqpi_msec);
|
|
|
|
json_object_int_add(
|
|
|
|
json_row, "timerQueryInterval",
|
|
|
|
igmp->querier_query_interval);
|
|
|
|
json_object_int_add(
|
|
|
|
json_row,
|
|
|
|
"timerQueryResponseIntervalMsec",
|
|
|
|
qri_msec);
|
|
|
|
json_object_int_add(
|
|
|
|
json_row, "timerRobustnessVariable",
|
|
|
|
igmp->querier_robustness_variable);
|
|
|
|
json_object_int_add(json_row,
|
|
|
|
"timerStartupQueryInterval",
|
|
|
|
sqi);
|
|
|
|
|
|
|
|
json_object_object_add(json, ifp->name,
|
|
|
|
json_row);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
vty_out(vty, "Interface : %s\n", ifp->name);
|
|
|
|
vty_out(vty, "State : %s\n",
|
|
|
|
if_is_up(ifp) ? "up" : "down");
|
|
|
|
vty_out(vty, "Address : %s\n",
|
|
|
|
inet_ntoa(pim_ifp->primary_address));
|
|
|
|
vty_out(vty, "Uptime : %s\n", uptime);
|
|
|
|
vty_out(vty, "Version : %d\n",
|
|
|
|
pim_ifp->igmp_version);
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
|
|
|
|
vty_out(vty, "Querier\n");
|
|
|
|
vty_out(vty, "-------\n");
|
|
|
|
vty_out(vty, "Querier : %s\n",
|
|
|
|
igmp->t_igmp_query_timer ? "local"
|
|
|
|
: "other");
|
|
|
|
vty_out(vty, "Start Count : %d\n",
|
|
|
|
igmp->startup_query_count);
|
|
|
|
vty_out(vty, "Query Timer : %s\n",
|
|
|
|
query_hhmmss);
|
|
|
|
vty_out(vty, "Other Timer : %s\n",
|
|
|
|
other_hhmmss);
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
|
|
|
|
vty_out(vty, "Timers\n");
|
|
|
|
vty_out(vty, "------\n");
|
|
|
|
vty_out(vty,
|
|
|
|
"Group Membership Interval : %lis\n",
|
|
|
|
gmi_msec / 1000);
|
|
|
|
vty_out(vty,
|
|
|
|
"Last Member Query Time : %lis\n",
|
|
|
|
lmqt_msec / 1000);
|
|
|
|
vty_out(vty,
|
|
|
|
"Older Host Present Interval : %lis\n",
|
|
|
|
ohpi_msec / 1000);
|
|
|
|
vty_out(vty,
|
|
|
|
"Other Querier Present Interval : %lis\n",
|
|
|
|
oqpi_msec / 1000);
|
|
|
|
vty_out(vty,
|
|
|
|
"Query Interval : %ds\n",
|
|
|
|
igmp->querier_query_interval);
|
|
|
|
vty_out(vty,
|
|
|
|
"Query Response Interval : %lis\n",
|
|
|
|
qri_msec / 1000);
|
|
|
|
vty_out(vty,
|
|
|
|
"Robustness Variable : %d\n",
|
|
|
|
igmp->querier_robustness_variable);
|
|
|
|
vty_out(vty,
|
|
|
|
"Startup Query Interval : %ds\n",
|
|
|
|
sqi);
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
|
|
|
|
pim_print_ifp_flags(vty, ifp, mloop);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uj) {
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
} else {
|
|
|
|
if (!found_ifname)
|
|
|
|
vty_out(vty, "%% No such interface\n");
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void igmp_show_interface_join(struct vty *vty, struct pim_instance *pim)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *node;
|
|
|
|
struct interface *ifp;
|
|
|
|
time_t now;
|
|
|
|
|
|
|
|
now = pim_time_monotonic_sec();
|
|
|
|
|
|
|
|
vty_out(vty,
|
|
|
|
"Interface Address Source Group Socket Uptime \n");
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
struct listnode *join_node;
|
|
|
|
struct igmp_join *ij;
|
|
|
|
struct in_addr pri_addr;
|
|
|
|
char pri_addr_str[INET_ADDRSTRLEN];
|
|
|
|
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
|
|
|
|
if (!pim_ifp)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!pim_ifp->igmp_join_list)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
pri_addr = pim_find_primary_addr(ifp);
|
|
|
|
pim_inet4_dump("<pri?>", pri_addr, pri_addr_str,
|
|
|
|
sizeof(pri_addr_str));
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_join_list, join_node,
|
|
|
|
ij)) {
|
|
|
|
char group_str[INET_ADDRSTRLEN];
|
|
|
|
char source_str[INET_ADDRSTRLEN];
|
|
|
|
char uptime[10];
|
|
|
|
|
|
|
|
pim_time_uptime(uptime, sizeof(uptime),
|
|
|
|
now - ij->sock_creation);
|
|
|
|
pim_inet4_dump("<grp?>", ij->group_addr, group_str,
|
|
|
|
sizeof(group_str));
|
|
|
|
pim_inet4_dump("<src?>", ij->source_addr, source_str,
|
|
|
|
sizeof(source_str));
|
|
|
|
|
|
|
|
vty_out(vty, "%-9s %-15s %-15s %-15s %6d %8s\n",
|
|
|
|
ifp->name, pri_addr_str, source_str, group_str,
|
|
|
|
ij->sock_fd, uptime);
|
|
|
|
} /* for (pim_ifp->igmp_join_list) */
|
|
|
|
|
|
|
|
} /* for (iflist) */
|
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void pim_show_interfaces_single(struct vty *vty,
|
|
|
|
struct pim_instance *pim,
|
|
|
|
const char *ifname, u_char uj)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
|
|
|
struct in_addr ifaddr;
|
|
|
|
struct interface *ifp;
|
|
|
|
struct listnode *neighnode;
|
|
|
|
struct listnode *node;
|
|
|
|
struct listnode *upnode;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
struct pim_neighbor *neigh;
|
|
|
|
struct pim_upstream *up;
|
|
|
|
time_t now;
|
|
|
|
char dr_str[INET_ADDRSTRLEN];
|
|
|
|
char dr_uptime[10];
|
|
|
|
char expire[10];
|
|
|
|
char grp_str[INET_ADDRSTRLEN];
|
|
|
|
char hello_period[10];
|
|
|
|
char hello_timer[10];
|
|
|
|
char neigh_src_str[INET_ADDRSTRLEN];
|
|
|
|
char src_str[INET_ADDRSTRLEN];
|
|
|
|
char stat_uptime[10];
|
|
|
|
char uptime[10];
|
2017-06-22 21:09:02 +02:00
|
|
|
int mloop = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
int found_ifname = 0;
|
|
|
|
int print_header;
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_row = NULL;
|
|
|
|
json_object *json_pim_neighbor = NULL;
|
|
|
|
json_object *json_pim_neighbors = NULL;
|
|
|
|
json_object *json_group = NULL;
|
|
|
|
json_object *json_group_source = NULL;
|
|
|
|
json_object *json_fhr_sources = NULL;
|
|
|
|
struct pim_secondary_addr *sec_addr;
|
|
|
|
struct listnode *sec_node;
|
|
|
|
|
|
|
|
now = pim_time_monotonic_sec();
|
|
|
|
|
|
|
|
if (uj)
|
|
|
|
json = json_object_new_object();
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_ifp = ifp->info;
|
|
|
|
|
|
|
|
if (!pim_ifp)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
found_ifname = 1;
|
|
|
|
ifaddr = pim_ifp->primary_address;
|
|
|
|
pim_inet4_dump("<dr?>", pim_ifp->pim_dr_addr, dr_str,
|
|
|
|
sizeof(dr_str));
|
|
|
|
pim_time_uptime_begin(dr_uptime, sizeof(dr_uptime), now,
|
|
|
|
pim_ifp->pim_dr_election_last);
|
|
|
|
pim_time_timer_to_hhmmss(hello_timer, sizeof(hello_timer),
|
|
|
|
pim_ifp->t_pim_hello_timer);
|
|
|
|
pim_time_mmss(hello_period, sizeof(hello_period),
|
|
|
|
pim_ifp->pim_hello_period);
|
|
|
|
pim_time_uptime(stat_uptime, sizeof(stat_uptime),
|
|
|
|
now - pim_ifp->pim_ifstat_start);
|
2017-06-22 21:09:02 +02:00
|
|
|
if (pim_ifp->pim_sock_fd >= 0)
|
|
|
|
mloop = pim_socket_mcastloop_get(pim_ifp->pim_sock_fd);
|
|
|
|
else
|
|
|
|
mloop = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
char pbuf[PREFIX2STR_BUFFER];
|
|
|
|
json_row = json_object_new_object();
|
|
|
|
json_object_pim_ifp_add(json_row, ifp);
|
|
|
|
|
|
|
|
if (pim_ifp->update_source.s_addr != INADDR_ANY) {
|
|
|
|
json_object_string_add(
|
|
|
|
json_row, "useSource",
|
|
|
|
inet_ntoa(pim_ifp->update_source));
|
|
|
|
}
|
|
|
|
if (pim_ifp->sec_addr_list) {
|
|
|
|
json_object *sec_list = NULL;
|
|
|
|
|
|
|
|
sec_list = json_object_new_array();
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(
|
|
|
|
pim_ifp->sec_addr_list, sec_node,
|
|
|
|
sec_addr)) {
|
|
|
|
json_object_array_add(
|
|
|
|
sec_list,
|
|
|
|
json_object_new_string(
|
|
|
|
prefix2str(
|
|
|
|
&sec_addr->addr,
|
|
|
|
pbuf,
|
|
|
|
sizeof(pbuf))));
|
|
|
|
}
|
|
|
|
json_object_object_add(json_row,
|
|
|
|
"secondaryAddressList",
|
|
|
|
sec_list);
|
|
|
|
}
|
|
|
|
|
|
|
|
// PIM neighbors
|
|
|
|
if (pim_ifp->pim_neighbor_list->count) {
|
|
|
|
json_pim_neighbors = json_object_new_object();
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(
|
|
|
|
pim_ifp->pim_neighbor_list,
|
|
|
|
neighnode, neigh)) {
|
|
|
|
json_pim_neighbor =
|
|
|
|
json_object_new_object();
|
|
|
|
pim_inet4_dump("<src?>",
|
|
|
|
neigh->source_addr,
|
|
|
|
neigh_src_str,
|
|
|
|
sizeof(neigh_src_str));
|
|
|
|
pim_time_uptime(uptime, sizeof(uptime),
|
|
|
|
now - neigh->creation);
|
|
|
|
pim_time_timer_to_hhmmss(
|
|
|
|
expire, sizeof(expire),
|
|
|
|
neigh->t_expire_timer);
|
|
|
|
|
|
|
|
json_object_string_add(
|
|
|
|
json_pim_neighbor, "address",
|
|
|
|
neigh_src_str);
|
|
|
|
json_object_string_add(
|
|
|
|
json_pim_neighbor, "upTime",
|
|
|
|
uptime);
|
|
|
|
json_object_string_add(
|
|
|
|
json_pim_neighbor, "holdtime",
|
|
|
|
expire);
|
|
|
|
|
|
|
|
json_object_object_add(
|
|
|
|
json_pim_neighbors,
|
|
|
|
neigh_src_str,
|
|
|
|
json_pim_neighbor);
|
|
|
|
}
|
|
|
|
|
|
|
|
json_object_object_add(json_row, "neighbors",
|
|
|
|
json_pim_neighbors);
|
|
|
|
}
|
|
|
|
|
|
|
|
json_object_string_add(json_row, "drAddress", dr_str);
|
|
|
|
json_object_int_add(json_row, "drPriority",
|
|
|
|
pim_ifp->pim_dr_priority);
|
|
|
|
json_object_string_add(json_row, "drUptime", dr_uptime);
|
|
|
|
json_object_int_add(json_row, "drElections",
|
|
|
|
pim_ifp->pim_dr_election_count);
|
|
|
|
json_object_int_add(json_row, "drChanges",
|
|
|
|
pim_ifp->pim_dr_election_changes);
|
|
|
|
|
|
|
|
// FHR
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode,
|
2017-07-17 14:03:14 +02:00
|
|
|
up)) {
|
|
|
|
if (ifp == up->rpf.source_nexthop.interface) {
|
|
|
|
if (up->flags
|
|
|
|
& PIM_UPSTREAM_FLAG_MASK_FHR) {
|
|
|
|
if (!json_fhr_sources) {
|
|
|
|
json_fhr_sources =
|
|
|
|
json_object_new_object();
|
|
|
|
}
|
|
|
|
|
|
|
|
pim_inet4_dump("<src?>",
|
|
|
|
up->sg.src,
|
|
|
|
src_str,
|
|
|
|
sizeof(src_str));
|
|
|
|
pim_inet4_dump("<grp?>",
|
|
|
|
up->sg.grp,
|
|
|
|
grp_str,
|
|
|
|
sizeof(grp_str));
|
|
|
|
pim_time_uptime(
|
|
|
|
uptime, sizeof(uptime),
|
|
|
|
now - up->state_transition);
|
|
|
|
|
|
|
|
/* Does this group live in
|
|
|
|
* json_fhr_sources? If not
|
|
|
|
* create it. */
|
|
|
|
json_object_object_get_ex(
|
|
|
|
json_fhr_sources,
|
|
|
|
grp_str, &json_group);
|
|
|
|
|
|
|
|
if (!json_group) {
|
|
|
|
json_group =
|
|
|
|
json_object_new_object();
|
|
|
|
json_object_object_add(
|
|
|
|
json_fhr_sources,
|
|
|
|
grp_str,
|
|
|
|
json_group);
|
|
|
|
}
|
|
|
|
|
|
|
|
json_group_source =
|
|
|
|
json_object_new_object();
|
|
|
|
json_object_string_add(
|
|
|
|
json_group_source,
|
|
|
|
"source", src_str);
|
|
|
|
json_object_string_add(
|
|
|
|
json_group_source,
|
|
|
|
"group", grp_str);
|
|
|
|
json_object_string_add(
|
|
|
|
json_group_source,
|
|
|
|
"upTime", uptime);
|
|
|
|
json_object_object_add(
|
|
|
|
json_group, src_str,
|
|
|
|
json_group_source);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (json_fhr_sources) {
|
|
|
|
json_object_object_add(json_row,
|
|
|
|
"firstHopRouter",
|
|
|
|
json_fhr_sources);
|
|
|
|
}
|
|
|
|
|
|
|
|
json_object_int_add(json_row, "helloPeriod",
|
|
|
|
pim_ifp->pim_hello_period);
|
|
|
|
json_object_string_add(json_row, "helloTimer",
|
|
|
|
hello_timer);
|
|
|
|
json_object_string_add(json_row, "helloStatStart",
|
|
|
|
stat_uptime);
|
|
|
|
json_object_int_add(json_row, "helloReceived",
|
|
|
|
pim_ifp->pim_ifstat_hello_recv);
|
|
|
|
json_object_int_add(json_row, "helloReceivedFailed",
|
|
|
|
pim_ifp->pim_ifstat_hello_recvfail);
|
|
|
|
json_object_int_add(json_row, "helloSend",
|
|
|
|
pim_ifp->pim_ifstat_hello_sent);
|
|
|
|
json_object_int_add(json_row, "hellosendFailed",
|
|
|
|
pim_ifp->pim_ifstat_hello_sendfail);
|
|
|
|
json_object_int_add(json_row, "helloGenerationId",
|
|
|
|
pim_ifp->pim_generation_id);
|
|
|
|
json_object_int_add(json_row, "flagMulticastLoop",
|
|
|
|
mloop);
|
|
|
|
|
|
|
|
json_object_int_add(
|
|
|
|
json_row, "effectivePropagationDelay",
|
|
|
|
pim_if_effective_propagation_delay_msec(ifp));
|
|
|
|
json_object_int_add(
|
|
|
|
json_row, "effectiveOverrideInterval",
|
|
|
|
pim_if_effective_override_interval_msec(ifp));
|
|
|
|
json_object_int_add(
|
|
|
|
json_row, "joinPruneOverrideInterval",
|
|
|
|
pim_if_jp_override_interval_msec(ifp));
|
|
|
|
|
|
|
|
json_object_int_add(
|
|
|
|
json_row, "propagationDelay",
|
|
|
|
pim_ifp->pim_propagation_delay_msec);
|
|
|
|
json_object_int_add(
|
|
|
|
json_row, "propagationDelayHighest",
|
|
|
|
pim_ifp->pim_neighbors_highest_propagation_delay_msec);
|
|
|
|
json_object_int_add(
|
|
|
|
json_row, "overrideInterval",
|
|
|
|
pim_ifp->pim_override_interval_msec);
|
|
|
|
json_object_int_add(
|
|
|
|
json_row, "overrideIntervalHighest",
|
|
|
|
pim_ifp->pim_neighbors_highest_override_interval_msec);
|
|
|
|
json_object_object_add(json, ifp->name, json_row);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
vty_out(vty, "Interface : %s\n", ifp->name);
|
|
|
|
vty_out(vty, "State : %s\n",
|
|
|
|
if_is_up(ifp) ? "up" : "down");
|
|
|
|
if (pim_ifp->update_source.s_addr != INADDR_ANY) {
|
|
|
|
vty_out(vty, "Use Source : %s\n",
|
|
|
|
inet_ntoa(pim_ifp->update_source));
|
|
|
|
}
|
|
|
|
if (pim_ifp->sec_addr_list) {
|
|
|
|
char pbuf[PREFIX2STR_BUFFER];
|
|
|
|
vty_out(vty, "Address : %s (primary)\n",
|
|
|
|
inet_ntoa(ifaddr));
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(
|
|
|
|
pim_ifp->sec_addr_list, sec_node,
|
|
|
|
sec_addr)) {
|
|
|
|
vty_out(vty, " %s\n",
|
|
|
|
prefix2str(&sec_addr->addr,
|
|
|
|
pbuf, sizeof(pbuf)));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
vty_out(vty, "Address : %s\n",
|
|
|
|
inet_ntoa(ifaddr));
|
|
|
|
}
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
|
|
|
|
// PIM neighbors
|
|
|
|
print_header = 1;
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list,
|
|
|
|
neighnode, neigh)) {
|
|
|
|
|
|
|
|
if (print_header) {
|
|
|
|
vty_out(vty, "PIM Neighbors\n");
|
|
|
|
vty_out(vty, "-------------\n");
|
|
|
|
print_header = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
pim_inet4_dump("<src?>", neigh->source_addr,
|
|
|
|
neigh_src_str,
|
|
|
|
sizeof(neigh_src_str));
|
|
|
|
pim_time_uptime(uptime, sizeof(uptime),
|
|
|
|
now - neigh->creation);
|
|
|
|
pim_time_timer_to_hhmmss(expire, sizeof(expire),
|
|
|
|
neigh->t_expire_timer);
|
|
|
|
vty_out(vty,
|
|
|
|
"%-15s : up for %s, holdtime expires in %s\n",
|
|
|
|
neigh_src_str, uptime, expire);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!print_header) {
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
vty_out(vty, "Designated Router\n");
|
|
|
|
vty_out(vty, "-----------------\n");
|
|
|
|
vty_out(vty, "Address : %s\n", dr_str);
|
|
|
|
vty_out(vty, "Priority : %d\n",
|
|
|
|
pim_ifp->pim_dr_priority);
|
|
|
|
vty_out(vty, "Uptime : %s\n", dr_uptime);
|
|
|
|
vty_out(vty, "Elections : %d\n",
|
|
|
|
pim_ifp->pim_dr_election_count);
|
|
|
|
vty_out(vty, "Changes : %d\n",
|
|
|
|
pim_ifp->pim_dr_election_changes);
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
|
|
|
|
// FHR
|
|
|
|
print_header = 1;
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode,
|
2017-07-17 14:03:14 +02:00
|
|
|
up)) {
|
2017-05-04 16:59:45 +02:00
|
|
|
if (strcmp(ifp->name, up->rpf.source_nexthop
|
|
|
|
.interface->name)
|
2017-07-17 14:03:14 +02:00
|
|
|
== 0) {
|
|
|
|
if (up->flags
|
|
|
|
& PIM_UPSTREAM_FLAG_MASK_FHR) {
|
|
|
|
|
|
|
|
if (print_header) {
|
|
|
|
vty_out(vty,
|
|
|
|
"FHR - First Hop Router\n");
|
|
|
|
vty_out(vty,
|
|
|
|
"----------------------\n");
|
|
|
|
print_header = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
pim_inet4_dump("<src?>",
|
|
|
|
up->sg.src,
|
|
|
|
src_str,
|
|
|
|
sizeof(src_str));
|
|
|
|
pim_inet4_dump("<grp?>",
|
|
|
|
up->sg.grp,
|
|
|
|
grp_str,
|
|
|
|
sizeof(grp_str));
|
|
|
|
pim_time_uptime(
|
|
|
|
uptime, sizeof(uptime),
|
|
|
|
now - up->state_transition);
|
|
|
|
vty_out(vty,
|
|
|
|
"%s : %s is a source, uptime is %s\n",
|
|
|
|
grp_str, src_str,
|
|
|
|
uptime);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!print_header) {
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
vty_out(vty, "Hellos\n");
|
|
|
|
vty_out(vty, "------\n");
|
|
|
|
vty_out(vty, "Period : %d\n",
|
|
|
|
pim_ifp->pim_hello_period);
|
|
|
|
vty_out(vty, "Timer : %s\n", hello_timer);
|
|
|
|
vty_out(vty, "StatStart : %s\n", stat_uptime);
|
|
|
|
vty_out(vty, "Receive : %d\n",
|
|
|
|
pim_ifp->pim_ifstat_hello_recv);
|
|
|
|
vty_out(vty, "Receive Failed : %d\n",
|
|
|
|
pim_ifp->pim_ifstat_hello_recvfail);
|
|
|
|
vty_out(vty, "Send : %d\n",
|
|
|
|
pim_ifp->pim_ifstat_hello_sent);
|
|
|
|
vty_out(vty, "Send Failed : %d\n",
|
|
|
|
pim_ifp->pim_ifstat_hello_sendfail);
|
|
|
|
vty_out(vty, "Generation ID : %08x\n",
|
|
|
|
pim_ifp->pim_generation_id);
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
|
|
|
|
pim_print_ifp_flags(vty, ifp, mloop);
|
|
|
|
|
|
|
|
vty_out(vty, "Join Prune Interval\n");
|
|
|
|
vty_out(vty, "-------------------\n");
|
|
|
|
vty_out(vty, "LAN Delay : %s\n",
|
|
|
|
pim_if_lan_delay_enabled(ifp) ? "yes" : "no");
|
|
|
|
vty_out(vty, "Effective Propagation Delay : %d msec\n",
|
|
|
|
pim_if_effective_propagation_delay_msec(ifp));
|
|
|
|
vty_out(vty, "Effective Override Interval : %d msec\n",
|
|
|
|
pim_if_effective_override_interval_msec(ifp));
|
|
|
|
vty_out(vty, "Join Prune Override Interval : %d msec\n",
|
|
|
|
pim_if_jp_override_interval_msec(ifp));
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
|
|
|
|
vty_out(vty, "LAN Prune Delay\n");
|
|
|
|
vty_out(vty, "---------------\n");
|
|
|
|
vty_out(vty, "Propagation Delay : %d msec\n",
|
|
|
|
pim_ifp->pim_propagation_delay_msec);
|
|
|
|
vty_out(vty, "Propagation Delay (Highest) : %d msec\n",
|
|
|
|
pim_ifp->pim_neighbors_highest_propagation_delay_msec);
|
|
|
|
vty_out(vty, "Override Interval : %d msec\n",
|
|
|
|
pim_ifp->pim_override_interval_msec);
|
|
|
|
vty_out(vty, "Override Interval (Highest) : %d msec\n",
|
|
|
|
pim_ifp->pim_neighbors_highest_override_interval_msec);
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uj) {
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
} else {
|
|
|
|
if (!found_ifname)
|
|
|
|
vty_out(vty, "%% No such interface\n");
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void pim_show_interfaces(struct vty *vty, struct pim_instance *pim,
|
|
|
|
u_char uj)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct listnode *node;
|
|
|
|
struct listnode *upnode;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
struct pim_upstream *up;
|
|
|
|
int fhr = 0;
|
|
|
|
int pim_nbrs = 0;
|
|
|
|
int pim_ifchannels = 0;
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_row = NULL;
|
|
|
|
json_object *json_tmp;
|
|
|
|
|
|
|
|
json = json_object_new_object();
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_ifp = ifp->info;
|
|
|
|
|
|
|
|
if (!pim_ifp)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
pim_nbrs = pim_ifp->pim_neighbor_list->count;
|
|
|
|
pim_ifchannels = pim_ifp->pim_ifchannel_list->count;
|
|
|
|
fhr = 0;
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up))
|
2017-07-17 14:03:14 +02:00
|
|
|
if (ifp == up->rpf.source_nexthop.interface)
|
|
|
|
if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
|
|
|
|
fhr++;
|
|
|
|
|
|
|
|
json_row = json_object_new_object();
|
|
|
|
json_object_pim_ifp_add(json_row, ifp);
|
|
|
|
json_object_int_add(json_row, "pimNeighbors", pim_nbrs);
|
|
|
|
json_object_int_add(json_row, "pimIfChannels", pim_ifchannels);
|
|
|
|
json_object_int_add(json_row, "firstHopRouter", fhr);
|
|
|
|
json_object_string_add(json_row, "pimDesignatedRouter",
|
|
|
|
inet_ntoa(pim_ifp->pim_dr_addr));
|
|
|
|
|
|
|
|
if (pim_ifp->pim_dr_addr.s_addr
|
|
|
|
== pim_ifp->primary_address.s_addr)
|
|
|
|
json_object_boolean_true_add(
|
|
|
|
json_row, "pimDesignatedRouterLocal");
|
|
|
|
|
|
|
|
json_object_object_add(json, ifp->name, json_row);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uj) {
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
} else {
|
|
|
|
vty_out(vty,
|
|
|
|
"Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
|
|
|
|
|
|
|
|
json_object_object_foreach(json, key, val)
|
|
|
|
{
|
|
|
|
vty_out(vty, "%-9s ", key);
|
|
|
|
|
|
|
|
json_object_object_get_ex(val, "state", &json_tmp);
|
|
|
|
vty_out(vty, "%5s ", json_object_get_string(json_tmp));
|
|
|
|
|
|
|
|
json_object_object_get_ex(val, "address", &json_tmp);
|
|
|
|
vty_out(vty, "%15s ",
|
|
|
|
json_object_get_string(json_tmp));
|
|
|
|
|
|
|
|
json_object_object_get_ex(val, "pimNeighbors",
|
|
|
|
&json_tmp);
|
|
|
|
vty_out(vty, "%8d ", json_object_get_int(json_tmp));
|
|
|
|
|
|
|
|
if (json_object_object_get_ex(
|
|
|
|
val, "pimDesignatedRouterLocal",
|
|
|
|
&json_tmp)) {
|
|
|
|
vty_out(vty, "%15s ", "local");
|
|
|
|
} else {
|
|
|
|
json_object_object_get_ex(
|
|
|
|
val, "pimDesignatedRouter", &json_tmp);
|
|
|
|
vty_out(vty, "%15s ",
|
|
|
|
json_object_get_string(json_tmp));
|
|
|
|
}
|
|
|
|
|
|
|
|
json_object_object_get_ex(val, "firstHopRouter",
|
|
|
|
&json_tmp);
|
|
|
|
vty_out(vty, "%3d ", json_object_get_int(json_tmp));
|
|
|
|
|
|
|
|
json_object_object_get_ex(val, "pimIfChannels",
|
|
|
|
&json_tmp);
|
|
|
|
vty_out(vty, "%9d\n", json_object_get_int(json_tmp));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
json_object_free(json);
|
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void pim_show_interface_traffic(struct vty *vty,
|
|
|
|
struct pim_instance *pim, u_char uj)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
|
|
|
struct interface *ifp = NULL;
|
|
|
|
struct pim_interface *pim_ifp = NULL;
|
|
|
|
struct listnode *node = NULL;
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_row = NULL;
|
|
|
|
|
|
|
|
if (uj)
|
|
|
|
json = json_object_new_object();
|
|
|
|
else {
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
|
|
|
|
"Interface", " HELLO", " JOIN", " PRUNE",
|
|
|
|
" REGISTER", " REGISTER-STOP", " ASSERT");
|
|
|
|
vty_out(vty, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
|
|
|
|
" Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
|
|
|
|
" Rx/Tx", " Rx/Tx");
|
|
|
|
vty_out(vty,
|
|
|
|
"---------------------------------------------------------------------------------------------------------------\n");
|
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_ifp = ifp->info;
|
|
|
|
|
|
|
|
if (!pim_ifp)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (pim_ifp->pim_sock_fd < 0)
|
|
|
|
continue;
|
|
|
|
if (uj) {
|
|
|
|
json_row = json_object_new_object();
|
|
|
|
json_object_pim_ifp_add(json_row, ifp);
|
|
|
|
json_object_int_add(json_row, "helloRx",
|
|
|
|
pim_ifp->pim_ifstat_hello_recv);
|
|
|
|
json_object_int_add(json_row, "helloTx",
|
|
|
|
pim_ifp->pim_ifstat_hello_sent);
|
|
|
|
json_object_int_add(json_row, "joinRx",
|
|
|
|
pim_ifp->pim_ifstat_join_recv);
|
|
|
|
json_object_int_add(json_row, "joinTx",
|
|
|
|
pim_ifp->pim_ifstat_join_send);
|
|
|
|
json_object_int_add(json_row, "registerRx",
|
|
|
|
pim_ifp->pim_ifstat_reg_recv);
|
|
|
|
json_object_int_add(json_row, "registerTx",
|
|
|
|
pim_ifp->pim_ifstat_reg_recv);
|
|
|
|
json_object_int_add(json_row, "registerStopRx",
|
|
|
|
pim_ifp->pim_ifstat_reg_stop_recv);
|
|
|
|
json_object_int_add(json_row, "registerStopTx",
|
|
|
|
pim_ifp->pim_ifstat_reg_stop_send);
|
|
|
|
json_object_int_add(json_row, "assertRx",
|
|
|
|
pim_ifp->pim_ifstat_assert_recv);
|
|
|
|
json_object_int_add(json_row, "assertTx",
|
|
|
|
pim_ifp->pim_ifstat_assert_send);
|
|
|
|
|
|
|
|
json_object_object_add(json, ifp->name, json_row);
|
|
|
|
} else {
|
|
|
|
vty_out(vty,
|
|
|
|
"%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
|
|
|
|
ifp->name, pim_ifp->pim_ifstat_hello_recv,
|
|
|
|
pim_ifp->pim_ifstat_hello_sent,
|
|
|
|
pim_ifp->pim_ifstat_join_recv,
|
|
|
|
pim_ifp->pim_ifstat_join_send,
|
|
|
|
pim_ifp->pim_ifstat_prune_recv,
|
|
|
|
pim_ifp->pim_ifstat_prune_send,
|
|
|
|
pim_ifp->pim_ifstat_reg_recv,
|
|
|
|
pim_ifp->pim_ifstat_reg_send,
|
|
|
|
pim_ifp->pim_ifstat_reg_stop_recv,
|
|
|
|
pim_ifp->pim_ifstat_reg_stop_send,
|
|
|
|
pim_ifp->pim_ifstat_assert_recv,
|
|
|
|
pim_ifp->pim_ifstat_assert_send);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (uj) {
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void pim_show_interface_traffic_single(struct vty *vty,
|
2017-05-23 14:57:11 +02:00
|
|
|
struct pim_instance *pim,
|
2017-07-17 14:03:14 +02:00
|
|
|
const char *ifname, u_char uj)
|
|
|
|
{
|
|
|
|
struct interface *ifp = NULL;
|
|
|
|
struct pim_interface *pim_ifp = NULL;
|
|
|
|
struct listnode *node = NULL;
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_row = NULL;
|
|
|
|
uint8_t found_ifname = 0;
|
|
|
|
|
|
|
|
if (uj)
|
|
|
|
json = json_object_new_object();
|
|
|
|
else {
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
|
|
|
|
"Interface", " HELLO", " JOIN", " PRUNE",
|
|
|
|
" REGISTER", " REGISTER-STOP", " ASSERT");
|
|
|
|
vty_out(vty, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
|
|
|
|
" Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
|
|
|
|
" Rx/Tx", " Rx/Tx");
|
|
|
|
vty_out(vty,
|
|
|
|
"---------------------------------------------------------------------------------------------------------------\n");
|
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
if (strcmp(ifname, ifp->name))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
|
|
|
|
if (!pim_ifp)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (pim_ifp->pim_sock_fd < 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
found_ifname = 1;
|
|
|
|
if (uj) {
|
|
|
|
json_row = json_object_new_object();
|
|
|
|
json_object_pim_ifp_add(json_row, ifp);
|
|
|
|
json_object_int_add(json_row, "helloRx",
|
|
|
|
pim_ifp->pim_ifstat_hello_recv);
|
|
|
|
json_object_int_add(json_row, "helloTx",
|
|
|
|
pim_ifp->pim_ifstat_hello_sent);
|
|
|
|
json_object_int_add(json_row, "joinRx",
|
|
|
|
pim_ifp->pim_ifstat_join_recv);
|
|
|
|
json_object_int_add(json_row, "joinTx",
|
|
|
|
pim_ifp->pim_ifstat_join_send);
|
|
|
|
json_object_int_add(json_row, "registerRx",
|
|
|
|
pim_ifp->pim_ifstat_reg_recv);
|
|
|
|
json_object_int_add(json_row, "registerTx",
|
|
|
|
pim_ifp->pim_ifstat_reg_recv);
|
|
|
|
json_object_int_add(json_row, "registerStopRx",
|
|
|
|
pim_ifp->pim_ifstat_reg_stop_recv);
|
|
|
|
json_object_int_add(json_row, "registerStopTx",
|
|
|
|
pim_ifp->pim_ifstat_reg_stop_send);
|
|
|
|
json_object_int_add(json_row, "assertRx",
|
|
|
|
pim_ifp->pim_ifstat_assert_recv);
|
|
|
|
json_object_int_add(json_row, "assertTx",
|
|
|
|
pim_ifp->pim_ifstat_assert_send);
|
|
|
|
|
|
|
|
json_object_object_add(json, ifp->name, json_row);
|
|
|
|
} else {
|
|
|
|
vty_out(vty,
|
|
|
|
"%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
|
|
|
|
ifp->name, pim_ifp->pim_ifstat_hello_recv,
|
|
|
|
pim_ifp->pim_ifstat_hello_sent,
|
|
|
|
pim_ifp->pim_ifstat_join_recv,
|
|
|
|
pim_ifp->pim_ifstat_join_send,
|
|
|
|
pim_ifp->pim_ifstat_prune_recv,
|
|
|
|
pim_ifp->pim_ifstat_prune_send,
|
|
|
|
pim_ifp->pim_ifstat_reg_recv,
|
|
|
|
pim_ifp->pim_ifstat_reg_send,
|
|
|
|
pim_ifp->pim_ifstat_reg_stop_recv,
|
|
|
|
pim_ifp->pim_ifstat_reg_stop_send,
|
|
|
|
pim_ifp->pim_ifstat_assert_recv,
|
|
|
|
pim_ifp->pim_ifstat_assert_send);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (uj) {
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
} else {
|
|
|
|
if (!found_ifname)
|
|
|
|
vty_out(vty, "%% No such interface\n");
|
|
|
|
}
|
2017-04-03 22:11:58 +02:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void pim_show_join(struct vty *vty, struct pim_instance *pim, u_char uj)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
struct in_addr ifaddr;
|
|
|
|
struct listnode *ch_node;
|
|
|
|
struct pim_ifchannel *ch;
|
|
|
|
time_t now;
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_iface = NULL;
|
|
|
|
json_object *json_row = NULL;
|
|
|
|
json_object *json_grp = NULL;
|
|
|
|
|
|
|
|
now = pim_time_monotonic_sec();
|
|
|
|
|
|
|
|
if (uj)
|
|
|
|
json = json_object_new_object();
|
|
|
|
else
|
|
|
|
vty_out(vty,
|
|
|
|
"Interface Address Source Group State Uptime Expire Prune\n");
|
|
|
|
|
2017-05-20 20:17:48 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->ifchannel_list, ch_node, ch)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
pim_ifp = ch->interface->info;
|
|
|
|
|
|
|
|
if (!pim_ifp)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
ifaddr = pim_ifp->primary_address;
|
|
|
|
|
|
|
|
char ch_src_str[INET_ADDRSTRLEN];
|
|
|
|
char ch_grp_str[INET_ADDRSTRLEN];
|
|
|
|
char uptime[10];
|
|
|
|
char expire[10];
|
|
|
|
char prune[10];
|
|
|
|
|
|
|
|
pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str,
|
|
|
|
sizeof(ch_src_str));
|
|
|
|
pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str,
|
|
|
|
sizeof(ch_grp_str));
|
|
|
|
|
|
|
|
pim_time_uptime_begin(uptime, sizeof(uptime), now,
|
|
|
|
ch->ifjoin_creation);
|
|
|
|
pim_time_timer_to_mmss(expire, sizeof(expire),
|
|
|
|
ch->t_ifjoin_expiry_timer);
|
|
|
|
pim_time_timer_to_mmss(prune, sizeof(prune),
|
|
|
|
ch->t_ifjoin_prune_pending_timer);
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json_object_object_get_ex(json, ch->interface->name,
|
|
|
|
&json_iface);
|
|
|
|
|
|
|
|
if (!json_iface) {
|
|
|
|
json_iface = json_object_new_object();
|
|
|
|
json_object_pim_ifp_add(json_iface,
|
|
|
|
ch->interface);
|
|
|
|
json_object_object_add(
|
|
|
|
json, ch->interface->name, json_iface);
|
|
|
|
}
|
|
|
|
|
|
|
|
json_row = json_object_new_object();
|
|
|
|
json_object_string_add(json_row, "source", ch_src_str);
|
|
|
|
json_object_string_add(json_row, "group", ch_grp_str);
|
|
|
|
json_object_string_add(json_row, "upTime", uptime);
|
|
|
|
json_object_string_add(json_row, "expire", expire);
|
|
|
|
json_object_string_add(json_row, "prune", prune);
|
|
|
|
json_object_string_add(
|
|
|
|
json_row, "channelJoinName",
|
|
|
|
pim_ifchannel_ifjoin_name(ch->ifjoin_state,
|
|
|
|
ch->flags));
|
|
|
|
if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags))
|
|
|
|
json_object_int_add(json_row, "SGRpt", 1);
|
|
|
|
|
|
|
|
json_object_object_get_ex(json_iface, ch_grp_str,
|
|
|
|
&json_grp);
|
|
|
|
if (!json_grp) {
|
|
|
|
json_grp = json_object_new_object();
|
|
|
|
json_object_object_add(json_grp, ch_src_str,
|
|
|
|
json_row);
|
|
|
|
json_object_object_add(json_iface, ch_grp_str,
|
|
|
|
json_grp);
|
|
|
|
} else
|
|
|
|
json_object_object_add(json_grp, ch_src_str,
|
|
|
|
json_row);
|
|
|
|
} else {
|
|
|
|
vty_out(vty,
|
|
|
|
"%-9s %-15s %-15s %-15s %-6s %8s %-6s %5s\n",
|
|
|
|
ch->interface->name, inet_ntoa(ifaddr),
|
|
|
|
ch_src_str, ch_grp_str,
|
|
|
|
pim_ifchannel_ifjoin_name(ch->ifjoin_state,
|
|
|
|
ch->flags),
|
|
|
|
uptime, expire, prune);
|
|
|
|
}
|
|
|
|
} /* scan interface channels */
|
|
|
|
|
|
|
|
if (uj) {
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void pim_show_neighbors_single(struct vty *vty, struct pim_instance *pim,
|
|
|
|
const char *neighbor, u_char uj)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
|
|
|
struct listnode *node;
|
|
|
|
struct listnode *neighnode;
|
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
struct pim_neighbor *neigh;
|
|
|
|
time_t now;
|
|
|
|
int found_neighbor = 0;
|
|
|
|
int option_address_list;
|
|
|
|
int option_dr_priority;
|
|
|
|
int option_generation_id;
|
|
|
|
int option_holdtime;
|
|
|
|
int option_lan_prune_delay;
|
|
|
|
int option_t_bit;
|
|
|
|
char uptime[10];
|
|
|
|
char expire[10];
|
|
|
|
char neigh_src_str[INET_ADDRSTRLEN];
|
|
|
|
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_ifp = NULL;
|
|
|
|
json_object *json_row = NULL;
|
|
|
|
|
|
|
|
now = pim_time_monotonic_sec();
|
|
|
|
|
|
|
|
if (uj)
|
|
|
|
json = json_object_new_object();
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_ifp = ifp->info;
|
|
|
|
|
|
|
|
if (!pim_ifp)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (pim_ifp->pim_sock_fd < 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
|
|
|
|
neigh)) {
|
|
|
|
pim_inet4_dump("<src?>", neigh->source_addr,
|
|
|
|
neigh_src_str, sizeof(neigh_src_str));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The user can specify either the interface name or the
|
|
|
|
* PIM neighbor IP.
|
|
|
|
* If this pim_ifp matches neither then skip.
|
|
|
|
*/
|
|
|
|
if (strcmp(neighbor, "detail")
|
|
|
|
&& strcmp(neighbor, ifp->name)
|
|
|
|
&& strcmp(neighbor, neigh_src_str))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
found_neighbor = 1;
|
|
|
|
pim_time_uptime(uptime, sizeof(uptime),
|
|
|
|
now - neigh->creation);
|
|
|
|
pim_time_timer_to_hhmmss(expire, sizeof(expire),
|
|
|
|
neigh->t_expire_timer);
|
|
|
|
|
|
|
|
option_address_list = 0;
|
|
|
|
option_dr_priority = 0;
|
|
|
|
option_generation_id = 0;
|
|
|
|
option_holdtime = 0;
|
|
|
|
option_lan_prune_delay = 0;
|
|
|
|
option_t_bit = 0;
|
|
|
|
|
|
|
|
if (PIM_OPTION_IS_SET(neigh->hello_options,
|
|
|
|
PIM_OPTION_MASK_ADDRESS_LIST))
|
|
|
|
option_address_list = 1;
|
|
|
|
|
|
|
|
if (PIM_OPTION_IS_SET(neigh->hello_options,
|
|
|
|
PIM_OPTION_MASK_DR_PRIORITY))
|
|
|
|
option_dr_priority = 1;
|
|
|
|
|
|
|
|
if (PIM_OPTION_IS_SET(neigh->hello_options,
|
|
|
|
PIM_OPTION_MASK_GENERATION_ID))
|
|
|
|
option_generation_id = 1;
|
|
|
|
|
|
|
|
if (PIM_OPTION_IS_SET(neigh->hello_options,
|
|
|
|
PIM_OPTION_MASK_HOLDTIME))
|
|
|
|
option_holdtime = 1;
|
|
|
|
|
|
|
|
if (PIM_OPTION_IS_SET(neigh->hello_options,
|
|
|
|
PIM_OPTION_MASK_LAN_PRUNE_DELAY))
|
|
|
|
option_lan_prune_delay = 1;
|
|
|
|
|
|
|
|
if (PIM_OPTION_IS_SET(
|
|
|
|
neigh->hello_options,
|
|
|
|
PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION))
|
|
|
|
option_t_bit = 1;
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
|
|
|
|
/* Does this ifp live in json? If not create
|
|
|
|
* it. */
|
|
|
|
json_object_object_get_ex(json, ifp->name,
|
|
|
|
&json_ifp);
|
|
|
|
|
|
|
|
if (!json_ifp) {
|
|
|
|
json_ifp = json_object_new_object();
|
|
|
|
json_object_pim_ifp_add(json_ifp, ifp);
|
|
|
|
json_object_object_add(json, ifp->name,
|
|
|
|
json_ifp);
|
|
|
|
}
|
|
|
|
|
|
|
|
json_row = json_object_new_object();
|
|
|
|
json_object_string_add(json_row, "interface",
|
|
|
|
ifp->name);
|
|
|
|
json_object_string_add(json_row, "address",
|
|
|
|
neigh_src_str);
|
|
|
|
json_object_string_add(json_row, "upTime",
|
|
|
|
uptime);
|
|
|
|
json_object_string_add(json_row, "holdtime",
|
|
|
|
expire);
|
|
|
|
json_object_int_add(json_row, "drPriority",
|
|
|
|
neigh->dr_priority);
|
|
|
|
json_object_int_add(json_row, "generationId",
|
|
|
|
neigh->generation_id);
|
|
|
|
|
|
|
|
if (option_address_list)
|
|
|
|
json_object_boolean_true_add(
|
|
|
|
json_row,
|
|
|
|
"helloOptionAddressList");
|
|
|
|
|
|
|
|
if (option_dr_priority)
|
|
|
|
json_object_boolean_true_add(
|
|
|
|
json_row,
|
|
|
|
"helloOptionDrPriority");
|
|
|
|
|
|
|
|
if (option_generation_id)
|
|
|
|
json_object_boolean_true_add(
|
|
|
|
json_row,
|
|
|
|
"helloOptionGenerationId");
|
|
|
|
|
|
|
|
if (option_holdtime)
|
|
|
|
json_object_boolean_true_add(
|
|
|
|
json_row,
|
|
|
|
"helloOptionHoldtime");
|
|
|
|
|
|
|
|
if (option_lan_prune_delay)
|
|
|
|
json_object_boolean_true_add(
|
|
|
|
json_row,
|
|
|
|
"helloOptionLanPruneDelay");
|
|
|
|
|
|
|
|
if (option_t_bit)
|
|
|
|
json_object_boolean_true_add(
|
|
|
|
json_row, "helloOptionTBit");
|
|
|
|
|
|
|
|
json_object_object_add(json_ifp, neigh_src_str,
|
|
|
|
json_row);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
vty_out(vty, "Interface : %s\n", ifp->name);
|
|
|
|
vty_out(vty, "Neighbor : %s\n", neigh_src_str);
|
|
|
|
vty_out(vty,
|
|
|
|
" Uptime : %s\n",
|
|
|
|
uptime);
|
|
|
|
vty_out(vty,
|
|
|
|
" Holdtime : %s\n",
|
|
|
|
expire);
|
|
|
|
vty_out(vty,
|
|
|
|
" DR Priority : %d\n",
|
|
|
|
neigh->dr_priority);
|
|
|
|
vty_out(vty,
|
|
|
|
" Generation ID : %08x\n",
|
|
|
|
neigh->generation_id);
|
|
|
|
vty_out(vty,
|
|
|
|
" Override Interval (msec) : %d\n",
|
|
|
|
neigh->override_interval_msec);
|
|
|
|
vty_out(vty,
|
|
|
|
" Propagation Delay (msec) : %d\n",
|
|
|
|
neigh->propagation_delay_msec);
|
|
|
|
vty_out(vty,
|
|
|
|
" Hello Option - Address List : %s\n",
|
|
|
|
option_address_list ? "yes" : "no");
|
|
|
|
vty_out(vty,
|
|
|
|
" Hello Option - DR Priority : %s\n",
|
|
|
|
option_dr_priority ? "yes" : "no");
|
|
|
|
vty_out(vty,
|
|
|
|
" Hello Option - Generation ID : %s\n",
|
|
|
|
option_generation_id ? "yes" : "no");
|
|
|
|
vty_out(vty,
|
|
|
|
" Hello Option - Holdtime : %s\n",
|
|
|
|
option_holdtime ? "yes" : "no");
|
|
|
|
vty_out(vty,
|
|
|
|
" Hello Option - LAN Prune Delay : %s\n",
|
|
|
|
option_lan_prune_delay ? "yes" : "no");
|
|
|
|
vty_out(vty,
|
|
|
|
" Hello Option - T-bit : %s\n",
|
|
|
|
option_t_bit ? "yes" : "no");
|
|
|
|
pim_bfd_show_info(vty, neigh->bfd_info,
|
|
|
|
json_ifp, uj, 0);
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uj) {
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
} else {
|
|
|
|
{
|
|
|
|
if (!found_neighbor)
|
|
|
|
vty_out(vty,
|
|
|
|
"%% No such interface or neighbor\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void pim_show_state(struct vty *vty, struct pim_instance *pim,
|
2017-05-21 14:29:56 +02:00
|
|
|
const char *src_or_group, const char *group,
|
|
|
|
u_char uj)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
|
|
|
struct channel_oil *c_oil;
|
|
|
|
struct listnode *node;
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_group = NULL;
|
|
|
|
json_object *json_ifp_in = NULL;
|
|
|
|
json_object *json_ifp_out = NULL;
|
|
|
|
json_object *json_source = NULL;
|
|
|
|
time_t now;
|
|
|
|
int first_oif;
|
|
|
|
now = pim_time_monotonic_sec();
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json = json_object_new_object();
|
|
|
|
} else {
|
|
|
|
vty_out(vty,
|
|
|
|
"Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
|
|
|
|
vty_out(vty,
|
|
|
|
"\nInstalled Source Group IIF OIL\n");
|
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
char grp_str[INET_ADDRSTRLEN];
|
|
|
|
char src_str[INET_ADDRSTRLEN];
|
|
|
|
char in_ifname[INTERFACE_NAMSIZ + 1];
|
|
|
|
char out_ifname[INTERFACE_NAMSIZ + 1];
|
|
|
|
int oif_vif_index;
|
|
|
|
struct interface *ifp_in;
|
|
|
|
first_oif = 1;
|
|
|
|
|
|
|
|
pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str,
|
|
|
|
sizeof(grp_str));
|
|
|
|
pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str,
|
|
|
|
sizeof(src_str));
|
2017-05-21 14:29:56 +02:00
|
|
|
ifp_in = pim_if_find_by_vif_index(pim, c_oil->oil.mfcc_parent);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
if (ifp_in)
|
|
|
|
strcpy(in_ifname, ifp_in->name);
|
|
|
|
else
|
|
|
|
strcpy(in_ifname, "<iif?>");
|
|
|
|
|
|
|
|
if (src_or_group) {
|
|
|
|
if (strcmp(src_or_group, src_str)
|
|
|
|
&& strcmp(src_or_group, grp_str))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (group && strcmp(group, grp_str))
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
|
|
|
|
/* Find the group, create it if it doesn't exist */
|
|
|
|
json_object_object_get_ex(json, grp_str, &json_group);
|
|
|
|
|
|
|
|
if (!json_group) {
|
|
|
|
json_group = json_object_new_object();
|
|
|
|
json_object_object_add(json, grp_str,
|
|
|
|
json_group);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Find the source nested under the group, create it if
|
|
|
|
* it doesn't exist */
|
|
|
|
json_object_object_get_ex(json_group, src_str,
|
|
|
|
&json_source);
|
|
|
|
|
|
|
|
if (!json_source) {
|
|
|
|
json_source = json_object_new_object();
|
|
|
|
json_object_object_add(json_group, src_str,
|
|
|
|
json_source);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Find the inbound interface nested under the source,
|
|
|
|
* create it if it doesn't exist */
|
|
|
|
json_object_object_get_ex(json_source, in_ifname,
|
|
|
|
&json_ifp_in);
|
|
|
|
|
|
|
|
if (!json_ifp_in) {
|
|
|
|
json_ifp_in = json_object_new_object();
|
|
|
|
json_object_object_add(json_source, in_ifname,
|
|
|
|
json_ifp_in);
|
|
|
|
json_object_int_add(json_source, "Installed",
|
|
|
|
c_oil->installed);
|
|
|
|
json_object_int_add(json_source, "RefCount",
|
|
|
|
c_oil->oil_ref_count);
|
|
|
|
json_object_int_add(json_source, "OilListSize",
|
|
|
|
c_oil->oil_size);
|
|
|
|
json_object_int_add(
|
|
|
|
json_source, "OilRescan",
|
|
|
|
c_oil->oil_inherited_rescan);
|
|
|
|
json_object_int_add(json_source, "LastUsed",
|
|
|
|
c_oil->cc.lastused);
|
|
|
|
json_object_int_add(json_source, "PacketCount",
|
|
|
|
c_oil->cc.pktcnt);
|
|
|
|
json_object_int_add(json_source, "ByteCount",
|
|
|
|
c_oil->cc.bytecnt);
|
|
|
|
json_object_int_add(json_source,
|
|
|
|
"WrongInterface",
|
|
|
|
c_oil->cc.wrong_if);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
vty_out(vty, "%-9d %-15s %-15s %-7s ",
|
|
|
|
c_oil->installed, src_str, grp_str,
|
|
|
|
ifp_in->name);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
|
|
|
|
++oif_vif_index) {
|
|
|
|
struct interface *ifp_out;
|
|
|
|
char oif_uptime[10];
|
|
|
|
int ttl;
|
|
|
|
|
|
|
|
ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
|
|
|
|
if (ttl < 1)
|
|
|
|
continue;
|
|
|
|
|
2017-05-21 14:29:56 +02:00
|
|
|
ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_time_uptime(
|
|
|
|
oif_uptime, sizeof(oif_uptime),
|
|
|
|
now - c_oil->oif_creation[oif_vif_index]);
|
|
|
|
|
|
|
|
if (ifp_out)
|
|
|
|
strcpy(out_ifname, ifp_out->name);
|
|
|
|
else
|
|
|
|
strcpy(out_ifname, "<oif?>");
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json_ifp_out = json_object_new_object();
|
|
|
|
json_object_string_add(json_ifp_out, "source",
|
|
|
|
src_str);
|
|
|
|
json_object_string_add(json_ifp_out, "group",
|
|
|
|
grp_str);
|
|
|
|
json_object_string_add(json_ifp_out,
|
|
|
|
"inboundInterface",
|
|
|
|
in_ifname);
|
|
|
|
json_object_string_add(json_ifp_out,
|
|
|
|
"outboundInterface",
|
|
|
|
out_ifname);
|
|
|
|
json_object_int_add(json_ifp_out, "installed",
|
|
|
|
c_oil->installed);
|
|
|
|
|
|
|
|
json_object_object_add(json_ifp_in, out_ifname,
|
|
|
|
json_ifp_out);
|
|
|
|
} else {
|
|
|
|
if (first_oif) {
|
|
|
|
first_oif = 0;
|
|
|
|
vty_out(vty, "%s(%c%c%c%c)", out_ifname,
|
|
|
|
(c_oil->oif_flags[oif_vif_index]
|
|
|
|
& PIM_OIF_FLAG_PROTO_IGMP)
|
|
|
|
? 'I'
|
|
|
|
: ' ',
|
|
|
|
(c_oil->oif_flags[oif_vif_index]
|
|
|
|
& PIM_OIF_FLAG_PROTO_PIM)
|
|
|
|
? 'J'
|
|
|
|
: ' ',
|
|
|
|
(c_oil->oif_flags[oif_vif_index]
|
|
|
|
& PIM_OIF_FLAG_PROTO_SOURCE)
|
|
|
|
? 'S'
|
|
|
|
: ' ',
|
|
|
|
(c_oil->oif_flags[oif_vif_index]
|
|
|
|
& PIM_OIF_FLAG_PROTO_STAR)
|
|
|
|
? '*'
|
|
|
|
: ' ');
|
|
|
|
} else
|
|
|
|
vty_out(vty, ", %s(%c%c%c%c)",
|
|
|
|
out_ifname,
|
|
|
|
(c_oil->oif_flags[oif_vif_index]
|
|
|
|
& PIM_OIF_FLAG_PROTO_IGMP)
|
|
|
|
? 'I'
|
|
|
|
: ' ',
|
|
|
|
(c_oil->oif_flags[oif_vif_index]
|
|
|
|
& PIM_OIF_FLAG_PROTO_PIM)
|
|
|
|
? 'J'
|
|
|
|
: ' ',
|
|
|
|
(c_oil->oif_flags[oif_vif_index]
|
|
|
|
& PIM_OIF_FLAG_PROTO_SOURCE)
|
|
|
|
? 'S'
|
|
|
|
: ' ',
|
|
|
|
(c_oil->oif_flags[oif_vif_index]
|
|
|
|
& PIM_OIF_FLAG_PROTO_STAR)
|
|
|
|
? '*'
|
|
|
|
: ' ');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!uj)
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (uj) {
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
} else {
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
}
|
2016-09-28 03:33:33 +02:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void pim_show_neighbors(struct vty *vty, struct pim_instance *pim,
|
|
|
|
u_char uj)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *node;
|
|
|
|
struct listnode *neighnode;
|
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
struct pim_neighbor *neigh;
|
|
|
|
time_t now;
|
|
|
|
char uptime[10];
|
|
|
|
char expire[10];
|
|
|
|
char neigh_src_str[INET_ADDRSTRLEN];
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_ifp_rows = NULL;
|
|
|
|
json_object *json_row = NULL;
|
|
|
|
|
|
|
|
now = pim_time_monotonic_sec();
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json = json_object_new_object();
|
|
|
|
} else {
|
|
|
|
vty_out(vty,
|
|
|
|
"Interface Neighbor Uptime Holdtime DR Pri\n");
|
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_ifp = ifp->info;
|
|
|
|
|
|
|
|
if (!pim_ifp)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (pim_ifp->pim_sock_fd < 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (uj)
|
|
|
|
json_ifp_rows = json_object_new_object();
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
|
|
|
|
neigh)) {
|
|
|
|
pim_inet4_dump("<src?>", neigh->source_addr,
|
|
|
|
neigh_src_str, sizeof(neigh_src_str));
|
|
|
|
pim_time_uptime(uptime, sizeof(uptime),
|
|
|
|
now - neigh->creation);
|
|
|
|
pim_time_timer_to_hhmmss(expire, sizeof(expire),
|
|
|
|
neigh->t_expire_timer);
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json_row = json_object_new_object();
|
|
|
|
json_object_string_add(json_row, "interface",
|
|
|
|
ifp->name);
|
|
|
|
json_object_string_add(json_row, "neighbor",
|
|
|
|
neigh_src_str);
|
|
|
|
json_object_string_add(json_row, "upTime",
|
|
|
|
uptime);
|
|
|
|
json_object_string_add(json_row, "holdTime",
|
|
|
|
expire);
|
|
|
|
json_object_int_add(json_row, "holdTimeMax",
|
|
|
|
neigh->holdtime);
|
|
|
|
json_object_int_add(json_row, "drPriority",
|
|
|
|
neigh->dr_priority);
|
|
|
|
json_object_object_add(json_ifp_rows,
|
|
|
|
neigh_src_str, json_row);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
vty_out(vty, "%-9s %15s %8s %8s %6d\n",
|
|
|
|
ifp->name, neigh_src_str, uptime,
|
|
|
|
expire, neigh->dr_priority);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json_object_object_add(json, ifp->name, json_ifp_rows);
|
|
|
|
json_ifp_rows = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uj) {
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void pim_show_neighbors_secondary(struct vty *vty,
|
|
|
|
struct pim_instance *pim)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *node;
|
|
|
|
struct interface *ifp;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty,
|
|
|
|
"Interface Address Neighbor Secondary \n");
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
struct in_addr ifaddr;
|
|
|
|
struct listnode *neighnode;
|
|
|
|
struct pim_neighbor *neigh;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_ifp = ifp->info;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!pim_ifp)
|
|
|
|
continue;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (pim_ifp->pim_sock_fd < 0)
|
|
|
|
continue;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
ifaddr = pim_ifp->primary_address;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
|
|
|
|
neigh)) {
|
|
|
|
char neigh_src_str[INET_ADDRSTRLEN];
|
|
|
|
struct listnode *prefix_node;
|
|
|
|
struct prefix *p;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!neigh->prefix_list)
|
|
|
|
continue;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_inet4_dump("<src?>", neigh->source_addr,
|
|
|
|
neigh_src_str, sizeof(neigh_src_str));
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list,
|
|
|
|
prefix_node, p)) {
|
|
|
|
char neigh_sec_str[PREFIX2STR_BUFFER];
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
prefix2str(p, neigh_sec_str,
|
|
|
|
sizeof(neigh_sec_str));
|
|
|
|
|
|
|
|
vty_out(vty, "%-9s %-15s %-15s %-15s\n",
|
|
|
|
ifp->name, inet_ntoa(ifaddr),
|
|
|
|
neigh_src_str, neigh_sec_str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
static void json_object_pim_upstream_add(json_object *json,
|
|
|
|
struct pim_upstream *up)
|
2016-09-14 17:12:13 +02:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
|
|
|
|
json_object_boolean_true_add(json, "drJoinDesired");
|
2016-09-14 17:12:13 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED)
|
|
|
|
json_object_boolean_true_add(json, "drJoinDesiredUpdated");
|
2016-09-14 17:12:13 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
|
|
|
|
json_object_boolean_true_add(json, "firstHopRouter");
|
2016-09-14 17:12:13 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
|
|
|
|
json_object_boolean_true_add(json, "sourceIgmp");
|
2016-09-14 17:12:13 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_PIM)
|
|
|
|
json_object_boolean_true_add(json, "sourcePim");
|
2016-11-08 19:34:31 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_STREAM)
|
|
|
|
json_object_boolean_true_add(json, "sourceStream");
|
2016-09-14 17:12:13 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
/* XXX: need to print ths flag in the plain text display as well */
|
|
|
|
if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_MSDP)
|
|
|
|
json_object_boolean_true_add(json, "sourceMsdp");
|
2017-03-09 20:42:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static const char *
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_upstream_state2brief_str(enum pim_upstream_state join_state,
|
|
|
|
char *state_str)
|
|
|
|
{
|
|
|
|
switch (join_state) {
|
|
|
|
case PIM_UPSTREAM_NOTJOINED:
|
|
|
|
strcpy(state_str, "NotJ");
|
|
|
|
break;
|
|
|
|
case PIM_UPSTREAM_JOINED:
|
|
|
|
strcpy(state_str, "J");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
strcpy(state_str, "Unk");
|
|
|
|
}
|
|
|
|
return state_str;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state,
|
|
|
|
char *state_str)
|
|
|
|
{
|
|
|
|
switch (reg_state) {
|
|
|
|
case PIM_REG_NOINFO:
|
|
|
|
strcpy(state_str, "RegNI");
|
|
|
|
break;
|
|
|
|
case PIM_REG_JOIN:
|
|
|
|
strcpy(state_str, "RegJ");
|
|
|
|
break;
|
|
|
|
case PIM_REG_JOIN_PENDING:
|
|
|
|
case PIM_REG_PRUNE:
|
|
|
|
strcpy(state_str, "RegP");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
strcpy(state_str, "Unk");
|
|
|
|
}
|
|
|
|
return state_str;
|
2017-03-09 20:42:55 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 13:25:30 +02:00
|
|
|
static void pim_show_upstream(struct vty *vty, struct pim_instance *pim,
|
|
|
|
u_char uj)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *upnode;
|
|
|
|
struct pim_upstream *up;
|
|
|
|
time_t now;
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_group = NULL;
|
|
|
|
json_object *json_row = NULL;
|
|
|
|
|
|
|
|
now = pim_time_monotonic_sec();
|
|
|
|
|
|
|
|
if (uj)
|
|
|
|
json = json_object_new_object();
|
|
|
|
else
|
|
|
|
vty_out(vty,
|
|
|
|
"Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
|
|
|
|
|
2017-05-23 13:25:30 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
char src_str[INET_ADDRSTRLEN];
|
|
|
|
char grp_str[INET_ADDRSTRLEN];
|
|
|
|
char uptime[10];
|
|
|
|
char join_timer[10];
|
|
|
|
char rs_timer[10];
|
|
|
|
char ka_timer[10];
|
|
|
|
char msdp_reg_timer[10];
|
|
|
|
char state_str[PIM_REG_STATE_STR_LEN];
|
|
|
|
|
|
|
|
pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
|
|
|
|
pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
|
|
|
|
pim_time_uptime(uptime, sizeof(uptime),
|
|
|
|
now - up->state_transition);
|
|
|
|
pim_time_timer_to_hhmmss(join_timer, sizeof(join_timer),
|
|
|
|
up->t_join_timer);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If we have a J/P timer for the neighbor display that
|
|
|
|
*/
|
|
|
|
if (!up->t_join_timer) {
|
|
|
|
struct pim_neighbor *nbr;
|
|
|
|
|
|
|
|
nbr = pim_neighbor_find(
|
|
|
|
up->rpf.source_nexthop.interface,
|
|
|
|
up->rpf.rpf_addr.u.prefix4);
|
|
|
|
if (nbr)
|
|
|
|
pim_time_timer_to_hhmmss(join_timer,
|
|
|
|
sizeof(join_timer),
|
|
|
|
nbr->jp_timer);
|
|
|
|
}
|
|
|
|
|
|
|
|
pim_time_timer_to_hhmmss(rs_timer, sizeof(rs_timer),
|
|
|
|
up->t_rs_timer);
|
|
|
|
pim_time_timer_to_hhmmss(ka_timer, sizeof(ka_timer),
|
|
|
|
up->t_ka_timer);
|
|
|
|
pim_time_timer_to_hhmmss(msdp_reg_timer, sizeof(msdp_reg_timer),
|
|
|
|
up->t_msdp_reg_timer);
|
|
|
|
|
|
|
|
pim_upstream_state2brief_str(up->join_state, state_str);
|
|
|
|
if (up->reg_state != PIM_REG_NOINFO) {
|
|
|
|
char tmp_str[PIM_REG_STATE_STR_LEN];
|
|
|
|
|
|
|
|
sprintf(state_str + strlen(state_str), ",%s",
|
|
|
|
pim_reg_state2brief_str(up->reg_state,
|
|
|
|
tmp_str));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json_object_object_get_ex(json, grp_str, &json_group);
|
|
|
|
|
|
|
|
if (!json_group) {
|
|
|
|
json_group = json_object_new_object();
|
|
|
|
json_object_object_add(json, grp_str,
|
|
|
|
json_group);
|
|
|
|
}
|
|
|
|
|
|
|
|
json_row = json_object_new_object();
|
|
|
|
json_object_pim_upstream_add(json_row, up);
|
|
|
|
json_object_string_add(
|
|
|
|
json_row, "inboundInterface",
|
|
|
|
up->rpf.source_nexthop.interface->name);
|
|
|
|
json_object_string_add(json_row, "source", src_str);
|
|
|
|
json_object_string_add(json_row, "group", grp_str);
|
|
|
|
json_object_string_add(json_row, "state", state_str);
|
|
|
|
json_object_string_add(
|
|
|
|
json_row, "joinState",
|
|
|
|
pim_upstream_state2str(up->join_state));
|
|
|
|
json_object_string_add(
|
|
|
|
json_row, "regState",
|
|
|
|
pim_reg_state2str(up->reg_state, state_str));
|
|
|
|
json_object_string_add(json_row, "upTime", uptime);
|
|
|
|
json_object_string_add(json_row, "joinTimer",
|
|
|
|
join_timer);
|
|
|
|
json_object_string_add(json_row, "resetTimer",
|
|
|
|
rs_timer);
|
|
|
|
json_object_string_add(json_row, "keepaliveTimer",
|
|
|
|
ka_timer);
|
|
|
|
json_object_string_add(json_row, "msdpRegTimer",
|
|
|
|
msdp_reg_timer);
|
|
|
|
json_object_int_add(json_row, "refCount",
|
|
|
|
up->ref_count);
|
|
|
|
json_object_int_add(json_row, "sptBit", up->sptbit);
|
|
|
|
json_object_object_add(json_group, src_str, json_row);
|
|
|
|
} else {
|
|
|
|
vty_out(vty,
|
|
|
|
"%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
|
|
|
|
up->rpf.source_nexthop.interface->name, src_str,
|
|
|
|
grp_str, state_str, uptime, join_timer,
|
|
|
|
rs_timer, ka_timer, up->ref_count);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uj) {
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void pim_show_join_desired(struct vty *vty, struct pim_instance *pim,
|
2017-05-20 20:17:48 +02:00
|
|
|
u_char uj)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *chnode;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
struct pim_ifchannel *ch;
|
|
|
|
char src_str[INET_ADDRSTRLEN];
|
|
|
|
char grp_str[INET_ADDRSTRLEN];
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_group = NULL;
|
|
|
|
json_object *json_row = NULL;
|
|
|
|
|
|
|
|
if (uj)
|
|
|
|
json = json_object_new_object();
|
|
|
|
else
|
|
|
|
vty_out(vty,
|
|
|
|
"Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
|
|
|
|
|
|
|
|
/* scan per-interface (S,G) state */
|
2017-05-20 20:17:48 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->ifchannel_list, chnode, ch)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
/* scan all interfaces */
|
|
|
|
pim_ifp = ch->interface->info;
|
|
|
|
if (!pim_ifp)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
struct pim_upstream *up = ch->upstream;
|
|
|
|
|
|
|
|
pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
|
|
|
|
pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json_object_object_get_ex(json, grp_str, &json_group);
|
|
|
|
|
|
|
|
if (!json_group) {
|
|
|
|
json_group = json_object_new_object();
|
|
|
|
json_object_object_add(json, grp_str,
|
|
|
|
json_group);
|
|
|
|
}
|
|
|
|
|
|
|
|
json_row = json_object_new_object();
|
|
|
|
json_object_pim_upstream_add(json_row, up);
|
|
|
|
json_object_string_add(json_row, "interface",
|
|
|
|
ch->interface->name);
|
|
|
|
json_object_string_add(json_row, "source", src_str);
|
|
|
|
json_object_string_add(json_row, "group", grp_str);
|
|
|
|
|
|
|
|
if (pim_macro_ch_lost_assert(ch))
|
|
|
|
json_object_boolean_true_add(json_row,
|
|
|
|
"lostAssert");
|
|
|
|
|
|
|
|
if (pim_macro_chisin_joins(ch))
|
|
|
|
json_object_boolean_true_add(json_row, "joins");
|
|
|
|
|
|
|
|
if (pim_macro_chisin_pim_include(ch))
|
|
|
|
json_object_boolean_true_add(json_row,
|
|
|
|
"pimInclude");
|
|
|
|
|
2017-05-23 13:25:30 +02:00
|
|
|
if (pim_upstream_evaluate_join_desired(pim, up))
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_boolean_true_add(
|
|
|
|
json_row, "evaluateJoinDesired");
|
|
|
|
|
|
|
|
json_object_object_add(json_group, src_str, json_row);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
vty_out(vty,
|
|
|
|
"%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
|
|
|
|
ch->interface->name, src_str, grp_str,
|
|
|
|
pim_macro_ch_lost_assert(ch) ? "yes" : "no",
|
|
|
|
pim_macro_chisin_joins(ch) ? "yes" : "no",
|
|
|
|
pim_macro_chisin_pim_include(ch) ? "yes" : "no",
|
|
|
|
PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(
|
|
|
|
up->flags)
|
|
|
|
? "yes"
|
|
|
|
: "no",
|
2017-05-23 13:25:30 +02:00
|
|
|
pim_upstream_evaluate_join_desired(pim, up)
|
2017-05-20 01:36:53 +02:00
|
|
|
? "yes"
|
|
|
|
: "no");
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uj) {
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void pim_show_upstream_rpf(struct vty *vty, struct pim_instance *pim,
|
|
|
|
u_char uj)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *upnode;
|
|
|
|
struct pim_upstream *up;
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_group = NULL;
|
|
|
|
json_object *json_row = NULL;
|
|
|
|
|
|
|
|
if (uj)
|
|
|
|
json = json_object_new_object();
|
|
|
|
else
|
|
|
|
vty_out(vty,
|
|
|
|
"Source Group RpfIface RibNextHop RpfAddress \n");
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
char src_str[INET_ADDRSTRLEN];
|
|
|
|
char grp_str[INET_ADDRSTRLEN];
|
|
|
|
char rpf_nexthop_str[PREFIX_STRLEN];
|
|
|
|
char rpf_addr_str[PREFIX_STRLEN];
|
|
|
|
struct pim_rpf *rpf;
|
|
|
|
const char *rpf_ifname;
|
|
|
|
|
|
|
|
rpf = &up->rpf;
|
|
|
|
|
|
|
|
pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
|
|
|
|
pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
|
|
|
|
pim_addr_dump("<nexthop?>",
|
|
|
|
&rpf->source_nexthop.mrib_nexthop_addr,
|
|
|
|
rpf_nexthop_str, sizeof(rpf_nexthop_str));
|
|
|
|
pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str,
|
|
|
|
sizeof(rpf_addr_str));
|
|
|
|
|
2017-07-22 14:52:33 +02:00
|
|
|
rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json_object_object_get_ex(json, grp_str, &json_group);
|
|
|
|
|
|
|
|
if (!json_group) {
|
|
|
|
json_group = json_object_new_object();
|
|
|
|
json_object_object_add(json, grp_str,
|
|
|
|
json_group);
|
|
|
|
}
|
|
|
|
|
|
|
|
json_row = json_object_new_object();
|
|
|
|
json_object_pim_upstream_add(json_row, up);
|
|
|
|
json_object_string_add(json_row, "source", src_str);
|
|
|
|
json_object_string_add(json_row, "group", grp_str);
|
|
|
|
json_object_string_add(json_row, "rpfInterface",
|
|
|
|
rpf_ifname);
|
|
|
|
json_object_string_add(json_row, "ribNexthop",
|
|
|
|
rpf_nexthop_str);
|
|
|
|
json_object_string_add(json_row, "rpfAddress",
|
|
|
|
rpf_addr_str);
|
|
|
|
json_object_object_add(json_group, src_str, json_row);
|
|
|
|
} else {
|
|
|
|
vty_out(vty, "%-15s %-15s %-8s %-15s %-15s\n", src_str,
|
|
|
|
grp_str, rpf_ifname, rpf_nexthop_str,
|
|
|
|
rpf_addr_str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uj) {
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void show_rpf_refresh_stats(struct vty *vty, time_t now,
|
|
|
|
json_object *json)
|
|
|
|
{
|
|
|
|
char refresh_uptime[10];
|
|
|
|
|
|
|
|
pim_time_uptime_begin(refresh_uptime, sizeof(refresh_uptime), now,
|
|
|
|
qpim_rpf_cache_refresh_last);
|
|
|
|
|
|
|
|
if (json) {
|
|
|
|
json_object_int_add(json, "rpfCacheRefreshDelayMsecs",
|
|
|
|
qpim_rpf_cache_refresh_delay_msec);
|
|
|
|
json_object_int_add(
|
|
|
|
json, "rpfCacheRefreshTimer",
|
|
|
|
pim_time_timer_remain_msec(qpim_rpf_cache_refresher));
|
|
|
|
json_object_int_add(json, "rpfCacheRefreshRequests",
|
|
|
|
qpim_rpf_cache_refresh_requests);
|
|
|
|
json_object_int_add(json, "rpfCacheRefreshEvents",
|
|
|
|
qpim_rpf_cache_refresh_events);
|
|
|
|
json_object_string_add(json, "rpfCacheRefreshLast",
|
|
|
|
refresh_uptime);
|
|
|
|
json_object_int_add(json, "nexthopLookups",
|
|
|
|
qpim_nexthop_lookups);
|
|
|
|
json_object_int_add(json, "nexthopLookupsAvoided",
|
|
|
|
nexthop_lookups_avoided);
|
|
|
|
} else {
|
|
|
|
vty_out(vty,
|
|
|
|
"RPF Cache Refresh Delay: %ld msecs\n"
|
|
|
|
"RPF Cache Refresh Timer: %ld msecs\n"
|
|
|
|
"RPF Cache Refresh Requests: %lld\n"
|
|
|
|
"RPF Cache Refresh Events: %lld\n"
|
|
|
|
"RPF Cache Refresh Last: %s\n"
|
|
|
|
"Nexthop Lookups: %lld\n"
|
|
|
|
"Nexthop Lookups Avoided: %lld\n",
|
|
|
|
qpim_rpf_cache_refresh_delay_msec,
|
|
|
|
pim_time_timer_remain_msec(qpim_rpf_cache_refresher),
|
|
|
|
(long long)qpim_rpf_cache_refresh_requests,
|
|
|
|
(long long)qpim_rpf_cache_refresh_events,
|
|
|
|
refresh_uptime, (long long)qpim_nexthop_lookups,
|
|
|
|
(long long)nexthop_lookups_avoided);
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void show_scan_oil_stats(struct vty *vty, struct pim_instance *pim,
|
|
|
|
time_t now)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
char uptime_scan_oil[10];
|
|
|
|
char uptime_mroute_add[10];
|
|
|
|
char uptime_mroute_del[10];
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_time_uptime_begin(uptime_scan_oil, sizeof(uptime_scan_oil), now,
|
|
|
|
qpim_scan_oil_last);
|
|
|
|
pim_time_uptime_begin(uptime_mroute_add, sizeof(uptime_mroute_add), now,
|
2017-05-23 14:57:11 +02:00
|
|
|
pim->mroute_add_last);
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_time_uptime_begin(uptime_mroute_del, sizeof(uptime_mroute_del), now,
|
2017-05-23 14:57:11 +02:00
|
|
|
pim->mroute_del_last);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty,
|
|
|
|
"Scan OIL - Last: %s Events: %lld\n"
|
|
|
|
"MFC Add - Last: %s Events: %lld\n"
|
|
|
|
"MFC Del - Last: %s Events: %lld\n",
|
|
|
|
uptime_scan_oil, (long long)qpim_scan_oil_events,
|
2017-05-23 14:57:11 +02:00
|
|
|
uptime_mroute_add, (long long)pim->mroute_add_events,
|
|
|
|
uptime_mroute_del, (long long)pim->mroute_del_events);
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void pim_show_rpf(struct vty *vty, struct pim_instance *pim, u_char uj)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *up_node;
|
|
|
|
struct pim_upstream *up;
|
|
|
|
time_t now = pim_time_monotonic_sec();
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_group = NULL;
|
|
|
|
json_object *json_row = NULL;
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json = json_object_new_object();
|
|
|
|
show_rpf_refresh_stats(vty, now, json);
|
|
|
|
} else {
|
|
|
|
show_rpf_refresh_stats(vty, now, json);
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
vty_out(vty,
|
|
|
|
"Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
|
|
|
|
}
|
pimd: Pim Nexthop Tracking support with ECMP
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>
2017-04-05 22:14:12 +02:00
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, up_node, up)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
char src_str[INET_ADDRSTRLEN];
|
|
|
|
char grp_str[INET_ADDRSTRLEN];
|
|
|
|
char rpf_addr_str[PREFIX_STRLEN];
|
|
|
|
char rib_nexthop_str[PREFIX_STRLEN];
|
|
|
|
const char *rpf_ifname;
|
|
|
|
struct pim_rpf *rpf = &up->rpf;
|
|
|
|
|
|
|
|
pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
|
|
|
|
pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
|
|
|
|
pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str,
|
|
|
|
sizeof(rpf_addr_str));
|
|
|
|
pim_addr_dump("<nexthop?>",
|
|
|
|
&rpf->source_nexthop.mrib_nexthop_addr,
|
|
|
|
rib_nexthop_str, sizeof(rib_nexthop_str));
|
|
|
|
|
2017-07-22 14:52:33 +02:00
|
|
|
rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json_object_object_get_ex(json, grp_str, &json_group);
|
|
|
|
|
|
|
|
if (!json_group) {
|
|
|
|
json_group = json_object_new_object();
|
|
|
|
json_object_object_add(json, grp_str,
|
|
|
|
json_group);
|
|
|
|
}
|
|
|
|
|
|
|
|
json_row = json_object_new_object();
|
|
|
|
json_object_string_add(json_row, "source", src_str);
|
|
|
|
json_object_string_add(json_row, "group", grp_str);
|
|
|
|
json_object_string_add(json_row, "rpfInterface",
|
|
|
|
rpf_ifname);
|
|
|
|
json_object_string_add(json_row, "rpfAddress",
|
|
|
|
rpf_addr_str);
|
|
|
|
json_object_string_add(json_row, "ribNexthop",
|
|
|
|
rib_nexthop_str);
|
|
|
|
json_object_int_add(
|
|
|
|
json_row, "routeMetric",
|
|
|
|
rpf->source_nexthop.mrib_route_metric);
|
|
|
|
json_object_int_add(
|
|
|
|
json_row, "routePreference",
|
|
|
|
rpf->source_nexthop.mrib_metric_preference);
|
|
|
|
json_object_object_add(json_group, src_str, json_row);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
vty_out(vty, "%-15s %-15s %-8s %-15s %-15s %6d %4d\n",
|
|
|
|
src_str, grp_str, rpf_ifname, rpf_addr_str,
|
|
|
|
rib_nexthop_str,
|
|
|
|
rpf->source_nexthop.mrib_route_metric,
|
|
|
|
rpf->source_nexthop.mrib_metric_preference);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uj) {
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
}
|
pimd: Pim Nexthop Tracking support with ECMP
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>
2017-04-05 22:14:12 +02:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
struct pnc_cache_walk_data {
|
|
|
|
struct vty *vty;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
};
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
static int pim_print_pnc_cache_walkcb(struct hash_backet *backet, void *arg)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct pim_nexthop_cache *pnc = backet->data;
|
2017-05-23 14:57:11 +02:00
|
|
|
struct pnc_cache_walk_data *cwd = arg;
|
|
|
|
struct vty *vty = cwd->vty;
|
|
|
|
struct pim_instance *pim = cwd->pim;
|
2017-07-17 14:03:14 +02:00
|
|
|
struct nexthop *nh_node = NULL;
|
|
|
|
ifindex_t first_ifindex;
|
|
|
|
struct interface *ifp = NULL;
|
|
|
|
|
|
|
|
if (!pnc)
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
|
|
|
for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next) {
|
|
|
|
first_ifindex = nh_node->ifindex;
|
2017-05-23 14:57:11 +02:00
|
|
|
ifp = if_lookup_by_index(first_ifindex, pim->vrf_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
vty_out(vty, "%-15s ", inet_ntoa(pnc->rpf.rpf_addr.u.prefix4));
|
|
|
|
vty_out(vty, "%-14s ", ifp ? ifp->name : "NULL");
|
|
|
|
vty_out(vty, "%s ", inet_ntoa(nh_node->gate.ipv4));
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void pim_show_nexthop(struct vty *vty, struct pim_instance *pim)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
struct pnc_cache_walk_data cwd;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
cwd.vty = vty;
|
|
|
|
cwd.pim = pim;
|
|
|
|
vty_out(vty, "Number of registered addresses: %lu\n",
|
|
|
|
pim->rpf_hash->count);
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty, "Address Interface Nexthop\n");
|
|
|
|
vty_out(vty, "-------------------------------------------\n");
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
hash_walk(pim->rpf_hash, pim_print_pnc_cache_walkcb, &cwd);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void igmp_show_groups(struct vty *vty, struct pim_instance *pim,
|
|
|
|
u_char uj)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
|
|
|
struct listnode *ifnode;
|
|
|
|
struct interface *ifp;
|
|
|
|
time_t now;
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_iface = NULL;
|
|
|
|
json_object *json_row = NULL;
|
|
|
|
|
|
|
|
now = pim_time_monotonic_sec();
|
|
|
|
|
|
|
|
if (uj)
|
|
|
|
json = json_object_new_object();
|
|
|
|
else
|
|
|
|
vty_out(vty,
|
|
|
|
"Interface Address Group Mode Timer Srcs V Uptime \n");
|
|
|
|
|
|
|
|
/* scan interfaces */
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), ifnode, ifp)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
struct pim_interface *pim_ifp = ifp->info;
|
|
|
|
struct listnode *sock_node;
|
|
|
|
struct igmp_sock *igmp;
|
|
|
|
|
|
|
|
if (!pim_ifp)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* scan igmp sockets */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
|
|
|
|
igmp)) {
|
|
|
|
char ifaddr_str[INET_ADDRSTRLEN];
|
|
|
|
struct listnode *grpnode;
|
|
|
|
struct igmp_group *grp;
|
|
|
|
|
|
|
|
pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
|
|
|
|
sizeof(ifaddr_str));
|
|
|
|
|
|
|
|
/* scan igmp groups */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
|
|
|
|
grpnode, grp)) {
|
|
|
|
char group_str[INET_ADDRSTRLEN];
|
|
|
|
char hhmmss[10];
|
|
|
|
char uptime[10];
|
|
|
|
|
|
|
|
pim_inet4_dump("<group?>", grp->group_addr,
|
|
|
|
group_str, sizeof(group_str));
|
|
|
|
pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss),
|
|
|
|
grp->t_group_timer);
|
|
|
|
pim_time_uptime(uptime, sizeof(uptime),
|
|
|
|
now - grp->group_creation);
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json_object_object_get_ex(
|
|
|
|
json, ifp->name, &json_iface);
|
|
|
|
|
|
|
|
if (!json_iface) {
|
|
|
|
json_iface =
|
|
|
|
json_object_new_object();
|
|
|
|
json_object_pim_ifp_add(
|
|
|
|
json_iface, ifp);
|
|
|
|
json_object_object_add(
|
|
|
|
json, ifp->name,
|
|
|
|
json_iface);
|
|
|
|
}
|
|
|
|
|
|
|
|
json_row = json_object_new_object();
|
|
|
|
json_object_string_add(
|
|
|
|
json_row, "source", ifaddr_str);
|
|
|
|
json_object_string_add(
|
|
|
|
json_row, "group", group_str);
|
|
|
|
|
|
|
|
if (grp->igmp_version == 3)
|
|
|
|
json_object_string_add(
|
|
|
|
json_row, "mode",
|
|
|
|
grp->group_filtermode_isexcl
|
|
|
|
? "EXCLUDE"
|
|
|
|
: "INCLUDE");
|
|
|
|
|
|
|
|
json_object_string_add(json_row,
|
|
|
|
"timer", hhmmss);
|
|
|
|
json_object_int_add(
|
|
|
|
json_row, "sourcesCount",
|
|
|
|
grp->group_source_list
|
|
|
|
? listcount(
|
|
|
|
grp->group_source_list)
|
|
|
|
: 0);
|
|
|
|
json_object_int_add(json_row, "version",
|
|
|
|
grp->igmp_version);
|
|
|
|
json_object_string_add(
|
|
|
|
json_row, "uptime", uptime);
|
|
|
|
json_object_object_add(json_iface,
|
|
|
|
group_str,
|
|
|
|
json_row);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
vty_out(vty,
|
|
|
|
"%-9s %-15s %-15s %4s %8s %4d %d %8s\n",
|
|
|
|
ifp->name, ifaddr_str,
|
|
|
|
group_str,
|
|
|
|
grp->igmp_version == 3
|
|
|
|
? (grp->group_filtermode_isexcl
|
|
|
|
? "EXCL"
|
|
|
|
: "INCL")
|
|
|
|
: "----",
|
|
|
|
hhmmss,
|
|
|
|
grp->group_source_list
|
|
|
|
? listcount(
|
|
|
|
grp->group_source_list)
|
|
|
|
: 0,
|
|
|
|
grp->igmp_version, uptime);
|
|
|
|
}
|
|
|
|
} /* scan igmp groups */
|
|
|
|
} /* scan igmp sockets */
|
|
|
|
} /* scan interfaces */
|
|
|
|
|
|
|
|
if (uj) {
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void igmp_show_group_retransmission(struct vty *vty,
|
|
|
|
struct pim_instance *pim)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *ifnode;
|
|
|
|
struct interface *ifp;
|
|
|
|
|
|
|
|
vty_out(vty,
|
|
|
|
"Interface Address Group RetTimer Counter RetSrcs\n");
|
|
|
|
|
|
|
|
/* scan interfaces */
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), ifnode, ifp)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
struct pim_interface *pim_ifp = ifp->info;
|
|
|
|
struct listnode *sock_node;
|
|
|
|
struct igmp_sock *igmp;
|
|
|
|
|
|
|
|
if (!pim_ifp)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* scan igmp sockets */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
|
|
|
|
igmp)) {
|
|
|
|
char ifaddr_str[INET_ADDRSTRLEN];
|
|
|
|
struct listnode *grpnode;
|
|
|
|
struct igmp_group *grp;
|
|
|
|
|
|
|
|
pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
|
|
|
|
sizeof(ifaddr_str));
|
|
|
|
|
|
|
|
/* scan igmp groups */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
|
|
|
|
grpnode, grp)) {
|
|
|
|
char group_str[INET_ADDRSTRLEN];
|
|
|
|
char grp_retr_mmss[10];
|
|
|
|
struct listnode *src_node;
|
|
|
|
struct igmp_source *src;
|
|
|
|
int grp_retr_sources = 0;
|
|
|
|
|
|
|
|
pim_inet4_dump("<group?>", grp->group_addr,
|
|
|
|
group_str, sizeof(group_str));
|
|
|
|
pim_time_timer_to_mmss(
|
|
|
|
grp_retr_mmss, sizeof(grp_retr_mmss),
|
|
|
|
grp->t_group_query_retransmit_timer);
|
|
|
|
|
|
|
|
|
|
|
|
/* count group sources with retransmission state
|
|
|
|
*/
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(
|
|
|
|
grp->group_source_list, src_node,
|
|
|
|
src)) {
|
|
|
|
if (src->source_query_retransmit_count
|
|
|
|
> 0) {
|
|
|
|
++grp_retr_sources;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vty_out(vty, "%-9s %-15s %-15s %-8s %7d %7d\n",
|
|
|
|
ifp->name, ifaddr_str, group_str,
|
|
|
|
grp_retr_mmss,
|
|
|
|
grp->group_specific_query_retransmit_count,
|
|
|
|
grp_retr_sources);
|
|
|
|
|
|
|
|
} /* scan igmp groups */
|
|
|
|
} /* scan igmp sockets */
|
|
|
|
} /* scan interfaces */
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void igmp_show_sources(struct vty *vty, struct pim_instance *pim)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *ifnode;
|
|
|
|
struct interface *ifp;
|
|
|
|
time_t now;
|
|
|
|
|
|
|
|
now = pim_time_monotonic_sec();
|
|
|
|
|
|
|
|
vty_out(vty,
|
|
|
|
"Interface Address Group Source Timer Fwd Uptime \n");
|
|
|
|
|
|
|
|
/* scan interfaces */
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), ifnode, ifp)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
struct pim_interface *pim_ifp = ifp->info;
|
|
|
|
struct listnode *sock_node;
|
|
|
|
struct igmp_sock *igmp;
|
|
|
|
|
|
|
|
if (!pim_ifp)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* scan igmp sockets */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
|
|
|
|
igmp)) {
|
|
|
|
char ifaddr_str[INET_ADDRSTRLEN];
|
|
|
|
struct listnode *grpnode;
|
|
|
|
struct igmp_group *grp;
|
|
|
|
|
|
|
|
pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
|
|
|
|
sizeof(ifaddr_str));
|
|
|
|
|
|
|
|
/* scan igmp groups */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
|
|
|
|
grpnode, grp)) {
|
|
|
|
char group_str[INET_ADDRSTRLEN];
|
|
|
|
struct listnode *srcnode;
|
|
|
|
struct igmp_source *src;
|
|
|
|
|
|
|
|
pim_inet4_dump("<group?>", grp->group_addr,
|
|
|
|
group_str, sizeof(group_str));
|
|
|
|
|
|
|
|
/* scan group sources */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(
|
|
|
|
grp->group_source_list, srcnode,
|
|
|
|
src)) {
|
|
|
|
char source_str[INET_ADDRSTRLEN];
|
|
|
|
char mmss[10];
|
|
|
|
char uptime[10];
|
|
|
|
|
|
|
|
pim_inet4_dump(
|
|
|
|
"<source?>", src->source_addr,
|
|
|
|
source_str, sizeof(source_str));
|
|
|
|
|
|
|
|
pim_time_timer_to_mmss(
|
|
|
|
mmss, sizeof(mmss),
|
|
|
|
src->t_source_timer);
|
|
|
|
|
|
|
|
pim_time_uptime(
|
|
|
|
uptime, sizeof(uptime),
|
|
|
|
now - src->source_creation);
|
|
|
|
|
|
|
|
vty_out(vty,
|
|
|
|
"%-9s %-15s %-15s %-15s %5s %3s %8s\n",
|
|
|
|
ifp->name, ifaddr_str,
|
|
|
|
group_str, source_str, mmss,
|
|
|
|
IGMP_SOURCE_TEST_FORWARDING(
|
|
|
|
src->source_flags)
|
|
|
|
? "Y"
|
|
|
|
: "N",
|
|
|
|
uptime);
|
|
|
|
|
|
|
|
} /* scan group sources */
|
|
|
|
} /* scan igmp groups */
|
|
|
|
} /* scan igmp sockets */
|
|
|
|
} /* scan interfaces */
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void igmp_show_source_retransmission(struct vty *vty,
|
|
|
|
struct pim_instance *pim)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *ifnode;
|
|
|
|
struct interface *ifp;
|
|
|
|
|
|
|
|
vty_out(vty,
|
|
|
|
"Interface Address Group Source Counter\n");
|
|
|
|
|
|
|
|
/* scan interfaces */
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), ifnode, ifp)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
struct pim_interface *pim_ifp = ifp->info;
|
|
|
|
struct listnode *sock_node;
|
|
|
|
struct igmp_sock *igmp;
|
|
|
|
|
|
|
|
if (!pim_ifp)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* scan igmp sockets */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
|
|
|
|
igmp)) {
|
|
|
|
char ifaddr_str[INET_ADDRSTRLEN];
|
|
|
|
struct listnode *grpnode;
|
|
|
|
struct igmp_group *grp;
|
|
|
|
|
|
|
|
pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
|
|
|
|
sizeof(ifaddr_str));
|
|
|
|
|
|
|
|
/* scan igmp groups */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
|
|
|
|
grpnode, grp)) {
|
|
|
|
char group_str[INET_ADDRSTRLEN];
|
|
|
|
struct listnode *srcnode;
|
|
|
|
struct igmp_source *src;
|
|
|
|
|
|
|
|
pim_inet4_dump("<group?>", grp->group_addr,
|
|
|
|
group_str, sizeof(group_str));
|
|
|
|
|
|
|
|
/* scan group sources */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(
|
|
|
|
grp->group_source_list, srcnode,
|
|
|
|
src)) {
|
|
|
|
char source_str[INET_ADDRSTRLEN];
|
|
|
|
|
|
|
|
pim_inet4_dump(
|
|
|
|
"<source?>", src->source_addr,
|
|
|
|
source_str, sizeof(source_str));
|
|
|
|
|
|
|
|
vty_out(vty,
|
|
|
|
"%-9s %-15s %-15s %-15s %7d\n",
|
|
|
|
ifp->name, ifaddr_str,
|
|
|
|
group_str, source_str,
|
|
|
|
src->source_query_retransmit_count);
|
|
|
|
|
|
|
|
} /* scan group sources */
|
|
|
|
} /* scan igmp groups */
|
|
|
|
} /* scan igmp sockets */
|
|
|
|
} /* scan interfaces */
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void clear_igmp_interfaces(struct pim_instance *pim)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *ifnode;
|
|
|
|
struct listnode *ifnextnode;
|
|
|
|
struct interface *ifp;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(vrf_iflist(pim->vrf_id), ifnode, ifnextnode,
|
2017-07-17 14:03:14 +02:00
|
|
|
ifp)) {
|
|
|
|
pim_if_addr_del_all_igmp(ifp);
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(vrf_iflist(pim->vrf_id), ifnode, ifnextnode,
|
2017-07-17 14:03:14 +02:00
|
|
|
ifp)) {
|
|
|
|
pim_if_addr_add_all(ifp);
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void clear_pim_interfaces(struct pim_instance *pim)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *ifnode;
|
|
|
|
struct listnode *ifnextnode;
|
|
|
|
struct interface *ifp;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(vrf_iflist(pim->vrf_id), ifnode, ifnextnode,
|
2017-07-17 14:03:14 +02:00
|
|
|
ifp)) {
|
|
|
|
if (ifp->info) {
|
|
|
|
pim_neighbor_delete_all(ifp, "interface cleared");
|
|
|
|
}
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void clear_interfaces(struct pim_instance *pim)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
clear_igmp_interfaces(pim);
|
|
|
|
clear_pim_interfaces(pim);
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (clear_ip_interfaces,
|
|
|
|
clear_ip_interfaces_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"clear ip interfaces [vrf NAME]",
|
2015-02-04 07:01:14 +01:00
|
|
|
CLEAR_STR
|
|
|
|
IP_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
"Reset interfaces\n"
|
|
|
|
VRF_CMD_HELP_STR)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
clear_interfaces(vrf->info);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (clear_ip_igmp_interfaces,
|
|
|
|
clear_ip_igmp_interfaces_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"clear ip igmp [vrf NAME] interfaces",
|
2015-02-04 07:01:14 +01:00
|
|
|
CLEAR_STR
|
|
|
|
IP_STR
|
|
|
|
CLEAR_IP_IGMP_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2015-02-04 07:01:14 +01:00
|
|
|
"Reset IGMP interfaces\n")
|
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
clear_igmp_interfaces(vrf->info);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void mroute_add_all(struct pim_instance *pim)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *node;
|
|
|
|
struct channel_oil *c_oil;
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
if (pim_mroute_add(c_oil, __PRETTY_FUNCTION__)) {
|
|
|
|
/* just log warning */
|
|
|
|
char source_str[INET_ADDRSTRLEN];
|
|
|
|
char group_str[INET_ADDRSTRLEN];
|
|
|
|
pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
|
|
|
|
source_str, sizeof(source_str));
|
|
|
|
pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
|
|
|
|
group_str, sizeof(group_str));
|
|
|
|
zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
|
|
|
|
__FILE__, __PRETTY_FUNCTION__, source_str,
|
|
|
|
group_str);
|
|
|
|
}
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void mroute_del_all(struct pim_instance *pim)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *node;
|
|
|
|
struct channel_oil *c_oil;
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
if (pim_mroute_del(c_oil, __PRETTY_FUNCTION__)) {
|
|
|
|
/* just log warning */
|
|
|
|
char source_str[INET_ADDRSTRLEN];
|
|
|
|
char group_str[INET_ADDRSTRLEN];
|
|
|
|
pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
|
|
|
|
source_str, sizeof(source_str));
|
|
|
|
pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
|
|
|
|
group_str, sizeof(group_str));
|
|
|
|
zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
|
|
|
|
__FILE__, __PRETTY_FUNCTION__, source_str,
|
|
|
|
group_str);
|
|
|
|
}
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (clear_ip_mroute,
|
|
|
|
clear_ip_mroute_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"clear ip mroute [vrf NAME]",
|
2015-02-04 07:01:14 +01:00
|
|
|
CLEAR_STR
|
|
|
|
IP_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
"Reset multicast routes\n"
|
|
|
|
VRF_CMD_HELP_STR)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
mroute_del_all(vrf->info);
|
|
|
|
mroute_add_all(vrf->info);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (clear_ip_pim_interfaces,
|
|
|
|
clear_ip_pim_interfaces_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"clear ip pim [vrf NAME] interfaces",
|
2015-02-04 07:01:14 +01:00
|
|
|
CLEAR_STR
|
|
|
|
IP_STR
|
|
|
|
CLEAR_IP_PIM_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2015-02-04 07:01:14 +01:00
|
|
|
"Reset PIM interfaces\n")
|
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
clear_pim_interfaces(vrf->info);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-04-03 22:11:58 +02:00
|
|
|
DEFUN (clear_ip_pim_interface_traffic,
|
|
|
|
clear_ip_pim_interface_traffic_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"clear ip pim [vrf NAME] interface traffic",
|
2017-04-03 22:11:58 +02:00
|
|
|
"Reset functions\n"
|
|
|
|
"IP information\n"
|
|
|
|
"PIM clear commands\n"
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2017-04-03 22:11:58 +02:00
|
|
|
"Reset PIM interfaces\n"
|
|
|
|
"Reset Protocol Packet counters\n")
|
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *ifnode = NULL;
|
|
|
|
struct listnode *ifnextnode = NULL;
|
|
|
|
struct interface *ifp = NULL;
|
|
|
|
struct pim_interface *pim_ifp = NULL;
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS(vrf_iflist(vrf->vrf_id), ifnode, ifnextnode,
|
2017-07-17 14:03:14 +02:00
|
|
|
ifp)) {
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
|
|
|
|
if (!pim_ifp)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
pim_ifp->pim_ifstat_hello_recv = 0;
|
|
|
|
pim_ifp->pim_ifstat_hello_sent = 0;
|
|
|
|
pim_ifp->pim_ifstat_join_recv = 0;
|
|
|
|
pim_ifp->pim_ifstat_join_send = 0;
|
|
|
|
pim_ifp->pim_ifstat_prune_recv = 0;
|
|
|
|
pim_ifp->pim_ifstat_prune_send = 0;
|
|
|
|
pim_ifp->pim_ifstat_reg_recv = 0;
|
|
|
|
pim_ifp->pim_ifstat_reg_send = 0;
|
|
|
|
pim_ifp->pim_ifstat_reg_stop_recv = 0;
|
|
|
|
pim_ifp->pim_ifstat_reg_stop_send = 0;
|
|
|
|
pim_ifp->pim_ifstat_assert_recv = 0;
|
|
|
|
pim_ifp->pim_ifstat_assert_send = 0;
|
|
|
|
}
|
2017-04-03 22:11:58 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-04-03 22:11:58 +02:00
|
|
|
}
|
|
|
|
|
2015-02-04 07:01:14 +01:00
|
|
|
DEFUN (clear_ip_pim_oil,
|
|
|
|
clear_ip_pim_oil_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"clear ip pim [vrf NAME] oil",
|
2015-02-04 07:01:14 +01:00
|
|
|
CLEAR_STR
|
|
|
|
IP_STR
|
|
|
|
CLEAR_IP_PIM_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2015-02-04 07:01:14 +01:00
|
|
|
"Rescan PIM OIL (output interface list)\n")
|
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
pim_scan_oil(vrf->info);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_igmp_interface,
|
|
|
|
show_ip_igmp_interface_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip igmp [vrf NAME] interface [detail|WORD] [json]",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
IGMP_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2016-09-15 19:16:36 +02:00
|
|
|
"IGMP interface information\n"
|
pimd: Added json to 'show ip igmp group'
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
root@superm-redxp-05[quagga-pim]# vtysh -c 'show ip igmp group'
Interface Address Group Mode Timer Srcs V Uptime
br1 20.0.13.1 230.40.40.1 EXCL 00:03:24 1 3 00:01:28
root@superm-redxp-05[quagga-pim]#
root@superm-redxp-05[quagga-pim]#
root@superm-redxp-05[quagga-pim]# vtysh -c 'show ip igmp group json' |
python -m json.tool
{
"br1": {
"230.40.40.1": {
"group": "230.40.40.1",
"mode": "EXCLUDE",
"source": "20.0.13.1",
"sourcesCount": 1,
"timer": "00:03:23",
"uptime": "00:01:30",
"version": 3
},
"address": "20.0.13.1",
"flagBroadcast": true,
"flagMulticast": true,
"index": 96,
"lanDelayEnabled": true,
"name": "br1",
"state": "up"
}
}
root@superm-redxp-05[quagga-pim]#
2016-09-27 18:37:38 +02:00
|
|
|
"Detailed output\n"
|
2016-09-15 19:16:36 +02:00
|
|
|
"interface name\n"
|
|
|
|
"JavaScript Object Notation\n")
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
2017-07-17 14:03:14 +02:00
|
|
|
u_char uj = use_json(argc, argv);
|
2017-05-23 14:57:11 +02:00
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
2017-01-26 15:10:54 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (argv_find(argv, argc, "detail", &idx)
|
|
|
|
|| argv_find(argv, argc, "WORD", &idx))
|
2017-05-23 14:57:11 +02:00
|
|
|
igmp_show_interfaces_single(vty, vrf->info, argv[idx]->arg, uj);
|
2017-07-17 14:03:14 +02:00
|
|
|
else
|
2017-05-23 14:57:11 +02:00
|
|
|
igmp_show_interfaces(vty, vrf->info, uj);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_igmp_join,
|
|
|
|
show_ip_igmp_join_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip igmp [vrf NAME] join",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
IGMP_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2015-02-04 07:01:14 +01:00
|
|
|
"IGMP static join information\n")
|
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
igmp_show_interface_join(vty, vrf->info);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_igmp_groups,
|
|
|
|
show_ip_igmp_groups_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip igmp [vrf NAME] groups [json]",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
IGMP_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
pimd: Added json to 'show ip igmp group'
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
root@superm-redxp-05[quagga-pim]# vtysh -c 'show ip igmp group'
Interface Address Group Mode Timer Srcs V Uptime
br1 20.0.13.1 230.40.40.1 EXCL 00:03:24 1 3 00:01:28
root@superm-redxp-05[quagga-pim]#
root@superm-redxp-05[quagga-pim]#
root@superm-redxp-05[quagga-pim]# vtysh -c 'show ip igmp group json' |
python -m json.tool
{
"br1": {
"230.40.40.1": {
"group": "230.40.40.1",
"mode": "EXCLUDE",
"source": "20.0.13.1",
"sourcesCount": 1,
"timer": "00:03:23",
"uptime": "00:01:30",
"version": 3
},
"address": "20.0.13.1",
"flagBroadcast": true,
"flagMulticast": true,
"index": 96,
"lanDelayEnabled": true,
"name": "br1",
"state": "up"
}
}
root@superm-redxp-05[quagga-pim]#
2016-09-27 18:37:38 +02:00
|
|
|
IGMP_GROUP_STR
|
|
|
|
"JavaScript Object Notation\n")
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
2017-07-17 14:03:14 +02:00
|
|
|
u_char uj = use_json(argc, argv);
|
2017-05-23 14:57:11 +02:00
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
igmp_show_groups(vty, vrf->info, uj);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_igmp_groups_retransmissions,
|
|
|
|
show_ip_igmp_groups_retransmissions_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip igmp [vrf NAME] groups retransmissions",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
IGMP_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2015-02-04 07:01:14 +01:00
|
|
|
IGMP_GROUP_STR
|
|
|
|
"IGMP group retransmissions\n")
|
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
igmp_show_group_retransmission(vty, vrf->info);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_igmp_sources,
|
|
|
|
show_ip_igmp_sources_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip igmp [vrf NAME] sources",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
IGMP_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2015-02-04 07:01:14 +01:00
|
|
|
IGMP_SOURCE_STR)
|
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
igmp_show_sources(vty, vrf->info);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_igmp_sources_retransmissions,
|
|
|
|
show_ip_igmp_sources_retransmissions_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip igmp [vrf NAME] sources retransmissions",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
IGMP_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2015-02-04 07:01:14 +01:00
|
|
|
IGMP_SOURCE_STR
|
|
|
|
"IGMP source retransmissions\n")
|
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
igmp_show_source_retransmission(vty, vrf->info);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_pim_assert,
|
|
|
|
show_ip_pim_assert_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip pim [vrf NAME] assert",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2015-02-04 07:01:14 +01:00
|
|
|
"PIM interface assert\n")
|
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
pim_show_assert(vty, vrf->info);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_pim_assert_internal,
|
|
|
|
show_ip_pim_assert_internal_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip pim [vrf NAME] assert-internal",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2015-02-04 07:01:14 +01:00
|
|
|
"PIM interface internal assert state\n")
|
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
pim_show_assert_internal(vty, vrf->info);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_pim_assert_metric,
|
|
|
|
show_ip_pim_assert_metric_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip pim [vrf NAME] assert-metric",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2015-02-04 07:01:14 +01:00
|
|
|
"PIM interface assert metric\n")
|
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
pim_show_assert_metric(vty, vrf->info);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_pim_assert_winner_metric,
|
|
|
|
show_ip_pim_assert_winner_metric_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip pim [vrf NAME] assert-winner-metric",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2015-02-04 07:01:14 +01:00
|
|
|
"PIM interface assert winner metric\n")
|
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
pim_show_assert_winner_metric(vty, vrf->info);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_pim_interface,
|
|
|
|
show_ip_pim_interface_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip pim [vrf NAME] interface [detail|WORD] [json]",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2016-09-15 19:16:36 +02:00
|
|
|
"PIM interface information\n"
|
pimd: Added json to 'show ip igmp group'
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
root@superm-redxp-05[quagga-pim]# vtysh -c 'show ip igmp group'
Interface Address Group Mode Timer Srcs V Uptime
br1 20.0.13.1 230.40.40.1 EXCL 00:03:24 1 3 00:01:28
root@superm-redxp-05[quagga-pim]#
root@superm-redxp-05[quagga-pim]#
root@superm-redxp-05[quagga-pim]# vtysh -c 'show ip igmp group json' |
python -m json.tool
{
"br1": {
"230.40.40.1": {
"group": "230.40.40.1",
"mode": "EXCLUDE",
"source": "20.0.13.1",
"sourcesCount": 1,
"timer": "00:03:23",
"uptime": "00:01:30",
"version": 3
},
"address": "20.0.13.1",
"flagBroadcast": true,
"flagMulticast": true,
"index": 96,
"lanDelayEnabled": true,
"name": "br1",
"state": "up"
}
}
root@superm-redxp-05[quagga-pim]#
2016-09-27 18:37:38 +02:00
|
|
|
"Detailed output\n"
|
2016-09-15 19:16:36 +02:00
|
|
|
"interface name\n"
|
|
|
|
"JavaScript Object Notation\n")
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
2017-07-17 14:03:14 +02:00
|
|
|
u_char uj = use_json(argc, argv);
|
2017-05-23 14:57:11 +02:00
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
2017-01-26 15:10:54 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (argv_find(argv, argc, "WORD", &idx)
|
|
|
|
|| argv_find(argv, argc, "detail", &idx))
|
2017-05-23 14:57:11 +02:00
|
|
|
pim_show_interfaces_single(vty, vrf->info, argv[idx]->arg, uj);
|
2017-01-26 15:10:54 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
else
|
2017-05-23 14:57:11 +02:00
|
|
|
pim_show_interfaces(vty, vrf->info, uj);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_pim_join,
|
|
|
|
show_ip_pim_join_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip pim [vrf NAME] join [json]",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2017-01-25 15:13:46 +01:00
|
|
|
"PIM interface join information\n"
|
|
|
|
JSON_STR)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
2017-07-17 14:03:14 +02:00
|
|
|
u_char uj = use_json(argc, argv);
|
2017-05-23 14:57:11 +02:00
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
pim_show_join(vty, vrf->info, uj);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_pim_local_membership,
|
|
|
|
show_ip_pim_local_membership_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip pim [vrf NAME] local-membership [json]",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2017-01-25 15:13:46 +01:00
|
|
|
"PIM interface local-membership\n"
|
|
|
|
JSON_STR)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
2017-07-17 14:03:14 +02:00
|
|
|
u_char uj = use_json(argc, argv);
|
2017-05-23 14:57:11 +02:00
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
pim_show_membership(vty, vrf->info, uj);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_pim_neighbor,
|
|
|
|
show_ip_pim_neighbor_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2016-09-15 19:16:36 +02:00
|
|
|
"PIM neighbor information\n"
|
pimd: Added json to 'show ip igmp group'
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
root@superm-redxp-05[quagga-pim]# vtysh -c 'show ip igmp group'
Interface Address Group Mode Timer Srcs V Uptime
br1 20.0.13.1 230.40.40.1 EXCL 00:03:24 1 3 00:01:28
root@superm-redxp-05[quagga-pim]#
root@superm-redxp-05[quagga-pim]#
root@superm-redxp-05[quagga-pim]# vtysh -c 'show ip igmp group json' |
python -m json.tool
{
"br1": {
"230.40.40.1": {
"group": "230.40.40.1",
"mode": "EXCLUDE",
"source": "20.0.13.1",
"sourcesCount": 1,
"timer": "00:03:23",
"uptime": "00:01:30",
"version": 3
},
"address": "20.0.13.1",
"flagBroadcast": true,
"flagMulticast": true,
"index": 96,
"lanDelayEnabled": true,
"name": "br1",
"state": "up"
}
}
root@superm-redxp-05[quagga-pim]#
2016-09-27 18:37:38 +02:00
|
|
|
"Detailed output\n"
|
2016-09-15 19:16:36 +02:00
|
|
|
"Name of interface or neighbor\n"
|
|
|
|
"JavaScript Object Notation\n")
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
2017-07-17 14:03:14 +02:00
|
|
|
u_char uj = use_json(argc, argv);
|
2017-05-23 14:57:11 +02:00
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
2017-01-26 15:10:54 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (argv_find(argv, argc, "detail", &idx)
|
|
|
|
|| argv_find(argv, argc, "WORD", &idx))
|
2017-05-23 14:57:11 +02:00
|
|
|
pim_show_neighbors_single(vty, vrf->info, argv[idx]->arg, uj);
|
2017-07-17 14:03:14 +02:00
|
|
|
else
|
2017-05-23 14:57:11 +02:00
|
|
|
pim_show_neighbors(vty, vrf->info, uj);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_pim_secondary,
|
|
|
|
show_ip_pim_secondary_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip pim [vrf NAME] secondary",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2015-02-04 07:01:14 +01:00
|
|
|
"PIM neighbor addresses\n")
|
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
pim_show_neighbors_secondary(vty, vrf->info);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2016-09-28 03:33:33 +02:00
|
|
|
DEFUN (show_ip_pim_state,
|
|
|
|
show_ip_pim_state_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
|
2016-09-28 03:33:33 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2016-09-28 03:33:33 +02:00
|
|
|
"PIM state information\n"
|
|
|
|
"Unicast or Multicast address\n"
|
|
|
|
"Multicast address\n"
|
|
|
|
"JavaScript Object Notation\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
const char *src_or_group = NULL;
|
|
|
|
const char *group = NULL;
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
2017-07-17 14:03:14 +02:00
|
|
|
u_char uj = use_json(argc, argv);
|
2017-05-23 14:57:11 +02:00
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (uj)
|
|
|
|
argc--;
|
2016-09-28 03:33:33 +02:00
|
|
|
|
2017-06-06 21:09:51 +02:00
|
|
|
if (argv_find(argv, argc, "A.B.C.D", &idx)) {
|
|
|
|
src_or_group = argv[idx]->arg;
|
|
|
|
if (idx + 1 < argc)
|
|
|
|
group = argv[idx + 1]->arg;
|
|
|
|
}
|
2016-09-28 03:33:33 +02:00
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
pim_show_state(vty, vrf->info, src_or_group, group, uj);
|
2016-09-28 03:33:33 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2016-09-28 03:33:33 +02:00
|
|
|
}
|
|
|
|
|
2015-02-04 07:01:14 +01:00
|
|
|
DEFUN (show_ip_pim_upstream,
|
|
|
|
show_ip_pim_upstream_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip pim [vrf NAME] upstream [json]",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2016-09-15 19:16:36 +02:00
|
|
|
"PIM upstream information\n"
|
|
|
|
"JavaScript Object Notation\n")
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-05-23 13:25:30 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
2017-07-17 14:03:14 +02:00
|
|
|
u_char uj = use_json(argc, argv);
|
2017-05-23 14:57:11 +02:00
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
2017-05-23 13:25:30 +02:00
|
|
|
pim_show_upstream(vty, vrf->info, uj);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_pim_upstream_join_desired,
|
|
|
|
show_ip_pim_upstream_join_desired_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip pim [vrf NAME] upstream-join-desired [json]",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2016-09-15 19:16:36 +02:00
|
|
|
"PIM upstream join-desired\n"
|
|
|
|
"JavaScript Object Notation\n")
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
2017-07-17 14:03:14 +02:00
|
|
|
u_char uj = use_json(argc, argv);
|
2017-05-23 14:57:11 +02:00
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
pim_show_join_desired(vty, vrf->info, uj);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_pim_upstream_rpf,
|
|
|
|
show_ip_pim_upstream_rpf_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip pim [vrf NAME] upstream-rpf [json]",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2016-09-15 19:16:36 +02:00
|
|
|
"PIM upstream source rpf\n"
|
|
|
|
"JavaScript Object Notation\n")
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
2017-07-17 14:03:14 +02:00
|
|
|
u_char uj = use_json(argc, argv);
|
2017-05-23 14:57:11 +02:00
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
pim_show_upstream_rpf(vty, vrf->info, uj);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2016-08-23 22:22:14 +02:00
|
|
|
DEFUN (show_ip_pim_rp,
|
|
|
|
show_ip_pim_rp_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip pim [vrf NAME] rp-info [json]",
|
2016-08-23 22:22:14 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2016-09-15 19:16:36 +02:00
|
|
|
"PIM RP information\n"
|
|
|
|
"JavaScript Object Notation\n")
|
2016-08-23 22:22:14 +02:00
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
2017-07-17 14:03:14 +02:00
|
|
|
u_char uj = use_json(argc, argv);
|
2017-05-23 14:57:11 +02:00
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
pim_rp_show_information(vty, vrf->info, uj);
|
2016-08-23 22:22:14 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2016-08-23 22:22:14 +02:00
|
|
|
}
|
|
|
|
|
2015-02-04 07:01:14 +01:00
|
|
|
DEFUN (show_ip_pim_rpf,
|
|
|
|
show_ip_pim_rpf_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip pim [vrf NAME] rpf [json]",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2016-09-15 19:16:36 +02:00
|
|
|
"PIM cached source rpf information\n"
|
|
|
|
"JavaScript Object Notation\n")
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
2017-07-17 14:03:14 +02:00
|
|
|
u_char uj = use_json(argc, argv);
|
2017-05-23 14:57:11 +02:00
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
pim_show_rpf(vty, vrf->info, uj);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
pimd: Pim Nexthop Tracking support with ECMP
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>
2017-04-05 22:14:12 +02:00
|
|
|
DEFUN (show_ip_pim_nexthop,
|
|
|
|
show_ip_pim_nexthop_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip pim [vrf NAME] nexthop",
|
pimd: Pim Nexthop Tracking support with ECMP
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>
2017-04-05 22:14:12 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
pimd: Pim Nexthop Tracking support with ECMP
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>
2017-04-05 22:14:12 +02:00
|
|
|
"PIM cached nexthop rpf information\n")
|
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
pim_show_nexthop(vty, vrf->info);
|
pimd: Pim Nexthop Tracking support with ECMP
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>
2017-04-05 22:14:12 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
pimd: Pim Nexthop Tracking support with ECMP
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>
2017-04-05 22:14:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_pim_nexthop_lookup,
|
|
|
|
show_ip_pim_nexthop_lookup_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
|
pimd: Pim Nexthop Tracking support with ECMP
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>
2017-04-05 22:14:12 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
pimd: Pim Nexthop Tracking support with ECMP
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>
2017-04-05 22:14:12 +02:00
|
|
|
"PIM cached nexthop rpf lookup\n"
|
|
|
|
"Source/RP address\n"
|
|
|
|
"Multicast Group address\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct pim_nexthop_cache pnc;
|
|
|
|
struct prefix nht_p;
|
|
|
|
int result = 0;
|
|
|
|
struct in_addr src_addr, grp_addr;
|
|
|
|
struct in_addr vif_source;
|
|
|
|
const char *addr_str, *addr_str1;
|
|
|
|
struct prefix grp;
|
|
|
|
struct pim_nexthop nexthop;
|
|
|
|
char nexthop_addr_str[PREFIX_STRLEN];
|
|
|
|
char grp_str[PREFIX_STRLEN];
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
argv_find(argv, argc, "A.B.C.D", &idx);
|
|
|
|
addr_str = argv[idx]->arg;
|
2017-07-17 14:03:14 +02:00
|
|
|
result = inet_pton(AF_INET, addr_str, &src_addr);
|
|
|
|
if (result <= 0) {
|
|
|
|
vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
|
|
|
|
errno, safe_strerror(errno));
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pim_is_group_224_4(src_addr)) {
|
|
|
|
vty_out(vty,
|
|
|
|
"Invalid argument. Expected Valid Source Address.\n");
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
addr_str1 = argv[idx + 1]->arg;
|
2017-07-17 14:03:14 +02:00
|
|
|
result = inet_pton(AF_INET, addr_str1, &grp_addr);
|
|
|
|
if (result <= 0) {
|
|
|
|
vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
|
|
|
|
errno, safe_strerror(errno));
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!pim_is_group_224_4(grp_addr)) {
|
|
|
|
vty_out(vty,
|
|
|
|
"Invalid argument. Expected Valid Multicast Group Address.\n");
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
if (!pim_rp_set_upstream_addr(vrf->info, &vif_source, src_addr,
|
|
|
|
grp_addr))
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
|
|
|
memset(&pnc, 0, sizeof(struct pim_nexthop_cache));
|
|
|
|
nht_p.family = AF_INET;
|
|
|
|
nht_p.prefixlen = IPV4_MAX_BITLEN;
|
|
|
|
nht_p.u.prefix4 = vif_source;
|
|
|
|
grp.family = AF_INET;
|
|
|
|
grp.prefixlen = IPV4_MAX_BITLEN;
|
|
|
|
grp.u.prefix4 = grp_addr;
|
|
|
|
memset(&nexthop, 0, sizeof(nexthop));
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
if (pim_find_or_track_nexthop(vrf->info, &nht_p, NULL, NULL, &pnc))
|
|
|
|
pim_ecmp_nexthop_search(vrf->info, &pnc, &nexthop, &nht_p, &grp,
|
|
|
|
0);
|
2017-05-19 04:53:50 +02:00
|
|
|
else
|
2017-05-23 14:57:11 +02:00
|
|
|
pim_ecmp_nexthop_lookup(vrf->info, &nexthop, vif_source, &nht_p,
|
2017-05-19 22:00:00 +02:00
|
|
|
&grp, 0);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
pim_addr_dump("<grp?>", &grp, grp_str, sizeof(grp_str));
|
|
|
|
pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
|
|
|
|
nexthop_addr_str, sizeof(nexthop_addr_str));
|
|
|
|
vty_out(vty, "Group %s --- Nexthop %s Interface %s \n", grp_str,
|
|
|
|
nexthop_addr_str, nexthop.interface->name);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
pimd: Pim Nexthop Tracking support with ECMP
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>
2017-04-05 22:14:12 +02:00
|
|
|
}
|
|
|
|
|
2017-04-03 22:11:58 +02:00
|
|
|
DEFUN (show_ip_pim_interface_traffic,
|
|
|
|
show_ip_pim_interface_traffic_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip pim [vrf NAME] interface traffic [WORD] [json]",
|
2017-04-03 22:11:58 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2017-04-03 22:11:58 +02:00
|
|
|
"PIM interface information\n"
|
|
|
|
"Protocol Packet counters\n"
|
2017-05-02 19:15:23 +02:00
|
|
|
"Interface name\n"
|
2017-04-03 22:11:58 +02:00
|
|
|
"JavaScript Object Notation\n")
|
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
2017-07-17 14:03:14 +02:00
|
|
|
u_char uj = use_json(argc, argv);
|
2017-05-23 14:57:11 +02:00
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
2017-04-03 22:11:58 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (argv_find(argv, argc, "WORD", &idx))
|
2017-05-23 14:57:11 +02:00
|
|
|
pim_show_interface_traffic_single(vty, vrf->info,
|
|
|
|
argv[idx]->arg, uj);
|
2017-07-17 14:03:14 +02:00
|
|
|
else
|
2017-05-23 14:57:11 +02:00
|
|
|
pim_show_interface_traffic(vty, vrf->info, uj);
|
2017-04-03 22:11:58 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-04-03 22:11:58 +02:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void show_multicast_interfaces(struct vty *vty, struct pim_instance *pim)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *node;
|
|
|
|
struct interface *ifp;
|
|
|
|
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
|
|
|
|
vty_out(vty,
|
2017-05-23 14:57:11 +02:00
|
|
|
"Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
struct in_addr ifaddr;
|
|
|
|
struct sioc_vif_req vreq;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
pim_ifp = ifp->info;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
if (!pim_ifp)
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
memset(&vreq, 0, sizeof(vreq));
|
|
|
|
vreq.vifi = pim_ifp->mroute_vif_index;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
if (ioctl(pim->mroute_socket, SIOCGETVIFCNT, &vreq)) {
|
|
|
|
zlog_warn(
|
|
|
|
"ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
|
|
|
|
(unsigned long)SIOCGETVIFCNT, ifp->name,
|
|
|
|
pim_ifp->mroute_vif_index, errno,
|
|
|
|
safe_strerror(errno));
|
|
|
|
}
|
2017-05-17 21:08:39 +02:00
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
ifaddr = pim_ifp->primary_address;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
vty_out(vty, "%-12s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
|
|
|
|
ifp->name, inet_ntoa(ifaddr), ifp->ifindex,
|
|
|
|
pim_ifp->mroute_vif_index, (unsigned long)vreq.icount,
|
|
|
|
(unsigned long)vreq.ocount, (unsigned long)vreq.ibytes,
|
|
|
|
(unsigned long)vreq.obytes);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_multicast,
|
|
|
|
show_ip_multicast_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip multicast [vrf NAME]",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2015-02-04 07:01:14 +01:00
|
|
|
"Multicast global information\n")
|
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
2017-05-24 13:45:18 +02:00
|
|
|
struct pim_instance *pim;
|
2017-07-17 14:03:14 +02:00
|
|
|
time_t now = pim_time_monotonic_sec();
|
|
|
|
char uptime[10];
|
|
|
|
|
2017-05-24 13:45:18 +02:00
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
pim = vrf->info;
|
|
|
|
|
2017-05-17 21:08:39 +02:00
|
|
|
vty_out(vty, "Mroute socket descriptor:");
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
vty_out(vty, " %d(%s)\n", pim->mroute_socket, vrf->name);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_time_uptime(uptime, sizeof(uptime),
|
2017-05-23 14:57:11 +02:00
|
|
|
now - pim->mroute_socket_creation);
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty, "Mroute socket uptime: %s\n", uptime);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty, "\n");
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_zebra_zclient_update(vty);
|
|
|
|
pim_zlookup_show_ip_multicast(vty);
|
2016-08-09 21:04:23 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty, "\n");
|
|
|
|
vty_out(vty, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty, "\n");
|
|
|
|
vty_out(vty, "Upstream Join Timer: %d secs\n", qpim_t_periodic);
|
|
|
|
vty_out(vty, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME);
|
|
|
|
vty_out(vty, "PIM ECMP: %s\n", qpim_ecmp_enable ? "Enable" : "Disable");
|
|
|
|
vty_out(vty, "PIM ECMP Rebalance: %s\n",
|
|
|
|
qpim_ecmp_rebalance_enable ? "Enable" : "Disable");
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty, "\n");
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
show_rpf_refresh_stats(vty, now, NULL);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty, "\n");
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
show_scan_oil_stats(vty, pim, now);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
show_multicast_interfaces(vty, pim);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void show_mroute(struct vty *vty, struct pim_instance *pim, u_char uj)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *node;
|
|
|
|
struct channel_oil *c_oil;
|
|
|
|
struct static_route *s_route;
|
|
|
|
time_t now;
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_group = NULL;
|
|
|
|
json_object *json_source = NULL;
|
|
|
|
json_object *json_oil = NULL;
|
|
|
|
json_object *json_ifp_out = NULL;
|
|
|
|
int found_oif = 0;
|
|
|
|
int first = 1;
|
|
|
|
char grp_str[INET_ADDRSTRLEN];
|
|
|
|
char src_str[INET_ADDRSTRLEN];
|
|
|
|
char in_ifname[INTERFACE_NAMSIZ + 1];
|
|
|
|
char out_ifname[INTERFACE_NAMSIZ + 1];
|
|
|
|
int oif_vif_index;
|
|
|
|
struct interface *ifp_in;
|
|
|
|
char proto[100];
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json = json_object_new_object();
|
|
|
|
} else {
|
|
|
|
vty_out(vty,
|
|
|
|
"Source Group Proto Input Output TTL Uptime\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
now = pim_time_monotonic_sec();
|
|
|
|
|
|
|
|
/* print list of PIM and IGMP routes */
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
found_oif = 0;
|
|
|
|
first = 1;
|
|
|
|
if (!c_oil->installed && !uj)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str,
|
|
|
|
sizeof(grp_str));
|
|
|
|
pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str,
|
|
|
|
sizeof(src_str));
|
2017-05-21 14:29:56 +02:00
|
|
|
ifp_in = pim_if_find_by_vif_index(pim, c_oil->oil.mfcc_parent);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
if (ifp_in)
|
|
|
|
strcpy(in_ifname, ifp_in->name);
|
|
|
|
else
|
|
|
|
strcpy(in_ifname, "<iif?>");
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
|
|
|
|
/* Find the group, create it if it doesn't exist */
|
|
|
|
json_object_object_get_ex(json, grp_str, &json_group);
|
|
|
|
|
|
|
|
if (!json_group) {
|
|
|
|
json_group = json_object_new_object();
|
|
|
|
json_object_object_add(json, grp_str,
|
|
|
|
json_group);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Find the source nested under the group, create it if
|
|
|
|
* it doesn't exist */
|
|
|
|
json_object_object_get_ex(json_group, src_str,
|
|
|
|
&json_source);
|
|
|
|
|
|
|
|
if (!json_source) {
|
|
|
|
json_source = json_object_new_object();
|
|
|
|
json_object_object_add(json_group, src_str,
|
|
|
|
json_source);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Find the inbound interface nested under the source,
|
|
|
|
* create it if it doesn't exist */
|
|
|
|
json_object_int_add(json_source, "installed",
|
|
|
|
c_oil->installed);
|
|
|
|
json_object_int_add(json_source, "refCount",
|
|
|
|
c_oil->oil_ref_count);
|
|
|
|
json_object_int_add(json_source, "oilSize",
|
|
|
|
c_oil->oil_size);
|
|
|
|
json_object_int_add(json_source, "OilInheritedRescan",
|
|
|
|
c_oil->oil_inherited_rescan);
|
|
|
|
json_object_string_add(json_source, "iif", in_ifname);
|
|
|
|
json_oil = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
|
|
|
|
++oif_vif_index) {
|
|
|
|
struct interface *ifp_out;
|
|
|
|
char oif_uptime[10];
|
|
|
|
int ttl;
|
|
|
|
|
|
|
|
ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
|
|
|
|
if (ttl < 1)
|
|
|
|
continue;
|
|
|
|
|
2017-05-21 14:29:56 +02:00
|
|
|
ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_time_uptime(
|
|
|
|
oif_uptime, sizeof(oif_uptime),
|
|
|
|
now - c_oil->oif_creation[oif_vif_index]);
|
|
|
|
found_oif = 1;
|
|
|
|
|
|
|
|
if (ifp_out)
|
|
|
|
strcpy(out_ifname, ifp_out->name);
|
|
|
|
else
|
|
|
|
strcpy(out_ifname, "<oif?>");
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json_ifp_out = json_object_new_object();
|
|
|
|
json_object_string_add(json_ifp_out, "source",
|
|
|
|
src_str);
|
|
|
|
json_object_string_add(json_ifp_out, "group",
|
|
|
|
grp_str);
|
|
|
|
|
|
|
|
if (c_oil->oif_flags[oif_vif_index]
|
|
|
|
& PIM_OIF_FLAG_PROTO_PIM)
|
|
|
|
json_object_boolean_true_add(
|
|
|
|
json_ifp_out, "protocolPim");
|
|
|
|
|
|
|
|
if (c_oil->oif_flags[oif_vif_index]
|
|
|
|
& PIM_OIF_FLAG_PROTO_IGMP)
|
|
|
|
json_object_boolean_true_add(
|
|
|
|
json_ifp_out, "protocolIgmp");
|
|
|
|
|
|
|
|
if (c_oil->oif_flags[oif_vif_index]
|
|
|
|
& PIM_OIF_FLAG_PROTO_SOURCE)
|
|
|
|
json_object_boolean_true_add(
|
|
|
|
json_ifp_out, "protocolSource");
|
|
|
|
|
|
|
|
if (c_oil->oif_flags[oif_vif_index]
|
|
|
|
& PIM_OIF_FLAG_PROTO_STAR)
|
|
|
|
json_object_boolean_true_add(
|
|
|
|
json_ifp_out,
|
|
|
|
"protocolInherited");
|
|
|
|
|
|
|
|
json_object_string_add(json_ifp_out,
|
|
|
|
"inboundInterface",
|
|
|
|
in_ifname);
|
|
|
|
json_object_int_add(json_ifp_out, "iVifI",
|
|
|
|
c_oil->oil.mfcc_parent);
|
|
|
|
json_object_string_add(json_ifp_out,
|
|
|
|
"outboundInterface",
|
|
|
|
out_ifname);
|
|
|
|
json_object_int_add(json_ifp_out, "oVifI",
|
|
|
|
oif_vif_index);
|
|
|
|
json_object_int_add(json_ifp_out, "ttl", ttl);
|
|
|
|
json_object_string_add(json_ifp_out, "upTime",
|
|
|
|
oif_uptime);
|
|
|
|
if (!json_oil) {
|
|
|
|
json_oil = json_object_new_object();
|
|
|
|
json_object_object_add(json_source,
|
|
|
|
"oil", json_oil);
|
|
|
|
}
|
|
|
|
json_object_object_add(json_oil, out_ifname,
|
|
|
|
json_ifp_out);
|
|
|
|
} else {
|
|
|
|
if (c_oil->oif_flags[oif_vif_index]
|
|
|
|
& PIM_OIF_FLAG_PROTO_PIM) {
|
|
|
|
strcpy(proto, "PIM");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c_oil->oif_flags[oif_vif_index]
|
|
|
|
& PIM_OIF_FLAG_PROTO_IGMP) {
|
|
|
|
strcpy(proto, "IGMP");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c_oil->oif_flags[oif_vif_index]
|
|
|
|
& PIM_OIF_FLAG_PROTO_SOURCE) {
|
|
|
|
strcpy(proto, "SRC");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c_oil->oif_flags[oif_vif_index]
|
|
|
|
& PIM_OIF_FLAG_PROTO_STAR) {
|
|
|
|
strcpy(proto, "STAR");
|
|
|
|
}
|
|
|
|
|
|
|
|
vty_out(vty,
|
|
|
|
"%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
|
|
|
|
src_str, grp_str, proto, in_ifname,
|
|
|
|
out_ifname, ttl, oif_uptime);
|
|
|
|
|
|
|
|
if (first) {
|
|
|
|
src_str[0] = '\0';
|
|
|
|
grp_str[0] = '\0';
|
|
|
|
in_ifname[0] = '\0';
|
|
|
|
first = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!uj && !found_oif) {
|
|
|
|
vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
|
|
|
|
src_str, grp_str, "none", in_ifname, "none", 0,
|
|
|
|
"--:--:--");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Print list of static routes */
|
2017-05-21 14:29:56 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) {
|
|
|
|
first = 1;
|
|
|
|
|
|
|
|
if (!s_route->c_oil.installed)
|
2017-07-17 14:03:14 +02:00
|
|
|
continue;
|
|
|
|
|
2017-05-21 14:29:56 +02:00
|
|
|
pim_inet4_dump("<group?>", s_route->group, grp_str,
|
|
|
|
sizeof(grp_str));
|
|
|
|
pim_inet4_dump("<source?>", s_route->source, src_str,
|
|
|
|
sizeof(src_str));
|
|
|
|
ifp_in = pim_if_find_by_vif_index(pim, s_route->iif);
|
|
|
|
found_oif = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-21 14:29:56 +02:00
|
|
|
if (ifp_in)
|
|
|
|
strcpy(in_ifname, ifp_in->name);
|
|
|
|
else
|
|
|
|
strcpy(in_ifname, "<iif?>");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-21 14:29:56 +02:00
|
|
|
if (uj) {
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-21 14:29:56 +02:00
|
|
|
/* Find the group, create it if it doesn't exist */
|
|
|
|
json_object_object_get_ex(json, grp_str, &json_group);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-21 14:29:56 +02:00
|
|
|
if (!json_group) {
|
|
|
|
json_group = json_object_new_object();
|
|
|
|
json_object_object_add(json, grp_str,
|
|
|
|
json_group);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-21 14:29:56 +02:00
|
|
|
/* Find the source nested under the group, create it if
|
|
|
|
* it doesn't exist */
|
|
|
|
json_object_object_get_ex(json_group, src_str,
|
|
|
|
&json_source);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-21 14:29:56 +02:00
|
|
|
if (!json_source) {
|
|
|
|
json_source = json_object_new_object();
|
|
|
|
json_object_object_add(json_group, src_str,
|
|
|
|
json_source);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-21 14:29:56 +02:00
|
|
|
json_object_string_add(json_source, "iif", in_ifname);
|
|
|
|
json_oil = NULL;
|
|
|
|
} else {
|
|
|
|
strcpy(proto, "STATIC");
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-21 14:29:56 +02:00
|
|
|
for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
|
|
|
|
++oif_vif_index) {
|
|
|
|
struct interface *ifp_out;
|
|
|
|
char oif_uptime[10];
|
|
|
|
int ttl;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-21 14:29:56 +02:00
|
|
|
ttl = s_route->oif_ttls[oif_vif_index];
|
|
|
|
if (ttl < 1)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
|
|
|
|
pim_time_uptime(
|
|
|
|
oif_uptime, sizeof(oif_uptime),
|
|
|
|
now
|
|
|
|
- s_route->c_oil
|
|
|
|
.oif_creation[oif_vif_index]);
|
|
|
|
found_oif = 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-21 14:29:56 +02:00
|
|
|
if (ifp_out)
|
|
|
|
strcpy(out_ifname, ifp_out->name);
|
|
|
|
else
|
|
|
|
strcpy(out_ifname, "<oif?>");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-21 14:29:56 +02:00
|
|
|
if (uj) {
|
|
|
|
json_ifp_out = json_object_new_object();
|
|
|
|
json_object_string_add(json_ifp_out, "source",
|
|
|
|
src_str);
|
|
|
|
json_object_string_add(json_ifp_out, "group",
|
|
|
|
grp_str);
|
|
|
|
json_object_boolean_true_add(json_ifp_out,
|
|
|
|
"protocolStatic");
|
|
|
|
json_object_string_add(json_ifp_out,
|
|
|
|
"inboundInterface",
|
|
|
|
in_ifname);
|
|
|
|
json_object_int_add(
|
|
|
|
json_ifp_out, "iVifI",
|
|
|
|
s_route->c_oil.oil.mfcc_parent);
|
|
|
|
json_object_string_add(json_ifp_out,
|
|
|
|
"outboundInterface",
|
|
|
|
out_ifname);
|
|
|
|
json_object_int_add(json_ifp_out, "oVifI",
|
|
|
|
oif_vif_index);
|
|
|
|
json_object_int_add(json_ifp_out, "ttl", ttl);
|
|
|
|
json_object_string_add(json_ifp_out, "upTime",
|
|
|
|
oif_uptime);
|
|
|
|
if (!json_oil) {
|
|
|
|
json_oil = json_object_new_object();
|
|
|
|
json_object_object_add(json_source,
|
|
|
|
"oil", json_oil);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2017-05-21 14:29:56 +02:00
|
|
|
json_object_object_add(json_oil, out_ifname,
|
|
|
|
json_ifp_out);
|
|
|
|
} else {
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty,
|
2017-05-19 01:56:10 +02:00
|
|
|
"%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
|
2017-07-17 14:03:14 +02:00
|
|
|
src_str, grp_str, proto, in_ifname,
|
2017-05-21 14:29:56 +02:00
|
|
|
out_ifname, ttl, oif_uptime,
|
|
|
|
pim->vrf->name);
|
|
|
|
if (first) {
|
|
|
|
src_str[0] = '\0';
|
|
|
|
grp_str[0] = '\0';
|
|
|
|
in_ifname[0] = '\0';
|
|
|
|
first = 0;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
}
|
2017-05-21 14:29:56 +02:00
|
|
|
|
|
|
|
if (!uj && !found_oif) {
|
|
|
|
vty_out(vty,
|
|
|
|
"%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
|
|
|
|
src_str, grp_str, proto, in_ifname, "none", 0,
|
|
|
|
"--:--:--", pim->vrf->name);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (uj) {
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_mroute,
|
|
|
|
show_ip_mroute_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip mroute [vrf NAME] [json]",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
2017-01-25 15:13:46 +01:00
|
|
|
MROUTE_STR
|
2017-05-23 13:25:30 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2017-01-25 15:13:46 +01:00
|
|
|
JSON_STR)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
u_char uj = use_json(argc, argv);
|
2017-05-23 13:25:30 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
2017-05-23 14:57:11 +02:00
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
show_mroute(vty, vrf->info, uj);
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void show_mroute_count(struct vty *vty, struct pim_instance *pim)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *node;
|
|
|
|
struct channel_oil *c_oil;
|
|
|
|
struct static_route *s_route;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty, "\n");
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty,
|
|
|
|
"Source Group LastUsed Packets Bytes WrongIf \n");
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
/* Print PIM and IGMP route counts */
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
char group_str[INET_ADDRSTRLEN];
|
|
|
|
char source_str[INET_ADDRSTRLEN];
|
2016-07-12 21:22:10 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!c_oil->installed)
|
|
|
|
continue;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_mroute_update_counters(c_oil);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str,
|
|
|
|
sizeof(group_str));
|
|
|
|
pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str,
|
|
|
|
sizeof(source_str));
|
2015-06-12 01:29:02 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
|
|
|
|
source_str, group_str, c_oil->cc.lastused / 100,
|
|
|
|
c_oil->cc.pktcnt, c_oil->cc.bytecnt,
|
|
|
|
c_oil->cc.wrong_if);
|
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) {
|
|
|
|
char group_str[INET_ADDRSTRLEN];
|
|
|
|
char source_str[INET_ADDRSTRLEN];
|
2015-06-12 01:29:02 +02:00
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
if (!s_route->c_oil.installed)
|
|
|
|
continue;
|
2015-06-12 01:29:02 +02:00
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
pim_mroute_update_counters(&s_route->c_oil);
|
2017-05-19 01:56:10 +02:00
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
pim_inet4_dump("<group?>", s_route->c_oil.oil.mfcc_mcastgrp,
|
|
|
|
group_str, sizeof(group_str));
|
|
|
|
pim_inet4_dump("<source?>", s_route->c_oil.oil.mfcc_origin,
|
|
|
|
source_str, sizeof(source_str));
|
2017-05-19 01:56:10 +02:00
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
|
|
|
|
source_str, group_str, s_route->c_oil.cc.lastused,
|
|
|
|
s_route->c_oil.cc.pktcnt, s_route->c_oil.cc.bytecnt,
|
|
|
|
s_route->c_oil.cc.wrong_if);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_mroute_count,
|
|
|
|
show_ip_mroute_count_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip mroute [vrf NAME] count",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
MROUTE_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2015-02-04 07:01:14 +01:00
|
|
|
"Route and packet count data\n")
|
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
|
|
|
|
|
|
|
show_mroute_count(vty, vrf->info);
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_rib,
|
|
|
|
show_ip_rib_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip rib [vrf NAME] A.B.C.D",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
RIB_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2015-02-04 07:01:14 +01:00
|
|
|
"Unicast address\n")
|
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
2017-07-17 14:03:14 +02:00
|
|
|
struct in_addr addr;
|
|
|
|
const char *addr_str;
|
|
|
|
struct pim_nexthop nexthop;
|
|
|
|
char nexthop_addr_str[PREFIX_STRLEN];
|
|
|
|
int result;
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
memset(&nexthop, 0, sizeof(nexthop));
|
2017-05-23 14:57:11 +02:00
|
|
|
argv_find(argv, argc, "A.B.C.D", &idx);
|
|
|
|
addr_str = argv[idx]->arg;
|
2017-07-17 14:03:14 +02:00
|
|
|
result = inet_pton(AF_INET, addr_str, &addr);
|
|
|
|
if (result <= 0) {
|
|
|
|
vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
|
|
|
|
errno, safe_strerror(errno));
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
if (pim_nexthop_lookup(vrf->info, &nexthop, addr, 0)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty,
|
|
|
|
"Failure querying RIB nexthop for unicast address %s\n",
|
|
|
|
addr_str);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty,
|
|
|
|
"Address NextHop Interface Metric Preference\n");
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
|
|
|
|
nexthop_addr_str, sizeof(nexthop_addr_str));
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty, "%-15s %-15s %-9s %6d %10d\n", addr_str, nexthop_addr_str,
|
|
|
|
nexthop.interface ? nexthop.interface->name : "<ifname?>",
|
|
|
|
nexthop.mrib_route_metric, nexthop.mrib_metric_preference);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void show_ssmpingd(struct vty *vty, struct pim_instance *pim)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *node;
|
|
|
|
struct ssmpingd_sock *ss;
|
|
|
|
time_t now;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty,
|
|
|
|
"Source Socket Address Port Uptime Requests\n");
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-05-22 17:09:13 +02:00
|
|
|
if (!pim->ssmpingd_list)
|
2017-07-17 14:03:14 +02:00
|
|
|
return;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
now = pim_time_monotonic_sec();
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-05-22 17:09:13 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->ssmpingd_list, node, ss)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
char source_str[INET_ADDRSTRLEN];
|
|
|
|
char ss_uptime[10];
|
|
|
|
struct sockaddr_in bind_addr;
|
|
|
|
socklen_t len = sizeof(bind_addr);
|
|
|
|
char bind_addr_str[INET_ADDRSTRLEN];
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_inet4_dump("<src?>", ss->source_addr, source_str,
|
|
|
|
sizeof(source_str));
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (pim_socket_getsockname(
|
|
|
|
ss->sock_fd, (struct sockaddr *)&bind_addr, &len)) {
|
|
|
|
vty_out(vty,
|
|
|
|
"%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
|
|
|
|
source_str, ss->sock_fd);
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_inet4_dump("<addr?>", bind_addr.sin_addr, bind_addr_str,
|
|
|
|
sizeof(bind_addr_str));
|
|
|
|
pim_time_uptime(ss_uptime, sizeof(ss_uptime),
|
|
|
|
now - ss->creation);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty, "%-15s %6d %-15s %5d %8s %8lld\n", source_str,
|
|
|
|
ss->sock_fd, bind_addr_str, ntohs(bind_addr.sin_port),
|
|
|
|
ss_uptime, (long long)ss->requests);
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_ssmpingd,
|
|
|
|
show_ip_ssmpingd_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip ssmpingd [vrf NAME]",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
SHOW_SSMPINGD_STR
|
|
|
|
VRF_CMD_HELP_STR)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
show_ssmpingd(vty, vrf->info);
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-05-22 21:13:13 +02:00
|
|
|
static int pim_rp_cmd_worker(struct vty *vty, struct pim_instance *pim,
|
|
|
|
const char *rp, const char *group,
|
2017-07-17 14:03:14 +02:00
|
|
|
const char *plist)
|
2016-08-05 19:08:06 +02:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
int result;
|
2016-08-05 19:08:06 +02:00
|
|
|
|
2017-05-22 21:13:13 +02:00
|
|
|
result = pim_rp_new(pim, rp, group, plist);
|
2016-09-13 21:41:33 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (result == PIM_MALLOC_FAIL) {
|
|
|
|
vty_out(vty, "%% Out of memory\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2016-09-13 21:41:33 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (result == PIM_GROUP_BAD_ADDRESS) {
|
|
|
|
vty_out(vty, "%% Bad group address specified: %s\n", group);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2016-09-13 21:41:33 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (result == PIM_RP_BAD_ADDRESS) {
|
|
|
|
vty_out(vty, "%% Bad RP address specified: %s\n", rp);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2016-08-05 19:08:06 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (result == PIM_RP_NO_PATH) {
|
|
|
|
vty_out(vty, "%% No Path to RP address specified: %s\n", rp);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2016-09-13 21:41:33 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (result == PIM_GROUP_OVERLAP) {
|
|
|
|
vty_out(vty, "%% Group range specified cannot overlap\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2016-09-13 21:41:33 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (result == PIM_GROUP_PFXLIST_OVERLAP) {
|
|
|
|
vty_out(vty,
|
|
|
|
"%% This group is already covered by a RP prefix-list\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2016-08-05 19:08:06 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (result == PIM_RP_PFXLIST_IN_USE) {
|
|
|
|
vty_out(vty,
|
|
|
|
"%% The same prefix-list cannot be applied to multiple RPs\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2016-08-05 19:08:06 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2016-08-05 19:08:06 +02:00
|
|
|
}
|
|
|
|
|
2017-05-22 22:32:14 +02:00
|
|
|
static int pim_cmd_spt_switchover(struct pim_instance *pim,
|
|
|
|
enum pim_spt_switchover spt,
|
2017-07-17 14:03:14 +02:00
|
|
|
const char *plist)
|
2017-04-07 16:16:23 +02:00
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
pim->spt.switchover = spt;
|
2017-04-07 16:16:23 +02:00
|
|
|
|
2017-05-22 22:32:14 +02:00
|
|
|
switch (pim->spt.switchover) {
|
2017-07-17 14:03:14 +02:00
|
|
|
case PIM_SPT_IMMEDIATE:
|
2017-05-22 22:32:14 +02:00
|
|
|
if (pim->spt.plist)
|
|
|
|
XFREE(MTYPE_PIM_SPT_PLIST_NAME, pim->spt.plist);
|
2017-04-07 16:16:23 +02:00
|
|
|
|
2017-05-22 22:32:14 +02:00
|
|
|
pim_upstream_add_lhr_star_pimreg(pim);
|
2017-07-17 14:03:14 +02:00
|
|
|
break;
|
|
|
|
case PIM_SPT_INFINITY:
|
2017-05-22 22:32:14 +02:00
|
|
|
pim_upstream_remove_lhr_star_pimreg(pim, plist);
|
2017-04-07 16:16:23 +02:00
|
|
|
|
2017-05-22 22:32:14 +02:00
|
|
|
if (pim->spt.plist)
|
|
|
|
XFREE(MTYPE_PIM_SPT_PLIST_NAME, pim->spt.plist);
|
2017-04-07 16:16:23 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (plist)
|
2017-05-23 14:57:11 +02:00
|
|
|
pim->spt.plist =
|
2017-07-17 14:03:14 +02:00
|
|
|
XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME, plist);
|
|
|
|
break;
|
|
|
|
}
|
2017-04-07 16:16:23 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-04-07 16:16:23 +02:00
|
|
|
}
|
|
|
|
|
2017-04-05 18:08:53 +02:00
|
|
|
DEFUN (ip_pim_spt_switchover_infinity,
|
|
|
|
ip_pim_spt_switchover_infinity_cmd,
|
|
|
|
"ip pim spt-switchover infinity-and-beyond",
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
|
|
|
"SPT-Switchover\n"
|
|
|
|
"Never switch to SPT Tree\n")
|
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
|
|
|
return pim_cmd_spt_switchover(pim, PIM_SPT_INFINITY, NULL);
|
2017-04-07 16:16:23 +02:00
|
|
|
}
|
2017-04-05 18:08:53 +02:00
|
|
|
|
2017-04-07 16:16:23 +02:00
|
|
|
DEFUN (ip_pim_spt_switchover_infinity_plist,
|
|
|
|
ip_pim_spt_switchover_infinity_plist_cmd,
|
|
|
|
"ip pim spt-switchover infinity-and-beyond prefix-list WORD",
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
|
|
|
"SPT-Switchover\n"
|
|
|
|
"Never switch to SPT Tree\n"
|
|
|
|
"Prefix-List to control which groups to switch\n"
|
|
|
|
"Prefix-List name\n")
|
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
|
|
|
return pim_cmd_spt_switchover(pim, PIM_SPT_INFINITY, argv[5]->arg);
|
2017-04-05 18:08:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ip_pim_spt_switchover_infinity,
|
|
|
|
no_ip_pim_spt_switchover_infinity_cmd,
|
|
|
|
"no ip pim spt-switchover infinity-and-beyond",
|
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
|
|
|
"SPT_Switchover\n"
|
|
|
|
"Never switch to SPT Tree\n")
|
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
|
|
|
return pim_cmd_spt_switchover(pim, PIM_SPT_IMMEDIATE, NULL);
|
2017-04-07 16:16:23 +02:00
|
|
|
}
|
2017-04-05 18:08:53 +02:00
|
|
|
|
2017-04-07 16:16:23 +02:00
|
|
|
DEFUN (no_ip_pim_spt_switchover_infinity_plist,
|
|
|
|
no_ip_pim_spt_switchover_infinity_plist_cmd,
|
|
|
|
"no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
|
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
|
|
|
"SPT_Switchover\n"
|
|
|
|
"Never switch to SPT Tree\n"
|
|
|
|
"Prefix-List to control which groups to switch\n"
|
|
|
|
"Prefix-List name\n")
|
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
|
|
|
return pim_cmd_spt_switchover(pim, PIM_SPT_IMMEDIATE, NULL);
|
2017-04-05 18:08:53 +02:00
|
|
|
}
|
|
|
|
|
2016-12-06 21:48:42 +01:00
|
|
|
DEFUN (ip_pim_joinprune_time,
|
|
|
|
ip_pim_joinprune_time_cmd,
|
2017-05-02 19:55:02 +02:00
|
|
|
"ip pim join-prune-interval (60-600)",
|
2016-12-06 21:48:42 +01:00
|
|
|
IP_STR
|
|
|
|
"pim multicast routing\n"
|
|
|
|
"Join Prune Send Interval\n"
|
|
|
|
"Seconds\n")
|
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
2017-07-17 14:03:14 +02:00
|
|
|
qpim_t_periodic = atoi(argv[3]->arg);
|
|
|
|
return CMD_SUCCESS;
|
2016-12-06 21:48:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ip_pim_joinprune_time,
|
|
|
|
no_ip_pim_joinprune_time_cmd,
|
2017-05-02 19:55:02 +02:00
|
|
|
"no ip pim join-prune-interval (60-600)",
|
2016-12-06 21:48:42 +01:00
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"pim multicast routing\n"
|
|
|
|
"Join Prune Send Interval\n"
|
|
|
|
"Seconds\n")
|
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
2017-07-17 14:03:14 +02:00
|
|
|
qpim_t_periodic = PIM_DEFAULT_T_PERIODIC;
|
|
|
|
return CMD_SUCCESS;
|
2016-12-06 21:48:42 +01:00
|
|
|
}
|
|
|
|
|
2016-11-17 00:11:49 +01:00
|
|
|
DEFUN (ip_pim_register_suppress,
|
|
|
|
ip_pim_register_suppress_cmd,
|
2017-05-02 19:55:02 +02:00
|
|
|
"ip pim register-suppress-time (5-60000)",
|
2016-08-18 15:07:14 +02:00
|
|
|
IP_STR
|
|
|
|
"pim multicast routing\n"
|
2016-11-17 00:11:49 +01:00
|
|
|
"Register Suppress Timer\n"
|
|
|
|
"Seconds\n")
|
2016-08-18 15:07:14 +02:00
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
2017-07-17 14:03:14 +02:00
|
|
|
qpim_register_suppress_time = atoi(argv[3]->arg);
|
|
|
|
return CMD_SUCCESS;
|
2016-08-18 15:07:14 +02:00
|
|
|
}
|
|
|
|
|
2016-11-17 00:11:49 +01:00
|
|
|
DEFUN (no_ip_pim_register_suppress,
|
|
|
|
no_ip_pim_register_suppress_cmd,
|
2017-05-02 19:55:02 +02:00
|
|
|
"no ip pim register-suppress-time (5-60000)",
|
2016-08-18 15:07:14 +02:00
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"pim multicast routing\n"
|
2016-11-17 00:11:49 +01:00
|
|
|
"Register Suppress Timer\n"
|
2016-08-18 16:00:02 +02:00
|
|
|
"Seconds\n")
|
2016-08-18 15:07:14 +02:00
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
2017-07-17 14:03:14 +02:00
|
|
|
qpim_register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT;
|
|
|
|
return CMD_SUCCESS;
|
2016-08-18 15:07:14 +02:00
|
|
|
}
|
|
|
|
|
2016-11-17 00:11:49 +01:00
|
|
|
DEFUN (ip_pim_keep_alive,
|
|
|
|
ip_pim_keep_alive_cmd,
|
2017-05-02 19:55:02 +02:00
|
|
|
"ip pim keep-alive-timer (31-60000)",
|
2016-08-18 16:00:02 +02:00
|
|
|
IP_STR
|
|
|
|
"pim multicast routing\n"
|
|
|
|
"Keep alive Timer\n"
|
|
|
|
"Seconds\n")
|
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
2017-07-17 14:03:14 +02:00
|
|
|
qpim_keep_alive_time = atoi(argv[3]->arg);
|
|
|
|
return CMD_SUCCESS;
|
2016-08-18 16:00:02 +02:00
|
|
|
}
|
|
|
|
|
2016-11-17 00:11:49 +01:00
|
|
|
DEFUN (no_ip_pim_keep_alive,
|
|
|
|
no_ip_pim_keep_alive_cmd,
|
2017-05-02 19:55:02 +02:00
|
|
|
"no ip pim keep-alive-timer (31-60000)",
|
2016-08-18 16:00:02 +02:00
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"pim multicast routing\n"
|
|
|
|
"Keep alive Timer\n"
|
|
|
|
"Seconds\n")
|
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
2017-07-17 14:03:14 +02:00
|
|
|
qpim_keep_alive_time = PIM_KEEPALIVE_PERIOD;
|
|
|
|
return CMD_SUCCESS;
|
2016-08-18 16:00:02 +02:00
|
|
|
}
|
|
|
|
|
2016-11-18 18:50:46 +01:00
|
|
|
DEFUN (ip_pim_packets,
|
|
|
|
ip_pim_packets_cmd,
|
2017-05-02 19:55:02 +02:00
|
|
|
"ip pim packets (1-100)",
|
2016-11-18 18:50:46 +01:00
|
|
|
IP_STR
|
|
|
|
"pim multicast routing\n"
|
2017-01-25 15:13:46 +01:00
|
|
|
"packets to process at one time per fd\n"
|
|
|
|
"Number of packets\n")
|
2016-11-18 18:50:46 +01:00
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
2017-07-17 14:03:14 +02:00
|
|
|
qpim_packet_process = atoi(argv[3]->arg);
|
|
|
|
return CMD_SUCCESS;
|
2016-11-18 18:50:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ip_pim_packets,
|
|
|
|
no_ip_pim_packets_cmd,
|
2017-05-02 19:55:02 +02:00
|
|
|
"no ip pim packets (1-100)",
|
2016-11-18 18:50:46 +01:00
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"pim multicast routing\n"
|
2017-01-25 15:13:46 +01:00
|
|
|
"packets to process at one time per fd\n"
|
|
|
|
"Number of packets\n")
|
2016-11-18 18:50:46 +01:00
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
2017-07-17 14:03:14 +02:00
|
|
|
qpim_packet_process = PIM_DEFAULT_PACKET_PROCESS;
|
|
|
|
return CMD_SUCCESS;
|
2016-11-18 18:50:46 +01:00
|
|
|
}
|
|
|
|
|
2017-03-30 05:23:25 +02:00
|
|
|
DEFUN (ip_pim_v6_secondary,
|
|
|
|
ip_pim_v6_secondary_cmd,
|
|
|
|
"ip pim send-v6-secondary",
|
|
|
|
IP_STR
|
|
|
|
"pim multicast routing\n"
|
|
|
|
"Send v6 secondary addresses\n")
|
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
2017-05-23 14:57:11 +02:00
|
|
|
pim->send_v6_secondary = 1;
|
2017-03-30 05:23:25 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-03-30 05:23:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ip_pim_v6_secondary,
|
|
|
|
no_ip_pim_v6_secondary_cmd,
|
|
|
|
"no ip pim send-v6-secondary",
|
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"pim multicast routing\n"
|
|
|
|
"Send v6 secondary addresses\n")
|
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
2017-05-23 14:57:11 +02:00
|
|
|
pim->send_v6_secondary = 0;
|
2017-03-30 05:23:25 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-03-30 05:23:25 +02:00
|
|
|
}
|
|
|
|
|
2015-09-08 17:10:19 +02:00
|
|
|
DEFUN (ip_pim_rp,
|
|
|
|
ip_pim_rp_cmd,
|
2016-08-05 15:07:46 +02:00
|
|
|
"ip pim rp A.B.C.D [A.B.C.D/M]",
|
2015-09-08 17:10:19 +02:00
|
|
|
IP_STR
|
2016-08-03 21:30:06 +02:00
|
|
|
"pim multicast routing\n"
|
|
|
|
"Rendevous Point\n"
|
2017-01-25 15:13:46 +01:00
|
|
|
"ip address of RP\n"
|
|
|
|
"Group Address range to cover\n")
|
2015-09-08 17:10:19 +02:00
|
|
|
{
|
2017-05-22 22:12:41 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
2017-07-17 14:03:14 +02:00
|
|
|
int idx_ipv4 = 3;
|
2017-05-02 19:15:06 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (argc == (idx_ipv4 + 1))
|
2017-05-22 21:13:13 +02:00
|
|
|
return pim_rp_cmd_worker(vty, pim, argv[idx_ipv4]->arg, NULL,
|
|
|
|
NULL);
|
2017-07-17 14:03:14 +02:00
|
|
|
else
|
2017-05-22 21:13:13 +02:00
|
|
|
return pim_rp_cmd_worker(vty, pim, argv[idx_ipv4]->arg,
|
2017-07-17 14:03:14 +02:00
|
|
|
argv[idx_ipv4 + 1]->arg, NULL);
|
2016-09-13 21:41:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (ip_pim_rp_prefix_list,
|
|
|
|
ip_pim_rp_prefix_list_cmd,
|
|
|
|
"ip pim rp A.B.C.D prefix-list WORD",
|
|
|
|
IP_STR
|
|
|
|
"pim multicast routing\n"
|
|
|
|
"Rendevous Point\n"
|
|
|
|
"ip address of RP\n"
|
|
|
|
"group prefix-list filter\n"
|
|
|
|
"Name of a prefix-list\n")
|
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
|
|
|
return pim_rp_cmd_worker(vty, pim, argv[3]->arg, NULL, argv[5]->arg);
|
2016-08-05 19:08:06 +02:00
|
|
|
}
|
2015-09-08 17:10:19 +02:00
|
|
|
|
2017-05-22 22:32:14 +02:00
|
|
|
static int pim_no_rp_cmd_worker(struct vty *vty, struct pim_instance *pim,
|
|
|
|
const char *rp, const char *group,
|
|
|
|
const char *plist)
|
2016-08-05 19:08:06 +02:00
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
int result = pim_rp_del(pim, rp, group, plist);
|
2016-09-13 21:41:33 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (result == PIM_GROUP_BAD_ADDRESS) {
|
|
|
|
vty_out(vty, "%% Bad group address specified: %s\n", group);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2016-08-05 15:07:46 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (result == PIM_RP_BAD_ADDRESS) {
|
|
|
|
vty_out(vty, "%% Bad RP address specified: %s\n", rp);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2015-09-08 17:10:19 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (result == PIM_RP_NOT_FOUND) {
|
|
|
|
vty_out(vty, "%% Unable to find specified RP\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2015-10-27 21:13:23 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-09-08 17:10:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ip_pim_rp,
|
|
|
|
no_ip_pim_rp_cmd,
|
2016-08-05 15:07:46 +02:00
|
|
|
"no ip pim rp A.B.C.D [A.B.C.D/M]",
|
2015-09-08 17:10:19 +02:00
|
|
|
NO_STR
|
|
|
|
IP_STR
|
2016-08-03 21:30:06 +02:00
|
|
|
"pim multicast routing\n"
|
|
|
|
"Rendevous Point\n"
|
2017-01-25 15:13:46 +01:00
|
|
|
"ip address of RP\n"
|
|
|
|
"Group Address range to cover\n")
|
2015-09-08 17:10:19 +02:00
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
2017-07-17 14:03:14 +02:00
|
|
|
int idx_ipv4 = 4, idx_group = 0;
|
2017-01-26 15:10:54 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (argv_find(argv, argc, "A.B.C.D/M", &idx_group))
|
2017-05-22 22:32:14 +02:00
|
|
|
return pim_no_rp_cmd_worker(vty, pim, argv[idx_ipv4]->arg,
|
2017-07-17 14:03:14 +02:00
|
|
|
argv[idx_group]->arg, NULL);
|
|
|
|
else
|
2017-05-22 22:32:14 +02:00
|
|
|
return pim_no_rp_cmd_worker(vty, pim, argv[idx_ipv4]->arg, NULL,
|
2017-07-17 14:03:14 +02:00
|
|
|
NULL);
|
2016-09-13 21:41:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ip_pim_rp_prefix_list,
|
|
|
|
no_ip_pim_rp_prefix_list_cmd,
|
|
|
|
"no ip pim rp A.B.C.D prefix-list WORD",
|
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"pim multicast routing\n"
|
|
|
|
"Rendevous Point\n"
|
|
|
|
"ip address of RP\n"
|
|
|
|
"group prefix-list filter\n"
|
|
|
|
"Name of a prefix-list\n")
|
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
|
|
|
return pim_no_rp_cmd_worker(vty, pim, argv[4]->arg, NULL, argv[6]->arg);
|
2015-09-08 17:10:19 +02:00
|
|
|
}
|
|
|
|
|
2017-05-21 15:30:02 +02:00
|
|
|
static int pim_ssm_cmd_worker(struct pim_instance *pim, struct vty *vty,
|
|
|
|
const char *plist)
|
2017-03-17 19:51:13 +01:00
|
|
|
{
|
2017-05-21 15:30:02 +02:00
|
|
|
int result = pim_ssm_range_set(pim, pim->vrf_id, plist);
|
2017-03-17 19:51:13 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (result == PIM_SSM_ERR_NONE)
|
|
|
|
return CMD_SUCCESS;
|
2017-03-17 19:51:13 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
switch (result) {
|
|
|
|
case PIM_SSM_ERR_NO_VRF:
|
|
|
|
vty_out(vty, "%% VRF doesn't exist\n");
|
|
|
|
break;
|
|
|
|
case PIM_SSM_ERR_DUP:
|
|
|
|
vty_out(vty, "%% duplicate config\n");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
vty_out(vty, "%% ssm range config failed\n");
|
|
|
|
}
|
2017-03-17 19:51:13 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2017-03-17 19:51:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (ip_pim_ssm_prefix_list,
|
|
|
|
ip_pim_ssm_prefix_list_cmd,
|
|
|
|
"ip pim ssm prefix-list WORD",
|
|
|
|
IP_STR
|
|
|
|
"pim multicast routing\n"
|
|
|
|
"Source Specific Multicast\n"
|
|
|
|
"group range prefix-list filter\n"
|
|
|
|
"Name of a prefix-list\n")
|
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
|
|
|
return pim_ssm_cmd_worker(pim, vty, argv[0]->arg);
|
2017-03-17 19:51:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ip_pim_ssm_prefix_list,
|
|
|
|
no_ip_pim_ssm_prefix_list_cmd,
|
|
|
|
"no ip pim ssm prefix-list",
|
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"pim multicast routing\n"
|
|
|
|
"Source Specific Multicast\n"
|
|
|
|
"group range prefix-list filter\n")
|
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
|
|
|
return pim_ssm_cmd_worker(pim, vty, NULL);
|
2017-03-17 19:51:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ip_pim_ssm_prefix_list_name,
|
|
|
|
no_ip_pim_ssm_prefix_list_name_cmd,
|
|
|
|
"no ip pim ssm prefix-list WORD",
|
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"pim multicast routing\n"
|
|
|
|
"Source Specific Multicast\n"
|
|
|
|
"group range prefix-list filter\n"
|
|
|
|
"Name of a prefix-list\n")
|
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
|
|
|
struct pim_ssm *ssm = pim->ssm_info;
|
2017-03-17 19:51:13 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (ssm->plist_name && !strcmp(ssm->plist_name, argv[0]->arg))
|
2017-05-22 22:32:14 +02:00
|
|
|
return pim_ssm_cmd_worker(pim, vty, NULL);
|
2017-03-17 19:51:13 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", argv[0]->arg);
|
2017-03-17 19:51:13 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2017-03-17 19:51:13 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void ip_pim_ssm_show_group_range(struct vty *vty,
|
|
|
|
struct pim_instance *pim, u_char uj)
|
2017-03-17 19:51:13 +01:00
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
struct pim_ssm *ssm = pim->ssm_info;
|
2017-07-17 14:03:14 +02:00
|
|
|
const char *range_str =
|
|
|
|
ssm->plist_name ? ssm->plist_name : PIM_SSM_STANDARD_RANGE;
|
2017-03-17 19:51:13 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (uj) {
|
|
|
|
json_object *json;
|
|
|
|
json = json_object_new_object();
|
|
|
|
json_object_string_add(json, "ssmGroups", range_str);
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
} else
|
|
|
|
vty_out(vty, "SSM group range : %s\n", range_str);
|
2017-03-17 19:51:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_pim_ssm_range,
|
|
|
|
show_ip_pim_ssm_range_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip pim [vrf NAME] group-type [json]",
|
2017-03-17 19:51:13 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2017-03-17 19:51:13 +01:00
|
|
|
"PIM group type\n"
|
|
|
|
"JavaScript Object Notation\n")
|
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
2017-07-17 14:03:14 +02:00
|
|
|
u_char uj = use_json(argc, argv);
|
2017-05-23 14:57:11 +02:00
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
ip_pim_ssm_show_group_range(vty, vrf->info, uj);
|
2017-03-17 19:51:13 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-03-17 19:51:13 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
static void ip_pim_ssm_show_group_type(struct vty *vty,
|
|
|
|
struct pim_instance *pim, u_char uj,
|
2017-07-17 14:03:14 +02:00
|
|
|
const char *group)
|
2017-03-17 19:51:13 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct in_addr group_addr;
|
|
|
|
const char *type_str;
|
|
|
|
int result;
|
2017-03-17 19:51:13 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
result = inet_pton(AF_INET, group, &group_addr);
|
|
|
|
if (result <= 0)
|
|
|
|
type_str = "invalid";
|
|
|
|
else {
|
|
|
|
if (pim_is_group_224_4(group_addr))
|
2017-05-23 14:57:11 +02:00
|
|
|
type_str =
|
|
|
|
pim_is_grp_ssm(pim, group_addr) ? "SSM" : "ASM";
|
2017-07-17 14:03:14 +02:00
|
|
|
else
|
|
|
|
type_str = "not-multicast";
|
|
|
|
}
|
2017-03-17 19:51:13 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (uj) {
|
|
|
|
json_object *json;
|
|
|
|
json = json_object_new_object();
|
|
|
|
json_object_string_add(json, "groupType", type_str);
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
} else
|
|
|
|
vty_out(vty, "Group type : %s\n", type_str);
|
2017-03-17 19:51:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_pim_group_type,
|
|
|
|
show_ip_pim_group_type_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip pim [vrf NAME] group-type A.B.C.D [json]",
|
2017-03-17 19:51:13 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
2017-05-23 14:57:11 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2017-03-17 19:51:13 +01:00
|
|
|
"multicast group type\n"
|
|
|
|
"group address\n"
|
|
|
|
"JavaScript Object Notation\n")
|
|
|
|
{
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
2017-07-17 14:03:14 +02:00
|
|
|
u_char uj = use_json(argc, argv);
|
2017-05-23 14:57:11 +02:00
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
argv_find(argv, argc, "A.B.C.D", &idx);
|
|
|
|
ip_pim_ssm_show_group_type(vty, vrf->info, uj, argv[idx]->arg);
|
2017-03-17 19:51:13 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-03-17 19:51:13 +01:00
|
|
|
}
|
|
|
|
|
2017-03-02 16:33:23 +01:00
|
|
|
DEFUN_HIDDEN (ip_multicast_routing,
|
|
|
|
ip_multicast_routing_cmd,
|
|
|
|
"ip multicast-routing",
|
|
|
|
IP_STR
|
|
|
|
"Enable IP multicast forwarding\n")
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-03-02 16:33:23 +01:00
|
|
|
DEFUN_HIDDEN (no_ip_multicast_routing,
|
|
|
|
no_ip_multicast_routing_cmd,
|
|
|
|
"no ip multicast-routing",
|
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"Enable IP multicast forwarding\n")
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty,
|
|
|
|
"Command is Disabled and will be removed in a future version\n");
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (ip_ssmpingd,
|
|
|
|
ip_ssmpingd_cmd,
|
|
|
|
"ip ssmpingd [A.B.C.D]",
|
|
|
|
IP_STR
|
|
|
|
CONF_SSMPINGD_STR
|
|
|
|
"Source address\n")
|
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
2017-07-17 14:03:14 +02:00
|
|
|
int idx_ipv4 = 2;
|
|
|
|
int result;
|
|
|
|
struct in_addr source_addr;
|
|
|
|
const char *source_str = (argc == 3) ? argv[idx_ipv4]->arg : "0.0.0.0";
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
result = inet_pton(AF_INET, source_str, &source_addr);
|
|
|
|
if (result <= 0) {
|
|
|
|
vty_out(vty, "%% Bad source address %s: errno=%d: %s\n",
|
|
|
|
source_str, errno, safe_strerror(errno));
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-05-22 22:32:14 +02:00
|
|
|
result = pim_ssmpingd_start(pim, source_addr);
|
2017-07-17 14:03:14 +02:00
|
|
|
if (result) {
|
|
|
|
vty_out(vty, "%% Failure starting ssmpingd for source %s: %d\n",
|
|
|
|
source_str, result);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ip_ssmpingd,
|
|
|
|
no_ip_ssmpingd_cmd,
|
|
|
|
"no ip ssmpingd [A.B.C.D]",
|
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
CONF_SSMPINGD_STR
|
|
|
|
"Source address\n")
|
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
2017-07-17 14:03:14 +02:00
|
|
|
int idx_ipv4 = 3;
|
|
|
|
int result;
|
|
|
|
struct in_addr source_addr;
|
|
|
|
const char *source_str = (argc == 4) ? argv[idx_ipv4]->arg : "0.0.0.0";
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
result = inet_pton(AF_INET, source_str, &source_addr);
|
|
|
|
if (result <= 0) {
|
|
|
|
vty_out(vty, "%% Bad source address %s: errno=%d: %s\n",
|
|
|
|
source_str, errno, safe_strerror(errno));
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-05-22 22:32:14 +02:00
|
|
|
result = pim_ssmpingd_stop(pim, source_addr);
|
2017-07-17 14:03:14 +02:00
|
|
|
if (result) {
|
|
|
|
vty_out(vty, "%% Failure stopping ssmpingd for source %s: %d\n",
|
|
|
|
source_str, result);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
pimd: Pim Nexthop Tracking support with ECMP
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>
2017-04-05 22:14:12 +02:00
|
|
|
DEFUN (ip_pim_ecmp,
|
|
|
|
ip_pim_ecmp_cmd,
|
|
|
|
"ip pim ecmp",
|
|
|
|
IP_STR
|
|
|
|
"pim multicast routing\n"
|
|
|
|
"Enable PIM ECMP \n")
|
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
2017-07-17 14:03:14 +02:00
|
|
|
qpim_ecmp_enable = 1;
|
pimd: Pim Nexthop Tracking support with ECMP
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>
2017-04-05 22:14:12 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
pimd: Pim Nexthop Tracking support with ECMP
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>
2017-04-05 22:14:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ip_pim_ecmp,
|
|
|
|
no_ip_pim_ecmp_cmd,
|
|
|
|
"no ip pim ecmp",
|
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"pim multicast routing\n"
|
|
|
|
"Disable PIM ECMP \n")
|
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
2017-07-17 14:03:14 +02:00
|
|
|
qpim_ecmp_enable = 0;
|
pimd: Pim Nexthop Tracking support with ECMP
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>
2017-04-05 22:14:12 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
pimd: Pim Nexthop Tracking support with ECMP
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>
2017-04-05 22:14:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (ip_pim_ecmp_rebalance,
|
|
|
|
ip_pim_ecmp_rebalance_cmd,
|
|
|
|
"ip pim ecmp rebalance",
|
|
|
|
IP_STR
|
|
|
|
"pim multicast routing\n"
|
|
|
|
"Enable PIM ECMP \n"
|
|
|
|
"Enable PIM ECMP Rebalance\n")
|
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
2017-07-17 14:03:14 +02:00
|
|
|
qpim_ecmp_enable = 1;
|
|
|
|
qpim_ecmp_rebalance_enable = 1;
|
pimd: Pim Nexthop Tracking support with ECMP
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>
2017-04-05 22:14:12 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
pimd: Pim Nexthop Tracking support with ECMP
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>
2017-04-05 22:14:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ip_pim_ecmp_rebalance,
|
|
|
|
no_ip_pim_ecmp_rebalance_cmd,
|
|
|
|
"no ip pim ecmp rebalance",
|
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"pim multicast routing\n"
|
|
|
|
"Disable PIM ECMP \n"
|
|
|
|
"Disable PIM ECMP Rebalance\n")
|
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
2017-07-17 14:03:14 +02:00
|
|
|
qpim_ecmp_rebalance_enable = 0;
|
pimd: Pim Nexthop Tracking support with ECMP
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>
2017-04-05 22:14:12 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
pimd: Pim Nexthop Tracking support with ECMP
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>
2017-04-05 22:14:12 +02:00
|
|
|
}
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
static int pim_cmd_igmp_start(struct vty *vty, struct interface *ifp)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
uint8_t need_startup = 0;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_ifp = ifp->info;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!pim_ifp) {
|
|
|
|
pim_ifp = pim_if_new(ifp, 1 /* igmp=true */, 0 /* pim=false */);
|
|
|
|
if (!pim_ifp) {
|
|
|
|
vty_out(vty, "Could not enable IGMP on interface %s\n",
|
|
|
|
ifp->name);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
need_startup = 1;
|
|
|
|
} else {
|
|
|
|
if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
|
|
|
|
PIM_IF_DO_IGMP(pim_ifp->options);
|
|
|
|
need_startup = 1;
|
|
|
|
}
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
/* 'ip igmp' executed multiple times, with need_startup
|
|
|
|
avoid multiple if add all and membership refresh */
|
|
|
|
if (need_startup) {
|
|
|
|
pim_if_addr_add_all(ifp);
|
|
|
|
pim_if_membership_refresh(ifp);
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-03-02 16:12:52 +01:00
|
|
|
DEFUN (interface_ip_igmp,
|
|
|
|
interface_ip_igmp_cmd,
|
|
|
|
"ip igmp",
|
|
|
|
IP_STR
|
|
|
|
IFACE_IGMP_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
2017-03-02 16:12:52 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return pim_cmd_igmp_start(vty, ifp);
|
2017-03-02 16:12:52 +01:00
|
|
|
}
|
|
|
|
|
2015-02-04 07:01:14 +01:00
|
|
|
DEFUN (interface_no_ip_igmp,
|
|
|
|
interface_no_ip_igmp_cmd,
|
|
|
|
"no ip igmp",
|
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
IFACE_IGMP_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
|
|
struct pim_interface *pim_ifp = ifp->info;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!pim_ifp)
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_IF_DONT_IGMP(pim_ifp->options);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_if_membership_clear(ifp);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_if_addr_del_all_igmp(ifp);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
|
|
|
|
pim_if_delete(ifp);
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (interface_ip_igmp_join,
|
|
|
|
interface_ip_igmp_join_cmd,
|
|
|
|
"ip igmp join A.B.C.D A.B.C.D",
|
|
|
|
IP_STR
|
|
|
|
IFACE_IGMP_STR
|
|
|
|
"IGMP join multicast group\n"
|
|
|
|
"Multicast group address\n"
|
|
|
|
"Source address\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
|
|
int idx_ipv4 = 3;
|
|
|
|
int idx_ipv4_2 = 4;
|
|
|
|
const char *group_str;
|
|
|
|
const char *source_str;
|
|
|
|
struct in_addr group_addr;
|
|
|
|
struct in_addr source_addr;
|
|
|
|
int result;
|
|
|
|
|
|
|
|
/* Group address */
|
|
|
|
group_str = argv[idx_ipv4]->arg;
|
|
|
|
result = inet_pton(AF_INET, group_str, &group_addr);
|
|
|
|
if (result <= 0) {
|
|
|
|
vty_out(vty, "Bad group address %s: errno=%d: %s\n", group_str,
|
|
|
|
errno, safe_strerror(errno));
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Source address */
|
|
|
|
source_str = argv[idx_ipv4_2]->arg;
|
|
|
|
result = inet_pton(AF_INET, source_str, &source_addr);
|
|
|
|
if (result <= 0) {
|
|
|
|
vty_out(vty, "Bad source address %s: errno=%d: %s\n",
|
|
|
|
source_str, errno, safe_strerror(errno));
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = pim_if_igmp_join_add(ifp, group_addr, source_addr);
|
|
|
|
if (result) {
|
|
|
|
vty_out(vty,
|
|
|
|
"%% Failure joining IGMP group %s source %s on interface %s: %d\n",
|
|
|
|
group_str, source_str, ifp->name, result);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (interface_no_ip_igmp_join,
|
|
|
|
interface_no_ip_igmp_join_cmd,
|
|
|
|
"no ip igmp join A.B.C.D A.B.C.D",
|
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
IFACE_IGMP_STR
|
|
|
|
"IGMP join multicast group\n"
|
|
|
|
"Multicast group address\n"
|
|
|
|
"Source address\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
|
|
int idx_ipv4 = 4;
|
|
|
|
int idx_ipv4_2 = 5;
|
|
|
|
const char *group_str;
|
|
|
|
const char *source_str;
|
|
|
|
struct in_addr group_addr;
|
|
|
|
struct in_addr source_addr;
|
|
|
|
int result;
|
|
|
|
|
|
|
|
/* Group address */
|
|
|
|
group_str = argv[idx_ipv4]->arg;
|
|
|
|
result = inet_pton(AF_INET, group_str, &group_addr);
|
|
|
|
if (result <= 0) {
|
|
|
|
vty_out(vty, "Bad group address %s: errno=%d: %s\n", group_str,
|
|
|
|
errno, safe_strerror(errno));
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Source address */
|
|
|
|
source_str = argv[idx_ipv4_2]->arg;
|
|
|
|
result = inet_pton(AF_INET, source_str, &source_addr);
|
|
|
|
if (result <= 0) {
|
|
|
|
vty_out(vty, "Bad source address %s: errno=%d: %s\n",
|
|
|
|
source_str, errno, safe_strerror(errno));
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = pim_if_igmp_join_del(ifp, group_addr, source_addr);
|
|
|
|
if (result) {
|
|
|
|
vty_out(vty,
|
|
|
|
"%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
|
|
|
|
group_str, source_str, ifp->name, result);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
CLI reconfiguration affects the interface level (struct pim_interface).
|
|
|
|
This function propagates the reconfiguration to every active socket
|
|
|
|
for that interface.
|
|
|
|
*/
|
|
|
|
static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
zassert(igmp);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
/* other querier present? */
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (igmp->t_other_querier_timer)
|
|
|
|
return;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
/* this is the querier */
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
zassert(igmp->interface);
|
|
|
|
zassert(igmp->interface->info);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
ifp = igmp->interface;
|
|
|
|
pim_ifp = ifp->info;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (PIM_DEBUG_IGMP_TRACE) {
|
|
|
|
char ifaddr_str[INET_ADDRSTRLEN];
|
|
|
|
pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
|
|
|
|
sizeof(ifaddr_str));
|
|
|
|
zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
|
|
|
|
__PRETTY_FUNCTION__, ifaddr_str, ifp->name,
|
|
|
|
pim_ifp->igmp_default_query_interval);
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
/*
|
|
|
|
igmp_startup_mode_on() will reset QQI:
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
|
|
|
|
*/
|
|
|
|
igmp_startup_mode_on(igmp);
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void igmp_sock_query_reschedule(struct igmp_sock *igmp)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
if (igmp->t_igmp_query_timer) {
|
|
|
|
/* other querier present */
|
|
|
|
zassert(igmp->t_igmp_query_timer);
|
|
|
|
zassert(!igmp->t_other_querier_timer);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_igmp_general_query_off(igmp);
|
|
|
|
pim_igmp_general_query_on(igmp);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
zassert(igmp->t_igmp_query_timer);
|
|
|
|
zassert(!igmp->t_other_querier_timer);
|
|
|
|
} else {
|
|
|
|
/* this is the querier */
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
zassert(!igmp->t_igmp_query_timer);
|
|
|
|
zassert(igmp->t_other_querier_timer);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_igmp_other_querier_timer_off(igmp);
|
|
|
|
pim_igmp_other_querier_timer_on(igmp);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
zassert(!igmp->t_igmp_query_timer);
|
|
|
|
zassert(igmp->t_other_querier_timer);
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void change_query_interval(struct pim_interface *pim_ifp,
|
|
|
|
int query_interval)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *sock_node;
|
|
|
|
struct igmp_sock *igmp;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_ifp->igmp_default_query_interval = query_interval;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
|
|
|
|
igmp_sock_query_interval_reconfig(igmp);
|
|
|
|
igmp_sock_query_reschedule(igmp);
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void change_query_max_response_time(struct pim_interface *pim_ifp,
|
|
|
|
int query_max_response_time_dsec)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *sock_node;
|
|
|
|
struct igmp_sock *igmp;
|
|
|
|
|
|
|
|
pim_ifp->igmp_query_max_response_time_dsec =
|
|
|
|
query_max_response_time_dsec;
|
|
|
|
|
|
|
|
/*
|
|
|
|
Below we modify socket/group/source timers in order to quickly
|
|
|
|
reflect the change. Otherwise, those timers would eventually catch
|
|
|
|
up.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* scan all sockets */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
|
|
|
|
struct listnode *grp_node;
|
|
|
|
struct igmp_group *grp;
|
|
|
|
|
|
|
|
/* reschedule socket general query */
|
|
|
|
igmp_sock_query_reschedule(igmp);
|
|
|
|
|
|
|
|
/* scan socket groups */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node,
|
|
|
|
grp)) {
|
|
|
|
struct listnode *src_node;
|
|
|
|
struct igmp_source *src;
|
|
|
|
|
|
|
|
/* reset group timers for groups in EXCLUDE mode */
|
|
|
|
if (grp->group_filtermode_isexcl) {
|
|
|
|
igmp_group_reset_gmi(grp);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* scan group sources */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
|
|
|
|
src_node, src)) {
|
|
|
|
|
|
|
|
/* reset source timers for sources with running
|
|
|
|
* timers */
|
|
|
|
if (src->t_source_timer) {
|
|
|
|
igmp_source_reset_gmi(igmp, grp, src);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#define IGMP_QUERY_INTERVAL_MIN (1)
|
|
|
|
#define IGMP_QUERY_INTERVAL_MAX (1800)
|
|
|
|
|
|
|
|
DEFUN (interface_ip_igmp_query_interval,
|
|
|
|
interface_ip_igmp_query_interval_cmd,
|
2016-09-25 16:10:48 +02:00
|
|
|
"ip igmp query-interval (1-1800)",
|
2015-02-04 07:01:14 +01:00
|
|
|
IP_STR
|
|
|
|
IFACE_IGMP_STR
|
|
|
|
IFACE_IGMP_QUERY_INTERVAL_STR
|
|
|
|
"Query interval in seconds\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
|
|
struct pim_interface *pim_ifp = ifp->info;
|
|
|
|
int query_interval;
|
|
|
|
int query_interval_dsec;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!pim_ifp) {
|
|
|
|
ret = pim_cmd_igmp_start(vty, ifp);
|
|
|
|
if (ret != CMD_SUCCESS)
|
|
|
|
return ret;
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
}
|
|
|
|
|
|
|
|
query_interval = atoi(argv[3]->arg);
|
|
|
|
query_interval_dsec = 10 * query_interval;
|
|
|
|
|
|
|
|
/*
|
|
|
|
It seems we don't need to check bounds since command.c does it
|
|
|
|
already, but we verify them anyway for extra safety.
|
|
|
|
*/
|
|
|
|
if (query_interval < IGMP_QUERY_INTERVAL_MIN) {
|
|
|
|
vty_out(vty,
|
|
|
|
"General query interval %d lower than minimum %d\n",
|
|
|
|
query_interval, IGMP_QUERY_INTERVAL_MIN);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
if (query_interval > IGMP_QUERY_INTERVAL_MAX) {
|
|
|
|
vty_out(vty,
|
|
|
|
"General query interval %d higher than maximum %d\n",
|
|
|
|
query_interval, IGMP_QUERY_INTERVAL_MAX);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
|
|
|
|
vty_out(vty,
|
|
|
|
"Can't set general query interval %d dsec <= query max response time %d dsec.\n",
|
|
|
|
query_interval_dsec,
|
|
|
|
pim_ifp->igmp_query_max_response_time_dsec);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
change_query_interval(pim_ifp, query_interval);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (interface_no_ip_igmp_query_interval,
|
|
|
|
interface_no_ip_igmp_query_interval_cmd,
|
2016-09-25 16:10:48 +02:00
|
|
|
"no ip igmp query-interval",
|
2015-02-04 07:01:14 +01:00
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
IFACE_IGMP_STR
|
|
|
|
IFACE_IGMP_QUERY_INTERVAL_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
|
|
struct pim_interface *pim_ifp = ifp->info;
|
|
|
|
int default_query_interval_dsec;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!pim_ifp)
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
default_query_interval_dsec = IGMP_GENERAL_QUERY_INTERVAL * 10;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (default_query_interval_dsec
|
|
|
|
<= pim_ifp->igmp_query_max_response_time_dsec) {
|
|
|
|
vty_out(vty,
|
|
|
|
"Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
|
|
|
|
default_query_interval_dsec,
|
|
|
|
pim_ifp->igmp_query_max_response_time_dsec);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
change_query_interval(pim_ifp, IGMP_GENERAL_QUERY_INTERVAL);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2016-10-20 15:34:29 +02:00
|
|
|
DEFUN (interface_ip_igmp_version,
|
|
|
|
interface_ip_igmp_version_cmd,
|
2017-01-26 15:10:54 +01:00
|
|
|
"ip igmp version (2-3)",
|
2016-10-20 15:34:29 +02:00
|
|
|
IP_STR
|
|
|
|
IFACE_IGMP_STR
|
|
|
|
"IGMP version\n"
|
|
|
|
"IGMP version number\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
|
|
struct pim_interface *pim_ifp = ifp->info;
|
|
|
|
int igmp_version, old_version = 0;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!pim_ifp) {
|
|
|
|
ret = pim_cmd_igmp_start(vty, ifp);
|
|
|
|
if (ret != CMD_SUCCESS)
|
|
|
|
return ret;
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
}
|
|
|
|
|
|
|
|
igmp_version = atoi(argv[3]->arg);
|
|
|
|
old_version = pim_ifp->igmp_version;
|
|
|
|
pim_ifp->igmp_version = igmp_version;
|
|
|
|
|
|
|
|
// Check if IGMP is Enabled otherwise, enable on interface
|
|
|
|
if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
|
|
|
|
PIM_IF_DO_IGMP(pim_ifp->options);
|
|
|
|
pim_if_addr_add_all(ifp);
|
|
|
|
pim_if_membership_refresh(ifp);
|
|
|
|
old_version = igmp_version; // avoid refreshing membership
|
|
|
|
// again.
|
|
|
|
}
|
|
|
|
/* Current and new version is different refresh existing
|
|
|
|
membership. Going from 3 -> 2 or 2 -> 3. */
|
|
|
|
if (old_version != igmp_version)
|
|
|
|
pim_if_membership_refresh(ifp);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
2016-10-20 15:34:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (interface_no_ip_igmp_version,
|
|
|
|
interface_no_ip_igmp_version_cmd,
|
2017-01-26 15:10:54 +01:00
|
|
|
"no ip igmp version (2-3)",
|
2016-10-20 15:34:29 +02:00
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
IFACE_IGMP_STR
|
|
|
|
"IGMP version\n"
|
|
|
|
"IGMP version number\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
|
|
struct pim_interface *pim_ifp = ifp->info;
|
2016-10-20 15:34:29 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!pim_ifp)
|
|
|
|
return CMD_SUCCESS;
|
2016-10-20 15:34:29 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_ifp->igmp_version = IGMP_DEFAULT_VERSION;
|
2016-10-20 15:34:29 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2016-10-20 15:34:29 +02:00
|
|
|
}
|
|
|
|
|
2016-11-29 21:48:54 +01:00
|
|
|
#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
|
|
|
|
#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
|
2015-02-04 07:01:14 +01:00
|
|
|
|
|
|
|
DEFUN (interface_ip_igmp_query_max_response_time,
|
|
|
|
interface_ip_igmp_query_max_response_time_cmd,
|
2016-11-29 21:48:54 +01:00
|
|
|
"ip igmp query-max-response-time (10-250)",
|
2015-02-04 07:01:14 +01:00
|
|
|
IP_STR
|
|
|
|
IFACE_IGMP_STR
|
|
|
|
IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
|
2016-11-29 21:48:54 +01:00
|
|
|
"Query response value in deci-seconds\n")
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
|
|
struct pim_interface *pim_ifp = ifp->info;
|
|
|
|
int query_max_response_time;
|
|
|
|
int ret;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!pim_ifp) {
|
|
|
|
ret = pim_cmd_igmp_start(vty, ifp);
|
|
|
|
if (ret != CMD_SUCCESS)
|
|
|
|
return ret;
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
query_max_response_time = atoi(argv[3]->arg);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (query_max_response_time
|
|
|
|
>= pim_ifp->igmp_default_query_interval * 10) {
|
|
|
|
vty_out(vty,
|
|
|
|
"Can't set query max response time %d sec >= general query interval %d sec\n",
|
|
|
|
query_max_response_time,
|
|
|
|
pim_ifp->igmp_default_query_interval);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
change_query_max_response_time(pim_ifp, query_max_response_time);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (interface_no_ip_igmp_query_max_response_time,
|
|
|
|
interface_no_ip_igmp_query_max_response_time_cmd,
|
2017-01-26 15:10:54 +01:00
|
|
|
"no ip igmp query-max-response-time (10-250)",
|
2015-02-04 07:01:14 +01:00
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
IFACE_IGMP_STR
|
2017-01-25 15:13:46 +01:00
|
|
|
IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
|
|
|
|
"Time for response in deci-seconds\n")
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
|
|
struct pim_interface *pim_ifp = ifp->info;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!pim_ifp)
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
change_query_max_response_time(pim_ifp,
|
|
|
|
IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
|
|
|
|
#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
|
|
|
|
|
2016-11-29 21:48:54 +01:00
|
|
|
DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec,
|
|
|
|
interface_ip_igmp_query_max_response_time_dsec_cmd,
|
|
|
|
"ip igmp query-max-response-time-dsec (10-250)",
|
|
|
|
IP_STR
|
|
|
|
IFACE_IGMP_STR
|
|
|
|
IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
|
|
|
|
"Query response value in deciseconds\n")
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
|
|
struct pim_interface *pim_ifp = ifp->info;
|
|
|
|
int query_max_response_time_dsec;
|
|
|
|
int default_query_interval_dsec;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!pim_ifp) {
|
|
|
|
ret = pim_cmd_igmp_start(vty, ifp);
|
|
|
|
if (ret != CMD_SUCCESS)
|
|
|
|
return ret;
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
query_max_response_time_dsec = atoi(argv[4]->arg);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (query_max_response_time_dsec >= default_query_interval_dsec) {
|
|
|
|
vty_out(vty,
|
|
|
|
"Can't set query max response time %d dsec >= general query interval %d dsec\n",
|
|
|
|
query_max_response_time_dsec,
|
|
|
|
default_query_interval_dsec);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
change_query_max_response_time(pim_ifp, query_max_response_time_dsec);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2016-11-29 21:48:54 +01:00
|
|
|
DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec,
|
|
|
|
interface_no_ip_igmp_query_max_response_time_dsec_cmd,
|
|
|
|
"no ip igmp query-max-response-time-dsec",
|
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
IFACE_IGMP_STR
|
|
|
|
IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
|
|
struct pim_interface *pim_ifp = ifp->info;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!pim_ifp)
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
change_query_max_response_time(pim_ifp,
|
|
|
|
IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2015-06-19 03:14:20 +02:00
|
|
|
DEFUN (interface_ip_pim_drprio,
|
|
|
|
interface_ip_pim_drprio_cmd,
|
2016-09-23 22:03:41 +02:00
|
|
|
"ip pim drpriority (1-4294967295)",
|
2015-06-19 03:14:20 +02:00
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
|
|
|
"Set the Designated Router Election Priority\n"
|
|
|
|
"Value of the new DR Priority\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
|
|
int idx_number = 3;
|
|
|
|
struct pim_interface *pim_ifp = ifp->info;
|
|
|
|
uint32_t old_dr_prio;
|
2015-06-19 03:14:20 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!pim_ifp) {
|
|
|
|
vty_out(vty, "Please enable PIM on interface, first\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2015-06-19 03:14:20 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
old_dr_prio = pim_ifp->pim_dr_priority;
|
2015-06-19 03:14:20 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_ifp->pim_dr_priority = strtol(argv[idx_number]->arg, NULL, 10);
|
2015-06-19 03:14:20 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (old_dr_prio != pim_ifp->pim_dr_priority) {
|
|
|
|
if (pim_if_dr_election(ifp))
|
|
|
|
pim_hello_restart_now(ifp);
|
|
|
|
}
|
2015-06-19 03:14:20 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-06-19 03:14:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (interface_no_ip_pim_drprio,
|
|
|
|
interface_no_ip_pim_drprio_cmd,
|
2016-09-23 22:03:41 +02:00
|
|
|
"no ip pim drpriority [(1-4294967295)]",
|
2016-11-08 02:46:04 +01:00
|
|
|
NO_STR
|
2015-06-19 03:14:20 +02:00
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
|
|
|
"Revert the Designated Router Priority to default\n"
|
|
|
|
"Old Value of the Priority\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
|
|
struct pim_interface *pim_ifp = ifp->info;
|
2015-06-19 03:14:20 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!pim_ifp) {
|
|
|
|
vty_out(vty, "Pim not enabled on this interface\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2015-06-19 03:14:20 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
|
|
|
|
pim_ifp->pim_dr_priority = PIM_DEFAULT_DR_PRIORITY;
|
|
|
|
if (pim_if_dr_election(ifp))
|
|
|
|
pim_hello_restart_now(ifp);
|
|
|
|
}
|
2015-06-19 03:14:20 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-06-19 03:14:20 +02:00
|
|
|
}
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
static int pim_cmd_interface_add(struct interface *ifp)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct pim_interface *pim_ifp = ifp->info;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!pim_ifp) {
|
|
|
|
pim_ifp = pim_if_new(ifp, 0 /* igmp=false */, 1 /* pim=true */);
|
|
|
|
if (!pim_ifp) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
PIM_IF_DO_PIM(pim_ifp->options);
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_if_addr_add_all(ifp);
|
|
|
|
pim_if_membership_refresh(ifp);
|
|
|
|
return 1;
|
2015-09-08 17:10:19 +02:00
|
|
|
}
|
|
|
|
|
2017-03-21 18:12:30 +01:00
|
|
|
DEFUN_HIDDEN (interface_ip_pim_ssm,
|
2015-09-08 17:10:19 +02:00
|
|
|
interface_ip_pim_ssm_cmd,
|
|
|
|
"ip pim ssm",
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
|
|
|
IFACE_PIM_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
2015-09-08 17:10:19 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!pim_cmd_interface_add(ifp)) {
|
|
|
|
vty_out(vty, "Could not enable PIM SM on interface\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2015-09-08 17:10:19 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty,
|
|
|
|
"WARN: Enabled PIM SM on interface; configure PIM SSM "
|
|
|
|
"range if needed\n");
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2015-09-08 17:10:19 +02:00
|
|
|
DEFUN (interface_ip_pim_sm,
|
|
|
|
interface_ip_pim_sm_cmd,
|
|
|
|
"ip pim sm",
|
2015-02-04 07:01:14 +01:00
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
2016-06-01 17:26:29 +02:00
|
|
|
IFACE_PIM_SM_STR)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-05-17 22:21:33 +02:00
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
|
|
if (!pim_cmd_interface_add(ifp)) {
|
|
|
|
vty_out(vty, "Could not enable PIM SM on interface\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2015-09-08 17:10:19 +02:00
|
|
|
|
2017-05-17 22:21:33 +02:00
|
|
|
pim_ifp = ifp->info;
|
2017-05-17 21:08:39 +02:00
|
|
|
|
2017-05-17 22:21:33 +02:00
|
|
|
pim_if_create_pimreg(pim_ifp->pim);
|
2015-10-29 14:35:12 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-09-08 17:10:19 +02:00
|
|
|
}
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
static int pim_cmd_interface_delete(struct interface *ifp)
|
2015-09-08 17:10:19 +02:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct pim_interface *pim_ifp = ifp->info;
|
2015-09-08 17:10:19 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!pim_ifp)
|
|
|
|
return 1;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_IF_DONT_PIM(pim_ifp->options);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_if_membership_clear(ifp);
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
/*
|
|
|
|
pim_sock_delete() removes all neighbors from
|
|
|
|
pim_ifp->pim_neighbor_list.
|
|
|
|
*/
|
|
|
|
pim_sock_delete(ifp, "pim unconfigured on interface");
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
|
|
|
|
pim_if_addr_del_all(ifp);
|
|
|
|
pim_if_delete(ifp);
|
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return 1;
|
2015-09-08 17:10:19 +02:00
|
|
|
}
|
|
|
|
|
2017-03-21 18:12:30 +01:00
|
|
|
DEFUN_HIDDEN (interface_no_ip_pim_ssm,
|
2015-09-08 17:10:19 +02:00
|
|
|
interface_no_ip_pim_ssm_cmd,
|
|
|
|
"no ip pim ssm",
|
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
|
|
|
IFACE_PIM_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
|
|
if (!pim_cmd_interface_delete(ifp)) {
|
|
|
|
vty_out(vty, "Unable to delete interface information\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2015-09-08 17:10:19 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-09-08 17:10:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (interface_no_ip_pim_sm,
|
|
|
|
interface_no_ip_pim_sm_cmd,
|
|
|
|
"no ip pim sm",
|
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
2016-06-01 17:26:29 +02:00
|
|
|
IFACE_PIM_SM_STR)
|
2015-09-08 17:10:19 +02:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
|
|
if (!pim_cmd_interface_delete(ifp)) {
|
|
|
|
vty_out(vty, "Unable to delete interface information\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2015-09-08 17:10:19 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2015-06-12 01:29:02 +02:00
|
|
|
DEFUN (interface_ip_mroute,
|
|
|
|
interface_ip_mroute_cmd,
|
|
|
|
"ip mroute INTERFACE A.B.C.D",
|
|
|
|
IP_STR
|
|
|
|
"Add multicast route\n"
|
|
|
|
"Outgoing interface name\n"
|
|
|
|
"Group address\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, iif);
|
2017-05-19 01:56:10 +02:00
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
struct pim_instance *pim;
|
2017-07-17 14:03:14 +02:00
|
|
|
int idx_interface = 2;
|
|
|
|
int idx_ipv4 = 3;
|
|
|
|
struct interface *oif;
|
|
|
|
const char *oifname;
|
|
|
|
const char *grp_str;
|
|
|
|
struct in_addr grp_addr;
|
|
|
|
struct in_addr src_addr;
|
|
|
|
int result;
|
|
|
|
|
2017-05-19 01:56:10 +02:00
|
|
|
pim_ifp = iif->info;
|
|
|
|
pim = pim_ifp->pim;
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
oifname = argv[idx_interface]->arg;
|
2017-05-19 01:56:10 +02:00
|
|
|
oif = if_lookup_by_name(oifname, pim->vrf_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!oif) {
|
|
|
|
vty_out(vty, "No such interface name %s\n", oifname);
|
2017-05-19 01:56:10 +02:00
|
|
|
return CMD_WARNING;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
grp_str = argv[idx_ipv4]->arg;
|
|
|
|
result = inet_pton(AF_INET, grp_str, &grp_addr);
|
|
|
|
if (result <= 0) {
|
|
|
|
vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
|
|
|
|
errno, safe_strerror(errno));
|
2017-05-19 01:56:10 +02:00
|
|
|
return CMD_WARNING;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
src_addr.s_addr = INADDR_ANY;
|
|
|
|
|
2017-05-19 01:56:10 +02:00
|
|
|
if (pim_static_add(pim, iif, oif, grp_addr, src_addr)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty, "Failed to add route\n");
|
2017-05-19 01:56:10 +02:00
|
|
|
return CMD_WARNING;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
2015-06-12 01:29:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (interface_ip_mroute_source,
|
|
|
|
interface_ip_mroute_source_cmd,
|
|
|
|
"ip mroute INTERFACE A.B.C.D A.B.C.D",
|
|
|
|
IP_STR
|
|
|
|
"Add multicast route\n"
|
|
|
|
"Outgoing interface name\n"
|
|
|
|
"Group address\n"
|
|
|
|
"Source address\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, iif);
|
2017-05-19 01:56:10 +02:00
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
struct pim_instance *pim;
|
2017-07-17 14:03:14 +02:00
|
|
|
int idx_interface = 2;
|
|
|
|
int idx_ipv4 = 3;
|
|
|
|
int idx_ipv4_2 = 4;
|
|
|
|
struct interface *oif;
|
|
|
|
const char *oifname;
|
|
|
|
const char *grp_str;
|
|
|
|
struct in_addr grp_addr;
|
|
|
|
const char *src_str;
|
|
|
|
struct in_addr src_addr;
|
|
|
|
int result;
|
|
|
|
|
2017-05-19 01:56:10 +02:00
|
|
|
pim_ifp = iif->info;
|
|
|
|
pim = pim_ifp->pim;
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
oifname = argv[idx_interface]->arg;
|
2017-05-19 01:56:10 +02:00
|
|
|
oif = if_lookup_by_name(oifname, pim->vrf_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!oif) {
|
|
|
|
vty_out(vty, "No such interface name %s\n", oifname);
|
2017-05-19 01:56:10 +02:00
|
|
|
return CMD_WARNING;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
grp_str = argv[idx_ipv4]->arg;
|
|
|
|
result = inet_pton(AF_INET, grp_str, &grp_addr);
|
|
|
|
if (result <= 0) {
|
|
|
|
vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
|
|
|
|
errno, safe_strerror(errno));
|
2017-05-19 01:56:10 +02:00
|
|
|
return CMD_WARNING;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
src_str = argv[idx_ipv4_2]->arg;
|
|
|
|
result = inet_pton(AF_INET, src_str, &src_addr);
|
|
|
|
if (result <= 0) {
|
|
|
|
vty_out(vty, "Bad source address %s: errno=%d: %s\n", src_str,
|
|
|
|
errno, safe_strerror(errno));
|
2017-05-19 01:56:10 +02:00
|
|
|
return CMD_WARNING;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2017-05-19 01:56:10 +02:00
|
|
|
if (pim_static_add(pim, iif, oif, grp_addr, src_addr)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty, "Failed to add route\n");
|
2017-05-19 01:56:10 +02:00
|
|
|
return CMD_WARNING;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
2015-06-12 01:29:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (interface_no_ip_mroute,
|
|
|
|
interface_no_ip_mroute_cmd,
|
|
|
|
"no ip mroute INTERFACE A.B.C.D",
|
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"Add multicast route\n"
|
|
|
|
"Outgoing interface name\n"
|
|
|
|
"Group Address\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, iif);
|
2017-05-19 01:56:10 +02:00
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
struct pim_instance *pim;
|
2017-07-17 14:03:14 +02:00
|
|
|
int idx_interface = 3;
|
|
|
|
int idx_ipv4 = 4;
|
|
|
|
struct interface *oif;
|
|
|
|
const char *oifname;
|
|
|
|
const char *grp_str;
|
|
|
|
struct in_addr grp_addr;
|
|
|
|
struct in_addr src_addr;
|
|
|
|
int result;
|
|
|
|
|
2017-05-19 01:56:10 +02:00
|
|
|
pim_ifp = iif->info;
|
|
|
|
pim = pim_ifp->pim;
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
oifname = argv[idx_interface]->arg;
|
2017-05-19 01:56:10 +02:00
|
|
|
oif = if_lookup_by_name(oifname, pim->vrf_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!oif) {
|
|
|
|
vty_out(vty, "No such interface name %s\n", oifname);
|
2017-05-19 01:56:10 +02:00
|
|
|
return CMD_WARNING;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
grp_str = argv[idx_ipv4]->arg;
|
|
|
|
result = inet_pton(AF_INET, grp_str, &grp_addr);
|
|
|
|
if (result <= 0) {
|
|
|
|
vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
|
|
|
|
errno, safe_strerror(errno));
|
2017-05-19 01:56:10 +02:00
|
|
|
return CMD_WARNING;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
src_addr.s_addr = INADDR_ANY;
|
|
|
|
|
2017-05-19 01:56:10 +02:00
|
|
|
if (pim_static_del(pim, iif, oif, grp_addr, src_addr)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty, "Failed to remove route\n");
|
2017-05-19 01:56:10 +02:00
|
|
|
return CMD_WARNING;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
2015-06-12 01:29:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (interface_no_ip_mroute_source,
|
|
|
|
interface_no_ip_mroute_source_cmd,
|
|
|
|
"no ip mroute INTERFACE A.B.C.D A.B.C.D",
|
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"Add multicast route\n"
|
|
|
|
"Outgoing interface name\n"
|
|
|
|
"Group Address\n"
|
|
|
|
"Source Address\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, iif);
|
2017-05-19 01:56:10 +02:00
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
struct pim_instance *pim;
|
2017-07-17 14:03:14 +02:00
|
|
|
int idx_interface = 3;
|
|
|
|
int idx_ipv4 = 4;
|
|
|
|
int idx_ipv4_2 = 5;
|
|
|
|
struct interface *oif;
|
|
|
|
const char *oifname;
|
|
|
|
const char *grp_str;
|
|
|
|
struct in_addr grp_addr;
|
|
|
|
const char *src_str;
|
|
|
|
struct in_addr src_addr;
|
|
|
|
int result;
|
|
|
|
|
2017-05-19 01:56:10 +02:00
|
|
|
pim_ifp = iif->info;
|
|
|
|
pim = pim_ifp->pim;
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
oifname = argv[idx_interface]->arg;
|
2017-05-19 01:56:10 +02:00
|
|
|
oif = if_lookup_by_name(oifname, pim->vrf_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!oif) {
|
|
|
|
vty_out(vty, "No such interface name %s\n", oifname);
|
2017-05-19 01:56:10 +02:00
|
|
|
return CMD_WARNING;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
grp_str = argv[idx_ipv4]->arg;
|
|
|
|
result = inet_pton(AF_INET, grp_str, &grp_addr);
|
|
|
|
if (result <= 0) {
|
|
|
|
vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
|
|
|
|
errno, safe_strerror(errno));
|
2017-05-19 01:56:10 +02:00
|
|
|
return CMD_WARNING;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
src_str = argv[idx_ipv4_2]->arg;
|
|
|
|
result = inet_pton(AF_INET, src_str, &src_addr);
|
|
|
|
if (result <= 0) {
|
|
|
|
vty_out(vty, "Bad source address %s: errno=%d: %s\n", src_str,
|
|
|
|
errno, safe_strerror(errno));
|
2017-05-19 01:56:10 +02:00
|
|
|
return CMD_WARNING;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2017-05-19 01:56:10 +02:00
|
|
|
if (pim_static_del(pim, iif, oif, grp_addr, src_addr)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty, "Failed to remove route\n");
|
2017-05-19 01:56:10 +02:00
|
|
|
return CMD_WARNING;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
2015-06-12 01:29:02 +02:00
|
|
|
}
|
|
|
|
|
2015-08-22 01:35:27 +02:00
|
|
|
DEFUN (interface_ip_pim_hello,
|
|
|
|
interface_ip_pim_hello_cmd,
|
2016-09-27 02:26:41 +02:00
|
|
|
"ip pim hello (1-180) [(1-180)]",
|
2015-08-22 01:35:27 +02:00
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
|
|
|
IFACE_PIM_HELLO_STR
|
2016-09-27 02:26:41 +02:00
|
|
|
IFACE_PIM_HELLO_TIME_STR
|
|
|
|
IFACE_PIM_HELLO_HOLD_STR)
|
2015-08-22 01:35:27 +02:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
|
|
int idx_time = 3;
|
|
|
|
int idx_hold = 4;
|
|
|
|
struct pim_interface *pim_ifp = ifp->info;
|
2015-08-22 01:35:27 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!pim_ifp) {
|
|
|
|
if (!pim_cmd_interface_add(ifp)) {
|
|
|
|
vty_out(vty, "Could not enable PIM SM on interface\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
}
|
2015-08-22 01:35:27 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_ifp = ifp->info;
|
|
|
|
pim_ifp->pim_hello_period = strtol(argv[idx_time]->arg, NULL, 10);
|
2015-08-22 01:35:27 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (argc == idx_hold + 1)
|
|
|
|
pim_ifp->pim_default_holdtime =
|
|
|
|
strtol(argv[idx_hold]->arg, NULL, 10);
|
2015-08-22 01:35:27 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-08-22 01:35:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (interface_no_ip_pim_hello,
|
|
|
|
interface_no_ip_pim_hello_cmd,
|
2016-09-23 22:03:41 +02:00
|
|
|
"no ip pim hello [(1-180) (1-180)]",
|
2015-08-22 01:35:27 +02:00
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
|
|
|
IFACE_PIM_HELLO_STR
|
|
|
|
IFACE_PIM_HELLO_TIME_STR
|
|
|
|
IFACE_PIM_HELLO_HOLD_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
|
|
struct pim_interface *pim_ifp = ifp->info;
|
2015-08-22 01:35:27 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!pim_ifp) {
|
|
|
|
vty_out(vty, "Pim not enabled on this interface\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2015-08-22 01:35:27 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_ifp->pim_hello_period = PIM_DEFAULT_HELLO_PERIOD;
|
|
|
|
pim_ifp->pim_default_holdtime = -1;
|
2015-08-22 01:35:27 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-08-22 01:35:27 +02:00
|
|
|
}
|
|
|
|
|
2015-02-04 07:01:14 +01:00
|
|
|
DEFUN (debug_igmp,
|
|
|
|
debug_igmp_cmd,
|
|
|
|
"debug igmp",
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_IGMP_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DO_DEBUG_IGMP_EVENTS;
|
|
|
|
PIM_DO_DEBUG_IGMP_PACKETS;
|
|
|
|
PIM_DO_DEBUG_IGMP_TRACE;
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_debug_igmp,
|
|
|
|
no_debug_igmp_cmd,
|
|
|
|
"no debug igmp",
|
|
|
|
NO_STR
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_IGMP_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DONT_DEBUG_IGMP_EVENTS;
|
|
|
|
PIM_DONT_DEBUG_IGMP_PACKETS;
|
|
|
|
PIM_DONT_DEBUG_IGMP_TRACE;
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DEFUN (debug_igmp_events,
|
|
|
|
debug_igmp_events_cmd,
|
|
|
|
"debug igmp events",
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_IGMP_STR
|
|
|
|
DEBUG_IGMP_EVENTS_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DO_DEBUG_IGMP_EVENTS;
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_debug_igmp_events,
|
|
|
|
no_debug_igmp_events_cmd,
|
|
|
|
"no debug igmp events",
|
|
|
|
NO_STR
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_IGMP_STR
|
|
|
|
DEBUG_IGMP_EVENTS_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DONT_DEBUG_IGMP_EVENTS;
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DEFUN (debug_igmp_packets,
|
|
|
|
debug_igmp_packets_cmd,
|
|
|
|
"debug igmp packets",
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_IGMP_STR
|
|
|
|
DEBUG_IGMP_PACKETS_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DO_DEBUG_IGMP_PACKETS;
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_debug_igmp_packets,
|
|
|
|
no_debug_igmp_packets_cmd,
|
|
|
|
"no debug igmp packets",
|
|
|
|
NO_STR
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_IGMP_STR
|
|
|
|
DEBUG_IGMP_PACKETS_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DONT_DEBUG_IGMP_PACKETS;
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DEFUN (debug_igmp_trace,
|
|
|
|
debug_igmp_trace_cmd,
|
|
|
|
"debug igmp trace",
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_IGMP_STR
|
|
|
|
DEBUG_IGMP_TRACE_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DO_DEBUG_IGMP_TRACE;
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_debug_igmp_trace,
|
|
|
|
no_debug_igmp_trace_cmd,
|
|
|
|
"no debug igmp trace",
|
|
|
|
NO_STR
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_IGMP_STR
|
|
|
|
DEBUG_IGMP_TRACE_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DONT_DEBUG_IGMP_TRACE;
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DEFUN (debug_mroute,
|
|
|
|
debug_mroute_cmd,
|
|
|
|
"debug mroute",
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_MROUTE_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DO_DEBUG_MROUTE;
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2016-08-17 03:13:22 +02:00
|
|
|
DEFUN (debug_mroute_detail,
|
|
|
|
debug_mroute_detail_cmd,
|
|
|
|
"debug mroute detail",
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_MROUTE_STR
|
|
|
|
"detailed\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DO_DEBUG_MROUTE_DETAIL;
|
|
|
|
return CMD_SUCCESS;
|
2016-08-17 03:13:22 +02:00
|
|
|
}
|
|
|
|
|
2015-02-04 07:01:14 +01:00
|
|
|
DEFUN (no_debug_mroute,
|
|
|
|
no_debug_mroute_cmd,
|
|
|
|
"no debug mroute",
|
|
|
|
NO_STR
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_MROUTE_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DONT_DEBUG_MROUTE;
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2016-08-17 03:13:22 +02:00
|
|
|
DEFUN (no_debug_mroute_detail,
|
|
|
|
no_debug_mroute_detail_cmd,
|
|
|
|
"no debug mroute detail",
|
|
|
|
NO_STR
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_MROUTE_STR
|
|
|
|
"detailed\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DONT_DEBUG_MROUTE_DETAIL;
|
|
|
|
return CMD_SUCCESS;
|
2016-08-17 03:13:22 +02:00
|
|
|
}
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2015-06-12 01:29:02 +02:00
|
|
|
DEFUN (debug_static,
|
|
|
|
debug_static_cmd,
|
|
|
|
"debug static",
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_STATIC_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DO_DEBUG_STATIC;
|
|
|
|
return CMD_SUCCESS;
|
2015-06-12 01:29:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_debug_static,
|
|
|
|
no_debug_static_cmd,
|
|
|
|
"no debug static",
|
|
|
|
NO_STR
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_STATIC_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DONT_DEBUG_STATIC;
|
|
|
|
return CMD_SUCCESS;
|
2015-06-12 01:29:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-02-04 07:01:14 +01:00
|
|
|
DEFUN (debug_pim,
|
|
|
|
debug_pim_cmd,
|
|
|
|
"debug pim",
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_PIM_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DO_DEBUG_PIM_EVENTS;
|
|
|
|
PIM_DO_DEBUG_PIM_PACKETS;
|
|
|
|
PIM_DO_DEBUG_PIM_TRACE;
|
|
|
|
PIM_DO_DEBUG_MSDP_EVENTS;
|
|
|
|
PIM_DO_DEBUG_MSDP_PACKETS;
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_debug_pim,
|
|
|
|
no_debug_pim_cmd,
|
|
|
|
"no debug pim",
|
|
|
|
NO_STR
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_PIM_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DONT_DEBUG_PIM_EVENTS;
|
|
|
|
PIM_DONT_DEBUG_PIM_PACKETS;
|
|
|
|
PIM_DONT_DEBUG_PIM_TRACE;
|
|
|
|
PIM_DONT_DEBUG_MSDP_EVENTS;
|
|
|
|
PIM_DONT_DEBUG_MSDP_PACKETS;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
|
|
|
|
PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
|
2015-02-04 07:01:14 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DEFUN (debug_pim_events,
|
|
|
|
debug_pim_events_cmd,
|
|
|
|
"debug pim events",
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_PIM_STR
|
|
|
|
DEBUG_PIM_EVENTS_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DO_DEBUG_PIM_EVENTS;
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_debug_pim_events,
|
|
|
|
no_debug_pim_events_cmd,
|
|
|
|
"no debug pim events",
|
|
|
|
NO_STR
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_PIM_STR
|
|
|
|
DEBUG_PIM_EVENTS_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DONT_DEBUG_PIM_EVENTS;
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (debug_pim_packets,
|
|
|
|
debug_pim_packets_cmd,
|
2017-01-25 15:13:46 +01:00
|
|
|
"debug pim packets [<hello|joins|register>]",
|
2015-02-04 07:01:14 +01:00
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_PIM_STR
|
|
|
|
DEBUG_PIM_PACKETS_STR
|
|
|
|
DEBUG_PIM_HELLO_PACKETS_STR
|
2016-08-03 03:44:29 +02:00
|
|
|
DEBUG_PIM_J_P_PACKETS_STR
|
|
|
|
DEBUG_PIM_PIM_REG_PACKETS_STR)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
int idx = 0;
|
|
|
|
if (argv_find(argv, argc, "hello", &idx)) {
|
|
|
|
PIM_DO_DEBUG_PIM_HELLO;
|
|
|
|
vty_out(vty, "PIM Hello debugging is on\n");
|
|
|
|
} else if (argv_find(argv, argc, "joins", &idx)) {
|
|
|
|
PIM_DO_DEBUG_PIM_J_P;
|
|
|
|
vty_out(vty, "PIM Join/Prune debugging is on\n");
|
|
|
|
} else if (argv_find(argv, argc, "register", &idx)) {
|
|
|
|
PIM_DO_DEBUG_PIM_REG;
|
|
|
|
vty_out(vty, "PIM Register debugging is on\n");
|
|
|
|
} else {
|
|
|
|
PIM_DO_DEBUG_PIM_PACKETS;
|
|
|
|
vty_out(vty, "PIM Packet debugging is on \n");
|
|
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_debug_pim_packets,
|
|
|
|
no_debug_pim_packets_cmd,
|
2017-01-25 15:13:46 +01:00
|
|
|
"no debug pim packets [<hello|joins|register>]",
|
2015-02-04 07:01:14 +01:00
|
|
|
NO_STR
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_PIM_STR
|
|
|
|
DEBUG_PIM_PACKETS_STR
|
|
|
|
DEBUG_PIM_HELLO_PACKETS_STR
|
2017-01-25 15:13:46 +01:00
|
|
|
DEBUG_PIM_J_P_PACKETS_STR
|
|
|
|
DEBUG_PIM_PIM_REG_PACKETS_STR)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
int idx = 0;
|
|
|
|
if (argv_find(argv, argc, "hello", &idx)) {
|
|
|
|
PIM_DONT_DEBUG_PIM_HELLO;
|
|
|
|
vty_out(vty, "PIM Hello debugging is off \n");
|
|
|
|
} else if (argv_find(argv, argc, "joins", &idx)) {
|
|
|
|
PIM_DONT_DEBUG_PIM_J_P;
|
|
|
|
vty_out(vty, "PIM Join/Prune debugging is off \n");
|
|
|
|
} else if (argv_find(argv, argc, "register", &idx)) {
|
|
|
|
PIM_DONT_DEBUG_PIM_REG;
|
|
|
|
vty_out(vty, "PIM Register debugging is off\n");
|
|
|
|
} else
|
|
|
|
PIM_DONT_DEBUG_PIM_PACKETS;
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DEFUN (debug_pim_packetdump_send,
|
|
|
|
debug_pim_packetdump_send_cmd,
|
|
|
|
"debug pim packet-dump send",
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_PIM_STR
|
|
|
|
DEBUG_PIM_PACKETDUMP_STR
|
|
|
|
DEBUG_PIM_PACKETDUMP_SEND_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_debug_pim_packetdump_send,
|
|
|
|
no_debug_pim_packetdump_send_cmd,
|
|
|
|
"no debug pim packet-dump send",
|
|
|
|
NO_STR
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_PIM_STR
|
|
|
|
DEBUG_PIM_PACKETDUMP_STR
|
|
|
|
DEBUG_PIM_PACKETDUMP_SEND_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (debug_pim_packetdump_recv,
|
|
|
|
debug_pim_packetdump_recv_cmd,
|
|
|
|
"debug pim packet-dump receive",
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_PIM_STR
|
|
|
|
DEBUG_PIM_PACKETDUMP_STR
|
|
|
|
DEBUG_PIM_PACKETDUMP_RECV_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_debug_pim_packetdump_recv,
|
|
|
|
no_debug_pim_packetdump_recv_cmd,
|
|
|
|
"no debug pim packet-dump receive",
|
|
|
|
NO_STR
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_PIM_STR
|
|
|
|
DEBUG_PIM_PACKETDUMP_STR
|
|
|
|
DEBUG_PIM_PACKETDUMP_RECV_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (debug_pim_trace,
|
|
|
|
debug_pim_trace_cmd,
|
|
|
|
"debug pim trace",
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_PIM_STR
|
|
|
|
DEBUG_PIM_TRACE_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DO_DEBUG_PIM_TRACE;
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-06-05 19:15:47 +02:00
|
|
|
DEFUN (debug_pim_trace_detail,
|
|
|
|
debug_pim_trace_detail_cmd,
|
|
|
|
"debug pim trace detail",
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_PIM_STR
|
2017-06-05 19:39:08 +02:00
|
|
|
DEBUG_PIM_TRACE_STR
|
|
|
|
"Detailed Information\n")
|
2017-06-05 19:15:47 +02:00
|
|
|
{
|
|
|
|
PIM_DO_DEBUG_PIM_TRACE_DETAIL;
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2015-02-04 07:01:14 +01:00
|
|
|
DEFUN (no_debug_pim_trace,
|
|
|
|
no_debug_pim_trace_cmd,
|
|
|
|
"no debug pim trace",
|
|
|
|
NO_STR
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_PIM_STR
|
|
|
|
DEBUG_PIM_TRACE_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DONT_DEBUG_PIM_TRACE;
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-06-05 19:15:47 +02:00
|
|
|
DEFUN (no_debug_pim_trace_detail,
|
|
|
|
no_debug_pim_trace_detail_cmd,
|
2017-06-16 17:31:36 +02:00
|
|
|
"no debug pim trace detail",
|
2017-06-05 19:15:47 +02:00
|
|
|
NO_STR
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_PIM_STR
|
|
|
|
DEBUG_PIM_TRACE_STR)
|
|
|
|
{
|
|
|
|
PIM_DONT_DEBUG_PIM_TRACE_DETAIL;
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2015-02-04 07:01:14 +01:00
|
|
|
DEFUN (debug_ssmpingd,
|
|
|
|
debug_ssmpingd_cmd,
|
|
|
|
"debug ssmpingd",
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_SSMPINGD_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DO_DEBUG_SSMPINGD;
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_debug_ssmpingd,
|
|
|
|
no_debug_ssmpingd_cmd,
|
|
|
|
"no debug ssmpingd",
|
|
|
|
NO_STR
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_SSMPINGD_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DONT_DEBUG_SSMPINGD;
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (debug_pim_zebra,
|
|
|
|
debug_pim_zebra_cmd,
|
|
|
|
"debug pim zebra",
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_PIM_STR
|
|
|
|
DEBUG_PIM_ZEBRA_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DO_DEBUG_ZEBRA;
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_debug_pim_zebra,
|
|
|
|
no_debug_pim_zebra_cmd,
|
|
|
|
"no debug pim zebra",
|
|
|
|
NO_STR
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_PIM_STR
|
|
|
|
DEBUG_PIM_ZEBRA_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DONT_DEBUG_ZEBRA;
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2016-10-25 19:59:48 +02:00
|
|
|
DEFUN (debug_msdp,
|
|
|
|
debug_msdp_cmd,
|
|
|
|
"debug msdp",
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_MSDP_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DO_DEBUG_MSDP_EVENTS;
|
|
|
|
PIM_DO_DEBUG_MSDP_PACKETS;
|
|
|
|
return CMD_SUCCESS;
|
2016-10-25 19:59:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_debug_msdp,
|
|
|
|
no_debug_msdp_cmd,
|
|
|
|
"no debug msdp",
|
|
|
|
NO_STR
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_MSDP_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DONT_DEBUG_MSDP_EVENTS;
|
|
|
|
PIM_DONT_DEBUG_MSDP_PACKETS;
|
|
|
|
return CMD_SUCCESS;
|
2016-10-25 19:59:48 +02:00
|
|
|
}
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
ALIAS(no_debug_msdp, undebug_msdp_cmd, "undebug msdp",
|
|
|
|
UNDEBUG_STR DEBUG_MSDP_STR)
|
2016-10-25 19:59:48 +02:00
|
|
|
|
|
|
|
DEFUN (debug_msdp_events,
|
|
|
|
debug_msdp_events_cmd,
|
|
|
|
"debug msdp events",
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_MSDP_STR
|
|
|
|
DEBUG_MSDP_EVENTS_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DO_DEBUG_MSDP_EVENTS;
|
|
|
|
return CMD_SUCCESS;
|
2016-10-25 19:59:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_debug_msdp_events,
|
|
|
|
no_debug_msdp_events_cmd,
|
|
|
|
"no debug msdp events",
|
|
|
|
NO_STR
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_MSDP_STR
|
|
|
|
DEBUG_MSDP_EVENTS_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DONT_DEBUG_MSDP_EVENTS;
|
|
|
|
return CMD_SUCCESS;
|
2016-10-25 19:59:48 +02:00
|
|
|
}
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
ALIAS(no_debug_msdp_events, undebug_msdp_events_cmd, "undebug msdp events",
|
|
|
|
UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_EVENTS_STR)
|
2016-10-25 19:59:48 +02:00
|
|
|
|
|
|
|
DEFUN (debug_msdp_packets,
|
|
|
|
debug_msdp_packets_cmd,
|
|
|
|
"debug msdp packets",
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_MSDP_STR
|
|
|
|
DEBUG_MSDP_PACKETS_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DO_DEBUG_MSDP_PACKETS;
|
|
|
|
return CMD_SUCCESS;
|
2016-10-25 19:59:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_debug_msdp_packets,
|
|
|
|
no_debug_msdp_packets_cmd,
|
|
|
|
"no debug msdp packets",
|
|
|
|
NO_STR
|
|
|
|
DEBUG_STR
|
|
|
|
DEBUG_MSDP_STR
|
|
|
|
DEBUG_MSDP_PACKETS_STR)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
PIM_DONT_DEBUG_MSDP_PACKETS;
|
|
|
|
return CMD_SUCCESS;
|
2016-10-25 19:59:48 +02:00
|
|
|
}
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
ALIAS(no_debug_msdp_packets, undebug_msdp_packets_cmd, "undebug msdp packets",
|
|
|
|
UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_PACKETS_STR)
|
2016-10-25 19:59:48 +02:00
|
|
|
|
2015-05-28 02:40:46 +02:00
|
|
|
DEFUN (show_debugging_pim,
|
|
|
|
show_debugging_pim_cmd,
|
|
|
|
"show debugging pim",
|
2015-02-04 07:01:14 +01:00
|
|
|
SHOW_STR
|
2015-05-28 02:40:46 +02:00
|
|
|
DEBUG_STR
|
|
|
|
PIM_STR)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_debug_config_write(vty);
|
|
|
|
return CMD_SUCCESS;
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
static int interface_pim_use_src_cmd_worker(struct vty *vty, const char *source)
|
2016-11-19 01:19:26 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
int result;
|
|
|
|
struct in_addr source_addr;
|
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
2016-11-19 01:19:26 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
result = inet_pton(AF_INET, source, &source_addr);
|
|
|
|
if (result <= 0) {
|
|
|
|
vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", source,
|
|
|
|
errno, safe_strerror(errno));
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2016-11-19 01:19:26 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
result = pim_update_source_set(ifp, source_addr);
|
|
|
|
switch (result) {
|
|
|
|
case PIM_SUCCESS:
|
|
|
|
break;
|
|
|
|
case PIM_IFACE_NOT_FOUND:
|
|
|
|
vty_out(vty, "Pim not enabled on this interface\n");
|
|
|
|
break;
|
|
|
|
case PIM_UPDATE_SOURCE_DUP:
|
|
|
|
vty_out(vty, "%% Source already set to %s\n", source);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
vty_out(vty, "%% Source set failed\n");
|
|
|
|
}
|
2016-11-19 01:19:26 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
|
2016-11-19 01:19:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (interface_pim_use_source,
|
|
|
|
interface_pim_use_source_cmd,
|
|
|
|
"ip pim use-source A.B.C.D",
|
|
|
|
IP_STR
|
|
|
|
"pim multicast routing\n"
|
|
|
|
"Configure primary IP address\n"
|
|
|
|
"source ip address\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
return interface_pim_use_src_cmd_worker(vty, argv[3]->arg);
|
2016-11-19 01:19:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (interface_no_pim_use_source,
|
|
|
|
interface_no_pim_use_source_cmd,
|
|
|
|
"no ip pim use-source",
|
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"pim multicast routing\n"
|
|
|
|
"Delete source IP address\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
return interface_pim_use_src_cmd_worker(vty, "0.0.0.0");
|
2016-11-19 01:19:26 +01:00
|
|
|
}
|
|
|
|
|
2017-04-11 03:01:53 +02:00
|
|
|
DEFUN (ip_pim_bfd,
|
|
|
|
ip_pim_bfd_cmd,
|
|
|
|
"ip pim bfd",
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
|
|
|
"Enables BFD support\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
|
|
struct pim_interface *pim_ifp = ifp->info;
|
|
|
|
struct bfd_info *bfd_info = NULL;
|
2017-04-11 03:01:53 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!pim_ifp)
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
bfd_info = pim_ifp->bfd_info;
|
2017-04-11 03:01:53 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!bfd_info || !CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG))
|
|
|
|
pim_bfd_if_param_set(ifp, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
|
|
|
|
BFD_DEF_DETECT_MULT, 1);
|
2017-04-11 03:01:53 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-04-11 03:01:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ip_pim_bfd,
|
|
|
|
no_ip_pim_bfd_cmd,
|
|
|
|
"no ip pim bfd",
|
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
|
|
|
"Disables BFD support\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
|
|
struct pim_interface *pim_ifp = ifp->info;
|
2017-04-11 03:01:53 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!pim_ifp)
|
|
|
|
return CMD_SUCCESS;
|
2017-04-11 03:01:53 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (pim_ifp->bfd_info) {
|
|
|
|
pim_bfd_reg_dereg_all_nbr(ifp, ZEBRA_BFD_DEST_DEREGISTER);
|
|
|
|
bfd_info_free(&(pim_ifp->bfd_info));
|
|
|
|
}
|
2017-04-11 03:01:53 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-04-11 03:01:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (ip_pim_bfd_param,
|
|
|
|
ip_pim_bfd_param_cmd,
|
|
|
|
"ip pim bfd (2-255) (50-60000) (50-60000)",
|
|
|
|
IP_STR
|
|
|
|
PIM_STR
|
|
|
|
"Enables BFD support\n"
|
|
|
|
"Detect Multiplier\n"
|
|
|
|
"Required min receive interval\n"
|
|
|
|
"Desired min transmit interval\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
|
|
int idx_number = 3;
|
|
|
|
int idx_number_2 = 4;
|
|
|
|
int idx_number_3 = 5;
|
|
|
|
u_int32_t rx_val;
|
|
|
|
u_int32_t tx_val;
|
|
|
|
u_int8_t dm_val;
|
|
|
|
int ret;
|
2017-04-11 03:01:53 +02:00
|
|
|
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if ((ret = bfd_validate_param(
|
|
|
|
vty, argv[idx_number]->arg, argv[idx_number_2]->arg,
|
|
|
|
argv[idx_number_3]->arg, &dm_val, &rx_val, &tx_val))
|
|
|
|
!= CMD_SUCCESS)
|
|
|
|
return ret;
|
2017-04-11 03:01:53 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_bfd_if_param_set(ifp, rx_val, tx_val, dm_val, 0);
|
2017-04-11 03:01:53 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-04-11 03:01:53 +02:00
|
|
|
}
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd,
|
2017-07-22 14:52:33 +02:00
|
|
|
"no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
|
2017-07-17 14:03:14 +02:00
|
|
|
"Enables BFD support\n"
|
|
|
|
"Detect Multiplier\n"
|
|
|
|
"Required min receive interval\n"
|
|
|
|
"Desired min transmit interval\n")
|
|
|
|
|
2017-05-22 22:32:14 +02:00
|
|
|
static int ip_msdp_peer_cmd_worker(struct vty *vty, struct pim_instance *pim,
|
|
|
|
const char *peer, const char *local)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
|
|
|
enum pim_msdp_err result;
|
|
|
|
struct in_addr peer_addr;
|
|
|
|
struct in_addr local_addr;
|
|
|
|
|
|
|
|
result = inet_pton(AF_INET, peer, &peer_addr);
|
|
|
|
if (result <= 0) {
|
|
|
|
vty_out(vty, "%% Bad peer address %s: errno=%d: %s\n", peer,
|
|
|
|
errno, safe_strerror(errno));
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = inet_pton(AF_INET, local, &local_addr);
|
|
|
|
if (result <= 0) {
|
|
|
|
vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", local,
|
|
|
|
errno, safe_strerror(errno));
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2017-04-11 03:01:53 +02:00
|
|
|
|
2017-05-22 22:32:14 +02:00
|
|
|
result = pim_msdp_peer_add(pim, peer_addr, local_addr, "default",
|
2017-07-17 14:03:14 +02:00
|
|
|
NULL /* mp_p */);
|
|
|
|
switch (result) {
|
|
|
|
case PIM_MSDP_ERR_NONE:
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_OOM:
|
|
|
|
vty_out(vty, "%% Out of memory\n");
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_PEER_EXISTS:
|
|
|
|
vty_out(vty, "%% Peer exists\n");
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_MAX_MESH_GROUPS:
|
|
|
|
vty_out(vty, "%% Only one mesh-group allowed currently\n");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
vty_out(vty, "%% peer add failed\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
|
2016-10-25 19:59:48 +02:00
|
|
|
}
|
|
|
|
|
2016-11-12 14:39:44 +01:00
|
|
|
DEFUN_HIDDEN (ip_msdp_peer,
|
2016-10-25 19:59:48 +02:00
|
|
|
ip_msdp_peer_cmd,
|
|
|
|
"ip msdp peer A.B.C.D source A.B.C.D",
|
|
|
|
IP_STR
|
|
|
|
CFG_MSDP_STR
|
|
|
|
"Configure MSDP peer\n"
|
|
|
|
"peer ip address\n"
|
|
|
|
"Source address for TCP connection\n"
|
|
|
|
"local ip address\n")
|
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
|
|
|
return ip_msdp_peer_cmd_worker(vty, pim, argv[3]->arg, argv[5]->arg);
|
2016-10-25 19:59:48 +02:00
|
|
|
}
|
|
|
|
|
2017-05-22 22:32:14 +02:00
|
|
|
static int ip_no_msdp_peer_cmd_worker(struct vty *vty, struct pim_instance *pim,
|
|
|
|
const char *peer)
|
2016-10-25 19:59:48 +02:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
enum pim_msdp_err result;
|
|
|
|
struct in_addr peer_addr;
|
2016-10-25 19:59:48 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
result = inet_pton(AF_INET, peer, &peer_addr);
|
|
|
|
if (result <= 0) {
|
|
|
|
vty_out(vty, "%% Bad peer address %s: errno=%d: %s\n", peer,
|
|
|
|
errno, safe_strerror(errno));
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2016-10-25 19:59:48 +02:00
|
|
|
|
2017-05-22 22:32:14 +02:00
|
|
|
result = pim_msdp_peer_del(pim, peer_addr);
|
2017-07-17 14:03:14 +02:00
|
|
|
switch (result) {
|
|
|
|
case PIM_MSDP_ERR_NONE:
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_NO_PEER:
|
|
|
|
vty_out(vty, "%% Peer does not exist\n");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
vty_out(vty, "%% peer del failed\n");
|
|
|
|
}
|
2016-10-25 19:59:48 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
|
2016-10-25 19:59:48 +02:00
|
|
|
}
|
|
|
|
|
2016-11-12 14:39:44 +01:00
|
|
|
DEFUN_HIDDEN (no_ip_msdp_peer,
|
2016-10-25 19:59:48 +02:00
|
|
|
no_ip_msdp_peer_cmd,
|
|
|
|
"no ip msdp peer A.B.C.D",
|
2016-11-12 14:39:44 +01:00
|
|
|
NO_STR
|
2016-10-25 19:59:48 +02:00
|
|
|
IP_STR
|
|
|
|
CFG_MSDP_STR
|
|
|
|
"Delete MSDP peer\n"
|
|
|
|
"peer ip address\n")
|
|
|
|
{
|
2017-05-22 22:32:14 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
|
|
|
return ip_no_msdp_peer_cmd_worker(vty, pim, argv[4]->arg);
|
2016-10-25 19:59:48 +02:00
|
|
|
}
|
|
|
|
|
2017-05-23 00:14:43 +02:00
|
|
|
static int ip_msdp_mesh_group_member_cmd_worker(struct vty *vty,
|
|
|
|
struct pim_instance *pim,
|
|
|
|
const char *mg, const char *mbr)
|
2016-11-12 14:39:44 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
enum pim_msdp_err result;
|
|
|
|
struct in_addr mbr_ip;
|
2016-11-12 14:39:44 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
result = inet_pton(AF_INET, mbr, &mbr_ip);
|
|
|
|
if (result <= 0) {
|
|
|
|
vty_out(vty, "%% Bad member address %s: errno=%d: %s\n", mbr,
|
|
|
|
errno, safe_strerror(errno));
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2016-11-12 14:39:44 +01:00
|
|
|
|
2017-05-23 00:14:43 +02:00
|
|
|
result = pim_msdp_mg_mbr_add(pim, mg, mbr_ip);
|
2017-07-17 14:03:14 +02:00
|
|
|
switch (result) {
|
|
|
|
case PIM_MSDP_ERR_NONE:
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_OOM:
|
|
|
|
vty_out(vty, "%% Out of memory\n");
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_MG_MBR_EXISTS:
|
|
|
|
vty_out(vty, "%% mesh-group member exists\n");
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_MAX_MESH_GROUPS:
|
|
|
|
vty_out(vty, "%% Only one mesh-group allowed currently\n");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
vty_out(vty, "%% member add failed\n");
|
|
|
|
}
|
2016-11-12 14:39:44 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
|
2016-11-12 14:39:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (ip_msdp_mesh_group_member,
|
|
|
|
ip_msdp_mesh_group_member_cmd,
|
|
|
|
"ip msdp mesh-group WORD member A.B.C.D",
|
|
|
|
IP_STR
|
|
|
|
CFG_MSDP_STR
|
|
|
|
"Configure MSDP mesh-group\n"
|
|
|
|
"mesh group name\n"
|
|
|
|
"mesh group member\n"
|
|
|
|
"peer ip address\n")
|
|
|
|
{
|
2017-05-23 00:14:43 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
|
|
|
return ip_msdp_mesh_group_member_cmd_worker(vty, pim, argv[3]->arg,
|
2017-07-17 14:03:14 +02:00
|
|
|
argv[5]->arg);
|
2016-11-12 14:39:44 +01:00
|
|
|
}
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
static int ip_no_msdp_mesh_group_member_cmd_worker(struct vty *vty,
|
2017-05-23 00:14:43 +02:00
|
|
|
struct pim_instance *pim,
|
2017-07-17 14:03:14 +02:00
|
|
|
const char *mg,
|
|
|
|
const char *mbr)
|
2016-11-12 14:39:44 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
enum pim_msdp_err result;
|
|
|
|
struct in_addr mbr_ip;
|
2016-11-12 14:39:44 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
result = inet_pton(AF_INET, mbr, &mbr_ip);
|
|
|
|
if (result <= 0) {
|
|
|
|
vty_out(vty, "%% Bad member address %s: errno=%d: %s\n", mbr,
|
|
|
|
errno, safe_strerror(errno));
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2016-11-12 14:39:44 +01:00
|
|
|
|
2017-05-23 00:14:43 +02:00
|
|
|
result = pim_msdp_mg_mbr_del(pim, mg, mbr_ip);
|
2017-07-17 14:03:14 +02:00
|
|
|
switch (result) {
|
|
|
|
case PIM_MSDP_ERR_NONE:
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_NO_MG:
|
|
|
|
vty_out(vty, "%% mesh-group does not exist\n");
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_NO_MG_MBR:
|
|
|
|
vty_out(vty, "%% mesh-group member does not exist\n");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
vty_out(vty, "%% mesh-group member del failed\n");
|
|
|
|
}
|
2016-11-12 14:39:44 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
|
2016-11-12 14:39:44 +01:00
|
|
|
}
|
|
|
|
DEFUN (no_ip_msdp_mesh_group_member,
|
|
|
|
no_ip_msdp_mesh_group_member_cmd,
|
|
|
|
"no ip msdp mesh-group WORD member A.B.C.D",
|
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
CFG_MSDP_STR
|
|
|
|
"Delete MSDP mesh-group member\n"
|
|
|
|
"mesh group name\n"
|
|
|
|
"mesh group member\n"
|
|
|
|
"peer ip address\n")
|
|
|
|
{
|
2017-05-23 00:14:43 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
|
|
|
return ip_no_msdp_mesh_group_member_cmd_worker(vty, pim, argv[4]->arg,
|
2017-07-17 14:03:14 +02:00
|
|
|
argv[6]->arg);
|
2016-11-12 14:39:44 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 00:14:43 +02:00
|
|
|
static int ip_msdp_mesh_group_source_cmd_worker(struct vty *vty,
|
|
|
|
struct pim_instance *pim,
|
|
|
|
const char *mg, const char *src)
|
2016-11-12 14:39:44 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
enum pim_msdp_err result;
|
|
|
|
struct in_addr src_ip;
|
2016-11-12 14:39:44 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
result = inet_pton(AF_INET, src, &src_ip);
|
|
|
|
if (result <= 0) {
|
|
|
|
vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", src,
|
|
|
|
errno, safe_strerror(errno));
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2016-11-12 14:39:44 +01:00
|
|
|
|
2017-05-23 00:14:43 +02:00
|
|
|
result = pim_msdp_mg_src_add(pim, mg, src_ip);
|
2017-07-17 14:03:14 +02:00
|
|
|
switch (result) {
|
|
|
|
case PIM_MSDP_ERR_NONE:
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_OOM:
|
|
|
|
vty_out(vty, "%% Out of memory\n");
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_MAX_MESH_GROUPS:
|
|
|
|
vty_out(vty, "%% Only one mesh-group allowed currently\n");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
vty_out(vty, "%% source add failed\n");
|
|
|
|
}
|
2016-11-12 14:39:44 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
|
2016-11-12 14:39:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DEFUN (ip_msdp_mesh_group_source,
|
|
|
|
ip_msdp_mesh_group_source_cmd,
|
|
|
|
"ip msdp mesh-group WORD source A.B.C.D",
|
|
|
|
IP_STR
|
|
|
|
CFG_MSDP_STR
|
|
|
|
"Configure MSDP mesh-group\n"
|
|
|
|
"mesh group name\n"
|
|
|
|
"mesh group local address\n"
|
|
|
|
"source ip address for the TCP connection\n")
|
|
|
|
{
|
2017-05-23 00:14:43 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
|
|
|
return ip_msdp_mesh_group_source_cmd_worker(vty, pim, argv[3]->arg,
|
2017-07-17 14:03:14 +02:00
|
|
|
argv[5]->arg);
|
2016-11-12 14:39:44 +01:00
|
|
|
}
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
static int ip_no_msdp_mesh_group_source_cmd_worker(struct vty *vty,
|
2017-05-23 00:14:43 +02:00
|
|
|
struct pim_instance *pim,
|
2017-07-17 14:03:14 +02:00
|
|
|
const char *mg)
|
2016-11-12 14:39:44 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
enum pim_msdp_err result;
|
2016-11-12 14:39:44 +01:00
|
|
|
|
2017-05-23 00:14:43 +02:00
|
|
|
result = pim_msdp_mg_src_del(pim, mg);
|
2017-07-17 14:03:14 +02:00
|
|
|
switch (result) {
|
|
|
|
case PIM_MSDP_ERR_NONE:
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_NO_MG:
|
|
|
|
vty_out(vty, "%% mesh-group does not exist\n");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
vty_out(vty, "%% mesh-group source del failed\n");
|
|
|
|
}
|
2016-11-12 14:39:44 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
|
2016-11-12 14:39:44 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 00:14:43 +02:00
|
|
|
static int ip_no_msdp_mesh_group_cmd_worker(struct vty *vty,
|
|
|
|
struct pim_instance *pim,
|
|
|
|
const char *mg)
|
2016-11-12 14:39:44 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
enum pim_msdp_err result;
|
2016-11-12 14:39:44 +01:00
|
|
|
|
2017-05-23 00:14:43 +02:00
|
|
|
result = pim_msdp_mg_del(pim, mg);
|
2017-07-17 14:03:14 +02:00
|
|
|
switch (result) {
|
|
|
|
case PIM_MSDP_ERR_NONE:
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_NO_MG:
|
|
|
|
vty_out(vty, "%% mesh-group does not exist\n");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
vty_out(vty, "%% mesh-group source del failed\n");
|
|
|
|
}
|
2016-11-12 14:39:44 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
|
2016-11-12 14:39:44 +01:00
|
|
|
}
|
|
|
|
|
2016-11-29 21:48:54 +01:00
|
|
|
DEFUN (no_ip_msdp_mesh_group_source,
|
|
|
|
no_ip_msdp_mesh_group_source_cmd,
|
|
|
|
"no ip msdp mesh-group WORD source [A.B.C.D]",
|
2016-11-12 14:39:44 +01:00
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
CFG_MSDP_STR
|
2016-11-29 21:48:54 +01:00
|
|
|
"Delete MSDP mesh-group source\n"
|
|
|
|
"mesh group name\n"
|
2017-01-25 15:13:46 +01:00
|
|
|
"mesh group source\n"
|
2016-11-29 21:48:54 +01:00
|
|
|
"mesh group local address\n")
|
2016-11-12 14:39:44 +01:00
|
|
|
{
|
2017-05-23 00:14:43 +02:00
|
|
|
PIM_DECLVAR_CONTEXT(vrf, pim);
|
2017-07-17 14:03:14 +02:00
|
|
|
if (argc == 7)
|
2017-05-23 00:14:43 +02:00
|
|
|
return ip_no_msdp_mesh_group_cmd_worker(vty, pim, argv[6]->arg);
|
2017-07-17 14:03:14 +02:00
|
|
|
else
|
2017-05-23 00:14:43 +02:00
|
|
|
return ip_no_msdp_mesh_group_source_cmd_worker(vty, pim,
|
2017-07-17 14:03:14 +02:00
|
|
|
argv[4]->arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void print_empty_json_obj(struct vty *vty)
|
|
|
|
{
|
|
|
|
json_object *json;
|
|
|
|
json = json_object_new_object();
|
|
|
|
vty_out(vty, "%s\n",
|
|
|
|
json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
|
|
|
|
json_object_free(json);
|
|
|
|
}
|
|
|
|
|
2017-05-23 00:14:43 +02:00
|
|
|
static void ip_msdp_show_mesh_group(struct vty *vty, struct pim_instance *pim,
|
|
|
|
u_char uj)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
|
|
|
struct listnode *mbrnode;
|
|
|
|
struct pim_msdp_mg_mbr *mbr;
|
2017-05-23 00:14:43 +02:00
|
|
|
struct pim_msdp_mg *mg = pim->msdp.mg;
|
2017-07-17 14:03:14 +02:00
|
|
|
char mbr_str[INET_ADDRSTRLEN];
|
|
|
|
char src_str[INET_ADDRSTRLEN];
|
|
|
|
char state_str[PIM_MSDP_STATE_STRLEN];
|
|
|
|
enum pim_msdp_peer_state state;
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_mg_row = NULL;
|
|
|
|
json_object *json_members = NULL;
|
|
|
|
json_object *json_row = NULL;
|
|
|
|
|
|
|
|
if (!mg) {
|
|
|
|
if (uj)
|
|
|
|
print_empty_json_obj(vty);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
pim_inet4_dump("<source?>", mg->src_ip, src_str, sizeof(src_str));
|
|
|
|
if (uj) {
|
|
|
|
json = json_object_new_object();
|
|
|
|
/* currently there is only one mesh group but we should still
|
|
|
|
* make
|
|
|
|
* it a dict with mg-name as key */
|
|
|
|
json_mg_row = json_object_new_object();
|
|
|
|
json_object_string_add(json_mg_row, "name",
|
|
|
|
mg->mesh_group_name);
|
|
|
|
json_object_string_add(json_mg_row, "source", src_str);
|
|
|
|
} else {
|
|
|
|
vty_out(vty, "Mesh group : %s\n", mg->mesh_group_name);
|
|
|
|
vty_out(vty, " Source : %s\n", src_str);
|
|
|
|
vty_out(vty, " Member State\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
|
|
|
|
pim_inet4_dump("<mbr?>", mbr->mbr_ip, mbr_str, sizeof(mbr_str));
|
|
|
|
if (mbr->mp) {
|
|
|
|
state = mbr->mp->state;
|
|
|
|
} else {
|
|
|
|
state = PIM_MSDP_DISABLED;
|
|
|
|
}
|
|
|
|
pim_msdp_state_dump(state, state_str, sizeof(state_str));
|
|
|
|
if (uj) {
|
|
|
|
json_row = json_object_new_object();
|
|
|
|
json_object_string_add(json_row, "member", mbr_str);
|
|
|
|
json_object_string_add(json_row, "state", state_str);
|
|
|
|
if (!json_members) {
|
|
|
|
json_members = json_object_new_object();
|
|
|
|
json_object_object_add(json_mg_row, "members",
|
|
|
|
json_members);
|
|
|
|
}
|
|
|
|
json_object_object_add(json_members, mbr_str, json_row);
|
|
|
|
} else {
|
|
|
|
vty_out(vty, " %-15s %11s\n", mbr_str, state_str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json_object_object_add(json, mg->mesh_group_name, json_mg_row);
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
}
|
2016-11-12 14:39:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_msdp_mesh_group,
|
|
|
|
show_ip_msdp_mesh_group_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip msdp [vrf NAME] mesh-group [json]",
|
2016-11-12 14:39:44 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
MSDP_STR
|
2017-05-23 13:34:19 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2016-11-12 14:39:44 +01:00
|
|
|
"MSDP mesh-group information\n"
|
|
|
|
"JavaScript Object Notation\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
u_char uj = use_json(argc, argv);
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
2017-05-23 00:14:43 +02:00
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
ip_msdp_show_mesh_group(vty, vrf->info, uj);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-05-23 00:14:43 +02:00
|
|
|
static void ip_msdp_show_peers(struct vty *vty, struct pim_instance *pim,
|
|
|
|
u_char uj)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
|
|
|
struct listnode *mpnode;
|
|
|
|
struct pim_msdp_peer *mp;
|
|
|
|
char peer_str[INET_ADDRSTRLEN];
|
|
|
|
char local_str[INET_ADDRSTRLEN];
|
|
|
|
char state_str[PIM_MSDP_STATE_STRLEN];
|
|
|
|
char timebuf[PIM_MSDP_UPTIME_STRLEN];
|
|
|
|
int64_t now;
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_row = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json = json_object_new_object();
|
|
|
|
} else {
|
|
|
|
vty_out(vty,
|
|
|
|
"Peer Local State Uptime SaCnt\n");
|
|
|
|
}
|
|
|
|
|
2017-05-23 00:14:43 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
if (mp->state == PIM_MSDP_ESTABLISHED) {
|
|
|
|
now = pim_time_monotonic_sec();
|
|
|
|
pim_time_uptime(timebuf, sizeof(timebuf),
|
|
|
|
now - mp->uptime);
|
|
|
|
} else {
|
|
|
|
strcpy(timebuf, "-");
|
|
|
|
}
|
|
|
|
pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
|
|
|
|
pim_inet4_dump("<local?>", mp->local, local_str,
|
|
|
|
sizeof(local_str));
|
|
|
|
pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
|
|
|
|
if (uj) {
|
|
|
|
json_row = json_object_new_object();
|
|
|
|
json_object_string_add(json_row, "peer", peer_str);
|
|
|
|
json_object_string_add(json_row, "local", local_str);
|
|
|
|
json_object_string_add(json_row, "state", state_str);
|
|
|
|
json_object_string_add(json_row, "upTime", timebuf);
|
|
|
|
json_object_int_add(json_row, "saCount", mp->sa_cnt);
|
|
|
|
json_object_object_add(json, peer_str, json_row);
|
|
|
|
} else {
|
|
|
|
vty_out(vty, "%-15s %15s %11s %8s %6d\n", peer_str,
|
|
|
|
local_str, state_str, timebuf, mp->sa_cnt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uj) {
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-23 00:14:43 +02:00
|
|
|
static void ip_msdp_show_peers_detail(struct vty *vty, struct pim_instance *pim,
|
|
|
|
const char *peer, u_char uj)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
|
|
|
struct listnode *mpnode;
|
|
|
|
struct pim_msdp_peer *mp;
|
|
|
|
char peer_str[INET_ADDRSTRLEN];
|
|
|
|
char local_str[INET_ADDRSTRLEN];
|
|
|
|
char state_str[PIM_MSDP_STATE_STRLEN];
|
|
|
|
char timebuf[PIM_MSDP_UPTIME_STRLEN];
|
|
|
|
char katimer[PIM_MSDP_TIMER_STRLEN];
|
|
|
|
char crtimer[PIM_MSDP_TIMER_STRLEN];
|
|
|
|
char holdtimer[PIM_MSDP_TIMER_STRLEN];
|
|
|
|
int64_t now;
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_row = NULL;
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json = json_object_new_object();
|
|
|
|
}
|
|
|
|
|
2017-05-23 00:14:43 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
|
|
|
|
if (strcmp(peer, "detail") && strcmp(peer, peer_str))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (mp->state == PIM_MSDP_ESTABLISHED) {
|
|
|
|
now = pim_time_monotonic_sec();
|
|
|
|
pim_time_uptime(timebuf, sizeof(timebuf),
|
|
|
|
now - mp->uptime);
|
|
|
|
} else {
|
|
|
|
strcpy(timebuf, "-");
|
|
|
|
}
|
|
|
|
pim_inet4_dump("<local?>", mp->local, local_str,
|
|
|
|
sizeof(local_str));
|
|
|
|
pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
|
|
|
|
pim_time_timer_to_hhmmss(katimer, sizeof(katimer),
|
|
|
|
mp->ka_timer);
|
|
|
|
pim_time_timer_to_hhmmss(crtimer, sizeof(crtimer),
|
|
|
|
mp->cr_timer);
|
|
|
|
pim_time_timer_to_hhmmss(holdtimer, sizeof(holdtimer),
|
|
|
|
mp->hold_timer);
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json_row = json_object_new_object();
|
|
|
|
json_object_string_add(json_row, "peer", peer_str);
|
|
|
|
json_object_string_add(json_row, "local", local_str);
|
|
|
|
json_object_string_add(json_row, "meshGroupName",
|
|
|
|
mp->mesh_group_name);
|
|
|
|
json_object_string_add(json_row, "state", state_str);
|
|
|
|
json_object_string_add(json_row, "upTime", timebuf);
|
|
|
|
json_object_string_add(json_row, "keepAliveTimer",
|
|
|
|
katimer);
|
|
|
|
json_object_string_add(json_row, "connRetryTimer",
|
|
|
|
crtimer);
|
|
|
|
json_object_string_add(json_row, "holdTimer",
|
|
|
|
holdtimer);
|
|
|
|
json_object_string_add(json_row, "lastReset",
|
|
|
|
mp->last_reset);
|
|
|
|
json_object_int_add(json_row, "connAttempts",
|
|
|
|
mp->conn_attempts);
|
|
|
|
json_object_int_add(json_row, "establishedChanges",
|
|
|
|
mp->est_flaps);
|
|
|
|
json_object_int_add(json_row, "saCount", mp->sa_cnt);
|
|
|
|
json_object_int_add(json_row, "kaSent", mp->ka_tx_cnt);
|
|
|
|
json_object_int_add(json_row, "kaRcvd", mp->ka_rx_cnt);
|
|
|
|
json_object_int_add(json_row, "saSent", mp->sa_tx_cnt);
|
|
|
|
json_object_int_add(json_row, "saRcvd", mp->sa_rx_cnt);
|
|
|
|
json_object_object_add(json, peer_str, json_row);
|
|
|
|
} else {
|
|
|
|
vty_out(vty, "Peer : %s\n", peer_str);
|
|
|
|
vty_out(vty, " Local : %s\n", local_str);
|
|
|
|
vty_out(vty, " Mesh Group : %s\n",
|
|
|
|
mp->mesh_group_name);
|
|
|
|
vty_out(vty, " State : %s\n", state_str);
|
|
|
|
vty_out(vty, " Uptime : %s\n", timebuf);
|
|
|
|
|
|
|
|
vty_out(vty, " Keepalive Timer : %s\n", katimer);
|
|
|
|
vty_out(vty, " Conn Retry Timer : %s\n", crtimer);
|
|
|
|
vty_out(vty, " Hold Timer : %s\n", holdtimer);
|
|
|
|
vty_out(vty, " Last Reset : %s\n",
|
|
|
|
mp->last_reset);
|
|
|
|
vty_out(vty, " Conn Attempts : %d\n",
|
|
|
|
mp->conn_attempts);
|
|
|
|
vty_out(vty, " Established Changes : %d\n",
|
|
|
|
mp->est_flaps);
|
|
|
|
vty_out(vty, " SA Count : %d\n",
|
|
|
|
mp->sa_cnt);
|
|
|
|
vty_out(vty, " Statistics :\n");
|
|
|
|
vty_out(vty,
|
|
|
|
" Sent Rcvd\n");
|
|
|
|
vty_out(vty, " Keepalives : %10d %10d\n",
|
|
|
|
mp->ka_tx_cnt, mp->ka_rx_cnt);
|
|
|
|
vty_out(vty, " SAs : %10d %10d\n",
|
|
|
|
mp->sa_tx_cnt, mp->sa_rx_cnt);
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uj) {
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
}
|
2016-11-12 14:39:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_msdp_peer_detail,
|
|
|
|
show_ip_msdp_peer_detail_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
|
2016-10-25 19:59:48 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
MSDP_STR
|
2017-05-23 13:34:19 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2016-10-25 19:59:48 +02:00
|
|
|
"MSDP peer information\n"
|
2016-11-12 14:39:44 +01:00
|
|
|
"Detailed output\n"
|
|
|
|
"peer ip address\n"
|
2016-10-25 19:59:48 +02:00
|
|
|
"JavaScript Object Notation\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
u_char uj = use_json(argc, argv);
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
2017-05-23 00:14:43 +02:00
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
2017-07-17 14:03:14 +02:00
|
|
|
if (uj)
|
|
|
|
argc--;
|
|
|
|
|
2017-06-08 14:37:02 +02:00
|
|
|
if (argv_find(argv, argc, "detail", &idx)
|
|
|
|
|| argv_find(argv, argc, "A.B.C.D", &idx))
|
|
|
|
ip_msdp_show_peers_detail(vty, vrf->info, argv[idx]->arg, uj);
|
2017-07-17 14:03:14 +02:00
|
|
|
else
|
2017-05-23 00:14:43 +02:00
|
|
|
ip_msdp_show_peers(vty, vrf->info, uj);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-05-23 00:14:43 +02:00
|
|
|
static void ip_msdp_show_sa(struct vty *vty, struct pim_instance *pim,
|
|
|
|
u_char uj)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
|
|
|
struct listnode *sanode;
|
|
|
|
struct pim_msdp_sa *sa;
|
|
|
|
char src_str[INET_ADDRSTRLEN];
|
|
|
|
char grp_str[INET_ADDRSTRLEN];
|
|
|
|
char rp_str[INET_ADDRSTRLEN];
|
|
|
|
char timebuf[PIM_MSDP_UPTIME_STRLEN];
|
|
|
|
char spt_str[8];
|
|
|
|
char local_str[8];
|
|
|
|
int64_t now;
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_group = NULL;
|
|
|
|
json_object *json_row = NULL;
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json = json_object_new_object();
|
|
|
|
} else {
|
|
|
|
vty_out(vty,
|
|
|
|
"Source Group RP Local SPT Uptime\n");
|
|
|
|
}
|
|
|
|
|
2017-05-23 00:14:43 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
now = pim_time_monotonic_sec();
|
|
|
|
pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
|
|
|
|
pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
|
|
|
|
pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
|
|
|
|
if (sa->flags & PIM_MSDP_SAF_PEER) {
|
|
|
|
pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
|
|
|
|
if (sa->up) {
|
|
|
|
strcpy(spt_str, "yes");
|
|
|
|
} else {
|
|
|
|
strcpy(spt_str, "no");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
strcpy(rp_str, "-");
|
|
|
|
strcpy(spt_str, "-");
|
|
|
|
}
|
|
|
|
if (sa->flags & PIM_MSDP_SAF_LOCAL) {
|
|
|
|
strcpy(local_str, "yes");
|
|
|
|
} else {
|
|
|
|
strcpy(local_str, "no");
|
|
|
|
}
|
|
|
|
if (uj) {
|
|
|
|
json_object_object_get_ex(json, grp_str, &json_group);
|
|
|
|
|
|
|
|
if (!json_group) {
|
|
|
|
json_group = json_object_new_object();
|
|
|
|
json_object_object_add(json, grp_str,
|
|
|
|
json_group);
|
|
|
|
}
|
|
|
|
|
|
|
|
json_row = json_object_new_object();
|
|
|
|
json_object_string_add(json_row, "source", src_str);
|
|
|
|
json_object_string_add(json_row, "group", grp_str);
|
|
|
|
json_object_string_add(json_row, "rp", rp_str);
|
|
|
|
json_object_string_add(json_row, "local", local_str);
|
|
|
|
json_object_string_add(json_row, "sptSetup", spt_str);
|
|
|
|
json_object_string_add(json_row, "upTime", timebuf);
|
|
|
|
json_object_object_add(json_group, src_str, json_row);
|
|
|
|
} else {
|
|
|
|
vty_out(vty, "%-15s %15s %15s %5c %3c %8s\n",
|
|
|
|
src_str, grp_str, rp_str, local_str[0],
|
|
|
|
spt_str[0], timebuf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uj) {
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa,
|
|
|
|
const char *src_str,
|
|
|
|
const char *grp_str, struct vty *vty,
|
|
|
|
u_char uj, json_object *json)
|
|
|
|
{
|
|
|
|
char rp_str[INET_ADDRSTRLEN];
|
|
|
|
char peer_str[INET_ADDRSTRLEN];
|
|
|
|
char timebuf[PIM_MSDP_UPTIME_STRLEN];
|
|
|
|
char spt_str[8];
|
|
|
|
char local_str[8];
|
|
|
|
char statetimer[PIM_MSDP_TIMER_STRLEN];
|
|
|
|
int64_t now;
|
|
|
|
json_object *json_group = NULL;
|
|
|
|
json_object *json_row = NULL;
|
|
|
|
|
|
|
|
now = pim_time_monotonic_sec();
|
|
|
|
pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
|
|
|
|
if (sa->flags & PIM_MSDP_SAF_PEER) {
|
|
|
|
pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
|
|
|
|
pim_inet4_dump("<peer?>", sa->peer, peer_str, sizeof(peer_str));
|
|
|
|
if (sa->up) {
|
|
|
|
strcpy(spt_str, "yes");
|
|
|
|
} else {
|
|
|
|
strcpy(spt_str, "no");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
strcpy(rp_str, "-");
|
|
|
|
strcpy(peer_str, "-");
|
|
|
|
strcpy(spt_str, "-");
|
|
|
|
}
|
|
|
|
if (sa->flags & PIM_MSDP_SAF_LOCAL) {
|
|
|
|
strcpy(local_str, "yes");
|
|
|
|
} else {
|
|
|
|
strcpy(local_str, "no");
|
|
|
|
}
|
|
|
|
pim_time_timer_to_hhmmss(statetimer, sizeof(statetimer),
|
|
|
|
sa->sa_state_timer);
|
|
|
|
if (uj) {
|
|
|
|
json_object_object_get_ex(json, grp_str, &json_group);
|
|
|
|
|
|
|
|
if (!json_group) {
|
|
|
|
json_group = json_object_new_object();
|
|
|
|
json_object_object_add(json, grp_str, json_group);
|
|
|
|
}
|
|
|
|
|
|
|
|
json_row = json_object_new_object();
|
|
|
|
json_object_string_add(json_row, "source", src_str);
|
|
|
|
json_object_string_add(json_row, "group", grp_str);
|
|
|
|
json_object_string_add(json_row, "rp", rp_str);
|
|
|
|
json_object_string_add(json_row, "local", local_str);
|
|
|
|
json_object_string_add(json_row, "sptSetup", spt_str);
|
|
|
|
json_object_string_add(json_row, "upTime", timebuf);
|
|
|
|
json_object_string_add(json_row, "stateTimer", statetimer);
|
|
|
|
json_object_object_add(json_group, src_str, json_row);
|
|
|
|
} else {
|
|
|
|
vty_out(vty, "SA : %s\n", sa->sg_str);
|
|
|
|
vty_out(vty, " RP : %s\n", rp_str);
|
|
|
|
vty_out(vty, " Peer : %s\n", peer_str);
|
|
|
|
vty_out(vty, " Local : %s\n", local_str);
|
|
|
|
vty_out(vty, " SPT Setup : %s\n", spt_str);
|
|
|
|
vty_out(vty, " Uptime : %s\n", timebuf);
|
|
|
|
vty_out(vty, " State Timer : %s\n", statetimer);
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-23 00:14:43 +02:00
|
|
|
static void ip_msdp_show_sa_detail(struct vty *vty, struct pim_instance *pim,
|
|
|
|
u_char uj)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
|
|
|
struct listnode *sanode;
|
|
|
|
struct pim_msdp_sa *sa;
|
|
|
|
char src_str[INET_ADDRSTRLEN];
|
|
|
|
char grp_str[INET_ADDRSTRLEN];
|
|
|
|
json_object *json = NULL;
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json = json_object_new_object();
|
|
|
|
}
|
|
|
|
|
2017-05-23 00:14:43 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
|
|
|
|
pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
|
|
|
|
ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj,
|
|
|
|
json);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uj) {
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
}
|
2016-11-12 14:39:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_msdp_sa_detail,
|
|
|
|
show_ip_msdp_sa_detail_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip msdp [vrf NAME] sa detail [json]",
|
2016-10-31 20:29:17 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
MSDP_STR
|
2017-05-23 13:34:19 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2016-10-31 20:29:17 +01:00
|
|
|
"MSDP active-source information\n"
|
2016-11-12 14:39:44 +01:00
|
|
|
"Detailed output\n"
|
2016-10-31 20:29:17 +01:00
|
|
|
"JavaScript Object Notation\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
u_char uj = use_json(argc, argv);
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
2017-05-23 00:14:43 +02:00
|
|
|
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
ip_msdp_show_sa_detail(vty, vrf->info, uj);
|
2016-11-12 14:39:44 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2016-11-12 14:39:44 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 00:14:43 +02:00
|
|
|
static void ip_msdp_show_sa_addr(struct vty *vty, struct pim_instance *pim,
|
|
|
|
const char *addr, u_char uj)
|
2016-11-12 14:39:44 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *sanode;
|
|
|
|
struct pim_msdp_sa *sa;
|
|
|
|
char src_str[INET_ADDRSTRLEN];
|
|
|
|
char grp_str[INET_ADDRSTRLEN];
|
|
|
|
json_object *json = NULL;
|
2016-11-12 14:39:44 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (uj) {
|
|
|
|
json = json_object_new_object();
|
|
|
|
}
|
2016-11-12 14:39:44 +01:00
|
|
|
|
2017-05-23 00:14:43 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
|
|
|
|
pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
|
|
|
|
if (!strcmp(addr, src_str) || !strcmp(addr, grp_str)) {
|
|
|
|
ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
|
|
|
|
uj, json);
|
|
|
|
}
|
|
|
|
}
|
2016-11-12 14:39:44 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (uj) {
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
}
|
2016-11-12 14:39:44 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 00:14:43 +02:00
|
|
|
static void ip_msdp_show_sa_sg(struct vty *vty, struct pim_instance *pim,
|
|
|
|
const char *src, const char *grp, u_char uj)
|
2016-11-12 14:39:44 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct listnode *sanode;
|
|
|
|
struct pim_msdp_sa *sa;
|
|
|
|
char src_str[INET_ADDRSTRLEN];
|
|
|
|
char grp_str[INET_ADDRSTRLEN];
|
|
|
|
json_object *json = NULL;
|
2016-11-12 14:39:44 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (uj) {
|
|
|
|
json = json_object_new_object();
|
|
|
|
}
|
2016-11-12 14:39:44 +01:00
|
|
|
|
2017-05-23 00:14:43 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
|
|
|
|
pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
|
|
|
|
if (!strcmp(src, src_str) && !strcmp(grp, grp_str)) {
|
|
|
|
ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
|
|
|
|
uj, json);
|
|
|
|
}
|
|
|
|
}
|
2016-11-12 14:39:44 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (uj) {
|
2017-07-22 14:52:33 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
}
|
2016-11-12 14:39:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_msdp_sa_sg,
|
|
|
|
show_ip_msdp_sa_sg_cmd,
|
2017-06-20 19:47:59 +02:00
|
|
|
"show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
|
2016-11-12 14:39:44 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
MSDP_STR
|
2017-05-23 13:34:19 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2016-11-12 14:39:44 +01:00
|
|
|
"MSDP active-source information\n"
|
|
|
|
"source or group ip\n"
|
2017-01-25 15:13:46 +01:00
|
|
|
"group ip\n"
|
2016-11-12 14:39:44 +01:00
|
|
|
"JavaScript Object Notation\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
u_char uj = use_json(argc, argv);
|
2017-05-23 00:14:43 +02:00
|
|
|
struct vrf *vrf;
|
2017-05-23 14:57:11 +02:00
|
|
|
int idx = 2;
|
2017-05-23 00:14:43 +02:00
|
|
|
|
|
|
|
vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
|
|
|
|
|
|
|
if (!vrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
|
|
|
|
: NULL;
|
|
|
|
char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
|
|
|
|
? argv[idx]->arg
|
|
|
|
: NULL;
|
2017-04-17 21:21:06 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (src_ip && grp_ip)
|
2017-05-23 00:14:43 +02:00
|
|
|
ip_msdp_show_sa_sg(vty, vrf->info, src_ip, grp_ip, uj);
|
2017-07-17 14:03:14 +02:00
|
|
|
else if (src_ip)
|
2017-05-23 00:14:43 +02:00
|
|
|
ip_msdp_show_sa_addr(vty, vrf->info, src_ip, uj);
|
2017-07-17 14:03:14 +02:00
|
|
|
else
|
2017-05-23 00:14:43 +02:00
|
|
|
ip_msdp_show_sa(vty, vrf->info, uj);
|
2016-10-31 20:29:17 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2016-10-31 20:29:17 +01:00
|
|
|
}
|
|
|
|
|
2017-05-23 14:57:11 +02:00
|
|
|
void pim_cmd_init(void)
|
2015-02-04 07:01:14 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
install_node(&pim_global_node, pim_global_config_write); /* PIM_NODE */
|
|
|
|
install_node(&interface_node,
|
|
|
|
pim_interface_config_write); /* INTERFACE_NODE */
|
|
|
|
if_cmd_init();
|
|
|
|
|
|
|
|
install_node(&debug_node, pim_debug_config_write);
|
|
|
|
|
|
|
|
install_element(CONFIG_NODE, &ip_multicast_routing_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_ip_multicast_routing_cmd);
|
|
|
|
install_element(CONFIG_NODE, &ip_pim_rp_cmd);
|
2017-05-22 21:13:13 +02:00
|
|
|
install_element(VRF_NODE, &ip_pim_rp_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &no_ip_pim_rp_cmd);
|
2017-05-22 21:13:13 +02:00
|
|
|
install_element(VRF_NODE, &no_ip_pim_rp_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &ip_pim_rp_prefix_list_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &ip_pim_rp_prefix_list_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &no_ip_pim_rp_prefix_list_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &no_ip_pim_rp_prefix_list_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &ip_pim_ssm_prefix_list_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &ip_pim_ssm_prefix_list_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &ip_pim_register_suppress_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &ip_pim_register_suppress_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &no_ip_pim_register_suppress_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &no_ip_pim_register_suppress_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE,
|
|
|
|
&no_ip_pim_spt_switchover_infinity_plist_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_plist_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &ip_pim_joinprune_time_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &ip_pim_joinprune_time_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &no_ip_pim_joinprune_time_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &no_ip_pim_joinprune_time_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &ip_pim_keep_alive_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &ip_pim_keep_alive_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &no_ip_pim_keep_alive_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &no_ip_pim_keep_alive_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &ip_pim_packets_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &ip_pim_packets_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &no_ip_pim_packets_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &no_ip_pim_packets_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &ip_pim_v6_secondary_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &ip_pim_v6_secondary_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &no_ip_pim_v6_secondary_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &no_ip_pim_v6_secondary_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &ip_ssmpingd_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &ip_ssmpingd_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &no_ip_ssmpingd_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &no_ip_ssmpingd_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &ip_msdp_peer_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &ip_msdp_peer_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &no_ip_msdp_peer_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &no_ip_msdp_peer_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &ip_pim_ecmp_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &ip_pim_ecmp_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &no_ip_pim_ecmp_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &no_ip_pim_ecmp_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &ip_pim_ecmp_rebalance_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &ip_pim_ecmp_rebalance_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &no_ip_pim_ecmp_rebalance_cmd);
|
2017-05-22 22:32:14 +02:00
|
|
|
install_element(VRF_NODE, &no_ip_pim_ecmp_rebalance_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
install_element(INTERFACE_NODE, &interface_ip_igmp_cmd);
|
|
|
|
install_element(INTERFACE_NODE, &interface_no_ip_igmp_cmd);
|
|
|
|
install_element(INTERFACE_NODE, &interface_ip_igmp_join_cmd);
|
|
|
|
install_element(INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
|
|
|
|
install_element(INTERFACE_NODE, &interface_ip_igmp_version_cmd);
|
|
|
|
install_element(INTERFACE_NODE, &interface_no_ip_igmp_version_cmd);
|
|
|
|
install_element(INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
|
|
|
|
install_element(INTERFACE_NODE,
|
|
|
|
&interface_no_ip_igmp_query_interval_cmd);
|
|
|
|
install_element(INTERFACE_NODE,
|
|
|
|
&interface_ip_igmp_query_max_response_time_cmd);
|
|
|
|
install_element(INTERFACE_NODE,
|
|
|
|
&interface_no_ip_igmp_query_max_response_time_cmd);
|
|
|
|
install_element(INTERFACE_NODE,
|
|
|
|
&interface_ip_igmp_query_max_response_time_dsec_cmd);
|
|
|
|
install_element(INTERFACE_NODE,
|
|
|
|
&interface_no_ip_igmp_query_max_response_time_dsec_cmd);
|
|
|
|
install_element(INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
|
|
|
|
install_element(INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
|
|
|
|
install_element(INTERFACE_NODE, &interface_ip_pim_sm_cmd);
|
|
|
|
install_element(INTERFACE_NODE, &interface_no_ip_pim_sm_cmd);
|
|
|
|
install_element(INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
|
|
|
|
install_element(INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
|
|
|
|
install_element(INTERFACE_NODE, &interface_ip_pim_hello_cmd);
|
|
|
|
install_element(INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
|
|
|
|
|
|
|
|
// Static mroutes NEB
|
|
|
|
install_element(INTERFACE_NODE, &interface_ip_mroute_cmd);
|
|
|
|
install_element(INTERFACE_NODE, &interface_ip_mroute_source_cmd);
|
|
|
|
install_element(INTERFACE_NODE, &interface_no_ip_mroute_cmd);
|
|
|
|
install_element(INTERFACE_NODE, &interface_no_ip_mroute_source_cmd);
|
|
|
|
|
|
|
|
install_element(VIEW_NODE, &show_ip_igmp_interface_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_igmp_join_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_igmp_groups_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_igmp_sources_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_pim_assert_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_pim_assert_internal_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_pim_assert_metric_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_pim_interface_traffic_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_pim_interface_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_pim_join_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_pim_local_membership_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_pim_neighbor_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_pim_rpf_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_pim_secondary_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_pim_state_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_pim_upstream_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_pim_rp_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_multicast_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_mroute_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_mroute_count_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_rib_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_ssmpingd_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_debugging_pim_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_pim_nexthop_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_pim_nexthop_lookup_cmd);
|
|
|
|
|
|
|
|
install_element(ENABLE_NODE, &clear_ip_interfaces_cmd);
|
|
|
|
install_element(ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
|
|
|
|
install_element(ENABLE_NODE, &clear_ip_mroute_cmd);
|
|
|
|
install_element(ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
|
|
|
|
install_element(ENABLE_NODE, &clear_ip_pim_interface_traffic_cmd);
|
|
|
|
install_element(ENABLE_NODE, &clear_ip_pim_oil_cmd);
|
|
|
|
|
|
|
|
install_element(ENABLE_NODE, &debug_igmp_cmd);
|
|
|
|
install_element(ENABLE_NODE, &no_debug_igmp_cmd);
|
|
|
|
install_element(ENABLE_NODE, &debug_igmp_events_cmd);
|
|
|
|
install_element(ENABLE_NODE, &no_debug_igmp_events_cmd);
|
|
|
|
install_element(ENABLE_NODE, &debug_igmp_packets_cmd);
|
|
|
|
install_element(ENABLE_NODE, &no_debug_igmp_packets_cmd);
|
|
|
|
install_element(ENABLE_NODE, &debug_igmp_trace_cmd);
|
|
|
|
install_element(ENABLE_NODE, &no_debug_igmp_trace_cmd);
|
|
|
|
install_element(ENABLE_NODE, &debug_mroute_cmd);
|
|
|
|
install_element(ENABLE_NODE, &debug_mroute_detail_cmd);
|
|
|
|
install_element(ENABLE_NODE, &no_debug_mroute_cmd);
|
|
|
|
install_element(ENABLE_NODE, &no_debug_mroute_detail_cmd);
|
|
|
|
install_element(ENABLE_NODE, &debug_static_cmd);
|
|
|
|
install_element(ENABLE_NODE, &no_debug_static_cmd);
|
|
|
|
install_element(ENABLE_NODE, &debug_pim_cmd);
|
|
|
|
install_element(ENABLE_NODE, &no_debug_pim_cmd);
|
|
|
|
install_element(ENABLE_NODE, &debug_pim_events_cmd);
|
|
|
|
install_element(ENABLE_NODE, &no_debug_pim_events_cmd);
|
|
|
|
install_element(ENABLE_NODE, &debug_pim_packets_cmd);
|
|
|
|
install_element(ENABLE_NODE, &no_debug_pim_packets_cmd);
|
|
|
|
install_element(ENABLE_NODE, &debug_pim_packetdump_send_cmd);
|
|
|
|
install_element(ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
|
|
|
|
install_element(ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
|
|
|
|
install_element(ENABLE_NODE, &no_debug_pim_packetdump_recv_cmd);
|
|
|
|
install_element(ENABLE_NODE, &debug_pim_trace_cmd);
|
|
|
|
install_element(ENABLE_NODE, &no_debug_pim_trace_cmd);
|
2017-06-05 19:15:47 +02:00
|
|
|
install_element(ENABLE_NODE, &debug_pim_trace_detail_cmd);
|
|
|
|
install_element(ENABLE_NODE, &no_debug_pim_trace_detail_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(ENABLE_NODE, &debug_ssmpingd_cmd);
|
|
|
|
install_element(ENABLE_NODE, &no_debug_ssmpingd_cmd);
|
|
|
|
install_element(ENABLE_NODE, &debug_pim_zebra_cmd);
|
|
|
|
install_element(ENABLE_NODE, &no_debug_pim_zebra_cmd);
|
|
|
|
install_element(ENABLE_NODE, &debug_msdp_cmd);
|
|
|
|
install_element(ENABLE_NODE, &no_debug_msdp_cmd);
|
|
|
|
install_element(ENABLE_NODE, &undebug_msdp_cmd);
|
|
|
|
install_element(ENABLE_NODE, &debug_msdp_events_cmd);
|
|
|
|
install_element(ENABLE_NODE, &no_debug_msdp_events_cmd);
|
|
|
|
install_element(ENABLE_NODE, &undebug_msdp_events_cmd);
|
|
|
|
install_element(ENABLE_NODE, &debug_msdp_packets_cmd);
|
|
|
|
install_element(ENABLE_NODE, &no_debug_msdp_packets_cmd);
|
|
|
|
install_element(ENABLE_NODE, &undebug_msdp_packets_cmd);
|
|
|
|
|
|
|
|
install_element(CONFIG_NODE, &debug_igmp_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_debug_igmp_cmd);
|
|
|
|
install_element(CONFIG_NODE, &debug_igmp_events_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_debug_igmp_events_cmd);
|
|
|
|
install_element(CONFIG_NODE, &debug_igmp_packets_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_debug_igmp_packets_cmd);
|
|
|
|
install_element(CONFIG_NODE, &debug_igmp_trace_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_debug_igmp_trace_cmd);
|
|
|
|
install_element(CONFIG_NODE, &debug_mroute_cmd);
|
|
|
|
install_element(CONFIG_NODE, &debug_mroute_detail_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_debug_mroute_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_debug_mroute_detail_cmd);
|
|
|
|
install_element(CONFIG_NODE, &debug_static_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_debug_static_cmd);
|
|
|
|
install_element(CONFIG_NODE, &debug_pim_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_debug_pim_cmd);
|
|
|
|
install_element(CONFIG_NODE, &debug_pim_events_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_debug_pim_events_cmd);
|
|
|
|
install_element(CONFIG_NODE, &debug_pim_packets_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_debug_pim_packets_cmd);
|
|
|
|
install_element(CONFIG_NODE, &debug_pim_trace_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_debug_pim_trace_cmd);
|
2017-06-05 19:15:47 +02:00
|
|
|
install_element(CONFIG_NODE, &debug_pim_trace_detail_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_debug_pim_trace_detail_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &debug_ssmpingd_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_debug_ssmpingd_cmd);
|
|
|
|
install_element(CONFIG_NODE, &debug_pim_zebra_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_debug_pim_zebra_cmd);
|
|
|
|
install_element(CONFIG_NODE, &debug_msdp_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_debug_msdp_cmd);
|
|
|
|
install_element(CONFIG_NODE, &undebug_msdp_cmd);
|
|
|
|
install_element(CONFIG_NODE, &debug_msdp_events_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_debug_msdp_events_cmd);
|
|
|
|
install_element(CONFIG_NODE, &undebug_msdp_events_cmd);
|
|
|
|
install_element(CONFIG_NODE, &debug_msdp_packets_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_debug_msdp_packets_cmd);
|
|
|
|
install_element(CONFIG_NODE, &undebug_msdp_packets_cmd);
|
2017-05-23 00:14:43 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
|
2017-05-23 00:14:43 +02:00
|
|
|
install_element(VRF_NODE, &ip_msdp_mesh_group_member_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd);
|
2017-06-02 14:16:13 +02:00
|
|
|
install_element(VRF_NODE, &no_ip_msdp_mesh_group_member_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &ip_msdp_mesh_group_source_cmd);
|
2017-05-23 00:14:43 +02:00
|
|
|
install_element(VRF_NODE, &ip_msdp_mesh_group_source_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_source_cmd);
|
2017-05-23 00:14:43 +02:00
|
|
|
install_element(VRF_NODE, &no_ip_msdp_mesh_group_source_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(VIEW_NODE, &show_ip_msdp_peer_detail_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_msdp_sa_detail_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_msdp_sa_sg_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_msdp_mesh_group_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_pim_ssm_range_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_pim_group_type_cmd);
|
|
|
|
install_element(INTERFACE_NODE, &interface_pim_use_source_cmd);
|
|
|
|
install_element(INTERFACE_NODE, &interface_no_pim_use_source_cmd);
|
|
|
|
/* Install BFD command */
|
|
|
|
install_element(INTERFACE_NODE, &ip_pim_bfd_cmd);
|
|
|
|
install_element(INTERFACE_NODE, &ip_pim_bfd_param_cmd);
|
|
|
|
install_element(INTERFACE_NODE, &no_ip_pim_bfd_cmd);
|
|
|
|
install_element(INTERFACE_NODE, &no_ip_pim_bfd_param_cmd);
|
2015-02-04 07:01:14 +01:00
|
|
|
}
|