]> git.proxmox.com Git - mirror_frr.git/blame - pimd/pim_register.c
Merge pull request #6385 from GalaxyGorilla/bfd_igp_topotest
[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"
01d68c9b
DS
47
48struct thread *send_test_packet_timer = NULL;
49
d62a17ae 50void pim_register_join(struct pim_upstream *up)
15a5dafe 51{
ac7eaeb4
DS
52 struct pim_instance *pim = up->channel_oil->pim;
53
6f439a70 54 if (pim_is_grp_ssm(pim, up->sg.grp)) {
d62a17ae 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
ac7eaeb4 61 pim_channel_add_oif(up->channel_oil, pim->regiface,
1b249e70 62 PIM_OIF_FLAG_PROTO_PIM, __func__);
d62a17ae 63 up->reg_state = PIM_REG_JOIN;
2951a7a4 64 pim_vxlan_update_sg_reg_state(pim, up, true /*reg_join*/);
15a5dafe 65}
66
d62a17ae 67void pim_register_stop_send(struct interface *ifp, struct prefix_sg *sg,
68 struct in_addr src, struct in_addr originator)
01d68c9b 69{
d62a17ae 70 struct pim_interface *pinfo;
71 unsigned char buffer[10000];
72 unsigned int b1length = 0;
73 unsigned int length;
74 uint8_t *b1;
75 struct prefix p;
76
77 if (PIM_DEBUG_PIM_REG) {
78 zlog_debug("Sending Register stop for %s to %s on %s",
79 pim_str_sg_dump(sg), inet_ntoa(originator),
80 ifp->name);
81 }
82
83 memset(buffer, 0, 10000);
84 b1 = (uint8_t *)buffer + PIM_MSG_REGISTER_STOP_LEN;
85
86 length = pim_encode_addr_group(b1, AFI_IP, 0, 0, sg->grp);
87 b1length += length;
88 b1 += length;
89
90 p.family = AF_INET;
91 p.u.prefix4 = sg->src;
92 p.prefixlen = 32;
93 length = pim_encode_addr_ucast(b1, &p);
94 b1length += length;
95
96 pim_msg_build_header(buffer, b1length + PIM_MSG_REGISTER_STOP_LEN,
d57a8bbf 97 PIM_MSG_TYPE_REG_STOP, false);
d62a17ae 98
99 pinfo = (struct pim_interface *)ifp->info;
100 if (!pinfo) {
101 if (PIM_DEBUG_PIM_TRACE)
15569c58 102 zlog_debug("%s: No pinfo!", __func__);
d62a17ae 103 return;
13c2408c 104 }
d62a17ae 105 if (pim_msg_send(pinfo->pim_sock_fd, src, originator, buffer,
106 b1length + PIM_MSG_REGISTER_STOP_LEN, ifp->name)) {
107 if (PIM_DEBUG_PIM_TRACE) {
108 zlog_debug(
109 "%s: could not send PIM register stop message on interface %s",
15569c58 110 __func__, ifp->name);
d62a17ae 111 }
112 }
113 ++pinfo->pim_ifstat_reg_stop_send;
01d68c9b
DS
114}
115
b206566b 116int pim_register_stop_recv(struct interface *ifp, uint8_t *buf, int buf_size)
4dffc880 117{
b206566b
DS
118 struct pim_interface *pim_ifp = ifp->info;
119 struct pim_instance *pim = pim_ifp->pim;
d62a17ae 120 struct pim_upstream *upstream = NULL;
121 struct prefix source;
122 struct prefix_sg sg;
123 int l;
124
25ed72fe
SP
125 ++pim_ifp->pim_ifstat_reg_stop_recv;
126
d62a17ae 127 memset(&sg, 0, sizeof(struct prefix_sg));
128 l = pim_parse_addr_group(&sg, buf, buf_size);
129 buf += l;
130 buf_size -= l;
131 pim_parse_addr_ucast(&source, buf, buf_size);
132 sg.src = source.u.prefix4;
133
b206566b 134 upstream = pim_upstream_find(pim, &sg);
d62a17ae 135 if (!upstream) {
136 return 0;
137 }
138
139 if (PIM_DEBUG_PIM_REG)
140 zlog_debug("Received Register stop for %s", upstream->sg_str);
141
142 switch (upstream->reg_state) {
143 case PIM_REG_NOINFO:
144 case PIM_REG_PRUNE:
145 return 0;
d62a17ae 146 case PIM_REG_JOIN:
147 upstream->reg_state = PIM_REG_PRUNE;
b206566b 148 pim_channel_del_oif(upstream->channel_oil, pim->regiface,
1b249e70 149 PIM_OIF_FLAG_PROTO_PIM, __func__);
d62a17ae 150 pim_upstream_start_register_stop_timer(upstream, 0);
b9f3a51c 151 pim_vxlan_update_sg_reg_state(pim, upstream,
2951a7a4 152 false/*reg_join*/);
d62a17ae 153 break;
154 case PIM_REG_JOIN_PENDING:
155 upstream->reg_state = PIM_REG_PRUNE;
156 pim_upstream_start_register_stop_timer(upstream, 0);
157 return 0;
d62a17ae 158 }
159
160 return 0;
4dffc880
DS
161}
162
d62a17ae 163void pim_register_send(const uint8_t *buf, int buf_size, struct in_addr src,
164 struct pim_rpf *rpg, int null_register,
165 struct pim_upstream *up)
998af219 166{
d62a17ae 167 unsigned char buffer[10000];
168 unsigned char *b1;
169 struct pim_interface *pinfo;
170 struct interface *ifp;
171
172 if (PIM_DEBUG_PIM_REG) {
173 zlog_debug("Sending %s %sRegister Packet to %s", up->sg_str,
174 null_register ? "NULL " : "",
175 inet_ntoa(rpg->rpf_addr.u.prefix4));
176 }
177
178 ifp = rpg->source_nexthop.interface;
179 if (!ifp) {
180 if (PIM_DEBUG_PIM_REG)
181 zlog_debug("%s: No interface to transmit register on",
15569c58 182 __func__);
d62a17ae 183 return;
184 }
185 pinfo = (struct pim_interface *)ifp->info;
186 if (!pinfo) {
187 if (PIM_DEBUG_PIM_REG)
188 zlog_debug(
63efca0e 189 "%s: Interface: %s not configured for pim to transmit on!",
15569c58 190 __func__, ifp->name);
d62a17ae 191 return;
192 }
193
194 if (PIM_DEBUG_PIM_REG) {
195 char rp_str[INET_ADDRSTRLEN];
81c077d0
QY
196 strlcpy(rp_str, inet_ntoa(rpg->rpf_addr.u.prefix4),
197 sizeof(rp_str));
d62a17ae 198 zlog_debug("%s: Sending %s %sRegister Packet to %s on %s",
15569c58
DA
199 __func__, up->sg_str, null_register ? "NULL " : "",
200 rp_str, ifp->name);
d62a17ae 201 }
202
203 memset(buffer, 0, 10000);
204 b1 = buffer + PIM_MSG_HEADER_LEN;
205 *b1 |= null_register << 6;
206 b1 = buffer + PIM_MSG_REGISTER_LEN;
207
208 memcpy(b1, (const unsigned char *)buf, buf_size);
209
210 pim_msg_build_header(buffer, buf_size + PIM_MSG_REGISTER_LEN,
d57a8bbf 211 PIM_MSG_TYPE_REGISTER, false);
d62a17ae 212
213 ++pinfo->pim_ifstat_reg_send;
214
215 if (pim_msg_send(pinfo->pim_sock_fd, src, rpg->rpf_addr.u.prefix4,
216 buffer, buf_size + PIM_MSG_REGISTER_LEN, ifp->name)) {
217 if (PIM_DEBUG_PIM_TRACE) {
218 zlog_debug(
219 "%s: could not send PIM register message on interface %s",
15569c58 220 __func__, ifp->name);
d62a17ae 221 }
222 return;
223 }
998af219
DS
224}
225
aea1f845
AK
226void pim_null_register_send(struct pim_upstream *up)
227{
228 struct ip ip_hdr;
229 struct pim_interface *pim_ifp;
230 struct pim_rpf *rpg;
231 struct in_addr src;
232
233 pim_ifp = up->rpf.source_nexthop.interface->info;
234 if (!pim_ifp) {
23fc858a 235 if (PIM_DEBUG_PIM_TRACE)
aea1f845
AK
236 zlog_debug(
237 "%s: Cannot send null-register for %s no valid iif",
15569c58 238 __func__, up->sg_str);
aea1f845
AK
239 return;
240 }
241
242 rpg = RP(pim_ifp->pim, up->sg.grp);
243 if (!rpg) {
23fc858a 244 if (PIM_DEBUG_PIM_TRACE)
aea1f845
AK
245 zlog_debug(
246 "%s: Cannot send null-register for %s no RPF to the RP",
15569c58 247 __func__, up->sg_str);
aea1f845
AK
248 return;
249 }
250
251 memset(&ip_hdr, 0, sizeof(struct ip));
252 ip_hdr.ip_p = PIM_IP_PROTO_PIM;
253 ip_hdr.ip_hl = 5;
254 ip_hdr.ip_v = 4;
255 ip_hdr.ip_src = up->sg.src;
256 ip_hdr.ip_dst = up->sg.grp;
257 ip_hdr.ip_len = htons(20);
258
259 /* checksum is broken */
260 src = pim_ifp->primary_address;
d9e75668
AK
261 if (PIM_UPSTREAM_FLAG_TEST_SRC_VXLAN_ORIG(up->flags)) {
262 if (!pim_vxlan_get_register_src(pim_ifp->pim, up, &src)) {
23fc858a 263 if (PIM_DEBUG_PIM_TRACE)
d9e75668
AK
264 zlog_debug(
265 "%s: Cannot send null-register for %s vxlan-aa PIP unavailable",
15569c58 266 __func__, up->sg_str);
d9e75668
AK
267 return;
268 }
269 }
aea1f845
AK
270 pim_register_send((uint8_t *)&ip_hdr, sizeof(struct ip),
271 src, rpg, 1, up);
272}
273
01d68c9b
DS
274/*
275 * 4.4.2 Receiving Register Messages at the RP
276 *
277 * When an RP receives a Register message, the course of action is
278 * decided according to the following pseudocode:
279 *
280 * packet_arrives_on_rp_tunnel( pkt ) {
281 * if( outer.dst is not one of my addresses ) {
282 * drop the packet silently.
283 * # Note: this may be a spoofing attempt
284 * }
285 * if( I_am_RP(G) AND outer.dst == RP(G) ) {
2951a7a4
QY
286 * sentRegisterStop = false;
287 * if ( register.borderbit == true ) {
01d68c9b
DS
288 * if ( PMBR(S,G) == unknown ) {
289 * PMBR(S,G) = outer.src
290 * } else if ( outer.src != PMBR(S,G) ) {
291 * send Register-Stop(S,G) to outer.src
292 * drop the packet silently.
293 * }
294 * }
295 * if ( SPTbit(S,G) OR
296 * ( SwitchToSptDesired(S,G) AND
297 * ( inherited_olist(S,G) == NULL ))) {
298 * send Register-Stop(S,G) to outer.src
2951a7a4 299 * sentRegisterStop = true;
01d68c9b
DS
300 * }
301 * if ( SPTbit(S,G) OR SwitchToSptDesired(S,G) ) {
2951a7a4 302 * if ( sentRegisterStop == true ) {
01d68c9b
DS
303 * set KeepaliveTimer(S,G) to RP_Keepalive_Period;
304 * } else {
305 * set KeepaliveTimer(S,G) to Keepalive_Period;
306 * }
307 * }
308 * if( !SPTbit(S,G) AND ! pkt.NullRegisterBit ) {
309 * decapsulate and forward the inner packet to
310 * inherited_olist(S,G,rpt) # Note (+)
311 * }
312 * } else {
313 * send Register-Stop(S,G) to outer.src
314 * # Note (*)
315 * }
316 * }
317 */
d62a17ae 318int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,
319 struct in_addr src_addr, uint8_t *tlv_buf,
320 int tlv_buf_size)
01d68c9b 321{
d62a17ae 322 int sentRegisterStop = 0;
323 struct ip *ip_hdr;
324 struct prefix_sg sg;
325 uint32_t *bits;
326 int i_am_rp = 0;
2ca35b64
DS
327 struct pim_interface *pim_ifp = ifp->info;
328 struct pim_instance *pim = pim_ifp->pim;
fec883d9 329
75a26779 330#define PIM_MSG_REGISTER_BIT_RESERVED_LEN 4
d62a17ae 331 ip_hdr = (struct ip *)(tlv_buf + PIM_MSG_REGISTER_BIT_RESERVED_LEN);
332
2ca35b64 333 if (!pim_rp_check_is_my_ip_address(pim, dest_addr)) {
d62a17ae 334 if (PIM_DEBUG_PIM_REG) {
335 char dest[INET_ADDRSTRLEN];
336
337 pim_inet4_dump("<dst?>", dest_addr, dest, sizeof(dest));
338 zlog_debug(
f43593d9 339 "%s: Received Register message for destination address: %s that I do not own",
d62a17ae 340 __func__, dest);
341 }
342 return 0;
343 }
344
d62a17ae 345 ++pim_ifp->pim_ifstat_reg_recv;
346
347 /*
348 * Please note this is not drawn to get the correct bit/data size
349 *
350 * The entirety of the REGISTER packet looks like this:
351 * -------------------------------------------------------------
352 * | Ver | Type | Reserved | Checksum |
353 * |-----------------------------------------------------------|
354 * |B|N| Reserved 2 |
355 * |-----------------------------------------------------------|
356 * | Encap | IP HDR |
357 * | Mcast | |
358 * | Packet |--------------------------------------------------|
359 * | | Mcast Data |
360 * | | |
361 * ...
362 *
363 * tlv_buf when received from the caller points at the B bit
364 * We need to know the inner source and dest
365 */
366 bits = (uint32_t *)tlv_buf;
367
368 /*
369 * tlv_buf points to the start of the |B|N|... Reserved
370 * Line above. So we need to add 4 bytes to get to the
371 * start of the actual Encapsulated data.
372 */
373 memset(&sg, 0, sizeof(struct prefix_sg));
374 sg.src = ip_hdr->ip_src;
375 sg.grp = ip_hdr->ip_dst;
376
2ca35b64 377 i_am_rp = I_am_RP(pim, sg.grp);
d62a17ae 378
379 if (PIM_DEBUG_PIM_REG) {
380 char src_str[INET_ADDRSTRLEN];
381
382 pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
41714081
DS
383 zlog_debug("Received Register message%s from %s on %s, rp: %d",
384 pim_str_sg_dump(&sg), src_str, ifp->name, i_am_rp);
d62a17ae 385 }
386
fec883d9
DS
387 if (i_am_rp
388 && (dest_addr.s_addr
2ca35b64 389 == ((RP(pim, sg.grp))->rpf_addr.u.prefix4.s_addr))) {
d62a17ae 390 sentRegisterStop = 0;
391
f4e74bd0
DS
392 if (pim->register_plist) {
393 struct prefix_list *plist;
394 struct prefix src;
395
396 plist = prefix_list_lookup(AFI_IP, pim->register_plist);
397
398 src.family = AF_INET;
399 src.prefixlen = IPV4_MAX_PREFIXLEN;
400 src.u.prefix4 = sg.src;
401
402 if (prefix_list_apply(plist, &src) == PREFIX_DENY) {
403 pim_register_stop_send(ifp, &sg, dest_addr,
404 src_addr);
405 if (PIM_DEBUG_PIM_PACKETS) {
406 char src_str[INET_ADDRSTRLEN];
407
408 pim_inet4_dump("<src?>", src_addr,
409 src_str,
410 sizeof(src_str));
411 zlog_debug("%s: Sending register-stop to %s for %pSG4 due to prefix-list denial, dropping packet",
412 __func__, src_str, &sg);
413 }
414
415 return 0;
416 }
417 }
418
d62a17ae 419 if (*bits & PIM_REGISTER_BORDER_BIT) {
420 struct in_addr pimbr = pim_br_get_pmbr(&sg);
421 if (PIM_DEBUG_PIM_PACKETS)
422 zlog_debug(
423 "%s: Received Register message with Border bit set",
424 __func__);
425
426 if (pimbr.s_addr == pim_br_unknown.s_addr)
427 pim_br_set_pmbr(&sg, src_addr);
428 else if (src_addr.s_addr != pimbr.s_addr) {
429 pim_register_stop_send(ifp, &sg, dest_addr,
430 src_addr);
431 if (PIM_DEBUG_PIM_PACKETS)
432 zlog_debug(
433 "%s: Sending register-Stop to %s and dropping mr. packet",
434 __func__, "Sender");
435 /* Drop Packet Silently */
436 return 0;
437 }
438 }
439
2ca35b64 440 struct pim_upstream *upstream = pim_upstream_find(pim, &sg);
d62a17ae 441 /*
442 * If we don't have a place to send ignore the packet
443 */
444 if (!upstream) {
445 upstream = pim_upstream_add(
2ca35b64 446 pim, &sg, ifp,
15569c58
DA
447 PIM_UPSTREAM_FLAG_MASK_SRC_STREAM, __func__,
448 NULL);
d62a17ae 449 if (!upstream) {
450 zlog_warn("Failure to create upstream state");
451 return 1;
452 }
453
454 upstream->upstream_register = src_addr;
cc61055f
DS
455 } else {
456 /*
457 * If the FHR has set a very very fast register timer
458 * there exists a possibility that the incoming NULL
459 * register
460 * is happening before we set the spt bit. If so
461 * Do a quick check to update the counters and
462 * then set the spt bit as appropriate
463 */
464 if (upstream->sptbit != PIM_UPSTREAM_SPTBIT_TRUE) {
465 pim_mroute_update_counters(
466 upstream->channel_oil);
467 /*
468 * Have we seen packets?
469 */
470 if (upstream->channel_oil->cc.oldpktcnt
471 < upstream->channel_oil->cc.pktcnt)
472 pim_upstream_set_sptbit(
473 upstream,
474 upstream->rpf.source_nexthop
475 .interface);
476 }
d62a17ae 477 }
478
479 if ((upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE)
2ca35b64
DS
480 || ((SwitchToSptDesiredOnRp(pim, &sg))
481 && pim_upstream_inherited_olist(pim, upstream) == 0)) {
d62a17ae 482 pim_register_stop_send(ifp, &sg, dest_addr, src_addr);
483 sentRegisterStop = 1;
484 } else {
485 if (PIM_DEBUG_PIM_REG)
486 zlog_debug("(%s) sptbit: %d", upstream->sg_str,
487 upstream->sptbit);
488 }
489 if ((upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE)
2ca35b64 490 || (SwitchToSptDesiredOnRp(pim, &sg))) {
d62a17ae 491 if (sentRegisterStop) {
492 pim_upstream_keep_alive_timer_start(
2ca35b64 493 upstream, pim->rp_keep_alive_time);
d62a17ae 494 } else {
495 pim_upstream_keep_alive_timer_start(
2ca35b64 496 upstream, pim->keep_alive_time);
d62a17ae 497 }
498 }
499
500 if (!(upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE)
501 && !(*bits & PIM_REGISTER_NR_BIT)) {
502 // decapsulate and forward the iner packet to
503 // inherited_olist(S,G,rpt)
504 // This is taken care of by the kernel for us
505 }
506 pim_upstream_msdp_reg_timer_start(upstream);
507 } else {
508 if (PIM_DEBUG_PIM_REG) {
509 if (!i_am_rp)
510 zlog_debug(
511 "Received Register packet for %s, Rejecting packet because I am not the RP configured for group",
512 pim_str_sg_dump(&sg));
513 else
514 zlog_debug(
515 "Received Register packet for %s, Rejecting packet because the dst ip address is not the actual RP",
516 pim_str_sg_dump(&sg));
517 }
518 pim_register_stop_send(ifp, &sg, dest_addr, src_addr);
519 }
520
8dc60b69 521 return 0;
01d68c9b 522}
46a9ea8b 523
524/*
525 * This routine scan all upstream and update register state and remove pimreg
526 * when couldreg becomes false.
527 */
528void pim_reg_del_on_couldreg_fail(struct interface *ifp)
529{
530 struct pim_interface *pim_ifp = ifp->info;
531 struct pim_instance *pim;
532 struct pim_upstream *up;
533
534 if (!pim_ifp)
535 return;
536
537 pim = pim_ifp->pim;
538
539 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
540 if (ifp != up->rpf.source_nexthop.interface)
541 continue;
542
543 if (!pim_upstream_could_register(up)
544 && (up->reg_state != PIM_REG_NOINFO)) {
545 pim_channel_del_oif(up->channel_oil, pim->regiface,
546 PIM_OIF_FLAG_PROTO_PIM, __func__);
547 THREAD_OFF(up->t_rs_timer);
548 up->reg_state = PIM_REG_NOINFO;
549 }
550 }
551}