source: branches/backfire/target/linux/generic-2.6/patches-2.6.30/110-netfilter_match_speedup.patch @ 29023

Last change on this file since 29023 was 29023, checked in by florian, 4 years ago

refresh 2.6.30 patches

File size: 4.1 KB
  • include/linux/netfilter_ipv4/ip_tables.h

    a b struct ipt_ip { 
    6262#define IPT_F_FRAG              0x01    /* Set if rule is a fragment rule */ 
    6363#define IPT_F_GOTO              0x02    /* Set if jump is a goto */ 
    6464#define IPT_F_MASK              0x03    /* All possible flag bits mask. */ 
     65#define IPT_F_NO_DEF_MATCH      0x80    /* Internal: no default match rules present */ 
    6566 
    6667/* Values for "inv" field in struct ipt_ip. */ 
    6768#define IPT_INV_VIA_IN          0x01    /* Invert the sense of IN IFACE. */ 
  • net/ipv4/netfilter/ip_tables.c

    a b ip_packet_match(const struct iphdr *ip, 
    8787 
    8888#define FWINV(bool, invflg) ((bool) ^ !!(ipinfo->invflags & (invflg))) 
    8989 
     90        if (ipinfo->flags & IPT_F_NO_DEF_MATCH) 
     91                return true; 
     92 
    9093        if (FWINV((ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr, 
    9194                  IPT_INV_SRCIP) 
    9295            || FWINV((ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr, 
    ip_packet_match(const struct iphdr *ip, 
    137140                return false; 
    138141        } 
    139142 
     143#undef FWINV 
    140144        return true; 
    141145} 
    142146 
    143147static bool 
    144 ip_checkentry(const struct ipt_ip *ip) 
     148ip_checkentry(struct ipt_ip *ip) 
    145149{ 
    146         if (ip->flags & ~IPT_F_MASK) { 
     150#define FWINV(bool, invflg) ((bool) || (ip->invflags & (invflg))) 
     151 
     152        if (FWINV(ip->smsk.s_addr, IPT_INV_SRCIP) || 
     153                FWINV(ip->dmsk.s_addr, IPT_INV_DSTIP)) 
     154                goto has_match_rules; 
     155 
     156        if (FWINV(!!((const unsigned long *)ip->iniface_mask)[0], 
     157                IPT_INV_VIA_IN) || 
     158            FWINV(!!((const unsigned long *)ip->outiface_mask)[0], 
     159                IPT_INV_VIA_OUT)) 
     160                goto has_match_rules; 
     161 
     162        if (FWINV(ip->proto, IPT_INV_PROTO)) 
     163                goto has_match_rules; 
     164 
     165        if (FWINV(ip->flags&IPT_F_FRAG, IPT_INV_FRAG)) 
     166                goto has_match_rules; 
     167 
     168        ip->flags |= IPT_F_NO_DEF_MATCH; 
     169 
     170has_match_rules: 
     171        if (ip->flags & ~(IPT_F_MASK|IPT_F_NO_DEF_MATCH)) { 
    147172                duprintf("Unknown flag bits set: %08X\n", 
    148173                         ip->flags & ~IPT_F_MASK); 
    149174                return false; 
    ip_checkentry(const struct ipt_ip *ip) 
    153178                         ip->invflags & ~IPT_INV_MASK); 
    154179                return false; 
    155180        } 
     181 
     182#undef FWINV 
    156183        return true; 
    157184} 
    158185 
    unconditional(const struct ipt_ip *ip) 
    200227                        return 0; 
    201228 
    202229        return 1; 
    203 #undef FWINV 
    204230} 
    205231 
    206232#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ 
    ipt_do_table(struct sk_buff *skb, 
    318344        struct xt_match_param mtpar; 
    319345        struct xt_target_param tgpar; 
    320346 
    321         /* Initialization */ 
    322347        ip = ip_hdr(skb); 
     348 
     349        IP_NF_ASSERT(table->valid_hooks & (1 << hook)); 
     350        xt_info_rdlock_bh(); 
     351        private = table->private; 
     352        table_base = private->entries[smp_processor_id()]; 
     353        e = get_entry(table_base, private->hook_entry[hook]); 
     354 
     355        if (e->target_offset <= sizeof(struct ipt_entry) && 
     356                (e->ip.flags & IPT_F_NO_DEF_MATCH)) { 
     357                        struct ipt_entry_target *t = ipt_get_target(e); 
     358                        if (!t->u.kernel.target->target) { 
     359                                int v = ((struct ipt_standard_target *)t)->verdict; 
     360                                if ((v < 0) && (v != IPT_RETURN)) { 
     361                                        ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); 
     362                                        xt_info_rdunlock_bh(); 
     363                                        return (unsigned)(-v) - 1; 
     364                                } 
     365                        } 
     366        } 
     367 
     368        /* Initialization */ 
    323369        datalen = skb->len - ip->ihl * 4; 
    324370        indev = in ? in->name : nulldevname; 
    325371        outdev = out ? out->name : nulldevname; 
    ipt_do_table(struct sk_buff *skb, 
    337383        mtpar.family  = tgpar.family = NFPROTO_IPV4; 
    338384        tgpar.hooknum = hook; 
    339385 
    340         IP_NF_ASSERT(table->valid_hooks & (1 << hook)); 
    341         xt_info_rdlock_bh(); 
    342         private = table->private; 
    343         table_base = private->entries[smp_processor_id()]; 
    344  
    345         e = get_entry(table_base, private->hook_entry[hook]); 
    346  
    347386        /* For return from builtin chain */ 
    348387        back = get_entry(table_base, private->underflow[hook]); 
    349388 
    copy_entries_to_user(unsigned int total_ 
    9761015                unsigned int i; 
    9771016                const struct ipt_entry_match *m; 
    9781017                const struct ipt_entry_target *t; 
     1018                u8 flags; 
    9791019 
    9801020                e = (struct ipt_entry *)(loc_cpu_entry + off); 
    9811021                if (copy_to_user(userptr + off 
    copy_entries_to_user(unsigned int total_ 
    9851025                        ret = -EFAULT; 
    9861026                        goto free_counters; 
    9871027                } 
     1028 
     1029                flags = e->ip.flags & ~IPT_F_NO_DEF_MATCH; 
     1030                if (copy_to_user(userptr + off 
     1031                                 + offsetof(struct ipt_entry, ip.flags), 
     1032                                 &flags, sizeof(flags)) != 0) { 
     1033                        ret = -EFAULT; 
     1034                        goto free_counters; 
     1035                } 
    9881036 
    9891037                for (i = sizeof(struct ipt_entry); 
    9901038                     i < e->target_offset; 
Note: See TracBrowser for help on using the repository browser.