History

netfilter: ebt_ip6: allow matching on ipv6-icmp types/codes

To avoid adding a new match revision icmp type/code are stored in the sport/dport area.

Florian Westphal committed 15 years ago

Commit 6faee601 parent 255d0dc2 files · +46 −15Browse files

Unified · Split

2 files
  1. include/linux/netfilter_bridge/ebt_ip6.h +12 −3
  2. net/bridge/netfilter/ebt_ip6.c +34 −12
include/linux/netfilter_bridge/ebt_ip6.h+12−3
@@ -18,8 +18,11 @@ · 17 unmodified lines
18#define EBT_IP6_PROTO 0x0818#define EBT_IP6_PROTO 0x08
19#define EBT_IP6_SPORT 0x1019#define EBT_IP6_SPORT 0x10
20#define EBT_IP6_DPORT 0x2020#define EBT_IP6_DPORT 0x20
21#define EBT_IP6_ICMP6 0x40
22
21#define EBT_IP6_MASK (EBT_IP6_SOURCE | EBT_IP6_DEST | EBT_IP6_TCLASS |\23#define EBT_IP6_MASK (EBT_IP6_SOURCE | EBT_IP6_DEST | EBT_IP6_TCLASS |\
22 EBT_IP6_PROTO | EBT_IP6_SPORT | EBT_IP6_DPORT)24 EBT_IP6_PROTO | EBT_IP6_SPORT | EBT_IP6_DPORT | \
25 EBT_IP6_ICMP6)
23#define EBT_IP6_MATCH "ip6"26#define EBT_IP6_MATCH "ip6"
24 27
25/* the same values are used for the invflags */28/* the same values are used for the invflags */
@@ -32,8 +35,14 @@ struct ebt_ip6_info { · 6 unmodified lines
32 uint8_t protocol;35 uint8_t protocol;
33 uint8_t bitmask;36 uint8_t bitmask;
34 uint8_t invflags;37 uint8_t invflags;
35 uint16_t sport[2];38 union {
36 uint16_t dport[2];39 uint16_t sport[2];
40 uint8_t icmpv6_type[2];
41 };
42 union {
43 uint16_t dport[2];
44 uint8_t icmpv6_code[2];
45 };
37};46};
38 47
39#endif48#endif
net/bridge/netfilter/ebt_ip6.c+34−12
@@ -22,9 +22,15 @@ · 21 unmodified lines
22#include <linux/netfilter_bridge/ebtables.h>22#include <linux/netfilter_bridge/ebtables.h>
23#include <linux/netfilter_bridge/ebt_ip6.h>23#include <linux/netfilter_bridge/ebt_ip6.h>
24 24
25struct tcpudphdr {25union pkthdr {
26 __be16 src;26 struct {
27 __be16 dst;27 __be16 src;
28 __be16 dst;
29 } tcpudphdr;
30 struct {
31 u8 type;
32 u8 code;
33 } icmphdr;
28};34};
29 35
30static bool36static bool
@@ -33,8 +39,8 @@ ebt_ip6_mt(const struct sk_buff *skb, struct xt_action_param *par) · 2 unmodified lines
33 const struct ebt_ip6_info *info = par->matchinfo;39 const struct ebt_ip6_info *info = par->matchinfo;
34 const struct ipv6hdr *ih6;40 const struct ipv6hdr *ih6;
35 struct ipv6hdr _ip6h;41 struct ipv6hdr _ip6h;
36 const struct tcpudphdr *pptr;42 const union pkthdr *pptr;
37 struct tcpudphdr _ports;43 union pkthdr _pkthdr;
38 44
39 ih6 = skb_header_pointer(skb, 0, sizeof(_ip6h), &_ip6h);45 ih6 = skb_header_pointer(skb, 0, sizeof(_ip6h), &_ip6h);
40 if (ih6 == NULL)46 if (ih6 == NULL)
@@ -56,26 +62,34 @@ ebt_ip6_mt(const struct sk_buff *skb, struct xt_action_param *par) · 15 unmodified lines
56 return false;62 return false;
57 if (FWINV(info->protocol != nexthdr, EBT_IP6_PROTO))63 if (FWINV(info->protocol != nexthdr, EBT_IP6_PROTO))
58 return false;64 return false;
59 if (!(info->bitmask & EBT_IP6_DPORT) &&65 if (!(info->bitmask & ( EBT_IP6_DPORT |
60 !(info->bitmask & EBT_IP6_SPORT))66 EBT_IP6_SPORT | EBT_IP6_ICMP6)))
61 return true;67 return true;
62 pptr = skb_header_pointer(skb, offset_ph, sizeof(_ports),68
63 &_ports);69 /* min icmpv6 headersize is 4, so sizeof(_pkthdr) is ok. */
70 pptr = skb_header_pointer(skb, offset_ph, sizeof(_pkthdr),
71 &_pkthdr);
64 if (pptr == NULL)72 if (pptr == NULL)
65 return false;73 return false;
66 if (info->bitmask & EBT_IP6_DPORT) {74 if (info->bitmask & EBT_IP6_DPORT) {
67 u32 dst = ntohs(pptr->dst);75 u16 dst = ntohs(pptr->tcpudphdr.dst);
68 if (FWINV(dst < info->dport[0] ||76 if (FWINV(dst < info->dport[0] ||
69 dst > info->dport[1], EBT_IP6_DPORT))77 dst > info->dport[1], EBT_IP6_DPORT))
70 return false;78 return false;
71 }79 }
72 if (info->bitmask & EBT_IP6_SPORT) {80 if (info->bitmask & EBT_IP6_SPORT) {
73 u32 src = ntohs(pptr->src);81 u16 src = ntohs(pptr->tcpudphdr.src);
74 if (FWINV(src < info->sport[0] ||82 if (FWINV(src < info->sport[0] ||
75 src > info->sport[1], EBT_IP6_SPORT))83 src > info->sport[1], EBT_IP6_SPORT))
76 return false;84 return false;
77 }85 }
78 return true;86 if ((info->bitmask & EBT_IP6_ICMP6) &&
87 FWINV(pptr->icmphdr.type < info->icmpv6_type[0] ||
88 pptr->icmphdr.type > info->icmpv6_type[1] ||
89 pptr->icmphdr.code < info->icmpv6_code[0] ||
90 pptr->icmphdr.code > info->icmpv6_code[1],
91 EBT_IP6_ICMP6))
92 return false;
79 }93 }
80 return true;94 return true;
81}95}
@@ -103,6 +117,14 @@ static int ebt_ip6_mt_check(const struct xt_mtchk_param *par) · 21 unmodified lines
103 return -EINVAL;117 return -EINVAL;
104 if (info->bitmask & EBT_IP6_SPORT && info->sport[0] > info->sport[1])118 if (info->bitmask & EBT_IP6_SPORT && info->sport[0] > info->sport[1])
105 return -EINVAL;119 return -EINVAL;
120 if (info->bitmask & EBT_IP6_ICMP6) {
121 if ((info->invflags & EBT_IP6_PROTO) ||
122 info->protocol != IPPROTO_ICMPV6)
123 return -EINVAL;
124 if (info->icmpv6_type[0] > info->icmpv6_type[1] ||
125 info->icmpv6_code[0] > info->icmpv6_code[1])
126 return -EINVAL;
127 }
106 return 0;128 return 0;
107}129}
108 130