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