summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_fsm.c2
-rw-r--r--bgpd/bgp_packet.c5
-rw-r--r--bgpd/bgp_vty.c16
-rw-r--r--bgpd/bgp_zebra.c3
-rw-r--r--bgpd/bgpd.c4
-rw-r--r--cumulus/start-stop-daemon.c1
-rw-r--r--ospfd/ospf_vty.c2
-rw-r--r--pimd/pim_cmd.c13
-rw-r--r--pimd/pim_ifchannel.c49
-rw-r--r--pimd/pim_igmp.c8
-rw-r--r--pimd/pim_nht.c6
-rw-r--r--pimd/pim_register.c4
-rw-r--r--pimd/pim_upstream.c95
-rw-r--r--pimd/pim_upstream.h2
-rwxr-xr-xtools/frr-reload.py56
-rw-r--r--vtysh/vtysh.c2
-rw-r--r--zebra/interface.c4
-rw-r--r--zebra/redistribute.c66
-rw-r--r--zebra/zebra_rnh.c2
19 files changed, 221 insertions, 119 deletions
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index 424eec55c4..fbca83c750 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -1026,7 +1026,7 @@ bgp_stop (struct peer *peer)
zlog_info ("%%ADJCHANGE: neighbor %s(%s) in vrf %s Down %s",
peer->host,
(peer->hostname) ? peer->hostname : "Unknown",
- (vrf->vrf_id != VRF_DEFAULT) ? vrf->name : "Default",
+ vrf ? ((vrf->vrf_id != VRF_DEFAULT) ? vrf->name : "Default") : "",
peer_down_str [(int) peer->last_reset]);
}
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 853fcc8697..661dce133c 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -1128,7 +1128,10 @@ bgp_open_receive (struct peer *peer, bgp_size_t size)
else
peer->v_holdtime = send_holdtime;
- peer->v_keepalive = peer->v_holdtime / 3;
+ if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
+ peer->v_keepalive = peer->keepalive;
+ else
+ peer->v_keepalive = peer->v_holdtime / 3;
/* Open option part parse. */
if (optlen != 0)
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 0c6648d562..1372e820f9 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -2704,7 +2704,12 @@ peer_conf_interface_get (struct vty *vty, const char *conf_if, afi_t afi,
}
peer = peer_lookup_by_conf_if (bgp, conf_if);
- if (!peer)
+ if (peer)
+ {
+ if (as_str)
+ ret = peer_remote_as (bgp, &su, conf_if, &as, as_type, afi, safi);
+ }
+ else
{
if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4)
&& afi == AFI_IP && safi == SAFI_UNICAST)
@@ -2728,8 +2733,9 @@ peer_conf_interface_get (struct vty *vty, const char *conf_if, afi_t afi,
if (peer->ifp)
bgp_zebra_initiate_radv (bgp, peer);
}
- else if ((v6only && !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)) ||
- (!v6only && CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)))
+
+ if ((v6only && !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)) ||
+ (!v6only && CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)))
{
if (v6only)
SET_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY);
@@ -7433,6 +7439,7 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
u_int16_t i;
u_char *msg;
json_object *json_neigh = NULL;
+ time_t epoch_tbuf;
bgp = p->bgp;
@@ -7622,8 +7629,11 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
uptime = bgp_clock();
uptime -= p->uptime;
tm = gmtime(&uptime);
+ epoch_tbuf = time(NULL) - uptime;
json_object_int_add(json_neigh, "bgpTimerUp", (tm->tm_sec * 1000) + (tm->tm_min * 60000) + (tm->tm_hour * 3600000));
+ json_object_string_add(json_neigh, "bgpTimerUpString", peer_uptime (p->uptime, timebuf, BGP_UPTIME_LEN, 0, NULL));
+ json_object_int_add(json_neigh, "bgpTimerUpEstablishedEpoch", epoch_tbuf);
}
else if (p->status == Active)
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 72bd081a7e..4e00367aff 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -1470,7 +1470,8 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
if (!ifindex)
{
if (info->peer->conf_if || info->peer->ifname)
- ifindex = if_nametoindex (info->peer->conf_if ? info->peer->conf_if : info->peer->ifname);
+ ifindex = ifname2ifindex_vrf (info->peer->conf_if ? info->peer->conf_if :
+ info->peer->ifname, bgp->vrf_id);
else if (info->peer->nexthop.ifp)
ifindex = info->peer->nexthop.ifp->ifindex;
}
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 7343d3714f..1da69c9f32 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -6341,7 +6341,7 @@ peer_clear_soft (struct peer *peer, afi_t afi, safi_t safi,
char *
peer_uptime (time_t uptime2, char *buf, size_t len, u_char use_json, json_object *json)
{
- time_t uptime1;
+ time_t uptime1, epoch_tbuf;
struct tm *tm;
/* Check buffer length. */
@@ -6395,8 +6395,10 @@ peer_uptime (time_t uptime2, char *buf, size_t len, u_char use_json, json_object
if (use_json)
{
+ epoch_tbuf = time(NULL) - uptime1;
json_object_string_add(json, "peerUptime", buf);
json_object_long_add(json, "peerUptimeMsec", uptime1 * 1000);
+ json_object_int_add(json, "peerUptimeEstablishedEpoch", epoch_tbuf);
}
return buf;
diff --git a/cumulus/start-stop-daemon.c b/cumulus/start-stop-daemon.c
index c123f87e92..f1a252a26f 100644
--- a/cumulus/start-stop-daemon.c
+++ b/cumulus/start-stop-daemon.c
@@ -811,6 +811,7 @@ run_stop_schedule(void)
anykilled = 0;
retry_nr = 0;
+ n_killed = 0;
if (schedule == NULL) {
do_stop(signal_nr, quietmode, &n_killed, &n_notkilled, 0);
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index 44bf1b8667..f409aa8bb4 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -6333,7 +6333,7 @@ DEFUN (no_ip_ospf_dead_interval,
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_ipv4 = argc - 1;
- struct in_addr addr;
+ struct in_addr addr = { .s_addr = 0L};
int ret;
struct ospf_if_params *params;
struct ospf_interface *oi;
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index d5dbe4f7ab..80decc34cd 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -5075,11 +5075,16 @@ DEFUN (interface_ip_pim_hello,
pim_ifp = ifp->info;
- if (!pim_ifp) {
- vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ if (!pim_ifp)
+ {
+ if (!pim_cmd_interface_add(ifp))
+ {
+ vty_out(vty, "Could not enable PIM SM on interface%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ pim_ifp = ifp->info;
pim_ifp->pim_hello_period = strtol(argv[idx_time]->arg, NULL, 10);
if (argc == idx_hold + 1)
diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c
index f4fe609605..c5953e560c 100644
--- a/pimd/pim_ifchannel.c
+++ b/pimd/pim_ifchannel.c
@@ -148,7 +148,6 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
/* SGRpt entry could have empty oil */
if (ch->upstream->channel_oil)
pim_channel_del_oif (ch->upstream->channel_oil, ch->interface, mask);
- pim_channel_del_oif (ch->upstream->channel_oil, ch->interface, mask);
/*
* Do we have any S,G's that are inheriting?
* Nuke from on high too.
@@ -179,6 +178,10 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
pim_upstream_update_join_desired(ch->upstream);
}
+ /* upstream is common across ifchannels, check if upstream's
+ ifchannel list is empty before deleting upstream_del
+ ref count will take care of it.
+ */
pim_upstream_del(ch->upstream, __PRETTY_FUNCTION__);
ch->upstream = NULL;
@@ -200,6 +203,9 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
hash_release(pim_ifp->pim_ifchannel_hash, ch);
listnode_delete(pim_ifchannel_list, ch);
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug ("%s: ifchannel entry %s is deleted ", __PRETTY_FUNCTION__, ch->sg_str);
+
pim_ifchannel_free(ch);
}
@@ -571,14 +577,18 @@ pim_ifchannel_add(struct interface *ifp,
listnode_add_sort(up->ifchannels, ch);
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug ("%s: ifchannel %s is created ", __PRETTY_FUNCTION__, ch->sg_str);
+
return ch;
}
-static void ifjoin_to_noinfo(struct pim_ifchannel *ch)
+static void ifjoin_to_noinfo(struct pim_ifchannel *ch, bool ch_del)
{
pim_forward_stop(ch);
pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_NOINFO);
- delete_on_noinfo(ch);
+ if (ch_del)
+ delete_on_noinfo(ch);
}
static int on_ifjoin_expiry_timer(struct thread *t)
@@ -589,7 +599,7 @@ static int on_ifjoin_expiry_timer(struct thread *t)
ch->t_ifjoin_expiry_timer = NULL;
- ifjoin_to_noinfo(ch);
+ ifjoin_to_noinfo(ch, true);
/* ch may have been deleted */
return 0;
@@ -613,10 +623,6 @@ static int on_ifjoin_prune_pending_timer(struct thread *t)
pim_ifp = ifp->info;
send_prune_echo = (listcount(pim_ifp->pim_neighbor_list) > 1);
- //ch->ifjoin_state transition to NOINFO
- ifjoin_to_noinfo(ch);
- /* from here ch may have been deleted */
-
if (send_prune_echo)
{
struct pim_rpf rpf;
@@ -625,6 +631,23 @@ static int on_ifjoin_prune_pending_timer(struct thread *t)
rpf.rpf_addr.u.prefix4 = pim_ifp->primary_address;
pim_jp_agg_single_upstream_send(&rpf, ch->upstream, 0);
}
+ /* If SGRpt flag is set on ifchannel, Trigger SGRpt
+ message on RP path upon prune timer expiry.
+ */
+ if (PIM_IF_FLAG_TEST_S_G_RPT (ch->flags))
+ {
+ if (ch->upstream)
+ pim_upstream_update_join_desired(ch->upstream);
+ /*
+ ch->ifjoin_state transition to NOINFO state
+ ch_del is set to 0 for not deleteing from here.
+ Holdtime expiry (ch_del set to 1) delete the entry.
+ */
+ ifjoin_to_noinfo(ch, false);
+ }
+ else
+ ifjoin_to_noinfo(ch, true);
+ /* from here ch may have been deleted */
}
else
{
@@ -801,7 +824,7 @@ void pim_ifchannel_join_add(struct interface *ifp,
(ch->upstream->parent->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP) &&
!(ch->upstream->flags & PIM_UPSTREAM_FLAG_MASK_SRC_LHR))
{
- pim_upstream_ref (ch->upstream, PIM_UPSTREAM_FLAG_MASK_SRC_LHR);
+ pim_upstream_ref (ch->upstream, PIM_UPSTREAM_FLAG_MASK_SRC_LHR, __PRETTY_FUNCTION__);
pim_upstream_keep_alive_timer_start (ch->upstream, qpim_keep_alive_time);
}
break;
@@ -895,8 +918,10 @@ void pim_ifchannel_prune(struct interface *ifp,
case PIM_IFJOIN_NOINFO:
if (source_flags & PIM_ENCODE_RPT_BIT)
{
- PIM_IF_FLAG_SET_S_G_RPT(ch->flags);
- ch->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING;
+ if (!(source_flags & PIM_ENCODE_WC_BIT))
+ PIM_IF_FLAG_SET_S_G_RPT(ch->flags);
+
+ ch->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING;
if (listcount(pim_ifp->pim_neighbor_list) > 1)
jp_override_interval_msec = pim_if_jp_override_interval_msec(ifp);
else
@@ -1306,7 +1331,7 @@ pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom, uint8_t
if (up)
{
if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: del inherit oif from up %s", __PRETTY_FUNCTION__, up->sg_str);
+ zlog_debug ("%s: SGRpt Set, del inherit oif from up %s", __PRETTY_FUNCTION__, up->sg_str);
pim_channel_del_oif (up->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
}
}
diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c
index ee88e7d8ea..dd5f7e77e9 100644
--- a/pimd/pim_igmp.c
+++ b/pimd/pim_igmp.c
@@ -39,6 +39,7 @@
#include "pim_zebra.h"
static void group_timer_off(struct igmp_group *group);
+static int pim_igmp_general_query(struct thread *t);
/* This socket is used for TXing IGMP packets only, IGMP RX happens
* in pim_mroute_msg()
@@ -172,8 +173,11 @@ static int pim_igmp_other_querier_expire(struct thread *t)
/*
We are the current querier, then
re-start sending general queries.
+ RFC 2236 - sec 7 Other Querier
+ present timer expired (Send General
+ Query, Set Gen. Query. timer)
*/
- pim_igmp_general_query_on(igmp);
+ pim_igmp_general_query(t);
return 0;
}
@@ -497,8 +501,6 @@ int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len)
return -1;
}
-static int pim_igmp_general_query(struct thread *t);
-
void pim_igmp_general_query_on(struct igmp_sock *igmp)
{
struct pim_interface *pim_ifp;
diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c
index c5f8d1d826..9165bef566 100644
--- a/pimd/pim_nht.c
+++ b/pimd/pim_nht.c
@@ -567,7 +567,7 @@ pim_ecmp_nexthop_search (struct pim_nexthop_cache *pnc,
//PIM ECMP flag is enable then choose ECMP path.
hash_val = pim_compute_ecmp_hash (src, grp);
mod_val = hash_val % pnc->nexthop_num;
- if (PIM_DEBUG_TRACE)
+ if (PIM_DEBUG_PIM_TRACE_DETAIL)
zlog_debug ("%s: hash_val %u mod_val %u ",
__PRETTY_FUNCTION__, hash_val, mod_val);
}
@@ -914,7 +914,7 @@ pim_ecmp_nexthop_lookup (struct pim_nexthop *nexthop, struct in_addr addr,
{
hash_val = pim_compute_ecmp_hash (src, grp);
mod_val = hash_val % num_ifindex;
- if (PIM_DEBUG_TRACE)
+ if (PIM_DEBUG_PIM_TRACE_DETAIL)
zlog_debug ("%s: hash_val %u mod_val %u",
__PRETTY_FUNCTION__, hash_val, mod_val);
}
@@ -1037,7 +1037,7 @@ int pim_ecmp_fib_lookup_if_vif_index(struct in_addr addr,
{
hash_val = pim_compute_ecmp_hash (src, grp);
mod_val = hash_val % num_ifindex;
- if (PIM_DEBUG_TRACE)
+ if (PIM_DEBUG_PIM_TRACE_DETAIL)
zlog_debug ("%s: hash_val %u mod_val %u",
__PRETTY_FUNCTION__, hash_val, mod_val);
}
diff --git a/pimd/pim_register.c b/pimd/pim_register.c
index 8dc179c144..e6145a142e 100644
--- a/pimd/pim_register.c
+++ b/pimd/pim_register.c
@@ -346,7 +346,7 @@ pim_register_recv (struct interface *ifp,
zlog_debug("%s: Sending register-Stop to %s and dropping mr. packet",
__func__, "Sender");
/* Drop Packet Silently */
- return 1;
+ return 0;
}
}
@@ -408,5 +408,5 @@ pim_register_recv (struct interface *ifp,
pim_register_stop_send (ifp, &sg, dest_addr, src_addr);
}
- return 1;
+ return 0;
}
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index dd6eab9cfe..6fadfc2f29 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -78,9 +78,17 @@ pim_upstream_remove_children (struct pim_upstream *up)
while (!list_isempty (up->sources))
{
child = listnode_head (up->sources);
- child->parent = NULL;
listnode_delete (up->sources, child);
+ if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(child->flags))
+ {
+ PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(child->flags);
+ child = pim_upstream_del(child, __PRETTY_FUNCTION__);
+ }
+ if (child)
+ child->parent = NULL;
}
+ list_delete(up->sources);
+ up->sources = NULL;
}
/*
@@ -149,10 +157,14 @@ void pim_upstream_free(struct pim_upstream *up)
static void upstream_channel_oil_detach(struct pim_upstream *up)
{
- if (up->channel_oil) {
- pim_channel_oil_del(up->channel_oil);
- up->channel_oil = NULL;
- }
+ if (up->channel_oil)
+ {
+ /* Detaching from channel_oil, channel_oil may exist post del,
+ but upstream would not keep reference of it
+ */
+ pim_channel_oil_del(up->channel_oil);
+ up->channel_oil = NULL;
+ }
}
struct pim_upstream *
@@ -163,7 +175,7 @@ pim_upstream_del(struct pim_upstream *up, const char *name)
if (PIM_DEBUG_TRACE)
zlog_debug ("%s(%s): Delete %s ref count: %d , flags: %d c_oil ref count %d (Pre decrement)",
- __PRETTY_FUNCTION__, name, up->sg_str, up->ref_count, up->flags,
+ __PRETTY_FUNCTION__, name, up->sg_str, up->ref_count, up->flags,
up->channel_oil->oil_ref_count);
--up->ref_count;
@@ -195,25 +207,11 @@ pim_upstream_del(struct pim_upstream *up, const char *name)
}
pim_upstream_remove_children (up);
- pim_mroute_del (up->channel_oil, __PRETTY_FUNCTION__);
- upstream_channel_oil_detach(up);
-
if (up->sources)
- {
- struct listnode *node, *nnode;
- struct pim_upstream *child;
- for (ALL_LIST_ELEMENTS (up->sources, node, nnode, child))
- {
- if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(child->flags))
- {
- PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(child->flags);
- pim_upstream_del(child, __PRETTY_FUNCTION__);
- }
- }
-
- list_delete (up->sources);
- }
+ list_delete (up->sources);
up->sources = NULL;
+ pim_mroute_del (up->channel_oil, __PRETTY_FUNCTION__);
+ upstream_channel_oil_detach(up);
list_delete (up->ifchannels);
up->ifchannels = NULL;
@@ -223,11 +221,10 @@ pim_upstream_del(struct pim_upstream *up, const char *name)
into pim_upstream_free() because the later is
called by list_delete_all_node()
*/
- if (up->parent)
- {
- listnode_delete (up->parent->sources, up);
- up->parent = NULL;
- }
+ if (up->parent && up->parent->sources)
+ listnode_delete (up->parent->sources, up);
+ up->parent = NULL;
+
listnode_delete (pim_upstream_list, up);
hash_release (pim_upstream_hash, up);
@@ -538,13 +535,14 @@ pim_upstream_switch(struct pim_upstream *up,
{
enum pim_upstream_state old_state = up->join_state;
- if (PIM_DEBUG_PIM_EVENTS) {
- zlog_debug("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s",
+ if (PIM_DEBUG_PIM_EVENTS)
+ {
+ zlog_debug ("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s",
__PRETTY_FUNCTION__,
up->sg_str,
pim_upstream_state2str (up->join_state),
pim_upstream_state2str (new_state));
- }
+ }
up->join_state = new_state;
if (old_state != new_state)
@@ -584,7 +582,17 @@ pim_upstream_switch(struct pim_upstream *up,
if (old_state == PIM_UPSTREAM_JOINED)
pim_msdp_up_join_state_changed(up);
- pim_jp_agg_single_upstream_send(&up->rpf, up, 0 /* prune */);
+ /* IHR, Trigger SGRpt on *,G IIF to prune S,G from RPT */
+ if (pim_upstream_is_sg_rpt(up) && up->parent)
+ {
+ if (PIM_DEBUG_PIM_TRACE_DETAIL)
+ zlog_debug ("%s: *,G IIF %s S,G IIF %s ", __PRETTY_FUNCTION__,
+ up->parent->rpf.source_nexthop.interface->name,
+ up->rpf.source_nexthop.interface->name);
+ pim_jp_agg_single_upstream_send(&up->parent->rpf, up->parent, 1 /* (W,G) Join */);
+ }
+ else
+ pim_jp_agg_single_upstream_send(&up->rpf, up, 0 /* prune */);
join_timer_stop(up);
}
}
@@ -717,9 +725,9 @@ pim_upstream_new (struct prefix_sg *sg,
if (PIM_DEBUG_TRACE)
{
- zlog_debug ("%s: Created Upstream %s upstream_addr %s",
+ zlog_debug ("%s: Created Upstream %s upstream_addr %s ref count %d increment",
__PRETTY_FUNCTION__, up->sg_str,
- inet_ntoa (up->upstream_addr));
+ inet_ntoa (up->upstream_addr), up->ref_count);
}
return up;
@@ -750,6 +758,9 @@ pim_upstream_find_or_add(struct prefix_sg *sg,
{
up->flags |= flags;
up->ref_count++;
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s(%s): upstream %s ref count %d increment",
+ __PRETTY_FUNCTION__, name, up->sg_str, up->ref_count);
}
}
else
@@ -759,10 +770,13 @@ pim_upstream_find_or_add(struct prefix_sg *sg,
}
void
-pim_upstream_ref(struct pim_upstream *up, int flags)
+pim_upstream_ref(struct pim_upstream *up, int flags, const char *name)
{
up->flags |= flags;
++up->ref_count;
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s(%s): upstream %s ref count %d increment",
+ __PRETTY_FUNCTION__, name, up->sg_str, up->ref_count);
}
struct pim_upstream *pim_upstream_add(struct prefix_sg *sg,
@@ -773,7 +787,7 @@ struct pim_upstream *pim_upstream_add(struct prefix_sg *sg,
int found = 0;
up = pim_upstream_find(sg);
if (up) {
- pim_upstream_ref(up, flags);
+ pim_upstream_ref(up, flags, name);
found = 1;
}
else {
@@ -786,10 +800,11 @@ struct pim_upstream *pim_upstream_add(struct prefix_sg *sg,
{
char buf[PREFIX2STR_BUFFER];
prefix2str (&up->rpf.rpf_addr, buf, sizeof (buf));
- zlog_debug("%s(%s): %s, iif %s found: %d: ref_count: %d",
+ zlog_debug("%s(%s): %s, iif %s (%s) found: %d: ref_count: %d",
__PRETTY_FUNCTION__, name,
- up->sg_str, buf, found,
- up->ref_count);
+ up->sg_str, buf, up->rpf.source_nexthop.interface ?
+ up->rpf.source_nexthop.interface->name : "NIL" ,
+ found, up->ref_count);
}
else
zlog_debug("%s(%s): (%s) failure to create",
@@ -1660,7 +1675,7 @@ pim_upstream_sg_running (void *arg)
if (PIM_DEBUG_TRACE)
zlog_debug ("source reference created on kat restart %s", up->sg_str);
- pim_upstream_ref(up, PIM_UPSTREAM_FLAG_MASK_SRC_STREAM);
+ pim_upstream_ref(up, PIM_UPSTREAM_FLAG_MASK_SRC_STREAM, __PRETTY_FUNCTION__);
PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags);
pim_upstream_fhr_kat_start(up);
}
diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h
index f1c8df35b1..d728c6c01f 100644
--- a/pimd/pim_upstream.h
+++ b/pimd/pim_upstream.h
@@ -145,7 +145,7 @@ struct pim_upstream *pim_upstream_find_or_add (struct prefix_sg *sg,
struct pim_upstream *pim_upstream_add (struct prefix_sg *sg,
struct interface *ifp, int flags,
const char *name);
-void pim_upstream_ref (struct pim_upstream *up, int flags);
+void pim_upstream_ref (struct pim_upstream *up, int flags, const char *name);
struct pim_upstream *pim_upstream_del(struct pim_upstream *up, const char *name);
int pim_upstream_evaluate_join_desired(struct pim_upstream *up);
diff --git a/tools/frr-reload.py b/tools/frr-reload.py
index c91392da15..a7a04be639 100755
--- a/tools/frr-reload.py
+++ b/tools/frr-reload.py
@@ -109,9 +109,12 @@ class Config(object):
log.info('Loading Config object from file %s', filename)
try:
- file_output = subprocess.check_output(['/usr/bin/vtysh', '-m', '-f', filename])
+ file_output = subprocess.check_output(['/usr/bin/vtysh', '-m', '-f', filename],
+ stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
- raise VtyshMarkException(str(e))
+ ve = VtyshMarkException(e)
+ ve.output = e.output
+ raise ve
for line in file_output.split('\n'):
line = line.strip()
@@ -134,9 +137,11 @@ class Config(object):
try:
config_text = subprocess.check_output(
"/usr/bin/vtysh -c 'show run' | /usr/bin/tail -n +4 | /usr/bin/vtysh -m -f -",
- shell=True)
+ shell=True, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
- raise VtyshMarkException(str(e))
+ ve = VtyshMarkException(e)
+ ve.output = e.output
+ raise ve
for line in config_text.split('\n'):
line = line.strip()
@@ -342,10 +347,12 @@ end
# the keywords that we know are single line contexts. bgp in this case
# is not the main router bgp block, but enabling multi-instance
oneline_ctx_keywords = ("access-list ",
+ "agentx",
"bgp ",
"debug ",
"dump ",
"enable ",
+ "frr ",
"hostname ",
"ip ",
"ipv6 ",
@@ -815,6 +822,14 @@ def compare_context_objects(newconf, running):
elif "router bgp" in running_ctx_keys[0] and len(running_ctx_keys) > 1 and delete_bgpd:
continue
+ elif ("router bgp" in running_ctx_keys[0] and
+ len(running_ctx_keys) > 1 and
+ running_ctx_keys[1].startswith('address-family')):
+ # There's no 'no address-family' support and so we have to
+ # delete each line individually again
+ for line in running_ctx.lines:
+ lines_to_del.append((running_ctx_keys, line))
+
# Non-global context
elif running_ctx_keys and not any("address-family" in key for key in running_ctx_keys):
lines_to_del.append((running_ctx_keys, None))
@@ -890,11 +905,15 @@ if __name__ == '__main__':
# Verify the new config file is valid
if not os.path.isfile(args.filename):
- print "Filename %s does not exist" % args.filename
+ msg = "Filename %s does not exist" % args.filename
+ print msg
+ log.error(msg)
sys.exit(1)
if not os.path.getsize(args.filename):
- print "Filename %s is an empty file" % args.filename
+ msg = "Filename %s is an empty file" % args.filename
+ print msg
+ log.error(msg)
sys.exit(1)
# Verify that 'service integrated-vtysh-config' is configured
@@ -911,7 +930,9 @@ if __name__ == '__main__':
break
if not service_integrated_vtysh_config:
- print "'service integrated-vtysh-config' is not configured, this is required for 'service frr reload'"
+ msg = "'service integrated-vtysh-config' is not configured, this is required for 'service frr reload'"
+ print msg
+ log.error(msg)
sys.exit(1)
if args.debug:
@@ -922,6 +943,7 @@ if __name__ == '__main__':
# Create a Config object from the config generated by newconf
newconf = Config()
newconf.load_from_file(args.filename)
+ reload_ok = True
if args.test:
@@ -1064,7 +1086,7 @@ if __name__ == '__main__':
# 'no ip ospf authentication message-digest 1.1.1.1' in
# our example above
# - Split that last entry by whitespace and drop the last word
- log.warning('Failed to execute %s', ' '.join(cmd))
+ log.info('Failed to execute %s', ' '.join(cmd))
last_arg = cmd[-1].split(' ')
if len(last_arg) <= 2:
@@ -1099,9 +1121,25 @@ if __name__ == '__main__':
with open(filename, 'w') as fh:
for line in lines_to_configure:
fh.write(line + '\n')
- subprocess.call(['/usr/bin/vtysh', '-f', filename])
+
+ output = subprocess.check_output(['/usr/bin/vtysh', '-f', filename])
+
+ # exit non-zero if we see these errors
+ for x in ('BGP instance name and AS number mismatch',
+ 'BGP instance is already running',
+ '% not a local address'):
+ for line in output.splitlines():
+ if x in line:
+ msg = "ERROR: %s" % x
+ log.error(msg)
+ print msg
+ reload_ok = False
+
os.unlink(filename)
# Make these changes persistent
if args.overwrite or args.filename != '/etc/frr/frr.conf':
subprocess.call(['/usr/bin/vtysh', '-c', 'write'])
+
+ if not reload_ok:
+ sys.exit(1)
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 5c39e1ee90..337925c6e8 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -646,7 +646,7 @@ vtysh_mark_file (const char *filename)
}
}
/* This is the end */
- fprintf(stdout, "end\n");
+ fprintf(stdout, "\nend\n");
vty_close(vty);
XFREE(MTYPE_VTYSH_CMD, vty_buf_copy);
diff --git a/zebra/interface.c b/zebra/interface.c
index 78ac0258ca..317cc722b4 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -709,6 +709,10 @@ if_delete_update (struct interface *ifp)
for setting ifindex to IFINDEX_INTERNAL after processing the
interface deletion message. */
ifp->ifindex = IFINDEX_INTERNAL;
+
+ /* if the ifp is in a vrf, move it to default so vrf can be deleted if desired */
+ if (ifp->vrf_id)
+ if_handle_vrf_change (ifp, VRF_DEFAULT);
}
/* VRF change for an interface */
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index c7ed209d3c..e1ec22463a 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -107,45 +107,41 @@ zebra_redistribute_default (struct zserv *client, vrf_id_t vrf_id)
/* Redistribute routes. */
static void
-zebra_redistribute (struct zserv *client, int type, u_short instance, vrf_id_t vrf_id)
+zebra_redistribute (struct zserv *client, int type, u_short instance, vrf_id_t vrf_id, int afi)
{
struct rib *newrib;
struct route_table *table;
struct route_node *rn;
- int afi;
- for (afi = AFI_IP; afi <= AFI_IP6; afi++)
- {
- table = zebra_vrf_table (afi, SAFI_UNICAST, vrf_id);
- if (! table)
- continue;
+ table = zebra_vrf_table (afi, SAFI_UNICAST, vrf_id);
+ if (! table)
+ return;
- for (rn = route_top (table); rn; rn = route_next (rn))
- RNODE_FOREACH_RIB (rn, newrib)
- {
- struct prefix *dst_p, *src_p;
- srcdest_rnode_prefixes(rn, &dst_p, &src_p);
-
- if (IS_ZEBRA_DEBUG_EVENT)
- zlog_debug("%s: checking: selected=%d, type=%d, distance=%d, "
- "zebra_check_addr=%d", __func__,
- CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED),
- newrib->type, newrib->distance,
- zebra_check_addr (dst_p));
-
- if (! CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED))
- continue;
- if ((type != ZEBRA_ROUTE_ALL &&
- (newrib->type != type || newrib->instance != instance)))
- continue;
- if (newrib->distance == DISTANCE_INFINITY)
- continue;
- if (! zebra_check_addr (dst_p))
- continue;
-
- zsend_redistribute_route (1, client, dst_p, src_p, newrib);
- }
- }
+ for (rn = route_top (table); rn; rn = route_next (rn))
+ RNODE_FOREACH_RIB (rn, newrib)
+ {
+ struct prefix *dst_p, *src_p;
+ srcdest_rnode_prefixes(rn, &dst_p, &src_p);
+
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug("%s: checking: selected=%d, type=%d, distance=%d, "
+ "zebra_check_addr=%d", __func__,
+ CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED),
+ newrib->type, newrib->distance,
+ zebra_check_addr (dst_p));
+
+ if (! CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED))
+ continue;
+ if ((type != ZEBRA_ROUTE_ALL &&
+ (newrib->type != type || newrib->instance != instance)))
+ continue;
+ if (newrib->distance == DISTANCE_INFINITY)
+ continue;
+ if (! zebra_check_addr (dst_p))
+ continue;
+
+ zsend_redistribute_route (1, client, dst_p, src_p, newrib);
+ }
}
/* Either advertise a route for redistribution to registered clients or */
@@ -265,13 +261,13 @@ zebra_redistribute_add (int command, struct zserv *client, int length,
if (! redist_check_instance (&client->mi_redist[afi][type], instance))
{
redist_add_instance (&client->mi_redist[afi][type], instance);
- zebra_redistribute (client, type, instance, zvrf_id (zvrf));
+ zebra_redistribute (client, type, instance, zvrf_id (zvrf), afi);
}
} else {
if (! vrf_bitmap_check (client->redist[afi][type], zvrf_id (zvrf)))
{
vrf_bitmap_set (client->redist[afi][type], zvrf_id (zvrf));
- zebra_redistribute (client, type, 0, zvrf_id (zvrf));
+ zebra_redistribute (client, type, 0, zvrf_id (zvrf), afi);
}
}
}
diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c
index 67859fd46b..5096e95395 100644
--- a/zebra/zebra_rnh.c
+++ b/zebra/zebra_rnh.c
@@ -555,7 +555,7 @@ zebra_rnh_process_static_routes (vrf_id_t vrfid, int family,
{
RNODE_FOREACH_RIB(static_rn, srib)
{
- if (srib->type == ZEBRA_ROUTE_STATIC)
+ if (srib->type != ZEBRA_ROUTE_STATIC)
continue;
/* Set the filter flag for the correct nexthop - static route may