[svn-commits] fjoe: freebsd/trunk r7803 - in /freebsd/trunk: drivers/dahdi/ freebsd/ freebs...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Sat Jan 9 17:25:37 CST 2010


Author: fjoe
Date: Sat Jan  9 17:25:33 2010
New Revision: 7803

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=7803
Log:
- Add dahdi netgraph module that emulates Linux network devices.
- dahdi_dynamic_eth port.

Added:
    freebsd/trunk/freebsd/ng_dahdi_netdev/
    freebsd/trunk/freebsd/ng_dahdi_netdev/Makefile   (with props)
    freebsd/trunk/freebsd/ng_dahdi_netdev/ng_dahdi_netdev.c   (with props)
    freebsd/trunk/freebsd/ng_dahdi_netdev/ng_dahdi_netdev.h   (with props)
Modified:
    freebsd/trunk/drivers/dahdi/dahdi_dynamic_eth.c
    freebsd/trunk/freebsd/Makefile

Modified: freebsd/trunk/drivers/dahdi/dahdi_dynamic_eth.c
URL: http://svnview.digium.com/svn/dahdi/freebsd/trunk/drivers/dahdi/dahdi_dynamic_eth.c?view=diff&rev=7803&r1=7802&r2=7803
==============================================================================
--- freebsd/trunk/drivers/dahdi/dahdi_dynamic_eth.c (original)
+++ freebsd/trunk/drivers/dahdi/dahdi_dynamic_eth.c Sat Jan  9 17:25:33 2010
@@ -22,6 +22,48 @@
  * this program for more details.
  */
 
+#if defined(__FreeBSD__)
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/module.h>
+
+#include <machine/stdarg.h>
+
+#include "ng_dahdi_netdev.h"
+
+#define ETH_ALEN ETHER_ADDR_LEN
+#define LINUX_VERSION_CODE -1
+
+#define try_module_get(m)	(1)
+#define module_put(m)
+
+#if _BYTE_ORDER == _LITTLE_ENDIAN
+#define __constant_htons(x)	((uint16_t) (((uint16_t) (x)) << 8 | ((uint16_t) (x)) >> 8))
+#else
+#define __constant_htons(x)	(x)
+#endif
+
+#if 0
+static void
+rlprintf(int pps, const char *fmt, ...)
+	__printflike(2, 3);
+
+static void
+rlprintf(int pps, const char *fmt, ...)
+{
+	va_list ap;
+	static struct timeval last_printf;
+	static int count;
+
+	if (ppsratecheck(&last_printf, &count, pps)) {
+		va_start(ap, fmt);
+		vprintf(fmt, ap);
+		va_end(ap);
+	}
+}
+#endif
+#else /* !__FreeBSD__ */
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/module.h>
@@ -31,6 +73,7 @@
 #include <linux/kmod.h>
 #include <linux/netdevice.h>
 #include <linux/notifier.h>
+#endif /* !__FreeBSD__ */
 
 #include <dahdi/kernel.h>
 
@@ -48,7 +91,9 @@
 static spinlock_t zlock = SPIN_LOCK_UNLOCKED;
 #endif
 
+#if !defined(__FreeBSD__)
 static struct sk_buff_head skbs;
+#endif
 
 static struct ztdeth {
 	unsigned char addr[ETH_ALEN];
@@ -78,6 +123,24 @@
 	return span;
 }
 
+#if defined(__FreeBSD__)
+static int ztdeth_rcv(struct net_device *dev, struct ether_header *eh,
+		      unsigned char *msg, int msglen)
+{
+	struct dahdi_span *span;
+	struct ztdeth_header *zh = (struct ztdeth_header *) msg;
+
+	if (msglen < sizeof(*zh))
+		return 0;
+	span = ztdeth_getspan(eh->ether_shost, zh->subaddr);
+	if (span) {
+		dahdi_dynamic_receive(span,
+		    msg + sizeof(*zh), msglen - sizeof(*zh));
+	}
+
+	return 0;
+}
+#else /* !__FreeBSD__ */
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
 static int ztdeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
 #else
@@ -108,6 +171,7 @@
 	kfree_skb(skb);
 	return 0;
 }
+#endif /* !__FreeBSD__ */
 
 static int ztdeth_notifier(struct notifier_block *block, unsigned long event, void *ptr)
 {
@@ -145,21 +209,53 @@
 static int ztdeth_transmit(void *pvt, unsigned char *msg, int msglen)
 {
 	struct ztdeth *z;
+#if defined(__FreeBSD__)
+	struct mbuf *m;
+	struct ether_header eh;
+	struct ztdeth_header zh;
+#else
 	struct sk_buff *skb;
 	struct ztdeth_header *zh;
+	unsigned char addr[ETH_ALEN];
+	unsigned short subaddr; /* Network byte order */
+#endif /* !__FreeBSD__ */
 	unsigned long flags;
 	struct net_device *dev;
-	unsigned char addr[ETH_ALEN];
-	unsigned short subaddr; /* Network byte order */
 
 	spin_lock_irqsave(&zlock, flags);
 	z = pvt;
 	if (z->dev) {
 		/* Copy fields to local variables to remove spinlock ASAP */
-		dev = z->dev;
+#if defined(__FreeBSD__)
+		bcopy(z->addr, &eh.ether_dhost, sizeof(eh.ether_dhost));
+		zh.subaddr = z->subaddr;
+#else
 		memcpy(addr, z->addr, sizeof(z->addr));
 		subaddr = z->subaddr;
+#endif
+		dev = z->dev;
 		spin_unlock_irqrestore(&zlock, flags);
+#if defined(__FreeBSD__)
+		MGETHDR(m, M_DONTWAIT, MT_DATA);
+		if (m != NULL) {
+			if (sizeof(eh) + sizeof(zh) + msglen >= MINCLSIZE) {
+				MCLGET(m, M_DONTWAIT);
+			}
+
+			/* copy ethernet header */
+			bcopy(dev->dev_addr, &eh.ether_shost, sizeof(eh.ether_shost));
+			eh.ether_type = __constant_htons(ETH_P_DAHDI_DETH);
+			m_copyback(m, 0, sizeof(eh), (caddr_t) &eh);
+			m->m_pkthdr.len = m->m_len = sizeof(eh);
+
+			/* append ztdeth header and message */
+			m_append(m, sizeof(zh), (caddr_t) &zh);
+			m_append(m, msglen, msg);
+
+			/* send raw ethernet frame */
+			dev_xmit(dev, m);
+		}
+#else /* !__FreeBSD__ */
 		skb = dev_alloc_skb(msglen + dev->hard_header_len + sizeof(struct ztdeth_header) + 32);
 		if (skb) {
 			/* Reserve header space */
@@ -188,6 +284,7 @@
 #endif
 			skb_queue_tail(&skbs, skb);
 		}
+#endif /* !__FreeBSD__ */
 	}
 	else
 		spin_unlock_irqrestore(&zlock, flags);
@@ -197,12 +294,14 @@
 
 static int ztdeth_flush(void)
 {
+#if !defined(__FreeBSD__)
 	struct sk_buff *skb;
 
 	/* Handle all transmissions now */
 	while ((skb = skb_dequeue(&skbs))) {
 		dev_queue_xmit(skb);
 	}
+#endif /* !__FreeBSD__ */
 	return 0;
 }
 
@@ -418,7 +517,9 @@
 	register_netdevice_notifier(&ztdeth_nblock);
 	dahdi_dynamic_register(&ztd_eth);
 
+#if !defined(__FreeBSD__)
 	skb_queue_head_init(&skbs);
+#endif
 
 	return 0;
 }
@@ -430,9 +531,31 @@
 	dahdi_dynamic_unregister(&ztd_eth);
 }
 
+#if defined(__FreeBSD__)
+static int
+dahdi_dynamic_eth_modevent(module_t mod __unused, int type, void *data __unused)
+{
+	switch (type) {
+	case MOD_LOAD:
+		return ztdeth_init();
+	case MOD_UNLOAD:
+		ztdeth_exit();
+		return 0;
+	default:
+		return EOPNOTSUPP;
+	}
+}
+
+DEV_MODULE(dahdi_dynamic_eth, dahdi_dynamic_eth_modevent, NULL);
+MODULE_VERSION(dahdi_dynamic_eth, 1);
+MODULE_DEPEND(dahdi_dynamic_eth, dahdi, 1, 1, 1);
+MODULE_DEPEND(dahdi_dynamic_eth, dahdi_dynamic, 1, 1, 1);
+MODULE_DEPEND(dahdi_dynamic_eth, ng_dahdi_netdev, 1, 1, 1);
+#else /* !__FreeBSD__ */
 MODULE_DESCRIPTION("DAHDI Dynamic TDMoE Support");
 MODULE_AUTHOR("Mark Spencer <markster at digium.com>");
 MODULE_LICENSE("GPL v2");
 
 module_init(ztdeth_init);
 module_exit(ztdeth_exit);
+#endif /* !__FreeBSD__ */

Modified: freebsd/trunk/freebsd/Makefile
URL: http://svnview.digium.com/svn/dahdi/freebsd/trunk/freebsd/Makefile?view=diff&rev=7803&r1=7802&r2=7803
==============================================================================
--- freebsd/trunk/freebsd/Makefile (original)
+++ freebsd/trunk/freebsd/Makefile Sat Jan  9 17:25:33 2010
@@ -5,6 +5,7 @@
 	dahdi_dummy\
 	dahdi_dynamic\
 	dahdi_dynamic_loc\
+	dahdi_dynamic_eth\
 	dahdi_echocan_jpah\
 	dahdi_echocan_kb1\
 	dahdi_echocan_mg2\
@@ -12,6 +13,7 @@
 	dahdi_echocan_sec2\
 	dahdi_fw_oct6114_064\
 	dahdi_fw_oct6114_128\
+	ng_dahdi_netdev\
 	wcb4xxp\
 	wct4xxp
 

Added: freebsd/trunk/freebsd/ng_dahdi_netdev/Makefile
URL: http://svnview.digium.com/svn/dahdi/freebsd/trunk/freebsd/ng_dahdi_netdev/Makefile?view=auto&rev=7803
==============================================================================
--- freebsd/trunk/freebsd/ng_dahdi_netdev/Makefile (added)
+++ freebsd/trunk/freebsd/ng_dahdi_netdev/Makefile Sat Jan  9 17:25:33 2010
@@ -1,0 +1,6 @@
+# $Id$
+
+KMOD=	ng_dahdi_netdev
+SRCS=	ng_dahdi_netdev.c
+
+.include <bsd.kmod.mk>

Propchange: freebsd/trunk/freebsd/ng_dahdi_netdev/Makefile
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: freebsd/trunk/freebsd/ng_dahdi_netdev/Makefile
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: freebsd/trunk/freebsd/ng_dahdi_netdev/Makefile
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: freebsd/trunk/freebsd/ng_dahdi_netdev/ng_dahdi_netdev.c
URL: http://svnview.digium.com/svn/dahdi/freebsd/trunk/freebsd/ng_dahdi_netdev/ng_dahdi_netdev.c?view=auto&rev=7803
==============================================================================
--- freebsd/trunk/freebsd/ng_dahdi_netdev/ng_dahdi_netdev.c (added)
+++ freebsd/trunk/freebsd/ng_dahdi_netdev/ng_dahdi_netdev.c Sat Jan  9 17:25:33 2010
@@ -1,0 +1,502 @@
+/*
+ * Copyright (c) 2010 Max Khon <fjoe at FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/callout.h>
+#include <sys/lock.h>
+#include <sys/mbuf.h>
+#include <sys/mutex.h>
+#include <sys/kernel.h>
+
+#include <machine/stdarg.h>
+
+#include <netgraph/ng_message.h>
+#include <netgraph/netgraph.h>
+#include <netgraph/ng_ether.h>
+
+#include "ng_dahdi_netdev.h"
+
+static struct mtx netdev_mtx;
+MTX_SYSINIT(netdev_mtx, &netdev_mtx, "DAHDI netdevice lock", 0);
+
+MALLOC_DEFINE(M_DAHDI_NETDEV, "dahdi netdev", "DAHDI netdev data structures");
+
+static SLIST_HEAD(, notifier_block) notifier_blocks =
+	SLIST_HEAD_INITIALIZER(notifier_blocks);
+
+static SLIST_HEAD(, packet_type) packet_types =
+	SLIST_HEAD_INITIALIZER(packet_types);
+
+int shutting_down = 0;
+
+static void
+rlprintf(int pps, const char *fmt, ...)
+	__printflike(2, 3);
+
+static void
+rlprintf(int pps, const char *fmt, ...)
+{
+	va_list ap;
+	static struct timeval last_printf;
+	static int count;
+
+	if (ppsratecheck(&last_printf, &count, pps)) {
+		va_start(ap, fmt);
+		vprintf(fmt, ap);
+		va_end(ap);
+	}
+}
+
+/**
+ * Register notifier
+ */
+int
+register_netdevice_notifier(struct notifier_block *block)
+{
+	mtx_lock(&netdev_mtx);
+	if (shutting_down)
+		return (ENXIO);
+	SLIST_INSERT_HEAD(&notifier_blocks, block, next);
+	mtx_unlock(&netdev_mtx);
+	return (0);
+}
+
+/**
+ * Unregister notifier
+ */
+int
+unregister_netdevice_notifier(struct notifier_block *block)
+{
+	mtx_lock(&netdev_mtx);
+	SLIST_REMOVE(&notifier_blocks, block, notifier_block, next);
+	mtx_unlock(&netdev_mtx);
+	return (0);
+}
+
+/**
+ * Notify netdevice
+ */
+static void
+netdevice_notify(struct net_device *netdev, unsigned long event)
+{
+	struct notifier_block *block;
+
+	printf("dahdi_netdev(%s): interface %s\n",
+	    NG_NODE_NAME(netdev->node),
+	    event == NETDEV_UP ? "up" : "down");
+	SLIST_FOREACH(block, &notifier_blocks, next) {
+		block->notifier_call(block, event, netdev);
+	}
+}
+
+/**
+ * Add packet type handler
+ */
+void
+dev_add_pack(struct packet_type *ptype)
+{
+	mtx_lock(&netdev_mtx);
+	if (shutting_down)
+		return;
+	SLIST_INSERT_HEAD(&packet_types, ptype, next);
+	mtx_unlock(&netdev_mtx);
+}
+
+/**
+ * Remove packet type handler
+ */
+void
+dev_remove_pack(struct packet_type *ptype)
+{
+	mtx_lock(&netdev_mtx);
+	SLIST_REMOVE(&packet_types, ptype, packet_type, next);
+	mtx_unlock(&netdev_mtx);
+}
+
+static int ng_dahdi_netdev_mod_event(module_t mod, int event, void *data);
+static ng_rcvmsg_t ng_dahdi_netdev_rcvmsg;
+static ng_shutdown_t ng_dahdi_netdev_shutdown;
+static ng_newhook_t ng_dahdi_netdev_newhook;
+static ng_disconnect_t ng_dahdi_netdev_disconnect;
+static ng_rcvdata_t ng_dahdi_netdev_rcvdata;
+
+static struct ng_type ng_dahdi_netdev_typestruct = {
+	.version =	NG_ABI_VERSION,
+	.name =		"ng_dahdi_netdev",
+	.mod_event =	ng_dahdi_netdev_mod_event,
+	.rcvmsg =	ng_dahdi_netdev_rcvmsg,
+	.shutdown =	ng_dahdi_netdev_shutdown,
+	.newhook =	ng_dahdi_netdev_newhook,
+	.rcvdata =	ng_dahdi_netdev_rcvdata,
+	.disconnect =	ng_dahdi_netdev_disconnect,
+};
+NETGRAPH_INIT(dahdi_netdev, &ng_dahdi_netdev_typestruct);
+MODULE_VERSION(ng_dahdi_netdev, 1);
+
+/**
+ * Get network device by name
+ */
+struct net_device *
+dev_get_by_name(const char *devname)
+{
+	struct ng_node *ether_node = NULL, *node = NULL;
+	struct net_device *netdev = NULL;
+	struct ng_mesg *msg;
+	char node_name[IFNAMSIZ + 8];
+	int error;
+	struct ngm_connect *nc;
+
+	/* check if DAHDI netgraph node for that device already exists */
+	snprintf(node_name, sizeof(node_name), "dahdi@%s", devname);
+	node = ng_name2noderef(NULL, node_name);
+	if (node != NULL) {
+		netdev = NG_NODE_PRIVATE(node);
+		printf("dahdi_netdev(%s): existing netgraph node ether %*D\n",
+		    NG_NODE_NAME(node), (int) sizeof(netdev->dev_addr), netdev->dev_addr, ":");
+		NG_NODE_UNREF(node);
+		return (netdev);
+	}
+
+	/* create new network device */
+	netdev = malloc(sizeof(*netdev), M_DAHDI_NETDEV, M_NOWAIT | M_ZERO);
+	if (netdev == NULL) {
+		printf("dahdi_netdev(%s): can not create netdevice\n",
+		    node_name);
+		goto error;
+	}
+	strlcpy(netdev->name, devname, sizeof(netdev->name));
+
+	/* create new DAHDI netgraph node */
+	if (ng_make_node_common(&ng_dahdi_netdev_typestruct, &node) != 0) {
+		printf("dahdi_netdev(%s): can not create netgraph node\n",
+		    node_name);
+		goto error;
+	}
+	netdev->node = node;
+	NG_NODE_SET_PRIVATE(node, netdev);
+	if (ng_name_node(node, node_name) != 0) {
+		printf("dahdi_netdev(%s): can not set netgraph node name\n",
+		    node_name);
+		goto error;
+	}
+
+	/* get reference to ethernet device ng node */
+	ether_node = ng_name2noderef(NULL, devname);
+	if (ether_node == NULL) {
+		printf("dahdi_netdev(%s): no netgraph node for %s\n",
+		    NG_NODE_NAME(node), netdev->name);
+		goto error;
+	}
+
+	/* get ethernet address */
+	NG_MKMESSAGE(msg, NGM_ETHER_COOKIE, NGM_ETHER_GET_ENADDR, 0, M_NOWAIT);
+	if (msg == NULL) {
+		printf("dahdi_netdev(%s): can not allocate NGM_ETHER_GET_ENADDR message\n",
+		    NG_NODE_NAME(node));
+		return (0);
+	}
+	NG_SEND_MSG_ID(error, node, msg, NG_NODE_ID(ether_node), NG_NODE_ID(node));
+	if (error) {
+		printf("dahdi_netdev(%s): NGM_ETHER_GET_ENADDR: error %d\n",
+		    NG_NODE_NAME(node), error);
+		return (0);
+	}
+	NG_NODE_UNREF(ether_node);
+	ether_node = NULL;
+
+	/* connect to ether "orphans" hook */
+	NG_MKMESSAGE(msg, NGM_GENERIC_COOKIE, NGM_CONNECT,
+	    sizeof(*nc), M_NOWAIT);
+	if (msg == NULL) {
+		printf("dahdi_netdev(%s): can not allocate NGM_CONNECT message\n",
+		    NG_NODE_NAME(node));
+		goto error;
+	}
+	nc = (struct ngm_connect *) msg->data;
+	snprintf(nc->path, sizeof(nc->path), "%s:", devname);
+	strlcpy(nc->ourhook, "upper", sizeof(nc->ourhook));
+	strlcpy(nc->peerhook, NG_ETHER_HOOK_ORPHAN, sizeof(nc->peerhook));
+	NG_SEND_MSG_ID(error, node, msg, NG_NODE_ID(node), NG_NODE_ID(node));
+	if (error) {
+		printf("dahdi_netdev(%s): NGM_CONNECT(%s:%s <-> %s): error %d\n",
+		    NG_NODE_NAME(node), devname, NG_ETHER_HOOK_ORPHAN, "upper", error);
+		goto error;
+	}
+
+	printf("dahdi_netdev(%s): new netgraph node\n",
+	    NG_NODE_NAME(node));
+	return (netdev);
+
+error:
+	if (netdev != NULL)
+		free(netdev, M_DAHDI_NETDEV);
+	if (node != NULL)
+		NG_NODE_UNREF(node);
+	if (ether_node != NULL)
+		NG_NODE_UNREF(ether_node);
+	return (NULL);
+}
+
+/**
+ * Release network device
+ */
+void
+dev_put(struct net_device *netdev)
+{
+	if (netdev == NULL)
+		return;
+
+	NG_NODE_REALLY_DIE(netdev->node);	/* Force real removal of node */
+	ng_rmnode_self(netdev->node);		/* remove all netgraph parts */
+}
+
+/**
+ * Transmit raw ethernet frame
+ *
+ * Takes ownership of passed mbuf.
+ */
+void
+dev_xmit(struct net_device *netdev, struct mbuf *m)
+{
+	int error;
+
+	if (netdev->upper == NULL)
+		return;
+	NG_SEND_DATA_ONLY(error, netdev->upper, m);
+}
+
+static int
+ng_dahdi_netdev_attach(void)
+{
+	/* intentionally left empty */
+	return (0);
+}
+
+static int
+ng_dahdi_netdev_detach(void)
+{
+	mtx_lock(&netdev_mtx);
+
+	shutting_down = 1;
+
+	if (!SLIST_EMPTY(&notifier_blocks)) {
+		printf("%s: notifier block list is not empty\n", __FUNCTION__);
+		return (EBUSY);
+	}
+
+	if (!SLIST_EMPTY(&packet_types)) {
+		printf("%s: packet type list is not empty\n", __FUNCTION__);
+		return (EBUSY);
+	}
+
+	mtx_unlock(&netdev_mtx);
+
+	return (0);
+}
+
+static int
+ng_dahdi_netdev_mod_event(module_t mod, int type, void *data)
+{
+	switch (type) {
+	case MOD_LOAD:
+		return ng_dahdi_netdev_attach();
+
+	case MOD_UNLOAD:
+		return ng_dahdi_netdev_detach();
+	}
+
+	return (EOPNOTSUPP);
+}
+
+/**
+ * Receive an incoming control message
+ */
+static int
+ng_dahdi_netdev_rcvmsg(struct ng_node *node, struct ng_item *item, struct ng_hook *lasthook)
+{
+	struct net_device *netdev = NG_NODE_PRIVATE(node);
+	struct ng_mesg *msg, *resp = NULL;
+	int error = 0;
+
+	NGI_GET_MSG(item, msg);
+	switch (msg->header.typecookie) {
+	case NGM_ETHER_COOKIE:
+		switch (msg->header.cmd) {
+		case NGM_ETHER_GET_ENADDR:
+			bcopy(msg->data, netdev->dev_addr, sizeof(netdev->dev_addr));
+			printf("dahdi_netdev(%s): ether %*D\n",
+			    NG_NODE_NAME(node),
+			    (int) sizeof(netdev->dev_addr), netdev->dev_addr, ":");
+			break;
+		default:
+			error = EINVAL;
+			break;
+		}
+		break;
+	case NGM_FLOW_COOKIE:
+		switch (msg->header.cmd) {
+		case NGM_LINK_IS_UP:
+		case NGM_LINK_IS_DOWN:
+			netdevice_notify(netdev,
+			    msg->header.cmd == NGM_LINK_IS_UP ?  NETDEV_UP : NETDEV_DOWN);
+			break;
+		default:
+			error = EINVAL;
+			break;
+		}
+		break;
+	default:
+		error = EINVAL;
+		break;
+	}
+	NG_RESPOND_MSG(error, node, item, resp);
+	NG_FREE_MSG(msg);
+	return (error);
+}
+
+/**
+ * Shutdown node
+ *
+ * Reset the node but does not remove it unless the REALLY_DIE flag is set.
+ */
+static int
+ng_dahdi_netdev_shutdown(struct ng_node *node)
+{
+	if (node->nd_flags & NGF_REALLY_DIE) {
+		struct net_device *netdev = NG_NODE_PRIVATE(node);
+
+		printf("dahdi_netdev(%s): destroying netgraph node\n",
+		    NG_NODE_NAME(node));
+		netdevice_notify(netdev, NETDEV_DOWN);
+		NG_NODE_SET_PRIVATE(node, NULL);
+		NG_NODE_UNREF(node);
+
+		free(netdev, M_DAHDI_NETDEV);
+		return (0);
+	}
+
+	NG_NODE_REVIVE(node);		/* Tell ng_rmnode we are persistent */
+	return (0);
+}
+
+/*
+ * Check for attaching a new hook.
+ */
+static int
+ng_dahdi_netdev_newhook(struct ng_node *node, struct ng_hook *hook, const char *name)
+{
+	struct net_device *netdev = NG_NODE_PRIVATE(node);
+	struct ng_hook **hookptr;
+
+	if (strcmp(name, "upper") == 0) {
+		hookptr = &netdev->upper;
+	} else {
+		printf("dahdi_netdev(%s): unsupported hook %s\n",
+		    NG_NODE_NAME(node), name);
+		return (EINVAL);
+	}
+
+	if (*hookptr != NULL) {
+		printf("dahdi_netdev(%s): %s hook is already connected\n",
+		    NG_NODE_NAME(node), name);
+		return (EISCONN);
+	}
+
+	*hookptr = hook;
+	return (0);
+}
+
+/*
+ * Hook disconnection.
+ */
+static int
+ng_dahdi_netdev_disconnect(struct ng_hook *hook)
+{
+	struct ng_node *node = NG_HOOK_NODE(hook);
+	struct net_device *netdev = NG_NODE_PRIVATE(node);
+
+	if (hook == netdev->upper) {
+		netdev->upper = NULL;
+	} else {
+		panic("dahdi_netdev(%s): %s: weird hook", NG_NODE_NAME(node), __func__);
+	}
+
+	return (0);
+}
+
+/**
+ * Receive data
+ */
+static int
+ng_dahdi_netdev_rcvdata(struct ng_hook *hook, struct ng_item *item)
+{
+	struct ng_node *node = NG_HOOK_NODE(hook);
+	struct net_device *netdev = NG_NODE_PRIVATE(node);
+	struct mbuf *m;
+	struct ether_header eh;
+	struct packet_type *ptype;
+	unsigned char *msg = NULL;
+	int msglen;
+
+	/* get mbuf */
+	NGI_GET_M(item, m);
+	NG_FREE_ITEM(item);
+
+	/*
+	 * get ethernet header
+	 * do copy because of possible m_pullup later
+	 */
+	msglen = m_length(m, NULL);
+	if (msglen < sizeof(eh))
+		return (EINVAL);
+	m_copydata(m, 0, sizeof(eh), (caddr_t) &eh);
+
+	/* pass it down to packet type handlers */
+	SLIST_FOREACH(ptype, &packet_types, next) {
+		if (ptype->type == eh.ether_type) {
+			if (msg == NULL) {
+				/* skip ethernet header */
+				msglen -= sizeof(eh);
+				msg = malloc(msglen, M_DAHDI_NETDEV, M_NOWAIT);
+				if (msg == NULL) {
+					rlprintf(10, "dahdi_netdev(%s): malloc failed\n",
+					    NG_NODE_NAME(node));
+					return (ENOMEM);
+				}
+				m_copydata(m, sizeof(eh), msglen, msg);
+			}
+			ptype->func(netdev, &eh, msg, msglen);
+		}
+	}
+
+	/* free memory */
+	NG_FREE_M(m);
+	if (msg != NULL)
+		free(msg, M_DAHDI_NETDEV);
+	return (0);
+}

Propchange: freebsd/trunk/freebsd/ng_dahdi_netdev/ng_dahdi_netdev.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: freebsd/trunk/freebsd/ng_dahdi_netdev/ng_dahdi_netdev.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: freebsd/trunk/freebsd/ng_dahdi_netdev/ng_dahdi_netdev.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: freebsd/trunk/freebsd/ng_dahdi_netdev/ng_dahdi_netdev.h
URL: http://svnview.digium.com/svn/dahdi/freebsd/trunk/freebsd/ng_dahdi_netdev/ng_dahdi_netdev.h?view=auto&rev=7803
==============================================================================
--- freebsd/trunk/freebsd/ng_dahdi_netdev/ng_dahdi_netdev.h (added)
+++ freebsd/trunk/freebsd/ng_dahdi_netdev/ng_dahdi_netdev.h Sat Jan  9 17:25:33 2010
@@ -1,0 +1,112 @@
+/*
+ * Copyright (c) 2010 Max Khon <fjoe at FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#ifndef _NG_DAHDI_NETDEV_H_
+#define _NG_DAHDI_NETDEV_H_
+
+#include <sys/queue.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+
+/**
+ * Notifier network device events
+ */
+#define NETDEV_UP		0x0001
+#define NETDEV_DOWN		0x0002
+#define NETDEV_GOING_DOWN	0x0009
+
+/**
+ * Notifier descriptor
+ */
+struct notifier_block {
+	int (*notifier_call)(struct notifier_block *block, unsigned long event, void *ptr);
+
+	SLIST_ENTRY(notifier_block) next;
+};
+
+/**
+ * Register notifier
+ */
+int register_netdevice_notifier(struct notifier_block *block);
+
+/**
+ * Unregister notifier
+ */
+int unregister_netdevice_notifier(struct notifier_block *block);
+
+/**
+ * Network device
+ */
+struct net_device {
+	char name[IFNAMSIZ];		// interface name
+	u_char dev_addr[ETHER_ADDR_LEN];// interface ethernet address
+	struct ng_node *node;		// corresponding netgraph node
+	struct ng_hook *upper;		// hook connected to ether node
+};
+
+/**
+ * Packet type descriptor
+ */
+struct packet_type {
+	uint16_t type;			// ethernet packet type
+	void *dev;			// unused
+	int (*func)(struct net_device *netdev, struct ether_header *eh,
+		    unsigned char *msg, int msglen);
+
+	SLIST_ENTRY(packet_type) next;
+};
+
+/**
+ * Add packet type handler
+ */
+void dev_add_pack(struct packet_type *ptype);
+
+/**
+ * Remove packet type handler
+ */
+void dev_remove_pack(struct packet_type *ptype);
+
+/**
+ * Get network device by name
+ */
+struct net_device *dev_get_by_name(const char *devname);
+
+/**
+ * Release network device
+ */
+void dev_put(struct net_device *netdev);
+
+/**
+ * Transmit raw ethernet frame
+ *
+ * Takes ownership of passed mbuf.
+ */
+void dev_xmit(struct net_device *netdev, struct mbuf *m);
+
+#endif /* _NG_DAHDI_NETDEV_H_ */

Propchange: freebsd/trunk/freebsd/ng_dahdi_netdev/ng_dahdi_netdev.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: freebsd/trunk/freebsd/ng_dahdi_netdev/ng_dahdi_netdev.h
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: freebsd/trunk/freebsd/ng_dahdi_netdev/ng_dahdi_netdev.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain




More information about the svn-commits mailing list