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"
47 struct thread
*send_test_packet_timer
= NULL
;
49 void pim_register_join(struct pim_upstream
*up
)
51 if (pim_is_grp_ssm(up
->sg
.grp
)) {
52 if (PIM_DEBUG_PIM_EVENTS
)
53 zlog_debug("%s register setup skipped as group is SSM",
58 pim_channel_add_oif(up
->channel_oil
, pimg
->regiface
,
59 PIM_OIF_FLAG_PROTO_PIM
);
60 up
->reg_state
= PIM_REG_JOIN
;
63 void pim_register_stop_send(struct interface
*ifp
, struct prefix_sg
*sg
,
64 struct in_addr src
, struct in_addr originator
)
66 struct pim_interface
*pinfo
;
67 unsigned char buffer
[10000];
68 unsigned int b1length
= 0;
73 if (PIM_DEBUG_PIM_REG
) {
74 zlog_debug("Sending Register stop for %s to %s on %s",
75 pim_str_sg_dump(sg
), inet_ntoa(originator
),
79 memset(buffer
, 0, 10000);
80 b1
= (uint8_t *)buffer
+ PIM_MSG_REGISTER_STOP_LEN
;
82 length
= pim_encode_addr_group(b1
, AFI_IP
, 0, 0, sg
->grp
);
87 p
.u
.prefix4
= sg
->src
;
89 length
= pim_encode_addr_ucast(b1
, &p
);
92 pim_msg_build_header(buffer
, b1length
+ PIM_MSG_REGISTER_STOP_LEN
,
93 PIM_MSG_TYPE_REG_STOP
);
95 pinfo
= (struct pim_interface
*)ifp
->info
;
97 if (PIM_DEBUG_PIM_TRACE
)
98 zlog_debug("%s: No pinfo!\n", __PRETTY_FUNCTION__
);
101 if (pim_msg_send(pinfo
->pim_sock_fd
, src
, originator
, buffer
,
102 b1length
+ PIM_MSG_REGISTER_STOP_LEN
, ifp
->name
)) {
103 if (PIM_DEBUG_PIM_TRACE
) {
105 "%s: could not send PIM register stop message on interface %s",
106 __PRETTY_FUNCTION__
, ifp
->name
);
109 ++pinfo
->pim_ifstat_reg_stop_send
;
112 int pim_register_stop_recv(uint8_t *buf
, int buf_size
)
114 struct pim_upstream
*upstream
= NULL
;
115 struct prefix source
;
119 memset(&sg
, 0, sizeof(struct prefix_sg
));
120 l
= pim_parse_addr_group(&sg
, buf
, buf_size
);
123 pim_parse_addr_ucast(&source
, buf
, buf_size
);
124 sg
.src
= source
.u
.prefix4
;
126 upstream
= pim_upstream_find(&sg
);
131 if (PIM_DEBUG_PIM_REG
)
132 zlog_debug("Received Register stop for %s", upstream
->sg_str
);
134 switch (upstream
->reg_state
) {
140 upstream
->reg_state
= PIM_REG_PRUNE
;
141 pim_channel_del_oif(upstream
->channel_oil
, pimg
->regiface
,
142 PIM_OIF_FLAG_PROTO_PIM
);
143 pim_upstream_start_register_stop_timer(upstream
, 0);
145 case PIM_REG_JOIN_PENDING
:
146 upstream
->reg_state
= PIM_REG_PRUNE
;
147 pim_upstream_start_register_stop_timer(upstream
, 0);
155 void pim_register_send(const uint8_t *buf
, int buf_size
, struct in_addr src
,
156 struct pim_rpf
*rpg
, int null_register
,
157 struct pim_upstream
*up
)
159 unsigned char buffer
[10000];
161 struct pim_interface
*pinfo
;
162 struct interface
*ifp
;
164 if (PIM_DEBUG_PIM_REG
) {
165 zlog_debug("Sending %s %sRegister Packet to %s", up
->sg_str
,
166 null_register
? "NULL " : "",
167 inet_ntoa(rpg
->rpf_addr
.u
.prefix4
));
170 ifp
= rpg
->source_nexthop
.interface
;
172 if (PIM_DEBUG_PIM_REG
)
173 zlog_debug("%s: No interface to transmit register on",
174 __PRETTY_FUNCTION__
);
177 pinfo
= (struct pim_interface
*)ifp
->info
;
179 if (PIM_DEBUG_PIM_REG
)
181 "%s: Interface: %s not configured for pim to trasmit on!\n",
182 __PRETTY_FUNCTION__
, ifp
->name
);
186 if (PIM_DEBUG_PIM_REG
) {
187 char rp_str
[INET_ADDRSTRLEN
];
188 strncpy(rp_str
, inet_ntoa(rpg
->rpf_addr
.u
.prefix4
),
189 INET_ADDRSTRLEN
- 1);
190 zlog_debug("%s: Sending %s %sRegister Packet to %s on %s",
191 __PRETTY_FUNCTION__
, up
->sg_str
,
192 null_register
? "NULL " : "", rp_str
, ifp
->name
);
195 memset(buffer
, 0, 10000);
196 b1
= buffer
+ PIM_MSG_HEADER_LEN
;
197 *b1
|= null_register
<< 6;
198 b1
= buffer
+ PIM_MSG_REGISTER_LEN
;
200 memcpy(b1
, (const unsigned char *)buf
, buf_size
);
202 pim_msg_build_header(buffer
, buf_size
+ PIM_MSG_REGISTER_LEN
,
203 PIM_MSG_TYPE_REGISTER
);
205 ++pinfo
->pim_ifstat_reg_send
;
207 if (pim_msg_send(pinfo
->pim_sock_fd
, src
, rpg
->rpf_addr
.u
.prefix4
,
208 buffer
, buf_size
+ PIM_MSG_REGISTER_LEN
, ifp
->name
)) {
209 if (PIM_DEBUG_PIM_TRACE
) {
211 "%s: could not send PIM register message on interface %s",
212 __PRETTY_FUNCTION__
, ifp
->name
);
219 * 4.4.2 Receiving Register Messages at the RP
221 * When an RP receives a Register message, the course of action is
222 * decided according to the following pseudocode:
224 * packet_arrives_on_rp_tunnel( pkt ) {
225 * if( outer.dst is not one of my addresses ) {
226 * drop the packet silently.
227 * # Note: this may be a spoofing attempt
229 * if( I_am_RP(G) AND outer.dst == RP(G) ) {
230 * sentRegisterStop = FALSE;
231 * if ( register.borderbit == TRUE ) {
232 * if ( PMBR(S,G) == unknown ) {
233 * PMBR(S,G) = outer.src
234 * } else if ( outer.src != PMBR(S,G) ) {
235 * send Register-Stop(S,G) to outer.src
236 * drop the packet silently.
239 * if ( SPTbit(S,G) OR
240 * ( SwitchToSptDesired(S,G) AND
241 * ( inherited_olist(S,G) == NULL ))) {
242 * send Register-Stop(S,G) to outer.src
243 * sentRegisterStop = TRUE;
245 * if ( SPTbit(S,G) OR SwitchToSptDesired(S,G) ) {
246 * if ( sentRegisterStop == TRUE ) {
247 * set KeepaliveTimer(S,G) to RP_Keepalive_Period;
249 * set KeepaliveTimer(S,G) to Keepalive_Period;
252 * if( !SPTbit(S,G) AND ! pkt.NullRegisterBit ) {
253 * decapsulate and forward the inner packet to
254 * inherited_olist(S,G,rpt) # Note (+)
257 * send Register-Stop(S,G) to outer.src
262 int pim_register_recv(struct interface
*ifp
, struct in_addr dest_addr
,
263 struct in_addr src_addr
, uint8_t *tlv_buf
,
266 int sentRegisterStop
= 0;
271 struct pim_interface
*pim_ifp
= NULL
;
275 #define PIM_MSG_REGISTER_BIT_RESERVED_LEN 4
276 ip_hdr
= (struct ip
*)(tlv_buf
+ PIM_MSG_REGISTER_BIT_RESERVED_LEN
);
278 if (!pim_rp_check_is_my_ip_address(pim_ifp
->pim
, ip_hdr
->ip_dst
,
280 if (PIM_DEBUG_PIM_REG
) {
281 char dest
[INET_ADDRSTRLEN
];
283 pim_inet4_dump("<dst?>", dest_addr
, dest
, sizeof(dest
));
285 "%s: Received Register message for %s that I do not own",
291 ++pim_ifp
->pim_ifstat_reg_recv
;
294 * Please note this is not drawn to get the correct bit/data size
296 * The entirety of the REGISTER packet looks like this:
297 * -------------------------------------------------------------
298 * | Ver | Type | Reserved | Checksum |
299 * |-----------------------------------------------------------|
301 * |-----------------------------------------------------------|
304 * | Packet |--------------------------------------------------|
309 * tlv_buf when received from the caller points at the B bit
310 * We need to know the inner source and dest
312 bits
= (uint32_t *)tlv_buf
;
315 * tlv_buf points to the start of the |B|N|... Reserved
316 * Line above. So we need to add 4 bytes to get to the
317 * start of the actual Encapsulated data.
319 memset(&sg
, 0, sizeof(struct prefix_sg
));
320 sg
.src
= ip_hdr
->ip_src
;
321 sg
.grp
= ip_hdr
->ip_dst
;
323 i_am_rp
= I_am_RP(sg
.grp
);
325 if (PIM_DEBUG_PIM_REG
) {
326 char src_str
[INET_ADDRSTRLEN
];
328 pim_inet4_dump("<src?>", src_addr
, src_str
, sizeof(src_str
));
330 "Received Register message(%s) from %s on %s, rp: %d",
331 pim_str_sg_dump(&sg
), src_str
, ifp
->name
, i_am_rp
);
336 == ((RP(pim_ifp
->pim
, sg
.grp
))->rpf_addr
.u
.prefix4
.s_addr
))) {
337 sentRegisterStop
= 0;
339 if (*bits
& PIM_REGISTER_BORDER_BIT
) {
340 struct in_addr pimbr
= pim_br_get_pmbr(&sg
);
341 if (PIM_DEBUG_PIM_PACKETS
)
343 "%s: Received Register message with Border bit set",
346 if (pimbr
.s_addr
== pim_br_unknown
.s_addr
)
347 pim_br_set_pmbr(&sg
, src_addr
);
348 else if (src_addr
.s_addr
!= pimbr
.s_addr
) {
349 pim_register_stop_send(ifp
, &sg
, dest_addr
,
351 if (PIM_DEBUG_PIM_PACKETS
)
353 "%s: Sending register-Stop to %s and dropping mr. packet",
355 /* Drop Packet Silently */
360 struct pim_upstream
*upstream
= pim_upstream_find(&sg
);
362 * If we don't have a place to send ignore the packet
365 upstream
= pim_upstream_add(
366 &sg
, ifp
, PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
,
367 __PRETTY_FUNCTION__
);
369 zlog_warn("Failure to create upstream state");
373 upstream
->upstream_register
= src_addr
;
376 if ((upstream
->sptbit
== PIM_UPSTREAM_SPTBIT_TRUE
)
377 || ((SwitchToSptDesired(&sg
))
378 && pim_upstream_inherited_olist(upstream
) == 0)) {
379 // pim_scan_individual_oil (upstream->channel_oil);
380 pim_register_stop_send(ifp
, &sg
, dest_addr
, src_addr
);
381 sentRegisterStop
= 1;
383 if (PIM_DEBUG_PIM_REG
)
384 zlog_debug("(%s) sptbit: %d", upstream
->sg_str
,
387 if ((upstream
->sptbit
== PIM_UPSTREAM_SPTBIT_TRUE
)
388 || (SwitchToSptDesired(&sg
))) {
389 if (sentRegisterStop
) {
390 pim_upstream_keep_alive_timer_start(
391 upstream
, qpim_rp_keep_alive_time
);
393 pim_upstream_keep_alive_timer_start(
394 upstream
, qpim_keep_alive_time
);
398 if (!(upstream
->sptbit
== PIM_UPSTREAM_SPTBIT_TRUE
)
399 && !(*bits
& PIM_REGISTER_NR_BIT
)) {
400 // decapsulate and forward the iner packet to
401 // inherited_olist(S,G,rpt)
402 // This is taken care of by the kernel for us
404 pim_upstream_msdp_reg_timer_start(upstream
);
406 if (PIM_DEBUG_PIM_REG
) {
409 "Received Register packet for %s, Rejecting packet because I am not the RP configured for group",
410 pim_str_sg_dump(&sg
));
413 "Received Register packet for %s, Rejecting packet because the dst ip address is not the actual RP",
414 pim_str_sg_dump(&sg
));
416 pim_register_stop_send(ifp
, &sg
, dest_addr
, src_addr
);