diff options
Diffstat (limited to 'pimd/pim_msdp.c')
| -rw-r--r-- | pimd/pim_msdp.c | 85 |
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; |
