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