]> git.proxmox.com Git - mirror_frr.git/blob - pimd/pim_register.c
Merge pull request #11355 from patrasar/pim6reg
[mirror_frr.git] / pimd / pim_register.c
1 /*
2 * PIM for Quagga
3 * Copyright (C) 2015 Cumulus Networks, Inc.
4 * Donald Sharp
5 *
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.
10 *
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.
15 *
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
19 */
20
21 #include <zebra.h>
22
23 #include "log.h"
24 #include "if.h"
25 #include "thread.h"
26 #include "prefix.h"
27 #include "vty.h"
28 #include "plist.h"
29
30 #include "pimd.h"
31 #include "pim_mroute.h"
32 #include "pim_iface.h"
33 #include "pim_msg.h"
34 #include "pim_pim.h"
35 #include "pim_str.h"
36 #include "pim_rp.h"
37 #include "pim_register.h"
38 #include "pim_upstream.h"
39 #include "pim_br.h"
40 #include "pim_rpf.h"
41 #include "pim_oil.h"
42 #include "pim_zebra.h"
43 #include "pim_join.h"
44 #include "pim_util.h"
45 #include "pim_ssm.h"
46 #include "pim_vxlan.h"
47 #include "pim_addr.h"
48
49 struct thread *send_test_packet_timer = NULL;
50
51 void pim_register_join(struct pim_upstream *up)
52 {
53 struct pim_instance *pim = up->channel_oil->pim;
54
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",
58 up->sg_str);
59 return;
60 }
61
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);
66 }
67
68 void pim_register_stop_send(struct interface *ifp, pim_sgaddr *sg, pim_addr src,
69 pim_addr originator)
70 {
71 struct pim_interface *pinfo;
72 unsigned char buffer[10000];
73 unsigned int b1length = 0;
74 unsigned int length;
75 uint8_t *b1;
76
77 if (PIM_DEBUG_PIM_REG) {
78 zlog_debug("Sending Register stop for %pSG to %pPA on %s", sg,
79 &originator, ifp->name);
80 }
81
82 memset(buffer, 0, 10000);
83 b1 = (uint8_t *)buffer + PIM_MSG_REGISTER_STOP_LEN;
84
85 length = pim_encode_addr_group(b1, AFI_IP, 0, 0, sg->grp);
86 b1length += length;
87 b1 += length;
88
89 length = pim_encode_addr_ucast(b1, sg->src);
90 b1length += length;
91
92 pim_msg_build_header(src, originator, buffer,
93 b1length + PIM_MSG_REGISTER_STOP_LEN,
94 PIM_MSG_TYPE_REG_STOP, false);
95
96 pinfo = (struct pim_interface *)ifp->info;
97 if (!pinfo) {
98 if (PIM_DEBUG_PIM_TRACE)
99 zlog_debug("%s: No pinfo!", __func__);
100 return;
101 }
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) {
105 zlog_debug(
106 "%s: could not send PIM register stop message on interface %s",
107 __func__, ifp->name);
108 }
109 }
110
111 if (!pinfo->pim_passive_enable)
112 ++pinfo->pim_ifstat_reg_stop_send;
113 }
114
115 static void pim_reg_stop_upstream(struct pim_instance *pim,
116 struct pim_upstream *up)
117 {
118 switch (up->reg_state) {
119 case PIM_REG_NOINFO:
120 case PIM_REG_PRUNE:
121 return;
122 case PIM_REG_JOIN:
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);
128 break;
129 case PIM_REG_JOIN_PENDING:
130 up->reg_state = PIM_REG_PRUNE;
131 pim_upstream_start_register_stop_timer(up, 0);
132 return;
133 }
134 }
135
136 int pim_register_stop_recv(struct interface *ifp, uint8_t *buf, int buf_size)
137 {
138 struct pim_interface *pim_ifp = ifp->info;
139 struct pim_instance *pim = pim_ifp->pim;
140 struct pim_upstream *up = NULL;
141 struct pim_rpf *rp;
142 pim_addr rpf_addr;
143 pim_sgaddr sg;
144 struct listnode *up_node;
145 struct pim_upstream *child;
146 bool wrong_af = false;
147 bool handling_star = false;
148 int l;
149
150 if (pim_ifp->pim_passive_enable) {
151 if (PIM_DEBUG_PIM_PACKETS)
152 zlog_debug(
153 "skip receiving PIM message on passive interface %s",
154 ifp->name);
155 return 0;
156 }
157
158 ++pim_ifp->pim_ifstat_reg_stop_recv;
159
160 memset(&sg, 0, sizeof(sg));
161 l = pim_parse_addr_group(&sg, buf, buf_size);
162 buf += l;
163 buf_size -= l;
164 pim_parse_addr_ucast(&sg.src, buf, buf_size, &wrong_af);
165
166 if (wrong_af) {
167 zlog_err("invalid AF in Register-Stop on %s", ifp->name);
168 return -1;
169 }
170
171
172 if (PIM_DEBUG_PIM_REG)
173 zlog_debug("Received Register stop for %pSG", &sg);
174
175 rp = RP(pim_ifp->pim, sg.grp);
176 if (rp) {
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.
181 */
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;
186 }
187 }
188
189 /*
190 * RFC 7761 Sec 4.4.1
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.
195 */
196 up = pim_upstream_find(pim, &sg);
197 if (up) {
198 /*
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
202 */
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",
206 child->sg_str);
207
208 pim_reg_stop_upstream(pim, child);
209 }
210
211 if (PIM_DEBUG_PIM_REG)
212 zlog_debug("Executing Reg stop for %s", up->sg_str);
213 pim_reg_stop_upstream(pim, up);
214 } else {
215 if (!handling_star)
216 return 0;
217 /*
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
222 * and stop
223 */
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",
228 up->sg_str);
229 pim_reg_stop_upstream(pim, up);
230 }
231 }
232 }
233
234 return 0;
235 }
236
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)
240 {
241 unsigned char buffer[10000];
242 unsigned char *b1;
243 struct pim_interface *pinfo;
244 struct interface *ifp;
245 pim_addr dst = pim_addr_from_prefix(&rpg->rpf_addr);
246
247 if (PIM_DEBUG_PIM_REG) {
248 zlog_debug("Sending %s %sRegister Packet to %pPA", up->sg_str,
249 null_register ? "NULL " : "", &dst);
250 }
251
252 ifp = rpg->source_nexthop.interface;
253 if (!ifp) {
254 if (PIM_DEBUG_PIM_REG)
255 zlog_debug("%s: No interface to transmit register on",
256 __func__);
257 return;
258 }
259 pinfo = (struct pim_interface *)ifp->info;
260 if (!pinfo) {
261 if (PIM_DEBUG_PIM_REG)
262 zlog_debug(
263 "%s: Interface: %s not configured for pim to transmit on!",
264 __func__, ifp->name);
265 return;
266 }
267
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 " : "",
271 &dst, ifp->name);
272 }
273
274 memset(buffer, 0, 10000);
275 b1 = buffer + PIM_MSG_HEADER_LEN;
276 *b1 |= null_register << 6;
277 b1 = buffer + PIM_MSG_REGISTER_LEN;
278
279 memcpy(b1, (const unsigned char *)buf, buf_size);
280
281 pim_msg_build_header(src, dst, buffer, buf_size + PIM_MSG_REGISTER_LEN,
282 PIM_MSG_TYPE_REGISTER, false);
283
284 if (!pinfo->pim_passive_enable)
285 ++pinfo->pim_ifstat_reg_send;
286
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) {
290 zlog_debug(
291 "%s: could not send PIM register message on interface %s",
292 __func__, ifp->name);
293 }
294 return;
295 }
296 }
297
298 #if PIM_IPV == 4
299 void pim_null_register_send(struct pim_upstream *up)
300 {
301 struct ip ip_hdr;
302 struct pim_interface *pim_ifp;
303 struct pim_rpf *rpg;
304 pim_addr src;
305
306 pim_ifp = up->rpf.source_nexthop.interface->info;
307 if (!pim_ifp) {
308 if (PIM_DEBUG_PIM_TRACE)
309 zlog_debug(
310 "%s: Cannot send null-register for %s no valid iif",
311 __func__, up->sg_str);
312 return;
313 }
314
315 rpg = RP(pim_ifp->pim, up->sg.grp);
316 if (!rpg) {
317 if (PIM_DEBUG_PIM_TRACE)
318 zlog_debug(
319 "%s: Cannot send null-register for %s no RPF to the RP",
320 __func__, up->sg_str);
321 return;
322 }
323
324 memset(&ip_hdr, 0, sizeof(ip_hdr));
325 ip_hdr.ip_p = PIM_IP_PROTO_PIM;
326 ip_hdr.ip_hl = 5;
327 ip_hdr.ip_v = 4;
328 ip_hdr.ip_src = up->sg.src;
329 ip_hdr.ip_dst = up->sg.grp;
330 ip_hdr.ip_len = htons(20);
331
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)
337 zlog_debug(
338 "%s: Cannot send null-register for %s vxlan-aa PIP unavailable",
339 __func__, up->sg_str);
340 return;
341 }
342 }
343 pim_register_send((uint8_t *)&ip_hdr, sizeof(struct ip), src, rpg, 1,
344 up);
345 }
346 #else
347 void pim_null_register_send(struct pim_upstream *up)
348 {
349 struct ip6_hdr ip6_hdr;
350 struct pim_msg_header pim_msg_header;
351 struct pim_interface *pim_ifp;
352 struct pim_rpf *rpg;
353 pim_addr src;
354 unsigned char buffer[sizeof(ip6_hdr) + sizeof(pim_msg_header)];
355 struct ipv6_ph ph;
356
357 pim_ifp = up->rpf.source_nexthop.interface->info;
358 if (!pim_ifp) {
359 if (PIM_DEBUG_PIM_TRACE)
360 zlog_debug(
361 "Cannot send null-register for %s no valid iif",
362 up->sg_str);
363 return;
364 }
365
366 rpg = RP(pim_ifp->pim, up->sg.grp);
367 if (!rpg) {
368 if (PIM_DEBUG_PIM_TRACE)
369 zlog_debug(
370 "Cannot send null-register for %s no RPF to the RP",
371 up->sg_str);
372 return;
373 }
374
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;
382
383 memset(buffer, 0, (sizeof(ip6_hdr) + sizeof(pim_msg_header)));
384 memcpy(buffer, &ip6_hdr, sizeof(ip6_hdr));
385
386 pim_msg_header.ver = 0;
387 pim_msg_header.type = 0;
388 pim_msg_header.reserved = 0;
389
390 pim_msg_header.checksum = 0;
391
392 ph.src = up->sg.src;
393 ph.dst = up->sg.grp;
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);
398
399 memcpy(buffer + sizeof(ip6_hdr), &pim_msg_header, PIM_MSG_HEADER_LEN);
400
401
402 src = pim_ifp->primary_address;
403 pim_register_send((uint8_t *)buffer,
404 sizeof(ip6_hdr) + PIM_MSG_HEADER_LEN, src, rpg, 1,
405 up);
406 }
407 #endif
408
409 /*
410 * 4.4.2 Receiving Register Messages at the RP
411 *
412 * When an RP receives a Register message, the course of action is
413 * decided according to the following pseudocode:
414 *
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
419 * }
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.
428 * }
429 * }
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;
435 * }
436 * if ( SPTbit(S,G) OR SwitchToSptDesired(S,G) ) {
437 * if ( sentRegisterStop == true ) {
438 * set KeepaliveTimer(S,G) to RP_Keepalive_Period;
439 * } else {
440 * set KeepaliveTimer(S,G) to Keepalive_Period;
441 * }
442 * }
443 * if( !SPTbit(S,G) AND ! pkt.NullRegisterBit ) {
444 * decapsulate and forward the inner packet to
445 * inherited_olist(S,G,rpt) # Note (+)
446 * }
447 * } else {
448 * send Register-Stop(S,G) to outer.src
449 * # Note (*)
450 * }
451 * }
452 */
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)
455 {
456 int sentRegisterStop = 0;
457 const void *ip_hdr;
458 pim_sgaddr sg;
459 uint32_t *bits;
460 int i_am_rp = 0;
461 struct pim_interface *pim_ifp = ifp->info;
462 struct pim_instance *pim = pim_ifp->pim;
463 pim_addr rp_addr;
464
465 if (pim_ifp->pim_passive_enable) {
466 if (PIM_DEBUG_PIM_PACKETS)
467 zlog_debug(
468 "skip receiving PIM message on passive interface %s",
469 ifp->name);
470 return 0;
471 }
472
473 #define PIM_MSG_REGISTER_BIT_RESERVED_LEN 4
474 ip_hdr = (tlv_buf + PIM_MSG_REGISTER_BIT_RESERVED_LEN);
475
476 if (!if_address_is_local(&dest_addr, PIM_AF, pim->vrf->vrf_id)) {
477 if (PIM_DEBUG_PIM_REG)
478 zlog_debug(
479 "%s: Received Register message for destination address: %pPA that I do not own",
480 __func__, &dest_addr);
481 return 0;
482 }
483
484 ++pim_ifp->pim_ifstat_reg_recv;
485
486 /*
487 * Please note this is not drawn to get the correct bit/data size
488 *
489 * The entirety of the REGISTER packet looks like this:
490 * -------------------------------------------------------------
491 * | Ver | Type | Reserved | Checksum |
492 * |-----------------------------------------------------------|
493 * |B|N| Reserved 2 |
494 * |-----------------------------------------------------------|
495 * | Encap | IP HDR |
496 * | Mcast | |
497 * | Packet |--------------------------------------------------|
498 * | | Mcast Data |
499 * | | |
500 * ...
501 *
502 * tlv_buf when received from the caller points at the B bit
503 * We need to know the inner source and dest
504 */
505 bits = (uint32_t *)tlv_buf;
506
507 /*
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.
511 */
512 memset(&sg, 0, sizeof(sg));
513 sg = pim_sgaddr_from_iphdr(ip_hdr);
514
515 #if PIM_IPV == 6
516 /*
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.
522 */
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;
528 struct ipv6_ph ph;
529 struct pim_msg_header *header;
530
531 header = (struct pim_msg_header
532 *)(tlv_buf +
533 PIM_MSG_REGISTER_BIT_RESERVED_LEN +
534 sizeof(struct ip6_hdr));
535 ph.src = sg.src;
536 ph.dst = sg.grp;
537 ph.ulpl = htonl(PIM_MSG_HEADER_LEN);
538 ph.next_hdr = IPPROTO_PIM;
539
540 received_checksum = header->checksum;
541
542 header->checksum = 0;
543 computed_checksum = in_cksum_with_ph6(
544 &ph, header, htonl(PIM_MSG_HEADER_LEN));
545
546 if (computed_checksum != received_checksum) {
547 if (PIM_DEBUG_PIM_PACKETS)
548 zlog_debug(
549 "Ignoring Null Register message%pSG from %pPA due to bad checksum in Encapsulated dummy PIM header",
550 &sg, &src_addr);
551 return 0;
552 }
553 }
554 #endif
555 i_am_rp = I_am_RP(pim, sg.grp);
556
557 if (PIM_DEBUG_PIM_REG)
558 zlog_debug(
559 "Received Register message%pSG from %pPA on %s, rp: %d",
560 &sg, &src_addr, ifp->name, i_am_rp);
561
562 if (pim_is_grp_ssm(pim_ifp->pim, sg.grp)) {
563 if (pim_addr_is_any(sg.src)) {
564 zlog_warn(
565 "%s: Received Register message for Group(%pPA) is now in SSM, dropping the packet",
566 __func__, &sg.grp);
567 /* Drop Packet Silently */
568 return 0;
569 }
570 }
571
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;
575
576 if (pim->register_plist) {
577 struct prefix_list *plist;
578 struct prefix src;
579
580 plist = prefix_list_lookup(PIM_AFI,
581 pim->register_plist);
582
583 pim_addr_to_prefix(&src, sg.src);
584
585 if (prefix_list_apply(plist, &src) == PREFIX_DENY) {
586 pim_register_stop_send(ifp, &sg, dest_addr,
587 src_addr);
588 if (PIM_DEBUG_PIM_PACKETS)
589 zlog_debug(
590 "%s: Sending register-stop to %pPA for %pSG due to prefix-list denial, dropping packet",
591 __func__, &src_addr, &sg);
592
593 return 0;
594 }
595 }
596
597 if (*bits & PIM_REGISTER_BORDER_BIT) {
598 pim_addr pimbr = pim_br_get_pmbr(&sg);
599 if (PIM_DEBUG_PIM_PACKETS)
600 zlog_debug(
601 "%s: Received Register message with Border bit set",
602 __func__);
603
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,
608 src_addr);
609 if (PIM_DEBUG_PIM_PACKETS)
610 zlog_debug(
611 "%s: Sending register-Stop to %s and dropping mr. packet",
612 __func__, "Sender");
613 /* Drop Packet Silently */
614 return 0;
615 }
616 }
617
618 struct pim_upstream *upstream = pim_upstream_find(pim, &sg);
619 /*
620 * If we don't have a place to send ignore the packet
621 */
622 if (!upstream) {
623 upstream = pim_upstream_add(
624 pim, &sg, ifp,
625 PIM_UPSTREAM_FLAG_MASK_SRC_STREAM, __func__,
626 NULL);
627 if (!upstream) {
628 zlog_warn("Failure to create upstream state");
629 return 1;
630 }
631
632 upstream->upstream_register = src_addr;
633 } else {
634 /*
635 * If the FHR has set a very very fast register timer
636 * there exists a possibility that the incoming NULL
637 * register
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
641 */
642 if (upstream->sptbit != PIM_UPSTREAM_SPTBIT_TRUE) {
643 pim_mroute_update_counters(
644 upstream->channel_oil);
645 /*
646 * Have we seen packets?
647 */
648 if (upstream->channel_oil->cc.oldpktcnt
649 < upstream->channel_oil->cc.pktcnt)
650 pim_upstream_set_sptbit(
651 upstream,
652 upstream->rpf.source_nexthop
653 .interface);
654 }
655 }
656
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;
662 } else {
663 if (PIM_DEBUG_PIM_REG)
664 zlog_debug("(%s) sptbit: %d", upstream->sg_str,
665 upstream->sptbit);
666 }
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);
672 } else {
673 pim_upstream_keep_alive_timer_start(
674 upstream, pim->keep_alive_time);
675 }
676 }
677
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
683 }
684 pim_upstream_msdp_reg_timer_start(upstream);
685 } else {
686 if (PIM_DEBUG_PIM_REG) {
687 if (!i_am_rp)
688 zlog_debug("Received Register packet for %pSG, Rejecting packet because I am not the RP configured for group",
689 &sg);
690 else
691 zlog_debug("Received Register packet for %pSG, Rejecting packet because the dst ip address is not the actual RP",
692 &sg);
693 }
694 pim_register_stop_send(ifp, &sg, dest_addr, src_addr);
695 }
696
697 return 0;
698 }
699
700 /*
701 * This routine scan all upstream and update register state and remove pimreg
702 * when couldreg becomes false.
703 */
704 void pim_reg_del_on_couldreg_fail(struct interface *ifp)
705 {
706 struct pim_interface *pim_ifp = ifp->info;
707 struct pim_instance *pim;
708 struct pim_upstream *up;
709
710 if (!pim_ifp)
711 return;
712
713 pim = pim_ifp->pim;
714
715 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
716 if (ifp != up->rpf.source_nexthop.interface)
717 continue;
718
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;
725 }
726 }
727 }