summaryrefslogtreecommitdiff
path: root/pimd/pim_msdp.c
diff options
context:
space:
mode:
Diffstat (limited to 'pimd/pim_msdp.c')
-rw-r--r--pimd/pim_msdp.c332
1 files changed, 198 insertions, 134 deletions
diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c
index 215cc3c502..5e5ee5e91f 100644
--- a/pimd/pim_msdp.c
+++ b/pimd/pim_msdp.c
@@ -26,13 +26,12 @@
#include "pim_time.h"
#include "pim_upstream.h"
#include "pim_oil.h"
+#include "pim_nht.h"
#include "pim_msdp.h"
#include "pim_msdp_packet.h"
#include "pim_msdp_socket.h"
-// struct pim_msdp pim_msdp, *msdp = &pim_msdp;
-
static void pim_msdp_peer_listen(struct pim_msdp_peer *mp);
static void pim_msdp_peer_cr_timer_setup(struct pim_msdp_peer *mp, bool start);
static void pim_msdp_peer_ka_timer_setup(struct pim_msdp_peer *mp, bool start);
@@ -46,21 +45,34 @@ static void pim_msdp_sa_deref(struct pim_msdp_sa *sa,
static int pim_msdp_mg_mbr_comp(const void *p1, const void *p2);
static void pim_msdp_mg_mbr_free(struct pim_msdp_mg_mbr *mbr);
-/************************ SA cache management ******************************/
-static void pim_msdp_sa_timer_expiry_log(struct pim_msdp_sa *sa,
- const char *timer_str)
+void pim_msdp_originator_id(struct pim_instance *pim, const struct prefix *group,
+ struct in_addr *originator_id)
{
- zlog_debug("MSDP SA %s %s timer expired", sa->sg_str, timer_str);
+ struct rp_info *rp_info;
+
+ originator_id->s_addr = INADDR_ANY;
+
+ /* Originator ID was configured, use it. */
+ if (pim->msdp.originator_id.s_addr != INADDR_ANY) {
+ *originator_id = pim->msdp.originator_id;
+ return;
+ }
+
+ rp_info = pim_rp_find_match_group(pim, group);
+ if (rp_info) {
+ *originator_id = rp_info->rp.rpf_addr;
+ return;
+ }
}
+/************************ SA cache management ******************************/
/* RFC-3618:Sec-5.1 - global active source advertisement timer */
static void pim_msdp_sa_adv_timer_cb(struct event *t)
{
struct pim_instance *pim = EVENT_ARG(t);
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP SA advertisement timer expired");
- }
+ if (pim_msdp_log_sa_events(pim))
+ zlog_info("MSDP SA advertisement timer expired");
pim_msdp_sa_adv_timer_setup(pim, true /* start */);
pim_msdp_pkt_sa_tx(pim);
@@ -83,9 +95,8 @@ static void pim_msdp_sa_state_timer_cb(struct event *t)
sa = EVENT_ARG(t);
- if (PIM_DEBUG_MSDP_EVENTS) {
- pim_msdp_sa_timer_expiry_log(sa, "state");
- }
+ if (pim_msdp_log_sa_events(sa->pim))
+ zlog_info("MSDP SA %s state timer expired", sa->sg_str);
pim_msdp_sa_deref(sa, PIM_MSDP_SAF_PEER);
}
@@ -120,9 +131,8 @@ static void pim_msdp_sa_upstream_del(struct pim_msdp_sa *sa)
sa->flags &= ~PIM_MSDP_SAF_UP_DEL_IN_PROG;
}
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP SA %s de-referenced SPT", sa->sg_str);
- }
+ if (pim_msdp_log_sa_events(sa->pim))
+ zlog_info("MSDP SA %s de-referenced SPT", sa->sg_str);
}
static bool pim_msdp_sa_upstream_add_ok(struct pim_msdp_sa *sa,
@@ -185,10 +195,8 @@ static void pim_msdp_sa_upstream_update(struct pim_msdp_sa *sa,
if (up && (PIM_UPSTREAM_FLAG_TEST_SRC_MSDP(up->flags))) {
/* somehow we lost track of the upstream ptr? best log it */
sa->up = up;
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP SA %s SPT reference missing",
- sa->sg_str);
- }
+ if (pim_msdp_log_sa_events(sa->pim))
+ zlog_info("MSDP SA %s SPT reference missing", sa->sg_str);
return;
}
@@ -204,14 +212,11 @@ static void pim_msdp_sa_upstream_update(struct pim_msdp_sa *sa,
/* should we also start the kat in parallel? we will need it
* when the
* SA ages out */
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP SA %s referenced SPT", sa->sg_str);
- }
+ if (pim_msdp_log_sa_events(sa->pim))
+ zlog_info("MSDP SA %s referenced SPT", sa->sg_str);
} else {
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP SA %s SPT reference failed",
- sa->sg_str);
- }
+ if (pim_msdp_log_sa_events(sa->pim))
+ zlog_info("MSDP SA %s SPT reference failed", sa->sg_str);
}
}
@@ -240,9 +245,8 @@ static struct pim_msdp_sa *pim_msdp_sa_new(struct pim_instance *pim,
sa = hash_get(pim->msdp.sa_hash, sa, hash_alloc_intern);
listnode_add_sort(pim->msdp.sa_list, sa);
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP SA %s created", sa->sg_str);
- }
+ if (pim_msdp_log_sa_events(pim))
+ zlog_info("MSDP SA %s created", sa->sg_str);
return sa;
}
@@ -282,9 +286,8 @@ static void pim_msdp_sa_del(struct pim_msdp_sa *sa)
listnode_delete(sa->pim->msdp.sa_list, sa);
hash_release(sa->pim->msdp.sa_hash, sa);
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP SA %s deleted", sa->sg_str);
- }
+ if (pim_msdp_log_sa_events(sa->pim))
+ zlog_info("MSDP SA %s deleted", sa->sg_str);
/* free up any associated memory */
pim_msdp_sa_free(sa);
@@ -333,10 +336,9 @@ static void pim_msdp_sa_deref(struct pim_msdp_sa *sa,
if ((sa->flags & PIM_MSDP_SAF_LOCAL)) {
if (flags & PIM_MSDP_SAF_LOCAL) {
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP SA %s local reference removed",
- sa->sg_str);
- }
+ if (pim_msdp_log_sa_events(sa->pim))
+ zlog_info("MSDP SA %s local reference removed", sa->sg_str);
+
if (sa->pim->msdp.local_cnt)
--sa->pim->msdp.local_cnt;
}
@@ -346,10 +348,9 @@ static void pim_msdp_sa_deref(struct pim_msdp_sa *sa,
if (flags & PIM_MSDP_SAF_PEER) {
struct in_addr rp;
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP SA %s peer reference removed",
- sa->sg_str);
- }
+ if (pim_msdp_log_sa_events(sa->pim))
+ zlog_info("MSDP SA %s peer reference removed", sa->sg_str);
+
pim_msdp_sa_state_timer_setup(sa, false /* start */);
rp.s_addr = INADDR_ANY;
pim_msdp_sa_peer_ip_set(sa, NULL /* mp */, rp);
@@ -374,9 +375,17 @@ void pim_msdp_sa_ref(struct pim_instance *pim, struct pim_msdp_peer *mp,
pim_sgaddr *sg, struct in_addr rp)
{
struct pim_msdp_sa *sa;
- struct rp_info *rp_info;
struct prefix grp;
+ /* Check peer SA limit. */
+ if (mp && mp->sa_limit && mp->sa_cnt >= mp->sa_limit) {
+ if (pim_msdp_log_sa_events(pim))
+ zlog_debug("MSDP peer %pI4 reject SA (%pI4, %pI4): SA limit %u of %u",
+ &mp->peer, &sg->src, &sg->grp, mp->sa_cnt, mp->sa_limit);
+
+ return;
+ }
+
sa = pim_msdp_sa_add(pim, sg, rp);
if (!sa) {
return;
@@ -386,10 +395,8 @@ void pim_msdp_sa_ref(struct pim_instance *pim, struct pim_msdp_peer *mp,
if (mp) {
if (!(sa->flags & PIM_MSDP_SAF_PEER)) {
sa->flags |= PIM_MSDP_SAF_PEER;
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP SA %s added by peer",
- sa->sg_str);
- }
+ if (pim_msdp_log_sa_events(pim))
+ zlog_info("MSDP SA %s added by peer", sa->sg_str);
}
pim_msdp_sa_peer_ip_set(sa, mp, rp);
/* start/re-start the state timer to prevent cache expiry */
@@ -403,18 +410,12 @@ void pim_msdp_sa_ref(struct pim_instance *pim, struct pim_msdp_peer *mp,
if (!(sa->flags & PIM_MSDP_SAF_LOCAL)) {
sa->flags |= PIM_MSDP_SAF_LOCAL;
++sa->pim->msdp.local_cnt;
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP SA %s added locally",
- sa->sg_str);
- }
+ if (pim_msdp_log_sa_events(pim))
+ zlog_info("MSDP SA %s added locally", sa->sg_str);
+
/* send an immediate SA update to peers */
pim_addr_to_prefix(&grp, sa->sg.grp);
- rp_info = pim_rp_find_match_group(pim, &grp);
- if (rp_info) {
- sa->rp = rp_info->rp.rpf_addr;
- } else {
- sa->rp = pim->msdp.originator_id;
- }
+ pim_msdp_originator_id(pim, &grp, &sa->rp);
pim_msdp_pkt_sa_tx_one(sa);
}
sa->flags &= ~PIM_MSDP_SAF_STALE;
@@ -705,11 +706,14 @@ bool pim_msdp_peer_rpf_check(struct pim_msdp_peer *mp, struct in_addr rp)
}
/* check if the MSDP peer is the nexthop for the RP */
- if (pim_nexthop_lookup(mp->pim, &nexthop, rp, 0) &&
+ if (pim_nht_lookup(mp->pim, &nexthop, rp, 0) &&
nexthop.mrib_nexthop_addr.s_addr == mp->peer.s_addr) {
return true;
}
+ if (pim_msdp_log_sa_events(mp->pim))
+ zlog_info("MSDP peer %pI4 RPF failure for %pI4", &mp->peer, &rp);
+
return false;
}
@@ -744,7 +748,7 @@ static void pim_msdp_peer_state_chg_log(struct pim_msdp_peer *mp)
char state_str[PIM_MSDP_STATE_STRLEN];
pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
- zlog_debug("MSDP peer %s state chg to %s", mp->key_str, state_str);
+ zlog_info("MSDP peer %s state changed to %s", mp->key_str, state_str);
}
/* MSDP Connection State Machine actions (defined in RFC-3618:Sec-11.2) */
@@ -752,10 +756,13 @@ static void pim_msdp_peer_state_chg_log(struct pim_msdp_peer *mp)
* a tcp connection will be made */
static void pim_msdp_peer_connect(struct pim_msdp_peer *mp)
{
+ /* Stop here if we are shutdown. */
+ if (mp->pim->msdp.shutdown)
+ return;
+
mp->state = PIM_MSDP_CONNECTING;
- if (PIM_DEBUG_MSDP_EVENTS) {
+ if (pim_msdp_log_neighbor_events(mp->pim))
pim_msdp_peer_state_chg_log(mp);
- }
pim_msdp_peer_cr_timer_setup(mp, true /* start */);
}
@@ -763,10 +770,13 @@ static void pim_msdp_peer_connect(struct pim_msdp_peer *mp)
/* 11.2.A3: passive peer - just listen for connections */
static void pim_msdp_peer_listen(struct pim_msdp_peer *mp)
{
+ /* Stop here if we are shutdown. */
+ if (mp->pim->msdp.shutdown)
+ return;
+
mp->state = PIM_MSDP_LISTEN;
- if (PIM_DEBUG_MSDP_EVENTS) {
+ if (pim_msdp_log_neighbor_events(mp->pim))
pim_msdp_peer_state_chg_log(mp);
- }
/* this is interntionally asymmetric i.e. we set up listen-socket when
* the
@@ -790,9 +800,8 @@ void pim_msdp_peer_established(struct pim_msdp_peer *mp)
mp->state = PIM_MSDP_ESTABLISHED;
mp->uptime = pim_time_monotonic_sec();
- if (PIM_DEBUG_MSDP_EVENTS) {
+ if (pim_msdp_log_neighbor_events(mp->pim))
pim_msdp_peer_state_chg_log(mp);
- }
/* stop retry timer on active peers */
pim_msdp_peer_cr_timer_setup(mp, false /* start */);
@@ -816,9 +825,9 @@ void pim_msdp_peer_stop_tcp_conn(struct pim_msdp_peer *mp, bool chg_state)
++mp->est_flaps;
}
mp->state = PIM_MSDP_INACTIVE;
- if (PIM_DEBUG_MSDP_EVENTS) {
+
+ if (pim_msdp_log_neighbor_events(mp->pim))
pim_msdp_peer_state_chg_log(mp);
- }
}
if (PIM_DEBUG_MSDP_INTERNAL) {
@@ -851,10 +860,10 @@ void pim_msdp_peer_stop_tcp_conn(struct pim_msdp_peer *mp, bool chg_state)
/* RFC-3618:Sec-5.6 - stop the peer tcp connection and startover */
void pim_msdp_peer_reset_tcp_conn(struct pim_msdp_peer *mp, const char *rc_str)
{
- if (PIM_DEBUG_EVENTS) {
- zlog_debug("MSDP peer %s tcp reset %s", mp->key_str, rc_str);
- snprintf(mp->last_reset, sizeof(mp->last_reset), "%s", rc_str);
- }
+ if (pim_msdp_log_neighbor_events(mp->pim))
+ zlog_info("MSDP peer %s tcp reset %s", mp->key_str, rc_str);
+
+ snprintf(mp->last_reset, sizeof(mp->last_reset), "%s", rc_str);
/* close the connection and transition to listening or connecting */
pim_msdp_peer_stop_tcp_conn(mp, true /* chg_state */);
@@ -865,12 +874,6 @@ void pim_msdp_peer_reset_tcp_conn(struct pim_msdp_peer *mp, const char *rc_str)
}
}
-static void pim_msdp_peer_timer_expiry_log(struct pim_msdp_peer *mp,
- const char *timer_str)
-{
- zlog_debug("MSDP peer %s %s timer expired", mp->key_str, timer_str);
-}
-
/* RFC-3618:Sec-5.4 - peer hold timer */
static void pim_msdp_peer_hold_timer_cb(struct event *t)
{
@@ -878,17 +881,16 @@ static void pim_msdp_peer_hold_timer_cb(struct event *t)
mp = EVENT_ARG(t);
- if (PIM_DEBUG_MSDP_EVENTS) {
- pim_msdp_peer_timer_expiry_log(mp, "hold");
- }
+ if (pim_msdp_log_neighbor_events(mp->pim))
+ zlog_info("MSDP peer %s hold timer expired", mp->key_str);
if (mp->state != PIM_MSDP_ESTABLISHED) {
return;
}
- if (PIM_DEBUG_MSDP_EVENTS) {
+ if (pim_msdp_log_neighbor_events(mp->pim))
pim_msdp_peer_state_chg_log(mp);
- }
+
pim_msdp_peer_reset_tcp_conn(mp, "ht-expired");
}
@@ -910,9 +912,8 @@ static void pim_msdp_peer_ka_timer_cb(struct event *t)
mp = EVENT_ARG(t);
- if (PIM_DEBUG_MSDP_EVENTS) {
- pim_msdp_peer_timer_expiry_log(mp, "ka");
- }
+ if (pim_msdp_log_neighbor_events(mp->pim))
+ zlog_info("MSDP peer %s keep alive timer expired", mp->key_str);
pim_msdp_pkt_ka_tx(mp);
pim_msdp_peer_ka_timer_setup(mp, true /* start */);
@@ -970,9 +971,8 @@ static void pim_msdp_peer_cr_timer_cb(struct event *t)
mp = EVENT_ARG(t);
- if (PIM_DEBUG_MSDP_EVENTS) {
- pim_msdp_peer_timer_expiry_log(mp, "connect-retry");
- }
+ if (pim_msdp_log_neighbor_events(mp->pim))
+ zlog_info("MSDP peer %s connection retry timer expired", mp->key_str);
if (mp->state != PIM_MSDP_CONNECTING || PIM_MSDP_PEER_IS_LISTENER(mp)) {
return;
@@ -1012,16 +1012,6 @@ void pim_msdp_peer_pkt_txed(struct pim_msdp_peer *mp)
}
}
-static void pim_msdp_addr2su(union sockunion *su, struct in_addr addr)
-{
- sockunion_init(su);
- su->sin.sin_addr = addr;
- su->sin.sin_family = AF_INET;
-#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
- su->sin.sin_len = sizeof(struct sockaddr_in);
-#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
-}
-
/* 11.2.A1: create a new peer and transition state to listen or connecting */
struct pim_msdp_peer *pim_msdp_peer_add(struct pim_instance *pim,
const struct in_addr *peer,
@@ -1037,11 +1027,7 @@ struct pim_msdp_peer *pim_msdp_peer_add(struct pim_instance *pim,
mp->pim = pim;
mp->peer = *peer;
pim_inet4_dump("<peer?>", mp->peer, mp->key_str, sizeof(mp->key_str));
- pim_msdp_addr2su(&mp->su_peer, mp->peer);
mp->local = *local;
- /* XXX: originator_id setting needs to move to the mesh group */
- pim->msdp.originator_id = *local;
- pim_msdp_addr2su(&mp->su_local, mp->local);
if (mesh_group_name)
mp->mesh_group_name =
XSTRDUP(MTYPE_PIM_MSDP_MG_NAME, mesh_group_name);
@@ -1063,8 +1049,8 @@ struct pim_msdp_peer *pim_msdp_peer_add(struct pim_instance *pim,
mp = hash_get(pim->msdp.peer_hash, mp, hash_alloc_intern);
listnode_add_sort(pim->msdp.peer_list, mp);
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP peer %s created", mp->key_str);
+ if (pim_msdp_log_neighbor_events(pim)) {
+ zlog_info("MSDP peer %s created", mp->key_str);
pim_msdp_peer_state_chg_log(mp);
}
@@ -1078,8 +1064,7 @@ struct pim_msdp_peer *pim_msdp_peer_add(struct pim_instance *pim,
return mp;
}
-struct pim_msdp_peer *pim_msdp_peer_find(struct pim_instance *pim,
- struct in_addr peer_addr)
+struct pim_msdp_peer *pim_msdp_peer_find(const struct pim_instance *pim, struct in_addr peer_addr)
{
struct pim_msdp_peer lookup;
@@ -1129,9 +1114,8 @@ void pim_msdp_peer_del(struct pim_msdp_peer **mp)
listnode_delete((*mp)->pim->msdp.peer_list, *mp);
hash_release((*mp)->pim->msdp.peer_hash, *mp);
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP peer %s deleted", (*mp)->key_str);
- }
+ if (pim_msdp_log_neighbor_events((*mp)->pim))
+ zlog_info("MSDP peer %s deleted", (*mp)->key_str);
/* free up any associated memory */
pim_msdp_peer_free(*mp);
@@ -1206,10 +1190,8 @@ void pim_msdp_mg_free(struct pim_instance *pim, struct pim_msdp_mg **mgp)
for (ALL_LIST_ELEMENTS((*mgp)->mbr_list, n, nn, mbr))
pim_msdp_mg_mbr_del((*mgp), mbr);
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP mesh-group %s deleted",
- (*mgp)->mesh_group_name);
- }
+ if (pim_msdp_log_neighbor_events(pim))
+ zlog_info("MSDP mesh-group %s deleted", (*mgp)->mesh_group_name);
XFREE(MTYPE_PIM_MSDP_MG_NAME, (*mgp)->mesh_group_name);
@@ -1226,15 +1208,14 @@ struct pim_msdp_mg *pim_msdp_mg_new(struct pim_instance *pim,
struct pim_msdp_mg *mg;
mg = XCALLOC(MTYPE_PIM_MSDP_MG, sizeof(*mg));
-
+ mg->pim = pim;
mg->mesh_group_name = XSTRDUP(MTYPE_PIM_MSDP_MG_NAME, mesh_group_name);
mg->mbr_list = list_new();
mg->mbr_list->del = (void (*)(void *))pim_msdp_mg_mbr_free;
mg->mbr_list->cmp = (int (*)(void *, void *))pim_msdp_mg_mbr_comp;
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP mesh-group %s created", mg->mesh_group_name);
- }
+ if (pim_msdp_log_neighbor_events(pim))
+ zlog_info("MSDP mesh-group %s created", mg->mesh_group_name);
SLIST_INSERT_HEAD(&pim->msdp.mglist, mg, mg_entry);
@@ -1268,12 +1249,10 @@ void pim_msdp_mg_mbr_del(struct pim_msdp_mg *mg, struct pim_msdp_mg_mbr *mbr)
}
listnode_delete(mg->mbr_list, mbr);
- if (PIM_DEBUG_MSDP_EVENTS) {
- char ip_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<mbr?>", mbr->mbr_ip, ip_str, sizeof(ip_str));
- zlog_debug("MSDP mesh-group %s mbr %s deleted",
- mg->mesh_group_name, ip_str);
- }
+ if (pim_msdp_log_neighbor_events(mg->pim))
+ zlog_info("MSDP mesh-group %s neighbor %pI4 deleted", mg->mesh_group_name,
+ &mbr->mbr_ip);
+
pim_msdp_mg_mbr_free(mbr);
if (mg->mbr_cnt) {
--mg->mbr_cnt;
@@ -1290,10 +1269,9 @@ static void pim_msdp_src_del(struct pim_msdp_mg *mg)
if (mbr->mp)
pim_msdp_peer_del(&mbr->mp);
}
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP mesh-group %s src cleared",
- mg->mesh_group_name);
- }
+
+ if (pim_msdp_log_neighbor_events(mg->pim))
+ zlog_info("MSDP mesh-group %s source cleared", mg->mesh_group_name);
}
/*********************** MSDP feature APIs *********************************/
@@ -1305,6 +1283,22 @@ int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty)
char src_str[INET_ADDRSTRLEN];
int count = 0;
+ if (pim->msdp.hold_time != PIM_MSDP_PEER_HOLD_TIME ||
+ pim->msdp.keep_alive != PIM_MSDP_PEER_KA_TIME ||
+ pim->msdp.connection_retry != PIM_MSDP_PEER_CONNECT_RETRY_TIME) {
+ vty_out(vty, " msdp timers %u %u", pim->msdp.hold_time, pim->msdp.keep_alive);
+ if (pim->msdp.connection_retry != PIM_MSDP_PEER_CONNECT_RETRY_TIME)
+ vty_out(vty, " %u", pim->msdp.connection_retry);
+ vty_out(vty, "\n");
+ }
+
+ if (pim_msdp_log_neighbor_events(pim))
+ vty_out(vty, " msdp log neighbor-events\n");
+ if (pim_msdp_log_sa_events(pim))
+ vty_out(vty, " msdp log sa-events\n");
+ if (pim->msdp.shutdown)
+ vty_out(vty, " msdp shutdown\n");
+
if (SLIST_EMPTY(&pim->msdp.mglist))
return count;
@@ -1353,9 +1347,18 @@ bool pim_msdp_peer_config_write(struct vty *vty, struct pim_instance *pim)
vty_out(vty, " msdp peer %pI4 sa-filter %s out\n",
&mp->peer, mp->acl_out);
+ if (mp->sa_limit)
+ vty_out(vty, " msdp peer %pI4 sa-limit %u\n", &mp->peer, mp->sa_limit);
+
written = true;
}
+ if (pim->msdp.originator_id.s_addr != INADDR_ANY)
+ vty_out(vty, " msdp originator-id %pI4\n", &pim->msdp.originator_id);
+
+ if (pim->msdp.shutdown)
+ vty_out(vty, " msdp shutdown\n");
+
return written;
}
@@ -1395,6 +1398,11 @@ void pim_msdp_init(struct pim_instance *pim, struct event_loop *master)
pim->msdp.sa_list = list_new();
pim->msdp.sa_list->del = (void (*)(void *))pim_msdp_sa_free;
pim->msdp.sa_list->cmp = (int (*)(void *, void *))pim_msdp_sa_comp;
+
+ /* MSDP global timer defaults. */
+ pim->msdp.hold_time = PIM_MSDP_PEER_HOLD_TIME;
+ pim->msdp.keep_alive = PIM_MSDP_PEER_KA_TIME;
+ pim->msdp.connection_retry = PIM_MSDP_PEER_CONNECT_RETRY_TIME;
}
/* counterpart to MSDP init; XXX: unused currently */
@@ -1439,9 +1447,8 @@ void pim_msdp_mg_src_add(struct pim_instance *pim, struct pim_msdp_mg *mg,
/* No new address, disable everyone. */
if (ai->s_addr == INADDR_ANY) {
- if (PIM_DEBUG_MSDP_EVENTS)
- zlog_debug("MSDP mesh-group %s src unset",
- mg->mesh_group_name);
+ if (pim_msdp_log_neighbor_events(pim))
+ zlog_info("MSDP mesh-group %s source unset", mg->mesh_group_name);
return;
}
@@ -1450,9 +1457,8 @@ void pim_msdp_mg_src_add(struct pim_instance *pim, struct pim_msdp_mg *mg,
mbr->mp = pim_msdp_peer_add(pim, &mbr->mbr_ip, &mg->src_ip,
mg->mesh_group_name);
- if (PIM_DEBUG_MSDP_EVENTS)
- zlog_debug("MSDP mesh-group %s src %pI4 set",
- mg->mesh_group_name, &mg->src_ip);
+ if (pim_msdp_log_neighbor_events(pim))
+ zlog_info("MSDP mesh-group %s source %pI4 set", mg->mesh_group_name, &mg->src_ip);
}
struct pim_msdp_mg_mbr *pim_msdp_mg_mbr_add(struct pim_instance *pim,
@@ -1470,11 +1476,69 @@ struct pim_msdp_mg_mbr *pim_msdp_mg_mbr_add(struct pim_instance *pim,
mbr->mp = pim_msdp_peer_add(pim, &mbr->mbr_ip, &mg->src_ip,
mg->mesh_group_name);
- if (PIM_DEBUG_MSDP_EVENTS)
- zlog_debug("MSDP mesh-group %s mbr %pI4 created",
- mg->mesh_group_name, &mbr->mbr_ip);
+ if (pim_msdp_log_neighbor_events(pim))
+ zlog_info("MSDP mesh-group %s neighbor %pI4 created", mg->mesh_group_name,
+ &mbr->mbr_ip);
++mg->mbr_cnt;
return mbr;
}
+
+/* MSDP on RP needs to know if a source is registerable to this RP */
+static void pim_upstream_msdp_reg_timer(struct event *t)
+{
+ struct pim_upstream *up = EVENT_ARG(t);
+ struct pim_instance *pim = up->channel_oil->pim;
+
+ /* source is no longer active - pull the SA from MSDP's cache */
+ pim_msdp_sa_local_del(pim, &up->sg);
+}
+
+void pim_upstream_msdp_reg_timer_start(struct pim_upstream *up)
+{
+ EVENT_OFF(up->t_msdp_reg_timer);
+ event_add_timer(router->master, pim_upstream_msdp_reg_timer, up, PIM_MSDP_REG_RXED_PERIOD,
+ &up->t_msdp_reg_timer);
+
+ pim_msdp_sa_local_update(up);
+}
+
+void pim_msdp_shutdown(struct pim_instance *pim, bool state)
+{
+ struct pim_msdp_peer *peer;
+ struct listnode *node;
+
+ /* Same value nothing to do. */
+ if (pim->msdp.shutdown == state)
+ return;
+
+ if (state) {
+ pim->msdp.shutdown = true;
+
+ for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, node, peer)) {
+ /* Stop the tcp connection and shutdown all timers */
+ pim_msdp_peer_stop_tcp_conn(peer, true);
+
+ /* Stop listening socket if any. */
+ event_cancel(&peer->auth_listen_ev);
+ if (peer->auth_listen_sock != -1)
+ close(peer->auth_listen_sock);
+
+ /* Disable and remove listener flag. */
+ UNSET_FLAG(pim->msdp.flags, PIM_MSDPF_ENABLE | PIM_MSDPF_LISTENER);
+ }
+ } else {
+ pim->msdp.shutdown = false;
+
+ for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, node, peer)) {
+ /* Start connection again. */
+ if (PIM_MSDP_PEER_IS_LISTENER(peer))
+ pim_msdp_peer_listen(peer);
+ else
+ pim_msdp_peer_connect(peer);
+
+ SET_FLAG(pim->msdp.flags, PIM_MSDPF_ENABLE);
+ }
+ }
+}