diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/xt_conntrack.c | 61 |
1 files changed, 17 insertions, 44 deletions
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c index 6dc4652f2fe8..ae66305f0fe5 100644 --- a/net/netfilter/xt_conntrack.c +++ b/net/netfilter/xt_conntrack.c | |||
@@ -113,7 +113,8 @@ ct_proto_port_check(const struct xt_conntrack_mtinfo2 *info, | |||
113 | } | 113 | } |
114 | 114 | ||
115 | static bool | 115 | static bool |
116 | conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par) | 116 | conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par, |
117 | u16 state_mask, u16 status_mask) | ||
117 | { | 118 | { |
118 | const struct xt_conntrack_mtinfo2 *info = par->matchinfo; | 119 | const struct xt_conntrack_mtinfo2 *info = par->matchinfo; |
119 | enum ip_conntrack_info ctinfo; | 120 | enum ip_conntrack_info ctinfo; |
@@ -136,7 +137,7 @@ conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
136 | if (test_bit(IPS_DST_NAT_BIT, &ct->status)) | 137 | if (test_bit(IPS_DST_NAT_BIT, &ct->status)) |
137 | statebit |= XT_CONNTRACK_STATE_DNAT; | 138 | statebit |= XT_CONNTRACK_STATE_DNAT; |
138 | } | 139 | } |
139 | if (!!(info->state_mask & statebit) ^ | 140 | if (!!(state_mask & statebit) ^ |
140 | !(info->invert_flags & XT_CONNTRACK_STATE)) | 141 | !(info->invert_flags & XT_CONNTRACK_STATE)) |
141 | return false; | 142 | return false; |
142 | } | 143 | } |
@@ -172,7 +173,7 @@ conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
172 | return false; | 173 | return false; |
173 | 174 | ||
174 | if ((info->match_flags & XT_CONNTRACK_STATUS) && | 175 | if ((info->match_flags & XT_CONNTRACK_STATUS) && |
175 | (!!(info->status_mask & ct->status) ^ | 176 | (!!(status_mask & ct->status) ^ |
176 | !(info->invert_flags & XT_CONNTRACK_STATUS))) | 177 | !(info->invert_flags & XT_CONNTRACK_STATUS))) |
177 | return false; | 178 | return false; |
178 | 179 | ||
@@ -192,11 +193,17 @@ conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
192 | static bool | 193 | static bool |
193 | conntrack_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par) | 194 | conntrack_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par) |
194 | { | 195 | { |
195 | const struct xt_conntrack_mtinfo2 *const *info = par->matchinfo; | 196 | const struct xt_conntrack_mtinfo1 *info = par->matchinfo; |
196 | struct xt_match_param newpar = *par; | ||
197 | 197 | ||
198 | newpar.matchinfo = *info; | 198 | return conntrack_mt(skb, par, info->state_mask, info->status_mask); |
199 | return conntrack_mt(skb, &newpar); | 199 | } |
200 | |||
201 | static bool | ||
202 | conntrack_mt_v2(const struct sk_buff *skb, const struct xt_match_param *par) | ||
203 | { | ||
204 | const struct xt_conntrack_mtinfo2 *info = par->matchinfo; | ||
205 | |||
206 | return conntrack_mt(skb, par, info->state_mask, info->status_mask); | ||
200 | } | 207 | } |
201 | 208 | ||
202 | static bool conntrack_mt_check(const struct xt_mtchk_param *par) | 209 | static bool conntrack_mt_check(const struct xt_mtchk_param *par) |
@@ -209,45 +216,11 @@ static bool conntrack_mt_check(const struct xt_mtchk_param *par) | |||
209 | return true; | 216 | return true; |
210 | } | 217 | } |
211 | 218 | ||
212 | static bool conntrack_mt_check_v1(const struct xt_mtchk_param *par) | ||
213 | { | ||
214 | struct xt_conntrack_mtinfo1 *info = par->matchinfo; | ||
215 | struct xt_conntrack_mtinfo2 *up; | ||
216 | int ret = conntrack_mt_check(par); | ||
217 | |||
218 | if (ret < 0) | ||
219 | return ret; | ||
220 | |||
221 | up = kmalloc(sizeof(*up), GFP_KERNEL); | ||
222 | if (up == NULL) { | ||
223 | nf_ct_l3proto_module_put(par->family); | ||
224 | return -ENOMEM; | ||
225 | } | ||
226 | |||
227 | /* | ||
228 | * The strategy here is to minimize the overhead of v1 matching, | ||
229 | * by prebuilding a v2 struct and putting the pointer into the | ||
230 | * v1 dataspace. | ||
231 | */ | ||
232 | memcpy(up, info, offsetof(typeof(*info), state_mask)); | ||
233 | up->state_mask = info->state_mask; | ||
234 | up->status_mask = info->status_mask; | ||
235 | *(void **)info = up; | ||
236 | return true; | ||
237 | } | ||
238 | |||
239 | static void conntrack_mt_destroy(const struct xt_mtdtor_param *par) | 219 | static void conntrack_mt_destroy(const struct xt_mtdtor_param *par) |
240 | { | 220 | { |
241 | nf_ct_l3proto_module_put(par->family); | 221 | nf_ct_l3proto_module_put(par->family); |
242 | } | 222 | } |
243 | 223 | ||
244 | static void conntrack_mt_destroy_v1(const struct xt_mtdtor_param *par) | ||
245 | { | ||
246 | struct xt_conntrack_mtinfo2 **info = par->matchinfo; | ||
247 | kfree(*info); | ||
248 | conntrack_mt_destroy(par); | ||
249 | } | ||
250 | |||
251 | static struct xt_match conntrack_mt_reg[] __read_mostly = { | 224 | static struct xt_match conntrack_mt_reg[] __read_mostly = { |
252 | { | 225 | { |
253 | .name = "conntrack", | 226 | .name = "conntrack", |
@@ -255,8 +228,8 @@ static struct xt_match conntrack_mt_reg[] __read_mostly = { | |||
255 | .family = NFPROTO_UNSPEC, | 228 | .family = NFPROTO_UNSPEC, |
256 | .matchsize = sizeof(struct xt_conntrack_mtinfo1), | 229 | .matchsize = sizeof(struct xt_conntrack_mtinfo1), |
257 | .match = conntrack_mt_v1, | 230 | .match = conntrack_mt_v1, |
258 | .checkentry = conntrack_mt_check_v1, | 231 | .checkentry = conntrack_mt_check, |
259 | .destroy = conntrack_mt_destroy_v1, | 232 | .destroy = conntrack_mt_destroy, |
260 | .me = THIS_MODULE, | 233 | .me = THIS_MODULE, |
261 | }, | 234 | }, |
262 | { | 235 | { |
@@ -264,7 +237,7 @@ static struct xt_match conntrack_mt_reg[] __read_mostly = { | |||
264 | .revision = 2, | 237 | .revision = 2, |
265 | .family = NFPROTO_UNSPEC, | 238 | .family = NFPROTO_UNSPEC, |
266 | .matchsize = sizeof(struct xt_conntrack_mtinfo2), | 239 | .matchsize = sizeof(struct xt_conntrack_mtinfo2), |
267 | .match = conntrack_mt, | 240 | .match = conntrack_mt_v2, |
268 | .checkentry = conntrack_mt_check, | 241 | .checkentry = conntrack_mt_check, |
269 | .destroy = conntrack_mt_destroy, | 242 | .destroy = conntrack_mt_destroy, |
270 | .me = THIS_MODULE, | 243 | .me = THIS_MODULE, |