]> git.proxmox.com Git - mirror_frr.git/blame - pimd/pim_register.c
Merge branch 'frr/pull/546' ("bgpd: resolve issue with sending vpn labels")
[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"
01d68c9b
DS
46
47struct thread *send_test_packet_timer = NULL;
48
15a5dafe 49void
50pim_register_join (struct pim_upstream *up)
51{
52 if (pim_is_grp_ssm (up->sg.grp))
53 {
54 if (PIM_DEBUG_PIM_EVENTS)
55 zlog_debug ("%s register setup skipped as group is SSM", up->sg_str);
19f4e33a 56 return;
15a5dafe 57 }
58
59 pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM);
60 up->reg_state = PIM_REG_JOIN;
61}
62
8e38a2cf 63void
4ed0af70 64pim_register_stop_send (struct interface *ifp, struct prefix_sg *sg,
4df01a4e 65 struct in_addr src, struct in_addr originator)
01d68c9b 66{
13c2408c 67 struct pim_interface *pinfo;
19e55095 68 unsigned char buffer[10000];
13c2408c
DS
69 unsigned int b1length = 0;
70 unsigned int length;
71 uint8_t *b1;
72 struct prefix p;
73
9add3b88
DS
74 if (PIM_DEBUG_PIM_REG)
75 {
76 zlog_debug ("Sending Register stop for %s to %s on %s",
77 pim_str_sg_dump (sg), inet_ntoa(originator), ifp->name);
78 }
79
19e55095 80 memset (buffer, 0, 10000);
13c2408c
DS
81 b1 = (uint8_t *)buffer + PIM_MSG_REGISTER_STOP_LEN;
82
4ed0af70 83 length = pim_encode_addr_group (b1, AFI_IP, 0, 0, sg->grp);
13c2408c
DS
84 b1length += length;
85 b1 += length;
86
87 p.family = AF_INET;
4ed0af70 88 p.u.prefix4 = sg->src;
13c2408c
DS
89 p.prefixlen = 32;
90 length = pim_encode_addr_ucast (b1, &p);
91 b1length += length;
92
93 pim_msg_build_header (buffer, b1length + PIM_MSG_REGISTER_STOP_LEN, PIM_MSG_TYPE_REG_STOP);
94
95 pinfo = (struct pim_interface *)ifp->info;
96 if (!pinfo)
97 {
98 if (PIM_DEBUG_PIM_TRACE)
99 zlog_debug ("%s: No pinfo!\n", __PRETTY_FUNCTION__);
100 return;
101 }
4df01a4e 102 if (pim_msg_send (pinfo->pim_sock_fd, src, originator,
13c2408c
DS
103 buffer, b1length + PIM_MSG_REGISTER_STOP_LEN,
104 ifp->name))
105 {
106 if (PIM_DEBUG_PIM_TRACE)
107 {
108 zlog_debug ("%s: could not send PIM register stop message on interface %s",
109 __PRETTY_FUNCTION__, ifp->name);
110 }
111 }
39438188 112 ++pinfo->pim_ifstat_reg_stop_send;
01d68c9b
DS
113}
114
4dffc880 115int
56638739 116pim_register_stop_recv (uint8_t *buf, int buf_size)
4dffc880 117{
56638739
DS
118 struct pim_upstream *upstream = NULL;
119 struct prefix source;
4ed0af70 120 struct prefix_sg sg;
56638739
DS
121 int l;
122
53e39e14 123 memset (&sg, 0, sizeof (struct prefix_sg));
bce0e645 124 l = pim_parse_addr_group (&sg, buf, buf_size);
56638739
DS
125 buf += l;
126 buf_size -= l;
a878ba45 127 pim_parse_addr_ucast (&source, buf, buf_size);
4ed0af70 128 sg.src = source.u.prefix4;
9add3b88 129
5074a423 130 upstream = pim_upstream_find (&sg);
56638739
DS
131 if (!upstream)
132 {
133 return 0;
134 }
135
8bfb8b67
DS
136 if (PIM_DEBUG_PIM_REG)
137 zlog_debug ("Received Register stop for %s",
138 upstream->sg_str);
139
e0e127b0 140 switch (upstream->reg_state)
56638739 141 {
0c2ebf00 142 case PIM_REG_NOINFO:
143 case PIM_REG_PRUNE:
56638739
DS
144 return 0;
145 break;
0c2ebf00 146 case PIM_REG_JOIN:
147 upstream->reg_state = PIM_REG_PRUNE;
bb027ee8
DS
148 pim_channel_del_oif (upstream->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM);
149 pim_upstream_start_register_stop_timer (upstream, 0);
35661ffa 150 break;
0c2ebf00 151 case PIM_REG_JOIN_PENDING:
152 upstream->reg_state = PIM_REG_PRUNE;
56638739 153 pim_upstream_start_register_stop_timer (upstream, 0);
56638739
DS
154 return 0;
155 break;
156 }
157
4dffc880
DS
158 return 0;
159}
160
998af219 161void
0e3b3d5d 162pim_register_send (const uint8_t *buf, int buf_size, struct in_addr src, struct pim_rpf *rpg, int null_register, struct pim_upstream *up)
998af219 163{
19e55095 164 unsigned char buffer[10000];
998af219
DS
165 unsigned char *b1;
166 struct pim_interface *pinfo;
167 struct interface *ifp;
998af219 168
9add3b88
DS
169 if (PIM_DEBUG_PIM_REG)
170 {
0e3b3d5d 171 zlog_debug ("Sending %s %sRegister Packet to %s",
35661ffa
DS
172 up->sg_str, null_register ? "NULL " : "",
173 inet_ntoa (rpg->rpf_addr.u.prefix4));
9add3b88
DS
174 }
175
998af219 176 ifp = rpg->source_nexthop.interface;
63b8f7a3
DS
177 if (!ifp)
178 {
179 if (PIM_DEBUG_PIM_REG)
180 zlog_debug ("%s: No interface to transmit register on", __PRETTY_FUNCTION__);
181 return;
182 }
998af219
DS
183 pinfo = (struct pim_interface *)ifp->info;
184 if (!pinfo) {
63b8f7a3
DS
185 if (PIM_DEBUG_PIM_REG)
186 zlog_debug("%s: Interface: %s not configured for pim to trasmit on!\n", __PRETTY_FUNCTION__, ifp->name);
998af219
DS
187 return;
188 }
189
633988a7
CS
190 if (PIM_DEBUG_PIM_REG)
191 {
192 char rp_str[INET_ADDRSTRLEN];
36b1fa86 193 strncpy (rp_str, inet_ntoa (rpg->rpf_addr.u.prefix4), INET_ADDRSTRLEN-1);
633988a7
CS
194 zlog_debug ("%s: Sending %s %sRegister Packet to %s on %s",
195 __PRETTY_FUNCTION__, up->sg_str,
196 null_register ? "NULL " : "", rp_str, ifp->name);
197 }
198
19e55095 199 memset(buffer, 0, 10000);
b100a4f5 200 b1 = buffer + PIM_MSG_HEADER_LEN;
dc686f82 201 *b1 |= null_register << 6;
998af219
DS
202 b1 = buffer + PIM_MSG_REGISTER_LEN;
203
b100a4f5 204 memcpy(b1, (const unsigned char *)buf, buf_size);
998af219 205
b100a4f5 206 pim_msg_build_header(buffer, buf_size + PIM_MSG_REGISTER_LEN, PIM_MSG_TYPE_REGISTER);
998af219 207
39438188
CS
208 ++pinfo->pim_ifstat_reg_send;
209
998af219 210 if (pim_msg_send(pinfo->pim_sock_fd,
4df01a4e 211 src,
63c59d0c 212 rpg->rpf_addr.u.prefix4,
998af219 213 buffer,
b100a4f5 214 buf_size + PIM_MSG_REGISTER_LEN,
998af219
DS
215 ifp->name)) {
216 if (PIM_DEBUG_PIM_TRACE) {
217 zlog_debug("%s: could not send PIM register message on interface %s",
218 __PRETTY_FUNCTION__, ifp->name);
219 }
220 return;
221 }
222}
223
01d68c9b
DS
224/*
225 * 4.4.2 Receiving Register Messages at the RP
226 *
227 * When an RP receives a Register message, the course of action is
228 * decided according to the following pseudocode:
229 *
230 * packet_arrives_on_rp_tunnel( pkt ) {
231 * if( outer.dst is not one of my addresses ) {
232 * drop the packet silently.
233 * # Note: this may be a spoofing attempt
234 * }
235 * if( I_am_RP(G) AND outer.dst == RP(G) ) {
236 * sentRegisterStop = FALSE;
237 * if ( register.borderbit == TRUE ) {
238 * if ( PMBR(S,G) == unknown ) {
239 * PMBR(S,G) = outer.src
240 * } else if ( outer.src != PMBR(S,G) ) {
241 * send Register-Stop(S,G) to outer.src
242 * drop the packet silently.
243 * }
244 * }
245 * if ( SPTbit(S,G) OR
246 * ( SwitchToSptDesired(S,G) AND
247 * ( inherited_olist(S,G) == NULL ))) {
248 * send Register-Stop(S,G) to outer.src
249 * sentRegisterStop = TRUE;
250 * }
251 * if ( SPTbit(S,G) OR SwitchToSptDesired(S,G) ) {
252 * if ( sentRegisterStop == TRUE ) {
253 * set KeepaliveTimer(S,G) to RP_Keepalive_Period;
254 * } else {
255 * set KeepaliveTimer(S,G) to Keepalive_Period;
256 * }
257 * }
258 * if( !SPTbit(S,G) AND ! pkt.NullRegisterBit ) {
259 * decapsulate and forward the inner packet to
260 * inherited_olist(S,G,rpt) # Note (+)
261 * }
262 * } else {
263 * send Register-Stop(S,G) to outer.src
264 * # Note (*)
265 * }
266 * }
267 */
268int
269pim_register_recv (struct interface *ifp,
270 struct in_addr dest_addr,
271 struct in_addr src_addr,
272 uint8_t *tlv_buf, int tlv_buf_size)
273{
77e390e5
DS
274 int sentRegisterStop = 0;
275 struct ip *ip_hdr;
4ed0af70 276 struct prefix_sg sg;
77e390e5 277 uint32_t *bits;
a6dc7de6 278 int i_am_rp = 0;
39438188 279 struct pim_interface *pim_ifp = NULL;
01d68c9b 280
75a26779
DS
281#define PIM_MSG_REGISTER_BIT_RESERVED_LEN 4
282 ip_hdr = (struct ip *)(tlv_buf + PIM_MSG_REGISTER_BIT_RESERVED_LEN);
283
284 if (!pim_rp_check_is_my_ip_address (ip_hdr->ip_dst, dest_addr)) {
d41b415c 285 if (PIM_DEBUG_PIM_REG) {
eaa54bdb 286 char dest[INET_ADDRSTRLEN];
01d68c9b
DS
287
288 pim_inet4_dump ("<dst?>", dest_addr, dest, sizeof(dest));
289 zlog_debug ("%s: Received Register message for %s that I do not own", __func__,
290 dest);
291 }
292 return 0;
293 }
294
39438188
CS
295 pim_ifp = ifp->info;
296 zassert(pim_ifp);
297 ++pim_ifp->pim_ifstat_reg_recv;
298
77e390e5
DS
299 /*
300 * Please note this is not drawn to get the correct bit/data size
301 *
302 * The entirety of the REGISTER packet looks like this:
303 * -------------------------------------------------------------
304 * | Ver | Type | Reserved | Checksum |
305 * |-----------------------------------------------------------|
306 * |B|N| Reserved 2 |
307 * |-----------------------------------------------------------|
308 * | Encap | IP HDR |
309 * | Mcast | |
310 * | Packet |--------------------------------------------------|
311 * | | Mcast Data |
312 * | | |
313 * ...
314 *
315 * tlv_buf when received from the caller points at the B bit
316 * We need to know the inner source and dest
317 */
318 bits = (uint32_t *)tlv_buf;
83d8ff00
DS
319
320 /*
321 * tlv_buf points to the start of the |B|N|... Reserved
322 * Line above. So we need to add 4 bytes to get to the
323 * start of the actual Encapsulated data.
324 */
4ed0af70
DS
325 memset (&sg, 0, sizeof (struct prefix_sg));
326 sg.src = ip_hdr->ip_src;
327 sg.grp = ip_hdr->ip_dst;
77e390e5 328
a6dc7de6 329 i_am_rp = I_am_RP (sg.grp);
5d84a3bc
DS
330
331 if (PIM_DEBUG_PIM_REG)
332 {
333 char src_str[INET_ADDRSTRLEN];
334
335 pim_inet4_dump ("<src?>", src_addr, src_str, sizeof (src_str));
336 zlog_debug ("Received Register message(%s) from %s on %s, rp: %d",
337 pim_str_sg_dump (&sg), src_str, ifp->name, i_am_rp);
338 }
339
a6dc7de6 340 if (i_am_rp && (dest_addr.s_addr == ((RP (sg.grp))->rpf_addr.u.prefix4.s_addr))) {
77e390e5 341 sentRegisterStop = 0;
01d68c9b 342
9eda95bd 343 if (*bits & PIM_REGISTER_BORDER_BIT) {
65e1fcd7 344 struct in_addr pimbr = pim_br_get_pmbr (&sg);
01d68c9b
DS
345 if (PIM_DEBUG_PIM_PACKETS)
346 zlog_debug("%s: Received Register message with Border bit set", __func__);
347
348 if (pimbr.s_addr == pim_br_unknown.s_addr)
65e1fcd7 349 pim_br_set_pmbr(&sg, src_addr);
80c0d168 350 else if (src_addr.s_addr != pimbr.s_addr) {
4df01a4e 351 pim_register_stop_send (ifp, &sg, dest_addr, src_addr);
01d68c9b
DS
352 if (PIM_DEBUG_PIM_PACKETS)
353 zlog_debug("%s: Sending register-Stop to %s and dropping mr. packet",
354 __func__, "Sender");
77e390e5
DS
355 /* Drop Packet Silently */
356 return 1;
01d68c9b
DS
357 }
358 }
77e390e5 359
5074a423 360 struct pim_upstream *upstream = pim_upstream_find (&sg);
77e390e5
DS
361 /*
362 * If we don't have a place to send ignore the packet
363 */
364 if (!upstream)
9fd309db 365 {
4a57e76a
DS
366 upstream = pim_upstream_add (&sg, ifp,
367 PIM_UPSTREAM_FLAG_MASK_SRC_STREAM,
368 __PRETTY_FUNCTION__);
4e85d209
DS
369 if (!upstream)
370 {
63b8f7a3 371 zlog_warn ("Failure to create upstream state");
4e85d209
DS
372 return 1;
373 }
5ce79466 374
8e38a2cf 375 upstream->upstream_register = src_addr;
9fd309db
DS
376 }
377
77e390e5 378 if ((upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE) ||
ad410c6c 379 ((SwitchToSptDesired(&sg)) &&
4fdc8f36 380 pim_upstream_inherited_olist (upstream) == 0)) {
216bb84f 381 //pim_scan_individual_oil (upstream->channel_oil);
4df01a4e 382 pim_register_stop_send (ifp, &sg, dest_addr, src_addr);
77e390e5 383 sentRegisterStop = 1;
5d84a3bc
DS
384 } else {
385 if (PIM_DEBUG_PIM_REG)
8bfb8b67 386 zlog_debug ("(%s) sptbit: %d", upstream->sg_str, upstream->sptbit);
77e390e5 387 }
77e390e5 388 if ((upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE) ||
ad410c6c 389 (SwitchToSptDesired(&sg))) {
80c0d168 390 if (sentRegisterStop) {
01408ede 391 pim_upstream_keep_alive_timer_start (upstream, qpim_rp_keep_alive_time);
77e390e5 392 } else {
4304f95c 393 pim_upstream_keep_alive_timer_start (upstream, qpim_keep_alive_time);
77e390e5
DS
394 }
395 }
396
397 if (!(upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE) &&
2ca35b3d
DS
398 !(*bits & PIM_REGISTER_NR_BIT))
399 {
2ca35b3d
DS
400 //decapsulate and forward the iner packet to
401 //inherited_olist(S,G,rpt)
0365f56b 402 // This is taken care of by the kernel for us
2ca35b3d 403 }
1bf16443 404 pim_upstream_msdp_reg_timer_start(upstream);
77e390e5 405 } else {
a6dc7de6
DS
406 if (PIM_DEBUG_PIM_REG)
407 {
408 if (!i_am_rp)
409 zlog_debug ("Received Register packet for %s, Rejecting packet because I am not the RP configured for group",
410 pim_str_sg_dump (&sg));
411 else
412 zlog_debug ("Received Register packet for %s, Rejecting packet because the dst ip address is not the actual RP",
413 pim_str_sg_dump (&sg));
414 }
4df01a4e 415 pim_register_stop_send (ifp, &sg, dest_addr, src_addr);
77e390e5 416 }
01d68c9b
DS
417
418 return 1;
419}