Commit 55bd079a authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'smc-EDID-support'



Guvenc Gulce says:

====================
net/smc: add EID support

please apply the following patch series for smc to netdev's net-next
tree. The series introduce the so called Enterprise ID support for smc
protocol. Including the generic netlink based interface.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents f787e3cf 3c572145
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -38,6 +38,9 @@ enum { /* SMC PNET Table commands */
#define SMC_GENL_FAMILY_VERSION		1

#define SMC_PCI_ID_STR_LEN		16 /* Max length of pci id string */
#define SMC_MAX_HOSTNAME_LEN		32 /* Max length of the hostname */
#define SMC_MAX_UEID			4  /* Max number of user EIDs */
#define SMC_MAX_EID_LEN			32 /* Max length of an EID */

/* SMC_GENL_FAMILY commands */
enum {
@@ -49,6 +52,13 @@ enum {
	SMC_NETLINK_GET_DEV_SMCR,
	SMC_NETLINK_GET_STATS,
	SMC_NETLINK_GET_FBACK_STATS,
	SMC_NETLINK_DUMP_UEID,
	SMC_NETLINK_ADD_UEID,
	SMC_NETLINK_REMOVE_UEID,
	SMC_NETLINK_FLUSH_UEID,
	SMC_NETLINK_DUMP_SEID,
	SMC_NETLINK_ENABLE_SEID,
	SMC_NETLINK_DISABLE_SEID,
};

/* SMC_GENL_FAMILY top level attributes */
@@ -242,4 +252,21 @@ enum {
	__SMC_NLA_FBACK_STATS_MAX,
	SMC_NLA_FBACK_STATS_MAX = __SMC_NLA_FBACK_STATS_MAX - 1
};

/* SMC_NETLINK_UEID attributes */
enum {
	SMC_NLA_EID_TABLE_UNSPEC,
	SMC_NLA_EID_TABLE_ENTRY,	/* string */
	__SMC_NLA_EID_TABLE_MAX,
	SMC_NLA_EID_TABLE_MAX = __SMC_NLA_EID_TABLE_MAX - 1
};

/* SMC_NETLINK_SEID attributes */
enum {
	SMC_NLA_SEID_UNSPEC,
	SMC_NLA_SEID_ENTRY,	/* string */
	SMC_NLA_SEID_ENABLED,	/* u8 */
	__SMC_NLA_SEID_TABLE_MAX,
	SMC_NLA_SEID_TABLE_MAX = __SMC_NLA_SEID_TABLE_MAX - 1
};
#endif /* _UAPI_LINUX_SMC_H */
+22 −12
Original line number Diff line number Diff line
@@ -829,7 +829,7 @@ static int smc_connect_rdma(struct smc_sock *smc,
	smc_rmb_sync_sg_for_device(&smc->conn);

	reason_code = smc_clc_send_confirm(smc, ini->first_contact_local,
					   SMC_V1);
					   SMC_V1, NULL);
	if (reason_code)
		goto connect_abort;

@@ -883,6 +883,7 @@ static int smc_connect_ism(struct smc_sock *smc,
			   struct smc_clc_msg_accept_confirm *aclc,
			   struct smc_init_info *ini)
{
	u8 *eid = NULL;
	int rc = 0;

	ini->is_smcd = true;
@@ -918,8 +919,15 @@ static int smc_connect_ism(struct smc_sock *smc,
	smc_rx_init(smc);
	smc_tx_init(smc);

	if (aclc->hdr.version > SMC_V1) {
		struct smc_clc_msg_accept_confirm_v2 *clc_v2 =
			(struct smc_clc_msg_accept_confirm_v2 *)aclc;

		eid = clc_v2->eid;
	}

	rc = smc_clc_send_confirm(smc, ini->first_contact_local,
				  aclc->hdr.version);
				  aclc->hdr.version, eid);
	if (rc)
		goto connect_abort;
	mutex_unlock(&smc_server_lgr_pending);
@@ -1533,9 +1541,8 @@ static void smc_find_ism_v2_device_serv(struct smc_sock *new_smc,
	pclc_smcd = smc_get_clc_msg_smcd(pclc);
	smc_v2_ext = smc_get_clc_v2_ext(pclc);
	smcd_v2_ext = smc_get_clc_smcd_v2_ext(smc_v2_ext);
	if (!smcd_v2_ext ||
	    !smc_v2_ext->hdr.flag.seid) { /* no system EID support for SMCD */
		smc_find_ism_store_rc(SMC_CLC_DECL_NOSEID, ini);
	if (!smcd_v2_ext) {
		smc_find_ism_store_rc(SMC_CLC_DECL_NOV2DEXT, ini);
		goto not_found;
	}

@@ -1555,13 +1562,13 @@ static void smc_find_ism_v2_device_serv(struct smc_sock *new_smc,
	}
	mutex_unlock(&smcd_dev_list.mutex);

	if (ini->ism_dev[0]) {
		smc_ism_get_system_eid(ini->ism_dev[0], &eid);
		if (memcmp(eid, smcd_v2_ext->system_eid, SMC_MAX_EID_LEN))
	if (!ini->ism_dev[0])
		goto not_found;
	} else {

	smc_ism_get_system_eid(&eid);
	if (!smc_clc_match_eid(ini->negotiated_eid, smc_v2_ext,
			       smcd_v2_ext->system_eid, eid))
		goto not_found;
	}

	/* separate - outside the smcd_dev_list.lock */
	smcd_version = ini->smcd_version;
@@ -1579,6 +1586,7 @@ static void smc_find_ism_v2_device_serv(struct smc_sock *new_smc,
	}
	/* no V2 ISM device could be initialized */
	ini->smcd_version = smcd_version;	/* restore original value */
	ini->negotiated_eid[0] = 0;

not_found:
	ini->smcd_version &= ~SMC_V2;
@@ -1788,7 +1796,8 @@ static void smc_listen_work(struct work_struct *work)

	/* send SMC Accept CLC message */
	rc = smc_clc_send_accept(new_smc, ini->first_contact_local,
				 ini->smcd_version == SMC_V2 ? SMC_V2 : SMC_V1);
				 ini->smcd_version == SMC_V2 ? SMC_V2 : SMC_V1,
				 ini->negotiated_eid);
	if (rc)
		goto out_unlock;

@@ -2662,6 +2671,7 @@ static void __exit smc_exit(void)
	proto_unregister(&smc_proto);
	smc_pnet_exit();
	smc_nl_exit();
	smc_clc_exit();
	unregister_pernet_subsys(&smc_net_stat_ops);
	unregister_pernet_subsys(&smc_net_ops);
	rcu_barrier();
+0 −3
Original line number Diff line number Diff line
@@ -29,9 +29,6 @@
					 * devices
					 */

#define SMC_MAX_HOSTNAME_LEN	32
#define SMC_MAX_EID_LEN		32

extern struct proto smc_proto;
extern struct proto smc_proto6;

+313 −17
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include "smc_clc.h"
#include "smc_ib.h"
#include "smc_ism.h"
#include "smc_netlink.h"

#define SMCR_CLC_ACCEPT_CONFIRM_LEN 68
#define SMCD_CLC_ACCEPT_CONFIRM_LEN 48
@@ -39,6 +40,285 @@ static const char SMCD_EYECATCHER[4] = {'\xe2', '\xd4', '\xc3', '\xc4'};

static u8 smc_hostname[SMC_MAX_HOSTNAME_LEN];

struct smc_clc_eid_table {
	rwlock_t lock;
	struct list_head list;
	u8 ueid_cnt;
	u8 seid_enabled;
};

static struct smc_clc_eid_table smc_clc_eid_table;

struct smc_clc_eid_entry {
	struct list_head list;
	u8 eid[SMC_MAX_EID_LEN];
};

/* The size of a user EID is 32 characters.
 * Valid characters should be (single-byte character set) A-Z, 0-9, '.' and '-'.
 * Blanks should only be used to pad to the expected size.
 * First character must be alphanumeric.
 */
static bool smc_clc_ueid_valid(char *ueid)
{
	char *end = ueid + SMC_MAX_EID_LEN;

	while (--end >= ueid && isspace(*end))
		;
	if (end < ueid)
		return false;
	if (!isalnum(*ueid) || islower(*ueid))
		return false;
	while (ueid <= end) {
		if ((!isalnum(*ueid) || islower(*ueid)) && *ueid != '.' &&
		    *ueid != '-')
			return false;
		ueid++;
	}
	return true;
}

static int smc_clc_ueid_add(char *ueid)
{
	struct smc_clc_eid_entry *new_ueid, *tmp_ueid;
	int rc;

	if (!smc_clc_ueid_valid(ueid))
		return -EINVAL;

	/* add a new ueid entry to the ueid table if there isn't one */
	new_ueid = kzalloc(sizeof(*new_ueid), GFP_KERNEL);
	if (!new_ueid)
		return -ENOMEM;
	memcpy(new_ueid->eid, ueid, SMC_MAX_EID_LEN);

	write_lock(&smc_clc_eid_table.lock);
	if (smc_clc_eid_table.ueid_cnt >= SMC_MAX_UEID) {
		rc = -ERANGE;
		goto err_out;
	}
	list_for_each_entry(tmp_ueid, &smc_clc_eid_table.list, list) {
		if (!memcmp(tmp_ueid->eid, ueid, SMC_MAX_EID_LEN)) {
			rc = -EEXIST;
			goto err_out;
		}
	}
	list_add_tail(&new_ueid->list, &smc_clc_eid_table.list);
	smc_clc_eid_table.ueid_cnt++;
	write_unlock(&smc_clc_eid_table.lock);
	return 0;

err_out:
	write_unlock(&smc_clc_eid_table.lock);
	kfree(new_ueid);
	return rc;
}

int smc_nl_add_ueid(struct sk_buff *skb, struct genl_info *info)
{
	struct nlattr *nla_ueid = info->attrs[SMC_NLA_EID_TABLE_ENTRY];
	char *ueid;

	if (!nla_ueid || nla_len(nla_ueid) != SMC_MAX_EID_LEN + 1)
		return -EINVAL;
	ueid = (char *)nla_data(nla_ueid);

	return smc_clc_ueid_add(ueid);
}

/* remove one or all ueid entries from the table */
static int smc_clc_ueid_remove(char *ueid)
{
	struct smc_clc_eid_entry *lst_ueid, *tmp_ueid;
	int rc = -ENOENT;

	/* remove table entry */
	write_lock(&smc_clc_eid_table.lock);
	list_for_each_entry_safe(lst_ueid, tmp_ueid, &smc_clc_eid_table.list,
				 list) {
		if (!ueid || !memcmp(lst_ueid->eid, ueid, SMC_MAX_EID_LEN)) {
			list_del(&lst_ueid->list);
			smc_clc_eid_table.ueid_cnt--;
			kfree(lst_ueid);
			rc = 0;
		}
	}
	if (!rc && !smc_clc_eid_table.ueid_cnt) {
		smc_clc_eid_table.seid_enabled = 1;
		rc = -EAGAIN;	/* indicate success and enabling of seid */
	}
	write_unlock(&smc_clc_eid_table.lock);
	return rc;
}

int smc_nl_remove_ueid(struct sk_buff *skb, struct genl_info *info)
{
	struct nlattr *nla_ueid = info->attrs[SMC_NLA_EID_TABLE_ENTRY];
	char *ueid;

	if (!nla_ueid || nla_len(nla_ueid) != SMC_MAX_EID_LEN + 1)
		return -EINVAL;
	ueid = (char *)nla_data(nla_ueid);

	return smc_clc_ueid_remove(ueid);
}

int smc_nl_flush_ueid(struct sk_buff *skb, struct genl_info *info)
{
	smc_clc_ueid_remove(NULL);
	return 0;
}

static int smc_nl_ueid_dumpinfo(struct sk_buff *skb, u32 portid, u32 seq,
				u32 flags, char *ueid)
{
	char ueid_str[SMC_MAX_EID_LEN + 1];
	void *hdr;

	hdr = genlmsg_put(skb, portid, seq, &smc_gen_nl_family,
			  flags, SMC_NETLINK_DUMP_UEID);
	if (!hdr)
		return -ENOMEM;
	snprintf(ueid_str, sizeof(ueid_str), "%s", ueid);
	if (nla_put_string(skb, SMC_NLA_EID_TABLE_ENTRY, ueid_str)) {
		genlmsg_cancel(skb, hdr);
		return -EMSGSIZE;
	}
	genlmsg_end(skb, hdr);
	return 0;
}

static int _smc_nl_ueid_dump(struct sk_buff *skb, u32 portid, u32 seq,
			     int start_idx)
{
	struct smc_clc_eid_entry *lst_ueid;
	int idx = 0;

	read_lock(&smc_clc_eid_table.lock);
	list_for_each_entry(lst_ueid, &smc_clc_eid_table.list, list) {
		if (idx++ < start_idx)
			continue;
		if (smc_nl_ueid_dumpinfo(skb, portid, seq, NLM_F_MULTI,
					 lst_ueid->eid)) {
			--idx;
			break;
		}
	}
	read_unlock(&smc_clc_eid_table.lock);
	return idx;
}

int smc_nl_dump_ueid(struct sk_buff *skb, struct netlink_callback *cb)
{
	struct smc_nl_dmp_ctx *cb_ctx = smc_nl_dmp_ctx(cb);
	int idx;

	idx = _smc_nl_ueid_dump(skb, NETLINK_CB(cb->skb).portid,
				cb->nlh->nlmsg_seq, cb_ctx->pos[0]);

	cb_ctx->pos[0] = idx;
	return skb->len;
}

int smc_nl_dump_seid(struct sk_buff *skb, struct netlink_callback *cb)
{
	struct smc_nl_dmp_ctx *cb_ctx = smc_nl_dmp_ctx(cb);
	char seid_str[SMC_MAX_EID_LEN + 1];
	u8 seid_enabled;
	void *hdr;
	u8 *seid;

	if (cb_ctx->pos[0])
		return skb->len;

	hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
			  &smc_gen_nl_family, NLM_F_MULTI,
			  SMC_NETLINK_DUMP_SEID);
	if (!hdr)
		return -ENOMEM;
	if (!smc_ism_is_v2_capable())
		goto end;

	smc_ism_get_system_eid(&seid);
	snprintf(seid_str, sizeof(seid_str), "%s", seid);
	if (nla_put_string(skb, SMC_NLA_SEID_ENTRY, seid_str))
		goto err;
	read_lock(&smc_clc_eid_table.lock);
	seid_enabled = smc_clc_eid_table.seid_enabled;
	read_unlock(&smc_clc_eid_table.lock);
	if (nla_put_u8(skb, SMC_NLA_SEID_ENABLED, seid_enabled))
		goto err;
end:
	genlmsg_end(skb, hdr);
	cb_ctx->pos[0]++;
	return skb->len;
err:
	genlmsg_cancel(skb, hdr);
	return -EMSGSIZE;
}

int smc_nl_enable_seid(struct sk_buff *skb, struct genl_info *info)
{
	write_lock(&smc_clc_eid_table.lock);
	smc_clc_eid_table.seid_enabled = 1;
	write_unlock(&smc_clc_eid_table.lock);
	return 0;
}

int smc_nl_disable_seid(struct sk_buff *skb, struct genl_info *info)
{
	int rc = 0;

	write_lock(&smc_clc_eid_table.lock);
	if (!smc_clc_eid_table.ueid_cnt)
		rc = -ENOENT;
	else
		smc_clc_eid_table.seid_enabled = 0;
	write_unlock(&smc_clc_eid_table.lock);
	return rc;
}

static bool _smc_clc_match_ueid(u8 *peer_ueid)
{
	struct smc_clc_eid_entry *tmp_ueid;

	list_for_each_entry(tmp_ueid, &smc_clc_eid_table.list, list) {
		if (!memcmp(tmp_ueid->eid, peer_ueid, SMC_MAX_EID_LEN))
			return true;
	}
	return false;
}

bool smc_clc_match_eid(u8 *negotiated_eid,
		       struct smc_clc_v2_extension *smc_v2_ext,
		       u8 *peer_eid, u8 *local_eid)
{
	bool match = false;
	int i;

	negotiated_eid[0] = 0;
	read_lock(&smc_clc_eid_table.lock);
	if (smc_clc_eid_table.seid_enabled &&
	    smc_v2_ext->hdr.flag.seid &&
	    !memcmp(peer_eid, local_eid, SMC_MAX_EID_LEN)) {
		memcpy(negotiated_eid, peer_eid, SMC_MAX_EID_LEN);
		match = true;
		goto out;
	}

	for (i = 0; i < smc_v2_ext->hdr.eid_cnt; i++) {
		if (_smc_clc_match_ueid(smc_v2_ext->user_eids[i])) {
			memcpy(negotiated_eid, smc_v2_ext->user_eids[i],
			       SMC_MAX_EID_LEN);
			match = true;
			goto out;
		}
	}
out:
	read_unlock(&smc_clc_eid_table.lock);
	return match;
}

/* check arriving CLC proposal */
static bool smc_clc_msg_prop_valid(struct smc_clc_msg_proposal *pclc)
{
@@ -550,6 +830,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
	if (ini->smc_type_v2 == SMC_TYPE_N) {
		pclc_smcd->v2_ext_offset = 0;
	} else {
		struct smc_clc_eid_entry *ueident;
		u16 v2_ext_offset;
		u8 *eid = NULL;

@@ -560,19 +841,25 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
						pclc_prfx->ipv6_prefixes_cnt *
						sizeof(ipv6_prfx[0]);
		pclc_smcd->v2_ext_offset = htons(v2_ext_offset);
		v2_ext->hdr.eid_cnt = 0;

		read_lock(&smc_clc_eid_table.lock);
		v2_ext->hdr.eid_cnt = smc_clc_eid_table.ueid_cnt;
		plen += smc_clc_eid_table.ueid_cnt * SMC_MAX_EID_LEN;
		i = 0;
		list_for_each_entry(ueident, &smc_clc_eid_table.list, list) {
			memcpy(v2_ext->user_eids[i++], ueident->eid,
			       sizeof(ueident->eid));
		}
		v2_ext->hdr.flag.seid = smc_clc_eid_table.seid_enabled;
		read_unlock(&smc_clc_eid_table.lock);
		v2_ext->hdr.ism_gid_cnt = ini->ism_offered_cnt;
		v2_ext->hdr.flag.release = SMC_RELEASE;
		v2_ext->hdr.flag.seid = 1;
		v2_ext->hdr.smcd_v2_ext_offset = htons(sizeof(*v2_ext) -
				offsetofend(struct smc_clnt_opts_area_hdr,
					    smcd_v2_ext_offset) +
				v2_ext->hdr.eid_cnt * SMC_MAX_EID_LEN);
		if (ini->ism_dev[0])
			smc_ism_get_system_eid(ini->ism_dev[0], &eid);
		else
			smc_ism_get_system_eid(ini->ism_dev[1], &eid);
		if (eid)
		smc_ism_get_system_eid(&eid);
		if (eid && v2_ext->hdr.flag.seid)
			memcpy(smcd_v2_ext->system_eid, eid, SMC_MAX_EID_LEN);
		plen += sizeof(*v2_ext) + sizeof(*smcd_v2_ext);
		if (ini->ism_offered_cnt) {
@@ -607,7 +894,8 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
	}
	if (ini->smc_type_v2 != SMC_TYPE_N) {
		vec[i].iov_base = v2_ext;
		vec[i++].iov_len = sizeof(*v2_ext);
		vec[i++].iov_len = sizeof(*v2_ext) +
				   (v2_ext->hdr.eid_cnt * SMC_MAX_EID_LEN);
		vec[i].iov_base = smcd_v2_ext;
		vec[i++].iov_len = sizeof(*smcd_v2_ext);
		if (ini->ism_offered_cnt) {
@@ -635,7 +923,8 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
/* build and send CLC CONFIRM / ACCEPT message */
static int smc_clc_send_confirm_accept(struct smc_sock *smc,
				       struct smc_clc_msg_accept_confirm_v2 *clc_v2,
				       int first_contact, u8 version)
				       int first_contact, u8 version,
				       u8 *eid)
{
	struct smc_connection *conn = &smc->conn;
	struct smc_clc_msg_accept_confirm *clc;
@@ -663,11 +952,8 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc,
		if (version == SMC_V1) {
			clc->hdr.length = htons(SMCD_CLC_ACCEPT_CONFIRM_LEN);
		} else {
			u8 *eid = NULL;

			clc_v2->chid = htons(smc_ism_get_chid(conn->lgr->smcd));
			smc_ism_get_system_eid(conn->lgr->smcd, &eid);
			if (eid)
			if (eid[0])
				memcpy(clc_v2->eid, eid, SMC_MAX_EID_LEN);
			len = SMCD_CLC_ACCEPT_CONFIRM_LEN_V2;
			if (first_contact)
@@ -732,7 +1018,7 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc,

/* send CLC CONFIRM message across internal TCP socket */
int smc_clc_send_confirm(struct smc_sock *smc, bool clnt_first_contact,
			 u8 version)
			 u8 version, u8 *eid)
{
	struct smc_clc_msg_accept_confirm_v2 cclc_v2;
	int reason_code = 0;
@@ -742,7 +1028,7 @@ int smc_clc_send_confirm(struct smc_sock *smc, bool clnt_first_contact,
	memset(&cclc_v2, 0, sizeof(cclc_v2));
	cclc_v2.hdr.type = SMC_CLC_CONFIRM;
	len = smc_clc_send_confirm_accept(smc, &cclc_v2, clnt_first_contact,
					  version);
					  version, eid);
	if (len < ntohs(cclc_v2.hdr.length)) {
		if (len >= 0) {
			reason_code = -ENETUNREACH;
@@ -757,7 +1043,7 @@ int smc_clc_send_confirm(struct smc_sock *smc, bool clnt_first_contact,

/* send CLC ACCEPT message across internal TCP socket */
int smc_clc_send_accept(struct smc_sock *new_smc, bool srv_first_contact,
			u8 version)
			u8 version, u8 *negotiated_eid)
{
	struct smc_clc_msg_accept_confirm_v2 aclc_v2;
	int len;
@@ -765,7 +1051,7 @@ int smc_clc_send_accept(struct smc_sock *new_smc, bool srv_first_contact,
	memset(&aclc_v2, 0, sizeof(aclc_v2));
	aclc_v2.hdr.type = SMC_CLC_ACCEPT;
	len = smc_clc_send_confirm_accept(new_smc, &aclc_v2, srv_first_contact,
					  version);
					  version, negotiated_eid);
	if (len < ntohs(aclc_v2.hdr.length))
		len = len >= 0 ? -EPROTO : -new_smc->clcsock->sk->sk_err;

@@ -785,4 +1071,14 @@ void __init smc_clc_init(void)
	u = utsname();
	memcpy(smc_hostname, u->nodename,
	       min_t(size_t, strlen(u->nodename), sizeof(smc_hostname)));

	INIT_LIST_HEAD(&smc_clc_eid_table.list);
	rwlock_init(&smc_clc_eid_table.lock);
	smc_clc_eid_table.ueid_cnt = 0;
	smc_clc_eid_table.seid_enabled = 1;
}

void smc_clc_exit(void)
{
	smc_clc_ueid_remove(NULL);
}
+17 −2
Original line number Diff line number Diff line
@@ -14,8 +14,10 @@
#define _SMC_CLC_H

#include <rdma/ib_verbs.h>
#include <linux/smc.h>

#include "smc.h"
#include "smc_netlink.h"

#define SMC_CLC_PROPOSAL	0x01
#define SMC_CLC_ACCEPT		0x02
@@ -158,6 +160,7 @@ struct smc_clc_msg_proposal { /* clc proposal message sent by Linux */
} __aligned(4);

#define SMC_CLC_MAX_V6_PREFIX		8
#define SMC_CLC_MAX_UEID		8

struct smc_clc_msg_proposal_area {
	struct smc_clc_msg_proposal		pclc_base;
@@ -165,6 +168,7 @@ struct smc_clc_msg_proposal_area {
	struct smc_clc_msg_proposal_prefix	pclc_prfx;
	struct smc_clc_ipv6_prefix	pclc_prfx_ipv6[SMC_CLC_MAX_V6_PREFIX];
	struct smc_clc_v2_extension		pclc_v2_ext;
	u8			user_eids[SMC_CLC_MAX_UEID][SMC_MAX_EID_LEN];
	struct smc_clc_smcd_v2_extension	pclc_smcd_v2_ext;
	struct smc_clc_smcd_gid_chid		pclc_gidchids[SMC_MAX_ISM_DEVS];
	struct smc_clc_msg_trail		pclc_trl;
@@ -330,10 +334,21 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info, u8 version);
int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini);
int smc_clc_send_confirm(struct smc_sock *smc, bool clnt_first_contact,
			 u8 version);
			 u8 version, u8 *eid);
int smc_clc_send_accept(struct smc_sock *smc, bool srv_first_contact,
			u8 version);
			u8 version, u8 *negotiated_eid);
void smc_clc_init(void) __init;
void smc_clc_exit(void);
void smc_clc_get_hostname(u8 **host);
bool smc_clc_match_eid(u8 *negotiated_eid,
		       struct smc_clc_v2_extension *smc_v2_ext,
		       u8 *peer_eid, u8 *local_eid);
int smc_nl_dump_ueid(struct sk_buff *skb, struct netlink_callback *cb);
int smc_nl_add_ueid(struct sk_buff *skb, struct genl_info *info);
int smc_nl_remove_ueid(struct sk_buff *skb, struct genl_info *info);
int smc_nl_flush_ueid(struct sk_buff *skb, struct genl_info *info);
int smc_nl_dump_seid(struct sk_buff *skb, struct netlink_callback *cb);
int smc_nl_enable_seid(struct sk_buff *skb, struct genl_info *info);
int smc_nl_disable_seid(struct sk_buff *skb, struct genl_info *info);

#endif
Loading