Exemple #1
0
static void pim_msdp_sa_peer_ip_set(struct pim_msdp_sa *sa,
				    struct pim_msdp_peer *mp, struct in_addr rp)
{
	struct pim_msdp_peer *old_mp;

	/* optimize the "no change" case as it will happen
	 * frequently/periodically */
	if (mp && (sa->peer.s_addr == mp->peer.s_addr)) {
		return;
	}

	/* any time the peer ip changes also update the rp address */
	if (PIM_INADDR_ISNOT_ANY(sa->peer)) {
		old_mp = pim_msdp_peer_find(sa->pim, sa->peer);
		if (old_mp && old_mp->sa_cnt) {
			--old_mp->sa_cnt;
		}
	}

	if (mp) {
		++mp->sa_cnt;
		sa->peer = mp->peer;
	} else {
		sa->peer.s_addr = PIM_NET_INADDR_ANY;
	}
	sa->rp = rp;
}
Exemple #2
0
/* add peer configuration if it doesn't already exist */
enum pim_msdp_err pim_msdp_peer_add(struct pim_instance *pim,
				    struct in_addr peer_addr,
				    struct in_addr local_addr,
				    const char *mesh_group_name,
				    struct pim_msdp_peer **mp_p)
{
	struct pim_msdp_peer *mp;

	if (mp_p) {
		*mp_p = NULL;
	}

	if (peer_addr.s_addr == local_addr.s_addr) {
		/* skip session setup if config is invalid */
		if (PIM_DEBUG_MSDP_EVENTS) {
			char peer_str[INET_ADDRSTRLEN];

			pim_inet4_dump("<peer?>", peer_addr, peer_str,
				       sizeof(peer_str));
			zlog_debug("%s add skipped as DIP=SIP", peer_str);
		}
		return PIM_MSDP_ERR_SIP_EQ_DIP;
	}

	mp = pim_msdp_peer_find(pim, peer_addr);
	if (mp) {
		if (mp_p) {
			*mp_p = mp;
		}
		return PIM_MSDP_ERR_PEER_EXISTS;
	}

	return pim_msdp_peer_new(pim, peer_addr, local_addr, mesh_group_name,
				 mp_p);
}
Exemple #3
0
enum pim_msdp_err pim_msdp_peer_del(struct pim_instance *pim,
				    struct in_addr peer_addr)
{
	struct pim_msdp_peer *mp;

	mp = pim_msdp_peer_find(pim, peer_addr);
	if (!mp) {
		return PIM_MSDP_ERR_NO_PEER;
	}

	return pim_msdp_peer_do_del(mp);
}
Exemple #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;
}