diff options
author | Adriano Marto Reis <adrianomarto@gmail.com> | 2020-07-10 00:56:24 +0200 |
---|---|---|
committer | Donald Sharp <sharpd@nvidia.com> | 2020-10-06 14:11:24 +0200 |
commit | 9fbd9fc48f7c620dc505ba27319b86035d7dc142 (patch) | |
tree | 84b11ff4784c2ae8800f55a019d24c13a027f7d0 /pimd/pim_msdp_packet.c | |
parent | Merge pull request #6904 from chiragshah6/yang_nb6 (diff) | |
download | frr-9fbd9fc48f7c620dc505ba27319b86035d7dc142.tar.xz frr-9fbd9fc48f7c620dc505ba27319b86035d7dc142.zip |
pimd: MSDP SA forwarding
* If the MSDP peer receives the SA from a non-RPF peer towards the
originating RP, it will drop the message.
* SA messages are forwarded away from the RP address only.
* SA messages are not forwarded within the mesh group.
* Preventing the MSDP connection from being dropped due to RPF check
failure (RFC3618, section 13 "MSDP Error Handling")
Signed-off-by: Adriano Marto Reis <adrianomarto@gmail.com>
Signed-off-by: Adriano Reis <areis@barrukka.local>
Diffstat (limited to 'pimd/pim_msdp_packet.c')
-rw-r--r-- | pimd/pim_msdp_packet.c | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/pimd/pim_msdp_packet.c b/pimd/pim_msdp_packet.c index 39e39b955..4aaf0f53d 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); |