3 * Copyright (C) 2015 Cumulus Networks, Inc.
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.
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.
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
31 #include "pim_mroute.h"
32 #include "pim_iface.h"
37 #include "pim_register.h"
38 #include "pim_upstream.h"
42 #include "pim_zebra.h"
46 #include "pim_vxlan.h"
48 struct thread
*send_test_packet_timer
= NULL
;
50 void pim_register_join(struct pim_upstream
*up
)
52 struct pim_instance
*pim
= up
->channel_oil
->pim
;
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",
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 /*reg_join*/);
67 void pim_register_stop_send(struct interface
*ifp
, struct prefix_sg
*sg
,
68 struct in_addr src
, struct in_addr originator
)
70 struct pim_interface
*pinfo
;
71 unsigned char buffer
[10000];
72 unsigned int b1length
= 0;
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
),
83 memset(buffer
, 0, 10000);
84 b1
= (uint8_t *)buffer
+ PIM_MSG_REGISTER_STOP_LEN
;
86 length
= pim_encode_addr_group(b1
, AFI_IP
, 0, 0, sg
->grp
);
91 p
.u
.prefix4
= sg
->src
;
93 length
= pim_encode_addr_ucast(b1
, &p
);
96 pim_msg_build_header(buffer
, b1length
+ PIM_MSG_REGISTER_STOP_LEN
,
97 PIM_MSG_TYPE_REG_STOP
, false);
99 pinfo
= (struct pim_interface
*)ifp
->info
;
101 if (PIM_DEBUG_PIM_TRACE
)
102 zlog_debug("%s: No pinfo!", __func__
);
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
) {
109 "%s: could not send PIM register stop message on interface %s",
110 __func__
, ifp
->name
);
113 ++pinfo
->pim_ifstat_reg_stop_send
;
116 int pim_register_stop_recv(struct interface
*ifp
, uint8_t *buf
, int buf_size
)
118 struct pim_interface
*pim_ifp
= ifp
->info
;
119 struct pim_instance
*pim
= pim_ifp
->pim
;
120 struct pim_upstream
*upstream
= NULL
;
121 struct prefix source
;
125 ++pim_ifp
->pim_ifstat_reg_stop_recv
;
127 memset(&sg
, 0, sizeof(struct prefix_sg
));
128 l
= pim_parse_addr_group(&sg
, buf
, buf_size
);
131 pim_parse_addr_ucast(&source
, buf
, buf_size
);
132 sg
.src
= source
.u
.prefix4
;
134 upstream
= pim_upstream_find(pim
, &sg
);
139 if (PIM_DEBUG_PIM_REG
)
140 zlog_debug("Received Register stop for %s", upstream
->sg_str
);
142 switch (upstream
->reg_state
) {
147 upstream
->reg_state
= PIM_REG_PRUNE
;
148 pim_channel_del_oif(upstream
->channel_oil
, pim
->regiface
,
149 PIM_OIF_FLAG_PROTO_PIM
, __func__
);
150 pim_upstream_start_register_stop_timer(upstream
, 0);
151 pim_vxlan_update_sg_reg_state(pim
, upstream
,
154 case PIM_REG_JOIN_PENDING
:
155 upstream
->reg_state
= PIM_REG_PRUNE
;
156 pim_upstream_start_register_stop_timer(upstream
, 0);
163 void 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
)
167 unsigned char buffer
[10000];
169 struct pim_interface
*pinfo
;
170 struct interface
*ifp
;
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
));
178 ifp
= rpg
->source_nexthop
.interface
;
180 if (PIM_DEBUG_PIM_REG
)
181 zlog_debug("%s: No interface to transmit register on",
185 pinfo
= (struct pim_interface
*)ifp
->info
;
187 if (PIM_DEBUG_PIM_REG
)
189 "%s: Interface: %s not configured for pim to transmit on!",
190 __func__
, ifp
->name
);
194 if (PIM_DEBUG_PIM_REG
) {
195 char rp_str
[INET_ADDRSTRLEN
];
196 strlcpy(rp_str
, inet_ntoa(rpg
->rpf_addr
.u
.prefix4
),
198 zlog_debug("%s: Sending %s %sRegister Packet to %s on %s",
199 __func__
, up
->sg_str
, null_register
? "NULL " : "",
203 memset(buffer
, 0, 10000);
204 b1
= buffer
+ PIM_MSG_HEADER_LEN
;
205 *b1
|= null_register
<< 6;
206 b1
= buffer
+ PIM_MSG_REGISTER_LEN
;
208 memcpy(b1
, (const unsigned char *)buf
, buf_size
);
210 pim_msg_build_header(buffer
, buf_size
+ PIM_MSG_REGISTER_LEN
,
211 PIM_MSG_TYPE_REGISTER
, false);
213 ++pinfo
->pim_ifstat_reg_send
;
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
) {
219 "%s: could not send PIM register message on interface %s",
220 __func__
, ifp
->name
);
226 void pim_null_register_send(struct pim_upstream
*up
)
229 struct pim_interface
*pim_ifp
;
233 pim_ifp
= up
->rpf
.source_nexthop
.interface
->info
;
235 if (PIM_DEBUG_PIM_TRACE
)
237 "%s: Cannot send null-register for %s no valid iif",
238 __func__
, up
->sg_str
);
242 rpg
= RP(pim_ifp
->pim
, up
->sg
.grp
);
244 if (PIM_DEBUG_PIM_TRACE
)
246 "%s: Cannot send null-register for %s no RPF to the RP",
247 __func__
, up
->sg_str
);
251 memset(&ip_hdr
, 0, sizeof(struct ip
));
252 ip_hdr
.ip_p
= PIM_IP_PROTO_PIM
;
255 ip_hdr
.ip_src
= up
->sg
.src
;
256 ip_hdr
.ip_dst
= up
->sg
.grp
;
257 ip_hdr
.ip_len
= htons(20);
259 /* checksum is broken */
260 src
= pim_ifp
->primary_address
;
261 if (PIM_UPSTREAM_FLAG_TEST_SRC_VXLAN_ORIG(up
->flags
)) {
262 if (!pim_vxlan_get_register_src(pim_ifp
->pim
, up
, &src
)) {
263 if (PIM_DEBUG_PIM_TRACE
)
265 "%s: Cannot send null-register for %s vxlan-aa PIP unavailable",
266 __func__
, up
->sg_str
);
270 pim_register_send((uint8_t *)&ip_hdr
, sizeof(struct ip
),
275 * 4.4.2 Receiving Register Messages at the RP
277 * When an RP receives a Register message, the course of action is
278 * decided according to the following pseudocode:
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
285 * if( I_am_RP(G) AND outer.dst == RP(G) ) {
286 * sentRegisterStop = false;
287 * if ( register.borderbit == true ) {
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.
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
299 * sentRegisterStop = true;
301 * if ( SPTbit(S,G) OR SwitchToSptDesired(S,G) ) {
302 * if ( sentRegisterStop == true ) {
303 * set KeepaliveTimer(S,G) to RP_Keepalive_Period;
305 * set KeepaliveTimer(S,G) to Keepalive_Period;
308 * if( !SPTbit(S,G) AND ! pkt.NullRegisterBit ) {
309 * decapsulate and forward the inner packet to
310 * inherited_olist(S,G,rpt) # Note (+)
313 * send Register-Stop(S,G) to outer.src
318 int pim_register_recv(struct interface
*ifp
, struct in_addr dest_addr
,
319 struct in_addr src_addr
, uint8_t *tlv_buf
,
322 int sentRegisterStop
= 0;
327 struct pim_interface
*pim_ifp
= ifp
->info
;
328 struct pim_instance
*pim
= pim_ifp
->pim
;
330 #define PIM_MSG_REGISTER_BIT_RESERVED_LEN 4
331 ip_hdr
= (struct ip
*)(tlv_buf
+ PIM_MSG_REGISTER_BIT_RESERVED_LEN
);
333 if (!pim_rp_check_is_my_ip_address(pim
, dest_addr
)) {
334 if (PIM_DEBUG_PIM_REG
) {
335 char dest
[INET_ADDRSTRLEN
];
337 pim_inet4_dump("<dst?>", dest_addr
, dest
, sizeof(dest
));
339 "%s: Received Register message for destination address: %s that I do not own",
345 ++pim_ifp
->pim_ifstat_reg_recv
;
348 * Please note this is not drawn to get the correct bit/data size
350 * The entirety of the REGISTER packet looks like this:
351 * -------------------------------------------------------------
352 * | Ver | Type | Reserved | Checksum |
353 * |-----------------------------------------------------------|
355 * |-----------------------------------------------------------|
358 * | Packet |--------------------------------------------------|
363 * tlv_buf when received from the caller points at the B bit
364 * We need to know the inner source and dest
366 bits
= (uint32_t *)tlv_buf
;
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.
373 memset(&sg
, 0, sizeof(struct prefix_sg
));
374 sg
.src
= ip_hdr
->ip_src
;
375 sg
.grp
= ip_hdr
->ip_dst
;
377 i_am_rp
= I_am_RP(pim
, sg
.grp
);
379 if (PIM_DEBUG_PIM_REG
) {
380 char src_str
[INET_ADDRSTRLEN
];
382 pim_inet4_dump("<src?>", src_addr
, src_str
, sizeof(src_str
));
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
);
389 == ((RP(pim
, sg
.grp
))->rpf_addr
.u
.prefix4
.s_addr
))) {
390 sentRegisterStop
= 0;
392 if (pim
->register_plist
) {
393 struct prefix_list
*plist
;
396 plist
= prefix_list_lookup(AFI_IP
, pim
->register_plist
);
398 src
.family
= AF_INET
;
399 src
.prefixlen
= IPV4_MAX_PREFIXLEN
;
400 src
.u
.prefix4
= sg
.src
;
402 if (prefix_list_apply(plist
, &src
) == PREFIX_DENY
) {
403 pim_register_stop_send(ifp
, &sg
, dest_addr
,
405 if (PIM_DEBUG_PIM_PACKETS
) {
406 char src_str
[INET_ADDRSTRLEN
];
408 pim_inet4_dump("<src?>", src_addr
,
411 zlog_debug("%s: Sending register-stop to %s for %pSG4 due to prefix-list denial, dropping packet",
412 __func__
, src_str
, &sg
);
419 if (*bits
& PIM_REGISTER_BORDER_BIT
) {
420 struct in_addr pimbr
= pim_br_get_pmbr(&sg
);
421 if (PIM_DEBUG_PIM_PACKETS
)
423 "%s: Received Register message with Border bit set",
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
,
431 if (PIM_DEBUG_PIM_PACKETS
)
433 "%s: Sending register-Stop to %s and dropping mr. packet",
435 /* Drop Packet Silently */
440 struct pim_upstream
*upstream
= pim_upstream_find(pim
, &sg
);
442 * If we don't have a place to send ignore the packet
445 upstream
= pim_upstream_add(
447 PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
, __func__
,
450 zlog_warn("Failure to create upstream state");
454 upstream
->upstream_register
= src_addr
;
457 * If the FHR has set a very very fast register timer
458 * there exists a possibility that the incoming NULL
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
464 if (upstream
->sptbit
!= PIM_UPSTREAM_SPTBIT_TRUE
) {
465 pim_mroute_update_counters(
466 upstream
->channel_oil
);
468 * Have we seen packets?
470 if (upstream
->channel_oil
->cc
.oldpktcnt
471 < upstream
->channel_oil
->cc
.pktcnt
)
472 pim_upstream_set_sptbit(
474 upstream
->rpf
.source_nexthop
479 if ((upstream
->sptbit
== PIM_UPSTREAM_SPTBIT_TRUE
)
480 || ((SwitchToSptDesiredOnRp(pim
, &sg
))
481 && pim_upstream_inherited_olist(pim
, upstream
) == 0)) {
482 pim_register_stop_send(ifp
, &sg
, dest_addr
, src_addr
);
483 sentRegisterStop
= 1;
485 if (PIM_DEBUG_PIM_REG
)
486 zlog_debug("(%s) sptbit: %d", upstream
->sg_str
,
489 if ((upstream
->sptbit
== PIM_UPSTREAM_SPTBIT_TRUE
)
490 || (SwitchToSptDesiredOnRp(pim
, &sg
))) {
491 if (sentRegisterStop
) {
492 pim_upstream_keep_alive_timer_start(
493 upstream
, pim
->rp_keep_alive_time
);
495 pim_upstream_keep_alive_timer_start(
496 upstream
, pim
->keep_alive_time
);
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
506 pim_upstream_msdp_reg_timer_start(upstream
);
508 if (PIM_DEBUG_PIM_REG
) {
511 "Received Register packet for %s, Rejecting packet because I am not the RP configured for group",
512 pim_str_sg_dump(&sg
));
515 "Received Register packet for %s, Rejecting packet because the dst ip address is not the actual RP",
516 pim_str_sg_dump(&sg
));
518 pim_register_stop_send(ifp
, &sg
, dest_addr
, src_addr
);