diff options
| author | Patrick McHardy <kaber@trash.net> | 2006-03-20 21:03:40 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2006-03-20 21:03:40 -0500 |
| commit | c4b885139203d37f76662c37ae645fe8e0f4e4e5 (patch) | |
| tree | 5cedf4d632b273df81bf1712b95dbc8b96cdc0e4 | |
| parent | f2ffd9eeda82b476c034d733be08ecf6a87d2edf (diff) | |
[NETFILTER]: x_tables: replace IPv4/IPv6 policy match by address family independant version
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | include/linux/netfilter/x_tables.h | 4 | ||||
| -rw-r--r-- | include/linux/netfilter/xt_policy.h | 58 | ||||
| -rw-r--r-- | include/linux/netfilter_ipv4/ipt_policy.h | 69 | ||||
| -rw-r--r-- | include/linux/netfilter_ipv6/ip6t_policy.h | 69 | ||||
| -rw-r--r-- | net/ipv4/netfilter/Kconfig | 10 | ||||
| -rw-r--r-- | net/ipv4/netfilter/Makefile | 1 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ipt_policy.c | 174 | ||||
| -rw-r--r-- | net/ipv6/netfilter/Kconfig | 10 | ||||
| -rw-r--r-- | net/ipv6/netfilter/Makefile | 1 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6t_policy.c | 174 | ||||
| -rw-r--r-- | net/netfilter/Kconfig | 10 | ||||
| -rw-r--r-- | net/netfilter/Makefile | 1 | ||||
| -rw-r--r-- | net/netfilter/xt_policy.c | 209 |
13 files changed, 314 insertions, 476 deletions
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 2fdbc4a446bf..46a0f974f87c 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h | |||
| @@ -126,6 +126,8 @@ struct xt_match | |||
| 126 | unsigned int matchsize; | 126 | unsigned int matchsize; |
| 127 | unsigned int hooks; | 127 | unsigned int hooks; |
| 128 | unsigned short proto; | 128 | unsigned short proto; |
| 129 | |||
| 130 | unsigned short family; | ||
| 129 | u_int8_t revision; | 131 | u_int8_t revision; |
| 130 | }; | 132 | }; |
| 131 | 133 | ||
| @@ -169,6 +171,8 @@ struct xt_target | |||
| 169 | unsigned int targetsize; | 171 | unsigned int targetsize; |
| 170 | unsigned int hooks; | 172 | unsigned int hooks; |
| 171 | unsigned short proto; | 173 | unsigned short proto; |
| 174 | |||
| 175 | unsigned short family; | ||
| 172 | u_int8_t revision; | 176 | u_int8_t revision; |
| 173 | }; | 177 | }; |
| 174 | 178 | ||
diff --git a/include/linux/netfilter/xt_policy.h b/include/linux/netfilter/xt_policy.h new file mode 100644 index 000000000000..a8132ec076fb --- /dev/null +++ b/include/linux/netfilter/xt_policy.h | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | #ifndef _XT_POLICY_H | ||
| 2 | #define _XT_POLICY_H | ||
| 3 | |||
| 4 | #define XT_POLICY_MAX_ELEM 4 | ||
| 5 | |||
| 6 | enum xt_policy_flags | ||
| 7 | { | ||
| 8 | XT_POLICY_MATCH_IN = 0x1, | ||
| 9 | XT_POLICY_MATCH_OUT = 0x2, | ||
| 10 | XT_POLICY_MATCH_NONE = 0x4, | ||
| 11 | XT_POLICY_MATCH_STRICT = 0x8, | ||
| 12 | }; | ||
| 13 | |||
| 14 | enum xt_policy_modes | ||
| 15 | { | ||
| 16 | XT_POLICY_MODE_TRANSPORT, | ||
| 17 | XT_POLICY_MODE_TUNNEL | ||
| 18 | }; | ||
| 19 | |||
| 20 | struct xt_policy_spec | ||
| 21 | { | ||
| 22 | u_int8_t saddr:1, | ||
| 23 | daddr:1, | ||
| 24 | proto:1, | ||
| 25 | mode:1, | ||
| 26 | spi:1, | ||
| 27 | reqid:1; | ||
| 28 | }; | ||
| 29 | |||
| 30 | union xt_policy_addr | ||
| 31 | { | ||
| 32 | struct in_addr a4; | ||
| 33 | struct in6_addr a6; | ||
| 34 | }; | ||
| 35 | |||
| 36 | struct xt_policy_elem | ||
| 37 | { | ||
| 38 | union xt_policy_addr saddr; | ||
| 39 | union xt_policy_addr smask; | ||
| 40 | union xt_policy_addr daddr; | ||
| 41 | union xt_policy_addr dmask; | ||
| 42 | u_int32_t spi; | ||
| 43 | u_int32_t reqid; | ||
| 44 | u_int8_t proto; | ||
| 45 | u_int8_t mode; | ||
| 46 | |||
| 47 | struct xt_policy_spec match; | ||
| 48 | struct xt_policy_spec invert; | ||
| 49 | }; | ||
| 50 | |||
| 51 | struct xt_policy_info | ||
| 52 | { | ||
| 53 | struct xt_policy_elem pol[XT_POLICY_MAX_ELEM]; | ||
| 54 | u_int16_t flags; | ||
| 55 | u_int16_t len; | ||
| 56 | }; | ||
| 57 | |||
| 58 | #endif /* _XT_POLICY_H */ | ||
diff --git a/include/linux/netfilter_ipv4/ipt_policy.h b/include/linux/netfilter_ipv4/ipt_policy.h index a3f6eff39d33..b9478a255301 100644 --- a/include/linux/netfilter_ipv4/ipt_policy.h +++ b/include/linux/netfilter_ipv4/ipt_policy.h | |||
| @@ -1,58 +1,21 @@ | |||
| 1 | #ifndef _IPT_POLICY_H | 1 | #ifndef _IPT_POLICY_H |
| 2 | #define _IPT_POLICY_H | 2 | #define _IPT_POLICY_H |
| 3 | 3 | ||
| 4 | #define IPT_POLICY_MAX_ELEM 4 | 4 | #define IPT_POLICY_MAX_ELEM XT_POLICY_MAX_ELEM |
| 5 | 5 | ||
| 6 | enum ipt_policy_flags | 6 | /* ipt_policy_flags */ |
| 7 | { | 7 | #define IPT_POLICY_MATCH_IN XT_POLICY_MATCH_IN |
| 8 | IPT_POLICY_MATCH_IN = 0x1, | 8 | #define IPT_POLICY_MATCH_OUT XT_POLICY_MATCH_OUT |
| 9 | IPT_POLICY_MATCH_OUT = 0x2, | 9 | #define IPT_POLICY_MATCH_NONE XT_POLICY_MATCH_NONE |
| 10 | IPT_POLICY_MATCH_NONE = 0x4, | 10 | #define IPT_POLICY_MATCH_STRICT XT_POLICY_MATCH_STRICT |
| 11 | IPT_POLICY_MATCH_STRICT = 0x8, | 11 | |
| 12 | }; | 12 | /* ipt_policy_modes */ |
| 13 | 13 | #define IPT_POLICY_MODE_TRANSPORT XT_POLICY_MODE_TRANSPORT | |
| 14 | enum ipt_policy_modes | 14 | #define IPT_POLICY_MODE_TUNNEL XT_POLICY_MODE_TUNNEL |
| 15 | { | 15 | |
| 16 | IPT_POLICY_MODE_TRANSPORT, | 16 | #define ipt_policy_spec xt_policy_spec |
| 17 | IPT_POLICY_MODE_TUNNEL | 17 | #define ipt_policy_addr xt_policy_addr |
| 18 | }; | 18 | #define ipt_policy_elem xt_policy_elem |
| 19 | 19 | #define ipt_policy_info xt_policy_info | |
| 20 | struct ipt_policy_spec | ||
| 21 | { | ||
| 22 | u_int8_t saddr:1, | ||
| 23 | daddr:1, | ||
| 24 | proto:1, | ||
| 25 | mode:1, | ||
| 26 | spi:1, | ||
| 27 | reqid:1; | ||
| 28 | }; | ||
| 29 | |||
| 30 | union ipt_policy_addr | ||
| 31 | { | ||
| 32 | struct in_addr a4; | ||
| 33 | struct in6_addr a6; | ||
| 34 | }; | ||
| 35 | |||
| 36 | struct ipt_policy_elem | ||
| 37 | { | ||
| 38 | union ipt_policy_addr saddr; | ||
| 39 | union ipt_policy_addr smask; | ||
| 40 | union ipt_policy_addr daddr; | ||
| 41 | union ipt_policy_addr dmask; | ||
| 42 | u_int32_t spi; | ||
| 43 | u_int32_t reqid; | ||
| 44 | u_int8_t proto; | ||
| 45 | u_int8_t mode; | ||
| 46 | |||
| 47 | struct ipt_policy_spec match; | ||
| 48 | struct ipt_policy_spec invert; | ||
| 49 | }; | ||
| 50 | |||
| 51 | struct ipt_policy_info | ||
| 52 | { | ||
| 53 | struct ipt_policy_elem pol[IPT_POLICY_MAX_ELEM]; | ||
| 54 | u_int16_t flags; | ||
| 55 | u_int16_t len; | ||
| 56 | }; | ||
| 57 | 20 | ||
| 58 | #endif /* _IPT_POLICY_H */ | 21 | #endif /* _IPT_POLICY_H */ |
diff --git a/include/linux/netfilter_ipv6/ip6t_policy.h b/include/linux/netfilter_ipv6/ip6t_policy.h index 671bd818300f..6bab3163d2fb 100644 --- a/include/linux/netfilter_ipv6/ip6t_policy.h +++ b/include/linux/netfilter_ipv6/ip6t_policy.h | |||
| @@ -1,58 +1,21 @@ | |||
| 1 | #ifndef _IP6T_POLICY_H | 1 | #ifndef _IP6T_POLICY_H |
| 2 | #define _IP6T_POLICY_H | 2 | #define _IP6T_POLICY_H |
| 3 | 3 | ||
| 4 | #define IP6T_POLICY_MAX_ELEM 4 | 4 | #define IP6T_POLICY_MAX_ELEM XT_POLICY_MAX_ELEM |
| 5 | 5 | ||
| 6 | enum ip6t_policy_flags | 6 | /* ip6t_policy_flags */ |
| 7 | { | 7 | #define IP6T_POLICY_MATCH_IN XT_POLICY_MATCH_IN |
| 8 | IP6T_POLICY_MATCH_IN = 0x1, | 8 | #define IP6T_POLICY_MATCH_OUT XT_POLICY_MATCH_OUT |
| 9 | IP6T_POLICY_MATCH_OUT = 0x2, | 9 | #define IP6T_POLICY_MATCH_NONE XT_POLICY_MATCH_NONE |
| 10 | IP6T_POLICY_MATCH_NONE = 0x4, | 10 | #define IP6T_POLICY_MATCH_STRICT XT_POLICY_MATCH_STRICT |
| 11 | IP6T_POLICY_MATCH_STRICT = 0x8, | 11 | |
| 12 | }; | 12 | /* ip6t_policy_modes */ |
| 13 | 13 | #define IP6T_POLICY_MODE_TRANSPORT XT_POLICY_MODE_TRANSPORT | |
| 14 | enum ip6t_policy_modes | 14 | #define IP6T_POLICY_MODE_TUNNEL XT_POLICY_MODE_TUNNEL |
| 15 | { | 15 | |
| 16 | IP6T_POLICY_MODE_TRANSPORT, | 16 | #define ip6t_policy_spec xt_policy_spec |
| 17 | IP6T_POLICY_MODE_TUNNEL | 17 | #define ip6t_policy_addr xt_policy_addr |
| 18 | }; | 18 | #define ip6t_policy_elem xt_policy_elem |
| 19 | 19 | #define ip6t_policy_info xt_policy_info | |
| 20 | struct ip6t_policy_spec | ||
| 21 | { | ||
| 22 | u_int8_t saddr:1, | ||
| 23 | daddr:1, | ||
| 24 | proto:1, | ||
| 25 | mode:1, | ||
| 26 | spi:1, | ||
| 27 | reqid:1; | ||
| 28 | }; | ||
| 29 | |||
| 30 | union ip6t_policy_addr | ||
| 31 | { | ||
| 32 | struct in_addr a4; | ||
| 33 | struct in6_addr a6; | ||
| 34 | }; | ||
| 35 | |||
| 36 | struct ip6t_policy_elem | ||
| 37 | { | ||
| 38 | union ip6t_policy_addr saddr; | ||
| 39 | union ip6t_policy_addr smask; | ||
| 40 | union ip6t_policy_addr daddr; | ||
| 41 | union ip6t_policy_addr dmask; | ||
| 42 | u_int32_t spi; | ||
| 43 | u_int32_t reqid; | ||
| 44 | u_int8_t proto; | ||
| 45 | u_int8_t mode; | ||
| 46 | |||
| 47 | struct ip6t_policy_spec match; | ||
| 48 | struct ip6t_policy_spec invert; | ||
| 49 | }; | ||
| 50 | |||
| 51 | struct ip6t_policy_info | ||
| 52 | { | ||
| 53 | struct ip6t_policy_elem pol[IP6T_POLICY_MAX_ELEM]; | ||
| 54 | u_int16_t flags; | ||
| 55 | u_int16_t len; | ||
| 56 | }; | ||
| 57 | 20 | ||
| 58 | #endif /* _IP6T_POLICY_H */ | 21 | #endif /* _IP6T_POLICY_H */ |
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index db783036e4d8..933ee7a9efdf 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig | |||
| @@ -303,16 +303,6 @@ config IP_NF_MATCH_HASHLIMIT | |||
| 303 | destination IP' or `500pps from any given source IP' with a single | 303 | destination IP' or `500pps from any given source IP' with a single |
| 304 | IPtables rule. | 304 | IPtables rule. |
| 305 | 305 | ||
| 306 | config IP_NF_MATCH_POLICY | ||
| 307 | tristate "IPsec policy match support" | ||
| 308 | depends on IP_NF_IPTABLES && XFRM | ||
| 309 | help | ||
| 310 | Policy matching allows you to match packets based on the | ||
| 311 | IPsec policy that was used during decapsulation/will | ||
| 312 | be used during encapsulation. | ||
| 313 | |||
| 314 | To compile it as a module, choose M here. If unsure, say N. | ||
| 315 | |||
| 316 | # `filter', generic and specific targets | 306 | # `filter', generic and specific targets |
| 317 | config IP_NF_FILTER | 307 | config IP_NF_FILTER |
| 318 | tristate "Packet filtering" | 308 | tristate "Packet filtering" |
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index e5c5b3202f02..3fe80924ac54 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile | |||
| @@ -57,7 +57,6 @@ obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o | |||
| 57 | obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_ah.o ipt_esp.o | 57 | obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_ah.o ipt_esp.o |
| 58 | obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o | 58 | obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o |
| 59 | obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o | 59 | obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o |
| 60 | obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o | ||
| 61 | 60 | ||
| 62 | # targets | 61 | # targets |
| 63 | obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o | 62 | obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o |
diff --git a/net/ipv4/netfilter/ipt_policy.c b/net/ipv4/netfilter/ipt_policy.c deleted file mode 100644 index b73f590b226b..000000000000 --- a/net/ipv4/netfilter/ipt_policy.c +++ /dev/null | |||
| @@ -1,174 +0,0 @@ | |||
| 1 | /* IP tables module for matching IPsec policy | ||
| 2 | * | ||
| 3 | * Copyright (c) 2004,2005 Patrick McHardy, <kaber@trash.net> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/kernel.h> | ||
| 11 | #include <linux/config.h> | ||
| 12 | #include <linux/module.h> | ||
| 13 | #include <linux/skbuff.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <net/xfrm.h> | ||
| 16 | |||
| 17 | #include <linux/netfilter_ipv4.h> | ||
| 18 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
| 19 | #include <linux/netfilter_ipv4/ipt_policy.h> | ||
| 20 | |||
| 21 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | ||
| 22 | MODULE_DESCRIPTION("IPtables IPsec policy matching module"); | ||
| 23 | MODULE_LICENSE("GPL"); | ||
| 24 | |||
| 25 | |||
| 26 | static inline int | ||
| 27 | match_xfrm_state(struct xfrm_state *x, const struct ipt_policy_elem *e) | ||
| 28 | { | ||
| 29 | #define MATCH_ADDR(x,y,z) (!e->match.x || \ | ||
| 30 | ((e->x.a4.s_addr == (e->y.a4.s_addr & (z))) \ | ||
| 31 | ^ e->invert.x)) | ||
| 32 | #define MATCH(x,y) (!e->match.x || ((e->x == (y)) ^ e->invert.x)) | ||
| 33 | |||
| 34 | return MATCH_ADDR(saddr, smask, x->props.saddr.a4) && | ||
| 35 | MATCH_ADDR(daddr, dmask, x->id.daddr.a4) && | ||
| 36 | MATCH(proto, x->id.proto) && | ||
| 37 | MATCH(mode, x->props.mode) && | ||
| 38 | MATCH(spi, x->id.spi) && | ||
| 39 | MATCH(reqid, x->props.reqid); | ||
| 40 | } | ||
| 41 | |||
| 42 | static int | ||
| 43 | match_policy_in(const struct sk_buff *skb, const struct ipt_policy_info *info) | ||
| 44 | { | ||
| 45 | const struct ipt_policy_elem *e; | ||
| 46 | struct sec_path *sp = skb->sp; | ||
| 47 | int strict = info->flags & IPT_POLICY_MATCH_STRICT; | ||
| 48 | int i, pos; | ||
| 49 | |||
| 50 | if (sp == NULL) | ||
| 51 | return -1; | ||
| 52 | if (strict && info->len != sp->len) | ||
| 53 | return 0; | ||
| 54 | |||
| 55 | for (i = sp->len - 1; i >= 0; i--) { | ||
| 56 | pos = strict ? i - sp->len + 1 : 0; | ||
| 57 | if (pos >= info->len) | ||
| 58 | return 0; | ||
| 59 | e = &info->pol[pos]; | ||
| 60 | |||
| 61 | if (match_xfrm_state(sp->x[i].xvec, e)) { | ||
| 62 | if (!strict) | ||
| 63 | return 1; | ||
| 64 | } else if (strict) | ||
| 65 | return 0; | ||
| 66 | } | ||
| 67 | |||
| 68 | return strict ? 1 : 0; | ||
| 69 | } | ||
| 70 | |||
| 71 | static int | ||
| 72 | match_policy_out(const struct sk_buff *skb, const struct ipt_policy_info *info) | ||
| 73 | { | ||
| 74 | const struct ipt_policy_elem *e; | ||
| 75 | struct dst_entry *dst = skb->dst; | ||
| 76 | int strict = info->flags & IPT_POLICY_MATCH_STRICT; | ||
| 77 | int i, pos; | ||
| 78 | |||
| 79 | if (dst->xfrm == NULL) | ||
| 80 | return -1; | ||
| 81 | |||
| 82 | for (i = 0; dst && dst->xfrm; dst = dst->child, i++) { | ||
| 83 | pos = strict ? i : 0; | ||
| 84 | if (pos >= info->len) | ||
| 85 | return 0; | ||
| 86 | e = &info->pol[pos]; | ||
| 87 | |||
| 88 | if (match_xfrm_state(dst->xfrm, e)) { | ||
| 89 | if (!strict) | ||
| 90 | return 1; | ||
| 91 | } else if (strict) | ||
| 92 | return 0; | ||
| 93 | } | ||
| 94 | |||
| 95 | return strict ? i == info->len : 0; | ||
| 96 | } | ||
| 97 | |||
| 98 | static int match(const struct sk_buff *skb, | ||
| 99 | const struct net_device *in, | ||
| 100 | const struct net_device *out, | ||
| 101 | const struct xt_match *match, | ||
| 102 | const void *matchinfo, | ||
| 103 | int offset, | ||
| 104 | unsigned int protoff, | ||
| 105 | int *hotdrop) | ||
| 106 | { | ||
| 107 | const struct ipt_policy_info *info = matchinfo; | ||
| 108 | int ret; | ||
| 109 | |||
| 110 | if (info->flags & IPT_POLICY_MATCH_IN) | ||
| 111 | ret = match_policy_in(skb, info); | ||
| 112 | else | ||
| 113 | ret = match_policy_out(skb, info); | ||
| 114 | |||
| 115 | if (ret < 0) | ||
| 116 | ret = info->flags & IPT_POLICY_MATCH_NONE ? 1 : 0; | ||
| 117 | else if (info->flags & IPT_POLICY_MATCH_NONE) | ||
| 118 | ret = 0; | ||
| 119 | |||
| 120 | return ret; | ||
| 121 | } | ||
| 122 | |||
| 123 | static int checkentry(const char *tablename, const void *ip_void, | ||
| 124 | const struct xt_match *match, | ||
| 125 | void *matchinfo, unsigned int matchsize, | ||
| 126 | unsigned int hook_mask) | ||
| 127 | { | ||
| 128 | struct ipt_policy_info *info = matchinfo; | ||
| 129 | |||
| 130 | if (!(info->flags & (IPT_POLICY_MATCH_IN|IPT_POLICY_MATCH_OUT))) { | ||
| 131 | printk(KERN_ERR "ipt_policy: neither incoming nor " | ||
| 132 | "outgoing policy selected\n"); | ||
| 133 | return 0; | ||
| 134 | } | ||
| 135 | if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN) | ||
| 136 | && info->flags & IPT_POLICY_MATCH_OUT) { | ||
| 137 | printk(KERN_ERR "ipt_policy: output policy not valid in " | ||
| 138 | "PRE_ROUTING and INPUT\n"); | ||
| 139 | return 0; | ||
| 140 | } | ||
| 141 | if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT) | ||
| 142 | && info->flags & IPT_POLICY_MATCH_IN) { | ||
| 143 | printk(KERN_ERR "ipt_policy: input policy not valid in " | ||
| 144 | "POST_ROUTING and OUTPUT\n"); | ||
| 145 | return 0; | ||
| 146 | } | ||
| 147 | if (info->len > IPT_POLICY_MAX_ELEM) { | ||
| 148 | printk(KERN_ERR "ipt_policy: too many policy elements\n"); | ||
| 149 | return 0; | ||
| 150 | } | ||
| 151 | |||
| 152 | return 1; | ||
| 153 | } | ||
| 154 | |||
| 155 | static struct ipt_match policy_match = { | ||
| 156 | .name = "policy", | ||
| 157 | .match = match, | ||
| 158 | .matchsize = sizeof(struct ipt_policy_info), | ||
| 159 | .checkentry = checkentry, | ||
| 160 | .me = THIS_MODULE, | ||
| 161 | }; | ||
| 162 | |||
| 163 | static int __init init(void) | ||
| 164 | { | ||
| 165 | return ipt_register_match(&policy_match); | ||
| 166 | } | ||
| 167 | |||
| 168 | static void __exit fini(void) | ||
| 169 | { | ||
| 170 | ipt_unregister_match(&policy_match); | ||
| 171 | } | ||
| 172 | |||
| 173 | module_init(init); | ||
| 174 | module_exit(fini); | ||
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index 2d6f8ecbc27b..98f78759f1ab 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig | |||
| @@ -133,16 +133,6 @@ config IP6_NF_MATCH_EUI64 | |||
| 133 | 133 | ||
| 134 | To compile it as a module, choose M here. If unsure, say N. | 134 | To compile it as a module, choose M here. If unsure, say N. |
| 135 | 135 | ||
| 136 | config IP6_NF_MATCH_POLICY | ||
| 137 | tristate "IPsec policy match support" | ||
| 138 | depends on IP6_NF_IPTABLES && XFRM | ||
| 139 | help | ||
| 140 | Policy matching allows you to match packets based on the | ||
| 141 | IPsec policy that was used during decapsulation/will | ||
| 142 | be used during encapsulation. | ||
| 143 | |||
| 144 | To compile it as a module, choose M here. If unsure, say N. | ||
| 145 | |||
| 146 | # The targets | 136 | # The targets |
| 147 | config IP6_NF_FILTER | 137 | config IP6_NF_FILTER |
| 148 | tristate "Packet filtering" | 138 | tristate "Packet filtering" |
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile index db6073c94163..8436a1a1731f 100644 --- a/net/ipv6/netfilter/Makefile +++ b/net/ipv6/netfilter/Makefile | |||
| @@ -9,7 +9,6 @@ obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o | |||
| 9 | obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o | 9 | obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o |
| 10 | obj-$(CONFIG_IP6_NF_MATCH_FRAG) += ip6t_frag.o | 10 | obj-$(CONFIG_IP6_NF_MATCH_FRAG) += ip6t_frag.o |
| 11 | obj-$(CONFIG_IP6_NF_MATCH_AHESP) += ip6t_esp.o ip6t_ah.o | 11 | obj-$(CONFIG_IP6_NF_MATCH_AHESP) += ip6t_esp.o ip6t_ah.o |
| 12 | obj-$(CONFIG_IP6_NF_MATCH_POLICY) += ip6t_policy.o | ||
| 13 | obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o | 12 | obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o |
| 14 | obj-$(CONFIG_IP6_NF_MATCH_MULTIPORT) += ip6t_multiport.o | 13 | obj-$(CONFIG_IP6_NF_MATCH_MULTIPORT) += ip6t_multiport.o |
| 15 | obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o | 14 | obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o |
diff --git a/net/ipv6/netfilter/ip6t_policy.c b/net/ipv6/netfilter/ip6t_policy.c deleted file mode 100644 index f2a59970e007..000000000000 --- a/net/ipv6/netfilter/ip6t_policy.c +++ /dev/null | |||
| @@ -1,174 +0,0 @@ | |||
| 1 | /* IP tables module for matching IPsec policy | ||
| 2 | * | ||
| 3 | * Copyright (c) 2004,2005 Patrick McHardy, <kaber@trash.net> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/kernel.h> | ||
| 11 | #include <linux/config.h> | ||
| 12 | #include <linux/module.h> | ||
| 13 | #include <linux/skbuff.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <net/xfrm.h> | ||
| 16 | |||
| 17 | #include <linux/netfilter_ipv6.h> | ||
| 18 | #include <linux/netfilter_ipv6/ip6_tables.h> | ||
| 19 | #include <linux/netfilter_ipv6/ip6t_policy.h> | ||
| 20 | |||
| 21 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | ||
| 22 | MODULE_DESCRIPTION("IPtables IPsec policy matching module"); | ||
| 23 | MODULE_LICENSE("GPL"); | ||
| 24 | |||
| 25 | |||
| 26 | static inline int | ||
| 27 | match_xfrm_state(struct xfrm_state *x, const struct ip6t_policy_elem *e) | ||
| 28 | { | ||
| 29 | #define MATCH_ADDR(x,y,z) (!e->match.x || \ | ||
| 30 | ((!ipv6_masked_addr_cmp(&e->x.a6, &e->y.a6, \ | ||
| 31 | z)) \ | ||
| 32 | ^ e->invert.x)) | ||
| 33 | #define MATCH(x,y) (!e->match.x || ((e->x == (y)) ^ e->invert.x)) | ||
| 34 | |||
| 35 | return MATCH_ADDR(saddr, smask, (struct in6_addr *)&x->props.saddr.a6) && | ||
| 36 | MATCH_ADDR(daddr, dmask, (struct in6_addr *)&x->id.daddr.a6) && | ||
| 37 | MATCH(proto, x->id.proto) && | ||
| 38 | MATCH(mode, x->props.mode) && | ||
| 39 | MATCH(spi, x->id.spi) && | ||
| 40 | MATCH(reqid, x->props.reqid); | ||
| 41 | } | ||
| 42 | |||
| 43 | static int | ||
| 44 | match_policy_in(const struct sk_buff *skb, const struct ip6t_policy_info *info) | ||
| 45 | { | ||
| 46 | const struct ip6t_policy_elem *e; | ||
| 47 | struct sec_path *sp = skb->sp; | ||
| 48 | int strict = info->flags & IP6T_POLICY_MATCH_STRICT; | ||
| 49 | int i, pos; | ||
| 50 | |||
| 51 | if (sp == NULL) | ||
| 52 | return -1; | ||
| 53 | if (strict && info->len != sp->len) | ||
| 54 | return 0; | ||
| 55 | |||
| 56 | for (i = sp->len - 1; i >= 0; i--) { | ||
| 57 | pos = strict ? i - sp->len + 1 : 0; | ||
| 58 | if (pos >= info->len) | ||
| 59 | return 0; | ||
| 60 | e = &info->pol[pos]; | ||
| 61 | |||
| 62 | if (match_xfrm_state(sp->x[i].xvec, e)) { | ||
| 63 | if (!strict) | ||
| 64 | return 1; | ||
| 65 | } else if (strict) | ||
| 66 | return 0; | ||
| 67 | } | ||
| 68 | |||
| 69 | return strict ? 1 : 0; | ||
| 70 | } | ||
| 71 | |||
| 72 | static int | ||
| 73 | match_policy_out(const struct sk_buff *skb, const struct ip6t_policy_info *info) | ||
| 74 | { | ||
| 75 | const struct ip6t_policy_elem *e; | ||
| 76 | struct dst_entry *dst = skb->dst; | ||
| 77 | int strict = info->flags & IP6T_POLICY_MATCH_STRICT; | ||
| 78 | int i, pos; | ||
| 79 | |||
| 80 | if (dst->xfrm == NULL) | ||
| 81 | return -1; | ||
| 82 | |||
| 83 | for (i = 0; dst && dst->xfrm; dst = dst->child, i++) { | ||
| 84 | pos = strict ? i : 0; | ||
| 85 | if (pos >= info->len) | ||
| 86 | return 0; | ||
| 87 | e = &info->pol[pos]; | ||
| 88 | |||
| 89 | if (match_xfrm_state(dst->xfrm, e)) { | ||
| 90 | if (!strict) | ||
| 91 | return 1; | ||
| 92 | } else if (strict) | ||
| 93 | return 0; | ||
| 94 | } | ||
| 95 | |||
| 96 | return strict ? i == info->len : 0; | ||
| 97 | } | ||
| 98 | |||
| 99 | static int match(const struct sk_buff *skb, | ||
| 100 | const struct net_device *in, | ||
| 101 | const struct net_device *out, | ||
| 102 | const struct xt_match *match, | ||
| 103 | const void *matchinfo, | ||
| 104 | int offset, | ||
| 105 | unsigned int protoff, | ||
| 106 | int *hotdrop) | ||
| 107 | { | ||
| 108 | const struct ip6t_policy_info *info = matchinfo; | ||
| 109 | int ret; | ||
| 110 | |||
| 111 | if (info->flags & IP6T_POLICY_MATCH_IN) | ||
| 112 | ret = match_policy_in(skb, info); | ||
| 113 | else | ||
| 114 | ret = match_policy_out(skb, info); | ||
| 115 | |||
| 116 | if (ret < 0) | ||
| 117 | ret = info->flags & IP6T_POLICY_MATCH_NONE ? 1 : 0; | ||
| 118 | else if (info->flags & IP6T_POLICY_MATCH_NONE) | ||
| 119 | ret = 0; | ||
| 120 | |||
| 121 | return ret; | ||
| 122 | } | ||
| 123 | |||
| 124 | static int checkentry(const char *tablename, const void *ip_void, | ||
| 125 | const struct xt_match *match, void *matchinfo, | ||
| 126 | unsigned int matchsize, unsigned int hook_mask) | ||
| 127 | { | ||
| 128 | struct ip6t_policy_info *info = matchinfo; | ||
| 129 | |||
| 130 | if (!(info->flags & (IP6T_POLICY_MATCH_IN|IP6T_POLICY_MATCH_OUT))) { | ||
| 131 | printk(KERN_ERR "ip6t_policy: neither incoming nor " | ||
| 132 | "outgoing policy selected\n"); | ||
| 133 | return 0; | ||
| 134 | } | ||
| 135 | if (hook_mask & (1 << NF_IP6_PRE_ROUTING | 1 << NF_IP6_LOCAL_IN) | ||
| 136 | && info->flags & IP6T_POLICY_MATCH_OUT) { | ||
| 137 | printk(KERN_ERR "ip6t_policy: output policy not valid in " | ||
| 138 | "PRE_ROUTING and INPUT\n"); | ||
| 139 | return 0; | ||
| 140 | } | ||
| 141 | if (hook_mask & (1 << NF_IP6_POST_ROUTING | 1 << NF_IP6_LOCAL_OUT) | ||
| 142 | && info->flags & IP6T_POLICY_MATCH_IN) { | ||
| 143 | printk(KERN_ERR "ip6t_policy: input policy not valid in " | ||
| 144 | "POST_ROUTING and OUTPUT\n"); | ||
| 145 | return 0; | ||
| 146 | } | ||
| 147 | if (info->len > IP6T_POLICY_MAX_ELEM) { | ||
| 148 | printk(KERN_ERR "ip6t_policy: too many policy elements\n"); | ||
| 149 | return 0; | ||
| 150 | } | ||
| 151 | |||
| 152 | return 1; | ||
| 153 | } | ||
| 154 | |||
| 155 | static struct ip6t_match policy_match = { | ||
| 156 | .name = "policy", | ||
| 157 | .match = match, | ||
| 158 | .matchsize = sizeof(struct ip6t_policy_info), | ||
| 159 | .checkentry = checkentry, | ||
| 160 | .me = THIS_MODULE, | ||
| 161 | }; | ||
| 162 | |||
| 163 | static int __init init(void) | ||
| 164 | { | ||
| 165 | return ip6t_register_match(&policy_match); | ||
| 166 | } | ||
| 167 | |||
| 168 | static void __exit fini(void) | ||
| 169 | { | ||
| 170 | ip6t_unregister_match(&policy_match); | ||
| 171 | } | ||
| 172 | |||
| 173 | module_init(init); | ||
| 174 | module_exit(fini); | ||
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index a8e5544da93e..174027809148 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig | |||
| @@ -279,6 +279,16 @@ config NETFILTER_XT_MATCH_MARK | |||
| 279 | 279 | ||
| 280 | To compile it as a module, choose M here. If unsure, say N. | 280 | To compile it as a module, choose M here. If unsure, say N. |
| 281 | 281 | ||
| 282 | config NETFILTER_XT_MATCH_POLICY | ||
| 283 | tristate 'IPsec "policy" match support' | ||
| 284 | depends on NETFILTER_XTABLES && XFRM | ||
| 285 | help | ||
| 286 | Policy matching allows you to match packets based on the | ||
| 287 | IPsec policy that was used during decapsulation/will | ||
| 288 | be used during encapsulation. | ||
| 289 | |||
| 290 | To compile it as a module, choose M here. If unsure, say N. | ||
| 291 | |||
| 282 | config NETFILTER_XT_MATCH_PHYSDEV | 292 | config NETFILTER_XT_MATCH_PHYSDEV |
| 283 | tristate '"physdev" match support' | 293 | tristate '"physdev" match support' |
| 284 | depends on NETFILTER_XTABLES && BRIDGE_NETFILTER | 294 | depends on NETFILTER_XTABLES && BRIDGE_NETFILTER |
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index 746172ebc91b..9558727f5e79 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile | |||
| @@ -40,6 +40,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o | |||
| 40 | obj-$(CONFIG_NETFILTER_XT_MATCH_LIMIT) += xt_limit.o | 40 | obj-$(CONFIG_NETFILTER_XT_MATCH_LIMIT) += xt_limit.o |
| 41 | obj-$(CONFIG_NETFILTER_XT_MATCH_MAC) += xt_mac.o | 41 | obj-$(CONFIG_NETFILTER_XT_MATCH_MAC) += xt_mac.o |
| 42 | obj-$(CONFIG_NETFILTER_XT_MATCH_MARK) += xt_mark.o | 42 | obj-$(CONFIG_NETFILTER_XT_MATCH_MARK) += xt_mark.o |
| 43 | obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o | ||
| 43 | obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o | 44 | obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o |
| 44 | obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o | 45 | obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o |
| 45 | obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o | 46 | obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o |
diff --git a/net/netfilter/xt_policy.c b/net/netfilter/xt_policy.c new file mode 100644 index 000000000000..1ec22082f04d --- /dev/null +++ b/net/netfilter/xt_policy.c | |||
| @@ -0,0 +1,209 @@ | |||
| 1 | /* IP tables module for matching IPsec policy | ||
| 2 | * | ||
| 3 | * Copyright (c) 2004,2005 Patrick McHardy, <kaber@trash.net> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/kernel.h> | ||
| 11 | #include <linux/config.h> | ||
| 12 | #include <linux/module.h> | ||
| 13 | #include <linux/skbuff.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <net/xfrm.h> | ||
| 16 | |||
| 17 | #include <linux/netfilter/xt_policy.h> | ||
| 18 | #include <linux/netfilter/x_tables.h> | ||
| 19 | |||
| 20 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | ||
| 21 | MODULE_DESCRIPTION("Xtables IPsec policy matching module"); | ||
| 22 | MODULE_LICENSE("GPL"); | ||
| 23 | |||
| 24 | static inline int | ||
| 25 | xt_addr_cmp(const union xt_policy_addr *a1, const union xt_policy_addr *m, | ||
| 26 | const union xt_policy_addr *a2, unsigned short family) | ||
| 27 | { | ||
| 28 | switch (family) { | ||
| 29 | case AF_INET: | ||
| 30 | return (a1->a4.s_addr ^ a2->a4.s_addr) & m->a4.s_addr; | ||
| 31 | case AF_INET6: | ||
| 32 | return ipv6_masked_addr_cmp(&a1->a6, &m->a6, &a2->a6); | ||
| 33 | } | ||
| 34 | return 0; | ||
| 35 | } | ||
| 36 | |||
| 37 | static inline int | ||
| 38 | match_xfrm_state(struct xfrm_state *x, const struct xt_policy_elem *e, | ||
| 39 | unsigned short family) | ||
| 40 | { | ||
| 41 | #define MATCH_ADDR(x,y,z) (!e->match.x || \ | ||
| 42 | (xt_addr_cmp(&e->x, &e->y, z, family) \ | ||
| 43 | ^ e->invert.x)) | ||
| 44 | #define MATCH(x,y) (!e->match.x || ((e->x == (y)) ^ e->invert.x)) | ||
| 45 | |||
| 46 | return MATCH_ADDR(saddr, smask, (union xt_policy_addr *)&x->props.saddr) && | ||
| 47 | MATCH_ADDR(daddr, dmask, (union xt_policy_addr *)&x->id.daddr.a4) && | ||
| 48 | MATCH(proto, x->id.proto) && | ||
| 49 | MATCH(mode, x->props.mode) && | ||
| 50 | MATCH(spi, x->id.spi) && | ||
| 51 | MATCH(reqid, x->props.reqid); | ||
| 52 | } | ||
| 53 | |||
| 54 | static int | ||
| 55 | match_policy_in(const struct sk_buff *skb, const struct xt_policy_info *info, | ||
| 56 | unsigned short family) | ||
| 57 | { | ||
| 58 | const struct xt_policy_elem *e; | ||
| 59 | struct sec_path *sp = skb->sp; | ||
| 60 | int strict = info->flags & XT_POLICY_MATCH_STRICT; | ||
| 61 | int i, pos; | ||
| 62 | |||
| 63 | if (sp == NULL) | ||
| 64 | return -1; | ||
| 65 | if (strict && info->len != sp->len) | ||
| 66 | return 0; | ||
| 67 | |||
| 68 | for (i = sp->len - 1; i >= 0; i--) { | ||
| 69 | pos = strict ? i - sp->len + 1 : 0; | ||
| 70 | if (pos >= info->len) | ||
| 71 | return 0; | ||
| 72 | e = &info->pol[pos]; | ||
| 73 | |||
| 74 | if (match_xfrm_state(sp->x[i].xvec, e, family)) { | ||
| 75 | if (!strict) | ||
| 76 | return 1; | ||
| 77 | } else if (strict) | ||
| 78 | return 0; | ||
| 79 | } | ||
| 80 | |||
| 81 | return strict ? 1 : 0; | ||
| 82 | } | ||
| 83 | |||
| 84 | static int | ||
| 85 | match_policy_out(const struct sk_buff *skb, const struct xt_policy_info *info, | ||
| 86 | unsigned short family) | ||
| 87 | { | ||
| 88 | const struct xt_policy_elem *e; | ||
| 89 | struct dst_entry *dst = skb->dst; | ||
| 90 | int strict = info->flags & XT_POLICY_MATCH_STRICT; | ||
| 91 | int i, pos; | ||
| 92 | |||
| 93 | if (dst->xfrm == NULL) | ||
| 94 | return -1; | ||
| 95 | |||
| 96 | for (i = 0; dst && dst->xfrm; dst = dst->child, i++) { | ||
| 97 | pos = strict ? i : 0; | ||
| 98 | if (pos >= info->len) | ||
| 99 | return 0; | ||
| 100 | e = &info->pol[pos]; | ||
| 101 | |||
| 102 | if (match_xfrm_state(dst->xfrm, e, family)) { | ||
| 103 | if (!strict) | ||
| 104 | return 1; | ||
| 105 | } else if (strict) | ||
| 106 | return 0; | ||
| 107 | } | ||
| 108 | |||
| 109 | return strict ? i == info->len : 0; | ||
| 110 | } | ||
| 111 | |||
| 112 | static int match(const struct sk_buff *skb, | ||
| 113 | const struct net_device *in, | ||
| 114 | const struct net_device *out, | ||
| 115 | const struct xt_match *match, | ||
| 116 | const void *matchinfo, | ||
| 117 | int offset, | ||
| 118 | unsigned int protoff, | ||
| 119 | int *hotdrop) | ||
| 120 | { | ||
| 121 | const struct xt_policy_info *info = matchinfo; | ||
| 122 | int ret; | ||
| 123 | |||
| 124 | if (info->flags & XT_POLICY_MATCH_IN) | ||
| 125 | ret = match_policy_in(skb, info, match->family); | ||
| 126 | else | ||
| 127 | ret = match_policy_out(skb, info, match->family); | ||
| 128 | |||
| 129 | if (ret < 0) | ||
| 130 | ret = info->flags & XT_POLICY_MATCH_NONE ? 1 : 0; | ||
| 131 | else if (info->flags & XT_POLICY_MATCH_NONE) | ||
| 132 | ret = 0; | ||
| 133 | |||
| 134 | return ret; | ||
| 135 | } | ||
| 136 | |||
| 137 | static int checkentry(const char *tablename, const void *ip_void, | ||
| 138 | const struct xt_match *match, | ||
| 139 | void *matchinfo, unsigned int matchsize, | ||
| 140 | unsigned int hook_mask) | ||
| 141 | { | ||
| 142 | struct xt_policy_info *info = matchinfo; | ||
| 143 | |||
| 144 | if (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT))) { | ||
| 145 | printk(KERN_ERR "xt_policy: neither incoming nor " | ||
| 146 | "outgoing policy selected\n"); | ||
| 147 | return 0; | ||
| 148 | } | ||
| 149 | /* hook values are equal for IPv4 and IPv6 */ | ||
| 150 | if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN) | ||
| 151 | && info->flags & XT_POLICY_MATCH_OUT) { | ||
| 152 | printk(KERN_ERR "xt_policy: output policy not valid in " | ||
| 153 | "PRE_ROUTING and INPUT\n"); | ||
| 154 | return 0; | ||
| 155 | } | ||
| 156 | if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT) | ||
| 157 | && info->flags & XT_POLICY_MATCH_IN) { | ||
| 158 | printk(KERN_ERR "xt_policy: input policy not valid in " | ||
| 159 | "POST_ROUTING and OUTPUT\n"); | ||
| 160 | return 0; | ||
| 161 | } | ||
| 162 | if (info->len > XT_POLICY_MAX_ELEM) { | ||
| 163 | printk(KERN_ERR "xt_policy: too many policy elements\n"); | ||
| 164 | return 0; | ||
| 165 | } | ||
| 166 | return 1; | ||
| 167 | } | ||
| 168 | |||
| 169 | static struct xt_match policy_match = { | ||
| 170 | .name = "policy", | ||
| 171 | .family = AF_INET, | ||
| 172 | .match = match, | ||
| 173 | .matchsize = sizeof(struct xt_policy_info), | ||
| 174 | .checkentry = checkentry, | ||
| 175 | .me = THIS_MODULE, | ||
| 176 | }; | ||
| 177 | |||
| 178 | static struct xt_match policy6_match = { | ||
| 179 | .name = "policy", | ||
| 180 | .family = AF_INET6, | ||
| 181 | .match = match, | ||
| 182 | .matchsize = sizeof(struct xt_policy_info), | ||
| 183 | .checkentry = checkentry, | ||
| 184 | .me = THIS_MODULE, | ||
| 185 | }; | ||
| 186 | |||
| 187 | static int __init init(void) | ||
| 188 | { | ||
| 189 | int ret; | ||
| 190 | |||
| 191 | ret = xt_register_match(AF_INET, &policy_match); | ||
| 192 | if (ret) | ||
| 193 | return ret; | ||
| 194 | ret = xt_register_match(AF_INET6, &policy6_match); | ||
| 195 | if (ret) | ||
| 196 | xt_unregister_match(AF_INET, &policy_match); | ||
| 197 | return ret; | ||
| 198 | } | ||
| 199 | |||
| 200 | static void __exit fini(void) | ||
| 201 | { | ||
| 202 | xt_unregister_match(AF_INET6, &policy6_match); | ||
| 203 | xt_unregister_match(AF_INET, &policy_match); | ||
| 204 | } | ||
| 205 | |||
| 206 | module_init(init); | ||
| 207 | module_exit(fini); | ||
| 208 | MODULE_ALIAS("ipt_policy"); | ||
| 209 | MODULE_ALIAS("ip6t_policy"); | ||
