--- zzzz-none-000/linux-2.6.19.2/net/core/dev.c 2007-01-10 19:10:37.000000000 +0000 +++ davinci-8020-5505/linux-2.6.19.2/net/core/dev.c 2008-05-15 09:52:52.000000000 +0000 @@ -149,6 +149,8 @@ static DEFINE_SPINLOCK(ptype_lock); static struct list_head ptype_base[16]; /* 16 way hashed list */ static struct list_head ptype_all; /* Taps */ +static int (*avm_recvhook)(struct sk_buff *skb); +static int (*avm_early_recvhook)(struct sk_buff *skb); #ifdef CONFIG_NET_DMA static struct dma_client *net_dma_client; @@ -207,7 +209,7 @@ * Device drivers call our routines to queue packets here. We empty the * queue in the local softnet handler. */ -DEFINE_PER_CPU(struct softnet_data, softnet_data) = { NULL }; +DEFINE_PER_CPU(struct softnet_data, softnet_data) = { .output_queue = NULL }; #ifdef CONFIG_SYSFS extern int netdev_sysfs_init(void); @@ -226,6 +228,20 @@ *******************************************************************************/ +void set_avm_recvhook(int (*recvhook)(struct sk_buff *skb)) +{ + spin_lock_bh(&ptype_lock); + avm_recvhook = recvhook; + spin_unlock_bh(&ptype_lock); +} + +void set_avm_early_recvhook(int (*recvhook)(struct sk_buff *skb)) +{ + spin_lock_bh(&ptype_lock); + avm_early_recvhook = recvhook; + spin_unlock_bh(&ptype_lock); +} + /* * For efficiency */ @@ -1425,6 +1441,8 @@ struct Qdisc *q; int rc = -ENOMEM; + skb_trace(skb, 18); + /* GSO will handle the following emulations directly. */ if (netif_needs_gso(dev, skb)) goto gso; @@ -1551,7 +1569,7 @@ int netdev_budget = 300; int weight_p = 64; /* old backlog weight */ -DEFINE_PER_CPU(struct netif_rx_stats, netdev_rx_stat) = { 0, }; +DEFINE_PER_CPU(struct netif_rx_stats, netdev_rx_stat) = { 0, 0, 0, 0 }; /** @@ -1577,6 +1595,8 @@ struct softnet_data *queue; unsigned long flags; + skb_trace(skb, 10); + /* if netpoll wants it, pretend we never saw it */ if (netpoll_rx(skb)) return NET_RX_DROP; @@ -1709,6 +1729,8 @@ { struct net_bridge_port *port; + skb_trace(*pskb, 12); + if ((*pskb)->pkt_type == PACKET_LOOPBACK || (port = rcu_dereference((*pskb)->dev->br_port)) == NULL) return 0; @@ -1827,11 +1849,27 @@ ncls: #endif + if (avm_early_recvhook && (*avm_early_recvhook)(skb)) { + /* + * paket consumed by hook + */ + ret = NET_RX_SUCCESS; + goto out; + } + handle_diverter(skb); if (handle_bridge(&skb, &pt_prev, &ret, orig_dev)) goto out; + if (avm_recvhook && (*avm_recvhook)(skb)) { + /* + * paket consumed by hook + */ + ret = NET_RX_SUCCESS; + goto out; + } + type = skb->protocol; list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type)&15], list) { if (ptype->type == type && @@ -3598,3 +3636,6 @@ #endif EXPORT_PER_CPU_SYMBOL(softnet_data); + +EXPORT_SYMBOL(set_avm_recvhook); +EXPORT_SYMBOL(set_avm_early_recvhook);