I have wrote a driver that adds vlan and my own sfab header to packets
(both defined in struct sfab_hdr ). I have increased hard_header_len so
new headers will always fit to skb. skb->dev is changed to bonding
device that will then at the end use real ethernet device to send the
packet over the network. So it goes like: -> sfab -> bond -> eth0 ->
network
The driver works fine, but it just leaks memory and seems to me the sent
skb is not freed somehow.
int hard_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct sfab_priv *priv = netdev_priv(dev);
struct sfab_hdr *sfab;
struct sk_buff *sk_tmp;
/* if no space in skb headroom for vlan and sfab, increase the
size */
if(skb_headroom(skb) < (sizeof(struct sfab_hdr)-ETH_HLEN))
{
/*We should never end up here because hard_header_len
enough*/
sk_tmp = skb;
skb = skb_realloc_headroom(sk_tmp,
(sizeof(struct sfab_hdr)-ETH_HLEN));
kfree_skb(sk_tmp);
if (!skb) {
printk(KERN_ERR "sfab: failed to realloc
headroom\n");
priv->stats.tx_errors++;
return 0;
}
}
else {
skb = skb_unshare(skb, GFP_ATOMIC);
if (!skb) {
printk(KERN_ERR "sfab: failed to unshare
skbuff\n");
priv->stats.tx_errors++;
return 0;
}
}
sfab = (struct sfab_hdr *)skb_push(skb,
(sizeof(struct sfab_hdr)-ETH_HLEN));
skb->mac.raw -= (sizeof(struct sfab_hdr)-ETH_HLEN);
skb->nh.raw -= (sizeof(struct sfab_hdr)-ETH_HLEN);
set_sfab_header(sfab,skb);/* make VLAN header + sfab header */
/* try to fix skb so it works*/
skb->nfct=NULL;
skb->protocol = __constant_htons(ETH_P_8021Q); /* VLAN */
skb->dev=priv->lower_dev; /* bonding device will send this
further */
dev->trans_start = jiffies; /* save the timestamp */
priv->stats.tx_packets++;
priv->stats.tx_bytes+=skb->len;
if(dev_queue_xmit(skb)<0)
{
/* Not able to transmit, free it */
skb_unlink(skb);
kfree_skb(skb);
priv->stats.tx_errors++;
}
return 0;
}
What should I do? If the skb pointer changes, should it be updated to
some list or what?
Tomi
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html