/*
  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 "memory.h"
#include "vrf.h"

#include "pimd.h"
#include "pim_cmd.h"
#include "pim_iface.h"
#include "pim_zebra.h"
#include "pim_str.h"
#include "pim_oil.h"
#include "pim_pim.h"
#include "pim_upstream.h"
#include "pim_rpf.h"
#include "pim_ssmpingd.h"

const char *const PIM_ALL_SYSTEMS      = MCAST_ALL_SYSTEMS;
const char *const PIM_ALL_ROUTERS      = MCAST_ALL_ROUTERS;
const char *const PIM_ALL_PIM_ROUTERS  = MCAST_ALL_PIM_ROUTERS;
const char *const PIM_ALL_IGMP_ROUTERS = MCAST_ALL_IGMP_ROUTERS;

struct thread_master     *master = 0;
uint32_t                  qpim_debugs = 0;
int                       qpim_mroute_socket_fd = -1;
int64_t                   qpim_mroute_socket_creation = 0; /* timestamp of creation */
struct thread            *qpim_mroute_socket_reader = 0;
int                       qpim_mroute_oif_highest_vif_index = -1;
struct list              *qpim_channel_oil_list = 0;
int                       qpim_t_periodic = PIM_DEFAULT_T_PERIODIC; /* Period between Join/Prune Messages */
struct list              *qpim_upstream_list = 0;
struct zclient           *qpim_zclient_update = 0;
struct zclient           *qpim_zclient_lookup = 0;
struct pim_assert_metric  qpim_infinite_assert_metric;
long                      qpim_rpf_cache_refresh_delay_msec = 10000;
struct thread            *qpim_rpf_cache_refresher = 0;
int64_t                   qpim_rpf_cache_refresh_requests = 0;
int64_t                   qpim_rpf_cache_refresh_events = 0;
int64_t                   qpim_rpf_cache_refresh_last =  0;
struct in_addr            qpim_inaddr_any;
struct list              *qpim_ssmpingd_list = 0;
struct in_addr            qpim_ssmpingd_group_addr;
int64_t                   qpim_scan_oil_events = 0;
int64_t                   qpim_scan_oil_last = 0;
int64_t                   qpim_mroute_add_events = 0;
int64_t                   qpim_mroute_add_last = 0;
int64_t                   qpim_mroute_del_events = 0;
int64_t                   qpim_mroute_del_last = 0;

static void pim_free()
{
  pim_ssmpingd_destroy();

  if (qpim_channel_oil_list)
    list_free(qpim_channel_oil_list);

  if (qpim_upstream_list)
    list_free(qpim_upstream_list);
}

void pim_init()
{
  srandom(time(NULL));

  if (!inet_aton(PIM_ALL_PIM_ROUTERS, &qpim_all_pim_routers_addr)) {
    zlog_err("%s %s: could not solve %s to group address: errno=%d: %s",
	     __FILE__, __PRETTY_FUNCTION__,
	     PIM_ALL_PIM_ROUTERS, errno, safe_strerror(errno));
    zassert(0);
    return;
  }

  qpim_channel_oil_list = list_new();
  if (!qpim_channel_oil_list) {
    zlog_err("%s %s: failure: channel_oil_list=list_new()",
	     __FILE__, __PRETTY_FUNCTION__);
    return;
  }
  qpim_channel_oil_list->del = (void (*)(void *)) pim_channel_oil_free;

  qpim_upstream_list = list_new();
  if (!qpim_upstream_list) {
    zlog_err("%s %s: failure: upstream_list=list_new()",
	     __FILE__, __PRETTY_FUNCTION__);
    pim_free();
    return;
  }
  qpim_upstream_list->del = (void (*)(void *)) pim_upstream_free;

  qpim_mroute_socket_fd = -1; /* mark mroute as disabled */
  qpim_mroute_oif_highest_vif_index = -1;

  zassert(!qpim_debugs);
  zassert(!PIM_MROUTE_IS_ENABLED);

  qpim_inaddr_any.s_addr = PIM_NET_INADDR_ANY;

  /*
    RFC 4601: 4.6.3.  Assert Metrics

    assert_metric
    infinite_assert_metric() {
    return {1,infinity,infinity,0}
    }
  */
  qpim_infinite_assert_metric.rpt_bit_flag      = 1;
  qpim_infinite_assert_metric.metric_preference = PIM_ASSERT_METRIC_PREFERENCE_MAX;
  qpim_infinite_assert_metric.route_metric      = PIM_ASSERT_ROUTE_METRIC_MAX;
  qpim_infinite_assert_metric.ip_address        = qpim_inaddr_any;

  pim_cmd_init();
  pim_ssmpingd_init();
}

void pim_terminate()
{
  vrf_terminate();
  pim_free();
}
