diff --git a/doc/user/pim.rst b/doc/user/pim.rst index d5899ab455..b33ca3f2f4 100644 --- a/doc/user/pim.rst +++ b/doc/user/pim.rst @@ -337,6 +337,42 @@ caution. Most of the time this will not be necessary. Insert into the Multicast Rib Route A.B.C.D/M using the specified INTERFACE. The distance can be specified as well if desired. +.. _msdp-configuration + +Multicast Source Discovery Protocol (MSDP) Configuration +==================== + +.. index:: ip msdp mesh-group [WORD] member A.B.C.D +.. clicmd:: ip msdp mesh-group [WORD] member A.B.C.D + + Include a MSDP peer as a member of a MSDP mesh-group. + +.. index:: ip msdp mesh-group [WORD] source A.B.C.D +.. clicmd:: ip msdp mesh-group [WORD] source A.B.C.D + + Create a MSDP mesh-group, defining a name for it and an associated local source + address. + +.. index:: ip msdp peer A.B.C.D source A.B.C.D +.. clicmd:: ip msdp peer A.B.C.D source A.B.C.D + + Establish a MSDP connection with a peer. + +.. index:: no ip msdp mesh-group [WORD] member A.B.C.D +.. clicmd:: no ip msdp mesh-group [WORD] member A.B.C.D + + Remove a MSDP peer member from a MSDP mesh-group. + +.. index:: no ip msdp mesh-group [WORD] source A.B.C.D +.. clicmd:: no ip msdp mesh-group [WORD] source A.B.C.D + + Delete a MSDP mesh-group. + +.. index:: no ip msdp peer A.B.C.D +.. clicmd:: no ip msdp peer A.B.C.D + + Delete a MSDP peer connection. + .. _show-pim-information: Show PIM Information @@ -422,6 +458,19 @@ cause great confusion. Display total number of S,G mroutes and number of S,G mroutes installed into the kernel for all vrfs. +.. index:: show ip msdp mesh-group +.. clicmd:: show ip msdp mesh-group + + Display the configured mesh-groups, the local address associated with each + mesh-group, the peer members included in each mesh-group, and their status. + +.. index:: show ip msdp peer +.. clicmd:: show ip msdp peer + + Display information about the MSDP peers. That includes the peer address, + the local address used to establish the connection to the peer, the + connection status, and the number of active sources. + .. index:: show ip pim assert .. clicmd:: show ip pim assert diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index db3f0b8b23..6256774464 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -9694,7 +9694,7 @@ static int ip_msdp_peer_cmd_worker(struct pim_instance *pim, struct vty *vty, return ret; } -DEFUN_HIDDEN (ip_msdp_peer, +DEFUN (ip_msdp_peer, ip_msdp_peer_cmd, "ip msdp peer A.B.C.D source A.B.C.D", IP_STR @@ -9735,7 +9735,7 @@ static int ip_no_msdp_peer_cmd_worker(struct pim_instance *pim, struct vty *vty, return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS; } -DEFUN_HIDDEN (no_ip_msdp_peer, +DEFUN (no_ip_msdp_peer, no_ip_msdp_peer_cmd, "no ip msdp peer A.B.C.D", NO_STR diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c index b42092a464..7336cdfef8 100644 --- a/pimd/pim_msdp.c +++ b/pimd/pim_msdp.c @@ -423,6 +423,7 @@ void pim_msdp_sa_ref(struct pim_instance *pim, struct pim_msdp_peer *mp, sa->sg_str); } /* send an immediate SA update to peers */ + sa->rp = pim->msdp.originator_id; pim_msdp_pkt_sa_tx_one(sa); } sa->flags &= ~PIM_MSDP_SAF_STALE; @@ -721,10 +722,18 @@ static int pim_msdp_sa_comp(const void *p1, const void *p2) /* XXX: this can use a bit of refining and extensions */ bool pim_msdp_peer_rpf_check(struct pim_msdp_peer *mp, struct in_addr rp) { + struct pim_nexthop nexthop; + if (mp->peer.s_addr == rp.s_addr) { return true; } + /* check if the MSDP peer is the nexthop for the RP */ + if (pim_nexthop_lookup(mp->pim, &nexthop, rp, 0) + && nexthop.mrib_nexthop_addr.u.prefix4.s_addr == mp->peer.s_addr) { + return true; + } + return false; } diff --git a/pimd/pim_msdp_packet.c b/pimd/pim_msdp_packet.c index 39e39b9557..4aaf0f53d1 100644 --- a/pimd/pim_msdp_packet.c +++ b/pimd/pim_msdp_packet.c @@ -348,7 +348,8 @@ static void pim_msdp_pkt_sa_push(struct pim_instance *pim, } } -static int pim_msdp_pkt_sa_fill_hdr(struct pim_instance *pim, int local_cnt) +static int pim_msdp_pkt_sa_fill_hdr(struct pim_instance *pim, int local_cnt, + struct in_addr rp) { int curr_tlv_ecnt; @@ -361,7 +362,7 @@ static int pim_msdp_pkt_sa_fill_hdr(struct pim_instance *pim, int local_cnt) stream_putw(pim->msdp.work_obuf, PIM_MSDP_SA_ENTRY_CNT2SIZE(curr_tlv_ecnt)); stream_putc(pim->msdp.work_obuf, curr_tlv_ecnt); - stream_put_ipv4(pim->msdp.work_obuf, pim->msdp.originator_id.s_addr); + stream_put_ipv4(pim->msdp.work_obuf, rp.s_addr); return local_cnt; } @@ -387,7 +388,8 @@ static void pim_msdp_pkt_sa_gen(struct pim_instance *pim, zlog_debug(" sa gen %d", local_cnt); } - local_cnt = pim_msdp_pkt_sa_fill_hdr(pim, local_cnt); + local_cnt = pim_msdp_pkt_sa_fill_hdr(pim, local_cnt, + pim->msdp.originator_id); for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) { if (!(sa->flags & PIM_MSDP_SAF_LOCAL)) { @@ -408,7 +410,8 @@ static void pim_msdp_pkt_sa_gen(struct pim_instance *pim, zlog_debug(" sa gen for remainder %d", local_cnt); } - local_cnt = pim_msdp_pkt_sa_fill_hdr(pim, local_cnt); + local_cnt = pim_msdp_pkt_sa_fill_hdr( + pim, local_cnt, pim->msdp.originator_id); } } @@ -441,7 +444,7 @@ void pim_msdp_pkt_sa_tx(struct pim_instance *pim) void pim_msdp_pkt_sa_tx_one(struct pim_msdp_sa *sa) { - pim_msdp_pkt_sa_fill_hdr(sa->pim, 1 /* cnt */); + pim_msdp_pkt_sa_fill_hdr(sa->pim, 1 /* cnt */, sa->rp); pim_msdp_pkt_sa_fill_one(sa); pim_msdp_pkt_sa_push(sa->pim, NULL); pim_msdp_pkt_sa_tx_done(sa->pim); @@ -454,6 +457,24 @@ void pim_msdp_pkt_sa_tx_to_one_peer(struct pim_msdp_peer *mp) pim_msdp_pkt_sa_tx_done(mp->pim); } +void pim_msdp_pkt_sa_tx_one_to_one_peer(struct pim_msdp_peer *mp, + struct in_addr rp, struct prefix_sg sg) +{ + struct pim_msdp_sa sa; + + /* Fills the SA header. */ + pim_msdp_pkt_sa_fill_hdr(mp->pim, 1, rp); + + /* Fills the message contents. */ + sa.pim = mp->pim; + sa.sg = sg; + pim_msdp_pkt_sa_fill_one(&sa); + + /* Pushes the message. */ + pim_msdp_pkt_sa_push(sa.pim, mp); + pim_msdp_pkt_sa_tx_done(sa.pim); +} + static void pim_msdp_pkt_rxed_with_fatal_error(struct pim_msdp_peer *mp) { pim_msdp_peer_reset_tcp_conn(mp, "invalid-pkt-rx"); @@ -473,6 +494,8 @@ static void pim_msdp_pkt_sa_rx_one(struct pim_msdp_peer *mp, struct in_addr rp) { int prefix_len; struct prefix_sg sg; + struct listnode *peer_node; + struct pim_msdp_peer *peer; /* just throw away the three reserved bytes */ stream_get3(mp->ibuf); @@ -493,6 +516,18 @@ static void pim_msdp_pkt_sa_rx_one(struct pim_msdp_peer *mp, struct in_addr rp) zlog_debug(" sg %s", pim_str_sg_dump(&sg)); } pim_msdp_sa_ref(mp->pim, mp, &sg, rp); + + /* Forwards the SA to the peers that are not in the RPF to the RP nor in + * the same mesh group as the peer from which we received the message. + * If the message group is not set, i.e. "default", then we assume that + * the message must be forwarded.*/ + for (ALL_LIST_ELEMENTS_RO(mp->pim->msdp.peer_list, peer_node, peer)) { + if (!pim_msdp_peer_rpf_check(peer, rp) + && (strcmp(mp->mesh_group_name, peer->mesh_group_name) + || !strcmp(mp->mesh_group_name, "default"))) { + pim_msdp_pkt_sa_tx_one_to_one_peer(peer, rp, sg); + } + } } static void pim_msdp_pkt_sa_rx(struct pim_msdp_peer *mp, int len) @@ -510,10 +545,9 @@ static void pim_msdp_pkt_sa_rx(struct pim_msdp_peer *mp, int len) entry_cnt = stream_getc(mp->ibuf); /* some vendors include the actual multicast data in the tlv (at the - * end). - * we will ignore such data. in the future we may consider pushing it - * down - * the RPT */ + * end). we will ignore such data. in the future we may consider pushing + * it down the RPT + */ if (len < PIM_MSDP_SA_ENTRY_CNT2SIZE(entry_cnt)) { pim_msdp_pkt_rxed_with_fatal_error(mp); return; @@ -526,6 +560,8 @@ static void pim_msdp_pkt_sa_rx(struct pim_msdp_peer *mp, int len) zlog_debug(" entry_cnt %d rp %s", entry_cnt, rp_str); } + pim_msdp_peer_pkt_rxed(mp); + if (!pim_msdp_peer_rpf_check(mp, rp)) { /* if peer-RPF check fails don't process the packet any further */ @@ -535,8 +571,6 @@ static void pim_msdp_pkt_sa_rx(struct pim_msdp_peer *mp, int len) return; } - pim_msdp_peer_pkt_rxed(mp); - /* update SA cache */ for (i = 0; i < entry_cnt; ++i) { pim_msdp_pkt_sa_rx_one(mp, rp); diff --git a/pimd/pim_msdp_packet.h b/pimd/pim_msdp_packet.h index d922fa50df..f5af8d1140 100644 --- a/pimd/pim_msdp_packet.h +++ b/pimd/pim_msdp_packet.h @@ -67,5 +67,7 @@ int pim_msdp_read(struct thread *thread); void pim_msdp_pkt_sa_tx(struct pim_instance *pim); void pim_msdp_pkt_sa_tx_one(struct pim_msdp_sa *sa); void pim_msdp_pkt_sa_tx_to_one_peer(struct pim_msdp_peer *mp); +void pim_msdp_pkt_sa_tx_one_to_one_peer(struct pim_msdp_peer *mp, + struct in_addr rp, struct prefix_sg sg); #endif