custom target: vlan_t extension problem.

Dawid Ciężarkiewicz <[email protected]>
Newsgroups gmane.linux.network.bridge.ebtables.devel
Organization ASN
Message-ID <[email protected]>
Hi,
 I'm trying to develop ebt-vlan_t extension for ebtables. It should change 
vlan ID of ethernet frame. Having most of work already done I'm experiencing 
problems with changing frame type from non-vlan to vlan.

I derived my work from ebt-mark so I just paste target function which 
essential here:

-- BEGIN --
static int ebt_target_vlan(struct sk_buff **pskb, unsigned int hooknr,
   const struct net_device *in, const struct net_device *out,
   const void *data, unsigned int datalen)
{
    struct ebt_vlan_t_info *info = (struct ebt_vlan_t_info *)data;
    struct vlan_hdr* vh, frame;
    unsigned short vlan_TCI;
    struct sk_buff *nskb;
    struct sk_buff *skb;
    struct vlan_ethhdr * veth;

    if ((*pskb)->protocol != __constant_htons(ETH_P_8021Q)) {
        printk("no vlan pskb - changing...\n");

        /* TODO: is this part needed? */
        /* TRY2 - BEGIN */
         if (skb_shared(*pskb) || skb_cloned(*pskb)) {
            printk("skb_shared(*pskb) || skb_cloned(*pskb)\n");

            nskb = skb_copy(*pskb, GFP_ATOMIC);
            if (!nskb)
                return EBT_DROP;
            if ((*pskb)->sk)
                skb_set_owner_w(nskb, (*pskb)->sk);
            kfree_skb(*pskb);
            *pskb = nskb;
         }

        if (skb_headroom(*pskb) < VLAN_HLEN) {
            printk("skb_headroom(*pskb) < VLAN_HLEN\n");
            nskb = *pskb;
            *pskb = skb_realloc_headroom(nskb, VLAN_HLEN);
            if (*pskb == NULL) {
                *pskb = nskb;
                printk(KERN_ERR "vlan: failed to realloc headroom\n");
                return EBT_DROP;
            }
            kfree_skb(nskb);
        }
        
        /* this mechanism is taken c&p from __vlan_put_tag() */
        veth = vlan_eth_hdr(skb_push(skb, VLAN_HLEN));

        /* Move the mac addresses to the beginning of the new header. */
        memmove(veth, veth + VLAN_HLEN, 2 * VLAN_ETH_ALEN);

        /* first, the ethernet type */
        veth->h_vlan_proto = __constant_htons(ETH_P_8021Q);

        /* now, the tag */
        veth->h_vlan_TCI = htons(info->id);

        veth->h_vlan_proto= __constant_htons(ETH_P_8021Q);
        skb->mac.raw -= VLAN_HLEN;
        skb->nh.raw -= VLAN_HLEN;
        
        /* TRY1 - BEGIN */
        /*
        nskb = __vlan_put_tag(*pskb, info->id);
        if (nskb == NULL) {
            printk("failed - dropping...\n");
            return EBT_DROP;
        } 
        *pskb = nskb;
        */

    } else {
        vh = skb_header_pointer(*pskb, 0, sizeof(frame), &frame);

        //printk("vlan_t - old TCI : %hx\n", vh->h_vlan_TCI);
        vlan_TCI = ntohs (vh->h_vlan_TCI) & ~VLAN_VID_MASK;

        //printk("vlan_t - applying id : %hx\n", info->id);
        //printk("vlan_t - new TCI: %hx\n", vlan_TCI | info->id);
        vh->h_vlan_TCI = htons(vlan_TCI | info->id);
    }
    return info->target;
}
--- END ---

While the second part (when (*pskb)->protocol == 
__constant_htons(ETH_P_8021Q)) works perfectly fine and frame VID is changed, 
the first one is now mix of my tries not to hang kernel.

At the beginning I was going to use  vlan_put_tag(*pskb, info->id); or 
__vlan_put_tag(*pskb, info->id);
, but they hang. So I tried many combinations of hand made and 
found&look-promising code in kernel source.

I'm probably not aware of many facts, because I'm totally kernel newbie. What 
I'd like to ask especially is:
- can ebt target modify pskb or substitute it with another one (struct sk_buff 
**pskb is used for that, I suppose); are there any additional conditions 
(chains, tables etc.)?
- are there any other limitations for ebt target (locks, interupts ...)?

Of course if anybody can point me anything interesting, like comments and 
advices (especially about pasted piece of code) I'd be most thankful. I'm not 
afraid of reading code so please point me function&file if you think I should 
read it more carefully.

Best Regards,
Dawid

Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.