Commit ee7e814e authored by Yizhen Fan's avatar Yizhen Fan Committed by fanyizhen1995
Browse files

ub: ubcore add handle delete tp req



driver inclusion
category: feature
bugzilla: NA
CVE: NA

--------------------------------

Ubcore add handle delete tp req, which allows ubcore to handle request of
tp deletion.

The TP link deletion process varies according to the transport
mode and transaction type.

Signed-off-by: default avatarGuoxin Qian <qianguoxin@huawei.com>
Signed-off-by: default avatarYizhen Fan <fanyizhen@huawei.com>
parent 92c149b6
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -88,6 +88,17 @@ struct ubcore_nl_create_tp_resp {
	uint8_t peer_ext[0]; /* struct ubcore_tp_ext->len */
};

struct ubcore_nl_destroy_tp_req {
	uint32_t tpn;
	uint32_t peer_tpn;
	enum ubcore_transport_mode trans_mode;
	struct ubcore_ta_data ta;
};

struct ubcore_nl_destroy_tp_resp {
	enum ubcore_nl_resp_status ret;
};

struct ubcore_nl_query_tp_req {
	enum ubcore_transport_mode trans_mode;
};
+123 −19
Original line number Diff line number Diff line
@@ -100,25 +100,6 @@ static struct ubcore_nlmsg *ubcore_alloc_nlmsg(size_t payload_len, const union u
	return msg;
}

static struct ubcore_nlmsg *ubcore_get_query_tp_req(struct ubcore_device *dev,
						    const union ubcore_eid *remote_eid,
						    enum ubcore_transport_mode trans_mode)
{
	uint32_t payload_len = sizeof(struct ubcore_nl_query_tp_req);
	struct ubcore_nl_query_tp_req *query;
	struct ubcore_nlmsg *req;

	req = ubcore_alloc_nlmsg(payload_len, &dev->attr.eid, remote_eid);
	if (req == NULL)
		return NULL;

	req->transport_type = dev->transport_type;
	req->msg_type = UBCORE_NL_QUERY_TP_REQ;
	query = (struct ubcore_nl_query_tp_req *)req->payload;
	query->trans_mode = trans_mode;
	return req;
}

static int ubcore_set_tp_peer_ext(struct ubcore_tp_attr *attr, const uint8_t *ext_addr,
				  const uint32_t ext_len)
{
@@ -158,6 +139,25 @@ static int ubcore_negotiate_optimal_cc_alg(uint16_t local_congestion_alg,
	return -1;
}

static struct ubcore_nlmsg *ubcore_get_query_tp_req(struct ubcore_device *dev,
						    const union ubcore_eid *remote_eid,
						    enum ubcore_transport_mode trans_mode)
{
	uint32_t payload_len = sizeof(struct ubcore_nl_query_tp_req);
	struct ubcore_nl_query_tp_req *query;
	struct ubcore_nlmsg *req;

	req = ubcore_alloc_nlmsg(payload_len, &dev->attr.eid, remote_eid);
	if (req == NULL)
		return NULL;

	req->transport_type = dev->transport_type;
	req->msg_type = UBCORE_NL_QUERY_TP_REQ;
	query = (struct ubcore_nl_query_tp_req *)req->payload;
	query->trans_mode = trans_mode;
	return req;
}

static int ubcore_query_tp(struct ubcore_device *dev, const union ubcore_eid *remote_eid,
			   enum ubcore_transport_mode trans_mode,
			   struct ubcore_nl_query_tp_resp *query_tp_resp)
@@ -429,6 +429,28 @@ static int ubcore_set_target_peer(const struct ubcore_tp *tp, struct ubcore_tp_a
	return ubcore_set_tp_peer_ext(attr, create->ext_udrv, create->ext_len);
}

static struct ubcore_nlmsg *ubcore_get_destroy_tp_response(enum ubcore_nl_resp_status ret,
							   struct ubcore_nlmsg *req)
{
	struct ubcore_nl_destroy_tp_resp *destroy_resp;
	struct ubcore_nlmsg *resp = NULL;

	resp = ubcore_alloc_nlmsg(sizeof(struct ubcore_nl_destroy_tp_resp), &req->dst_eid,
				  &req->src_eid);
	if (resp == NULL) {
		ubcore_log_err("Failed to alloc destroy tp response");
		return NULL;
	}

	resp->msg_type = UBCORE_NL_DESTROY_TP_RESP;
	resp->nlmsg_seq = req->nlmsg_seq;
	resp->transport_type = req->transport_type;
	destroy_resp = (struct ubcore_nl_destroy_tp_resp *)resp->payload;
	destroy_resp->ret = ret;

	return resp;
}

static struct ubcore_nlmsg *ubcore_get_create_tp_response(struct ubcore_tp *tp,
							  struct ubcore_nlmsg *req)
{
@@ -752,6 +774,88 @@ struct ubcore_nlmsg *ubcore_handle_create_tp_req(struct ubcore_nlmsg *req)
}
EXPORT_SYMBOL(ubcore_handle_create_tp_req);

/* destroy target vtp created by ubcore_accept_target_vtp */
static int ubcore_unaccept_target_vtp(struct ubcore_device *dev,
				      struct ubcore_nl_destroy_tp_req *destroy)
{
	struct ubcore_tp *tp = ubcore_remove_tp_with_tpn(dev, destroy->peer_tpn);

	if (tp == NULL) {
		ubcore_log_warn("tp is not found or already destroyed %u", destroy->peer_tpn);
		return 0;
	}
	return ubcore_destroy_tp(tp);
}

/* destroy target RM tp created by ubcore_advise_target_tp */
static int ubcore_unadvise_target_tp(struct ubcore_device *dev,
				     struct ubcore_nl_destroy_tp_req *destroy)
{
	struct ubcore_tp_advice advice;
	struct ubcore_tp_meta *meta;
	struct ubcore_tp *tp = NULL;

	meta = &advice.meta;
	if (ubcore_parse_ta(dev, &destroy->ta, &advice) != 0) {
		ubcore_log_err("Failed to parse ta with type %u", destroy->ta.type);
		return -1;
	} else if (meta->ht == NULL) {
		ubcore_log_warn("tp table is already released");
		return 0;
	}

	tp = ubcore_find_remove_tp(meta->ht, meta->hash, &meta->key);
	/* pair with get_tptable in parse_ta */
	ubcore_put_tptable(meta->ht);
	if (tp == NULL) {
		ubcore_log_warn("tp is not found, already destroyed or under use %u",
				destroy->peer_tpn);
		return 0;
	}

	return ubcore_destroy_tp(tp);
}

/* destroy target RC tp created by ubcore_bind_target_tp */
static int ubcore_unbind_target_tp(struct ubcore_device *dev,
				   struct ubcore_nl_destroy_tp_req *destroy)
{
	return ubcore_unadvise_target_tp(dev, destroy);
}

struct ubcore_nlmsg *ubcore_handle_destroy_tp_req(struct ubcore_nlmsg *req)
{
	struct ubcore_nl_destroy_tp_req *destroy =
		(struct ubcore_nl_destroy_tp_req *)(void *)req->payload;
	struct ubcore_device *dev;
	int ret = -1;

	if (req->payload_len != sizeof(struct ubcore_nl_destroy_tp_req)) {
		ubcore_log_err("Invalid destroy req");
		return NULL;
	}

	dev = ubcore_find_device(&req->dst_eid, req->transport_type);
	if (dev == NULL || !ubcore_have_tp_ops(dev)) {
		if (dev != NULL)
			ubcore_put_device(dev);
		ubcore_log_err("Failed to find device or device ops invalid");
		return ubcore_get_destroy_tp_response(UBCORE_NL_RESP_FAIL, req);
	}

	if (destroy->ta.type == UBCORE_TA_VIRT) {
		ret = ubcore_unaccept_target_vtp(dev, destroy);
	} else if (destroy->trans_mode == UBCORE_TP_RC) {
		ret = ubcore_unbind_target_tp(dev, destroy);
	} else if (destroy->trans_mode == UBCORE_TP_RM &&
		   dev->transport_type == UBCORE_TRANSPORT_IB) {
		ret = ubcore_unadvise_target_tp(dev, destroy);
	}
	ubcore_put_device(dev);
	return ubcore_get_destroy_tp_response((enum ubcore_nl_resp_status)ret, req);
}
EXPORT_SYMBOL(ubcore_handle_destroy_tp_req);

struct ubcore_tp *ubcore_create_vtp(struct ubcore_device *dev, const union ubcore_eid *remote_eid,
				    enum ubcore_transport_mode trans_mode,
				    struct ubcore_udata *udata)
+1 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ int ubcore_advise_tp(struct ubcore_device *dev, const union ubcore_eid *remote_e
		     struct ubcore_tp_advice *advice, struct ubcore_udata *udata);

struct ubcore_nlmsg *ubcore_handle_create_tp_req(struct ubcore_nlmsg *req);
struct ubcore_nlmsg *ubcore_handle_destroy_tp_req(struct ubcore_nlmsg *req);
/* Called when clear tp table */
int ubcore_destroy_tp(struct ubcore_tp *tp);
#endif