diff options
-rw-r--r-- | libdde_linux26/contrib/include/linux/skbuff.h | 5 | ||||
-rw-r--r-- | libdde_linux26/include/dde26_net.h | 9 | ||||
-rw-r--r-- | libdde_linux26/lib/src/Makefile | 1 | ||||
-rw-r--r-- | libdde_linux26/lib/src/arch/l4/mach_glue.c | 85 | ||||
-rw-r--r-- | libdde_linux26/lib/src/net/core/skbuff.c | 11 |
5 files changed, 108 insertions, 3 deletions
diff --git a/libdde_linux26/contrib/include/linux/skbuff.h b/libdde_linux26/contrib/include/linux/skbuff.h index 9dcf956a..a9e9534d 100644 --- a/libdde_linux26/contrib/include/linux/skbuff.h +++ b/libdde_linux26/contrib/include/linux/skbuff.h @@ -354,6 +354,11 @@ struct sk_buff { *data; unsigned int truesize; atomic_t users; + +#ifdef DDE_LINUX + void *del_data; + int (*pre_del_func) (struct sk_buff *, void *); +#endif }; #ifdef __KERNEL__ diff --git a/libdde_linux26/include/dde26_net.h b/libdde_linux26/include/dde26_net.h index 2c3847b8..4545e7cc 100644 --- a/libdde_linux26/include/dde26_net.h +++ b/libdde_linux26/include/dde26_net.h @@ -2,9 +2,10 @@ #define __DDE_26_NET_H #include <linux/skbuff.h> +#include <linux/netdevice.h> /** rx callback function */ -typedef int (*linux_rx_callback)(struct sk_buff *); +typedef int (*linux_rx_callback)(char *, int, struct net_device *); extern linux_rx_callback l4dde26_rx_callback; @@ -25,8 +26,10 @@ linux_rx_callback l4dde26_register_rx_callback(linux_rx_callback cb); */ static inline int l4dde26_do_rx_callback(struct sk_buff *s) { - if (l4dde26_rx_callback != NULL) - return l4dde26_rx_callback(s); + if (l4dde26_rx_callback != NULL) { + skb_push(s, s->dev->hard_header_len); + return l4dde26_rx_callback(s->data, s->len, s->dev); + } return 0; } diff --git a/libdde_linux26/lib/src/Makefile b/libdde_linux26/lib/src/Makefile index b6670ed5..d06a8d6b 100644 --- a/libdde_linux26/lib/src/Makefile +++ b/libdde_linux26/lib/src/Makefile @@ -150,6 +150,7 @@ SRC_C_libdde_linux26.o.a += \ ################################################################## SRC_C_libdde_linux26_net.a += \ arch/l4/net.c \ + arch/l4/mach_glue.c \ drivers/net/mii.c \ net/core/dev.c \ net/core/dev_mcast.c \ diff --git a/libdde_linux26/lib/src/arch/l4/mach_glue.c b/libdde_linux26/lib/src/arch/l4/mach_glue.c new file mode 100644 index 00000000..9130c550 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/mach_glue.c @@ -0,0 +1,85 @@ +#include <linux/netdevice.h> +#include <linux/if.h> + +#define D_INVALID_SIZE 2507 +#define D_NO_MEMORY 2508 + +/* List of sk_buffs waiting to be freed. */ +static struct sk_buff_head skb_done_list; + +struct net_device *search_netdev (char *name) +{ + struct net_device *dev; + struct net *net; + + read_lock(&dev_base_lock); + for_each_net(net) { + for_each_netdev(net, dev) { + if (!strcmp (name, dev->name) + && dev->base_addr && dev->base_addr != 0xffe0) + goto end; + } + } +end: + read_unlock(&dev_base_lock); + return dev; +} + +int linux_pkg_xmit (char *pkg_data, int len, void *del_data, + int (*del_func) (struct sk_buff *, void *), + struct net_device *dev) +{ + struct sk_buff *skb; + + if (len == 0 || len > dev->mtu + dev->hard_header_len) + return D_INVALID_SIZE; + + /* Allocate a sk_buff. */ + skb = dev_alloc_skb (len); + if (!skb) + return D_NO_MEMORY; + + skb->del_data = del_data; + skb->pre_del_func = del_func; + + /* Copy user data. This is only required if it spans multiple pages. */ + skb->len = len; + skb->tail = skb->data + len; + skb->end = skb->tail; + + memcpy (skb->data, pkg_data, len); + + skb->dev = dev; + + return dev->netdev_ops->ndo_start_xmit(skb, dev); +} + +char *netdev_addr(struct net_device *dev) +{ + return dev->dev_addr; +} + +int netdev_flags(struct net_device *dev) +{ + return dev->flags; +} + +void *skb_reply(struct sk_buff *skb) +{ + return skb->del_data; +} + +void skb_done_head_init() +{ + skb_queue_head_init (&skb_done_list); +} + +struct sk_buff *skb_done_dequeue() +{ + return skb_dequeue (&skb_done_list); +} + +void skb_done_queue(struct sk_buff *skb) +{ + skb_queue_tail (&skb_done_list, skb); +} diff --git a/libdde_linux26/lib/src/net/core/skbuff.c b/libdde_linux26/lib/src/net/core/skbuff.c index 59b275b0..853b535b 100644 --- a/libdde_linux26/lib/src/net/core/skbuff.c +++ b/libdde_linux26/lib/src/net/core/skbuff.c @@ -421,6 +421,11 @@ static void skb_release_all(struct sk_buff *skb) void __kfree_skb(struct sk_buff *skb) { +#ifdef DDE_LINUX + if (skb->del_data && skb->pre_del_func + && skb->pre_del_func(skb, skb->del_data)) + return; +#endif skb_release_all(skb); kfree_skbmem(skb); } @@ -436,6 +441,12 @@ void kfree_skb(struct sk_buff *skb) { if (unlikely(!skb)) return; +#ifdef DDE_LINUX + if (atomic_read(&skb->users) == 0) { + __kfree_skb(skb); + return; + } +#endif if (likely(atomic_read(&skb->users) == 1)) smp_rmb(); else if (likely(!atomic_dec_and_test(&skb->users))) |