[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(¬ifier_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(¬ifier_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, ¬ifier_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(¬ifier_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