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.c85
1 files changed, 73 insertions, 12 deletions
diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c
index ae887b2482..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,6 +45,26 @@ 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);
+void pim_msdp_originator_id(struct pim_instance *pim, const struct prefix *group,
+ struct in_addr *originator_id)
+{
+ 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)
@@ -356,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;
@@ -388,12 +415,7 @@ void pim_msdp_sa_ref(struct pim_instance *pim, struct pim_msdp_peer *mp,
/* 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;
@@ -684,7 +706,7 @@ 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;
}
@@ -1006,8 +1028,6 @@ struct pim_msdp_peer *pim_msdp_peer_add(struct pim_instance *pim,
mp->peer = *peer;
pim_inet4_dump("<peer?>", mp->peer, mp->key_str, sizeof(mp->key_str));
mp->local = *local;
- /* XXX: originator_id setting needs to move to the mesh group */
- pim->msdp.originator_id = *local;
if (mesh_group_name)
mp->mesh_group_name =
XSTRDUP(MTYPE_PIM_MSDP_MG_NAME, mesh_group_name);
@@ -1263,10 +1283,21 @@ 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;
@@ -1316,9 +1347,15 @@ 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");
@@ -1361,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 */
@@ -1443,6 +1485,25 @@ struct pim_msdp_mg_mbr *pim_msdp_mg_mbr_add(struct pim_instance *pim,
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;