]> git.proxmox.com Git - mirror_frr.git/blob - pimd/pim_register.c
Merge pull request #13649 from donaldsharp/unlock_the_node_or_else
[mirror_frr.git] / pimd / pim_register.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * PIM for Quagga
4 * Copyright (C) 2015 Cumulus Networks, Inc.
5 * Donald Sharp
6 */
7
8 #include <zebra.h>
9
10 #include "log.h"
11 #include "if.h"
12 #include "frrevent.h"
13 #include "prefix.h"
14 #include "vty.h"
15 #include "plist.h"
16
17 #include "pimd.h"
18 #include "pim_mroute.h"
19 #include "pim_iface.h"
20 #include "pim_msg.h"
21 #include "pim_pim.h"
22 #include "pim_str.h"
23 #include "pim_rp.h"
24 #include "pim_register.h"
25 #include "pim_upstream.h"
26 #include "pim_rpf.h"
27 #include "pim_oil.h"
28 #include "pim_zebra.h"
29 #include "pim_join.h"
30 #include "pim_util.h"
31 #include "pim_ssm.h"
32 #include "pim_vxlan.h"
33 #include "pim_addr.h"
34
35 struct event *send_test_packet_timer = NULL;
36
37 void pim_register_join(struct pim_upstream *up)
38 {
39 struct pim_instance *pim = up->channel_oil->pim;
40
41 if (pim_is_grp_ssm(pim, up->sg.grp)) {
42 if (PIM_DEBUG_PIM_EVENTS)
43 zlog_debug("%s register setup skipped as group is SSM",
44 up->sg_str);
45 return;
46 }
47
48 pim_channel_add_oif(up->channel_oil, pim->regiface,
49 PIM_OIF_FLAG_PROTO_PIM, __func__);
50 up->reg_state = PIM_REG_JOIN;
51 pim_vxlan_update_sg_reg_state(pim, up, true);
52 }
53
54 void pim_register_stop_send(struct interface *ifp, pim_sgaddr *sg, pim_addr src,
55 pim_addr originator)
56 {
57 struct pim_interface *pinfo;
58 unsigned char buffer[10000];
59 unsigned int b1length = 0;
60 unsigned int length;
61 uint8_t *b1;
62
63 if (PIM_DEBUG_PIM_REG) {
64 zlog_debug("Sending Register stop for %pSG to %pPA on %s", sg,
65 &originator, ifp->name);
66 }
67
68 memset(buffer, 0, 10000);
69 b1 = (uint8_t *)buffer + PIM_MSG_REGISTER_STOP_LEN;
70
71 length = pim_encode_addr_group(b1, AFI_IP, 0, 0, sg->grp);
72 b1length += length;
73 b1 += length;
74
75 length = pim_encode_addr_ucast(b1, sg->src);
76 b1length += length;
77
78 pim_msg_build_header(src, originator, buffer,
79 b1length + PIM_MSG_REGISTER_STOP_LEN,
80 PIM_MSG_TYPE_REG_STOP, false);
81
82 pinfo = (struct pim_interface *)ifp->info;
83 if (!pinfo) {
84 if (PIM_DEBUG_PIM_TRACE)
85 zlog_debug("%s: No pinfo!", __func__);
86 return;
87 }
88 if (pim_msg_send(pinfo->pim_sock_fd, src, originator, buffer,
89 b1length + PIM_MSG_REGISTER_STOP_LEN, ifp)) {
90 if (PIM_DEBUG_PIM_TRACE) {
91 zlog_debug(
92 "%s: could not send PIM register stop message on interface %s",
93 __func__, ifp->name);
94 }
95 }
96
97 if (!pinfo->pim_passive_enable)
98 ++pinfo->pim_ifstat_reg_stop_send;
99 }
100
101 static void pim_reg_stop_upstream(struct pim_instance *pim,
102 struct pim_upstream *up)
103 {
104 switch (up->reg_state) {
105 case PIM_REG_NOINFO:
106 case PIM_REG_PRUNE:
107 return;
108 case PIM_REG_JOIN:
109 up->reg_state = PIM_REG_PRUNE;
110 pim_channel_del_oif(up->channel_oil, pim->regiface,
111 PIM_OIF_FLAG_PROTO_PIM, __func__);
112 pim_upstream_start_register_stop_timer(up, 0);
113 pim_vxlan_update_sg_reg_state(pim, up, false);
114 break;
115 case PIM_REG_JOIN_PENDING:
116 up->reg_state = PIM_REG_PRUNE;
117 pim_upstream_start_register_stop_timer(up, 0);
118 return;
119 }
120 }
121
122 int pim_register_stop_recv(struct interface *ifp, uint8_t *buf, int buf_size)
123 {
124 struct pim_interface *pim_ifp = ifp->info;
125 struct pim_instance *pim = pim_ifp->pim;
126 struct pim_upstream *up = NULL;
127 struct pim_rpf *rp;
128 pim_sgaddr sg;
129 struct listnode *up_node;
130 struct pim_upstream *child;
131 bool wrong_af = false;
132 bool handling_star = false;
133 int l;
134
135 if (pim_ifp->pim_passive_enable) {
136 if (PIM_DEBUG_PIM_PACKETS)
137 zlog_debug(
138 "skip receiving PIM message on passive interface %s",
139 ifp->name);
140 return 0;
141 }
142
143 ++pim_ifp->pim_ifstat_reg_stop_recv;
144
145 memset(&sg, 0, sizeof(sg));
146 l = pim_parse_addr_group(&sg, buf, buf_size);
147 buf += l;
148 buf_size -= l;
149 pim_parse_addr_ucast(&sg.src, buf, buf_size, &wrong_af);
150
151 if (wrong_af) {
152 zlog_err("invalid AF in Register-Stop on %s", ifp->name);
153 return -1;
154 }
155
156
157 if (PIM_DEBUG_PIM_REG)
158 zlog_debug("Received Register stop for %pSG", &sg);
159
160 rp = RP(pim_ifp->pim, sg.grp);
161 if (rp) {
162 /* As per RFC 7761, Section 4.9.4:
163 * A special wildcard value consisting of an address field of
164 * all zeros can be used to indicate any source.
165 */
166 if ((pim_addr_cmp(sg.src, rp->rpf_addr) == 0) ||
167 pim_addr_is_any(sg.src)) {
168 handling_star = true;
169 sg.src = PIMADDR_ANY;
170 }
171 }
172
173 /*
174 * RFC 7761 Sec 4.4.1
175 * Handling Register-Stop(*,G) Messages at the DR:
176 * A Register-Stop(*,G) should be treated as a
177 * Register-Stop(S,G) for all (S,G) Register state
178 * machines that are not in the NoInfo state.
179 */
180 up = pim_upstream_find(pim, &sg);
181 if (up) {
182 /*
183 * If the upstream find actually found a particular
184 * S,G then we *know* that the following for loop
185 * is not going to execute and this is ok
186 */
187 for (ALL_LIST_ELEMENTS_RO(up->sources, up_node, child)) {
188 if (PIM_DEBUG_PIM_REG)
189 zlog_debug("Executing Reg stop for %s",
190 child->sg_str);
191
192 pim_reg_stop_upstream(pim, child);
193 }
194
195 if (PIM_DEBUG_PIM_REG)
196 zlog_debug("Executing Reg stop for %s", up->sg_str);
197 pim_reg_stop_upstream(pim, up);
198 } else {
199 if (!handling_star)
200 return 0;
201 /*
202 * Unfortunately pim was unable to find a *,G
203 * but pim may still actually have individual
204 * S,G's that need to be processed. In that
205 * case pim must do the expensive walk to find
206 * and stop
207 */
208 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
209 if (pim_addr_cmp(up->sg.grp, sg.grp) == 0) {
210 if (PIM_DEBUG_PIM_REG)
211 zlog_debug("Executing Reg stop for %s",
212 up->sg_str);
213 pim_reg_stop_upstream(pim, up);
214 }
215 }
216 }
217
218 return 0;
219 }
220
221 #if PIM_IPV == 6
222 struct in6_addr pim_register_get_unicast_v6_addr(struct pim_interface *p_ifp)
223 {
224 struct listnode *node;
225 struct listnode *nextnode;
226 struct pim_secondary_addr *sec_addr;
227 struct pim_interface *pim_ifp;
228 struct interface *ifp;
229 struct pim_instance *pim = p_ifp->pim;
230
231 /* Trying to get the unicast address from the RPF interface first */
232 for (ALL_LIST_ELEMENTS(p_ifp->sec_addr_list, node, nextnode,
233 sec_addr)) {
234 if (!is_ipv6_global_unicast(&sec_addr->addr.u.prefix6))
235 continue;
236
237 return sec_addr->addr.u.prefix6;
238 }
239
240 /* Loop through all the pim interface and try to return a global
241 * unicast ipv6 address
242 */
243 FOR_ALL_INTERFACES (pim->vrf, ifp) {
244 pim_ifp = ifp->info;
245
246 if (!pim_ifp)
247 continue;
248
249 for (ALL_LIST_ELEMENTS(pim_ifp->sec_addr_list, node, nextnode,
250 sec_addr)) {
251 if (!is_ipv6_global_unicast(&sec_addr->addr.u.prefix6))
252 continue;
253
254 return sec_addr->addr.u.prefix6;
255 }
256 }
257
258 zlog_warn("No global address found for use to send register message");
259 return PIMADDR_ANY;
260 }
261 #endif
262
263 void pim_register_send(const uint8_t *buf, int buf_size, pim_addr src,
264 struct pim_rpf *rpg, int null_register,
265 struct pim_upstream *up)
266 {
267 unsigned char buffer[10000];
268 unsigned char *b1;
269 struct pim_interface *pinfo;
270 struct interface *ifp;
271
272 if (PIM_DEBUG_PIM_REG) {
273 zlog_debug("Sending %s %sRegister Packet to %pPA", up->sg_str,
274 null_register ? "NULL " : "", &rpg->rpf_addr);
275 }
276
277 ifp = rpg->source_nexthop.interface;
278 if (!ifp) {
279 if (PIM_DEBUG_PIM_REG)
280 zlog_debug("%s: No interface to transmit register on",
281 __func__);
282 return;
283 }
284 pinfo = (struct pim_interface *)ifp->info;
285 if (!pinfo) {
286 if (PIM_DEBUG_PIM_REG)
287 zlog_debug(
288 "%s: Interface: %s not configured for pim to transmit on!",
289 __func__, ifp->name);
290 return;
291 }
292
293 if (PIM_DEBUG_PIM_REG) {
294 zlog_debug("%s: Sending %s %sRegister Packet to %pPA on %s",
295 __func__, up->sg_str, null_register ? "NULL " : "",
296 &rpg->rpf_addr, ifp->name);
297 }
298
299 memset(buffer, 0, 10000);
300 b1 = buffer + PIM_MSG_HEADER_LEN;
301 *b1 |= null_register << 6;
302 b1 = buffer + PIM_MSG_REGISTER_LEN;
303
304 memcpy(b1, (const unsigned char *)buf, buf_size);
305
306 #if PIM_IPV == 6
307 /* While sending Register message to RP, we cannot use link-local
308 * address therefore using unicast ipv6 address here, choosing it
309 * from the RPF Interface
310 */
311 src = pim_register_get_unicast_v6_addr(pinfo);
312 #endif
313 pim_msg_build_header(src, rpg->rpf_addr, buffer,
314 buf_size + PIM_MSG_REGISTER_LEN,
315 PIM_MSG_TYPE_REGISTER, false);
316
317 if (!pinfo->pim_passive_enable)
318 ++pinfo->pim_ifstat_reg_send;
319
320 if (pim_msg_send(pinfo->pim->reg_sock, src, rpg->rpf_addr, buffer,
321 buf_size + PIM_MSG_REGISTER_LEN, ifp)) {
322 if (PIM_DEBUG_PIM_TRACE) {
323 zlog_debug(
324 "%s: could not send PIM register message on interface %s",
325 __func__, ifp->name);
326 }
327 return;
328 }
329 }
330
331 #if PIM_IPV == 4
332 void pim_null_register_send(struct pim_upstream *up)
333 {
334 struct ip ip_hdr;
335 struct pim_interface *pim_ifp;
336 struct pim_rpf *rpg;
337 pim_addr src;
338
339 pim_ifp = up->rpf.source_nexthop.interface->info;
340 if (!pim_ifp) {
341 if (PIM_DEBUG_PIM_TRACE)
342 zlog_debug(
343 "%s: Cannot send null-register for %s no valid iif",
344 __func__, up->sg_str);
345 return;
346 }
347
348 rpg = RP(pim_ifp->pim, up->sg.grp);
349 if (!rpg) {
350 if (PIM_DEBUG_PIM_TRACE)
351 zlog_debug(
352 "%s: Cannot send null-register for %s no RPF to the RP",
353 __func__, up->sg_str);
354 return;
355 }
356
357 memset(&ip_hdr, 0, sizeof(ip_hdr));
358 ip_hdr.ip_p = PIM_IP_PROTO_PIM;
359 ip_hdr.ip_hl = 5;
360 ip_hdr.ip_v = 4;
361 ip_hdr.ip_src = up->sg.src;
362 ip_hdr.ip_dst = up->sg.grp;
363 ip_hdr.ip_len = htons(20);
364
365 /* checksum is broken */
366 src = pim_ifp->primary_address;
367 if (PIM_UPSTREAM_FLAG_TEST_SRC_VXLAN_ORIG(up->flags)) {
368 if (!pim_vxlan_get_register_src(pim_ifp->pim, up, &src)) {
369 if (PIM_DEBUG_PIM_TRACE)
370 zlog_debug(
371 "%s: Cannot send null-register for %s vxlan-aa PIP unavailable",
372 __func__, up->sg_str);
373 return;
374 }
375 }
376 pim_register_send((uint8_t *)&ip_hdr, sizeof(struct ip), src, rpg, 1,
377 up);
378 }
379 #else
380 void pim_null_register_send(struct pim_upstream *up)
381 {
382 struct ip6_hdr ip6_hdr;
383 struct pim_msg_header pim_msg_header;
384 struct pim_interface *pim_ifp;
385 struct pim_rpf *rpg;
386 pim_addr src;
387 unsigned char buffer[sizeof(ip6_hdr) + sizeof(pim_msg_header)];
388 struct ipv6_ph ph;
389
390 pim_ifp = up->rpf.source_nexthop.interface->info;
391 if (!pim_ifp) {
392 if (PIM_DEBUG_PIM_TRACE)
393 zlog_debug(
394 "Cannot send null-register for %s no valid iif",
395 up->sg_str);
396 return;
397 }
398
399 rpg = RP(pim_ifp->pim, up->sg.grp);
400 if (!rpg) {
401 if (PIM_DEBUG_PIM_TRACE)
402 zlog_debug(
403 "Cannot send null-register for %s no RPF to the RP",
404 up->sg_str);
405 return;
406 }
407
408 memset(&ip6_hdr, 0, sizeof(ip6_hdr));
409 ip6_hdr.ip6_nxt = PIM_IP_PROTO_PIM;
410 ip6_hdr.ip6_plen = PIM_MSG_HEADER_LEN;
411 ip6_hdr.ip6_vfc = 6 << 4;
412 ip6_hdr.ip6_hlim = MAXTTL;
413 ip6_hdr.ip6_src = up->sg.src;
414 ip6_hdr.ip6_dst = up->sg.grp;
415
416 memset(buffer, 0, (sizeof(ip6_hdr) + sizeof(pim_msg_header)));
417 memcpy(buffer, &ip6_hdr, sizeof(ip6_hdr));
418
419 pim_msg_header.ver = 0;
420 pim_msg_header.type = 0;
421 pim_msg_header.reserved = 0;
422
423 pim_msg_header.checksum = 0;
424
425 ph.src = up->sg.src;
426 ph.dst = up->sg.grp;
427 ph.ulpl = htonl(PIM_MSG_HEADER_LEN);
428 ph.next_hdr = IPPROTO_PIM;
429 pim_msg_header.checksum =
430 in_cksum_with_ph6(&ph, &pim_msg_header, PIM_MSG_HEADER_LEN);
431
432 memcpy(buffer + sizeof(ip6_hdr), &pim_msg_header, PIM_MSG_HEADER_LEN);
433
434
435 src = pim_ifp->primary_address;
436 pim_register_send((uint8_t *)buffer,
437 sizeof(ip6_hdr) + PIM_MSG_HEADER_LEN, src, rpg, 1,
438 up);
439 }
440 #endif
441
442 /*
443 * 4.4.2 Receiving Register Messages at the RP
444 *
445 * When an RP receives a Register message, the course of action is
446 * decided according to the following pseudocode:
447 *
448 * packet_arrives_on_rp_tunnel( pkt ) {
449 * if( outer.dst is not one of my addresses ) {
450 * drop the packet silently.
451 * # Note: this may be a spoofing attempt
452 * }
453 * if( I_am_RP(G) AND outer.dst == RP(G) ) {
454 * sentRegisterStop = false;
455 * if ( register.borderbit == true ) {
456 * if ( PMBR(S,G) == unknown ) {
457 * PMBR(S,G) = outer.src
458 * } else if ( outer.src != PMBR(S,G) ) {
459 * send Register-Stop(S,G) to outer.src
460 * drop the packet silently.
461 * }
462 * }
463 * if ( SPTbit(S,G) OR
464 * ( SwitchToSptDesired(S,G) AND
465 * ( inherited_olist(S,G) == NULL ))) {
466 * send Register-Stop(S,G) to outer.src
467 * sentRegisterStop = true;
468 * }
469 * if ( SPTbit(S,G) OR SwitchToSptDesired(S,G) ) {
470 * if ( sentRegisterStop == true ) {
471 * set KeepaliveTimer(S,G) to RP_Keepalive_Period;
472 * } else {
473 * set KeepaliveTimer(S,G) to Keepalive_Period;
474 * }
475 * }
476 * if( !SPTbit(S,G) AND ! pkt.NullRegisterBit ) {
477 * decapsulate and forward the inner packet to
478 * inherited_olist(S,G,rpt) # Note (+)
479 * }
480 * } else {
481 * send Register-Stop(S,G) to outer.src
482 * # Note (*)
483 * }
484 * }
485 */
486 int pim_register_recv(struct interface *ifp, pim_addr dest_addr,
487 pim_addr src_addr, uint8_t *tlv_buf, int tlv_buf_size)
488 {
489 int sentRegisterStop = 0;
490 const void *ip_hdr;
491 pim_sgaddr sg;
492 uint32_t *bits;
493 int i_am_rp = 0;
494 struct pim_interface *pim_ifp = ifp->info;
495 struct pim_instance *pim = pim_ifp->pim;
496 pim_addr rp_addr;
497
498 if (pim_ifp->pim_passive_enable) {
499 if (PIM_DEBUG_PIM_PACKETS)
500 zlog_debug(
501 "skip receiving PIM message on passive interface %s",
502 ifp->name);
503 return 0;
504 }
505
506 #define PIM_MSG_REGISTER_BIT_RESERVED_LEN 4
507 ip_hdr = (tlv_buf + PIM_MSG_REGISTER_BIT_RESERVED_LEN);
508
509 if (!if_address_is_local(&dest_addr, PIM_AF, pim->vrf->vrf_id)) {
510 if (PIM_DEBUG_PIM_REG)
511 zlog_debug(
512 "%s: Received Register message for destination address: %pPA that I do not own",
513 __func__, &dest_addr);
514 return 0;
515 }
516
517 ++pim_ifp->pim_ifstat_reg_recv;
518
519 /*
520 * Please note this is not drawn to get the correct bit/data size
521 *
522 * The entirety of the REGISTER packet looks like this:
523 * -------------------------------------------------------------
524 * | Ver | Type | Reserved | Checksum |
525 * |-----------------------------------------------------------|
526 * |B|N| Reserved 2 |
527 * |-----------------------------------------------------------|
528 * | Encap | IP HDR |
529 * | Mcast | |
530 * | Packet |--------------------------------------------------|
531 * | | Mcast Data |
532 * | | |
533 * ...
534 *
535 * tlv_buf when received from the caller points at the B bit
536 * We need to know the inner source and dest
537 */
538 bits = (uint32_t *)tlv_buf;
539
540 /*
541 * tlv_buf points to the start of the |B|N|... Reserved
542 * Line above. So we need to add 4 bytes to get to the
543 * start of the actual Encapsulated data.
544 */
545 memset(&sg, 0, sizeof(sg));
546 sg = pim_sgaddr_from_iphdr(ip_hdr);
547
548 #if PIM_IPV == 6
549 /*
550 * According to RFC section 4.9.3, If Dummy PIM Header is included
551 * in NULL Register as a payload there would be two PIM headers.
552 * The inner PIM Header's checksum field should also be validated
553 * in addition to the outer PIM Header's checksum. Validation of
554 * inner PIM header checksum is done here.
555 */
556 if ((*bits & PIM_REGISTER_NR_BIT) &&
557 ((tlv_buf_size - PIM_MSG_REGISTER_BIT_RESERVED_LEN) >
558 (int)sizeof(struct ip6_hdr))) {
559 uint16_t computed_checksum;
560 uint16_t received_checksum;
561 struct ipv6_ph ph;
562 struct pim_msg_header *header;
563
564 header = (struct pim_msg_header
565 *)(tlv_buf +
566 PIM_MSG_REGISTER_BIT_RESERVED_LEN +
567 sizeof(struct ip6_hdr));
568 ph.src = sg.src;
569 ph.dst = sg.grp;
570 ph.ulpl = htonl(PIM_MSG_HEADER_LEN);
571 ph.next_hdr = IPPROTO_PIM;
572
573 received_checksum = header->checksum;
574
575 header->checksum = 0;
576 computed_checksum = in_cksum_with_ph6(
577 &ph, header, htonl(PIM_MSG_HEADER_LEN));
578
579 if (computed_checksum != received_checksum) {
580 if (PIM_DEBUG_PIM_PACKETS)
581 zlog_debug(
582 "Ignoring Null Register message%pSG from %pPA due to bad checksum in Encapsulated dummy PIM header",
583 &sg, &src_addr);
584 return 0;
585 }
586 }
587 #endif
588 i_am_rp = I_am_RP(pim, sg.grp);
589
590 if (PIM_DEBUG_PIM_REG)
591 zlog_debug(
592 "Received Register message%pSG from %pPA on %s, rp: %d",
593 &sg, &src_addr, ifp->name, i_am_rp);
594
595 if (pim_is_grp_ssm(pim_ifp->pim, sg.grp)) {
596 if (pim_addr_is_any(sg.src)) {
597 zlog_warn(
598 "%s: Received Register message for Group(%pPA) is now in SSM, dropping the packet",
599 __func__, &sg.grp);
600 /* Drop Packet Silently */
601 return 0;
602 }
603 }
604
605 rp_addr = (RP(pim, sg.grp))->rpf_addr;
606 if (i_am_rp && (!pim_addr_cmp(dest_addr, rp_addr))) {
607 sentRegisterStop = 0;
608
609 if (pim->register_plist) {
610 struct prefix_list *plist;
611 struct prefix src;
612
613 plist = prefix_list_lookup(PIM_AFI,
614 pim->register_plist);
615
616 pim_addr_to_prefix(&src, sg.src);
617
618 if (prefix_list_apply_ext(plist, NULL, &src, true) ==
619 PREFIX_DENY) {
620 pim_register_stop_send(ifp, &sg, dest_addr,
621 src_addr);
622 if (PIM_DEBUG_PIM_PACKETS)
623 zlog_debug(
624 "%s: Sending register-stop to %pPA for %pSG due to prefix-list denial, dropping packet",
625 __func__, &src_addr, &sg);
626
627 return 0;
628 }
629 }
630
631 if (*bits & PIM_REGISTER_BORDER_BIT) {
632 if (PIM_DEBUG_PIM_PACKETS)
633 zlog_debug(
634 "%s: Received Register message with Border bit set, ignoring",
635 __func__);
636
637 /* Drop Packet Silently */
638 return 0;
639 }
640
641 struct pim_upstream *upstream = pim_upstream_find(pim, &sg);
642 /*
643 * If we don't have a place to send ignore the packet
644 */
645 if (!upstream) {
646 upstream = pim_upstream_add(
647 pim, &sg, ifp,
648 PIM_UPSTREAM_FLAG_MASK_SRC_STREAM, __func__,
649 NULL);
650 if (!upstream) {
651 zlog_warn("Failure to create upstream state");
652 return 1;
653 }
654
655 upstream->upstream_register = src_addr;
656 } else {
657 /*
658 * If the FHR has set a very very fast register timer
659 * there exists a possibility that the incoming NULL
660 * register
661 * is happening before we set the spt bit. If so
662 * Do a quick check to update the counters and
663 * then set the spt bit as appropriate
664 */
665 if (upstream->sptbit != PIM_UPSTREAM_SPTBIT_TRUE) {
666 pim_mroute_update_counters(
667 upstream->channel_oil);
668 /*
669 * Have we seen packets?
670 */
671 if (upstream->channel_oil->cc.oldpktcnt
672 < upstream->channel_oil->cc.pktcnt)
673 pim_upstream_set_sptbit(
674 upstream,
675 upstream->rpf.source_nexthop
676 .interface);
677 }
678 }
679
680 if ((upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE)
681 || ((SwitchToSptDesiredOnRp(pim, &sg))
682 && pim_upstream_inherited_olist(pim, upstream) == 0)) {
683 pim_register_stop_send(ifp, &sg, dest_addr, src_addr);
684 sentRegisterStop = 1;
685 } else {
686 if (PIM_DEBUG_PIM_REG)
687 zlog_debug("(%s) sptbit: %d", upstream->sg_str,
688 upstream->sptbit);
689 }
690 if ((upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE)
691 || (SwitchToSptDesiredOnRp(pim, &sg))) {
692 if (sentRegisterStop) {
693 pim_upstream_keep_alive_timer_start(
694 upstream, pim->rp_keep_alive_time);
695 } else {
696 pim_upstream_keep_alive_timer_start(
697 upstream, pim->keep_alive_time);
698 }
699 }
700
701 if (!(upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE)
702 && !(*bits & PIM_REGISTER_NR_BIT)) {
703 // decapsulate and forward the iner packet to
704 // inherited_olist(S,G,rpt)
705 // This is taken care of by the kernel for us
706 }
707 pim_upstream_msdp_reg_timer_start(upstream);
708 } else {
709 if (PIM_DEBUG_PIM_REG) {
710 if (!i_am_rp)
711 zlog_debug("Received Register packet for %pSG, Rejecting packet because I am not the RP configured for group",
712 &sg);
713 else
714 zlog_debug("Received Register packet for %pSG, Rejecting packet because the dst ip address is not the actual RP",
715 &sg);
716 }
717 pim_register_stop_send(ifp, &sg, dest_addr, src_addr);
718 }
719
720 return 0;
721 }
722
723 /*
724 * This routine scan all upstream and update register state and remove pimreg
725 * when couldreg becomes false.
726 */
727 void pim_reg_del_on_couldreg_fail(struct interface *ifp)
728 {
729 struct pim_interface *pim_ifp = ifp->info;
730 struct pim_instance *pim;
731 struct pim_upstream *up;
732
733 if (!pim_ifp)
734 return;
735
736 pim = pim_ifp->pim;
737
738 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
739 if (ifp != up->rpf.source_nexthop.interface)
740 continue;
741
742 if (!pim_upstream_could_register(up)
743 && (up->reg_state != PIM_REG_NOINFO)) {
744 pim_channel_del_oif(up->channel_oil, pim->regiface,
745 PIM_OIF_FLAG_PROTO_PIM, __func__);
746 EVENT_OFF(up->t_rs_timer);
747 up->reg_state = PIM_REG_NOINFO;
748 }
749 }
750 }