/*
  PIM for Quagga
  Copyright (C) 2008  Everton da Silva Marques

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  General Public License for more details.
  
  You should have received a copy of the GNU General Public License
  along with this program; see the file COPYING; if not, write to the
  Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
  MA 02110-1301 USA
  
  $QuaggaId: $Format:%an, %ai, %h$ $
*/

#include <zebra.h>

#include "log.h"
#include "thread.h"
#include "memory.h"

#include "pimd.h"
#include "pim_pim.h"
#include "pim_time.h"
#include "pim_iface.h"
#include "pim_sock.h"
#include "pim_str.h"
#include "pim_util.h"
#include "pim_tlv.h"
#include "pim_neighbor.h"
#include "pim_hello.h"
#include "pim_join.h"
#include "pim_assert.h"
#include "pim_msg.h"
#include "pim_rand.h"

static int on_pim_hello_send(struct thread *t);
static int pim_hello_send(struct interface *ifp,
			  uint16_t holdtime);

static void sock_close(struct interface *ifp)
{
  struct pim_interface *pim_ifp = ifp->info;

  if (PIM_DEBUG_PIM_TRACE) {
    if (pim_ifp->t_pim_sock_read) {
      zlog_debug("Cancelling READ event for PIM socket fd=%d on interface %s",
		 pim_ifp->pim_sock_fd,
		 ifp->name);
    }
  }
  THREAD_OFF(pim_ifp->t_pim_sock_read);

  if (PIM_DEBUG_PIM_TRACE) {
    if (pim_ifp->t_pim_hello_timer) {
      zlog_debug("Cancelling PIM hello timer for interface %s",
		 ifp->name);
    }
  }
  THREAD_OFF(pim_ifp->t_pim_hello_timer);

  if (PIM_DEBUG_PIM_TRACE) {
    zlog_debug("Deleting PIM socket fd=%d on interface %s",
	       pim_ifp->pim_sock_fd, ifp->name);
  }

  if (close(pim_ifp->pim_sock_fd)) {
    zlog_warn("Failure closing PIM socket fd=%d on interface %s: errno=%d: %s",
	      pim_ifp->pim_sock_fd, ifp->name,
	      errno, strerror(errno));
  }
  
  pim_ifp->pim_sock_fd = -1;
  pim_ifp->pim_sock_creation = 0;

  zassert(pim_ifp->pim_sock_fd < 0);
  zassert(!pim_ifp->t_pim_sock_read);
  zassert(!pim_ifp->t_pim_hello_timer);
  zassert(!pim_ifp->pim_sock_creation);
}

void pim_sock_delete(struct interface *ifp, const char *delete_message)
{
  zlog_info("PIM INTERFACE DOWN: on interface %s: %s",
	    ifp->name, delete_message);

  /*
    RFC 4601: 4.3.1.  Sending Hello Messages
    
    Before an interface goes down or changes primary IP address, a Hello
    message with a zero HoldTime should be sent immediately (with the
    old IP address if the IP address changed).
  */
  pim_hello_send(ifp, 0 /* zero-sec holdtime */);

  pim_neighbor_delete_all(ifp, delete_message);

  sock_close(ifp);
}

int pim_pim_packet(struct interface *ifp, char *buf, size_t len)
{
  struct ip *ip_hdr;
  size_t ip_hlen; /* ip header length in bytes */
  char src_str[100];
  char dst_str[100];
  char *pim_msg;
  int pim_msg_len;
  uint8_t pim_version;
  uint8_t pim_type;
  uint16_t pim_checksum; /* received checksum */
  uint16_t checksum;     /* computed checksum */
  struct pim_neighbor *neigh;

  if (!ifp->info) {
    zlog_warn("%s: PIM not enabled on interface %s",
	      __PRETTY_FUNCTION__, ifp->name);
    return -1;
  }
    
  if (len < sizeof(*ip_hdr)) {
    zlog_warn("PIM packet size=%d shorter than minimum=%d",
	      len, sizeof(*ip_hdr));
    return -1;
  }

  ip_hdr = (struct ip *) buf;

  pim_inet4_dump("<src?>", ip_hdr->ip_src, src_str, sizeof(src_str));
  pim_inet4_dump("<dst?>", ip_hdr->ip_dst, dst_str, sizeof(dst_str));

  ip_hlen = ip_hdr->ip_hl << 2; /* ip_hl gives length in 4-byte words */

  if (PIM_DEBUG_PIM_PACKETS) {
    zlog_debug("Recv IP packet from %s to %s on %s: size=%d ip_header_size=%d ip_proto=%d",
	       src_str, dst_str, ifp->name, len, ip_hlen, ip_hdr->ip_p);
  }

  if (ip_hdr->ip_p != PIM_IP_PROTO_PIM) {
    zlog_warn("IP packet protocol=%d is not PIM=%d",
	      ip_hdr->ip_p, PIM_IP_PROTO_PIM);
    return -1;
  }

  if (ip_hlen < PIM_IP_HEADER_MIN_LEN) {
    zlog_warn("IP packet header size=%d shorter than minimum=%d",
	      ip_hlen, PIM_IP_HEADER_MIN_LEN);
    return -1;
  }
  if (ip_hlen > PIM_IP_HEADER_MAX_LEN) {
    zlog_warn("IP packet header size=%d greater than maximum=%d",
	      ip_hlen, PIM_IP_HEADER_MAX_LEN);
    return -1;
  }

  pim_msg = buf + ip_hlen;
  pim_msg_len = len - ip_hlen;

  if (pim_msg_len < PIM_PIM_MIN_LEN) {
    zlog_warn("PIM message size=%d shorter than minimum=%d",
	      pim_msg_len, PIM_PIM_MIN_LEN);
    return -1;
  }

  pim_version = PIM_MSG_HDR_GET_VERSION(pim_msg);
  pim_type    = PIM_MSG_HDR_GET_TYPE(pim_msg);

  if (pim_version != PIM_PROTO_VERSION) {
    zlog_warn("Ignoring PIM pkt from %s with unsupported version: %d",
	      ifp->name, pim_version);
    return -1;
  }

  /* save received checksum */
  pim_checksum = PIM_MSG_HDR_GET_CHECKSUM(pim_msg);

  /* for computing checksum */
  *(uint16_t *) PIM_MSG_HDR_OFFSET_CHECKSUM(pim_msg) = 0;

  checksum = pim_inet_checksum(pim_msg, pim_msg_len);
  if (checksum != pim_checksum) {
    zlog_warn("Ignoring PIM pkt from %s with invalid checksum: received=%x calculated=%x",
	      ifp->name, pim_checksum, checksum);
    return -1;
  }

  if (PIM_DEBUG_PIM_PACKETS) {
    zlog_debug("Recv PIM packet from %s to %s on %s: ttl=%d pim_version=%d pim_type=%d pim_msg_size=%d checksum=%x",
	       src_str, dst_str, ifp->name, ip_hdr->ip_ttl,
	       pim_version, pim_type, pim_msg_len, checksum);
  }

  if (pim_type == PIM_MSG_TYPE_HELLO) {
    return pim_hello_recv(ifp,
			  ip_hdr->ip_src,
			  pim_msg + PIM_MSG_HEADER_LEN,
			  pim_msg_len - PIM_MSG_HEADER_LEN);
  }

  neigh = pim_neighbor_find(ifp, ip_hdr->ip_src);
  if (!neigh) {
    zlog_warn("%s %s: non-hello PIM message type=%d from non-neighbor %s on %s",
	      __FILE__, __PRETTY_FUNCTION__,
	      pim_type, src_str, ifp->name);
    return -1;
  }

  switch (pim_type) {
  case PIM_MSG_TYPE_JOIN_PRUNE:
    return pim_joinprune_recv(ifp, neigh,
			      ip_hdr->ip_src,
			      pim_msg + PIM_MSG_HEADER_LEN,
			      pim_msg_len - PIM_MSG_HEADER_LEN);
  case PIM_MSG_TYPE_ASSERT:
    return pim_assert_recv(ifp, neigh,
			   ip_hdr->ip_src,
			   pim_msg + PIM_MSG_HEADER_LEN,
			   pim_msg_len - PIM_MSG_HEADER_LEN);
  default:
    zlog_warn("%s %s: unsupported PIM message type=%d from %s on %s",
	      __FILE__, __PRETTY_FUNCTION__,
	      pim_type, src_str, ifp->name);
  }

  return -1;
}

static void pim_sock_read_on(struct interface *ifp);

static int pim_sock_read(struct thread *t)
{
  struct interface *ifp;
  struct pim_interface *pim_ifp;
  int fd;
  struct sockaddr_in from;
  struct sockaddr_in to;
  socklen_t fromlen = sizeof(from);
  socklen_t tolen = sizeof(to);
  char buf[PIM_PIM_BUFSIZE_READ];
  int len;
  int ifindex = -1;
  int result = -1; /* defaults to bad */

  zassert(t);

  ifp = THREAD_ARG(t);
  zassert(ifp);

  fd = THREAD_FD(t);

  pim_ifp = ifp->info;
  zassert(pim_ifp);

  zassert(fd == pim_ifp->pim_sock_fd);

  len = pim_socket_recvfromto(fd, buf, sizeof(buf),
			      &from, &fromlen,
			      &to, &tolen,
			      &ifindex);
  if (len < 0) {
    zlog_warn("Failure receiving IP PIM packet on fd=%d: errno=%d: %s",
	      fd, errno, strerror(errno));
    goto done;
  }

  if (PIM_DEBUG_PIM_PACKETS) {
    char from_str[100];
    char to_str[100];
    
    if (!inet_ntop(AF_INET, &from.sin_addr, from_str, sizeof(from_str)))
      sprintf(from_str, "<from?>");
    if (!inet_ntop(AF_INET, &to.sin_addr, to_str, sizeof(to_str)))
      sprintf(to_str, "<to?>");
    
    zlog_debug("Recv IP PIM pkt size=%d from %s to %s on fd=%d on ifindex=%d (sock_ifindex=%d)",
	       len, from_str, to_str, fd, ifindex, ifp->ifindex);
  }

#ifdef PIM_CHECK_RECV_IFINDEX_SANITY
  /* ifindex sanity check */
  if (ifindex != (int) ifp->ifindex) {
    char from_str[100];
    char to_str[100];
    struct interface *recv_ifp;

    if (!inet_ntop(AF_INET, &from.sin_addr, from_str , sizeof(from_str)))
      sprintf(from_str, "<from?>");
    if (!inet_ntop(AF_INET, &to.sin_addr, to_str , sizeof(to_str)))
      sprintf(to_str, "<to?>");

    recv_ifp = if_lookup_by_index(ifindex);
    if (recv_ifp) {
      zassert(ifindex == (int) recv_ifp->ifindex);
    }

#ifdef PIM_REPORT_RECV_IFINDEX_MISMATCH
    zlog_warn("Interface mismatch: recv PIM pkt from %s to %s on fd=%d: recv_ifindex=%d (%s) sock_ifindex=%d (%s)",
	      from_str, to_str, fd,
	      ifindex, recv_ifp ? recv_ifp->name : "<if-notfound>",
	      ifp->ifindex, ifp->name);
#endif
    goto done;
  }
#endif

  if (pim_pim_packet(ifp, buf, len)) {
    goto done;
  }

  result = 0; /* good */

 done:
  pim_sock_read_on(ifp);

  if (result) {
    ++pim_ifp->pim_ifstat_hello_recvfail;
  }

  return result;
}

static void pim_sock_read_on(struct interface *ifp)
{
  struct pim_interface *pim_ifp;

  zassert(ifp);
  zassert(ifp->info);

  pim_ifp = ifp->info;

  if (PIM_DEBUG_PIM_TRACE) {
    zlog_debug("Scheduling READ event on PIM socket fd=%d",
	       pim_ifp->pim_sock_fd);
  }
  pim_ifp->t_pim_sock_read = 0;
  zassert(!pim_ifp->t_pim_sock_read);
  THREAD_READ_ON(master, pim_ifp->t_pim_sock_read, pim_sock_read, ifp,
		 pim_ifp->pim_sock_fd);
}

static int pim_sock_open(struct in_addr ifaddr, int ifindex)
{
  int fd;

  fd = pim_socket_mcast(IPPROTO_PIM, ifaddr, 0 /* loop=false */);
  if (fd < 0)
    return -1;

  if (pim_socket_join(fd, qpim_all_pim_routers_addr, ifaddr, ifindex)) {
    return -2;
  }

  return fd;
}

void pim_ifstat_reset(struct interface *ifp)
{
  struct pim_interface *pim_ifp;

  zassert(ifp);

  pim_ifp = ifp->info;
  if (!pim_ifp) {
    return;
  }

  pim_ifp->pim_ifstat_start          = pim_time_monotonic_sec();
  pim_ifp->pim_ifstat_hello_sent     = 0;
  pim_ifp->pim_ifstat_hello_sendfail = 0;
  pim_ifp->pim_ifstat_hello_recv     = 0;
  pim_ifp->pim_ifstat_hello_recvfail = 0;
}

void pim_sock_reset(struct interface *ifp)
{
  struct pim_interface *pim_ifp;

  zassert(ifp);
  zassert(ifp->info);

  pim_ifp = ifp->info;

  pim_ifp->primary_address = pim_find_primary_addr(ifp);

  pim_ifp->pim_sock_fd       = -1;
  pim_ifp->pim_sock_creation = 0;
  pim_ifp->t_pim_sock_read   = 0;

  pim_ifp->t_pim_hello_timer          = 0;
  pim_ifp->pim_hello_period           = PIM_DEFAULT_HELLO_PERIOD;
  pim_ifp->pim_default_holdtime       = -1; /* unset: means 3.5 * pim_hello_period */
  pim_ifp->pim_triggered_hello_delay  = PIM_DEFAULT_TRIGGERED_HELLO_DELAY;
  pim_ifp->pim_dr_priority            = PIM_DEFAULT_DR_PRIORITY;
  pim_ifp->pim_propagation_delay_msec = PIM_DEFAULT_PROPAGATION_DELAY_MSEC;
  pim_ifp->pim_override_interval_msec = PIM_DEFAULT_OVERRIDE_INTERVAL_MSEC;
  if (PIM_DEFAULT_CAN_DISABLE_JOIN_SUPPRESSION) {
    PIM_IF_DO_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options);
  }
  else {
    PIM_IF_DONT_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options);
  }

  /* neighbors without lan_delay */
  pim_ifp->pim_number_of_nonlandelay_neighbors = 0;
  pim_ifp->pim_neighbors_highest_propagation_delay_msec = 0;
  pim_ifp->pim_neighbors_highest_override_interval_msec = 0;

  /* DR Election */
  pim_ifp->pim_dr_election_last          = 0; /* timestamp */
  pim_ifp->pim_dr_election_count         = 0;
  pim_ifp->pim_dr_num_nondrpri_neighbors = 0; /* neighbors without dr_pri */
  pim_ifp->pim_dr_addr                   = pim_ifp->primary_address;

  pim_ifstat_reset(ifp);
}

int pim_msg_send(int fd,
		 struct in_addr dst,
		 char *pim_msg,
		 int pim_msg_size,
		 const char *ifname)
{
  ssize_t            sent;
  struct sockaddr_in to;
  socklen_t          tolen;

  if (PIM_DEBUG_PIM_PACKETS) {
    char dst_str[100];
    pim_inet4_dump("<dst?>", dst, dst_str, sizeof(dst_str));
    zlog_debug("%s: to %s on %s: msg_size=%d checksum=%x",
	       __PRETTY_FUNCTION__,
	       dst_str, ifname, pim_msg_size,
	       *(uint16_t *) PIM_MSG_HDR_OFFSET_CHECKSUM(pim_msg));
  }

#if 0
  memset(&to, 0, sizeof(to));
#endif
  to.sin_family = AF_INET;
  to.sin_addr = dst;
#if 0
  to.sin_port = htons(0);
#endif
  tolen = sizeof(to);

  sent = sendto(fd, pim_msg, pim_msg_size, MSG_DONTWAIT, &to, tolen);
  if (sent != (ssize_t) pim_msg_size) {
    int e = errno;
    char dst_str[100];
    pim_inet4_dump("<dst?>", dst, dst_str, sizeof(dst_str));
    if (sent < 0) {
      zlog_warn("%s: sendto() failure to %s on %s: fd=%d msg_size=%d: errno=%d: %s",
		__PRETTY_FUNCTION__,
		dst_str, ifname, fd, pim_msg_size,
		e, strerror(e));
    }
    else {
      zlog_warn("%s: sendto() partial to %s on %s: fd=%d msg_size=%d: sent=%d",
		__PRETTY_FUNCTION__,
		dst_str, ifname, fd,
		pim_msg_size, sent);
    }
    return -1;
  }

  return 0;
}

static int hello_send(struct interface *ifp,
		      uint16_t holdtime)
{
  char pim_msg[PIM_PIM_BUFSIZE_WRITE];
  struct pim_interface *pim_ifp;
  int pim_tlv_size;
  int pim_msg_size;

  pim_ifp = ifp->info;

  if (PIM_DEBUG_PIM_PACKETS) {
    char dst_str[100];
    pim_inet4_dump("<dst?>", qpim_all_pim_routers_addr, dst_str, sizeof(dst_str));
    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",
	       __PRETTY_FUNCTION__,
	       dst_str, ifp->name,
	       holdtime,
	       pim_ifp->pim_propagation_delay_msec, pim_ifp->pim_override_interval_msec,
	       PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options),
	       pim_ifp->pim_dr_priority, pim_ifp->pim_generation_id,
	       listcount(ifp->connected));
  }

  pim_tlv_size = pim_hello_build_tlv(ifp->name,
				     pim_msg + PIM_PIM_MIN_LEN,
				     sizeof(pim_msg) - PIM_PIM_MIN_LEN,
				     holdtime,
				     pim_ifp->pim_dr_priority,
				     pim_ifp->pim_generation_id,
				     pim_ifp->pim_propagation_delay_msec,
				     pim_ifp->pim_override_interval_msec,
				     PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options),
				     ifp->connected);
  if (pim_tlv_size < 0) {
    return -1;
  }

  pim_msg_size = pim_tlv_size + PIM_PIM_MIN_LEN;

  zassert(pim_msg_size >= PIM_PIM_MIN_LEN);
  zassert(pim_msg_size <= PIM_PIM_BUFSIZE_WRITE);

  pim_msg_build_header(pim_msg, pim_msg_size,
		       PIM_MSG_TYPE_HELLO);

  if (pim_msg_send(pim_ifp->pim_sock_fd,
		   qpim_all_pim_routers_addr,
		   pim_msg,
		   pim_msg_size,
		   ifp->name)) {
    zlog_warn("%s: could not send PIM message on interface %s",
	      __PRETTY_FUNCTION__, ifp->name);
    return -2;
  }

  return 0;
}

static int pim_hello_send(struct interface *ifp,
			  uint16_t holdtime)
{
  struct pim_interface *pim_ifp;

  zassert(ifp);
  pim_ifp = ifp->info;
  zassert(pim_ifp);

  if (hello_send(ifp, holdtime)) {
    ++pim_ifp->pim_ifstat_hello_sendfail;

    zlog_warn("Could not send PIM hello on interface %s",
	      ifp->name);
    return -1;
  }

  ++pim_ifp->pim_ifstat_hello_sent;

  return 0;
}

static void hello_resched(struct interface *ifp)
{
  struct pim_interface *pim_ifp;

  zassert(ifp);
  pim_ifp = ifp->info;
  zassert(pim_ifp);

  if (PIM_DEBUG_PIM_TRACE) {
    zlog_debug("Rescheduling %d sec hello on interface %s",
	       pim_ifp->pim_hello_period, ifp->name);
  }
  THREAD_OFF(pim_ifp->t_pim_hello_timer);
  THREAD_TIMER_ON(master, pim_ifp->t_pim_hello_timer,
		  on_pim_hello_send,
		  ifp, pim_ifp->pim_hello_period);
}

/*
  Periodic hello timer
 */
static int on_pim_hello_send(struct thread *t)
{
  struct pim_interface *pim_ifp;
  struct interface *ifp;

  zassert(t);
  ifp = THREAD_ARG(t);
  zassert(ifp);

  pim_ifp = ifp->info;

  /*
   * Schedule next hello
   */
  pim_ifp->t_pim_hello_timer = 0;
  hello_resched(ifp);

  /*
   * Send hello
   */
  return pim_hello_send(ifp, PIM_IF_DEFAULT_HOLDTIME(pim_ifp));
}

/*
  RFC 4601: 4.3.1.  Sending Hello Messages

  Thus, if a router needs to send a Join/Prune or Assert message on an
  interface on which it has not yet sent a Hello message with the
  currently configured IP address, then it MUST immediately send the
  relevant Hello message without waiting for the Hello Timer to
  expire, followed by the Join/Prune or Assert message.
 */
void pim_hello_restart_now(struct interface *ifp)
{
  struct pim_interface *pim_ifp;

  zassert(ifp);
  pim_ifp = ifp->info;
  zassert(pim_ifp);

  /*
   * Reset next hello timer
   */
  hello_resched(ifp);

  /*
   * Immediately send hello
   */
  pim_hello_send(ifp, PIM_IF_DEFAULT_HOLDTIME(pim_ifp));
}

/*
  RFC 4601: 4.3.1.  Sending Hello Messages

  To allow new or rebooting routers to learn of PIM neighbors quickly,
  when a Hello message is received from a new neighbor, or a Hello
  message with a new GenID is received from an existing neighbor, a
  new Hello message should be sent on this interface after a
  randomized delay between 0 and Triggered_Hello_Delay.
 */
void pim_hello_restart_triggered(struct interface *ifp)
{
  struct pim_interface *pim_ifp;
  int triggered_hello_delay_msec;
  int random_msec;

  zassert(ifp);
  pim_ifp = ifp->info;
  zassert(pim_ifp);

  triggered_hello_delay_msec = 1000 * pim_ifp->pim_triggered_hello_delay;

  if (pim_ifp->t_pim_hello_timer) {
    long remain_msec = pim_time_timer_remain_msec(pim_ifp->t_pim_hello_timer);
    if (remain_msec <= triggered_hello_delay_msec) {
      /* Rescheduling hello would increase the delay, then it's faster
	 to just wait for the scheduled periodic hello. */
      return;
    }

    THREAD_OFF(pim_ifp->t_pim_hello_timer);
    pim_ifp->t_pim_hello_timer = 0;
  }
  zassert(!pim_ifp->t_pim_hello_timer);

  random_msec = pim_rand_next(0, triggered_hello_delay_msec);

  if (PIM_DEBUG_PIM_EVENTS) {
    zlog_debug("Scheduling %d msec triggered hello on interface %s",
	       random_msec, ifp->name);
  }

  THREAD_TIMER_MSEC_ON(master, pim_ifp->t_pim_hello_timer,
		       on_pim_hello_send,
		       ifp, triggered_hello_delay_msec);
}

int pim_sock_add(struct interface *ifp)
{
  struct pim_interface *pim_ifp;
  struct in_addr ifaddr;

  pim_ifp = ifp->info;
  zassert(pim_ifp);

  if (pim_ifp->pim_sock_fd >= 0) {
    zlog_warn("Can't recreate existing PIM socket fd=%d for interface %s",
	      pim_ifp->pim_sock_fd, ifp->name);
    return -1;
  }

  ifaddr = pim_ifp->primary_address;

  pim_ifp->pim_sock_fd = pim_sock_open(ifaddr, ifp->ifindex);
  if (pim_ifp->pim_sock_fd < 0) {
    zlog_warn("Could not open PIM socket on interface %s",
	      ifp->name);
    return -2;
  }

  pim_ifp->t_pim_sock_read   = 0;
  pim_ifp->pim_sock_creation = pim_time_monotonic_sec();

  pim_ifp->pim_generation_id = pim_rand() & (int64_t) 0xFFFFFFFF;

  zlog_info("PIM INTERFACE UP: on interface %s",
	    ifp->name);

  /*
   * Start receiving PIM messages
   */
  pim_sock_read_on(ifp);

  /*
   * Start sending PIM hello's
   */
  pim_hello_restart_triggered(ifp);

  return 0;
}
