1 --- a/include/linux/netfilter_ipv4/ip_tables.h
2 +++ b/include/linux/netfilter_ipv4/ip_tables.h
3 @@ -93,6 +93,7 @@ struct ipt_ip {
4 #define IPT_F_FRAG 0x01 /* Set if rule is a fragment rule */
5 #define IPT_F_GOTO 0x02 /* Set if jump is a goto */
6 #define IPT_F_MASK 0x03 /* All possible flag bits mask. */
7 +#define IPT_F_NO_DEF_MATCH 0x80 /* Internal: no default match rules present */
9 /* Values for "inv" field in struct ipt_ip. */
10 #define IPT_INV_VIA_IN 0x01 /* Invert the sense of IN IFACE. */
11 --- a/net/ipv4/netfilter/ip_tables.c
12 +++ b/net/ipv4/netfilter/ip_tables.c
13 @@ -90,6 +90,9 @@ ip_packet_match(const struct iphdr *ip,
15 #define FWINV(bool, invflg) ((bool) ^ !!(ipinfo->invflags & (invflg)))
17 + if (ipinfo->flags & IPT_F_NO_DEF_MATCH)
20 if (FWINV((ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr,
22 FWINV((ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr,
23 @@ -143,6 +146,26 @@ ip_packet_match(const struct iphdr *ip,
28 +ip_checkdefault(struct ipt_ip *ip)
30 + static const char iface_mask[IFNAMSIZ] = {};
32 + if (ip->invflags || ip->flags & IPT_F_FRAG)
35 + if (memcmp(ip->iniface_mask, iface_mask, IFNAMSIZ) != 0)
38 + if (memcmp(ip->outiface_mask, iface_mask, IFNAMSIZ) != 0)
44 + ip->flags |= IPT_F_NO_DEF_MATCH;
48 ip_checkentry(const struct ipt_ip *ip)
50 @@ -566,7 +589,7 @@ static void cleanup_match(struct xt_entr
54 -check_entry(const struct ipt_entry *e, const char *name)
55 +check_entry(struct ipt_entry *e, const char *name)
57 const struct xt_entry_target *t;
59 @@ -575,6 +598,8 @@ check_entry(const struct ipt_entry *e, c
63 + ip_checkdefault(&e->ip);
65 if (e->target_offset + sizeof(struct xt_entry_target) >
68 @@ -936,6 +961,7 @@ copy_entries_to_user(unsigned int total_
69 const struct xt_table_info *private = table->private;
71 const void *loc_cpu_entry;
74 counters = alloc_counters(table);
76 @@ -967,6 +993,14 @@ copy_entries_to_user(unsigned int total_
80 + flags = e->ip.flags & IPT_F_MASK;
81 + if (copy_to_user(userptr + off
82 + + offsetof(struct ipt_entry, ip.flags),
83 + &flags, sizeof(flags)) != 0) {
88 for (i = sizeof(struct ipt_entry);
90 i += m->u.match_size) {