3 * Copyright (C) 2015 Cumulus Networks, Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31 #include "pim_mroute.h"
32 #include "pim_iface.h"
37 #include "pim_register.h"
38 #include "pim_upstream.h"
42 #include "pim_zebra.h"
46 #include "pim_vxlan.h"
49 struct thread
*send_test_packet_timer
= NULL
;
51 void pim_register_join(struct pim_upstream
*up
)
53 struct pim_instance
*pim
= up
->channel_oil
->pim
;
55 if (pim_is_grp_ssm(pim
, up
->sg
.grp
)) {
56 if (PIM_DEBUG_PIM_EVENTS
)
57 zlog_debug("%s register setup skipped as group is SSM",
62 pim_channel_add_oif(up
->channel_oil
, pim
->regiface
,
63 PIM_OIF_FLAG_PROTO_PIM
, __func__
);
64 up
->reg_state
= PIM_REG_JOIN
;
65 pim_vxlan_update_sg_reg_state(pim
, up
, true);
68 void pim_register_stop_send(struct interface
*ifp
, pim_sgaddr
*sg
, pim_addr src
,
71 struct pim_interface
*pinfo
;
72 unsigned char buffer
[10000];
73 unsigned int b1length
= 0;
77 if (PIM_DEBUG_PIM_REG
) {
78 zlog_debug("Sending Register stop for %pSG to %pPA on %s", sg
,
79 &originator
, ifp
->name
);
82 memset(buffer
, 0, 10000);
83 b1
= (uint8_t *)buffer
+ PIM_MSG_REGISTER_STOP_LEN
;
85 length
= pim_encode_addr_group(b1
, AFI_IP
, 0, 0, sg
->grp
);
89 length
= pim_encode_addr_ucast(b1
, sg
->src
);
92 pim_msg_build_header(src
, originator
, buffer
,
93 b1length
+ PIM_MSG_REGISTER_STOP_LEN
,
94 PIM_MSG_TYPE_REG_STOP
, false);
96 pinfo
= (struct pim_interface
*)ifp
->info
;
98 if (PIM_DEBUG_PIM_TRACE
)
99 zlog_debug("%s: No pinfo!", __func__
);
102 if (pim_msg_send(pinfo
->pim_sock_fd
, src
, originator
, buffer
,
103 b1length
+ PIM_MSG_REGISTER_STOP_LEN
, ifp
)) {
104 if (PIM_DEBUG_PIM_TRACE
) {
106 "%s: could not send PIM register stop message on interface %s",
107 __func__
, ifp
->name
);
111 if (!pinfo
->pim_passive_enable
)
112 ++pinfo
->pim_ifstat_reg_stop_send
;
115 static void pim_reg_stop_upstream(struct pim_instance
*pim
,
116 struct pim_upstream
*up
)
118 switch (up
->reg_state
) {
123 up
->reg_state
= PIM_REG_PRUNE
;
124 pim_channel_del_oif(up
->channel_oil
, pim
->regiface
,
125 PIM_OIF_FLAG_PROTO_PIM
, __func__
);
126 pim_upstream_start_register_stop_timer(up
, 0);
127 pim_vxlan_update_sg_reg_state(pim
, up
, false);
129 case PIM_REG_JOIN_PENDING
:
130 up
->reg_state
= PIM_REG_PRUNE
;
131 pim_upstream_start_register_stop_timer(up
, 0);
136 int pim_register_stop_recv(struct interface
*ifp
, uint8_t *buf
, int buf_size
)
138 struct pim_interface
*pim_ifp
= ifp
->info
;
139 struct pim_instance
*pim
= pim_ifp
->pim
;
140 struct pim_upstream
*up
= NULL
;
144 struct listnode
*up_node
;
145 struct pim_upstream
*child
;
146 bool wrong_af
= false;
147 bool handling_star
= false;
150 if (pim_ifp
->pim_passive_enable
) {
151 if (PIM_DEBUG_PIM_PACKETS
)
153 "skip receiving PIM message on passive interface %s",
158 ++pim_ifp
->pim_ifstat_reg_stop_recv
;
160 memset(&sg
, 0, sizeof(sg
));
161 l
= pim_parse_addr_group(&sg
, buf
, buf_size
);
164 pim_parse_addr_ucast(&sg
.src
, buf
, buf_size
, &wrong_af
);
167 zlog_err("invalid AF in Register-Stop on %s", ifp
->name
);
172 if (PIM_DEBUG_PIM_REG
)
173 zlog_debug("Received Register stop for %pSG", &sg
);
175 rp
= RP(pim_ifp
->pim
, sg
.grp
);
177 rpf_addr
= pim_addr_from_prefix(&rp
->rpf_addr
);
178 /* As per RFC 7761, Section 4.9.4:
179 * A special wildcard value consisting of an address field of
180 * all zeros can be used to indicate any source.
182 if ((pim_addr_cmp(sg
.src
, rpf_addr
) == 0) ||
183 pim_addr_is_any(sg
.src
)) {
184 handling_star
= true;
185 sg
.src
= PIMADDR_ANY
;
191 * Handling Register-Stop(*,G) Messages at the DR:
192 * A Register-Stop(*,G) should be treated as a
193 * Register-Stop(S,G) for all (S,G) Register state
194 * machines that are not in the NoInfo state.
196 up
= pim_upstream_find(pim
, &sg
);
199 * If the upstream find actually found a particular
200 * S,G then we *know* that the following for loop
201 * is not going to execute and this is ok
203 for (ALL_LIST_ELEMENTS_RO(up
->sources
, up_node
, child
)) {
204 if (PIM_DEBUG_PIM_REG
)
205 zlog_debug("Executing Reg stop for %s",
208 pim_reg_stop_upstream(pim
, child
);
211 if (PIM_DEBUG_PIM_REG
)
212 zlog_debug("Executing Reg stop for %s", up
->sg_str
);
213 pim_reg_stop_upstream(pim
, up
);
218 * Unfortunately pim was unable to find a *,G
219 * but pim may still actually have individual
220 * S,G's that need to be processed. In that
221 * case pim must do the expensive walk to find
224 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
225 if (pim_addr_cmp(up
->sg
.grp
, sg
.grp
) == 0) {
226 if (PIM_DEBUG_PIM_REG
)
227 zlog_debug("Executing Reg stop for %s",
229 pim_reg_stop_upstream(pim
, up
);
237 void pim_register_send(const uint8_t *buf
, int buf_size
, pim_addr src
,
238 struct pim_rpf
*rpg
, int null_register
,
239 struct pim_upstream
*up
)
241 unsigned char buffer
[10000];
243 struct pim_interface
*pinfo
;
244 struct interface
*ifp
;
245 pim_addr dst
= pim_addr_from_prefix(&rpg
->rpf_addr
);
247 if (PIM_DEBUG_PIM_REG
) {
248 zlog_debug("Sending %s %sRegister Packet to %pPA", up
->sg_str
,
249 null_register
? "NULL " : "", &dst
);
252 ifp
= rpg
->source_nexthop
.interface
;
254 if (PIM_DEBUG_PIM_REG
)
255 zlog_debug("%s: No interface to transmit register on",
259 pinfo
= (struct pim_interface
*)ifp
->info
;
261 if (PIM_DEBUG_PIM_REG
)
263 "%s: Interface: %s not configured for pim to transmit on!",
264 __func__
, ifp
->name
);
268 if (PIM_DEBUG_PIM_REG
) {
269 zlog_debug("%s: Sending %s %sRegister Packet to %pPA on %s",
270 __func__
, up
->sg_str
, null_register
? "NULL " : "",
274 memset(buffer
, 0, 10000);
275 b1
= buffer
+ PIM_MSG_HEADER_LEN
;
276 *b1
|= null_register
<< 6;
277 b1
= buffer
+ PIM_MSG_REGISTER_LEN
;
279 memcpy(b1
, (const unsigned char *)buf
, buf_size
);
281 pim_msg_build_header(src
, dst
, buffer
, buf_size
+ PIM_MSG_REGISTER_LEN
,
282 PIM_MSG_TYPE_REGISTER
, false);
284 if (!pinfo
->pim_passive_enable
)
285 ++pinfo
->pim_ifstat_reg_send
;
287 if (pim_msg_send(pinfo
->pim_sock_fd
, src
, dst
, buffer
,
288 buf_size
+ PIM_MSG_REGISTER_LEN
, ifp
)) {
289 if (PIM_DEBUG_PIM_TRACE
) {
291 "%s: could not send PIM register message on interface %s",
292 __func__
, ifp
->name
);
299 void pim_null_register_send(struct pim_upstream
*up
)
302 struct pim_interface
*pim_ifp
;
306 pim_ifp
= up
->rpf
.source_nexthop
.interface
->info
;
308 if (PIM_DEBUG_PIM_TRACE
)
310 "%s: Cannot send null-register for %s no valid iif",
311 __func__
, up
->sg_str
);
315 rpg
= RP(pim_ifp
->pim
, up
->sg
.grp
);
317 if (PIM_DEBUG_PIM_TRACE
)
319 "%s: Cannot send null-register for %s no RPF to the RP",
320 __func__
, up
->sg_str
);
324 memset(&ip_hdr
, 0, sizeof(ip_hdr
));
325 ip_hdr
.ip_p
= PIM_IP_PROTO_PIM
;
328 ip_hdr
.ip_src
= up
->sg
.src
;
329 ip_hdr
.ip_dst
= up
->sg
.grp
;
330 ip_hdr
.ip_len
= htons(20);
332 /* checksum is broken */
333 src
= pim_ifp
->primary_address
;
334 if (PIM_UPSTREAM_FLAG_TEST_SRC_VXLAN_ORIG(up
->flags
)) {
335 if (!pim_vxlan_get_register_src(pim_ifp
->pim
, up
, &src
)) {
336 if (PIM_DEBUG_PIM_TRACE
)
338 "%s: Cannot send null-register for %s vxlan-aa PIP unavailable",
339 __func__
, up
->sg_str
);
343 pim_register_send((uint8_t *)&ip_hdr
, sizeof(struct ip
), src
, rpg
, 1,
347 void pim_null_register_send(struct pim_upstream
*up
)
349 struct ip6_hdr ip6_hdr
;
350 struct pim_msg_header pim_msg_header
;
351 struct pim_interface
*pim_ifp
;
354 unsigned char buffer
[sizeof(ip6_hdr
) + sizeof(pim_msg_header
)];
357 pim_ifp
= up
->rpf
.source_nexthop
.interface
->info
;
359 if (PIM_DEBUG_PIM_TRACE
)
361 "Cannot send null-register for %s no valid iif",
366 rpg
= RP(pim_ifp
->pim
, up
->sg
.grp
);
368 if (PIM_DEBUG_PIM_TRACE
)
370 "Cannot send null-register for %s no RPF to the RP",
375 memset(&ip6_hdr
, 0, sizeof(ip6_hdr
));
376 ip6_hdr
.ip6_nxt
= PIM_IP_PROTO_PIM
;
377 ip6_hdr
.ip6_plen
= PIM_MSG_HEADER_LEN
;
378 ip6_hdr
.ip6_vfc
= 6 << 4;
379 ip6_hdr
.ip6_hlim
= MAXTTL
;
380 ip6_hdr
.ip6_src
= up
->sg
.src
;
381 ip6_hdr
.ip6_dst
= up
->sg
.grp
;
383 memset(buffer
, 0, (sizeof(ip6_hdr
) + sizeof(pim_msg_header
)));
384 memcpy(buffer
, &ip6_hdr
, sizeof(ip6_hdr
));
386 pim_msg_header
.ver
= 0;
387 pim_msg_header
.type
= 0;
388 pim_msg_header
.reserved
= 0;
390 pim_msg_header
.checksum
= 0;
394 ph
.ulpl
= htonl(PIM_MSG_HEADER_LEN
);
395 ph
.next_hdr
= IPPROTO_PIM
;
396 pim_msg_header
.checksum
=
397 in_cksum_with_ph6(&ph
, &pim_msg_header
, PIM_MSG_HEADER_LEN
);
399 memcpy(buffer
+ sizeof(ip6_hdr
), &pim_msg_header
, PIM_MSG_HEADER_LEN
);
402 src
= pim_ifp
->primary_address
;
403 pim_register_send((uint8_t *)buffer
,
404 sizeof(ip6_hdr
) + PIM_MSG_HEADER_LEN
, src
, rpg
, 1,
410 * 4.4.2 Receiving Register Messages at the RP
412 * When an RP receives a Register message, the course of action is
413 * decided according to the following pseudocode:
415 * packet_arrives_on_rp_tunnel( pkt ) {
416 * if( outer.dst is not one of my addresses ) {
417 * drop the packet silently.
418 * # Note: this may be a spoofing attempt
420 * if( I_am_RP(G) AND outer.dst == RP(G) ) {
421 * sentRegisterStop = false;
422 * if ( register.borderbit == true ) {
423 * if ( PMBR(S,G) == unknown ) {
424 * PMBR(S,G) = outer.src
425 * } else if ( outer.src != PMBR(S,G) ) {
426 * send Register-Stop(S,G) to outer.src
427 * drop the packet silently.
430 * if ( SPTbit(S,G) OR
431 * ( SwitchToSptDesired(S,G) AND
432 * ( inherited_olist(S,G) == NULL ))) {
433 * send Register-Stop(S,G) to outer.src
434 * sentRegisterStop = true;
436 * if ( SPTbit(S,G) OR SwitchToSptDesired(S,G) ) {
437 * if ( sentRegisterStop == true ) {
438 * set KeepaliveTimer(S,G) to RP_Keepalive_Period;
440 * set KeepaliveTimer(S,G) to Keepalive_Period;
443 * if( !SPTbit(S,G) AND ! pkt.NullRegisterBit ) {
444 * decapsulate and forward the inner packet to
445 * inherited_olist(S,G,rpt) # Note (+)
448 * send Register-Stop(S,G) to outer.src
453 int pim_register_recv(struct interface
*ifp
, pim_addr dest_addr
,
454 pim_addr src_addr
, uint8_t *tlv_buf
, int tlv_buf_size
)
456 int sentRegisterStop
= 0;
461 struct pim_interface
*pim_ifp
= ifp
->info
;
462 struct pim_instance
*pim
= pim_ifp
->pim
;
465 if (pim_ifp
->pim_passive_enable
) {
466 if (PIM_DEBUG_PIM_PACKETS
)
468 "skip receiving PIM message on passive interface %s",
473 #define PIM_MSG_REGISTER_BIT_RESERVED_LEN 4
474 ip_hdr
= (tlv_buf
+ PIM_MSG_REGISTER_BIT_RESERVED_LEN
);
476 if (!if_address_is_local(&dest_addr
, PIM_AF
, pim
->vrf
->vrf_id
)) {
477 if (PIM_DEBUG_PIM_REG
)
479 "%s: Received Register message for destination address: %pPA that I do not own",
480 __func__
, &dest_addr
);
484 ++pim_ifp
->pim_ifstat_reg_recv
;
487 * Please note this is not drawn to get the correct bit/data size
489 * The entirety of the REGISTER packet looks like this:
490 * -------------------------------------------------------------
491 * | Ver | Type | Reserved | Checksum |
492 * |-----------------------------------------------------------|
494 * |-----------------------------------------------------------|
497 * | Packet |--------------------------------------------------|
502 * tlv_buf when received from the caller points at the B bit
503 * We need to know the inner source and dest
505 bits
= (uint32_t *)tlv_buf
;
508 * tlv_buf points to the start of the |B|N|... Reserved
509 * Line above. So we need to add 4 bytes to get to the
510 * start of the actual Encapsulated data.
512 memset(&sg
, 0, sizeof(sg
));
513 sg
= pim_sgaddr_from_iphdr(ip_hdr
);
517 * According to RFC section 4.9.3, If Dummy PIM Header is included
518 * in NULL Register as a payload there would be two PIM headers.
519 * The inner PIM Header's checksum field should also be validated
520 * in addition to the outer PIM Header's checksum. Validation of
521 * inner PIM header checksum is done here.
523 if ((*bits
& PIM_REGISTER_NR_BIT
) &&
524 ((tlv_buf_size
- PIM_MSG_REGISTER_BIT_RESERVED_LEN
) >
525 (int)sizeof(struct ip6_hdr
))) {
526 uint16_t computed_checksum
;
527 uint16_t received_checksum
;
529 struct pim_msg_header
*header
;
531 header
= (struct pim_msg_header
533 PIM_MSG_REGISTER_BIT_RESERVED_LEN
+
534 sizeof(struct ip6_hdr
));
537 ph
.ulpl
= htonl(PIM_MSG_HEADER_LEN
);
538 ph
.next_hdr
= IPPROTO_PIM
;
540 received_checksum
= header
->checksum
;
542 header
->checksum
= 0;
543 computed_checksum
= in_cksum_with_ph6(
544 &ph
, header
, htonl(PIM_MSG_HEADER_LEN
));
546 if (computed_checksum
!= received_checksum
) {
547 if (PIM_DEBUG_PIM_PACKETS
)
549 "Ignoring Null Register message%pSG from %pPA due to bad checksum in Encapsulated dummy PIM header",
555 i_am_rp
= I_am_RP(pim
, sg
.grp
);
557 if (PIM_DEBUG_PIM_REG
)
559 "Received Register message%pSG from %pPA on %s, rp: %d",
560 &sg
, &src_addr
, ifp
->name
, i_am_rp
);
562 if (pim_is_grp_ssm(pim_ifp
->pim
, sg
.grp
)) {
563 if (pim_addr_is_any(sg
.src
)) {
565 "%s: Received Register message for Group(%pPA) is now in SSM, dropping the packet",
567 /* Drop Packet Silently */
572 rp_addr
= pim_addr_from_prefix(&(RP(pim
, sg
.grp
))->rpf_addr
);
573 if (i_am_rp
&& (!pim_addr_cmp(dest_addr
, rp_addr
))) {
574 sentRegisterStop
= 0;
576 if (pim
->register_plist
) {
577 struct prefix_list
*plist
;
580 plist
= prefix_list_lookup(PIM_AFI
,
581 pim
->register_plist
);
583 pim_addr_to_prefix(&src
, sg
.src
);
585 if (prefix_list_apply(plist
, &src
) == PREFIX_DENY
) {
586 pim_register_stop_send(ifp
, &sg
, dest_addr
,
588 if (PIM_DEBUG_PIM_PACKETS
)
590 "%s: Sending register-stop to %pPA for %pSG due to prefix-list denial, dropping packet",
591 __func__
, &src_addr
, &sg
);
597 if (*bits
& PIM_REGISTER_BORDER_BIT
) {
598 pim_addr pimbr
= pim_br_get_pmbr(&sg
);
599 if (PIM_DEBUG_PIM_PACKETS
)
601 "%s: Received Register message with Border bit set",
604 if (pim_addr_is_any(pimbr
))
605 pim_br_set_pmbr(&sg
, src_addr
);
606 else if (pim_addr_cmp(src_addr
, pimbr
)) {
607 pim_register_stop_send(ifp
, &sg
, dest_addr
,
609 if (PIM_DEBUG_PIM_PACKETS
)
611 "%s: Sending register-Stop to %s and dropping mr. packet",
613 /* Drop Packet Silently */
618 struct pim_upstream
*upstream
= pim_upstream_find(pim
, &sg
);
620 * If we don't have a place to send ignore the packet
623 upstream
= pim_upstream_add(
625 PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
, __func__
,
628 zlog_warn("Failure to create upstream state");
632 upstream
->upstream_register
= src_addr
;
635 * If the FHR has set a very very fast register timer
636 * there exists a possibility that the incoming NULL
638 * is happening before we set the spt bit. If so
639 * Do a quick check to update the counters and
640 * then set the spt bit as appropriate
642 if (upstream
->sptbit
!= PIM_UPSTREAM_SPTBIT_TRUE
) {
643 pim_mroute_update_counters(
644 upstream
->channel_oil
);
646 * Have we seen packets?
648 if (upstream
->channel_oil
->cc
.oldpktcnt
649 < upstream
->channel_oil
->cc
.pktcnt
)
650 pim_upstream_set_sptbit(
652 upstream
->rpf
.source_nexthop
657 if ((upstream
->sptbit
== PIM_UPSTREAM_SPTBIT_TRUE
)
658 || ((SwitchToSptDesiredOnRp(pim
, &sg
))
659 && pim_upstream_inherited_olist(pim
, upstream
) == 0)) {
660 pim_register_stop_send(ifp
, &sg
, dest_addr
, src_addr
);
661 sentRegisterStop
= 1;
663 if (PIM_DEBUG_PIM_REG
)
664 zlog_debug("(%s) sptbit: %d", upstream
->sg_str
,
667 if ((upstream
->sptbit
== PIM_UPSTREAM_SPTBIT_TRUE
)
668 || (SwitchToSptDesiredOnRp(pim
, &sg
))) {
669 if (sentRegisterStop
) {
670 pim_upstream_keep_alive_timer_start(
671 upstream
, pim
->rp_keep_alive_time
);
673 pim_upstream_keep_alive_timer_start(
674 upstream
, pim
->keep_alive_time
);
678 if (!(upstream
->sptbit
== PIM_UPSTREAM_SPTBIT_TRUE
)
679 && !(*bits
& PIM_REGISTER_NR_BIT
)) {
680 // decapsulate and forward the iner packet to
681 // inherited_olist(S,G,rpt)
682 // This is taken care of by the kernel for us
684 pim_upstream_msdp_reg_timer_start(upstream
);
686 if (PIM_DEBUG_PIM_REG
) {
688 zlog_debug("Received Register packet for %pSG, Rejecting packet because I am not the RP configured for group",
691 zlog_debug("Received Register packet for %pSG, Rejecting packet because the dst ip address is not the actual RP",
694 pim_register_stop_send(ifp
, &sg
, dest_addr
, src_addr
);
701 * This routine scan all upstream and update register state and remove pimreg
702 * when couldreg becomes false.
704 void pim_reg_del_on_couldreg_fail(struct interface
*ifp
)
706 struct pim_interface
*pim_ifp
= ifp
->info
;
707 struct pim_instance
*pim
;
708 struct pim_upstream
*up
;
715 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
716 if (ifp
!= up
->rpf
.source_nexthop
.interface
)
719 if (!pim_upstream_could_register(up
)
720 && (up
->reg_state
!= PIM_REG_NOINFO
)) {
721 pim_channel_del_oif(up
->channel_oil
, pim
->regiface
,
722 PIM_OIF_FLAG_PROTO_PIM
, __func__
);
723 THREAD_OFF(up
->t_rs_timer
);
724 up
->reg_state
= PIM_REG_NOINFO
;