3 Copyright (C) 2008 Everton da Silva Marques
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; see the file COPYING; if not, write to the
17 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
31 #include "pim_iface.h"
36 #include "pim_neighbor.h"
37 #include "pim_hello.h"
39 #include "pim_assert.h"
41 #include "pim_register.h"
43 static int on_pim_hello_send(struct thread
*t
);
44 static int pim_hello_send(struct interface
*ifp
,
48 const char *pim_pim_msgtype2str (enum pim_msg_type type
)
52 case PIM_MSG_TYPE_HELLO
: return "HELLO";
53 case PIM_MSG_TYPE_REGISTER
: return "REGISTER";
54 case PIM_MSG_TYPE_REG_STOP
: return "REGSTOP";
55 case PIM_MSG_TYPE_JOIN_PRUNE
: return "JOINPRUNE";
56 case PIM_MSG_TYPE_BOOTSTRAP
: return "BOOT";
57 case PIM_MSG_TYPE_ASSERT
: return "ASSERT";
58 case PIM_MSG_TYPE_GRAFT
: return "GRAFT";
59 case PIM_MSG_TYPE_GRAFT_ACK
: return "GACK";
60 case PIM_MSG_TYPE_CANDIDATE
: return "CANDIDATE";
66 static void sock_close(struct interface
*ifp
)
68 struct pim_interface
*pim_ifp
= ifp
->info
;
70 if (PIM_DEBUG_PIM_TRACE
) {
71 if (pim_ifp
->t_pim_sock_read
) {
72 zlog_debug("Cancelling READ event for PIM socket fd=%d on interface %s",
77 THREAD_OFF(pim_ifp
->t_pim_sock_read
);
79 if (PIM_DEBUG_PIM_TRACE
) {
80 if (pim_ifp
->t_pim_hello_timer
) {
81 zlog_debug("Cancelling PIM hello timer for interface %s",
85 THREAD_OFF(pim_ifp
->t_pim_hello_timer
);
87 if (PIM_DEBUG_PIM_TRACE
) {
88 zlog_debug("Deleting PIM socket fd=%d on interface %s",
89 pim_ifp
->pim_sock_fd
, ifp
->name
);
93 * If the fd is already deleted no need to do anything here
95 if (pim_ifp
->pim_sock_fd
> 0 && close(pim_ifp
->pim_sock_fd
)) {
96 zlog_warn("Failure closing PIM socket fd=%d on interface %s: errno=%d: %s",
97 pim_ifp
->pim_sock_fd
, ifp
->name
,
98 errno
, safe_strerror(errno
));
101 pim_ifp
->pim_sock_fd
= -1;
102 pim_ifp
->pim_sock_creation
= 0;
105 void pim_sock_delete(struct interface
*ifp
, const char *delete_message
)
107 zlog_info("PIM INTERFACE DOWN: on interface %s: %s",
108 ifp
->name
, delete_message
);
111 zlog_err("%s: %s: but PIM not enabled on interface %s (!)",
112 __PRETTY_FUNCTION__
, delete_message
, ifp
->name
);
117 RFC 4601: 4.3.1. Sending Hello Messages
119 Before an interface goes down or changes primary IP address, a Hello
120 message with a zero HoldTime should be sent immediately (with the
121 old IP address if the IP address changed).
123 pim_hello_send(ifp
, 0 /* zero-sec holdtime */);
125 pim_neighbor_delete_all(ifp
, delete_message
);
130 int pim_pim_packet(struct interface
*ifp
, uint8_t *buf
, size_t len
)
133 size_t ip_hlen
; /* ip header length in bytes */
134 char src_str
[INET_ADDRSTRLEN
];
135 char dst_str
[INET_ADDRSTRLEN
];
139 enum pim_msg_type pim_type
;
140 uint16_t pim_checksum
; /* received checksum */
141 uint16_t checksum
; /* computed checksum */
142 struct pim_neighbor
*neigh
;
144 if (len
< sizeof(*ip_hdr
)) {
145 if (PIM_DEBUG_PIM_PACKETS
)
146 zlog_debug("PIM packet size=%zu shorter than minimum=%zu",
147 len
, sizeof(*ip_hdr
));
151 ip_hdr
= (struct ip
*) buf
;
152 ip_hlen
= ip_hdr
->ip_hl
<< 2; /* ip_hl gives length in 4-byte words */
154 if (ip_hdr
->ip_p
!= PIM_IP_PROTO_PIM
) {
155 if (PIM_DEBUG_PIM_PACKETS
)
156 zlog_debug("IP packet protocol=%d is not PIM=%d",
157 ip_hdr
->ip_p
, PIM_IP_PROTO_PIM
);
161 if (ip_hlen
< PIM_IP_HEADER_MIN_LEN
) {
162 if (PIM_DEBUG_PIM_PACKETS
)
163 zlog_debug("IP packet header size=%zu shorter than minimum=%d",
164 ip_hlen
, PIM_IP_HEADER_MIN_LEN
);
167 if (ip_hlen
> PIM_IP_HEADER_MAX_LEN
) {
168 if (PIM_DEBUG_PIM_PACKETS
)
169 zlog_debug("IP packet header size=%zu greater than maximum=%d",
170 ip_hlen
, PIM_IP_HEADER_MAX_LEN
);
174 pim_msg
= buf
+ ip_hlen
;
175 pim_msg_len
= len
- ip_hlen
;
177 if (pim_msg_len
< PIM_PIM_MIN_LEN
) {
178 if (PIM_DEBUG_PIM_PACKETS
)
179 zlog_debug("PIM message size=%d shorter than minimum=%d",
180 pim_msg_len
, PIM_PIM_MIN_LEN
);
184 pim_version
= PIM_MSG_HDR_GET_VERSION(pim_msg
);
185 pim_type
= PIM_MSG_HDR_GET_TYPE(pim_msg
);
187 if (pim_version
!= PIM_PROTO_VERSION
) {
188 if (PIM_DEBUG_PIM_PACKETS
)
189 zlog_debug("Ignoring PIM pkt from %s with unsupported version: %d",
190 ifp
->name
, pim_version
);
194 /* save received checksum */
195 pim_checksum
= PIM_MSG_HDR_GET_CHECKSUM(pim_msg
);
197 /* for computing checksum */
198 *(uint16_t *) PIM_MSG_HDR_OFFSET_CHECKSUM(pim_msg
) = 0;
200 checksum
= in_cksum(pim_msg
, pim_msg_len
);
201 if (checksum
!= pim_checksum
) {
202 if (PIM_DEBUG_PIM_PACKETS
)
203 zlog_debug("Ignoring PIM pkt from %s with invalid checksum: received=%x calculated=%x",
204 ifp
->name
, pim_checksum
, checksum
);
208 if (PIM_DEBUG_PIM_PACKETS
) {
209 pim_inet4_dump("<src?>", ip_hdr
->ip_src
, src_str
, sizeof(src_str
));
210 pim_inet4_dump("<dst?>", ip_hdr
->ip_dst
, dst_str
, sizeof(dst_str
));
211 zlog_debug("Recv PIM %s packet from %s to %s on %s: ttl=%d pim_version=%d pim_msg_size=%d checksum=%x",
212 pim_pim_msgtype2str (pim_type
), src_str
, dst_str
, ifp
->name
,
213 ip_hdr
->ip_ttl
, pim_version
, pim_msg_len
, checksum
);
214 if (PIM_DEBUG_PIM_PACKETDUMP_RECV
) {
215 pim_pkt_dump(__PRETTY_FUNCTION__
, pim_msg
, pim_msg_len
);
221 case PIM_MSG_TYPE_HELLO
:
222 return pim_hello_recv (ifp
,
224 pim_msg
+ PIM_MSG_HEADER_LEN
,
225 pim_msg_len
- PIM_MSG_HEADER_LEN
);
227 case PIM_MSG_TYPE_REGISTER
:
228 return pim_register_recv (ifp
,
231 pim_msg
+ PIM_MSG_HEADER_LEN
,
232 pim_msg_len
- PIM_MSG_HEADER_LEN
);
234 case PIM_MSG_TYPE_REG_STOP
:
235 return pim_register_stop_recv (pim_msg
+ PIM_MSG_HEADER_LEN
,
236 pim_msg_len
- PIM_MSG_HEADER_LEN
);
238 case PIM_MSG_TYPE_JOIN_PRUNE
:
239 neigh
= pim_neighbor_find(ifp
, ip_hdr
->ip_src
);
241 if (PIM_DEBUG_PIM_PACKETS
)
242 zlog_debug("%s %s: non-hello PIM message type=%d from non-neighbor %s on %s",
243 __FILE__
, __PRETTY_FUNCTION__
,
244 pim_type
, src_str
, ifp
->name
);
247 pim_neighbor_timer_reset(neigh
, neigh
->holdtime
);
248 return pim_joinprune_recv(ifp
, neigh
,
250 pim_msg
+ PIM_MSG_HEADER_LEN
,
251 pim_msg_len
- PIM_MSG_HEADER_LEN
);
253 case PIM_MSG_TYPE_ASSERT
:
254 neigh
= pim_neighbor_find(ifp
, ip_hdr
->ip_src
);
256 if (PIM_DEBUG_PIM_PACKETS
)
257 zlog_debug("%s %s: non-hello PIM message type=%d from non-neighbor %s on %s",
258 __FILE__
, __PRETTY_FUNCTION__
,
259 pim_type
, src_str
, ifp
->name
);
262 pim_neighbor_timer_reset(neigh
, neigh
->holdtime
);
263 return pim_assert_recv(ifp
, neigh
,
265 pim_msg
+ PIM_MSG_HEADER_LEN
,
266 pim_msg_len
- PIM_MSG_HEADER_LEN
);
269 if (PIM_DEBUG_PIM_PACKETS
) {
270 zlog_debug("Recv PIM packet type %d which is not currently understood",
278 static void pim_sock_read_on(struct interface
*ifp
);
280 static int pim_sock_read(struct thread
*t
)
282 struct interface
*ifp
;
283 struct pim_interface
*pim_ifp
;
285 struct sockaddr_in from
;
286 struct sockaddr_in to
;
287 socklen_t fromlen
= sizeof(from
);
288 socklen_t tolen
= sizeof(to
);
289 uint8_t buf
[PIM_PIM_BUFSIZE_READ
];
291 ifindex_t ifindex
= -1;
292 int result
= -1; /* defaults to bad */
293 static long long count
= 0;
303 len
= pim_socket_recvfromto(fd
, buf
, sizeof(buf
),
311 if (errno
== EWOULDBLOCK
|| errno
== EAGAIN
)
316 if (PIM_DEBUG_PIM_PACKETS
)
317 zlog_debug ("Received errno: %d %s", errno
, safe_strerror (errno
));
321 #ifdef PIM_CHECK_RECV_IFINDEX_SANITY
322 /* ifindex sanity check */
323 if (ifindex
!= (int) ifp
->ifindex
) {
324 char from_str
[INET_ADDRSTRLEN
];
325 char to_str
[INET_ADDRSTRLEN
];
326 struct interface
*recv_ifp
;
328 if (!inet_ntop(AF_INET
, &from
.sin_addr
, from_str
, sizeof(from_str
)))
329 sprintf(from_str
, "<from?>");
330 if (!inet_ntop(AF_INET
, &to
.sin_addr
, to_str
, sizeof(to_str
)))
331 sprintf(to_str
, "<to?>");
333 recv_ifp
= if_lookup_by_index(ifindex
);
335 zassert(ifindex
== (int) recv_ifp
->ifindex
);
338 #ifdef PIM_REPORT_RECV_IFINDEX_MISMATCH
339 zlog_warn("Interface mismatch: recv PIM pkt from %s to %s on fd=%d: recv_ifindex=%d (%s) sock_ifindex=%d (%s)",
340 from_str
, to_str
, fd
,
341 ifindex
, recv_ifp
? recv_ifp
->name
: "<if-notfound>",
342 ifp
->ifindex
, ifp
->name
);
348 int fail
= pim_pim_packet(ifp
, buf
, len
);
350 if (PIM_DEBUG_PIM_PACKETS
)
351 zlog_debug("%s: pim_pim_packet() return=%d",
352 __PRETTY_FUNCTION__
, fail
);
357 if (count
% qpim_packet_process
== 0)
361 result
= 0; /* good */
364 pim_sock_read_on(ifp
);
367 ++pim_ifp
->pim_ifstat_hello_recvfail
;
373 static void pim_sock_read_on(struct interface
*ifp
)
375 struct pim_interface
*pim_ifp
;
382 if (PIM_DEBUG_PIM_TRACE_DETAIL
) {
383 zlog_debug("Scheduling READ event on PIM socket fd=%d",
384 pim_ifp
->pim_sock_fd
);
386 pim_ifp
->t_pim_sock_read
= NULL
;
387 zassert(!pim_ifp
->t_pim_sock_read
);
388 THREAD_READ_ON(master
, pim_ifp
->t_pim_sock_read
, pim_sock_read
, ifp
,
389 pim_ifp
->pim_sock_fd
);
392 static int pim_sock_open(struct in_addr ifaddr
, ifindex_t ifindex
)
396 fd
= pim_socket_mcast(IPPROTO_PIM
, ifaddr
, ifindex
, 0 /* loop=false */);
400 if (pim_socket_join(fd
, qpim_all_pim_routers_addr
, ifaddr
, ifindex
)) {
408 void pim_ifstat_reset(struct interface
*ifp
)
410 struct pim_interface
*pim_ifp
;
419 pim_ifp
->pim_ifstat_start
= pim_time_monotonic_sec();
420 pim_ifp
->pim_ifstat_hello_sent
= 0;
421 pim_ifp
->pim_ifstat_hello_sendfail
= 0;
422 pim_ifp
->pim_ifstat_hello_recv
= 0;
423 pim_ifp
->pim_ifstat_hello_recvfail
= 0;
426 void pim_sock_reset(struct interface
*ifp
)
428 struct pim_interface
*pim_ifp
;
435 pim_ifp
->primary_address
= pim_find_primary_addr(ifp
);
437 pim_ifp
->pim_sock_fd
= -1;
438 pim_ifp
->pim_sock_creation
= 0;
439 pim_ifp
->t_pim_sock_read
= NULL
;
441 pim_ifp
->t_pim_hello_timer
= NULL
;
442 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
443 pim_ifp
->pim_default_holdtime
= -1; /* unset: means 3.5 * pim_hello_period */
444 pim_ifp
->pim_triggered_hello_delay
= PIM_DEFAULT_TRIGGERED_HELLO_DELAY
;
445 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
446 pim_ifp
->pim_propagation_delay_msec
= PIM_DEFAULT_PROPAGATION_DELAY_MSEC
;
447 pim_ifp
->pim_override_interval_msec
= PIM_DEFAULT_OVERRIDE_INTERVAL_MSEC
;
448 if (PIM_DEFAULT_CAN_DISABLE_JOIN_SUPPRESSION
) {
449 PIM_IF_DO_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp
->options
);
452 PIM_IF_DONT_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp
->options
);
455 /* neighbors without lan_delay */
456 pim_ifp
->pim_number_of_nonlandelay_neighbors
= 0;
457 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
= 0;
458 pim_ifp
->pim_neighbors_highest_override_interval_msec
= 0;
461 pim_ifp
->pim_dr_election_last
= 0; /* timestamp */
462 pim_ifp
->pim_dr_election_count
= 0;
463 pim_ifp
->pim_dr_election_changes
= 0;
464 pim_ifp
->pim_dr_num_nondrpri_neighbors
= 0; /* neighbors without dr_pri */
465 pim_ifp
->pim_dr_addr
= pim_ifp
->primary_address
;
467 pim_ifstat_reset(ifp
);
470 static uint16_t ip_id
= 0;
474 pim_msg_send_frame (int fd
, char *buf
, size_t len
,
475 struct sockaddr
*dst
, size_t salen
)
477 struct ip
*ip
= (struct ip
*)buf
;
479 while (sendto (fd
, buf
, len
, MSG_DONTWAIT
, dst
, salen
) < 0)
481 char dst_str
[INET_ADDRSTRLEN
];
487 size_t hdrsize
= sizeof (struct ip
);
488 size_t newlen1
= ((len
- hdrsize
) / 2 ) & 0xFFF8;
489 size_t sendlen
= newlen1
+ hdrsize
;
490 size_t offset
= ntohs (ip
->ip_off
);
492 ip
->ip_len
= htons (sendlen
);
493 ip
->ip_off
= htons (offset
| IP_MF
);
494 if (pim_msg_send_frame (fd
, buf
, sendlen
, dst
, salen
) == 0)
496 struct ip
*ip2
= (struct ip
*)(buf
+ newlen1
);
497 size_t newlen2
= len
- sendlen
;
498 sendlen
= newlen2
+ hdrsize
;
500 memcpy (ip2
, ip
, hdrsize
);
501 ip2
->ip_len
= htons (sendlen
);
502 ip2
->ip_off
= htons (offset
+ (newlen1
>> 3));
503 return pim_msg_send_frame (fd
, (char *)ip2
, sendlen
, dst
, salen
);
510 if (PIM_DEBUG_PIM_PACKETS
)
512 pim_inet4_dump ("<dst?>", ip
->ip_dst
, dst_str
, sizeof (dst_str
));
513 zlog_warn ("%s: sendto() failure to %s: fd=%d msg_size=%zd: errno=%d: %s",
516 errno
, safe_strerror(errno
));
527 pim_msg_send(int fd
, struct in_addr src
,
528 struct in_addr dst
, uint8_t *pim_msg
,
529 int pim_msg_size
, const char *ifname
)
531 struct sockaddr_in to
;
533 unsigned char buffer
[10000];
534 unsigned char *msg_start
;
537 memset (buffer
, 0, 10000);
538 int sendlen
= sizeof (struct ip
) + pim_msg_size
;
540 msg_start
= buffer
+ sizeof (struct ip
);
541 memcpy (msg_start
, pim_msg
, pim_msg_size
);
543 ip
= (struct ip
*)buffer
;
544 ip
->ip_id
= htons (++ip_id
);
547 ip
->ip_p
= PIM_IP_PROTO_PIM
;
551 ip
->ip_len
= htons (sendlen
);
553 if (PIM_DEBUG_PIM_PACKETS
) {
554 char dst_str
[INET_ADDRSTRLEN
];
555 pim_inet4_dump("<dst?>", dst
, dst_str
, sizeof(dst_str
));
556 zlog_debug("%s: to %s on %s: msg_size=%d checksum=%x",
558 dst_str
, ifname
, pim_msg_size
,
559 *(uint16_t *) PIM_MSG_HDR_OFFSET_CHECKSUM(pim_msg
));
562 memset(&to
, 0, sizeof(to
));
563 to
.sin_family
= AF_INET
;
567 if (PIM_DEBUG_PIM_PACKETDUMP_SEND
) {
568 pim_pkt_dump(__PRETTY_FUNCTION__
, pim_msg
, pim_msg_size
);
571 pim_msg_send_frame (fd
, (char *)buffer
, sendlen
,
572 (struct sockaddr
*)&to
, tolen
);
576 static int hello_send(struct interface
*ifp
,
579 uint8_t pim_msg
[PIM_PIM_BUFSIZE_WRITE
];
580 struct pim_interface
*pim_ifp
;
586 if (PIM_DEBUG_PIM_HELLO
) {
587 char dst_str
[INET_ADDRSTRLEN
];
588 pim_inet4_dump("<dst?>", qpim_all_pim_routers_addr
, dst_str
, sizeof(dst_str
));
589 zlog_debug("%s: to %s on %s: holdt=%u prop_d=%u overr_i=%u dis_join_supp=%d dr_prio=%u gen_id=%08x addrs=%d",
593 pim_ifp
->pim_propagation_delay_msec
, pim_ifp
->pim_override_interval_msec
,
594 PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp
->options
),
595 pim_ifp
->pim_dr_priority
, pim_ifp
->pim_generation_id
,
596 listcount(ifp
->connected
));
599 pim_tlv_size
= pim_hello_build_tlv(ifp
->name
,
600 pim_msg
+ PIM_PIM_MIN_LEN
,
601 sizeof(pim_msg
) - PIM_PIM_MIN_LEN
,
603 pim_ifp
->pim_dr_priority
,
604 pim_ifp
->pim_generation_id
,
605 pim_ifp
->pim_propagation_delay_msec
,
606 pim_ifp
->pim_override_interval_msec
,
607 PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp
->options
),
609 if (pim_tlv_size
< 0) {
613 pim_msg_size
= pim_tlv_size
+ PIM_PIM_MIN_LEN
;
615 zassert(pim_msg_size
>= PIM_PIM_MIN_LEN
);
616 zassert(pim_msg_size
<= PIM_PIM_BUFSIZE_WRITE
);
618 pim_msg_build_header(pim_msg
, pim_msg_size
,
621 if (pim_msg_send(pim_ifp
->pim_sock_fd
,
622 pim_ifp
->primary_address
,
623 qpim_all_pim_routers_addr
,
627 if (PIM_DEBUG_PIM_HELLO
) {
628 zlog_debug("%s: could not send PIM message on interface %s",
629 __PRETTY_FUNCTION__
, ifp
->name
);
637 static int pim_hello_send(struct interface
*ifp
,
640 struct pim_interface
*pim_ifp
;
646 if (if_is_loopback (ifp
))
649 if (hello_send(ifp
, holdtime
)) {
650 ++pim_ifp
->pim_ifstat_hello_sendfail
;
652 if (PIM_DEBUG_PIM_HELLO
) {
653 zlog_warn("Could not send PIM hello on interface %s",
659 ++pim_ifp
->pim_ifstat_hello_sent
;
664 static void hello_resched(struct interface
*ifp
)
666 struct pim_interface
*pim_ifp
;
672 if (PIM_DEBUG_PIM_HELLO
) {
673 zlog_debug("Rescheduling %d sec hello on interface %s",
674 pim_ifp
->pim_hello_period
, ifp
->name
);
676 THREAD_OFF(pim_ifp
->t_pim_hello_timer
);
677 THREAD_TIMER_ON(master
, pim_ifp
->t_pim_hello_timer
,
679 ifp
, pim_ifp
->pim_hello_period
);
685 static int on_pim_hello_send(struct thread
*t
)
687 struct pim_interface
*pim_ifp
;
688 struct interface
*ifp
;
695 * Schedule next hello
697 pim_ifp
->t_pim_hello_timer
= NULL
;
703 return pim_hello_send(ifp
, PIM_IF_DEFAULT_HOLDTIME(pim_ifp
));
707 RFC 4601: 4.3.1. Sending Hello Messages
709 Thus, if a router needs to send a Join/Prune or Assert message on an
710 interface on which it has not yet sent a Hello message with the
711 currently configured IP address, then it MUST immediately send the
712 relevant Hello message without waiting for the Hello Timer to
713 expire, followed by the Join/Prune or Assert message.
715 void pim_hello_restart_now(struct interface
*ifp
)
717 struct pim_interface
*pim_ifp
;
724 * Reset next hello timer
729 * Immediately send hello
731 pim_hello_send(ifp
, PIM_IF_DEFAULT_HOLDTIME(pim_ifp
));
735 RFC 4601: 4.3.1. Sending Hello Messages
737 To allow new or rebooting routers to learn of PIM neighbors quickly,
738 when a Hello message is received from a new neighbor, or a Hello
739 message with a new GenID is received from an existing neighbor, a
740 new Hello message should be sent on this interface after a
741 randomized delay between 0 and Triggered_Hello_Delay.
743 void pim_hello_restart_triggered(struct interface
*ifp
)
745 struct pim_interface
*pim_ifp
;
746 int triggered_hello_delay_msec
;
754 * There exists situations where we have the a RPF out this
755 * interface, but we haven't formed a neighbor yet. This
756 * happens especially during interface flaps. While
757 * we would like to handle this more gracefully in other
758 * parts of the code. In order to get us up and running
759 * let's just send the hello immediate'ish
760 * This should be revisited when we get nexthop tracking
761 * in and when we have a better handle on safely
762 * handling the rpf information for upstreams that
763 * we cannot legally reach yet.
765 triggered_hello_delay_msec
= 1;
766 //triggered_hello_delay_msec = 1000 * pim_ifp->pim_triggered_hello_delay;
768 if (pim_ifp
->t_pim_hello_timer
) {
769 long remain_msec
= pim_time_timer_remain_msec(pim_ifp
->t_pim_hello_timer
);
770 if (remain_msec
<= triggered_hello_delay_msec
) {
771 /* Rescheduling hello would increase the delay, then it's faster
772 to just wait for the scheduled periodic hello. */
776 THREAD_OFF(pim_ifp
->t_pim_hello_timer
);
777 pim_ifp
->t_pim_hello_timer
= NULL
;
780 random_msec
= triggered_hello_delay_msec
;
781 //random_msec = random() % (triggered_hello_delay_msec + 1);
783 if (PIM_DEBUG_PIM_HELLO
) {
784 zlog_debug("Scheduling %d msec triggered hello on interface %s",
785 random_msec
, ifp
->name
);
788 THREAD_TIMER_MSEC_ON(master
, pim_ifp
->t_pim_hello_timer
,
793 int pim_sock_add(struct interface
*ifp
)
795 struct pim_interface
*pim_ifp
;
796 struct in_addr ifaddr
;
802 if (pim_ifp
->pim_sock_fd
>= 0) {
803 if (PIM_DEBUG_PIM_PACKETS
)
804 zlog_debug("Can't recreate existing PIM socket fd=%d for interface %s",
805 pim_ifp
->pim_sock_fd
, ifp
->name
);
809 ifaddr
= pim_ifp
->primary_address
;
811 pim_ifp
->pim_sock_fd
= pim_sock_open(ifaddr
, ifp
->ifindex
);
812 if (pim_ifp
->pim_sock_fd
< 0) {
813 if (PIM_DEBUG_PIM_PACKETS
)
814 zlog_debug("Could not open PIM socket on interface %s",
819 pim_socket_ip_hdr (pim_ifp
->pim_sock_fd
);
821 pim_ifp
->t_pim_sock_read
= NULL
;
822 pim_ifp
->pim_sock_creation
= pim_time_monotonic_sec();
825 * Just ensure that the new generation id
826 * actually chooses something different.
827 * Actually ran across a case where this
828 * happened, pre-switch to random().
829 * While this is unlikely to happen now
830 * let's make sure it doesn't.
832 old_genid
= pim_ifp
->pim_generation_id
;
834 while (old_genid
== pim_ifp
->pim_generation_id
)
835 pim_ifp
->pim_generation_id
= random();
837 zlog_info("PIM INTERFACE UP: on interface %s ifindex=%d",
838 ifp
->name
, ifp
->ifindex
);
841 * Start receiving PIM messages
843 pim_sock_read_on(ifp
);
846 * Start sending PIM hello's
848 pim_hello_restart_triggered(ifp
);