论坛风格切换切换到宽版
  • 643阅读
  • 5回复

[问题求助]写了个vlan模块 但不能FORWARD [复制链接]

上一主题 下一主题
离线yinhezixun.
 
发帖
2061
C币
-235551
威望
386
贡献值
1
银元
-1
铜钱
4624
人人网人气币
0
只看楼主 倒序阅读 使用道具 楼主  发表于: 2009-05-01
不知道哪的问题:
iptable.s -A FORWARD -m vlan --vlan-id 1220 -j ACC.EPT服务器

内核中.没有match,其他链没有问题.

http://upload.bbs.csuboy.com/Mon_1004/126_6699_0b0a34ccc7cf0fd.gif[/img]http://upload.bbs.csuboy.com/Mon_1004/126_6699_0b0a34ccc7cf0fd.gif[/img]    健康

评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
离线免失志.
发帖
2221
C币
5540
威望
451
贡献值
0
银元
0
铜钱
5030
人人网人气币
0
只看该作者 沙发  发表于: 2010-04-13
Re:写了个vlan模块
主要代码:

用户空间;
static int parse(int c, char **argv, int invert,unsigned int *flags,
                const struct ipt_entry *entry,unsigned int *nfcache,
                struct ipt_entry_match **match)
{
        struct ipt_vlan_info *vlaninfo = (struct ipt_vlan_info *) (*match)->data;
        char *end;
        struct ipt_vlan_info local;

        switch (c) {
        case VLAN_ID:
                if(*flags & OPT_VLAN_ID)
                        exit_error(PARAMETER_PROBLEM,
                                   "Can't specify --vlan-id twice");
                check_inverse(optarg, &invert, &optind, 0);
                 if(invert){
                         vlaninfo->invflags |= EBT_VLAN_ID;
                 }
                local.id = strtoul(optarg, &end, 10);
                if (local.id > 4094 || *end != '\0')
                        exit_error(PARAMETER_PROBLEM,
                                  "Invalid --vlan-id range ('%s')", optarg);
                vlaninfo->id = local.id;
                vlaninfo->bitmask |= EBT_VLAN_ID;

                break;
        case VLAN_PRIO:
                if(*flags & OPT_VLAN_PRIO)
                        exit_error(PARAMETER_PROBLEM,
                                   "Can't specify --vlan-prio twice");
                check_inverse(optarg, &invert, &optind, 0);
                 if(invert){
                         vlaninfo->invflags |= EBT_VLAN_PRIO;
                 }

                local.prio = strtoul(optarg, &end, 10);
                if (local.prio >= 8 || *end != '\0')
                        exit_error(PARAMETER_PROBLEM,
                                "Invalid --vlan-prio range ('%s')", optarg);
                vlaninfo->prio = local.prio;
                vlaninfo->bitmask |= EBT_VLAN_PRIO;
                break;
        case VLAN_ENCAP:
                if(*flags & OPT_VLAN_ENCAP)
                        exit_error(PARAMETER_PROBLEM,
                                   "Can't specify --vlan-encap twice");
                check_inverse(optarg, &invert, &optind, 0);
                 if(invert){
                         vlaninfo->invflags |= EBT_VLAN_ENCAP;
                 }

                local.encap = strtoul(optarg, &end, 16);

                if (local.encap < ETH_ZLEN)
                        exit_error(PARAMETER_PROBLEM,
                                "Invalid --vlan-encap range ('%s')", optarg);
                vlaninfo->encap = htons(local.encap);
                vlaninfo->bitmask |= EBT_VLAN_ENCAP;
                break;
        default:
                return 0;

        }
        return 1;
}

/* Final check; we don't care. */
static void final_check(unsigned int flags)
{
                /* Nothing to do */
}

static void print(const struct ipt_ip *ip,
                  const struct ipt_entry_match *match,
                  int numeric)
{
        struct ipt_vlan_info *vlaninfo = (struct ipt_vlan_info *) match->data;

        if (vlaninfo->bitmask & EBT_VLAN_ID) {
                printf("--vlan-id %s %d ", (vlaninfo->invflags & EBT_VLAN_ID) ? "! " : "", vlaninfo->id);
        }
        if (vlaninfo->bitmask & EBT_VLAN_PRIO) {
                printf("--vlan-prio %s %d ", (vlaninfo->invflags & EBT_VLAN_PRIO) ? "! " : "", vlaninfo->prio);
        }
        if (vlaninfo->bitmask & EBT_VLAN_ENCAP) {
                printf("--vlan-encap %s ", (vlaninfo->invflags & EBT_VLAN_ENCAP) ? "! " : "");
                printf("%4.4X ", ntohs(vlaninfo->encap));
        }
}

离线ygzhd.
发帖
1968
C币
-236010
威望
330
贡献值
6
银元
0
铜钱
4280
人人网人气币
0
只看该作者 板凳  发表于: 2010-04-13
Re:写了个vlan模块
内核:

#define GET_BITMASK(_BIT_MASK_) info->bitmask & _BIT_MASK_
#define SET_BITMASK(_BIT_MASK_) info->bitmask |= _BIT_MASK_
#define EXIT_ON_MISMATCH(_MATCH_,_MASK_) {if (!((info->_MATCH_ == _MATCH_)^!!(info->invflags & _MASK_))) return EBT_NOMATCH;}

static int match(const struct sk_buff *skb,
      const struct net_device *in,
      const struct net_device *out,
      const struct xt_match *match,
      const void *matchinfo,
     int offset, unsigned int protoff, int *hotdrop)
{
        const struct ipt_vlan_info *info = matchinfo;
        struct vlan_hdr _frame, *fp;

        printk("for match************\n");
        unsigned short TCI;     /* Whole TCI, given from parsed frame */
        unsigned short id;      /* VLAN ID, given from frame TCI */
        unsigned char prio;     /* user_priority, given from frame TCI */
        /* VLAN encapsulated Type/Length field, given from orig frame */
        unsigned short encap;

        fp = skb_header_pointer(skb, 0, sizeof(_frame), &_frame);
        printk("skb->protocol==%u\n",skb->protocol);
        if (fp == NULL)
                return EBT_NOMATCH;
        /* Tag Control Information (TCI) consists of the following elements:
         * - User_priority. The user_priority field is three bits in length,
         * interpreted as a binary number.
         * - Canonical Format Indicator (CFI). The Canonical Format Indicator
         * (CFI) is a single bit flag value. Currently ignored.
         * - VLAN Identifier (VID). The VID is encoded as
         * an unsigned binary number. */
        TCI = ntohs(fp->h_vlan_TCI);
        id = TCI & VLAN_VID_MASK;
        prio = (TCI >> 13) & 0x7;
        encap = fp->h_vlan_encapsulated_proto;

        printk("vlanid====%u\n",id);
        /* Checking VLAN Identifier (VID) */
        if(info->id != id){
                printk("not match vlanid\n");
                return EBT_NOMATCH;
        }
#if 0
        if (GET_BITMASK(EBT_VLAN_ID))
                EXIT_ON_MISMATCH(id, EBT_VLAN_ID);
#endif
        printk("prio==%u\n",prio);
        /* Checking user_priority */
        if (GET_BITMASK(EBT_VLAN_PRIO))
                EXIT_ON_MISMATCH(prio, EBT_VLAN_PRIO);

        printk("encap ===%u\n",encap);
        /* Checking Encapsulated Proto (Length/Type) field */
        if (GET_BITMASK(EBT_VLAN_ENCAP))
                EXIT_ON_MISMATCH(encap, EBT_VLAN_ENCAP);

        printk("vlan  match\n");
        return EBT_MATCH;
}

离线xunleifilm.
发帖
2062
C币
-152450
威望
382
贡献值
1
银元
-1
铜钱
4740
人人网人气币
0
只看该作者 地板  发表于: 2010-04-13
Re:写了个vlan模块
首先你确认上来的包是带VID的。应该用vconfig来配置。
ebtables有这个功能,你不用自己写了。或者说你可以参考一下。

离线cnstwb.
发帖
2149
C币
-235019
威望
398
贡献值
1
银元
-2
铜钱
4856
人人网人气币
0
只看该作者 4楼 发表于: 2010-04-13
Re:写了个vlan模块
我就是参照ebtables里的vlan 写的
但需要能用iptables来实现,所以给加到iptables里了

离线vcdesign.
发帖
2016
C币
-60934
威望
345
贡献值
1
银元
-2
铜钱
4414
人人网人气币
0
只看该作者 5楼 发表于: 2010-04-13
Re:写了个vlan模块
我的分析是,netfilter 只接收和处理 L3+ 的数据,这也就是为什么 skb->data 永远指向 iph 的原因
你用 printk 输出一下从 skb_mac_header(skb) 开始的内容,看是否包含 VLAN TAG 和 VLAN ID 先
如果没猜错的话,这里已经不存在了
如果存在,那就是程序处理上有问题
快速回复
限100 字节
如果您在写长篇帖子又不马上发表,建议存为草稿
 
上一个 下一个