netfilter: implement hotdrop for Ebtables
Jan Engelhardt [Wed, 8 Oct 2008 09:35:16 +0000 (11:35 +0200)]
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
Signed-off-by: Patrick McHardy <kaber@trash.net>

net/bridge/netfilter/ebtables.c

index c4f7a2e..7964d3f 100644 (file)
@@ -78,9 +78,10 @@ static inline int ebt_do_watcher (struct ebt_entry_watcher *w,
 
 static inline int ebt_do_match (struct ebt_entry_match *m,
    const struct sk_buff *skb, const struct net_device *in,
-   const struct net_device *out)
+   const struct net_device *out, bool *hotdrop)
 {
-       return m->u.match->match(skb, in, out, m->u.match, m->data, 0, 0, NULL);
+       return m->u.match->match(skb, in, out, m->u.match,
+              m->data, 0, 0, hotdrop);
 }
 
 static inline int ebt_dev_check(char *entry, const struct net_device *device)
@@ -156,6 +157,7 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
        struct ebt_entries *chaininfo;
        char *base;
        struct ebt_table_info *private;
+       bool hotdrop = false;
 
        read_lock_bh(&table->lock);
        private = table->private;
@@ -176,8 +178,13 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
                if (ebt_basic_match(point, eth_hdr(skb), in, out))
                        goto letscontinue;
 
-               if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, in, out) != 0)
+               if (EBT_MATCH_ITERATE(point, ebt_do_match, skb,
+                   in, out, &hotdrop) != 0)
                        goto letscontinue;
+               if (hotdrop) {
+                       read_unlock_bh(&table->lock);
+                       return NF_DROP;
+               }
 
                /* increase counter */
                (*(counter_base + i)).pcnt++;