Exemple #1
0
static int process_dreg_ack(struct vio_driver_state *vio,
			    struct vio_dring_register *pkt)
{
	struct vio_dring_state *dr;

	viodbg(HS, "GOT DRING_REG ACK ident[%llx] "
	       "ndesc[%u] dsz[%u] opt[0x%x] ncookies[%u]\n",
	       (unsigned long long) pkt->dring_ident,
	       pkt->num_descr, pkt->descr_size, pkt->options,
	       pkt->num_cookies);

	dr = &vio->drings[VIO_DRIVER_TX_RING];

	if (!(vio->dr_state & VIO_DR_STATE_TXREQ))
		return handshake_failure(vio);

	dr->ident = pkt->dring_ident;
	vio->dr_state |= VIO_DR_STATE_TXREG;

	if (all_drings_registered(vio)) {
		if (send_rdx(vio) < 0)
			return handshake_failure(vio);
		vio->hs_state = VIO_HS_SENT_RDX;
	}
	return 0;
}
static void
handshake_cb(SoupSession *session,
		SoupMessage *message,
		void *user_data)
{
	sr_session_t *s = user_data;
	struct sr_session_priv *priv = s->priv;
	const char *data, *end;

	if (!SOUP_STATUS_IS_SUCCESSFUL(message->status_code)) {
		handshake_failure(s);
		return;
	}

	data = message->response_body->data;
	end = strchr(data, '\n');
	if (!end) /* really bad */
		return;

	if (strncmp(data, "OK", end - data) == 0) {
		priv->handshake_delay = 1;
		parse_handshake(s, data);
		sr_session_submit(s);
	}
	else if (strncmp(data, "BANNED", end - data) == 0)
		fatal_error(s, "Client is banned");
	else if (strncmp(data, "BADAUTH", end - data) == 0)
		fatal_error(s, "Bad authorization");
	else if (strncmp(data, "BADTIME", end - data) == 0)
		fatal_error(s, "Wrong system time");
	else
		handshake_failure(s);
}
Exemple #3
0
static int process_attr(struct vio_driver_state *vio, void *pkt)
{
	int err;

	if (!(vio->hs_state & VIO_HS_GOTVERS))
		return handshake_failure(vio);

	if (!vio->ops)
		return 0;

	err = vio->ops->handle_attr(vio, pkt);
	if (err < 0) {
		return handshake_failure(vio);
	} else {
		vio->hs_state |= VIO_HS_GOT_ATTR;

		if ((vio->dr_state & VIO_DR_STATE_TXREQ) &&
		    !(vio->hs_state & VIO_HS_SENT_DREG)) {
			if (send_dreg(vio) < 0)
				return handshake_failure(vio);

			vio->hs_state |= VIO_HS_SENT_DREG;
		}
	}

	return 0;
}
Exemple #4
0
static int process_rdx(struct vio_driver_state *vio, struct vio_rdx *pkt)
{
	if (!all_drings_registered(vio))
		handshake_failure(vio);

	switch (pkt->tag.stype) {
	case VIO_SUBTYPE_INFO:
		return process_rdx_info(vio, pkt);

	case VIO_SUBTYPE_ACK:
		return process_rdx_ack(vio, pkt);

	case VIO_SUBTYPE_NACK:
		return process_rdx_nack(vio, pkt);

	default:
		return handshake_failure(vio);
	}
}
Exemple #5
0
static int process_rdx_ack(struct vio_driver_state *vio, struct vio_rdx *pkt)
{
	viodbg(HS, "GOT RDX ACK\n");

	if (!(vio->hs_state & VIO_HS_SENT_RDX))
		return handshake_failure(vio);

	vio->hs_state |= VIO_HS_GOT_RDX_ACK;
	return 0;
}
Exemple #6
0
static int process_ver_nack(struct vio_driver_state *vio,
			    struct vio_ver_info *pkt)
{
	struct vio_version *nver;

	viodbg(HS, "GOT VERSION NACK maj[%u] min[%u] devclass[%u]\n",
	       pkt->major, pkt->minor, pkt->dev_class);

	if (pkt->major == 0 && pkt->minor == 0)
		return handshake_failure(vio);
	nver = find_by_major(vio, pkt->major);
	if (!nver)
		return handshake_failure(vio);

	if (send_version(vio, nver->major, nver->minor) < 0)
		return handshake_failure(vio);

	return 0;
}
Exemple #7
0
static int process_dreg(struct vio_driver_state *vio,
			struct vio_dring_register *pkt)
{
	if (!(vio->hs_state & VIO_HS_GOTVERS))
		return handshake_failure(vio);

	switch (pkt->tag.stype) {
	case VIO_SUBTYPE_INFO:
		return process_dreg_info(vio, pkt);

	case VIO_SUBTYPE_ACK:
		return process_dreg_ack(vio, pkt);

	case VIO_SUBTYPE_NACK:
		return process_dreg_nack(vio, pkt);

	default:
		return handshake_failure(vio);
	}
}
Exemple #8
0
static int process_dreg_nack(struct vio_driver_state *vio,
			     struct vio_dring_register *pkt)
{
	viodbg(HS, "GOT DRING_REG NACK ident[%llx] "
	       "ndesc[%u] dsz[%u] opt[0x%x] ncookies[%u]\n",
	       (unsigned long long) pkt->dring_ident,
	       pkt->num_descr, pkt->descr_size, pkt->options,
	       pkt->num_cookies);

	return handshake_failure(vio);
}
Exemple #9
0
static int process_rdx_info(struct vio_driver_state *vio, struct vio_rdx *pkt)
{
	viodbg(HS, "GOT RDX INFO\n");

	pkt->tag.stype = VIO_SUBTYPE_ACK;
	viodbg(HS, "SEND RDX ACK\n");
	if (send_ctrl(vio, &pkt->tag, sizeof(*pkt)) < 0)
		return handshake_failure(vio);

	vio->hs_state |= VIO_HS_SENT_RDX_ACK;
	return 0;
}
Exemple #10
0
static int process_ver(struct vio_driver_state *vio, struct vio_ver_info *pkt)
{
	switch (pkt->tag.stype) {
	case VIO_SUBTYPE_INFO:
		return process_ver_info(vio, pkt);

	case VIO_SUBTYPE_ACK:
		return process_ver_ack(vio, pkt);

	case VIO_SUBTYPE_NACK:
		return process_ver_nack(vio, pkt);

	default:
		return handshake_failure(vio);
	}
}
Exemple #11
0
static int process_rdx_nack(struct vio_driver_state *vio, struct vio_rdx *pkt)
{
	viodbg(HS, "GOT RDX NACK\n");

	return handshake_failure(vio);
}
Exemple #12
0
static int process_dreg_info(struct vio_driver_state *vio,
			     struct vio_dring_register *pkt)
{
	struct vio_dring_state *dr;
	int i, len;

	viodbg(HS, "GOT DRING_REG INFO ident[%llx] "
	       "ndesc[%u] dsz[%u] opt[0x%x] ncookies[%u]\n",
	       (unsigned long long) pkt->dring_ident,
	       pkt->num_descr, pkt->descr_size, pkt->options,
	       pkt->num_cookies);

	if (!(vio->dr_state & VIO_DR_STATE_RXREQ))
		goto send_nack;

	if (vio->dr_state & VIO_DR_STATE_RXREG)
		goto send_nack;

	BUG_ON(vio->desc_buf);

	vio->desc_buf = kzalloc(pkt->descr_size, GFP_ATOMIC);
	if (!vio->desc_buf)
		goto send_nack;

	vio->desc_buf_len = pkt->descr_size;

	dr = &vio->drings[VIO_DRIVER_RX_RING];

	dr->num_entries = pkt->num_descr;
	dr->entry_size = pkt->descr_size;
	dr->ncookies = pkt->num_cookies;
	for (i = 0; i < dr->ncookies; i++) {
		dr->cookies[i] = pkt->cookies[i];

		viodbg(HS, "DRING COOKIE(%d) [%016llx:%016llx]\n",
		       i,
		       (unsigned long long)
		       pkt->cookies[i].cookie_addr,
		       (unsigned long long)
		       pkt->cookies[i].cookie_size);
	}

	pkt->tag.stype = VIO_SUBTYPE_ACK;
	pkt->dring_ident = ++dr->ident;

	viodbg(HS, "SEND DRING_REG ACK ident[%llx]\n",
	       (unsigned long long) pkt->dring_ident);

	len = (sizeof(*pkt) +
	       (dr->ncookies * sizeof(struct ldc_trans_cookie)));
	if (send_ctrl(vio, &pkt->tag, len) < 0)
		goto send_nack;

	vio->dr_state |= VIO_DR_STATE_RXREG;

	return 0;

send_nack:
	pkt->tag.stype = VIO_SUBTYPE_NACK;
	viodbg(HS, "SEND DRING_REG NACK\n");
	(void) send_ctrl(vio, &pkt->tag, sizeof(*pkt));

	return handshake_failure(vio);
}
Exemple #13
0
static int process_ver_info(struct vio_driver_state *vio,
			    struct vio_ver_info *pkt)
{
	struct vio_version *vap;
	int err;

	viodbg(HS, "GOT VERSION INFO maj[%u] min[%u] devclass[%u]\n",
	       pkt->major, pkt->minor, pkt->dev_class);

	if (vio->hs_state != VIO_HS_INVALID) {
		/* XXX Perhaps invoke start_handshake? XXX */
		memset(&vio->ver, 0, sizeof(vio->ver));
		vio->hs_state = VIO_HS_INVALID;
	}

	vap = find_by_major(vio, pkt->major);

	vio->_peer_sid = pkt->tag.sid;

	if (!vap) {
		pkt->tag.stype = VIO_SUBTYPE_NACK;
		pkt->major = 0;
		pkt->minor = 0;
		viodbg(HS, "SEND VERSION NACK maj[0] min[0]\n");
		err = send_ctrl(vio, &pkt->tag, sizeof(*pkt));
	} else if (vap->major != pkt->major) {
		pkt->tag.stype = VIO_SUBTYPE_NACK;
		pkt->major = vap->major;
		pkt->minor = vap->minor;
		viodbg(HS, "SEND VERSION NACK maj[%u] min[%u]\n",
		       pkt->major, pkt->minor);
		err = send_ctrl(vio, &pkt->tag, sizeof(*pkt));
	} else {
		struct vio_version ver = {
			.major = pkt->major,
			.minor = pkt->minor,
		};
		if (ver.minor > vap->minor)
			ver.minor = vap->minor;
		pkt->minor = ver.minor;
		pkt->tag.stype = VIO_SUBTYPE_ACK;
		viodbg(HS, "SEND VERSION ACK maj[%u] min[%u]\n",
		       pkt->major, pkt->minor);
		err = send_ctrl(vio, &pkt->tag, sizeof(*pkt));
		if (err > 0) {
			vio->ver = ver;
			vio->hs_state = VIO_HS_GOTVERS;
		}
	}
	if (err < 0)
		return handshake_failure(vio);

	return 0;
}

static int process_ver_ack(struct vio_driver_state *vio,
			   struct vio_ver_info *pkt)
{
	viodbg(HS, "GOT VERSION ACK maj[%u] min[%u] devclass[%u]\n",
	       pkt->major, pkt->minor, pkt->dev_class);

	if (vio->hs_state & VIO_HS_GOTVERS) {
		if (vio->ver.major != pkt->major ||
		    vio->ver.minor != pkt->minor) {
			pkt->tag.stype = VIO_SUBTYPE_NACK;
			(void) send_ctrl(vio, &pkt->tag, sizeof(*pkt));
			return handshake_failure(vio);
		}
	} else {
		vio->ver.major = pkt->major;
		vio->ver.minor = pkt->minor;
		vio->hs_state = VIO_HS_GOTVERS;
	}

	switch (vio->dev_class) {
	case VDEV_NETWORK:
	case VDEV_DISK:
		if (send_attr(vio) < 0)
			return handshake_failure(vio);
		break;

	default:
		break;
	}

	return 0;
}