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