start_vrrp(data_t *old_global_data)
{
	/* Clear the flags used for optimising performance */
	clear_summary_flags();

	/* Initialize sub-system */
	if (!__test_bit(CONFIG_TEST_BIT, &debug))
		kernel_netlink_init();

	if (reload)
		global_data = alloc_global_data();
	else if (global_data->default_ifname) {
		/* We need to set the default_ifp here on startup, since
		 * the parent process doesn't know about the interfaces */
		global_data->default_ifp = if_get_by_ifname(global_data->default_ifname, IF_CREATE_IF_DYNAMIC);
		if (!global_data->default_ifp)
			log_message(LOG_INFO, "WARNING - default interface %s doesn't exist", global_data->default_ifname);
	}

	/* Parse configuration file */
	vrrp_data = alloc_vrrp_data();
	if (!vrrp_data) {
		stop_vrrp(KEEPALIVED_EXIT_FATAL);
		return;
	}

	init_data(conf_file, vrrp_init_keywords);

	if (non_existent_interface_specified) {
		report_config_error(CONFIG_BAD_IF, "Non-existent interface specified in configuration");
		stop_vrrp(KEEPALIVED_EXIT_CONFIG);
		return;
	}

	if (reload)
		init_global_data(global_data, old_global_data);

	/* Set our copy of time */
	set_time_now();

	if (!__test_bit(CONFIG_TEST_BIT, &debug)) {
#if defined _WITH_SNMP_RFC || defined _WITH_SNMP_VRRP_
		if (!reload && (
#ifdef _WITH_SNMP_VRRP_
		     global_data->enable_snmp_vrrp ||
#endif
#ifdef _WITH_SNMP_RFCV2_
		     global_data->enable_snmp_rfcv2 ||
#endif
#ifdef _WITH_SNMP_RFCV3_
		     global_data->enable_snmp_rfcv3 ||
#endif
		     false)) {
			vrrp_snmp_agent_init(global_data->snmp_socket);
#ifdef _WITH_SNMP_RFC_
			vrrp_start_time = time_now;
#endif
		}
#endif

#ifdef _WITH_LVS_
		if (vrrp_ipvs_needed()) {
			/* Initialize ipvs related */
			if (ipvs_start() != IPVS_SUCCESS) {
				stop_vrrp(KEEPALIVED_EXIT_FATAL);
				return;
			}

			/* Set LVS timeouts */
			if (global_data->lvs_tcp_timeout ||
			    global_data->lvs_tcpfin_timeout ||
			    global_data->lvs_udp_timeout)
				ipvs_set_timeouts(global_data->lvs_tcp_timeout, global_data->lvs_tcpfin_timeout, global_data->lvs_udp_timeout);

			/* If we are managing the sync daemon, then stop any
			 * instances of it that may have been running if
			 * we terminated abnormally */
			ipvs_syncd_cmd(IPVS_STOPDAEMON, NULL, IPVS_MASTER, true, true);
			ipvs_syncd_cmd(IPVS_STOPDAEMON, NULL, IPVS_BACKUP, true, true);
		}
#endif

		if (reload) {
			kernel_netlink_set_recv_bufs();

			clear_diff_saddresses();
#ifdef _HAVE_FIB_ROUTING_
			clear_diff_srules();
			clear_diff_sroutes();
#endif
			clear_diff_script();
#ifdef _WITH_BFD_
			clear_diff_bfd();
#endif
		}
		else {
			/* Clear leftover static entries */
			netlink_iplist(vrrp_data->static_addresses, IPADDRESS_DEL, false);
#ifdef _HAVE_FIB_ROUTING_
			netlink_rtlist(vrrp_data->static_routes, IPROUTE_DEL);
			netlink_error_ignore = ENOENT;
			netlink_rulelist(vrrp_data->static_rules, IPRULE_DEL, true);
			netlink_error_ignore = 0;
#endif
		}

#ifdef _WITH_DBUS_
		if (!reload && global_data->enable_dbus)
			if (!dbus_start())
				global_data->enable_dbus = false;
#endif
	}

	/* Complete VRRP initialization */
	if (!vrrp_complete_init()) {
		stop_vrrp(KEEPALIVED_EXIT_CONFIG);
		return;
	}

	/* If we are just testing the configuration, then we terminate now */
	if (__test_bit(CONFIG_TEST_BIT, &debug))
		return;

	/* Start or stop gratuitous arp/ndisc as appropriate */
	if (have_ipv4_instance)
		gratuitous_arp_init();
	else
		gratuitous_arp_close();
	if (have_ipv6_instance)
		ndisc_init();
	else
		ndisc_close();

	/* We need to delay the init of iptables to after vrrp_complete_init()
	 * has been called so we know whether we want IPv4 and/or IPv6 */
	iptables_init();

	/* Make sure we don't have any old iptables/ipsets settings left around */
#ifdef _HAVE_LIBIPTC_
	if (!reload)
		iptables_cleanup();

	iptables_startup(reload);
#endif

	if (!reload)
		vrrp_restore_interfaces_startup();

	/* clear_diff_vrrp must be called after vrrp_complete_init, since the latter
	 * sets ifp on the addresses, which is used for the address comparison */
	if (reload)
		clear_diff_vrrp();

#ifdef _WITH_DBUS_
	if (reload && global_data->enable_dbus)
		dbus_reload(old_vrrp_data->vrrp, vrrp_data->vrrp);
#endif

	/* Post initializations */
#ifdef _MEM_CHECK_
	log_message(LOG_INFO, "Configuration is using : %zu Bytes", mem_allocated);
#endif

	/* Set static entries */
	netlink_iplist(vrrp_data->static_addresses, IPADDRESS_ADD, false);
#ifdef _HAVE_FIB_ROUTING_
	netlink_rtlist(vrrp_data->static_routes, IPROUTE_ADD);
	netlink_rulelist(vrrp_data->static_rules, IPRULE_ADD, false);
#endif

	/* Dump configuration */
	if (__test_bit(DUMP_CONF_BIT, &debug))
		dump_data_vrrp(NULL);

	/* Init & start the VRRP packet dispatcher */
	thread_add_event(master, vrrp_dispatcher_init, NULL,
			 VRRP_DISPATCHER);

	/* Set the process priority and non swappable if configured */
	set_process_priorities(
#ifdef _HAVE_SCHED_RT_
			       global_data->vrrp_realtime_priority,
#if HAVE_DECL_RLIMIT_RTTIME == 1
			       global_data->vrrp_rlimit_rt,
#endif
#endif
			       global_data->vrrp_process_priority, global_data->vrrp_no_swap ? 4096 : 0);

	/* Ensure we can open sufficient file descriptors */
	set_vrrp_max_fds();
}