lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1305290648-9613-8-git-send-email-sjur.brandeland@stericsson.com>
Date:	Fri, 13 May 2011 14:44:05 +0200
From:	Sjur Brændeland <sjur.brandeland@...ricsson.com>
To:	"David S. Miller" <davem@...emloft.net>, netdev@...r.kernel.org
Cc:	Sjur Brændeland <sjur.brandeland@...ricsson.com>
Subject: [net-next-2.6 07/10] caif: prepare support for namespaces

Use struct net to reference CAIF configuration object instead of static variables.
Refactor functions caif_connect_client, caif_disconnect_client and squach
files cfcnfg.c and caif_config_utils.

Signed-off-by: Sjur Brændeland <sjur.brandeland@...ricsson.com>
---
 include/net/caif/caif_dev.h |   24 ++-----
 include/net/caif/cfcnfg.h   |   71 +++------------------
 net/caif/Makefile           |    2 +-
 net/caif/caif_config_util.c |   99 -----------------------------
 net/caif/caif_dev.c         |   77 +++++++++++------------
 net/caif/caif_socket.c      |    6 +-
 net/caif/cfcnfg.c           |  146 ++++++++++++++++++++++++++++++++++---------
 net/caif/chnl_net.c         |   12 ++--
 8 files changed, 176 insertions(+), 261 deletions(-)
 delete mode 100644 net/caif/caif_config_util.c

diff --git a/include/net/caif/caif_dev.h b/include/net/caif/caif_dev.h
index 6638435..c011281 100644
--- a/include/net/caif/caif_dev.h
+++ b/include/net/caif/caif_dev.h
@@ -11,6 +11,7 @@
 #include <net/caif/cfcnfg.h>
 #include <linux/caif/caif_socket.h>
 #include <linux/if.h>
+#include <linux/net.h>
 
 /**
  * struct caif_param - CAIF parameters.
@@ -62,16 +63,18 @@ struct caif_connect_request {
  * E.g. CAIF Socket will call this function for each socket it connects
  * and have one client_layer instance for each socket.
  */
-int caif_connect_client(struct caif_connect_request *conn_req,
+int caif_connect_client(struct net *net,
+			struct caif_connect_request *conn_req,
 			struct cflayer *client_layer, int *ifindex,
 			int *headroom, int *tailroom);
 
 /**
  * caif_disconnect_client - Disconnects a client from the CAIF stack.
  *
- * @client_layer: Client layer to be removed.
+ * @client_layer: Client layer to be disconnected.
  */
-int caif_disconnect_client(struct cflayer *client_layer);
+int caif_disconnect_client(struct net *net, struct cflayer *client_layer);
+
 
 /**
  * caif_client_register_refcnt - register ref-count functions provided by client.
@@ -91,21 +94,6 @@ void caif_client_register_refcnt(struct cflayer *adapt_layer,
 					void (*hold)(struct cflayer *lyr),
 					void (*put)(struct cflayer *lyr));
 /**
- * caif_connect_req_to_link_param - Translate configuration parameters
- *				    from socket format to internal format.
- * @cnfg:	Pointer to configuration handler
- * @con_req:	Configuration parameters supplied in function
- *		caif_connect_client
- * @channel_setup_param: Parameters supplied to the CAIF Core stack for
- *			 setting up channels.
- *
- */
-
-int caif_connect_req_to_link_param(struct cfcnfg *cnfg,
-				   struct caif_connect_request *con_req,
-				   struct cfctrl_link_param *setup_param);
-
-/**
  * caif_free_client - Free memory used to manage the client in the CAIF Stack.
  *
  * @client_layer: Client layer to be removed.
diff --git a/include/net/caif/cfcnfg.h b/include/net/caif/cfcnfg.h
index e0a1eb5..3e93a4a 100644
--- a/include/net/caif/cfcnfg.h
+++ b/include/net/caif/cfcnfg.h
@@ -46,6 +46,12 @@ enum cfcnfg_phy_preference {
 };
 
 /**
+ * cfcnfg_create() - Get the CAIF configuration object given network.
+ * @net:	Network for the CAIF configuration object.
+ */
+struct cfcnfg *get_cfcnfg(struct net *net);
+
+/**
  * cfcnfg_create() - Create the CAIF configuration object.
  */
 struct cfcnfg *cfcnfg_create(void);
@@ -65,17 +71,15 @@ void cfcnfg_remove(struct cfcnfg *cfg);
  * @dev:	Pointer to link layer device
  * @phy_layer:	Specify the physical layer. The transmit function
  *		MUST be set in the structure.
- * @phyid:	The assigned physical ID for this layer, used in
- *		cfcnfg_add_adapt_layer to specify PHY for the link.
  * @pref:	The phy (link layer) preference.
  * @fcs:	Specify if checksum is used in CAIF Framing Layer.
- * @stx:	Specify if Start Of Frame extension is used.
+ * @stx:	Specify if Start Of Frame eXtention is used.
  */
 
 void
 cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type,
 		     struct net_device *dev, struct cflayer *phy_layer,
-		     u16 *phyid, enum cfcnfg_phy_preference pref,
+		     enum cfcnfg_phy_preference pref,
 		     bool fcs, bool stx);
 
 /**
@@ -88,65 +92,6 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type,
 int cfcnfg_del_phy_layer(struct cfcnfg *cnfg, struct cflayer *phy_layer);
 
 /**
- * cfcnfg_disconn_adapt_layer - Disconnects an adaptation layer.
- *
- * @cnfg:	Pointer to a CAIF configuration object, created by
- *		cfcnfg_create().
- * @adap_layer: Adaptation layer to be removed.
- */
-int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg,
-			struct cflayer *adap_layer);
-
-/**
- * cfcnfg_release_adap_layer - Used by client to release the adaptation layer.
- *
- * @adap_layer: Adaptation layer.
- */
-void cfcnfg_release_adap_layer(struct cflayer *adap_layer);
-
-/**
- * cfcnfg_add_adaptation_layer - Add an adaptation layer to the CAIF stack.
- *
- * The adaptation Layer is where the interface to application or higher-level
- * driver functionality is implemented.
- *
- * @cnfg:		Pointer to a CAIF configuration object, created by
- *			cfcnfg_create().
- * @param:		Link setup parameters.
- * @adap_layer:		Specify the adaptation layer; the receive and
- *			flow-control functions MUST be set in the structure.
- * @ifindex:		Link layer interface index used for this connection.
- * @proto_head:		Protocol head-space needed by CAIF protocol,
- *			excluding link layer.
- * @proto_tail:		Protocol tail-space needed by CAIF protocol,
- *			excluding link layer.
- */
-int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg,
-			    struct cfctrl_link_param *param,
-			    struct cflayer *adap_layer,
-			    int *ifindex,
-			    int *proto_head,
-			    int *proto_tail);
-
-/**
- * cfcnfg_get_phyid() - Get physical ID, given type.
- * Returns one of the physical interfaces matching the given type.
- * Zero if no match is found.
- * @cnfg:	Configuration object
- * @phy_pref:	Caif Link Layer preference
- */
-struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg,
-		     enum cfcnfg_phy_preference phy_pref);
-
-/**
- * cfcnfg_get_id_from_ifi() - Get the Physical Identifier of ifindex,
- * 			it matches caif physical id with the kernel interface id.
- * @cnfg:	Configuration object
- * @ifi:	ifindex obtained from socket.c bindtodevice.
- */
-int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi);
-
-/**
  * cfcnfg_set_phy_state() - Set the state of the physical interface device.
  * @cnfg:	Configuration object
  * @phy_layer:	Physical Layer representation
diff --git a/net/caif/Makefile b/net/caif/Makefile
index 9d38e40..ebcd4e7 100644
--- a/net/caif/Makefile
+++ b/net/caif/Makefile
@@ -5,7 +5,7 @@ caif-y := caif_dev.o \
 	cffrml.o cfveil.o cfdbgl.o\
 	cfserl.o cfdgml.o  \
 	cfrfml.o cfvidl.o cfutill.o \
-	cfsrvl.o cfpkt_skbuff.o caif_config_util.o
+	cfsrvl.o cfpkt_skbuff.o
 
 obj-$(CONFIG_CAIF) += caif.o
 obj-$(CONFIG_CAIF_NETDEV) += chnl_net.o
diff --git a/net/caif/caif_config_util.c b/net/caif/caif_config_util.c
deleted file mode 100644
index 9b63e4e..0000000
--- a/net/caif/caif_config_util.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author:	Sjur Brendeland sjur.brandeland@...ricsson.com
- * License terms: GNU General Public License (GPL) version 2
- */
-
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <net/caif/cfctrl.h>
-#include <net/caif/cfcnfg.h>
-#include <net/caif/caif_dev.h>
-
-int caif_connect_req_to_link_param(struct cfcnfg *cnfg,
-				   struct caif_connect_request *s,
-				   struct cfctrl_link_param *l)
-{
-	struct dev_info *dev_info;
-	enum cfcnfg_phy_preference pref;
-	int res;
-
-	memset(l, 0, sizeof(*l));
-	/* In caif protocol low value is high priority */
-	l->priority = CAIF_PRIO_MAX - s->priority + 1;
-
-	if (s->ifindex != 0){
-		res = cfcnfg_get_id_from_ifi(cnfg, s->ifindex);
-		if (res < 0)
-			return res;
-		l->phyid = res;
-	}
-	else {
-		switch (s->link_selector) {
-		case CAIF_LINK_HIGH_BANDW:
-			pref = CFPHYPREF_HIGH_BW;
-			break;
-		case CAIF_LINK_LOW_LATENCY:
-			pref = CFPHYPREF_LOW_LAT;
-			break;
-		default:
-			return -EINVAL;
-		}
-		dev_info = cfcnfg_get_phyid(cnfg, pref);
-		if (dev_info == NULL)
-			return -ENODEV;
-		l->phyid = dev_info->id;
-	}
-	switch (s->protocol) {
-	case CAIFPROTO_AT:
-		l->linktype = CFCTRL_SRV_VEI;
-		if (s->sockaddr.u.at.type == CAIF_ATTYPE_PLAIN)
-			l->chtype = 0x02;
-		else
-			l->chtype = s->sockaddr.u.at.type;
-		l->endpoint = 0x00;
-		break;
-	case CAIFPROTO_DATAGRAM:
-		l->linktype = CFCTRL_SRV_DATAGRAM;
-		l->chtype = 0x00;
-		l->u.datagram.connid = s->sockaddr.u.dgm.connection_id;
-		break;
-	case CAIFPROTO_DATAGRAM_LOOP:
-		l->linktype = CFCTRL_SRV_DATAGRAM;
-		l->chtype = 0x03;
-		l->endpoint = 0x00;
-		l->u.datagram.connid = s->sockaddr.u.dgm.connection_id;
-		break;
-	case CAIFPROTO_RFM:
-		l->linktype = CFCTRL_SRV_RFM;
-		l->u.datagram.connid = s->sockaddr.u.rfm.connection_id;
-		strncpy(l->u.rfm.volume, s->sockaddr.u.rfm.volume,
-			sizeof(l->u.rfm.volume)-1);
-		l->u.rfm.volume[sizeof(l->u.rfm.volume)-1] = 0;
-		break;
-	case CAIFPROTO_UTIL:
-		l->linktype = CFCTRL_SRV_UTIL;
-		l->endpoint = 0x00;
-		l->chtype = 0x00;
-		strncpy(l->u.utility.name, s->sockaddr.u.util.service,
-			sizeof(l->u.utility.name)-1);
-		l->u.utility.name[sizeof(l->u.utility.name)-1] = 0;
-		caif_assert(sizeof(l->u.utility.name) > 10);
-		l->u.utility.paramlen = s->param.size;
-		if (l->u.utility.paramlen > sizeof(l->u.utility.params))
-			l->u.utility.paramlen = sizeof(l->u.utility.params);
-
-		memcpy(l->u.utility.params, s->param.data,
-		       l->u.utility.paramlen);
-
-		break;
-	case CAIFPROTO_DEBUG:
-		l->linktype = CFCTRL_SRV_DBG;
-		l->endpoint = s->sockaddr.u.dbg.service;
-		l->chtype = s->sockaddr.u.dbg.type;
-		break;
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c
index 6d1d86b..0e651cf 100644
--- a/net/caif/caif_dev.c
+++ b/net/caif/caif_dev.c
@@ -21,7 +21,6 @@
 #include <net/net_namespace.h>
 #include <net/pkt_sched.h>
 #include <net/caif/caif_device.h>
-#include <net/caif/caif_dev.h>
 #include <net/caif/caif_layer.h>
 #include <net/caif/cfpkt.h>
 #include <net/caif/cfcnfg.h>
@@ -43,11 +42,21 @@ struct caif_device_entry_list {
 };
 
 struct caif_net {
+	struct cfcnfg *cfg;
 	struct caif_device_entry_list caifdevs;
 };
 
 static int caif_net_id;
-static struct cfcnfg *cfg;
+
+struct cfcnfg *get_cfcnfg(struct net *net)
+{
+	struct caif_net *caifn;
+	BUG_ON(!net);
+	caifn = net_generic(net, caif_net_id);
+	BUG_ON(!caifn);
+	return caifn->cfg;
+}
+EXPORT_SYMBOL(get_cfcnfg);
 
 static struct caif_device_entry_list *caif_device_list(struct net *net)
 {
@@ -191,12 +200,17 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what,
 	struct caif_dev_common *caifdev;
 	enum cfcnfg_phy_preference pref;
 	enum cfcnfg_phy_type phy_type;
+	struct cfcnfg *cfg;
 	struct caif_device_entry_list *caifdevs =
 	    caif_device_list(dev_net(dev));
 
 	if (dev->type != ARPHRD_CAIF)
 		return 0;
 
+	cfg = get_cfcnfg(dev_net(dev));
+	if (cfg == NULL)
+		return 0;
+
 	switch (what) {
 	case NETDEV_REGISTER:
 		caifd = caif_device_alloc(dev);
@@ -235,7 +249,6 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what,
 				     phy_type,
 				     dev,
 				     &caifd->layer,
-				     0,
 				     pref,
 				     caifdev->use_fcs,
 				     caifdev->use_stx);
@@ -323,35 +336,20 @@ static struct notifier_block caif_device_notifier = {
 	.priority = 0,
 };
 
-int caif_connect_client(struct caif_connect_request *conn_req,
-		       struct cflayer *client_layer, int *ifindex,
-		       int *headroom, int *tailroom)
-{
-	struct cfctrl_link_param param;
-	int ret;
-
-	ret = caif_connect_req_to_link_param(cfg, conn_req, &param);
-	if (ret)
-		return ret;
-	/* Hook up the adaptation layer. */
-	return cfcnfg_add_adaptation_layer(cfg, &param,
-				       client_layer, ifindex,
-				       headroom, tailroom);
-}
-EXPORT_SYMBOL(caif_connect_client);
-
-int caif_disconnect_client(struct cflayer *adap_layer)
-{
-	return cfcnfg_disconn_adapt_layer(cfg, adap_layer);
-}
-EXPORT_SYMBOL(caif_disconnect_client);
-
 /* Per-namespace Caif devices handling */
 static int caif_init_net(struct net *net)
 {
 	struct caif_net *caifn = net_generic(net, caif_net_id);
+	BUG_ON(!caifn);
 	INIT_LIST_HEAD(&caifn->caifdevs.list);
 	mutex_init(&caifn->caifdevs.lock);
+
+	caifn->cfg = cfcnfg_create();
+	if (!caifn->cfg) {
+		pr_warn("can't create cfcnfg\n");
+		return -ENOMEM;
+	}
+
 	return 0;
 }
 
@@ -360,10 +358,17 @@ static void caif_exit_net(struct net *net)
 	struct caif_device_entry *caifd, *tmp;
 	struct caif_device_entry_list *caifdevs =
 	    caif_device_list(net);
+	struct cfcnfg *cfg;
 
 	rtnl_lock();
 	mutex_lock(&caifdevs->lock);
 
+	cfg = get_cfcnfg(net);
+	if (cfg == NULL) {
+		mutex_unlock(&caifdevs->lock);
+		return;
+	}
+
 	list_for_each_entry_safe(caifd, tmp, &caifdevs->list, list) {
 		int i = 0;
 		list_del_rcu(&caifd->list);
@@ -382,7 +387,7 @@ static void caif_exit_net(struct net *net)
 		free_percpu(caifd->pcpu_refcnt);
 		kfree(caifd);
 	}
-
+	cfcnfg_remove(cfg);
 
 	mutex_unlock(&caifdevs->lock);
 	rtnl_unlock();
@@ -400,32 +405,22 @@ static int __init caif_device_init(void)
 {
 	int result;
 
-	cfg = cfcnfg_create();
-	if (!cfg) {
-		pr_warn("can't create cfcnfg\n");
-		goto err_cfcnfg_create_failed;
-	}
 	result = register_pernet_device(&caif_net_ops);
 
-	if (result) {
-		kfree(cfg);
-		cfg = NULL;
+	if (result)
 		return result;
-	}
-	dev_add_pack(&caif_packet_type);
+
 	register_netdevice_notifier(&caif_device_notifier);
+	dev_add_pack(&caif_packet_type);
 
 	return result;
-err_cfcnfg_create_failed:
-	return -ENODEV;
 }
 
 static void __exit caif_device_exit(void)
 {
-	dev_remove_pack(&caif_packet_type);
 	unregister_pernet_device(&caif_net_ops);
 	unregister_netdevice_notifier(&caif_device_notifier);
-	cfcnfg_remove(cfg);
+	dev_remove_pack(&caif_packet_type);
 }
 
 module_init(caif_device_init);
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
index 01f612d..653db75 100644
--- a/net/caif/caif_socket.c
+++ b/net/caif/caif_socket.c
@@ -810,7 +810,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
 				sk->sk_state == CAIF_DISCONNECTED);
 		if (sk->sk_shutdown & SHUTDOWN_MASK) {
 			/* Allow re-connect after SHUTDOWN_IND */
-			caif_disconnect_client(&cf_sk->layer);
+			caif_disconnect_client(sock_net(sk), &cf_sk->layer);
 			break;
 		}
 		/* No reconnect on a seqpacket socket */
@@ -851,7 +851,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
 	dbfs_atomic_inc(&cnt.num_connect_req);
 	cf_sk->layer.receive = caif_sktrecv_cb;
 
-	err = caif_connect_client(&cf_sk->conn_req,
+	err = caif_connect_client(sock_net(sk), &cf_sk->conn_req,
 				&cf_sk->layer, &ifindex, &headroom, &tailroom);
 
 	if (err < 0) {
@@ -949,7 +949,7 @@ static int caif_release(struct socket *sock)
 
 	if (cf_sk->sk.sk_socket->state == SS_CONNECTED ||
 		cf_sk->sk.sk_socket->state == SS_CONNECTING)
-		res = caif_disconnect_client(&cf_sk->layer);
+		res = caif_disconnect_client(sock_net(sk), &cf_sk->layer);
 
 	cf_sk->sk.sk_socket->state = SS_DISCONNECTING;
 	wake_up_interruptible_poll(sk_sleep(sk), POLLERR|POLLHUP);
diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c
index 3f4f31f..e857d89 100644
--- a/net/caif/cfcnfg.c
+++ b/net/caif/cfcnfg.c
@@ -150,7 +150,7 @@ static void cfctrl_enum_resp(void)
 {
 }
 
-struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg,
+static struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg,
 				  enum cfcnfg_phy_preference phy_pref)
 {
 	/* Try to match with specified preference */
@@ -171,7 +171,7 @@ struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg,
 	return NULL;
 }
 
-int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi)
+static int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi)
 {
 	struct cfcnfg_phyinfo *phy;
 
@@ -181,11 +181,12 @@ int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi)
 	return -ENODEV;
 }
 
-int cfcnfg_disconn_adapt_layer(struct cfcnfg *cfg, struct cflayer *adap_layer)
+int caif_disconnect_client(struct net *net, struct cflayer *adap_layer)
 {
 	u8 channel_id = 0;
 	int ret = 0;
 	struct cflayer *servl = NULL;
+	struct cfcnfg *cfg = get_cfcnfg(net);
 
 	caif_assert(adap_layer != NULL);
 
@@ -217,14 +218,7 @@ end:
 	return ret;
 
 }
-EXPORT_SYMBOL(cfcnfg_disconn_adapt_layer);
-
-void cfcnfg_release_adap_layer(struct cflayer *adap_layer)
-{
-	if (adap_layer->dn)
-		cfsrvl_put(adap_layer->dn);
-}
-EXPORT_SYMBOL(cfcnfg_release_adap_layer);
+EXPORT_SYMBOL(caif_disconnect_client);
 
 static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id)
 {
@@ -238,19 +232,109 @@ static const int protohead[CFCTRL_SRV_MASK] = {
 	[CFCTRL_SRV_DBG] = 3,
 };
 
-int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg,
-				struct cfctrl_link_param *param,
-				struct cflayer *adap_layer,
-				int *ifindex,
+
+static int caif_connect_req_to_link_param(struct cfcnfg *cnfg,
+				   struct caif_connect_request *s,
+				   struct cfctrl_link_param *l)
+{
+	struct dev_info *dev_info;
+	enum cfcnfg_phy_preference pref;
+	int res;
+
+	memset(l, 0, sizeof(*l));
+	/* In caif protocol low value is high priority */
+	l->priority = CAIF_PRIO_MAX - s->priority + 1;
+
+	if (s->ifindex != 0) {
+		res = cfcnfg_get_id_from_ifi(cnfg, s->ifindex);
+		if (res < 0)
+			return res;
+		l->phyid = res;
+	} else {
+		switch (s->link_selector) {
+		case CAIF_LINK_HIGH_BANDW:
+			pref = CFPHYPREF_HIGH_BW;
+			break;
+		case CAIF_LINK_LOW_LATENCY:
+			pref = CFPHYPREF_LOW_LAT;
+			break;
+		default:
+			return -EINVAL;
+		}
+		dev_info = cfcnfg_get_phyid(cnfg, pref);
+		if (dev_info == NULL)
+			return -ENODEV;
+		l->phyid = dev_info->id;
+	}
+	switch (s->protocol) {
+	case CAIFPROTO_AT:
+		l->linktype = CFCTRL_SRV_VEI;
+		l->endpoint = (s->sockaddr.u.at.type >> 2) & 0x3;
+		l->chtype = s->sockaddr.u.at.type & 0x3;
+		break;
+	case CAIFPROTO_DATAGRAM:
+		l->linktype = CFCTRL_SRV_DATAGRAM;
+		l->chtype = 0x00;
+		l->u.datagram.connid = s->sockaddr.u.dgm.connection_id;
+		break;
+	case CAIFPROTO_DATAGRAM_LOOP:
+		l->linktype = CFCTRL_SRV_DATAGRAM;
+		l->chtype = 0x03;
+		l->endpoint = 0x00;
+		l->u.datagram.connid = s->sockaddr.u.dgm.connection_id;
+		break;
+	case CAIFPROTO_RFM:
+		l->linktype = CFCTRL_SRV_RFM;
+		l->u.datagram.connid = s->sockaddr.u.rfm.connection_id;
+		strncpy(l->u.rfm.volume, s->sockaddr.u.rfm.volume,
+			sizeof(l->u.rfm.volume)-1);
+		l->u.rfm.volume[sizeof(l->u.rfm.volume)-1] = 0;
+		break;
+	case CAIFPROTO_UTIL:
+		l->linktype = CFCTRL_SRV_UTIL;
+		l->endpoint = 0x00;
+		l->chtype = 0x00;
+		strncpy(l->u.utility.name, s->sockaddr.u.util.service,
+			sizeof(l->u.utility.name)-1);
+		l->u.utility.name[sizeof(l->u.utility.name)-1] = 0;
+		caif_assert(sizeof(l->u.utility.name) > 10);
+		l->u.utility.paramlen = s->param.size;
+		if (l->u.utility.paramlen > sizeof(l->u.utility.params))
+			l->u.utility.paramlen = sizeof(l->u.utility.params);
+
+		memcpy(l->u.utility.params, s->param.data,
+		       l->u.utility.paramlen);
+
+		break;
+	case CAIFPROTO_DEBUG:
+		l->linktype = CFCTRL_SRV_DBG;
+		l->endpoint = s->sockaddr.u.dbg.service;
+		l->chtype = s->sockaddr.u.dbg.type;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+int caif_connect_client(struct net *net, struct caif_connect_request *conn_req,
+			struct cflayer *adap_layer, int *ifindex,
 				int *proto_head,
 				int *proto_tail)
 {
 	struct cflayer *frml;
 	struct cfcnfg_phyinfo *phy;
 	int err;
+	struct cfctrl_link_param param;
+	struct cfcnfg *cfg = get_cfcnfg(net);
+	caif_assert(cfg != NULL);
 
 	rcu_read_lock();
-	phy = cfcnfg_get_phyinfo_rcu(cnfg, param->phyid);
+	err = caif_connect_req_to_link_param(cfg, conn_req, &param);
+	if (err)
+		goto unlock;
+
+	phy = cfcnfg_get_phyinfo_rcu(cfg, param.phyid);
 	if (!phy) {
 		err = -ENODEV;
 		goto unlock;
@@ -276,28 +360,29 @@ int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg,
 		pr_err("Specified PHY type does not exist!\n");
 		goto unlock;
 	}
-	caif_assert(param->phyid == phy->id);
+	caif_assert(param.phyid == phy->id);
 	caif_assert(phy->frm_layer->id ==
-		     param->phyid);
+		     param.phyid);
 	caif_assert(phy->phy_layer->id ==
-		     param->phyid);
+		     param.phyid);
 
 	*ifindex = phy->ifindex;
 	*proto_tail = 2;
 	*proto_head =
-		protohead[param->linktype] + (phy->use_stx ? 1 : 0);
+
+	protohead[param.linktype] + (phy->use_stx ? 1 : 0);
 
 	rcu_read_unlock();
 
 	/* FIXME: ENUMERATE INITIALLY WHEN ACTIVATING PHYSICAL INTERFACE */
-	cfctrl_enum_req(cnfg->ctrl, param->phyid);
-	return cfctrl_linkup_request(cnfg->ctrl, param, adap_layer);
+	cfctrl_enum_req(cfg->ctrl, param.phyid);
+	return cfctrl_linkup_request(cfg->ctrl, &param, adap_layer);
 
 unlock:
 	rcu_read_unlock();
 	return err;
 }
-EXPORT_SYMBOL(cfcnfg_add_adaptation_layer);
+EXPORT_SYMBOL(caif_connect_client);
 
 static void cfcnfg_reject_rsp(struct cflayer *layer, u8 channel_id,
 			     struct cflayer *adapt_layer)
@@ -389,7 +474,7 @@ unlock:
 void
 cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type,
 		     struct net_device *dev, struct cflayer *phy_layer,
-		     u16 *phy_id, enum cfcnfg_phy_preference pref,
+		     enum cfcnfg_phy_preference pref,
 		     bool fcs, bool stx)
 {
 	struct cflayer *frml;
@@ -512,23 +597,26 @@ int cfcnfg_del_phy_layer(struct cfcnfg *cnfg, struct cflayer *phy_layer)
 	phyid = phy_layer->id;
 	phyinfo = cfcnfg_get_phyinfo_rcu(cnfg, phyid);
 
-	if (phyinfo == NULL)
+	if (phyinfo == NULL) {
+		mutex_unlock(&cnfg->lock);
 		return 0;
+	}
 	caif_assert(phyid == phyinfo->id);
 	caif_assert(phy_layer == phyinfo->phy_layer);
 	caif_assert(phy_layer->id == phyid);
 	caif_assert(phyinfo->frm_layer->id == phyid);
 
+	list_del_rcu(&phyinfo->node);
+	synchronize_rcu();
+
 	/* Fail if reference count is not zero */
 	if (cffrml_refcnt_read(phyinfo->frm_layer) != 0) {
 		pr_info("Wait for device inuse\n");
+		list_add_rcu(&phyinfo->node, &cnfg->phys);
 		mutex_unlock(&cnfg->lock);
 		return -EAGAIN;
 	}
 
-	list_del_rcu(&phyinfo->node);
-	synchronize_rcu();
-
 	frml = phyinfo->frm_layer;
 	frml_dn = frml->dn;
 	cffrml_set_uplayer(frml, NULL);
@@ -539,8 +627,6 @@ int cfcnfg_del_phy_layer(struct cfcnfg *cnfg, struct cflayer *phy_layer)
 	}
 	layer_set_up(phy_layer, NULL);
 
-
-
 	if (phyinfo->phy_layer != frml_dn)
 		kfree(frml_dn);
 
diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c
index 9ef8f16..1a3398a 100644
--- a/net/caif/chnl_net.c
+++ b/net/caif/chnl_net.c
@@ -20,7 +20,6 @@
 #include <linux/caif/if_caif.h>
 #include <net/rtnetlink.h>
 #include <net/caif/caif_layer.h>
-#include <net/caif/cfcnfg.h>
 #include <net/caif/cfpkt.h>
 #include <net/caif/caif_dev.h>
 
@@ -270,8 +269,9 @@ static int chnl_net_open(struct net_device *dev)
 
 	if (priv->state != CAIF_CONNECTING) {
 		priv->state = CAIF_CONNECTING;
-		result = caif_connect_client(&priv->conn_req, &priv->chnl,
-					&llifindex, &headroom, &tailroom);
+		result = caif_connect_client(dev_net(dev), &priv->conn_req,
+						&priv->chnl, &llifindex,
+						&headroom, &tailroom);
 		if (result != 0) {
 				pr_debug("err: "
 					 "Unable to register and open device,"
@@ -327,7 +327,7 @@ static int chnl_net_open(struct net_device *dev)
 
 	if (result == 0) {
 		pr_debug("connect timeout\n");
-		caif_disconnect_client(&priv->chnl);
+		caif_disconnect_client(dev_net(dev), &priv->chnl);
 		priv->state = CAIF_DISCONNECTED;
 		pr_debug("state disconnected\n");
 		result = -ETIMEDOUT;
@@ -343,7 +343,7 @@ static int chnl_net_open(struct net_device *dev)
 	return 0;
 
 error:
-	caif_disconnect_client(&priv->chnl);
+	caif_disconnect_client(dev_net(dev), &priv->chnl);
 	priv->state = CAIF_DISCONNECTED;
 	pr_debug("state disconnected\n");
 	return result;
@@ -357,7 +357,7 @@ static int chnl_net_stop(struct net_device *dev)
 	ASSERT_RTNL();
 	priv = netdev_priv(dev);
 	priv->state = CAIF_DISCONNECTED;
-	caif_disconnect_client(&priv->chnl);
+	caif_disconnect_client(dev_net(dev), &priv->chnl);
 	return 0;
 }
 
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ