-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Patrick McHardy
authored and
David S. Miller
committed
Jan 7, 2006
1 parent
673665b
commit bf5fc56
Showing
9 changed files
with
472 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: eb9c7ebe6980c41cf6ae889e301c3b49f473ee9f | ||
refs/heads/master: e16a8f0b8c53312beb1d8b52e463aae79aa809c7 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#ifndef _IPT_POLICY_H | ||
#define _IPT_POLICY_H | ||
|
||
#define IPT_POLICY_MAX_ELEM 4 | ||
|
||
enum ipt_policy_flags | ||
{ | ||
IPT_POLICY_MATCH_IN = 0x1, | ||
IPT_POLICY_MATCH_OUT = 0x2, | ||
IPT_POLICY_MATCH_NONE = 0x4, | ||
IPT_POLICY_MATCH_STRICT = 0x8, | ||
}; | ||
|
||
enum ipt_policy_modes | ||
{ | ||
IPT_POLICY_MODE_TRANSPORT, | ||
IPT_POLICY_MODE_TUNNEL | ||
}; | ||
|
||
struct ipt_policy_spec | ||
{ | ||
u_int8_t saddr:1, | ||
daddr:1, | ||
proto:1, | ||
mode:1, | ||
spi:1, | ||
reqid:1; | ||
}; | ||
|
||
struct ipt_policy_elem | ||
{ | ||
u_int32_t saddr; | ||
u_int32_t smask; | ||
u_int32_t daddr; | ||
u_int32_t dmask; | ||
u_int32_t spi; | ||
u_int32_t reqid; | ||
u_int8_t proto; | ||
u_int8_t mode; | ||
|
||
struct ipt_policy_spec match; | ||
struct ipt_policy_spec invert; | ||
}; | ||
|
||
struct ipt_policy_info | ||
{ | ||
struct ipt_policy_elem pol[IPT_POLICY_MAX_ELEM]; | ||
u_int16_t flags; | ||
u_int16_t len; | ||
}; | ||
|
||
#endif /* _IPT_POLICY_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#ifndef _IP6T_POLICY_H | ||
#define _IP6T_POLICY_H | ||
|
||
#define IP6T_POLICY_MAX_ELEM 4 | ||
|
||
enum ip6t_policy_flags | ||
{ | ||
IP6T_POLICY_MATCH_IN = 0x1, | ||
IP6T_POLICY_MATCH_OUT = 0x2, | ||
IP6T_POLICY_MATCH_NONE = 0x4, | ||
IP6T_POLICY_MATCH_STRICT = 0x8, | ||
}; | ||
|
||
enum ip6t_policy_modes | ||
{ | ||
IP6T_POLICY_MODE_TRANSPORT, | ||
IP6T_POLICY_MODE_TUNNEL | ||
}; | ||
|
||
struct ip6t_policy_spec | ||
{ | ||
u_int8_t saddr:1, | ||
daddr:1, | ||
proto:1, | ||
mode:1, | ||
spi:1, | ||
reqid:1; | ||
}; | ||
|
||
struct ip6t_policy_elem | ||
{ | ||
struct in6_addr saddr; | ||
struct in6_addr smask; | ||
struct in6_addr daddr; | ||
struct in6_addr dmask; | ||
u_int32_t spi; | ||
u_int32_t reqid; | ||
u_int8_t proto; | ||
u_int8_t mode; | ||
|
||
struct ip6t_policy_spec match; | ||
struct ip6t_policy_spec invert; | ||
}; | ||
|
||
struct ip6t_policy_info | ||
{ | ||
struct ip6t_policy_elem pol[IP6T_POLICY_MAX_ELEM]; | ||
u_int16_t flags; | ||
u_int16_t len; | ||
}; | ||
|
||
#endif /* _IP6T_POLICY_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
/* IP tables module for matching IPsec policy | ||
* | ||
* Copyright (c) 2004,2005 Patrick McHardy, <kaber@trash.net> | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
*/ | ||
|
||
#include <linux/kernel.h> | ||
#include <linux/config.h> | ||
#include <linux/module.h> | ||
#include <linux/skbuff.h> | ||
#include <linux/init.h> | ||
#include <net/xfrm.h> | ||
|
||
#include <linux/netfilter_ipv4.h> | ||
#include <linux/netfilter_ipv4/ip_tables.h> | ||
#include <linux/netfilter_ipv4/ipt_policy.h> | ||
|
||
MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | ||
MODULE_DESCRIPTION("IPtables IPsec policy matching module"); | ||
MODULE_LICENSE("GPL"); | ||
|
||
|
||
static inline int | ||
match_xfrm_state(struct xfrm_state *x, const struct ipt_policy_elem *e) | ||
{ | ||
#define MATCH(x,y) (!e->match.x || ((e->x == (y)) ^ e->invert.x)) | ||
|
||
return MATCH(saddr, x->props.saddr.a4 & e->smask) && | ||
MATCH(daddr, x->id.daddr.a4 & e->dmask) && | ||
MATCH(proto, x->id.proto) && | ||
MATCH(mode, x->props.mode) && | ||
MATCH(spi, x->id.spi) && | ||
MATCH(reqid, x->props.reqid); | ||
} | ||
|
||
static int | ||
match_policy_in(const struct sk_buff *skb, const struct ipt_policy_info *info) | ||
{ | ||
const struct ipt_policy_elem *e; | ||
struct sec_path *sp = skb->sp; | ||
int strict = info->flags & IPT_POLICY_MATCH_STRICT; | ||
int i, pos; | ||
|
||
if (sp == NULL) | ||
return -1; | ||
if (strict && info->len != sp->len) | ||
return 0; | ||
|
||
for (i = sp->len - 1; i >= 0; i--) { | ||
pos = strict ? i - sp->len + 1 : 0; | ||
if (pos >= info->len) | ||
return 0; | ||
e = &info->pol[pos]; | ||
|
||
if (match_xfrm_state(sp->x[i].xvec, e)) { | ||
if (!strict) | ||
return 1; | ||
} else if (strict) | ||
return 0; | ||
} | ||
|
||
return strict ? 1 : 0; | ||
} | ||
|
||
static int | ||
match_policy_out(const struct sk_buff *skb, const struct ipt_policy_info *info) | ||
{ | ||
const struct ipt_policy_elem *e; | ||
struct dst_entry *dst = skb->dst; | ||
int strict = info->flags & IPT_POLICY_MATCH_STRICT; | ||
int i, pos; | ||
|
||
if (dst->xfrm == NULL) | ||
return -1; | ||
|
||
for (i = 0; dst && dst->xfrm; dst = dst->child, i++) { | ||
pos = strict ? i : 0; | ||
if (pos >= info->len) | ||
return 0; | ||
e = &info->pol[pos]; | ||
|
||
if (match_xfrm_state(dst->xfrm, e)) { | ||
if (!strict) | ||
return 1; | ||
} else if (strict) | ||
return 0; | ||
} | ||
|
||
return strict ? 1 : 0; | ||
} | ||
|
||
static int match(const struct sk_buff *skb, | ||
const struct net_device *in, | ||
const struct net_device *out, | ||
const void *matchinfo, int offset, int *hotdrop) | ||
{ | ||
const struct ipt_policy_info *info = matchinfo; | ||
int ret; | ||
|
||
if (info->flags & IPT_POLICY_MATCH_IN) | ||
ret = match_policy_in(skb, info); | ||
else | ||
ret = match_policy_out(skb, info); | ||
|
||
if (ret < 0) | ||
ret = info->flags & IPT_POLICY_MATCH_NONE ? 1 : 0; | ||
else if (info->flags & IPT_POLICY_MATCH_NONE) | ||
ret = 0; | ||
|
||
return ret; | ||
} | ||
|
||
static int checkentry(const char *tablename, const struct ipt_ip *ip, | ||
void *matchinfo, unsigned int matchsize, | ||
unsigned int hook_mask) | ||
{ | ||
struct ipt_policy_info *info = matchinfo; | ||
|
||
if (matchsize != IPT_ALIGN(sizeof(*info))) { | ||
printk(KERN_ERR "ipt_policy: matchsize %u != %zu\n", | ||
matchsize, IPT_ALIGN(sizeof(*info))); | ||
return 0; | ||
} | ||
if (!(info->flags & (IPT_POLICY_MATCH_IN|IPT_POLICY_MATCH_OUT))) { | ||
printk(KERN_ERR "ipt_policy: neither incoming nor " | ||
"outgoing policy selected\n"); | ||
return 0; | ||
} | ||
if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN) | ||
&& info->flags & IPT_POLICY_MATCH_OUT) { | ||
printk(KERN_ERR "ipt_policy: output policy not valid in " | ||
"PRE_ROUTING and INPUT\n"); | ||
return 0; | ||
} | ||
if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT) | ||
&& info->flags & IPT_POLICY_MATCH_IN) { | ||
printk(KERN_ERR "ipt_policy: input policy not valid in " | ||
"POST_ROUTING and OUTPUT\n"); | ||
return 0; | ||
} | ||
if (info->len > IPT_POLICY_MAX_ELEM) { | ||
printk(KERN_ERR "ipt_policy: too many policy elements\n"); | ||
return 0; | ||
} | ||
|
||
return 1; | ||
} | ||
|
||
static struct ipt_match policy_match = { | ||
.name = "policy", | ||
.match = match, | ||
.checkentry = checkentry, | ||
.me = THIS_MODULE, | ||
}; | ||
|
||
static int __init init(void) | ||
{ | ||
return ipt_register_match(&policy_match); | ||
} | ||
|
||
static void __exit fini(void) | ||
{ | ||
ipt_unregister_match(&policy_match); | ||
} | ||
|
||
module_init(init); | ||
module_exit(fini); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.