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
17 * along with this program; see the file COPYING; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
30 #include "pim_mroute.h"
31 #include "pim_iface.h"
36 #include "pim_register.h"
37 #include "pim_upstream.h"
41 #include "pim_zebra.h"
45 struct thread
*send_test_packet_timer
= NULL
;
48 * This seems stupidly expensive. A list lookup. Why is this
52 pim_check_is_my_ip_address (struct in_addr dest_addr
)
55 * See if we can short-cut some?
56 * This might not make sense if we ever leave a static RP
57 * type of configuration.
58 * Note - Premature optimization might bite our patooeys' here.
60 if (I_am_RP(dest_addr
) && (dest_addr
.s_addr
== qpim_rp
.rpf_addr
.s_addr
))
63 if (if_lookup_exact_address (&dest_addr
, AF_INET
))
70 pim_register_stop_send (struct interface
*ifp
, struct prefix_sg
*sg
,
71 struct in_addr originator
)
73 struct pim_interface
*pinfo
;
74 unsigned char buffer
[3000];
75 unsigned int b1length
= 0;
80 if (PIM_DEBUG_PIM_REG
)
82 zlog_debug ("Sending Register stop for %s to %s on %s",
83 pim_str_sg_dump (sg
), inet_ntoa(originator
), ifp
->name
);
86 memset (buffer
, 0, 3000);
87 b1
= (uint8_t *)buffer
+ PIM_MSG_REGISTER_STOP_LEN
;
89 length
= pim_encode_addr_group (b1
, AFI_IP
, 0, 0, sg
->grp
);
94 p
.u
.prefix4
= sg
->src
;
96 length
= pim_encode_addr_ucast (b1
, &p
);
99 pim_msg_build_header (buffer
, b1length
+ PIM_MSG_REGISTER_STOP_LEN
, PIM_MSG_TYPE_REG_STOP
);
101 pinfo
= (struct pim_interface
*)ifp
->info
;
104 if (PIM_DEBUG_PIM_TRACE
)
105 zlog_debug ("%s: No pinfo!\n", __PRETTY_FUNCTION__
);
108 if (pim_msg_send (pinfo
->pim_sock_fd
, originator
,
109 buffer
, b1length
+ PIM_MSG_REGISTER_STOP_LEN
,
112 if (PIM_DEBUG_PIM_TRACE
)
114 zlog_debug ("%s: could not send PIM register stop message on interface %s",
115 __PRETTY_FUNCTION__
, ifp
->name
);
121 pim_register_stop_recv (uint8_t *buf
, int buf_size
)
123 struct pim_upstream
*upstream
= NULL
;
124 struct prefix source
;
129 l
= pim_parse_addr_group (&group
, buf
, buf_size
);
132 l
= pim_parse_addr_ucast (&source
, buf
, buf_size
);
133 memset (&sg
, 0, sizeof (struct prefix_sg
));
134 sg
.src
= source
.u
.prefix4
;
135 sg
.grp
= group
.u
.prefix4
;
137 if (PIM_DEBUG_PIM_REG
)
139 zlog_debug ("Received Register stop for %s",
140 pim_str_sg_dump (&sg
));
143 upstream
= pim_upstream_find (&sg
);
149 switch (upstream
->join_state
)
151 case PIM_UPSTREAM_NOTJOINED
:
152 case PIM_UPSTREAM_PRUNE
:
155 case PIM_UPSTREAM_JOINED
:
156 case PIM_UPSTREAM_JOIN_PENDING
:
157 upstream
->join_state
= PIM_UPSTREAM_PRUNE
;
158 pim_upstream_start_register_stop_timer (upstream
, 0);
159 pim_channel_del_oif (upstream
->channel_oil
, pim_regiface
, PIM_OIF_FLAG_PROTO_PIM
);
168 pim_register_send (const uint8_t *buf
, int buf_size
, struct pim_rpf
*rpg
, int null_register
)
170 unsigned char buffer
[3000];
172 struct pim_interface
*pinfo
;
173 struct interface
*ifp
;
175 if (PIM_DEBUG_PIM_REG
)
178 strcpy (rp_str
, inet_ntoa (rpg
->rpf_addr
));
179 zlog_debug ("Sending %sRegister Packet to %s", null_register
? "NULL " : "", rp_str
);
182 ifp
= rpg
->source_nexthop
.interface
;
183 pinfo
= (struct pim_interface
*)ifp
->info
;
185 zlog_debug("%s: No pinfo!\n", __PRETTY_FUNCTION__
);
189 memset(buffer
, 0, 3000);
190 b1
= buffer
+ PIM_MSG_HEADER_LEN
;
191 *b1
|= null_register
<< 6;
192 b1
= buffer
+ PIM_MSG_REGISTER_LEN
;
194 memcpy(b1
, (const unsigned char *)buf
, buf_size
);
196 pim_msg_build_header(buffer
, buf_size
+ PIM_MSG_REGISTER_LEN
, PIM_MSG_TYPE_REGISTER
);
198 if (pim_msg_send(pinfo
->pim_sock_fd
,
201 buf_size
+ PIM_MSG_REGISTER_LEN
,
203 if (PIM_DEBUG_PIM_TRACE
) {
204 zlog_debug("%s: could not send PIM register message on interface %s",
205 __PRETTY_FUNCTION__
, ifp
->name
);
212 * 4.4.2 Receiving Register Messages at the RP
214 * When an RP receives a Register message, the course of action is
215 * decided according to the following pseudocode:
217 * packet_arrives_on_rp_tunnel( pkt ) {
218 * if( outer.dst is not one of my addresses ) {
219 * drop the packet silently.
220 * # Note: this may be a spoofing attempt
222 * if( I_am_RP(G) AND outer.dst == RP(G) ) {
223 * sentRegisterStop = FALSE;
224 * if ( register.borderbit == TRUE ) {
225 * if ( PMBR(S,G) == unknown ) {
226 * PMBR(S,G) = outer.src
227 * } else if ( outer.src != PMBR(S,G) ) {
228 * send Register-Stop(S,G) to outer.src
229 * drop the packet silently.
232 * if ( SPTbit(S,G) OR
233 * ( SwitchToSptDesired(S,G) AND
234 * ( inherited_olist(S,G) == NULL ))) {
235 * send Register-Stop(S,G) to outer.src
236 * sentRegisterStop = TRUE;
238 * if ( SPTbit(S,G) OR SwitchToSptDesired(S,G) ) {
239 * if ( sentRegisterStop == TRUE ) {
240 * set KeepaliveTimer(S,G) to RP_Keepalive_Period;
242 * set KeepaliveTimer(S,G) to Keepalive_Period;
245 * if( !SPTbit(S,G) AND ! pkt.NullRegisterBit ) {
246 * decapsulate and forward the inner packet to
247 * inherited_olist(S,G,rpt) # Note (+)
250 * send Register-Stop(S,G) to outer.src
256 pim_register_recv (struct interface
*ifp
,
257 struct in_addr dest_addr
,
258 struct in_addr src_addr
,
259 uint8_t *tlv_buf
, int tlv_buf_size
)
261 int sentRegisterStop
= 0;
266 if (!pim_check_is_my_ip_address (dest_addr
)) {
267 if (PIM_DEBUG_PIM_REG
) {
270 pim_inet4_dump ("<dst?>", dest_addr
, dest
, sizeof(dest
));
271 zlog_debug ("%s: Received Register message for %s that I do not own", __func__
,
277 if (PIM_DEBUG_PIM_REG
)
281 pim_inet4_dump ("<src?>", src_addr
, src_str
, sizeof (src_str
));
282 zlog_debug ("Received Register message from %s on %s", src_str
, ifp
->name
);
286 * Please note this is not drawn to get the correct bit/data size
288 * The entirety of the REGISTER packet looks like this:
289 * -------------------------------------------------------------
290 * | Ver | Type | Reserved | Checksum |
291 * |-----------------------------------------------------------|
293 * |-----------------------------------------------------------|
296 * | Packet |--------------------------------------------------|
301 * tlv_buf when received from the caller points at the B bit
302 * We need to know the inner source and dest
304 bits
= (uint32_t *)tlv_buf
;
307 * tlv_buf points to the start of the |B|N|... Reserved
308 * Line above. So we need to add 4 bytes to get to the
309 * start of the actual Encapsulated data.
311 #define PIM_MSG_REGISTER_BIT_RESERVED_LEN 4
312 ip_hdr
= (struct ip
*)(tlv_buf
+ PIM_MSG_REGISTER_BIT_RESERVED_LEN
);
313 memset (&sg
, 0, sizeof (struct prefix_sg
));
314 sg
.src
= ip_hdr
->ip_src
;
315 sg
.grp
= ip_hdr
->ip_dst
;
317 if (I_am_RP (sg
.grp
) && (dest_addr
.s_addr
== ((RP (sg
.grp
))->rpf_addr
.s_addr
))) {
318 sentRegisterStop
= 0;
320 if (*bits
& PIM_REGISTER_BORDER_BIT
) {
321 struct in_addr pimbr
= pim_br_get_pmbr (&sg
);
322 if (PIM_DEBUG_PIM_PACKETS
)
323 zlog_debug("%s: Received Register message with Border bit set", __func__
);
325 if (pimbr
.s_addr
== pim_br_unknown
.s_addr
)
326 pim_br_set_pmbr(&sg
, src_addr
);
327 else if (src_addr
.s_addr
!= pimbr
.s_addr
) {
328 pim_register_stop_send (ifp
, &sg
, src_addr
);
329 if (PIM_DEBUG_PIM_PACKETS
)
330 zlog_debug("%s: Sending register-Stop to %s and dropping mr. packet",
332 /* Drop Packet Silently */
337 struct pim_upstream
*upstream
= pim_upstream_find (&sg
);
339 * If we don't have a place to send ignore the packet
343 upstream
= pim_upstream_add (&sg
, ifp
);
345 pim_rp_set_upstream_addr (&upstream
->upstream_addr
, sg
.src
);
346 pim_nexthop_lookup (&upstream
->rpf
.source_nexthop
,
347 upstream
->upstream_addr
, NULL
);
348 upstream
->rpf
.source_nexthop
.interface
= ifp
;
349 upstream
->sg
.src
= sg
.src
;
350 upstream
->rpf
.rpf_addr
= upstream
->rpf
.source_nexthop
.mrib_nexthop_addr
;
352 pim_upstream_switch (upstream
, PIM_UPSTREAM_PRUNE
);
356 if ((upstream
->sptbit
== PIM_UPSTREAM_SPTBIT_TRUE
) ||
357 ((SwitchToSptDesired(&sg
)) &&
358 pim_upstream_inherited_olist (upstream
) == 0)) {
359 //pim_scan_individual_oil (upstream->channel_oil);
360 pim_register_stop_send (ifp
, &sg
, src_addr
);
361 sentRegisterStop
= 1;
364 if ((upstream
->sptbit
== PIM_UPSTREAM_SPTBIT_TRUE
) ||
365 (SwitchToSptDesired(&sg
))) {
366 if (sentRegisterStop
) {
367 pim_upstream_keep_alive_timer_start (upstream
, PIM_RP_KEEPALIVE_PERIOD
);
369 pim_upstream_keep_alive_timer_start (upstream
, PIM_KEEPALIVE_PERIOD
);
373 if (!(upstream
->sptbit
== PIM_UPSTREAM_SPTBIT_TRUE
) &&
374 !(*bits
& PIM_REGISTER_NR_BIT
))
376 //decapsulate and forward the iner packet to
377 //inherited_olist(S,G,rpt)
378 // This is taken care of by the kernel for us
381 pim_register_stop_send (ifp
, &sg
, src_addr
);
389 pim_register_send_test_packet (struct thread
*t
)
393 packet
= THREAD_ARG(t
);
401 * pim_register_send_test_packet
403 * Send a test packet to the RP from source, in group and pps packets per second
406 pim_register_send_test_packet_start (struct in_addr source
,
407 struct in_addr group
,
410 uint8_t *packet
= NULL
;
412 THREAD_TIMER_MSEC_ON(master
, send_test_packet_timer
,
413 pim_register_send_test_packet
, packet
, 1000/pps
);