コード例 #1
0
ファイル: pim_msdp.c プロジェクト: ton31337/frr
/* RFC-3618:Sec-5.6 - stop the peer tcp connection and startover */
void pim_msdp_peer_reset_tcp_conn(struct pim_msdp_peer *mp, const char *rc_str)
{
	if (PIM_DEBUG_EVENTS) {
		zlog_debug("MSDP peer %s tcp reset %s", mp->key_str, rc_str);
		snprintf(mp->last_reset, sizeof(mp->last_reset), "%s", rc_str);
	}

	/* close the connection and transition to listening or connecting */
	pim_msdp_peer_stop_tcp_conn(mp, true /* chg_state */);
	if (PIM_MSDP_PEER_IS_LISTENER(mp)) {
		pim_msdp_peer_listen(mp);
	} else {
		pim_msdp_peer_connect(mp);
	}
}
コード例 #2
0
ファイル: pim_msdp.c プロジェクト: ton31337/frr
/* delete the peer config */
static enum pim_msdp_err pim_msdp_peer_do_del(struct pim_msdp_peer *mp)
{
	/* stop the tcp connection and shutdown all timers */
	pim_msdp_peer_stop_tcp_conn(mp, true /* chg_state */);

	/* remove the session from various tables */
	listnode_delete(mp->pim->msdp.peer_list, mp);
	hash_release(mp->pim->msdp.peer_hash, mp);

	if (PIM_DEBUG_MSDP_EVENTS) {
		zlog_debug("MSDP peer %s deleted", mp->key_str);
	}

	/* free up any associated memory */
	pim_msdp_peer_free(mp);

	return PIM_MSDP_ERR_NONE;
}
コード例 #3
0
ファイル: pim_msdp.c プロジェクト: ton31337/frr
/* release all mem associated with a peer */
static void pim_msdp_peer_free(struct pim_msdp_peer *mp)
{
	/*
	 * Let's make sure we are not running when we delete
	 * the underlying data structure
	 */
	pim_msdp_peer_stop_tcp_conn(mp, false);

	if (mp->ibuf) {
		stream_free(mp->ibuf);
	}

	if (mp->obuf) {
		stream_fifo_free(mp->obuf);
	}

	if (mp->mesh_group_name) {
		XFREE(MTYPE_PIM_MSDP_MG_NAME, mp->mesh_group_name);
	}

	mp->pim = NULL;
	XFREE(MTYPE_PIM_MSDP_PEER, mp);
}
コード例 #4
0
/* passive peer socket accept */
static int pim_msdp_sock_accept(struct thread *thread)
{
	union sockunion su;
	struct pim_instance *pim = THREAD_ARG(thread);
	int accept_sock;
	int msdp_sock;
	struct pim_msdp_peer *mp;
	char buf[SU_ADDRSTRLEN];

	sockunion_init(&su);

	/* re-register accept thread */
	accept_sock = THREAD_FD(thread);
	if (accept_sock < 0) {
		flog_err(LIB_ERR_DEVELOPMENT,
			  "accept_sock is negative value %d", accept_sock);
		return -1;
	}
	pim->msdp.listener.thread = NULL;
	thread_add_read(master, pim_msdp_sock_accept, pim, accept_sock,
			&pim->msdp.listener.thread);

	/* accept client connection. */
	msdp_sock = sockunion_accept(accept_sock, &su);
	if (msdp_sock < 0) {
		flog_err_sys(LIB_ERR_SOCKET, "pim_msdp_sock_accept failed (%s)",
			     safe_strerror(errno));
		return -1;
	}

	/* see if have peer config for this */
	mp = pim_msdp_peer_find(pim, su.sin.sin_addr);
	if (!mp || !PIM_MSDP_PEER_IS_LISTENER(mp)) {
		++pim->msdp.rejected_accepts;
		if (PIM_DEBUG_MSDP_EVENTS) {
			flog_err(PIM_ERR_MSDP_PACKET,
				  "msdp peer connection refused from %s",
				  sockunion2str(&su, buf, SU_ADDRSTRLEN));
		}
		close(msdp_sock);
		return -1;
	}

	if (PIM_DEBUG_MSDP_INTERNAL) {
		zlog_debug("MSDP peer %s accept success%s", mp->key_str,
			   mp->fd >= 0 ? "(dup)" : "");
	}

	/* if we have an existing connection we need to kill that one
	 * with this one */
	if (mp->fd >= 0) {
		if (PIM_DEBUG_MSDP_EVENTS) {
			zlog_notice(
				"msdp peer new connection from %s stop old connection",
				sockunion2str(&su, buf, SU_ADDRSTRLEN));
		}
		pim_msdp_peer_stop_tcp_conn(mp, true /* chg_state */);
	}
	mp->fd = msdp_sock;
	set_nonblocking(mp->fd);
	pim_msdp_update_sock_send_buffer_size(mp->fd);
	pim_msdp_peer_established(mp);
	return 0;
}
コード例 #5
0
/* active peer socket setup */
int pim_msdp_sock_connect(struct pim_msdp_peer *mp)
{
	int rc;

	if (PIM_DEBUG_MSDP_INTERNAL) {
		zlog_debug("MSDP peer %s attempt connect%s", mp->key_str,
			   mp->fd < 0 ? "" : "(dup)");
	}

	/* if we have an existing connection we need to kill that one
	 * with this one */
	if (mp->fd >= 0) {
		if (PIM_DEBUG_MSDP_EVENTS) {
			zlog_notice(
				"msdp duplicate connect to %s nuke old connection",
				mp->key_str);
		}
		pim_msdp_peer_stop_tcp_conn(mp, false /* chg_state */);
	}

	/* Make socket for the peer. */
	mp->fd = sockunion_socket(&mp->su_peer);
	if (mp->fd < 0) {
		flog_err_sys(LIB_ERR_SOCKET,
			     "pim_msdp_socket socket failure: %s",
			     safe_strerror(errno));
		return -1;
	}

	if (mp->pim->vrf_id != VRF_DEFAULT) {
		struct interface *ifp =
			if_lookup_by_name(mp->pim->vrf->name, mp->pim->vrf_id);
		if (!ifp) {
			flog_err(LIB_ERR_INTERFACE,
				  "%s: Unable to lookup vrf interface: %s",
				  __PRETTY_FUNCTION__, mp->pim->vrf->name);
			return -1;
		}
		if (pim_socket_bind(mp->fd, ifp)) {
			flog_err_sys(LIB_ERR_SOCKET,
				     "%s: Unable to bind to socket: %s",
				     __PRETTY_FUNCTION__, safe_strerror(errno));
			close(mp->fd);
			mp->fd = -1;
			return -1;
		}
	}

	set_nonblocking(mp->fd);

	/* Set socket send buffer size */
	pim_msdp_update_sock_send_buffer_size(mp->fd);
	sockopt_reuseaddr(mp->fd);
	sockopt_reuseport(mp->fd);

	/* source bind */
	rc = sockunion_bind(mp->fd, &mp->su_local, 0, &mp->su_local);
	if (rc < 0) {
		flog_err_sys(LIB_ERR_SOCKET,
			     "pim_msdp_socket connect bind failure: %s",
			     safe_strerror(errno));
		close(mp->fd);
		mp->fd = -1;
		return rc;
	}

	/* Connect to the remote mp. */
	return (sockunion_connect(mp->fd, &mp->su_peer,
				  htons(PIM_MSDP_TCP_PORT), 0));
}